Skip to content

Commit 2b75416

Browse files
authored
Add WDT capability to UPDATE operation (#62)
* add WDT capability to update operation * replace unzip in update template with jar to eliminate need for yum update * updated Readmes to reflect new command line options and changes
1 parent 06de88d commit 2b75416

File tree

11 files changed

+511
-332
lines changed

11 files changed

+511
-332
lines changed

.idea/codeStyles/Project.xml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ image.
1111
## Features
1212

1313
The Image Tool provides three functions within the main script:
14-
- [Create Image](site/create-image.md) - The `create` command helps build a WebLogic Docker image from a given base OS
15-
image.
16-
- [Update Image](site/update-image.md) - The `update` command can be used to apply WebLogic patches to an existing
17-
WebLogic Docker image.
18-
- [Cache](site/cache.md) - The Image Tool maintains a local file cache for patches and installers. The `cache`
19-
command can be used to manipulate the local file cache.
14+
- [Create Image](site/create-image.md) - The `create` command creates a new Docker image and installs the requested
15+
Java and WebLogic software. Additionally, you can create a WebLogic domain in the image at the same time.
16+
- [Update Image](site/update-image.md) - The `update` command creates a new Docker image by applying WebLogic patches
17+
to an existing image. Additionally, you can create a WebLogic domain if one did not exist previously.
18+
- [Cache](site/cache.md) - The Image Tool maintains metadata on the local file system for patches and installers.
19+
The `cache` command can be used to manipulate the local metadata.
2020

2121
## Prerequisites
2222

2323
- Docker client and daemon on the build machine, with minimum Docker version Docker 18.03.1.ce.
24-
- WebLogic Server and JDK installers from OTN / Oracle e-Delivery.
24+
- Installers for WebLogic Server and JDK from OTN / Oracle e-Delivery.
2525
- (For patches) Oracle support credentials.
2626
- Bash version 4.0 or higher to enable the `<tab>` command complete feature.
2727

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

Lines changed: 6 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
package com.oracle.weblogic.imagetool.cli.menu;
55

66
import java.io.File;
7-
import java.io.FileInputStream;
87
import java.io.IOException;
98
import java.nio.file.Files;
109
import java.nio.file.Path;
@@ -13,23 +12,18 @@
1312
import java.time.Instant;
1413
import java.util.ArrayList;
1514
import java.util.HashSet;
16-
import java.util.LinkedList;
1715
import java.util.List;
1816
import java.util.Properties;
1917
import java.util.Set;
20-
import java.util.logging.Level;
21-
import java.util.stream.Collectors;
2218

2319
import com.oracle.weblogic.imagetool.api.model.CommandResponse;
24-
import com.oracle.weblogic.imagetool.api.model.DomainType;
2520
import com.oracle.weblogic.imagetool.api.model.InstallerType;
2621
import com.oracle.weblogic.imagetool.api.model.WLSInstallerType;
2722
import com.oracle.weblogic.imagetool.impl.InstallerFile;
2823
import com.oracle.weblogic.imagetool.logging.LoggingFacade;
2924
import com.oracle.weblogic.imagetool.logging.LoggingFactory;
3025
import com.oracle.weblogic.imagetool.util.ARUUtil;
3126
import com.oracle.weblogic.imagetool.util.Constants;
32-
import com.oracle.weblogic.imagetool.util.HttpUtil;
3327
import com.oracle.weblogic.imagetool.util.Utils;
3428
import com.oracle.weblogic.imagetool.util.ValidationResult;
3529
import picocli.CommandLine.Command;
@@ -80,12 +74,7 @@ public CommandResponse call() throws Exception {
8074
Utils.copyResourceAsFile("/probe-env/test-create-env.sh",
8175
tmpDir + File.separator + "test-env.sh", true);
8276

83-
List<String> imageEnvCmd = Utils.getDockerRunCmd(tmpDir, fromImage, "test-env.sh");
84-
Properties baseImageProperties = Utils.runDockerCommand(imageEnvCmd);
85-
if (logger.isLoggable(Level.FINE)) {
86-
baseImageProperties.keySet().forEach(x -> logger.fine("ENV(" + fromImage + "): "
87-
+ x + "=" + baseImageProperties.getProperty(x.toString())));
88-
}
77+
Properties baseImageProperties = Utils.getBaseImageProperties(fromImage, tmpDir);
8978

9079
boolean ohAlreadyExists = baseImageProperties.getProperty("WLS_VERSION", null) != null;
9180

@@ -144,34 +133,6 @@ public CommandResponse call() throws Exception {
144133
+ Duration.between(startTime, endTime).getSeconds() + "s. image tag: " + imageTag);
145134
}
146135

147-
/**
148-
* Builds a list of build args to pass on to docker with the required installer files.
149-
* Also, creates links to installer files instead of copying over to build context dir.
150-
*
151-
* @param tmpDir build context directory
152-
* @return list of strings
153-
* @throws Exception in case of error
154-
*/
155-
private List<String> handleInstallerFiles(String tmpDir) throws Exception {
156-
157-
logger.entering(tmpDir);
158-
List<String> retVal = new LinkedList<>();
159-
List<InstallerFile> requiredInstallers = gatherRequiredInstallers();
160-
for (InstallerFile installerFile : requiredInstallers) {
161-
String targetFilePath = installerFile.resolve(cacheStore);
162-
logger.finer("copying targetFilePath: {0}", targetFilePath);
163-
String filename = new File(targetFilePath).getName();
164-
try {
165-
Files.copy(Paths.get(targetFilePath), Paths.get(tmpDir, filename));
166-
retVal.addAll(installerFile.getBuildArg(filename));
167-
} catch (Exception ee) {
168-
ee.printStackTrace();
169-
}
170-
}
171-
logger.exiting(retVal);
172-
return retVal;
173-
}
174-
175136
@Override
176137
List<String> handlePatchFiles(String tmpDir, Path tmpPatchesDir) throws Exception {
177138
logger.finer("Entering CreateImage.handlePatchFiles: " + tmpDir);
@@ -209,110 +170,16 @@ List<String> handlePatchFiles(String tmpDir, Path tmpPatchesDir) throws Exceptio
209170
return super.handlePatchFiles(tmpDir, tmpPatchesDir);
210171
}
211172

212-
/**
213-
* Checks whether the user requested a domain to be created with WDT.
214-
* If so, returns the required build args to pass to docker and creates required file links to pass
215-
* the model, archive, variables file to build process
216-
*
217-
* @param tmpDir the tmp directory which is passed to docker as the build context directory
218-
* @return list of build args
219-
* @throws IOException in case of error
220-
*/
221-
private List<String> handleWdtArgsIfRequired(String tmpDir) throws IOException {
222-
logger.finer("Entering CreateImage.handleWdtArgsIfRequired: " + tmpDir);
223-
List<String> retVal = new LinkedList<>();
224-
if (wdtModelPath != null) {
225-
String[] modelFiles = wdtModelPath.toString().split(",");
226-
List<String> modelList = new ArrayList<>();
227-
228-
for (String modelFile : modelFiles) {
229-
Path modelFilePath = Paths.get(modelFile);
230-
if (Files.isRegularFile(modelFilePath)) {
231-
String modelFilename = modelFilePath.getFileName().toString();
232-
Files.copy(modelFilePath, Paths.get(tmpDir, modelFilename));
233-
modelList.add(modelFilename);
234-
} else {
235-
throw new IOException("WDT model file " + modelFile + " not found");
236-
}
237-
}
238-
dockerfileOptions.setWdtModels(modelList);
239-
240-
if (wdtDomainType != DomainType.WLS) {
241-
if (installerType != WLSInstallerType.FMW) {
242-
throw new IOException("FMW installer is required for JRF domain");
243-
}
244-
retVal.add(Constants.BUILD_ARG);
245-
retVal.add("DOMAIN_TYPE=" + wdtDomainType);
246-
if (runRcu) {
247-
retVal.add(Constants.BUILD_ARG);
248-
retVal.add("RCU_RUN_FLAG=" + "-run_rcu");
249-
}
250-
}
251-
dockerfileOptions.setWdtEnabled();
252-
253-
if (wdtArchivePath != null && Files.isRegularFile(wdtArchivePath)) {
254-
String wdtArchiveFilename = wdtArchivePath.getFileName().toString();
255-
Files.copy(wdtArchivePath, Paths.get(tmpDir, wdtArchiveFilename));
256-
retVal.add(Constants.BUILD_ARG);
257-
retVal.add("WDT_ARCHIVE=" + wdtArchiveFilename);
258-
}
259-
if (wdtDomainHome != null) {
260-
retVal.add(Constants.BUILD_ARG);
261-
retVal.add("DOMAIN_HOME=" + wdtDomainHome);
262-
}
263-
264-
if (wdtVariablesPath != null && Files.isRegularFile(wdtVariablesPath)) {
265-
String wdtVariableFilename = wdtVariablesPath.getFileName().toString();
266-
Files.copy(wdtVariablesPath, Paths.get(tmpDir, wdtVariableFilename));
267-
retVal.add(Constants.BUILD_ARG);
268-
retVal.add("WDT_VARIABLE=" + wdtVariableFilename);
269-
retVal.addAll(getWdtRequiredBuildArgs(wdtVariablesPath));
270-
}
271-
}
272-
logger.finer("Exiting CreateImage.handleWdtArgsIfRequired: ");
273-
return retVal;
274-
}
275-
276-
/**
277-
* Certain environment variables need to be set in docker images for WDT domains to work.
278-
*
279-
* @param wdtVariablesPath wdt variables file path.
280-
* @return list of build args
281-
* @throws IOException in case of error
282-
*/
283-
private List<String> getWdtRequiredBuildArgs(Path wdtVariablesPath) throws IOException {
284-
logger.finer("Entering CreateImage.getWdtRequiredBuildArgs: " + wdtVariablesPath.toAbsolutePath().toString());
285-
List<String> retVal = new LinkedList<>();
286-
Properties variableProps = new Properties();
287-
variableProps.load(new FileInputStream(wdtVariablesPath.toFile()));
288-
List<Object> matchingKeys = variableProps.keySet().stream().filter(
289-
x -> variableProps.getProperty(((String) x)) != null
290-
&& Constants.REQD_WDT_BUILD_ARGS.contains(((String) x).toUpperCase())
291-
).collect(Collectors.toList());
292-
matchingKeys.forEach(x -> {
293-
retVal.add(Constants.BUILD_ARG);
294-
retVal.add(((String) x).toUpperCase() + "=" + variableProps.getProperty((String) x));
295-
});
296-
logger.finer("Exiting CreateImage.getWdtRequiredBuildArgs: ");
297-
return retVal;
298-
}
299-
300173
/**
301174
* Builds a list of {@link InstallerFile} objects based on user input which are processed.
302175
* to download the required install artifacts
303176
*
304177
* @return list of InstallerFile
305178
* @throws Exception in case of error
306179
*/
307-
private List<InstallerFile> gatherRequiredInstallers() throws Exception {
180+
protected List<InstallerFile> gatherRequiredInstallers() throws Exception {
308181
logger.entering();
309-
List<InstallerFile> retVal = new LinkedList<>();
310-
if (wdtModelPath != null) {
311-
logger.finer("IMG-0001", InstallerType.WDT, wdtVersion);
312-
InstallerFile wdtInstaller = new InstallerFile(useCache, InstallerType.WDT, wdtVersion, null, null);
313-
retVal.add(wdtInstaller);
314-
addWdtUrl(wdtInstaller.getKey());
315-
}
182+
List<InstallerFile> retVal = super.gatherRequiredInstallers();
316183
logger.finer("IMG-0001", installerType, installerVersion);
317184
retVal.add(new InstallerFile(useCache, InstallerType.fromValue(installerType.toString()), installerVersion,
318185
userId, password));
@@ -324,32 +191,6 @@ private List<InstallerFile> gatherRequiredInstallers() throws Exception {
324191
return retVal;
325192
}
326193

327-
/**
328-
* Parses wdtVersion and constructs the url to download WDT and adds the url to cache.
329-
*
330-
* @param wdtKey key in the format wdt_0.17
331-
* @throws Exception in case of error
332-
*/
333-
private void addWdtUrl(String wdtKey) throws Exception {
334-
logger.entering(wdtKey);
335-
String wdtUrlKey = wdtKey + "_url";
336-
if (cacheStore.getValueFromCache(wdtKey) == null) {
337-
if (userId == null || password == null) {
338-
throw new Exception("CachePolicy prohibits download. Add the required wdt installer to cache");
339-
}
340-
List<String> wdtTags = HttpUtil.getWDTTags();
341-
String tagToMatch = "latest".equalsIgnoreCase(wdtVersion) ? wdtTags.get(0) :
342-
"weblogic-deploy-tooling-" + wdtVersion;
343-
if (wdtTags.contains(tagToMatch)) {
344-
String downloadLink = String.format(Constants.WDT_URL_FORMAT, tagToMatch);
345-
logger.info("IMG-0007", downloadLink);
346-
cacheStore.addToCache(wdtUrlKey, downloadLink);
347-
} else {
348-
throw new Exception("Couldn't find WDT download url for version:" + wdtVersion);
349-
}
350-
}
351-
logger.exiting();
352-
}
353194

354195
/**
355196
* Copies response files required for wls install to the tmp directory which provides docker build context.
@@ -373,23 +214,23 @@ private void copyResponseFilesToDir(String dirPath) throws IOException {
373214

374215
@Option(
375216
names = {"--type"},
376-
description = "Installer type. default: ${DEFAULT-VALUE}. supported values: ${COMPLETION-CANDIDATES}",
217+
description = "Installer type. Default: ${DEFAULT-VALUE}. Supported values: ${COMPLETION-CANDIDATES}",
377218
required = true,
378219
defaultValue = "wls"
379220
)
380221
private WLSInstallerType installerType;
381222

382223
@Option(
383224
names = {"--version"},
384-
description = "Installer version. default: ${DEFAULT-VALUE}",
225+
description = "Installer version. Default: ${DEFAULT-VALUE}",
385226
required = true,
386227
defaultValue = Constants.DEFAULT_WLS_VERSION
387228
)
388229
private String installerVersion;
389230

390231
@Option(
391232
names = {"--jdkVersion"},
392-
description = "Version of server jdk to install. default: ${DEFAULT-VALUE}",
233+
description = "Version of server jdk to install. Default: ${DEFAULT-VALUE}",
393234
required = true,
394235
defaultValue = Constants.DEFAULT_JDK_VERSION
395236
)
@@ -401,63 +242,13 @@ private void copyResponseFilesToDir(String dirPath) throws IOException {
401242
)
402243
private String fromImage;
403244

404-
@Option(
405-
names = {"--wdtModel"},
406-
description = "path to the wdt model file to create domain with"
407-
)
408-
private Path wdtModelPath;
409-
410-
@Option(
411-
names = {"--wdtArchive"},
412-
description = "path to wdt archive file used by wdt model"
413-
)
414-
private Path wdtArchivePath;
415-
416-
@Option(
417-
names = {"--wdtVariables"},
418-
description = "path to wdt variables file used by wdt model"
419-
)
420-
private Path wdtVariablesPath;
421-
422-
@Option(
423-
names = {"--wdtVersion"},
424-
description = "wdt version to create the domain",
425-
defaultValue = "latest"
426-
)
427-
private String wdtVersion;
428-
429-
@Option(
430-
names = {"--wdtDomainType"},
431-
description = "type of domain to create. default: ${DEFAULT-VALUE}. supported values: "
432-
+ "${COMPLETION-CANDIDATES}",
433-
defaultValue = "wls",
434-
required = true
435-
)
436-
private DomainType wdtDomainType;
437-
438-
@Option(
439-
names = "--wdtRunRCU",
440-
description = "whether to run rcu to create the required database schemas"
441-
)
442-
private boolean runRcu = false;
443-
444-
445-
@Option(
446-
names = {"--wdtDomainHome"},
447-
description = "pass to the -domain_home for wdt",
448-
defaultValue = "/u01/domains/base_domain"
449-
)
450-
private String wdtDomainHome;
451-
452-
453245
@Option(
454246
names = {"--opatchBugNumber"},
455247
description = "use this opatch patch bug number",
456248
defaultValue = "28186730"
457249
)
458250
private String opatchBugNumber;
459251

460-
461252
@Option(
462253
names = {"--installerResponseFile"},
463254
description = "path to a response file. Override the default responses for the Oracle installer"

0 commit comments

Comments
 (0)