Skip to content
Permalink
Browse files

Merge pull request #107 from abayer/jenkins-41668

[FIXED JENKINS-41668] Add "dir" option for Dockerfile.
  • Loading branch information
abayer committed Feb 15, 2017
2 parents 7f851e9 + 82f83dd commit 3aa4358e5d5369d2d01282d5add5934ab5a5a835
@@ -588,6 +588,13 @@ class ModelValidatorImpl implements ModelValidator {
}
}
map.variables.each { k, v ->
// TODO: JENKINS-41746 - get rid of this hardcoding and use extensible validation instead once we can
if (typeName == "dockerfile") {
if (k.key == "filename" && (v.toGroovy().contains("/") || v.toGroovy().contains("\\"))) {
errorCollector.error(k, Messages.ModelValidatorImpl_DirSeparatorInDockerfileName())
valid = false
}
}
// Make sure we don't actually include "context" in the valid param names, since, well, it's
// not really one.
List<String> validParamNames = model.parameters.collect { it.name }.findAll { it != "context" }
@@ -25,6 +25,8 @@
package org.jenkinsci.plugins.pipeline.modeldefinition.agent.impl;

import hudson.Extension;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.Symbol;
import org.jenkinsci.plugins.pipeline.modeldefinition.agent.AbstractDockerAgent;
import org.jenkinsci.plugins.pipeline.modeldefinition.agent.DeclarativeAgent;
@@ -38,12 +40,13 @@

public class DockerPipelineFromDockerfile extends AbstractDockerAgent<DockerPipelineFromDockerfile> {
private String filename;
private String dir;

@DataBoundConstructor
public DockerPipelineFromDockerfile() {
}

public @Nonnull Object getFilename() {
public Object getFilename() {
return filename;
}

@@ -52,6 +55,36 @@ public void setFilename(String filename) {
this.filename = filename;
}

public String getDir() {
return dir;
}

@DataBoundSetter
public void setDir(String dir) {
this.dir = dir;
}

@Nonnull
public String getActualDir() {
if (!StringUtils.isEmpty(dir)) {
return dir;
} else {
return ".";
}
}

@Nonnull
public String getDockerfilePath() {
StringBuilder fullPath = new StringBuilder();
if (!StringUtils.isEmpty(dir)) {
fullPath.append(dir);
fullPath.append(IOUtils.DIR_SEPARATOR);
}
fullPath.append(getDockerfileAsString());
return fullPath.toString();
}

@Nonnull
public String getDockerfileAsString() {
if (filename != null) {
return filename;
@@ -119,4 +119,5 @@ ModelValidatorImpl.InvalidAgentParameter=Invalid config option "{0}" for agent t
ModelValidatorImpl.UnknownWhenConditional=Unknown conditional {0}. Valid conditionals are: {1}
ModelValidatorImpl.MultipleAgentParameters=Multiple parameters are required for agent type "{0}" - {1}. Please use a block instead.
ModelValidatorImpl.InvalidIdentifierInEnv="{0}" is not a valid identifier and cannot be used for an environment variable.
ModelValidatorImpl.DirSeparatorInDockerfileName=Dockerfile filename cannot contain directory separators.
ModelInterpreter.NoNodeContext=Attempted to execute a step that requires a node context while 'agent none' was specified. Be sure to specify your own 'node { ... }' blocks when using 'agent none'.
@@ -75,11 +75,13 @@ public class DockerPipelineFromDockerfileScript extends AbstractDockerPipelineSc
private Closure buildImage() {
return {
try {
def hash = Utils.stringToSHA1(script.readFile(describable.getDockerfileAsString()))
def hash = Utils.stringToSHA1(script.readFile("${describable.getDockerfilePath()}"))
def imgName = "${hash}"
return script.getProperty("docker").build(imgName, "-f ${describable.getDockerfileAsString()} .")
script.sh "docker build -t ${imgName} -f \"${describable.getDockerfilePath()}\" \"${describable.getActualDir()}\""
script.dockerFingerprintFrom dockerfile: describable.dockerfilePath, image: imgName, toolName: script.env.DOCKER_TOOL_NAME
return script.getProperty("docker").image(imgName)
} catch (FileNotFoundException f) {
script.error("No Dockerfile found at root of repository - failing.")
script.error("No Dockerfile found at ${describable.getDockerfilePath()} in repository - failing.")
return null
}
}
@@ -163,6 +163,26 @@ public void fromDockerfile() throws Exception {
.go();
}

@Issue("JENKINS-41668")
@Test
public void fromDockerfileInOtherDir() throws Exception {
assumeDocker();
// Bind mounting /var on OS X doesn't work at the moment
onAllowedOS(PossibleOS.LINUX);

sampleRepo.write("subdir/Dockerfile", "FROM ubuntu:14.04\n\nRUN echo 'HI THERE' > /hi-there\n\n");
sampleRepo.git("init");
sampleRepo.git("add", "subdir/Dockerfile");
sampleRepo.git("commit", "--message=Dockerfile");

expect("fromDockerfileInOtherDir")
.logContains("[Pipeline] { (foo)",
"The answer is 42",
"-v /tmp:/tmp -p 8000:8000",
"HI THERE")
.go();
}

@Test
public void fromDockerfileNoArgs() throws Exception {
assumeDocker();
@@ -484,6 +484,14 @@ public void notificationsSectionRemoved() throws Exception {
.go();
}

@Issue("JENKINS-41668")
@Test
public void dirSepInDockerfileName() throws Exception {
expectError("dirSepInDockerfileName")
.logContains(Messages.ModelValidatorImpl_DirSeparatorInDockerfileName())
.go();
}

@Issue("JENKINS-39799")
@Test
public void badPostContent() throws Exception {
@@ -0,0 +1,43 @@
/*
* The MIT License
*
* Copyright (c) 2017, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

pipeline {
agent {
dockerfile {
filename "Dockerfile/alternate"
args "-v /tmp:/tmp -p 8000:8000"
}
}
stages {
stage("foo") {
steps {
sh 'cat /hi-there'
sh 'echo "The answer is 42"'
}
}
}
}



@@ -0,0 +1,43 @@
/*
* The MIT License
*
* Copyright (c) 2017, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

pipeline {
agent {
dockerfile {
args "-v /tmp:/tmp -p 8000:8000"
dir "subdir"
}
}
stages {
stage("foo") {
steps {
sh 'cat /hi-there'
sh 'echo "The answer is 42"'
}
}
}
}



0 comments on commit 3aa4358

Please sign in to comment.
You can’t perform that action at this time.