Skip to content

Commit 3037f90

Browse files
authored
BI-545 - Exception raised during download when 'java.io.tmpdir' is not defined (#418)
1 parent fa23cac commit 3037f90

File tree

7 files changed

+111
-22
lines changed

7 files changed

+111
-22
lines changed

Diff for: build-info-api/src/main/java/org/jfrog/build/api/util/CommonUtils.java

+36
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package org.jfrog.build.api.util;
22

3+
import org.apache.commons.io.FileUtils;
4+
import org.apache.commons.lang.StringUtils;
5+
import org.apache.commons.lang.SystemUtils;
6+
37
import java.io.BufferedWriter;
48
import java.io.File;
59
import java.io.IOException;
610
import java.nio.charset.Charset;
711
import java.nio.file.Files;
12+
import java.nio.file.Paths;
813
import java.util.*;
914
import java.util.function.Function;
1015
import java.util.function.Predicate;
@@ -152,4 +157,35 @@ public static <E> HashSet<E> newHashSet(E... elements) {
152157
public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
153158
return iterable == null ? Collections.emptyList() : iterable;
154159
}
160+
161+
/**
162+
* Handle 'java.io.tmpdir' system property.
163+
* If not defined in POSIX compliant systems - use '/tmp' folder.
164+
* If defined but directory does not exist - try to create it.
165+
*
166+
* @throws RuntimeException if 'java.io.tmpdir' property is missing in Windows or the path is not accessible.
167+
*/
168+
public static void handleJavaTmpdirProperty() {
169+
String tmpDirPath = FileUtils.getTempDirectoryPath();
170+
171+
if (StringUtils.isNotBlank(tmpDirPath)) {
172+
// java.io.tmpdir is defined.
173+
if (FileUtils.getTempDirectory().exists()) {
174+
return;
175+
}
176+
// java.io.tmpdir is defined, but the directory doesn't exist.
177+
try {
178+
Files.createDirectories(Paths.get(tmpDirPath));
179+
} catch (IOException e) {
180+
throw new RuntimeException("The directory defined by the system property 'java.io.tmpdir' (" + tmpDirPath + ") doesn't exit. " +
181+
"An attempt to create a directory in this path failed: ", e);
182+
}
183+
} else if (SystemUtils.IS_OS_UNIX) {
184+
// java.io.tmpdir is not defined and the OS is POSIX compliant system.
185+
System.setProperty("java.io.tmpdir", "/tmp");
186+
} else {
187+
// java.io.tmpdir is not defined and the OS is not POSIX compliant system.
188+
throw new RuntimeException("java.io.tmpdir system property is missing!");
189+
}
190+
}
155191
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package org.jfrog.build.api.util;
2+
3+
import org.apache.commons.lang.SystemUtils;
4+
import org.apache.commons.lang.exception.ExceptionUtils;
5+
import org.testng.annotations.AfterMethod;
6+
import org.testng.annotations.Test;
7+
8+
import java.io.IOException;
9+
import java.nio.file.Path;
10+
import java.nio.file.Paths;
11+
12+
import static org.jfrog.build.api.util.CommonUtils.handleJavaTmpdirProperty;
13+
import static org.testng.Assert.assertEquals;
14+
import static org.testng.Assert.assertThrows;
15+
import static org.testng.FileAssert.fail;
16+
17+
/**
18+
* @author yahavi
19+
**/
20+
@Test
21+
public class CreateTempDirTests {
22+
23+
private static final String JAVA_IO_TMPDIR_PROP = "java.io.tmpdir";
24+
private static final String OLD_JAVA_IO_TMPDIR = System.getProperty(JAVA_IO_TMPDIR_PROP);
25+
26+
@AfterMethod
27+
public void setUp() {
28+
System.setProperty(JAVA_IO_TMPDIR_PROP, OLD_JAVA_IO_TMPDIR);
29+
}
30+
31+
public void createTempDirPropertyExist() {
32+
String oldJavaIoTmpdir = System.getProperty(JAVA_IO_TMPDIR_PROP);
33+
try {
34+
handleJavaTmpdirProperty();
35+
assertEquals(System.getProperty(JAVA_IO_TMPDIR_PROP), oldJavaIoTmpdir);
36+
} catch (RuntimeException e) {
37+
fail(ExceptionUtils.getRootCauseMessage(e));
38+
}
39+
}
40+
41+
public void createTempDirMissingProperty() {
42+
System.setProperty(JAVA_IO_TMPDIR_PROP, "");
43+
if (SystemUtils.IS_OS_WINDOWS) {
44+
assertThrows(RuntimeException.class, CommonUtils::handleJavaTmpdirProperty);
45+
return;
46+
}
47+
try {
48+
handleJavaTmpdirProperty();
49+
assertEquals(System.getProperty(JAVA_IO_TMPDIR_PROP), "/tmp");
50+
} catch (RuntimeException e) {
51+
fail(ExceptionUtils.getRootCauseMessage(e));
52+
}
53+
}
54+
55+
public void createTempDirMissingDir() {
56+
Path currentDir = Paths.get("not-exist-dir").toAbsolutePath();
57+
System.setProperty(JAVA_IO_TMPDIR_PROP, currentDir.toString());
58+
try {
59+
handleJavaTmpdirProperty();
60+
assertEquals(System.getProperty(JAVA_IO_TMPDIR_PROP), currentDir.toString());
61+
} catch (RuntimeException e) {
62+
fail(ExceptionUtils.getRootCauseMessage(e));
63+
}
64+
}
65+
66+
}

Diff for: build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/DockerUtils.java

-15
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212
import org.apache.http.util.EntityUtils;
1313
import org.jfrog.build.extractor.clientConfiguration.client.ArtifactoryDependenciesClient;
1414

15-
import java.io.File;
1615
import java.io.IOException;
1716
import java.io.InputStream;
1817
import java.nio.charset.StandardCharsets;
19-
import java.nio.file.Paths;
2018
import java.security.MessageDigest;
2119
import java.security.NoSuchAlgorithmException;
2220
import java.util.ArrayList;
@@ -273,19 +271,6 @@ public static Boolean isImageVersioned(String imageTag) {
273271
return indexOfFirstSlash < indexOfLastColon;
274272
}
275273

276-
/**
277-
* Docker-Java uses the temp dir to execute binaries, in some cases the default temp dir (especially on Linux OS)
278-
* might have a NONEXE flag, therefore we override it with our build info extractor dir.
279-
*
280-
* @param path - Local path to create temp dir.
281-
*/
282-
public static void initTempDir(File path) {
283-
// Extract the dir path.
284-
String pathDir = path.getAbsoluteFile().getParent();
285-
// Set the Java temp dir system property. As a result, java will create it for us.
286-
System.setProperty("java.io.tmpdir", Paths.get(pathDir, "DockerJavaTemp").toString());
287-
}
288-
289274
/**
290275
* Download meta data from .marker layer in Artifactory.
291276
* As a result, the marker layer will transform to a regular docker layer (required to collect build info such as sha1, etc.).

Diff for: build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPull.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313
import org.jfrog.build.extractor.docker.DockerUtils;
1414
import org.jfrog.build.extractor.docker.types.DockerImage;
1515

16-
import java.io.File;
1716
import java.io.IOException;
1817
import java.util.Map;
1918

20-
import static org.jfrog.build.extractor.docker.DockerUtils.initTempDir;
2119
import static org.jfrog.build.extractor.packageManager.PackageManagerUtils.createArtifactoryClientConfiguration;
2220

2321
public class DockerPull extends DockerCommand {
@@ -58,8 +56,7 @@ public static void main(String[] ignored) {
5856
clientConfiguration.resolver.getPassword(),
5957
clientConfiguration.getLog(),
6058
clientConfiguration.getAllProperties());
61-
// Init temp dir.
62-
initTempDir(new File(clientConfiguration.info.getGeneratedBuildInfoFilePath()));
59+
6360
// Exe docker pull & collect build info.
6461
dockerPush.executeAndSaveBuildInfo(clientConfiguration);
6562
} catch (RuntimeException e) {

Diff for: build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPush.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@
1818
import org.jfrog.build.extractor.docker.types.DockerLayer;
1919
import org.jfrog.build.extractor.docker.types.DockerLayers;
2020

21-
import java.io.File;
2221
import java.io.IOException;
2322
import java.util.Map;
2423

2524
import static org.jfrog.build.extractor.clientConfiguration.util.DeploymentUrlUtils.buildMatrixParamsString;
26-
import static org.jfrog.build.extractor.docker.DockerUtils.initTempDir;
2725
import static org.jfrog.build.extractor.packageManager.PackageManagerUtils.createArtifactoryClientConfiguration;
2826

2927
public class DockerPush extends DockerCommand {
@@ -73,7 +71,7 @@ public static void main(String[] ignored) {
7371
clientConfiguration.publisher.getPassword(),
7472
clientConfiguration.getLog(),
7573
clientConfiguration.getAllProperties());
76-
initTempDir(new File(clientConfiguration.info.getGeneratedBuildInfoFilePath()));
74+
7775
// Exe docker push & collect build info.
7876
dockerPush.executeAndSaveBuildInfo(clientConfiguration);
7977
} catch (RuntimeException e) {

Diff for: build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecsHelper.java

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.io.IOException;
2929
import java.util.*;
3030

31+
import static org.jfrog.build.api.util.CommonUtils.handleJavaTmpdirProperty;
3132
import static org.jfrog.build.client.PreemptiveHttpClientBuilder.CONNECTION_POOL_SIZE;
3233

3334
/**
@@ -133,6 +134,8 @@ public static <K, V> Multimap<K, V> createMultiMap(Map<K, V> input) {
133134
* @throws IOException in case of IOException
134135
*/
135136
public List<Dependency> downloadArtifactsBySpec(String spec, ArtifactoryDependenciesClient client, String targetDirectory) throws IOException {
137+
// During download, temp directories are created. This will make sure 'java.io.tmpdir' property is defined in Unix.
138+
handleJavaTmpdirProperty();
136139
DependenciesDownloaderHelper helper = new DependenciesDownloaderHelper(client, targetDirectory, log);
137140
return helper.downloadDependencies(getSpecFromString(spec, new SearchBasedSpecValidator()));
138141
}

Diff for: build-info-extractor/src/main/java/org/jfrog/build/extractor/packageManager/PackageManagerExtractor.java

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import java.io.IOException;
1111
import java.io.Serializable;
1212

13+
import static org.jfrog.build.api.util.CommonUtils.handleJavaTmpdirProperty;
14+
1315
/**
1416
* Created by Bar Belity on 12/07/2020.
1517
*/
@@ -26,6 +28,8 @@ public abstract class PackageManagerExtractor implements Serializable {
2628
* @throws RuntimeException in case of any error.
2729
*/
2830
public void executeAndSaveBuildInfo(ArtifactoryClientConfiguration clientConfiguration) throws RuntimeException {
31+
// During build extractor's job, temp directories are created. This will make sure 'java.io.tmpdir' property is defined in Unix.
32+
handleJavaTmpdirProperty();
2933
Build build = execute();
3034
if (build == null) {
3135
return;

0 commit comments

Comments
 (0)