This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Deprecated Components

1 - cm2kc (clustermap to kubeconfig)


cm2kc is a CLI tool used to convert a clustermap file to a kubeconfig file.


go run ./cmd/cm2kc <options>

The following is a list of supported options for cm2kc:

  -i, --input string    Input clustermap file. (default "/dev/stdin")
  -o, --output string   Output kubeconfig file. (default "/dev/stdout")


Add a kubeconfig file in a secret: kubeconfig from a clustermap file in another secret: build-cluster for context: my-context

The following command will:

  1. Get a clustermap formatted secret: build-cluster in key: cluster for context: my-context.
  2. Base64 decode the secret.
  3. Convert the clustermap data to a kubeconfig format.
  4. Create a kubeconfig formatted secret: kubeconfig in key: config for context: my-context from the converted data.
kubectl --context=my-context get secrets build-cluster -o jsonpath='{.data.cluster}' |
  base64 -d |
  go run ./cmd/cm2kc |
  kubectl --context=my-context create secret generic kubeconfig --from-file=config=/dev/stdin

Lastly, to begin using this in Prow, update the volume mount and replace --build-cluster with --kubeconfig in the deployment of each relevant Prow component (e.g. crier, deck, plank, and sinker).

Create a kubeconfig file at path /path/to/kubeconfig.yaml from a clustermap file at path /path/to/clustermap.yaml

Ensure the clustermap file exists at the specified --input path:

# /path/to/clustermap.yaml

  clientCertificate: fake-default-client-cert
  clientKey: fake-default-client-key
  clusterCaCertificate: fake-default-ca-cert
  clientCertificate: fake-build-client-cert
  clientKey: fake-build-client-key
  clusterCaCertificate: fake-build-ca-cert

Execute cm2kc specifying an --input path to the clustermap file and an --output path to the desired location of the generated kubeconfig file:

go run ./cmd/cm2kc --input=/path/to/clustermap.yaml --output=/path/to/kubeconfig.yaml

The following kubeconfig file will be created at the specified --output path:

# /path/to/kubeconfig.yaml

apiVersion: v1
- name: default
    certificate-authority-data: fake-default-ca-cert
- name: build
    certificate-authority-data: fake-build-ca-cert
- name: default
    cluster: default
    user: default
- name: build
    cluster: build
    user: build
current-context: default
kind: Config
preferences: {}
- name: default
    client-certificate-data: fake-default-ca-cert
    client-key-data: fake-default-ca-cert
- name: build
    client-certificate-data: fake-build-ca-cert
    client-key-data: fake-build-ca-cert

2 - Phaino

Run prowjobs on your local workstation with phaino.

Plato believed that ideas and forms are the ultimate truth, whereas we only see the imperfect physical appearances of those idea.

He linkens this in his Allegory of the Cave to someone living in a cave who can only see the shadows projected on the wall from objects passing in front of a fire.

Phaino is act of making those imperfect shadows appear.

Phaino shares a prefix with Pharos, meaning lighthouse and in particular the ancient one in Alexandria.



# Use a job from deck
go run ./cmd/phaino $URL # or /path/to/prowjob.yaml
# Use mkpj to create the job
go run ./cmd/mkpj --config-path=/path/to/prow/config.yaml --job-config-path=/path/to/prow/job/configs --job=foo > /tmp/foo
go run ./cmd/phaino /tmp/foo

Phaino is an interactive utility; it will prompt you for a local copy of any secrets or volumes that the Prow Job may require.

Common options

  • --grace=5m controls how long to wait for interrupted jobs before terminating
  • --print the command that runs each job without running it
  • --privileged jobs are allowed to run instead of rejected
  • --timeout=10m controls how long to allow jobs to run before interrupting them
  • --code-mount-path=/go changes the path where code is mounted in the container
  • --skip-volume-mounts=volume1,volume2 includes the unwanted volume mounts that are defined in the job spec
  • --extra-volume-mounts=/go/src/ includes the extra volume mounts needed for the container. Key is the mount path and value is the local path
  • --skip-envs=env1,env2 includes the unwanted env vars that are defined in the job spec
  • --extra-envs=env1=val1,env2=val2 includes the extra env vars needed for the container
  • --use-local-gcloud-credentials controls whether to use the same gcloud credentials as local or not
  • --use-local-kubeconfig controls whether to use the same kubeconfig as local or not

Common options usage scenarios

Phaino is smart at prompting for where repo is located, volume mounts etc., if it’s desired to save the prompts, use the following tricks instead:

  • If the repo needs to be cloned under GOPATH, use:

    --code-mount-path==/whatever/go/src # Controls where source code is mounted in container
  • If job requires mounting kubeconfig, assume the mount is named kubeconfig,use:

  • If job requires mounting gcloud default credentials, assume the mount is named service-account,use:

  • If job requires mounting something else like name:foo; mountPath: /bar,use:

  • If job requires env vars,use:


See go run ./cmd/phaino --help for full option list.

Usage examples

URL example

  • Go to your deck deployment
  • Pick a job and click the rerun icon on the left
  • Copy the URL (something like
  • Paste it as a phaino arg
    • go run ./cmd/phaino
    • Alternatively go run ./cmd/phaino <(curl $URL)

Configuration example

  • Use mkpj to create the job and pipe this to phaino
    • For jobs use //config:mkpj

      go run ./config:mkpj --job=pull-test-infra-bazel > /tmp/foo
      go run ./cmd/phaino /tmp/foo
    • Other deployments will need to clone that rule and/or pass in extra flags:

      go run ./cmd/mkpj --config-path=/my/config.yaml --job=my-job
      go run ./cmd/phaino /tmp/foo

3 - Plank

Plank is the controller that manages the job execution and lifecycle for jobs running in k8s.


go run ./cmd/prow-controller-manager --help


GCS and S3 are supported as the job log storage.

# config.yaml

  # used to link to job results for decorated jobs (with pod utilities)
    '*': https://<domain>/view
  # used to link to job results for non decorated jobs (without pod utilities)
  job_url_template: 'https://<domain>/view/<bucket-name>/pr-logs/pull/{{.Spec.Refs.Repo}}/{{with index .Spec.Refs.Pulls 0}}{{.Number}}{{end}}/{{.Spec.Job}}/{{.Status.BuildID}}'
  report_template: '[Full PR test history](https://<domain>/pr-history?org={{.Spec.Refs.Org}}&repo={{.Spec.Refs.Repo}}&pr={{with index .Spec.Refs.Pulls 0}}{{.Number}}{{end}})'
  # All entries that match a job are used, later entries override previous values.
  # Omission of 'repo' and 'cluster' fields makes this entry match all jobs.
  - config:
      timeout: 4h
      grace_period: 15s
      utility_images: # pull specs for container images used to construct job pods
      gcs_configuration: # configuration for uploading job results to GCS
        bucket: <bucket-name> or s3://<bucket-name>
        path_strategy: explicit # or `legacy`, `single`
        default_org: <github-org> # should not need this if `strategy` is set to explicit
        default_repo: <github-repo> # should not need this if `strategy` is set to explicit
      gcs_credentials_secret: <secret-name> # the name of the secret that stores cloud provider credentials
        - ssh-secret # name of the secret that stores the bot's ssh keys for GitHub, doesn't matter what the key of the map is and it will just uses the values
  - repo: "^org/" # some regexp to match against <org/repo>
  - cluster: "-trusted$" #some regexp to match against the cluster name
      # example override to use k8s SA with GCP workload identity rather than
      # a GCP service account key file.
      gcs_credentials_secret: ""