0

I have the following yaml file

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-backend
  labels:
    app: app-backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-backend
  template:
    metadata:
      labels:
        app: app-backend
    spec:
      serviceAccountName: app
#      securityContext:
#          fsGroup: 1001090001        
      containers:
      - name: app-backend
        image: registry/import-proj/app_backend:dc47096c66513dc252b21398e0307efd021c7c8e
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: app-backend
        - secretRef:
            name: dbsecret
  strategy:
    type: Recreate                 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-frontend
  labels:
    app: app-frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-frontend
  template:
    metadata:
      labels:
        app: app-frontend
    spec:
      serviceAccountName: app
#      securityContext:
#          fsGroup: 1001090002    
      containers:
      - name: app-frontend
        image: registry/import-proj/app_frontend:c6e525b71e5c9480330431e55418ff15dcbe4f36
        ports:
        - containerPort: 3000

I am trying to use yq to replace the tag c6e525b71e5c9480330431e55418ff15dcbe4f36 of app_frontend.

My command is the following -

yq eval-all -i 'select(.kind == "Deployment" and .metadata.name == "app-frontend") | .spec.template.spec.containers[] |= (select(.name == "app-frontend") | .image |= sub(":.*", ":new-tag"))' try.yaml

The problem is, the backend part is completely gone after replacement. I have tried using yq eval-all -i [] .|select(.. I cannot understand where the problem is.

1 Answer 1

0

Using the pipe in select(…) | .spec.template.spec.containers[] changes the primary context, and makes only the latter part being the LHS of the following update |=. Solution: Don't use it, just continue with the traversal after the selection, making all of it a single expression on the LHS of the update:

select(…).spec.template.spec.containers[] |= (…)

Alternatively, if you actually do need that pipe (because you just over-simplified this sample data, inadvertently rendering it dispensable), use parens to combine selection and traversal into one expression on the LHS of the update:

(select(…) | … | .spec.template.spec.containers[]) |= (…)

Tested with mikefarah/yq version v4.35.1

Note that, at least with this sample input, you don't need the ea command. e does the job as well (and can even be omitted since version 4.18.1).

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you, that works! I have noticed although, that yq adds blank lines between comments and also messes up the indentation. For me, it adds an extra column for all the subsequent lines after "containers". How can I avoid this? I am using docker image yq:4.40.5
@user2179627 Can't reproduce this (using plain yq without docker). Does this happen on your end only with your production data or also with the given sample data (in which case you'd need to improve it to fail the same way). As a shot in the dark, I further simplified your filter, and added everything but the substitution to the LHS: (select(.kind == "Deployment" and .metadata.name == "app-frontend").spec.template.spec.containers[] | select(.name == "app-frontend").image) |= sub(":.*", ":new-tag")
I tried this with a normal installation on my machine on windows (using exe) the problem is here as well. I will try with the version you have 4.35.1 and see if it works.
I tried it with previous versions, the problem still exists with the indentation. :-/
As for the indentation: The YAML specs require "more indentation" for subordinate (block-styled) entities (i.e. the child list's dashes have to be indented more than the parent map's key), and yq simply rectifies your input in this regard. Simple example: yq -n '{"key":[1,2,3]}'. Other YAML processors (tested kislyuk/yq and itchyny/gojq) behave the same. As for the blank lines (which I can't reproduce), maybe you have set a default styling somewhere. Try removing it with yq '... style=""' (to see a difference, also try "flow" or "tagged" instead of "")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.