18

I'm trying to use google cloud build. At one step, I need to get a list of all running compute instances.

- name: gcr.io/cloud-builders/gcloud
  args: ['compute', 'instances', 'list']

and it works fine. Problem starts when I tried to save the output to a file


Trial 1: failed

- name: gcr.io/cloud-builders/gcloud
  args: ['compute', 'instances', 'list', '> gce-list.txt']

Trial 2: failed

- name: gcr.io/cloud-builders/gcloud
  args: ['compute', 'instances', 'list', '>', 'gce-list.txt']

Trial 3: failed

- name: gcr.io/cloud-builders/gcloud
  args: >
      compute instances list > gce-list.txt

Trial 4: failed

- name: gcr.io/cloud-builders/gcloud
  args: |
      compute instances list > gce-list.txt

UPDATE: 2018-09-04 17:50

Trial 5: failed

  1. Build an gcloud image based on ubuntu
  2. Used that image to run custom script file 'list-gce.sh'
  3. list-gce.sh calls gcloud compute instances list

For more details you can check this gist: https://gist.github.com/mahmoud-samy/e67f141e8b5d553de68a58a30a432ed2

Unfortunately I got this strange error:

rev 1

ERROR: (gcloud) unrecognized arguments: list (did you mean 'list'?)

rev 2

ERROR: (gcloud) unrecognized arguments: --version (did you mean '--version'?)

Any suggestions, or references?

Mahmoud Samy
  • 2,822
  • 7
  • 34
  • 78

2 Answers2

25

In addition to other answers, to do cmd > foo.txt, you need to override the build entrypoint to bash (or sh):

- name: gcr.io/cloud-builders/gcloud
  entrypoint: /bin/bash
  args: ['-c', 'gcloud compute instances list > gce-list.txt']
ahmet alp balkan
  • 42,679
  • 38
  • 138
  • 214
  • what to do when the container is built from scratch and doesn't have even bash or sh installed? Example case https://github.com/anchore/syft/blob/main/Dockerfile – Utkarsh Sharma Apr 14 '21 at 14:59
5

Those commands are not executed in a shell, so shell operations such as pipes (|) and redirections (>) are not available.


Workaround

Use a gcloud container which does have a shell. The gcr.io/cloud-builders/gcloud container should have bash, as it is ultimately derived from an Ubuntu 16.04 image.

In your Cloud Build task sequence, execute a shell script which performs the gcloud calls for you and redirects the output to a file. This has some observations:

  • You'll need to store the shell script somewhere sensible; probably in your source repository so it becomes available to the build.
  • The gcloud container can still be used, as this will ensure the Google Cloud SDK tools are available to your script. You will need to override the entrypoint in the Cloud Build manifest to be /bin/bash, or some other shell, and pass the path to your script as an argument.
  • As DazWilkin identifies in a comment, the Cloud Build service account will also require the compute.instances.list permission to list instances.

The /workspace directory is mounted into all Cloud Build containers and its contents will be persisted between and accessible from subsequent build steps. If the output of the gcloud command, or a post-processed version, is require by subsequent build steps, you can write it out here.

Relevant Google documentation.

Cosmic Ossifrage
  • 4,977
  • 29
  • 30
  • The Cloud Build service account will need `compute.instances.list` (`roles/compute.viewer`) and the build step will need to override `cloud-builders/gcloud` entrypoint with e.g. `/bin/bash` to get a shell. – DazWilkin Sep 04 '18 at 01:31
  • 1
    @DazWilkin I wasn't intending the answer to be a full step-by-step description, but those are good points and I'll edit accordingly. – Cosmic Ossifrage Sep 04 '18 at 09:05
  • Apologies. Your answer is good and comprehensive. I suspect the IAM change would have been unclear to other readers. – DazWilkin Sep 04 '18 at 14:51