Home > front end >  gcloud command for bulk metadata update
gcloud command for bulk metadata update

Time:07-27

I am trying to craft a gcloud command that does a bulk metadata update on compute engine instances.

Normally I could just pipe gcloud compute instances list to xargs gcloud compute instances add-metadata. However, this is thwarted because for some inexplicable reason, add-metadata needs both an instance name, and a zone, even though compute instance names appear to be globally unique. So now I'm forced to try to shuttle both pieces of data (both name and zone) to the add-metadata command. If I don't provide both, I get:

ERROR: (gcloud.compute.instances.add-metadata) Underspecified resource [worker-1]. Specify the [--zone] flag.

I'm about ready to give up on the bash/xargs incantation and switch to python but I thought I'd check here first.

I have this command:

gcloud compute instances list \
        --filter="name~'worker' AND zone~'us-central1'" \
        --format 'value(name,zone)'

which returns something like:

worker-1    us-central1-c
worker-2    us-central1-c
worker-3    us-central1-c
worker-4    us-central1-c

I then need to pipe these into a command like:

gcloud compute instances add-metadata --zone=[zone goes here] --metadata myvalue=true [instance name goes here]

But this is proving tricky/annoying using xargs alone. Is there a better or simpler way to accomplish what I'm attempting?

CodePudding user response:

Pipe it to while read sequence:

gcloud compute instances list \
       --filter="name~'worker' AND zone~'us-central1'" \
       --format 'value(name,zone)' | \
while read instance zone; do
    gcloud compute instances add-metadata \
    --zone=$zone --metadata myvalue=true $instance
done

CodePudding user response:

You can wrap a sh "in the middle" to help with positional arguments. In your case you can run below CLI, noting that it'll echo the gcloud commands that it would run, then once comfortable with the resulting set of commands, either remove the echo there, or run the whole command |sh -x :

gcloud compute instances list \
        --filter="name~'worker' AND zone~'us-central1'" \
        --format 'value(name,zone)' |\
xargs -n2 sh -c \
'echo gcloud compute instances add-metadata --zone="$2" --metadata myvalue=true "$1"' --

The trick here is this CLI arrangement: xargs -n2 sh -c '... $1 ... $2' --

  • -n2 to let xargs pass in args in groups of two
  • sh -c '... $1 ... $2' -- as a mini scriptlet
  • Related