Skip to content

Commit c7ceba4

Browse files
author
Christoph Linder
committed
JENKINS-46105 Docker 17.05 ARG in FROM breaks docker inspect (adhere to coding standards)
1 parent 35caf3f commit c7ceba4

File tree

3 files changed

+98
-95
lines changed

3 files changed

+98
-95
lines changed

.editorconfig

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 4
9+
10+
[Makefile]
11+
indent_style = tab
12+
indent_size = 4

src/main/java/org/jenkinsci/plugins/docker/workflow/DockerUtils.java

+37-39
Original file line numberDiff line numberDiff line change
@@ -32,53 +32,51 @@
3232
import org.apache.tools.ant.types.Commandline;
3333

3434
public final class DockerUtils {
35-
private DockerUtils() {
36-
// utility class
37-
}
35+
private DockerUtils() {
36+
// utility class
37+
}
3838

39-
public static Map<String, String> parseBuildArgs(String commandLine) {
40-
// this also accounts for quote, escapes, ...
41-
Commandline parsed = new Commandline(commandLine);
42-
Map<String, String> result = new HashMap<>();
39+
public static Map<String, String> parseBuildArgs(String commandLine) {
40+
// this also accounts for quote, escapes, ...
41+
Commandline parsed = new Commandline(commandLine);
42+
Map<String, String> result = new HashMap<>();
4343

44-
String[] arguments = parsed.getArguments();
45-
for (int i = 0; i < arguments.length; i++) {
46-
String arg = arguments[i];
47-
if (arg.equals("--build-arg")) {
48-
if (arguments.length < i + 1) {
49-
throw new IllegalArgumentException(
50-
"Missing parameter for --build-arg: " + commandLine);
51-
}
52-
String keyVal = arguments[i+1];
44+
String[] arguments = parsed.getArguments();
45+
for (int i = 0; i < arguments.length; i++) {
46+
String arg = arguments[i];
47+
if (arg.equals("--build-arg")) {
48+
if (arguments.length < i + 1) {
49+
throw new IllegalArgumentException("Missing parameter for --build-arg: " + commandLine);
50+
}
51+
String keyVal = arguments[i+1];
5352

54-
String parts[] = keyVal.split("=", 2);
55-
if (parts.length != 2) {
56-
throw new IllegalArgumentException("Illegal syntax for --build-arg " + keyVal + ", need KEY=VALUE");
57-
}
58-
String key = parts[0];
59-
String value = parts[1];
53+
String parts[] = keyVal.split("=", 2);
54+
if (parts.length != 2) {
55+
throw new IllegalArgumentException("Illegal syntax for --build-arg " + keyVal + ", need KEY=VALUE");
56+
}
57+
String key = parts[0];
58+
String value = parts[1];
6059

61-
result.put(key, value);
62-
}
63-
}
60+
result.put(key, value);
61+
}
62+
}
6463

65-
return result;
66-
}
64+
return result;
65+
}
6766

68-
public static SimpleEntry<String, String> splitArgs(String argString) {
69-
//TODO: support complex single/double quotation marks
70-
Pattern p = Pattern.compile("^['\"]?(\\w+)=(.*?)['\"]?$");
67+
public static SimpleEntry<String, String> splitArgs(String argString) {
68+
//TODO: support complex single/double quotation marks
69+
Pattern p = Pattern.compile("^['\"]?(\\w+)=(.*?)['\"]?$");
7170

72-
Matcher matcher = p.matcher(argString.trim());
73-
if (!matcher.matches()) {
74-
throw new IllegalArgumentException("Illegal --build-arg parameter syntax: " + argString);
75-
}
71+
Matcher matcher = p.matcher(argString.trim());
72+
if (!matcher.matches()) {
73+
throw new IllegalArgumentException("Illegal --build-arg parameter syntax: " + argString);
74+
}
7675

77-
String key = matcher.group(1);
78-
String value = matcher.group(2);
79-
80-
return new SimpleEntry<>(key, value);
81-
}
76+
String key = matcher.group(1);
77+
String value = matcher.group(2);
8278

79+
return new SimpleEntry<>(key, value);
80+
}
8381

8482
}

src/test/java/org/jenkinsci/plugins/docker/workflow/FromFingerprintStepTest.java

+49-56
Original file line numberDiff line numberDiff line change
@@ -42,70 +42,63 @@
4242
import static org.junit.Assert.assertNotNull;
4343

4444
public class FromFingerprintStepTest {
45-
@Rule
46-
public RestartableJenkinsRule story = new RestartableJenkinsRule();
45+
@Rule public RestartableJenkinsRule story = new RestartableJenkinsRule();
4746

48-
/**
49-
* Test quotation marks in --build-arg parameters
50-
*/
51-
@Test
52-
public void buildWithFROMArgs()
53-
throws Exception {
47+
/**
48+
* Test quotation marks in --build-arg parameters
49+
*/
50+
@Test public void buildWithFROMArgs() throws Exception {
51+
assertBuild("prj-simple",
52+
script("--build-arg IMAGE_TO_UPDATE=hello-world:latest"));
5453

55-
assertBuild("prj-simple",
56-
script("--build-arg IMAGE_TO_UPDATE=hello-world:latest"));
54+
assertBuild("prj-singlequotes-in-build-arg---aroundValue",
55+
script("--build-arg IMAGE_TO_UPDATE=\\'hello-world:latest\\'"));
5756

58-
assertBuild("prj-singlequotes-in-build-arg---aroundValue",
59-
script("--build-arg IMAGE_TO_UPDATE=\\'hello-world:latest\\'"));
57+
assertBuild("prj-dobulequotes-in-build-arg---aroundValue",
58+
script("--build-arg IMAGE_TO_UPDATE=\"hello-world:latest\""));
6059

61-
assertBuild("prj-dobulequotes-in-build-arg---aroundValue",
62-
script("--build-arg IMAGE_TO_UPDATE=\"hello-world:latest\""));
60+
assertBuild("prj-singlequotes-in-build-arg---aroundAll",
61+
script("--build-arg \\'IMAGE_TO_UPDATE=hello-world:latest\\'"));
6362

64-
assertBuild("prj-singlequotes-in-build-arg---aroundAll",
65-
script("--build-arg \\'IMAGE_TO_UPDATE=hello-world:latest\\'"));
63+
assertBuild("prj-doublequotes-in-build-arg---aroundAll",
64+
script("--build-arg \"IMAGE_TO_UPDATE=hello-world:latest\""));
65+
}
6666

67-
assertBuild("prj-doublequotes-in-build-arg---aroundAll",
68-
script("--build-arg \"IMAGE_TO_UPDATE=hello-world:latest\""));
69-
}
67+
private static String script(String buildArg) {
68+
String dockerfile = "" +
69+
"ARG IMAGE_TO_UPDATE\\n" +
70+
"FROM ${IMAGE_TO_UPDATE}\\n";
71+
String fullBuildArgs = buildArg + " buildWithFROMArgs";
7072

71-
private static String script(String buildArg) {
72-
String dockerfile = ""
73-
+ "ARG IMAGE_TO_UPDATE\\n"
74-
+ "FROM ${IMAGE_TO_UPDATE}\\n";
75-
String fullBuildArgs = buildArg + " buildWithFROMArgs";
73+
String script = "node {\n" +
74+
" sh 'mkdir buildWithFROMArgs'\n" +
75+
" writeFile file: 'buildWithFROMArgs/Dockerfile', text: '" + dockerfile + "'\n" +
76+
" def built = docker.build 'from-with-arg', '" + fullBuildArgs + "'\n" +
77+
" echo \"built ${built.id}\"\n" +
78+
"}";
7679

77-
String script = "node {\n"
78-
+ " sh 'mkdir buildWithFROMArgs'\n"
79-
+ " writeFile file: 'buildWithFROMArgs/Dockerfile', text: '" + dockerfile + "'\n"
80-
+ " def built = docker.build 'from-with-arg', '" + fullBuildArgs + "'\n"
81-
+ " echo \"built ${built.id}\"\n"
82-
+ "}";
80+
return script;
81+
}
8382

84-
return script;
85-
}
83+
private void assertBuild(final String projectName, final String piplineCode) throws Exception {
84+
story.addStep(new Statement() {
85+
@Override
86+
public void evaluate() throws Throwable {
87+
assumeDocker();
8688

87-
private void assertBuild(final String projectName, final String piplineCode)
88-
throws Exception {
89-
story.addStep(new Statement() {
90-
@Override
91-
public void evaluate()
92-
throws Throwable {
93-
assumeDocker();
89+
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, projectName);
90+
p.setDefinition(new CpsFlowDefinition(piplineCode, true));
91+
WorkflowRun b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0));
92+
DockerClient client = new DockerClient(new LocalLauncher(StreamTaskListener.NULL), null, null);
93+
String ancestorImageId = client.inspect(new EnvVars(), "hello-world", ".Id");
94+
story.j.assertLogContains("built from-with-arg", b);
95+
story.j.assertLogContains(ancestorImageId.replaceFirst("^sha256:", "").substring(0, 12), b);
96+
Fingerprint f = DockerFingerprints.of(ancestorImageId);
97+
assertNotNull(f);
98+
DockerDescendantFingerprintFacet descendantFacet = f.getFacet(DockerDescendantFingerprintFacet.class);
99+
assertNotNull(descendantFacet);
100+
}
101+
});
102+
}
94103

95-
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, projectName);
96-
p.setDefinition(new CpsFlowDefinition(piplineCode, true));
97-
WorkflowRun b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0));
98-
DockerClient client = new DockerClient(new LocalLauncher(StreamTaskListener.NULL), null, null);
99-
String ancestorImageId = client.inspect(new EnvVars(), "hello-world", ".Id");
100-
story.j.assertLogContains("built from-with-arg", b);
101-
story.j.assertLogContains(ancestorImageId.replaceFirst("^sha256:", "").substring(0, 12), b);
102-
Fingerprint f = DockerFingerprints.of(ancestorImageId);
103-
assertNotNull(f);
104-
DockerDescendantFingerprintFacet descendantFacet = f.getFacet(
105-
DockerDescendantFingerprintFacet.class);
106-
assertNotNull(descendantFacet);
107-
}
108-
});
109-
}
110-
111-
}
104+
}

0 commit comments

Comments
 (0)