Skip to content

Commit 80b05e3

Browse files
authored
improve OPatch error troubleshooting (#180)
* improve error message when duplicate patches are specified on the command line * Deprecated --type argument for AddPatchEntry (#179) * print the OPatch log to stdout upon failure * moved --type deprecation message to i18n
1 parent 8fa4529 commit 80b05e3

File tree

5 files changed

+36
-18
lines changed

5 files changed

+36
-18
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class AddPatchEntry extends CacheOperation {
3131
public CommandResponse call() throws Exception {
3232

3333
if (type != null) {
34-
logger.warning("[[cyan: --type]] is [[brightred: DEPRECATED]] and will be removed in an upcoming release.");
34+
logger.warning("IMG-0078");
3535
}
3636

3737
if (patchId != null && !patchId.isEmpty()

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.io.File;
77
import java.io.FileNotFoundException;
88
import java.io.IOException;
9+
import java.nio.file.FileAlreadyExistsException;
910
import java.nio.file.Files;
1011
import java.nio.file.Path;
1112
import java.nio.file.Paths;
@@ -112,7 +113,8 @@ DockerBuildCommand getInitialBuildCmd(String contextFolder) {
112113
logger.entering();
113114
DockerBuildCommand cmdBuilder = new DockerBuildCommand(contextFolder);
114115

115-
cmdBuilder.tag(imageTag)
116+
cmdBuilder.forceRm(!skipcleanup)
117+
.tag(imageTag)
116118
.network(buildNetwork)
117119
.pull(buildPull)
118120
.buildArg("http_proxy", httpProxyUrl)
@@ -229,13 +231,12 @@ void handlePatchFiles() throws Exception {
229231
* @param previousInventory existing inventory found in the "from" image
230232
* @throws Exception in case of error
231233
*/
232-
void handlePatchFiles(String previousInventory, String existingPsuVersion) throws Exception {
233-
logger.entering(existingPsuVersion);
234+
void handlePatchFiles(String previousInventory, String psuVersion) throws Exception {
235+
logger.entering(psuVersion);
234236
if (!applyingPatches()) {
235237
return;
236238
}
237239

238-
String psuVersion = existingPsuVersion;
239240
String toPatchesPath = createPatchesTempDirectory().toAbsolutePath().toString();
240241

241242
List<PatchFile> patchFiles = new ArrayList<>();
@@ -287,7 +288,11 @@ void handlePatchFiles(String previousInventory, String existingPsuVersion) throw
287288
String patchLocation = patch.resolve(cache());
288289
if (patchLocation != null && !Utils.isEmptyString(patchLocation)) {
289290
File patchFile = new File(patchLocation);
290-
Files.copy(Paths.get(patchLocation), Paths.get(toPatchesPath, patchFile.getName()));
291+
try {
292+
Files.copy(Paths.get(patchLocation), Paths.get(toPatchesPath, patchFile.getName()));
293+
} catch (FileAlreadyExistsException ee) {
294+
logger.warning("IMG-0077", patch.getKey());
295+
}
291296
} else {
292297
logger.severe("IMG-0024", patch.getKey());
293298
}
@@ -389,8 +394,7 @@ String getPassword() {
389394

390395
@Option(
391396
names = {"--skipcleanup"},
392-
description = "Do no delete Docker context folder or intermediate images.",
393-
hidden = true
397+
description = "Do no delete Docker context folder, intermediate images, and failed build container."
394398
)
395399
boolean skipcleanup = false;
396400

imagetool/src/main/java/com/oracle/weblogic/imagetool/util/DockerBuildCommand.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ public class DockerBuildCommand {
3636
public DockerBuildCommand(String contextFolder) {
3737
Objects.requireNonNull(contextFolder);
3838
buildArgs = new ArrayList<>();
39-
command = Stream.of("docker", "build",
40-
"--force-rm=true", "--no-cache").collect(Collectors.toList());
39+
command = Stream.of("docker", "build", "--no-cache").collect(Collectors.toList());
4140
context = contextFolder;
4241
}
4342

@@ -59,6 +58,19 @@ public DockerBuildCommand tag(String value) {
5958
return this;
6059
}
6160

61+
/**
62+
* Always remove intermediate containers if set to true.
63+
* By default, Docker leaves intermediate containers when the build fails which is not ideal for CI/CD servers.
64+
* @param value true to enable --force-rm on docker build.
65+
* @return this
66+
*/
67+
public DockerBuildCommand forceRm(boolean value) {
68+
if (value) {
69+
command.add("--force-rm");
70+
}
71+
return this;
72+
}
73+
6274
/**
6375
* Add a --build-arg to the Docker build command.
6476
* Conceal is defaulted to false.
@@ -137,7 +149,7 @@ public DockerBuildCommand run(Path dockerLog)
137149
logger.finer("Starting docker process...");
138150
final Process process = processBuilder.start();
139151
logger.finer("Docker process started");
140-
writeFromInputToOutputStreams(process.getInputStream(), outputStreams.toArray(new OutputStream[0]));
152+
writeFromInputToOutputStreams(process.getInputStream(), outputStreams);
141153
logger.finer("Waiting for Docker to finish");
142154
if (process.waitFor() != 0) {
143155
Utils.processError(process);
@@ -175,7 +187,7 @@ private Path createFile(Path filePath) {
175187
return logFilePath;
176188
}
177189

178-
private void writeFromInputToOutputStreams(InputStream inputStream, OutputStream... outputStreams) {
190+
private void writeFromInputToOutputStreams(InputStream inputStream, List<OutputStream> outputStreams) {
179191
Thread readerThread = new Thread(() -> {
180192
try (
181193
BufferedReader processReader = new BufferedReader(new InputStreamReader(inputStream));
@@ -196,12 +208,10 @@ private void writeFromInputToOutputStreams(InputStream inputStream, OutputStream
196208
readerThread.start();
197209
}
198210

199-
private CloseableList<PrintWriter> createPrintWriters(OutputStream... outputStreams) {
211+
private CloseableList<PrintWriter> createPrintWriters(List<OutputStream> outputStreams) {
200212
CloseableList<PrintWriter> retVal = new CloseableList<>();
201-
if (outputStreams != null) {
202-
for (OutputStream outputStream : outputStreams) {
203-
retVal.add(new PrintWriter(new OutputStreamWriter(outputStream), true));
204-
}
213+
for (OutputStream outputStream : outputStreams) {
214+
retVal.add(new PrintWriter(new OutputStreamWriter(outputStream), true));
205215
}
206216
return retVal;
207217
}

imagetool/src/main/resources/ImageTool.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,5 @@ IMG-0073=Invalid file {0} listed for Verrazzano model
7575
IMG-0074=OPatch will not be updated, fromImage has version {0}, available version is {1}
7676
IMG-0075=Added patch entry [[cyan: {0}]]={1}
7777
IMG-0076=Cache key {0} already exists, remove it first
78+
IMG-0077=Skipping duplicate patch {0}. Patch file already exists in the build context folder. Did you accidentally list the patch twice?
79+
IMG-0078=[[cyan: --type]] is [[brightred: DEPRECATED]] and will be removed in an upcoming release.

imagetool/src/main/resources/docker-files/Create_Image.mustache

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ RUN cd {{{tempDir}}}/opatch \
114114

115115
{{#isPatchingEnabled}}
116116
RUN {{{oracle_home}}}/OPatch/opatch napply -silent -oh {{{oracle_home}}} -phBaseDir {{{tempDir}}}/patches \
117-
&& {{{oracle_home}}}/OPatch/opatch util cleanup -silent -oh {{{oracle_home}}}
117+
&& test $? -eq 0 \
118+
&& {{{oracle_home}}}/OPatch/opatch util cleanup -silent -oh {{{oracle_home}}} \
119+
|| (cat {{{oracle_home}}}/cfgtoollogs/opatch/opatch*.log && exit 1)
118120
{{/isPatchingEnabled}}
119121

120122
{{#afterFmwInstall}}

0 commit comments

Comments
 (0)