gitgcloudgithooksgoogle-cloud-buildcloudbuild.yaml

Google Cloud Build Doesn't Work Properly on Git Hooks


Im using gcloud and I have a git server on a vm, where in a repository through a git hook (post-receive), Im calling cloud build to triggers the construction of a docker image and the deployment of the image on kubernetes.

I already set the proper permission on the cloud build Service account to get access to the Container/Artifact Registry and another repository on Cloud Source Repositories which has the kubernetes manifests to deploy.

The problem is that this flow sometimes works and sometimes it doesn't and the logs give no indication of why it fails. If I compare the logs of a flow that did end well and a flow that didn't, they are identical, with the exception that one simply stops.

The script in the git hook who calls Cloud Build looks like this (This is inside of GCP vm):

#!/bin/bash

oldrev=$1
newrev=$2
refname=$3

BRANCH_REF=$(git rev-parse --symbolic --abbrev-ref $refname)
BASE_PATH="path/to/basepath"

build_image() {
    cd "$BASE_PATH"
    mkdir -p "build.tmp"
    cd "build.tmp"
    git clone --branch $BRANCH_REF --single-branch "/path/to/repo" "$NAME"
    # This directory contains the Dockerfile
    cd repo

    #
    # code the condition to call cloud build
    # through the commit message
    #

    if [[ $COMMIT_MSG =~ $pattern ]]; then
        nohup gcloud builds submit --log-http --config="/path/to/cloudbuild.yaml" --substitutions=_NAME="myproyect",_HASH=$HASH > "$BASE_PATH/build_log.txt" 2>&1 &
    fi
}

And this is what it looks the cloudbuild yaml

# This step builds the container image and pushes the image to Conteiner Registry
steps:
- name: 'gcr.io/cloud-builders/docker'
  id: Build
  args: [ 'build', '-t', 'gcr.io/cloud-builders/${_NAME}:docker-${_HASH}', '-t', 'gcr.io/cloud-builders/${_NAME}:latest', '.' ]

# This step clones the kubernetes google repository
- name: 'gcr.io/cloud-builders/gcloud'
  id: Clone env repository
  entrypoint: /bin/sh
  args:
  - '-c'
  - |
    gcloud source repos clone kubernetes_manifests && \
    cd kubernetes_manifests && \
    git config user.email $(gcloud auth list --filter=status:ACTIVE --format='value(account)')

# This step generates the new manifest
- name: 'gcr.io/cloud-builders/gcloud'
  id: Generate manifest
  entrypoint: /bin/sh
  args:
  - '-c'
  - |
    sed -e "s#image: gcr.io/cloud-builders/myproyect:.*#image: gcr.io/cloud-builders/${_NAME}:docker-${_HASH}#" kubernetes_manifests/myproyect/development/3.deployment.yaml > kubernetes_manifests/myproyect/development/3.deployment.yaml.tmp && \
    mv kubernetes_manifests/myproyect/development/3.deployment.yaml.tmp kubernetes_manifests/myproyect/development/3.deployment.yaml

# This step pushes the manifest back to kubernetes
- name: 'gcr.io/cloud-builders/gcloud'
  id: Push manifest
  entrypoint: /bin/sh
  args:
  - '-c'
  - |
    set -x && \
    cd kubernetes_manifests && \
    git add myproyect/development/3.deployment.yaml && \
    git commit -m "Update image gcr.io/cloud-builders/${_NAME}:${_HASH}
    Built from commit ${_HASH} of repository ${_NAME}" --author="Cloud Build Agent" && \
    git push origin master

# This step deploys the new version of our container image
- name: 'gcr.io/cloud-builders/kubectl'
  id: Deploy
  args:
  - 'apply'
  - '-f'
  - 'kubernetes_manifests/myproyect/development/3.deployment.yaml'
  env:
  - 'CLOUDSDK_COMPUTE_REGION=us-central1-f'
  - 'CLOUDSDK_CONTAINER_CLUSTER=k8-myproyect'
  - 'CLOUDSDK_CORE_PROJECT=cloud-builders'

timeout: 43200s
options:
 machineType: 'N1_HIGHCPU_8'
 logging: CLOUD_LOGGING_ONLY
substitutions:
 _NAME: 'myproyect' # default value
 _HASH: 'latest' # default value
images:
- 'gcr.io/cloud-builders/${_NAME}:docker-${_HASH}'
- 'gcr.io/cloud-builders/${_NAME}:latest'

Like I said, sometimes it works and sometimes it doesn't, I don't understand why. I hope someone can point me in the right direction to resolve this issue.

In case it's worth anything this is the last request in the log when it fails/stop

==== request start ====
uri: https://storage.googleapis.com/storage/v1/b?alt=json&maxResults=1000&prefix=myproyect_cloudbuild&project=myProyect
method: GET
== headers start ==
b'accept': b'application/json'
b'accept-encoding': b'gzip, deflate'
b'authorization': --- Token Redacted ---
b'content-length': b'0'
b'user-agent': b'google-cloud-sdk gcloud/445.0.0 command/gcloud.builds.submit invocation-id/6aa15f12724940dea7fc6bc4a244eac9 environment/GCE environment-version/None client-os/LINUX client-os-ver/5.15.0 client-pltf-arch/x86_64 interactive/False from-script/False python/3.9.16 term/ (Linux 5.15.0-1038-gcp)'
b'x-goog-api-client': b'cred-type/mds'
== headers end ==
== body start ==

== body end ==
==== request end ====
---- response start ----
status: 200
-- headers start --
Cache-Control: private, max-age=0, must-revalidate, no-transform
Content-Length: 789
Content-Type: application/json; charset=UTF-8
Date: Tue, 12 Sep 2023 17:30:52 GMT
Expires: Tue, 12 Sep 2023 17:30:52 GMT
Server: UploadServer
Vary: Origin, X-Origin
X-GUploader-UploadID: ADPycdtf0wrEzjksupKzYNSnqtRqv9z93lIEVFhG0tjpoxELV-WkCSmlW4YPMl8idPfG194FtutaWllo37PMhVYmcrk0rg
-- headers end --
-- body start --
{
  "kind": "storage#buckets",
  "items": [
    {
      "kind": "storage#bucket",
      "selfLink": "https://www.googleapis.com/storage/v1/b/myproyect_cloudbuild",
      "id": "myproyect_cloudbuild",
      "name": "myproyect_cloudbuild",
      "projectNumber": "249995562558",
      "metageneration": "1",
      "location": "US",
      "storageClass": "STANDARD",
      "etag": "CAE=",
      "timeCreated": "2023-06-13T00:53:30.886Z",
      "updated": "2023-06-13T00:53:30.886Z",
      "iamConfiguration": {
        "bucketPolicyOnly": {
          "enabled": false
        },
        "uniformBucketLevelAccess": {
          "enabled": false
        },
        "publicAccessPrevention": "inherited"
      },
      "locationType": "multi-region",
      "rpo": "DEFAULT"
    }
  ]
}

-- body end --
total round trip time (request+response): 0.074 secs
---- response end ----
----------------------

Solution

  • Basically my mistake was trying to run the cloud build command in the background, the solution was to use the async option from gcloud builds submit

    gcloud builds submit --async --config="/path/to/cloudbuild.yaml" --substitutions=_NAME="myproyect",_HASH=$HASH

    instead of this

    nohup gcloud builds submit .... etc