Skip to content

Mark project working directory as safe for Git

Tomasz Maczukin requested to merge mark-project-directory-as-safe-for-git into main

What does this MR do?

Calls git config --global --add safe.directory $CI_PROJECT_DIR when preparing the Git fetch command environment.

Why was this MR needed?

As described in gitlab#368133 (closed) and at !3533 (comment 1034686184), with newer Git versions there is a possibility that job will fail because of mixed files ownership.

Currently known case requires:

  1. Docker or Docker Machine executor to be used.
  2. Executor to be configured in a way that it persist working directory for future jobs.
  3. FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR=true to be set.
  4. A job using container running in an UID!=0 scope to be executed at some time.

In this case some (all) of the files already existing in the persisted working directory will be owned by a non root user. When another job will be started and will re-use the persisted working directory, when predefined container (which in most cases is based on the helper image that GitLab provides and uses root user scope) executes the Git fetch operation, it will fail with:

fatal: unsafe repository ('/builds/rPrca3qv/0/group/project' is owned by someone else)
To add an exception for this directory, call:
	git config --global --add safe.directory /builds/rPrca3qv/0/group/project

This MR uses the solution proposed in this error message. It marks the working directory as safe.directory for Git, which allows it to proceed. The existing feature enabled with the FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR feature flag will then make sure that after Git sources are updated and cache/artifact files are downloaded, all files will be set to be owned by the current job container's user. !3533 (closed) will also make sure that this is done even when the job container is running in the root scope.

What's the best way to test this MR?

  1. Setup a project runner and make sure that it's the only runner available in the test project.

  2. Setup the Runner with docker executor. Set concurrent=1.

  3. In the test project define this simple CI/CD Pipeline:

    stages:
    - one
    - two
    
    variables:
      FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR: "true"
    
    one:
      stage: one
      image: raesene/alpine-noroot-containertools:latest
      script:
      - echo "Hello"
    
    two:
      stage: two
      image: alpine:latest
      script:
      - echo "World"
  4. Start the pipeline and execute it with your local Runner. The two job should fail with the Git error mentioned above.

  5. Compile/Download the runner version with this MR changes

  6. Restart the runner and run the pipeline again - it should pass.

What are the relevant issue numbers?

Fixes:

Edited by Darren Eastman

Merge request reports