Skip to content

Commit d0418dc

Browse files
committed
Added --platform for selection of the build target platform
1 parent 9f9d733 commit d0418dc

File tree

12 files changed

+354
-101
lines changed

12 files changed

+354
-101
lines changed

imagetool/src/main/java/com/oracle/weblogic/imagetool/api/model/CachedFile.java

+81-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2019, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2019, 2024, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.weblogic.imagetool.api.model;
@@ -15,6 +15,7 @@
1515
import com.oracle.weblogic.imagetool.installer.InstallerType;
1616
import com.oracle.weblogic.imagetool.logging.LoggingFacade;
1717
import com.oracle.weblogic.imagetool.logging.LoggingFactory;
18+
import com.oracle.weblogic.imagetool.util.BuildPlatform;
1819
import com.oracle.weblogic.imagetool.util.Utils;
1920

2021
/**
@@ -24,31 +25,55 @@ public class CachedFile {
2425

2526
private static final LoggingFacade logger = LoggingFactory.getLogger(CachedFile.class);
2627

27-
private String id;
28-
private String version;
28+
private final String id;
29+
private final String version;
30+
private final String architecture;
2931

3032
/**
3133
* Represents a locally cached file.
3234
*
33-
* @param id cache ID (like installer type or patchId)
34-
* @param version version number for the patch or installer.
35+
* @param id cache ID (like installer type or patchId)
36+
* @param version version number for the patch or installer.
37+
* @param architecture the system architecture that this file/installer is applicable
3538
*/
36-
public CachedFile(String id, String version) {
39+
public CachedFile(String id, String version, String architecture) {
3740
Objects.requireNonNull(id, "key for the cached file cannot be null");
38-
logger.entering(id, version);
41+
logger.entering(id, version, architecture);
3942
this.id = id;
4043
this.version = version;
44+
this.architecture = architecture;
4145
logger.exiting();
4246
}
4347

48+
/**
49+
* Represents a locally cached file.
50+
*
51+
* @param id cache ID (like installer type or patchId)
52+
* @param version version number for the patch or installer.
53+
*/
54+
public CachedFile(String id, String version) {
55+
this(id, version, null);
56+
}
57+
58+
/**
59+
* Represents a locally cached file.
60+
*
61+
* @param id cache ID (like installer type)
62+
* @param version version number for the patch or installer.
63+
* @param architecture the system architecture that this file/installer is applicable
64+
*/
65+
public CachedFile(InstallerType id, String version, String architecture) {
66+
this(id.toString(), version, architecture);
67+
}
68+
4469
/**
4570
* Represents a locally cached file.
4671
*
4772
* @param id cache ID (like installer type)
4873
* @param version version number for the patch or installer.
4974
*/
5075
public CachedFile(InstallerType id, String version) {
51-
this(id.toString(), version);
76+
this(id.toString(), version, null);
5277
}
5378

5479
public static boolean isFileOnDisk(String filePath) {
@@ -62,11 +87,23 @@ public static boolean isFileOnDisk(String filePath) {
6287
* @return the key to use for this cache entry, like xxxx_yyyy.
6388
*/
6489
public String getKey() {
90+
return getCacheKey(architecture);
91+
}
92+
93+
private String getCacheKey(String architecture) {
6594
if (id.contains(CacheStore.CACHE_KEY_SEPARATOR)) {
6695
return id;
67-
} else {
68-
return id + CacheStore.CACHE_KEY_SEPARATOR + getVersion();
6996
}
97+
98+
StringBuilder key = new StringBuilder(32);
99+
key.append(id);
100+
key.append(CacheStore.CACHE_KEY_SEPARATOR);
101+
key.append(version);
102+
if (architecture != null) {
103+
key.append(CacheStore.CACHE_KEY_SEPARATOR);
104+
key.append(architecture);
105+
}
106+
return key.toString();
70107
}
71108

72109
/**
@@ -77,8 +114,22 @@ public String getVersion() {
77114
return version;
78115
}
79116

117+
/**
118+
* Get the system architecture name for this cache entry/file.
119+
* @return the system architecture name applicable fo this cached file.
120+
*/
121+
public String getArchitecture() {
122+
return architecture;
123+
}
124+
80125
/**
81126
* Get the path of the file stored locally in the cache.
127+
* Searching the cache starts with the specified key. If the key is not found in the cache,
128+
* one additional attempt is made to find an acceptable alternative. The second search is based on
129+
* whether the user specified a platform/architecture. If the user specified an architecture, check the cache
130+
* for an entry listing without the architecture in the key (generic architecture entry). If the user
131+
* did not specify an architecture, check the cache for an entry listing using the local architecture
132+
* in case the user added the cache entry with the architecture.
82133
* @param cacheStore the cache store to search
83134
* @return the Path of the file, if found
84135
* @throws IOException throws FileNotFoundException, if this cached file (key) could not be located in the cache
@@ -88,6 +139,25 @@ public String resolve(CacheStore cacheStore) throws IOException {
88139
String key = getKey();
89140
logger.entering(key);
90141
String filePath = cacheStore.getValueFromCache(key);
142+
if (filePath == null) {
143+
// The KEY for this CachedFile was not found in the local cache.
144+
logger.fine("Unable to find cache entry for {0}", key);
145+
String alternateKey;
146+
if (getArchitecture() == null) {
147+
// The user did not specify an architecture in the KEY and that key was not found in the cache.
148+
// Try adding the local architecture to the key, and look for that entry.
149+
alternateKey = getCacheKey(BuildPlatform.getPlatformName());
150+
logger.fine("Trying local architecture: {0}", alternateKey);
151+
} else {
152+
// The user specified an architecture in the KEY, but that key was not found.
153+
// Try removing the architecture from the key, and look for that entry.
154+
alternateKey = getCacheKey(null);
155+
logger.fine("Trying no-arch/generic architecture: {0}", alternateKey);
156+
}
157+
// second attempt to find a reasonable cache entry
158+
filePath = cacheStore.getValueFromCache(alternateKey);
159+
}
160+
91161
if (!isFileOnDisk(filePath)) {
92162
throw new FileNotFoundException(Utils.getMessage("IMG-0011", key));
93163
}
@@ -103,7 +173,7 @@ public String resolve(CacheStore cacheStore) throws IOException {
103173
* @return the path of the file copied to the Docker build context directory
104174
*/
105175
public Path copyFile(CacheStore cacheStore, String buildContextDir) throws IOException {
106-
logger.entering();
176+
logger.entering(id, version, architecture, buildContextDir);
107177
Path result;
108178
String sourceFile = resolve(cacheStore);
109179
logger.info("IMG-0043", sourceFile);

imagetool/src/main/java/com/oracle/weblogic/imagetool/builder/BuildCommand.java

+29-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2020, 2024, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.weblogic.imagetool.builder;
@@ -17,8 +17,6 @@
1717
import java.util.List;
1818
import java.util.Map;
1919
import java.util.Objects;
20-
import java.util.stream.Collectors;
21-
import java.util.stream.Stream;
2220

2321
import com.oracle.weblogic.imagetool.logging.LoggingFacade;
2422
import com.oracle.weblogic.imagetool.logging.LoggingFactory;
@@ -28,10 +26,12 @@
2826
public class BuildCommand {
2927
private static final LoggingFacade logger = LoggingFactory.getLogger(BuildCommand.class);
3028

29+
private final String executable;
3130
private final List<String> command;
3231
private final List<BuildArg> buildArgs;
3332
private List<String> additionalOptions;
3433
private final String context;
34+
private boolean useBuildx = false;
3535

3636
/**
3737
* Create a build command for creating an image. At some point, it might
@@ -41,7 +41,8 @@ public class BuildCommand {
4141
public BuildCommand(String buildEngine, String contextFolder) {
4242
Objects.requireNonNull(contextFolder);
4343
buildArgs = new ArrayList<>();
44-
command = Stream.of(buildEngine, "build", "--no-cache").collect(Collectors.toList());
44+
executable = buildEngine;
45+
command = new ArrayList<>();
4546
context = contextFolder;
4647
}
4748

@@ -59,6 +60,22 @@ public BuildCommand tag(String value) {
5960
return this;
6061
}
6162

63+
/**
64+
* Add container build platform. Pass the desired
65+
* build architecture to the build process.
66+
* @param value a single platform name.
67+
* @return this
68+
*/
69+
public BuildCommand platform(String value) {
70+
if (Utils.isEmptyString(value)) {
71+
return this;
72+
}
73+
command.add("--platform");
74+
command.add(value);
75+
useBuildx = true;
76+
return this;
77+
}
78+
6279
/**
6380
* Always remove intermediate containers if set to true.
6481
* By default, Docker leaves intermediate containers when the build fails which is not ideal for CI/CD servers.
@@ -237,7 +254,14 @@ private CloseableList<PrintWriter> createPrintWriters(List<OutputStream> outputS
237254
}
238255

239256
private List<String> getCommand(boolean showPasswords) {
240-
List<String> result = new ArrayList<>(command);
257+
List<String> result = new ArrayList<>();
258+
result.add(executable);
259+
if (useBuildx) {
260+
result.add("buildx");
261+
}
262+
result.add("build");
263+
result.add("--no-cache");
264+
result.addAll(command);
241265
if (additionalOptions != null && !additionalOptions.isEmpty()) {
242266
result.addAll(additionalOptions);
243267
}

imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddInstallerEntry.java

+26-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2019, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2019, 2024, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.weblogic.imagetool.cli.cache;
@@ -22,23 +22,44 @@ public CommandResponse call() throws CacheStoreException {
2222
if ("NONE".equalsIgnoreCase(version)) {
2323
throw new IllegalArgumentException("IMG-0105");
2424
}
25-
String key = String.format("%s%s%s", type, CacheStore.CACHE_KEY_SEPARATOR, version);
26-
return addToCache(key);
25+
26+
return addToCache();
27+
}
28+
29+
@Override
30+
public String getKey() {
31+
StringBuilder key = new StringBuilder(25)
32+
.append(type)
33+
.append(CacheStore.CACHE_KEY_SEPARATOR)
34+
.append(version);
35+
36+
if (architecture != null) {
37+
key.append(CacheStore.CACHE_KEY_SEPARATOR)
38+
.append(architecture);
39+
}
40+
41+
return key.toString();
2742
}
2843

2944
@Option(
30-
names = {"--type"},
45+
names = {"-t", "--type"},
3146
description = "Type of installer. Valid values: ${COMPLETION-CANDIDATES}",
3247
required = true,
3348
defaultValue = "wls"
3449
)
3550
private InstallerType type;
3651

3752
@Option(
38-
names = {"--version"},
53+
names = {"-v", "--version"},
3954
description = "Installer version. Ex: For WLS|FMW use 12.2.1.3.0 For jdk, use 8u201",
4055
required = true
4156
)
4257
private String version;
4358

59+
@Option(
60+
names = {"-a", "--architecture"},
61+
description = "(Optional) Installer architecture. Ex: linux/amd64 or linux/arm64."
62+
)
63+
private String architecture;
64+
4465
}

imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntry.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@
1717
)
1818
public class AddPatchEntry extends CacheAddOperation {
1919

20+
public String getKey() {
21+
return patchId;
22+
}
23+
2024
@Override
2125
public CommandResponse call() throws Exception {
2226
try {
2327
if (patchId != null && !patchId.isEmpty()) {
2428
Utils.validatePatchIds(Collections.singletonList(patchId), true);
25-
return addToCache(patchId);
29+
return addToCache();
2630
} else {
2731
return CommandResponse.error("IMG-0076", "--patchId");
2832
}

imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/CacheAddOperation.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@
1414

1515
public abstract class CacheAddOperation extends CacheOperation {
1616

17-
CommandResponse addToCache(String key) throws CacheStoreException {
17+
public abstract String getKey();
18+
19+
CommandResponse addToCache() throws CacheStoreException {
1820
// if file is invalid or does not exist, return an error
1921
if (filePath == null || !Files.isRegularFile(filePath)) {
2022
return CommandResponse.error("IMG-0049", filePath);
2123
}
2224

25+
String key = getKey();
2326
// if the new value is the same as the existing cache value, do nothing
2427
String existingValue = cache().getValueFromCache(key);
2528
if (absolutePath().toString().equals(existingValue)) {
@@ -36,7 +39,7 @@ CommandResponse addToCache(String key) throws CacheStoreException {
3639
return CommandResponse.success("IMG-0050", key, cache().getValueFromCache(key));
3740
}
3841

39-
Path absolutePath() {
42+
private Path absolutePath() {
4043
if (absolutePath == null) {
4144
absolutePath = filePath.toAbsolutePath();
4245
}
@@ -53,8 +56,8 @@ Path absolutePath() {
5356

5457

5558
@Option(
56-
names = {"--path"},
57-
description = "Location on disk. For ex: /path/to/patch-or-installer.zip",
59+
names = {"-p", "--path"},
60+
description = "Location of the file on disk. For ex: /path/to/patch-or-installer.zip",
5861
required = true
5962
)
6063
private Path filePath;

imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonCreateOptions.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2021, 2022, Oracle and/or its affiliates.
1+
// Copyright (c) 2021, 2024, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.weblogic.imagetool.cli.menu;
@@ -34,14 +34,14 @@ void prepareNewImage() throws IOException, InterruptedException, XPathExpression
3434
copyOptionsFromImage();
3535

3636
if (dockerfileOptions.installJava()) {
37-
CachedFile jdk = new CachedFile(InstallerType.JDK, jdkVersion);
37+
CachedFile jdk = new CachedFile(InstallerType.JDK, jdkVersion, getBuildPlatform());
3838
Path installerPath = jdk.copyFile(cache(), buildDir());
3939
dockerfileOptions.setJavaInstaller(installerPath.getFileName().toString());
4040
}
4141

4242
if (dockerfileOptions.installMiddleware()) {
4343
MiddlewareInstall install =
44-
new MiddlewareInstall(getInstallerType(), installerVersion, installerResponseFiles);
44+
new MiddlewareInstall(getInstallerType(), installerVersion, installerResponseFiles, getBuildPlatform());
4545
install.copyFiles(cache(), buildDir());
4646
dockerfileOptions.setMiddlewareInstall(install);
4747
} else {

0 commit comments

Comments
 (0)