Skip to content

Commit ea2cb4e

Browse files
authored
Create can be used to add a WDT domain or model (#280)
* Rearrange Dockerfile templates so that installation of Oracle Home is optional * consolidate image probe scripts * update mustache compiler to fix java illegal access issue * allow create to update a base image with an Oracle Home (no patching) * merge with change from #279 * print warning and error messages from the FMW WLS installer when an error occurs during the docker build * add group write permissions for WDT home directory
1 parent a59bdd6 commit ea2cb4e

23 files changed

+476
-574
lines changed

imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruUtil.java

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,11 @@
2020
import org.apache.http.client.HttpResponseException;
2121
import org.apache.http.client.fluent.Request;
2222
import org.w3c.dom.Document;
23-
import org.w3c.dom.NamedNodeMap;
24-
import org.w3c.dom.Node;
2523
import org.w3c.dom.NodeList;
2624

2725
import static com.oracle.weblogic.imagetool.util.Constants.ARU_LANG_URL;
2826
import static com.oracle.weblogic.imagetool.util.Constants.ARU_REST_URL;
2927
import static com.oracle.weblogic.imagetool.util.Constants.CONFLICTCHECKER_URL;
30-
import static com.oracle.weblogic.imagetool.util.Constants.GET_LSINVENTORY_URL;
3128
import static com.oracle.weblogic.imagetool.util.Constants.RECOMMENDED_PATCHES_URL;
3229
import static com.oracle.weblogic.imagetool.util.Constants.REL_URL;
3330

@@ -189,27 +186,27 @@ private String getPsuVersion(List<AruPatch> patches) {
189186
/**
190187
* Validate patches conflicts by passing a list of patches.
191188
*
192-
* @param inventoryContent opatch lsinventory content (null if non is passed)
189+
* @param installedPatches opatch lsinventory content (null if none is passed)
193190
* @param patches A list of patches number
194191
* @param userId userId for support account
195192
* @param password password for support account
196193
* @throws IOException when failed to access the aru api
197194
*/
198-
public static void validatePatches(String inventoryContent, List<AruPatch> patches, String userId, String password)
199-
throws IOException, XPathExpressionException {
200-
validatePatches(inventoryContent, patches, new AruHttpHelper(userId, password));
195+
public static void validatePatches(List<InstalledPatch> installedPatches, List<AruPatch> patches, String userId,
196+
String password) throws IOException {
197+
validatePatches(installedPatches, patches, new AruHttpHelper(userId, password));
201198
}
202199

203200
/**
204201
* Validate patches conflict by passing a list of patches and encapsulated userId and password.
205202
*
206-
* @param inventoryContent opatch lsinventory content (null if non is passed)
203+
* @param installedPatches opatch lsinventory content (null if non is passed)
207204
* @param patches A list of patches number
208205
* @param aruHttpHelper encapsulated account credentials
209206
* @throws IOException when failed to access the aru api
210207
*/
211-
static void validatePatches(String inventoryContent, List<AruPatch> patches,
212-
AruHttpHelper aruHttpHelper) throws IOException, XPathExpressionException {
208+
static void validatePatches(List<InstalledPatch> installedPatches, List<AruPatch> patches,
209+
AruHttpHelper aruHttpHelper) throws IOException {
213210
logger.entering(patches, aruHttpHelper);
214211

215212
if (aruHttpHelper.userId() == null || aruHttpHelper.password() == null) {
@@ -220,28 +217,12 @@ static void validatePatches(String inventoryContent, List<AruPatch> patches,
220217

221218
StringBuilder payload = new StringBuilder("<conflict_check_request><platform>2000</platform>");
222219

223-
if (inventoryContent != null) {
224-
String upiPayload = "<inventory_upi_request><lsinventory_output>" + inventoryContent
225-
+ "</lsinventory_output></inventory_upi_request>";
226-
227-
AruHttpHelper upiResult = aruHttpHelper.execValidation(GET_LSINVENTORY_URL, upiPayload);
228-
229-
NodeList upiList = XPathUtil.nodelist(upiResult.results(),
230-
"/inventory_upi_response/upi");
231-
if (upiList.getLength() > 0) {
232-
payload.append("<target_patch_list>");
233-
234-
for (int ii = 0; ii < upiList.getLength(); ii++) {
235-
Node upi = upiList.item(ii);
236-
NamedNodeMap m = upi.getAttributes();
237-
payload.append(String.format("<installed_patch upi=\"%s\"/>",
238-
m.getNamedItem("number").getNodeValue()));
239-
240-
}
241-
payload.append("</target_patch_list>");
242-
} else {
243-
payload.append("<target_patch_list/>");
220+
if (installedPatches != null && !installedPatches.isEmpty()) {
221+
payload.append("<target_patch_list>");
222+
for (InstalledPatch patch : installedPatches) {
223+
payload.append(String.format("<installed_patch upi=\"%s\"/>", patch.getUniquePatchNumber()));
244224
}
225+
payload.append("</target_patch_list>");
245226
} else {
246227
payload.append("<target_patch_list/>");
247228
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright (c) 2021, Oracle and/or its affiliates.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
3+
4+
package com.oracle.weblogic.imagetool.aru;
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
import java.util.regex.Matcher;
9+
import java.util.regex.Pattern;
10+
11+
import com.oracle.weblogic.imagetool.logging.LoggingFacade;
12+
import com.oracle.weblogic.imagetool.logging.LoggingFactory;
13+
14+
public class InstalledPatch {
15+
private static final LoggingFacade logger = LoggingFactory.getLogger(InstalledPatch.class);
16+
17+
private String bugNumber;
18+
private String uniquePatchNumber;
19+
private String patchDescription;
20+
21+
/**
22+
* Parse the output from the image probe list of Oracle patches.
23+
*
24+
* @param oraclePatches semi-colon separated list of patches and fields
25+
* @return a simple list of InstalledPatch
26+
*/
27+
public static List<InstalledPatch> getPatchList(String oraclePatches) {
28+
List<InstalledPatch> result = new ArrayList<>();
29+
String[] tokens = oraclePatches.split(";");
30+
if (tokens.length % 3 != 0) {
31+
logger.severe("Too many tokens in oracle patches " + tokens.length);
32+
}
33+
for (int i = 0; i < tokens.length; i++) {
34+
InstalledPatch found = new InstalledPatch();
35+
found.bugNumber = tokens[i];
36+
if (tokens.length > i + 1) {
37+
found.uniquePatchNumber = tokens[++i];
38+
}
39+
if (tokens.length > i + 1) {
40+
found.patchDescription = tokens[++i].replaceAll("^\"|\"$", "");
41+
}
42+
result.add(found);
43+
}
44+
45+
return result;
46+
}
47+
48+
/**
49+
* Parse the patch descriptions and return the PSU number if there is one installed.
50+
* @param installedPatches The opatch lsinventory patches.
51+
* @return the version of the PSU, or null if no PSU is found.
52+
*/
53+
public static String getPsuVersion(List<InstalledPatch> installedPatches) {
54+
String result = null;
55+
// search inventory for PSU and extract PSU version, if available
56+
Pattern patternOne = Pattern.compile(
57+
"WLS PATCH SET UPDATE (\\d+\\.\\d+\\.\\d+\\.\\d+\\.)\\d+\\(ID:(\\d+)\\.\\d+\\)");
58+
Pattern patternTwo = Pattern.compile(
59+
"WLS PATCH SET UPDATE (\\d+\\.\\d+\\.\\d+\\.\\d+\\.[1-9]\\d+)");
60+
61+
for (InstalledPatch patch : installedPatches) {
62+
String description = patch.getPatchDescription();
63+
Matcher matchPatternOne = patternOne.matcher(description);
64+
Matcher matchPatternTwo = patternTwo.matcher(description);
65+
if (matchPatternOne.find()) {
66+
result = matchPatternOne.group(1) + matchPatternOne.group(2);
67+
logger.fine("Found PSU in inventory {0}, in {1}", result, description);
68+
break;
69+
} else if (matchPatternTwo.find()) {
70+
result = matchPatternTwo.group(1);
71+
logger.fine("Found PSU in inventory {0}, in {1}", result, description);
72+
break;
73+
}
74+
}
75+
return result;
76+
}
77+
78+
public String getBugNumber() {
79+
return bugNumber;
80+
}
81+
82+
public String getUniquePatchNumber() {
83+
return uniquePatchNumber;
84+
}
85+
86+
public String getPatchDescription() {
87+
return patchDescription;
88+
}
89+
90+
@Override
91+
public String toString() {
92+
return bugNumber + ":" + uniquePatchNumber + ":" + patchDescription;
93+
}
94+
}

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

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.nio.file.Path;
1212
import java.nio.file.Paths;
1313
import java.util.ArrayList;
14+
import java.util.Collections;
1415
import java.util.List;
1516
import java.util.Properties;
1617
import java.util.regex.Matcher;
@@ -22,6 +23,7 @@
2223
import com.oracle.weblogic.imagetool.aru.AruPatch;
2324
import com.oracle.weblogic.imagetool.aru.AruProduct;
2425
import com.oracle.weblogic.imagetool.aru.AruUtil;
26+
import com.oracle.weblogic.imagetool.aru.InstalledPatch;
2527
import com.oracle.weblogic.imagetool.builder.BuildCommand;
2628
import com.oracle.weblogic.imagetool.cachestore.MultiplePatchVersionsException;
2729
import com.oracle.weblogic.imagetool.cachestore.OPatchFile;
@@ -205,24 +207,32 @@ boolean shouldUpdateOpatch() {
205207
}
206208

207209
void handlePatchFiles(FmwInstallerType installerType) throws AruException, XPathExpressionException, IOException {
208-
handlePatchFiles(installerType, null, null);
210+
if (dockerfileOptions.installMiddleware()) {
211+
handlePatchFiles(installerType, Collections.emptyList());
212+
} else {
213+
if (applyingPatches()) {
214+
// user intended to apply patches, but used a fromImage that already had an Oracle Home
215+
// The template does not support (yet) patches on existing Oracle Homes due to image size impact
216+
logger.warning("IMG-0093");
217+
}
218+
}
209219
}
210220

211221
/**
212222
* Process all patches requested by the user, if any.
213223
* Downloads and copies patch JARs to the build context directory.
214224
*
215225
* @param installerType The installer type used to create the Oracle Home
216-
* @param previousInventory OPatch lsinventory output (currently applied patches, if any)
217-
* @param psuVersion The PSU version, if any are already applied to the OH.
226+
* @param installedPatches a list of patches applied already installed on the target image.
218227
* @throws AruException if an error occurs trying to read patch metadata from ARU.
219228
* @throws IOException if a transport error occurs trying to access the Oracle REST services.
220229
* @throws XPathExpressionException when the payload from the REST service is not formatted as expected
221230
* or a partial response was returned.
222231
*/
223-
void handlePatchFiles(FmwInstallerType installerType, String previousInventory, String psuVersion)
232+
void handlePatchFiles(FmwInstallerType installerType, List<InstalledPatch> installedPatches)
224233
throws AruException, IOException, XPathExpressionException {
225-
logger.entering(psuVersion);
234+
logger.entering(installerType, installedPatches);
235+
String psuVersion = InstalledPatch.getPsuVersion(installedPatches);
226236
if (!applyingPatches()) {
227237
logger.exiting("not applying patches");
228238
return;
@@ -298,7 +308,7 @@ void handlePatchFiles(FmwInstallerType installerType, String previousInventory,
298308
}
299309
}
300310

301-
AruUtil.validatePatches(previousInventory, aruPatches, userId, password);
311+
AruUtil.validatePatches(installedPatches, aruPatches, userId, password);
302312

303313
String patchesFolderName = createPatchesTempDirectory().toAbsolutePath().toString();
304314
// copy the patch JARs to the Docker build context directory from the local cache, downloading them if needed
@@ -359,20 +369,21 @@ public void copyOptionsFromImage(String fromImage, String tmpDir) throws IOExcep
359369
dockerfileOptions.setBaseImage(fromImage);
360370

361371
Properties baseImageProperties = Utils.getBaseImageProperties(buildEngine, fromImage,
362-
"/probe-env/test-create-env.sh", tmpDir);
372+
"/probe-env/inspect-image.sh", tmpDir);
363373

364-
if (baseImageProperties.getProperty("WLS_VERSION", null) != null) {
365-
throw new IllegalArgumentException(Utils.getMessage("IMG-0038", fromImage,
366-
baseImageProperties.getProperty("ORACLE_HOME")));
367-
}
368-
369-
String existingJavaHome = baseImageProperties.getProperty("JAVA_HOME", null);
374+
String existingJavaHome = baseImageProperties.getProperty("javaHome", null);
370375
if (existingJavaHome != null) {
371376
dockerfileOptions.disableJavaInstall(existingJavaHome);
372-
logger.info("IMG-0000", existingJavaHome);
377+
logger.info("IMG-0000", fromImage);
378+
}
379+
380+
String existingOracleHome = baseImageProperties.getProperty("oracleHome", null);
381+
if (existingOracleHome != null) {
382+
dockerfileOptions.disableMiddlewareInstall(existingOracleHome);
383+
logger.info("IMG-0092", fromImage);
373384
}
374385

375-
String pkgMgrProp = baseImageProperties.getProperty("PACKAGE_MANAGER", "YUM");
386+
String pkgMgrProp = baseImageProperties.getProperty("packageManager", "YUM");
376387

377388
PackageManagerType pkgMgr = PackageManagerType.valueOf(pkgMgrProp);
378389
logger.fine("fromImage package manager {0}", pkgMgr);

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,14 @@ public CommandResponse call() throws Exception {
6262
dockerfileOptions.setJavaInstaller(installerPath.getFileName().toString());
6363
}
6464

65-
MiddlewareInstall install = new MiddlewareInstall(installerType, installerVersion, installerResponseFiles);
66-
install.copyFiles(cache(), tmpDir);
67-
dockerfileOptions.setMiddlewareInstall(install);
65+
if (dockerfileOptions.installMiddleware()) {
66+
MiddlewareInstall install =
67+
new MiddlewareInstall(installerType, installerVersion, installerResponseFiles);
68+
install.copyFiles(cache(), tmpDir);
69+
dockerfileOptions.setMiddlewareInstall(install);
70+
} else {
71+
dockerfileOptions.setWdtBase(fromImage);
72+
}
6873

6974
BuildCommand cmdBuilder = getInitialBuildCmd(tmpDir);
7075
// build wdt args if user passes --wdtModelPath

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ public CommandResponse call() throws Exception {
6767

6868
logger.info("IMG-0091", sourceImage);
6969
Properties baseImageProperties = Utils.getBaseImageProperties(buildEngine, sourceImage,
70-
"/probe-env/test-update-env.sh", tmpDir);
70+
"/probe-env/inspect-image.sh", tmpDir);
7171

72-
oldOracleHome = baseImageProperties.getProperty("ORACLE_HOME", null);
73-
oldJavaHome = baseImageProperties.getProperty("JAVA_PATH", null);
74-
domainHome = baseImageProperties.getProperty("DOMAIN_HOME", null);
75-
modelHome = baseImageProperties.getProperty("WDT_MODEL_HOME", null);
76-
modelOnly = Boolean.parseBoolean(baseImageProperties.getProperty("WDT_MODEL_ONLY", null));
72+
oldOracleHome = baseImageProperties.getProperty("oracleHome", null);
73+
oldJavaHome = baseImageProperties.getProperty("javaHome", null);
74+
domainHome = baseImageProperties.getProperty("domainHome", null);
75+
modelHome = baseImageProperties.getProperty("wdtModelHome", null);
76+
modelOnly = Boolean.parseBoolean(baseImageProperties.getProperty("wdtModelOnly", null));
7777
} else {
7878
return new CommandResponse(-1, "Source Image not set");
7979
}
@@ -84,10 +84,10 @@ public CommandResponse call() throws Exception {
8484
dockerfileOptions.setRebaseToTarget(true);
8585

8686
Properties baseImageProperties = Utils.getBaseImageProperties(buildEngine, targetImage,
87-
"/probe-env/test-update-env.sh", tmpDir);
87+
"/probe-env/inspect-image.sh", tmpDir);
8888

89-
newOracleHome = baseImageProperties.getProperty("ORACLE_HOME", null);
90-
newJavaHome = baseImageProperties.getProperty("JAVA_PATH", null);
89+
newOracleHome = baseImageProperties.getProperty("oracleHome", null);
90+
newJavaHome = baseImageProperties.getProperty("javaHome", null);
9191

9292
} else {
9393
dockerfileOptions.setRebaseToNew(true);

0 commit comments

Comments
 (0)