2

I am trying to set up my Jenkins pipeline using this docker image. It requires to be executed as following:

docker run --rm \
  -v $PROJECT_DIR:/input \
  -v $PROJECT_DIR:/output \
  -e PLATFORM_ID=$PLATFORM_ID \
  particle/buildpack-particle-firmware:$VERSION

The implementation in my Jenkins pipeline looks like this:

stage('build firmware') {
  agent { 
      docker { 
        image 'particle/buildpack-particle-firmware:4.0.2-tracker' 
        args '-v application:/input -v application:/output -e PLATFORM_ID=26 particle/buildpack-particle-firmware:4.0.2-tracker'    
      }
   }
   steps {
      archiveArtifacts artifacts: 'application/target/*.bin', fingerprint: true, onlyIfSuccessful: true
   }
}

Executing this on my PC system works just fine. Upon executing the Jenkins pipeline, I am eventually getting this error:

java.io.IOException: Failed to run image 'particle/buildpack-particle-firmware:4.0.2-tracker'. Error: docker: Error response from daemon: failed to create shim: OCI runtime create failed: runc create failed: unable to start container process: exec: "-w": executable file not found in $PATH: unknown.

I read through the documentation of Jenkins + Docker, but I couldn't find out how to use such an image. All the guides usually explain how to run a docker image and execute shell commands.

If I get it right, this Dockerfile is the layout for the said docker image.

How do I get around this issue and call a docker container with run arguments?

STerliakov
  • 4,983
  • 3
  • 15
  • 37
extraj
  • 41
  • 3

2 Answers2

2

The agent mode is intended if you want run Jenkins build steps inside a container; in your example, run the archiveArtifacts step instead of the thing the container normally does. You can imagine using an image that only contains a build tool, like golang or one of the Java images, in the agent { docker { image } } line, and Jenkins will inject several lines of docker command-line options so that it runs against the workspace tree.

The Jenkins Docker interface may not have a built-in way to wait for a container to complete. Instead, you can launch a "sidecar" container, then run docker wait still from outside the container to wait for it to complete. This would roughly look like

stage('build firmware') {
  steps {
    docker
      .image('particle/buildpack-particle-firmware:4.0.2-tracker')
      .withRun('-v application:/input -v application:/output -e PLATFORM_ID=26 particle/buildpack-particle-firmware:4.0.2-tracker') { c ->
        sh "docker wait ${c.id}"
    }
    archiveArtifacts artifacts: 'application/target/*.bin', fingerprint: true, onlyIfSuccessful: true
  }
}
David Maze
  • 130,717
  • 29
  • 175
  • 215
0

In the end, it is up to Jenkins how the docker run command is executed and which entrypoint is taken. Unfortunately, I can't change the settings of the Jenkins Server so I had to find a workaround.

The solution for me is similar to my initial approach and looks like this:

agent { 
    docker { 
        image 'particle/buildpack-hal'
    }
}
environment {
    APPDIR="$WORKSPACE/tracker-edge"
    DEVICE_OS_PATH="$WORKSPACE/device-os"
    PLATFORM_ID="26"
}
steps {             
    sh 'make sanitize -s'
}

One guess is that calling the docker container as expected doesn't work on my Jenkins Server. It requires to be run and shell commands to be executed from within.

extraj
  • 41
  • 3