web-dev-qa-db-fra.com

Comment définir un environnement ou une variable de substitution via une étape dans Google Cloud Build?

Fondamentalement, lorsque j'utilise Google Cloud Build, comment lire une valeur qui a été écrite lors d'une étape de build précédente dans les étapes suivantes?

Plus précisément, je voudrais créer une balise d'image personnalisée basée sur une combinaison de l'horodatage et de $ SHORT_SHA. Quelque chose comme ci-dessous. Cependant, cela ne fonctionne pas, car Docker se plaint de "l'exportation", et, même si cela a fonctionné, ce sera probablement un environnement différent:

  # Setting tag in a variable:
  - name: 'ubuntu'
    args: ['export', '_BUILD_TAG=`date', '-u', '+%Y%m%dT%H%M%S_$SHORT_SHA`']

Ensuite, dans une étape ultérieure:

  # Using tag from the variable:
  - name: gcr.io/cloud-builders/docker
    args: ['build', '-t', 'gcr.io/$PROJECT_ID/$_BUILD_TAG', '.']

Alors, comment puis-je utiliser la sortie d'une étape dans une autre? Je pourrais écrire le contenu de date dans un fichier, puis le lire, mais je ne sais plus comment définir la variable à partir du fichier que j'ai lu (ou autrement interpoler ses résultats pour former l'argument à construction de docker).

9
JJC

Je n'ai jamais trouvé de moyen de définir une variable d'environnement dans une étape de construction qui peut être lue dans d'autres étapes, mais j'ai fini par obtenir le même effet en s'appuyant sur la réponse de Konstantin de la manière suivante:

Dans une première étape, je génère et écris ma balise basée sur la date dans un fichier. Le système de fichiers (/ workspace) est conservé entre les étapes et sert de stockage de ma variable d'environnement. Ensuite, à chaque étape dont j'ai besoin pour référencer cette valeur, je cat ce fichier en place. L'astuce consiste à utiliser sh ou bash comme point d'entrée dans chaque conteneur afin que le sous-shell qui lit à partir du fichier puisse s'exécuter.

Voici un exemple:

## Set build tag and write to file _TAG
- name: 'ubuntu'
  args: ['bash', '-c', 'date -u +%Y%m%dT%H%M_$SHORT_SHA > _TAG']

...

# Using the _TAG during Docker build:
- name: gcr.io/cloud-builders/docker
entrypoint: sh
args: ['-c', 'docker build -t gcr.io/$PROJECT_ID/image_name:$(cat _TAG) .']

Une mise en garde à noter est que si vous effectuez l'interpolation bash de cette manière dans, disons, un objet JSON ou quelque chose qui nécessite des guillemets doubles, vous devez que l'appel de sous-shell ne soit jamais entouré de guillemets simples lorsqu'il est exécuté dans le conteneur, seulement double , ce qui peut nécessiter l'échappement des guillemets internes pour créer l'objet JSON. Voici un exemple où je corrige la configuration de kubernetes en utilisant la valeur du fichier _TAG pour déployer l'image nouvellement créée:

- name: gcr.io/cloud-builders/kubectl
entrypoint: bash
args: ['-c', 'gcloud container clusters get-credentials --zone $$CLOUDSDK_COMPUTE_ZONE $$CLOUDSDK_CONTAINER_CLUSTER ; kubectl patch deployment deployment_name -n mynamespace -p "{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"image_name\",\"image\":\"gcr.io/$PROJECT_ID/image_name:$(cat _TAG)\"}]}}}}}"']
env:
- 'CLOUDSDK_COMPUTE_ZONE=us-central1-b'
- 'CLOUDSDK_CONTAINER_CLUSTER=my-google-proj-cluster-name'
8
JJC
- name: gcr.io/cloud-builders/docker
  entrypoint: sh
  args
    - '-c'
    - 'docker build -t gcr.io/$PROJECT_ID/$(date -u +%Y%m%dT%H%M%S_$SHORT_SHA) .'
3
Konstantin Tarkus

Bien que cela ne résout pas votre problème, je voulais publier cette réponse car la première phrase de votre question est: " Fondamentalement, lorsque j'utilise Google Cloud Build, comment lire une valeur qui a été écrit dans une étape de construction antérieure dans les étapes suivantes? ". Voilà comment vous procéderiez.

De la documentation officielle :

Un volume est un conteneur Docker qui est monté dans les étapes de génération pour conserver les fichiers à travers les étapes de génération. Lorsque Cloud Build exécute une étape de génération, il monte automatiquement un volume d'espace de travail dans/workspace. Vous pouvez spécifier des volumes supplémentaires à monter dans les conteneurs de vos étapes de génération à l'aide du champ volumes de vos étapes.

Voici un exemple implémenté par quelqu'un qui a posé cette question dans un problème github , mais pour mettre la date dans le volume pour une lecture ultérieure par une autre étape:

steps:
- name: 'ubuntu'
  volumes:
  - name: 'vol1'
    path: '/persistent_volume'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
        date -u +%Y%m%dT%H%M_$SHORT_SHA > /persistent_volume/file
- name: 'gcr.io/cloud-builders/docker'
  volumes:
  - name: 'vol1'
    path: '/persistent_volume'
  args: ['run', '-v', 'vol1:/data', 'Alpine', 'cat', 'data/file']

Cependant, pour votre cas particulier, je voudrais simplement le marquer avec une commande de sous-shell comme c'est fait dans cette réponse ici :

$(date -u +%Y%m%dT%H%M%S_$SHORT_SHA)
1
Droogans

Vous n'avez pas besoin d'exporter ni de monter un volume dans votre boîtier.

steps:
- name: 'ubuntu'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
        printenv

- name: gcr.io/cloud-builders/docker
  entrypoint: 'bash'
  args:
  - '-c'
  - |
        printenv

Il produira

BUILD
Starting Step #0
Step #0: Pulling image: ubuntu
Step #0: Using default tag: latest
Step #0: latest: Pulling from library/ubuntu
Step #0: Digest: sha256:eb70667a801686f914408558660da753cde27192cd036148e58258819b927395
Step #0: Status: Downloaded newer image for ubuntu:latest
Step #0: HOSTNAME=XXXXXXXXXXX
Step #0: BUILDER_OUTPUT=/builder/outputs
Step #0: PWD=/workspace
Step #0: HOME=/builder/home
Step #0: SHLVL=1
Step #0: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Step #0: _=/usr/bin/printenv
Finished Step #0
Starting Step #1
Step #1: Already have image (with digest): gcr.io/cloud-builders/docker
Step #1: HOSTNAME=XXXXXXXXXXX
Step #1: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Step #1: PWD=/workspace
Step #1: SHLVL=1
Step #1: HOME=/builder/home
Step #1: DEBIAN_FRONTEND=noninteractive
Step #1: BUILDER_OUTPUT=/builder/outputs
Step #1: _=/usr/bin/printenv
Finished Step #1

Vous pouvez donc utiliser /workspace ou /builder/home, mais comme nous ne pouvons pas utiliser une variable autre que substitution définie sur le fichier yaml, puis les mettre comme script dans le référentiel comme ceci:

steps:
- name: 'ubuntu'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
        bash test.bash

- name: gcr.io/cloud-builders/docker
  entrypoint: 'bash'
  args:
  - '-c'
  - |
        bash result.bash

test.bash

#!/bin/bash
SHORT_SHA=myvar
date -u +%Y%m%dT%H%M_$SHORT_SHA > /workspace/myfile.txt

result.bash

#!/bin/bash
_BUILD_TAG=`cat /workspace/myfile.txt`
echo "the transferred value is: $_BUILD_TAG"

Production:

BUILD
Starting Step #0
Step #0: Pulling image: ubuntu
Step #0: Using default tag: latest
Step #0: latest: Pulling from library/ubuntu
Step #0: Digest: sha256:eb70667a801686f914408558660da753cde27192cd036148e58258819b927395
Step #0: Status: Downloaded newer image for ubuntu:latest
Finished Step #0
Starting Step #1
Step #1: Already have image (with digest): gcr.io/cloud-builders/docker
Step #1: the transferred value is: 20190708T1706_myvar
Finished Step #1
Push
DONE
0
Chetabahana