Search code examples
concourseconcourse-git-resource

Is there a way to put a lock on Concourse git-resource?


I have setup pipeline in Concourse with some jobs that are building Docker images. After the build I push the image tag to the git repo. The problem is when the builds come to end at the same time, one jobs pushes to git, while the other just pulled, and when second job tries push to git it gets error.

error: failed to push some refs to '[email protected]:*****/*****'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

So is there any way to prevent concurrent push?

So far I've tried applying serial and serial_groups to jobs. It helps, but all the jobs got queued up, because we have a lot of builds.

I expect jobs to run concurrently and pause before doing operations to git if some other job have a lock on it.

resources:
- name: backend-helm-repo
  type: git
  source:
    branch: master
    paths:
    - helm
    uri: [email protected]:******/******
-...

jobs:

-...

- name: some-hidden-api-build
  serial: true
  serial_groups:
  - build-alone
  plan:
  - get: some-hidden-api-repo
    trigger: true
  - get: golang
  - task: build-image
    file: somefile.yaml
  - put: some-hidden-api-image
  - get: backend-helm-repo
  - task: update-helm-tag
    config:
      platform: linux
      image_resource:
        type: registry-image
        source:
          repository: mikefarah/yq
          tag: latest
      run:
        path: /bin/sh
        args:
        - -xce
        - "file manipulations && git commit"
      inputs:
      - name: some-hidden-api-repo
      - name: backend-helm-repo
      outputs:
      - name: backend-helm-tag-bump
  - put: backend-helm-repo
    params:
      repository: backend-helm-tag-bump
  - put: some-hidden-api-status
    params:
      commit: some-hidden-api-repo
      state: success


- name: some-other-build
  serial: true
  serial_groups:
  - build-alone
  plan:
  - get: some-other-repo
    trigger: true
  - get: golang
  - task: build-image
    file: somefile.yaml
  - put: some-other-image
  - get: backend-helm-repo
  - task: update-helm-tag
    config:
      platform: linux
      image_resource:
        type: registry-image
        source:
          repository: mikefarah/yq
          tag: latest
      run:
        path: /bin/sh
        args:
        - -xce
        - "file manipulations && git commit"
      inputs:
      - name: some-other-repo
      - name: backend-helm-repo
      outputs:
      - name: backend-helm-tag-bump
  - put: backend-helm-repo
    params:
      repository: backend-helm-tag-bump
  - put: some-other-status
    params:
      commit: some-other-repo
      state: success

-...

So if jobs come finish image build at the same time and make git commit in parallel, one pushes faster, than second one, second one breaks.

Can someone help?


Solution

  • note that your description is too vague to give detailed answer.

    I expect jobs to concurrently and stop before pushing to git if some other job have a lock on git.

    This will not be enough, if they stop just before pushing, they are already referencing a git commit, which will become stale when the lock is released by the other job :-)

    The jobs would have to stop, waiting on the lock, before cloning the git repo, so at the very beginning.

    All this is speculation on my part, since again it is not clear what you want to do, for these kind of questions posting a as-small-as-possible pipeline image and as-small-as-possible configuration code is helpful.

    You can consider https://github.com/concourse/pool-resource as locking mechanism.