Skip to content

Could not create parent directory for lock file when a non-root user #10

@markieww

Description

@markieww

How to run the image using a non-root user offline?

The previously downloaded already locally available gradle distribution (downloaded at the moment of building the https://github.com/docToolchain/docker-image/blob/master/alpine/Dockerfile) should be used.

Problem

I integrated this docker-image in my Jenkins-CI pipeline like this.

pipeline {

    agent {
        docker {
            image 'rdmueller/doctoolchain:rc-1.2.0'
        }
    }

    stages {
        stage ("Generate PDFs") {
            steps {
                sh "doctoolchain . generatePDF"
            }
        }
}

Which is equivalent to

#!/usr/bin/env bash
docker run --user jenkinbuilduser --rm -it --entrypoint /bin/bash -v ${PWD}:/project rdmueller/doctoolchain:rc-1.2.0 \
-c "doctoolchain . $1 $2 $3 $4 $5 $6 $7 $8 $9 -PinputPath=src/main/asciidoc -PmainConfigFile=config/docToolchain.groovy && exit"

or

#!/usr/bin/env bash
docker run --user 501 --rm -it --entrypoint /bin/bash -v ${PWD}:/project rdmueller/doctoolchain:rc-1.2.0 \
-c "doctoolchain . $1 $2 $3 $4 $5 $6 $7 $8 $9 -PinputPath=src/main/asciidoc -PmainConfigFile=config/docToolchain.groovy && exit"

from your documentation. Note the added option --user jenkinbuilduser and --user 501.

But this leads to exceptions like

Exception in thread "main" java.lang.RuntimeException: Could not create parent directory for lock file /docToolchain/?/.gradle/wrapper/dists/gradle-6.0.1-bin/1lxlpkiy24sb18odw96cp4ojv/gradle-6.0.1-bin.zip.lck
	at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:43)
	at org.gradle.wrapper.Install.createDist(Install.java:48)
	at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:107)
	at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:63)

My investigations showed that /root/.gradle (which holds the downloaded gradle distribution created by https://github.com/docToolchain/docker-image/blob/master/alpine/Dockerfile#L41) is not accessible by a non-root user like jenkinbuilduser. gradlew interprets it that no distribution is locally available and starts the download of the gradle distribution into /docToolchain/?/.gradle. This directory is read-only, which leads to the exception.

First workaround (non-working)

My first workaround was to run the image as user root.

pipeline {

    agent {
        docker {
            image 'rdmueller/doctoolchain:rc-1.2.0'
            args """-u root """
        }
    }

    stages {
        stage ("Generate PDFs") {
            steps {
                sh "doctoolchain . generatePDF"
            }
        }
}

Which is equivalent to

#!/usr/bin/env bash
docker run --rm -it --user root --entrypoint /bin/bash -v ${PWD}:/project rdmueller/doctoolchain:rc-1.2.0 \
-c "doctoolchain . $1 $2 $3 $4 $5 $6 $7 $8 $9 -PinputPath=src/main/asciidoc -PmainConfigFile=config/docToolchain.groovy && exit"

(Note the option --user root)

This way there is no exception, the generation works, but the generated file are owned by user root on the host file-system. This is not acceptable, because these files cannot be removed anymore (at least not by a next build steps within the build job. It can only be deleted manually by a fellow administrator with root-user rights)

Second workaround (partially working)

Set a non-root user and a rw-directory for the gradle distribution.

#!/usr/bin/env bash
docker run --user 501 -e GRADLE_USER_HOME='/project/.gradlecustom' --rm -it ---entrypoint /bin/bash -v ${PWD}:/project rdmueller/doctoolchain:rc-1.2.0 \
-c "doctoolchain . $1 $2 $3 $4 $5 $6 $7 $8 $9 -PinputPath=src/main/asciidoc -PmainConfigFile=config/docToolchain.groovy && exit"

gradlew will download a distribution to /project/.gradlecustom , the generation succeeds and the generated files are owned by a non-root user.

The problem: A buildjob should not have access to the internet.

The remaining problem

The issue is still remaining: How to run the image using a non-root user offline. The previously downloaded already locally available gradle distribution should be used.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions