diff --git a/.github/workflows/sonar-branch.yml b/.github/workflows/sonar-branch.yml index b4cb18f2..d141b5fe 100644 --- a/.github/workflows/sonar-branch.yml +++ b/.github/workflows/sonar-branch.yml @@ -27,7 +27,7 @@ jobs: - name: Sonar Scan run: | mvn -B sonar:sonar \ - -Dsonar.branch.name=main \ + -Dsonar.branch.name=${GITHUB_REF##*/} \ -Dsonar.projectKey=oracle_weblogic-image-tool env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/imagetool/pom.xml b/imagetool/pom.xml index 3fee7728..aaf84136 100644 --- a/imagetool/pom.xml +++ b/imagetool/pom.xml @@ -13,7 +13,7 @@ imagetool-parent com.oracle.weblogic.lifecycle.imagetool - 1.14.0 + 1.14.1 ../pom.xml diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruPatch.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruPatch.java index db8e5991..98e8f4aa 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruPatch.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruPatch.java @@ -3,9 +3,9 @@ package com.oracle.weblogic.imagetool.aru; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import java.util.stream.Stream; import javax.xml.xpath.XPathExpressionException; @@ -237,8 +237,14 @@ public static AruPatch selectPatch(List patches, String providedVersio logger.entering(patches, providedVersion, psuVersion, installerVersion); AruPatch selected = null; - Map patchMap = patches.stream().collect(Collectors - .toMap(AruPatch::version, aruPatch -> aruPatch)); + Map patchMap = new HashMap<>(); + for (AruPatch patch: patches) { + if (patchMap.containsKey(patch.version())) { + throw new IllegalStateException(Utils.getMessage("IMG-0122", patch.patchId(), patch.version())); + } + patchMap.put(patch.version(), patch); + } + // select the correct patch version (priority order: user provided version, PSU version, GA installer version) if (providedVersion != null) { // if the user provided a specific version, select the provided version, or fail @@ -270,6 +276,7 @@ public static AruPatch selectPatch(List patches, String providedVersio * @return true if this patch is applicable to the provided platform. */ public boolean isApplicableToTarget(int aruPlatform) { + logger.finer("AruPatch id {0} platform {1} checking against {2}", patchId, platform, aruPlatform); // if this patch is for platform 2000, always return true, else return true if platforms are equal. return platform == 2000 || platform == aruPlatform; } diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruUtil.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruUtil.java index a5a0660f..64c8f26a 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruUtil.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/AruUtil.java @@ -518,8 +518,11 @@ private List getPatchesOffline(String bugNumber) throws CacheStoreExce if (matcher.groupCount() == 3 && matcher.group(3) != null) { int aruPlatform = Architecture.fromString(matcher.group(3)).getAruPlatform(); patch.platform(Integer.toString(aruPlatform)); + } else { + // architecture was not specified in the cache key, assume generic platform + patch.platform("2000"); } - patch.description("UNAVAILABLE WHILE OFFLINE"); + patch.description("description unavailable while working offline"); patchesInCache.add(patch); } return patchesInCache; diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/PatchVersionException.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/PatchVersionException.java index ba3d8fb2..339fc5ea 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/PatchVersionException.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/aru/PatchVersionException.java @@ -12,7 +12,7 @@ public class PatchVersionException extends IOException { /** - * Signals that the bug number provided was not unique, and has multiple versions available. + * Signals that the bug number provided was unavailable for the requested or derived version. * * @param bugNumber the bug number that was searched * @param versionsAvailable the list of versions for patches of that bug diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntry.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntry.java index ff882d4b..5445696e 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntry.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntry.java @@ -25,7 +25,7 @@ public String getKey() { public CommandResponse call() throws Exception { try { if (patchId != null && !patchId.isEmpty()) { - Utils.validatePatchIds(Collections.singletonList(patchId), true); + Utils.validatePatchIds(Collections.singletonList(patchId), false); return addToCache(); } else { return CommandResponse.error("IMG-0076", "--patchId"); diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonPatchingOptions.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonPatchingOptions.java index 775ab06d..92a368ee 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonPatchingOptions.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/CommonPatchingOptions.java @@ -63,7 +63,7 @@ void initializeOptions() throws IOException, InvalidCredentialException, Invalid throw new InvalidCredentialException(); } - Utils.validatePatchIds(patches, false); + Utils.validatePatchIds(patches, true); } } @@ -211,6 +211,7 @@ String findPsuVersion(AruPatch aruPatch) { List resolveUserRequestedPatches(String psuVersion) throws XPathExpressionException, IOException, AruException { + logger.entering(psuVersion); List result = new ArrayList<>(patches.size()); // if the user specified the PSU as a normal bug number in the list of --patches, use that String effectivePsuVersion = psuVersion; @@ -248,6 +249,7 @@ List resolveUserRequestedPatches(String psuVersion) result.add(selectedVersion); } } + logger.exiting(result); return result; } diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/UpdateImage.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/UpdateImage.java index c79c75a0..8ad02fb1 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/UpdateImage.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/cli/menu/UpdateImage.java @@ -121,9 +121,7 @@ public CommandResponse call() throws Exception { if (userId == null) { logger.info("IMG-0009"); } else { - if (!Utils.validatePatchIds(patches, false)) { - return CommandResponse.error("Patch ID validation failed"); - } + Utils.validatePatchIds(patches, true); String oraclePatches = baseImageProperties.getProperty("oraclePatches", null); if (oraclePatches != null) { diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Constants.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Constants.java index 81e57719..dd0245f6 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Constants.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Constants.java @@ -23,8 +23,6 @@ public final class Constants { public static final String DELETE_ALL_FOR_SURE = "deleteAll4Sure"; public static final String HTTP = "http"; public static final String HTTPS = "https"; - public static final String PATCH_ID_REGEX = "^(\\d{8})(?:[_][0-9][0-9](?:\\.[0-9]){3,8}\\.(\\d+))?"; - public static final String RIGID_PATCH_ID_REGEX = "^(\\d{8})[_][0-9][0-9](?:\\.[0-9]){3,8}\\.(\\d+)"; public static final String BUSYBOX = "busybox"; public static final List BUSYBOX_OS_IDS = Collections.unmodifiableList(Arrays.asList("bb", "alpine")); public static final String ORACLE_LINUX = "ghcr.io/oracle/oraclelinux:8-slim"; diff --git a/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Utils.java b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Utils.java index 5aef7cd3..0c752f5d 100644 --- a/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Utils.java +++ b/imagetool/src/main/java/com/oracle/weblogic/imagetool/util/Utils.java @@ -43,6 +43,7 @@ import com.oracle.weblogic.imagetool.logging.LoggingFacade; import com.oracle.weblogic.imagetool.logging.LoggingFactory; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.PropertyKey; public class Utils { @@ -582,38 +583,36 @@ public static String getBuildWorkingDir() throws IOException { return workingDir; } + private static void validatePatchIds(List patches, Pattern pattern, + String example) throws InvalidPatchIdFormatException { + for (String patchId: patches) { + Matcher matcher = pattern.matcher(patchId); + if (!matcher.matches()) { + throw new InvalidPatchIdFormatException(patchId, example); + } + } + } + /** - * validatePatchIds validate the format of the patch ids. + * Validate the format of the patch ID. + * Simple ID: 12345678 + * Full ID: {bug number}_{version}_{architecture} * - * @param patches list of patch ids - * @return true if all patch IDs are valid , false otherwise. + * @param patches List of patch IDs to validate against the required format. + * @param allowSimpleId Allow simple bug number without version or architecture + * @throws InvalidPatchIdFormatException if any of the provide patch IDs are of invalid format */ - - public static boolean validatePatchIds(List patches, boolean rigid) throws InvalidPatchIdFormatException { - Pattern patchIdPattern; - if (rigid) { - patchIdPattern = Pattern.compile(Constants.RIGID_PATCH_ID_REGEX); + public static void validatePatchIds(@NotNull List patches, + boolean allowSimpleId) throws InvalidPatchIdFormatException { + if (allowSimpleId) { + validatePatchIds(patches, + Pattern.compile("^(\\d{8,9})(?:_\\d\\d(?:\\.\\d){3,8}\\.(\\d+)(_.*)?)?"), + "12345678[_12.2.1.3.0[_arm64]]"); } else { - patchIdPattern = Pattern.compile(Constants.PATCH_ID_REGEX); - } - if (patches != null && !patches.isEmpty()) { - for (String patchId : patches) { - logger.finer("pattern matching patchId: {0}", patchId); - Matcher matcher = patchIdPattern.matcher(patchId); - if (!matcher.matches()) { - String errorFormat; - if (rigid) { - errorFormat = "12345678_12.2.1.3.0"; - } else { - errorFormat = "12345678[_12.2.1.3.0]"; - } - - throw new InvalidPatchIdFormatException(patchId, errorFormat); - } - } + validatePatchIds(patches, + Pattern.compile("^(\\d{8,9})_\\d\\d(?:\\.\\d){3,8}\\.(\\d+)(_.*)?"), + "12345678_12.2.1.3.0[_arm64]"); } - - return true; } /** diff --git a/imagetool/src/main/resources/ImageTool.properties b/imagetool/src/main/resources/ImageTool.properties index 0c0b0314..4d9fefda 100644 --- a/imagetool/src/main/resources/ImageTool.properties +++ b/imagetool/src/main/resources/ImageTool.properties @@ -120,3 +120,4 @@ IMG-0118=Failed to clean up intermediate container images for build ID {0} IMG-0119=All parameters and options provided after the -- will be passed to the container image build command. IMG-0120=Retries exhausted, unable to download patch from Oracle. Try again later or manually add the patch to the cache to skip this download step. IMG-0121=Did not recognize architecture name {0}. Defaulted to AMD64. +IMG-0122=Invalid patch {0} for version {1}. A patch cannot be both generic and architecture specific. Remove the invalid entry from the cache, like {0}_{1}_xxx64. diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/PatchFileTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/PatchFileTest.java index 58e3ea57..4d4e4294 100644 --- a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/PatchFileTest.java +++ b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cachestore/PatchFileTest.java @@ -68,8 +68,9 @@ static void setup(@TempDir Path tempDir) addToCache(tempDir, "11100003_12.2.1.3.0", "p11100003_122130_Generic.zip"); addToCache(tempDir, "11100007_12.2.1.4.0_arm64", "p11100007_122140_ARM64.zip"); addToCache(tempDir, "11100007_12.2.1.4.0_amd64", "p11100007_122140_AMD64.zip"); - addToCache(tempDir, "11100007_12.2.1.4.0", "p11100007_122140_GENERIC.zip"); - + addToCache(tempDir, "11100008_12.2.1.4.0_arm64", "p11100008_122140_ARM64.zip"); + addToCache(tempDir, "11100008_12.2.1.4.0_amd64", "p11100008_122140_AMD64.zip"); + addToCache(tempDir, "11100008_12.2.1.4.0", "p11100008_122140_GENERIC.zip"); // disable console logging LoggingFacade logger = LoggingFactory.getLogger(PatchFile.class); originalLogLevel = logger.getLevel(); @@ -454,7 +455,7 @@ void resolveArmFile() throws IOException { @Test void findArmPatch() throws Exception { - // 11100007 has multiple patches, 1 ARM, 1 AMD, and 1 GENERIC + // 11100007 has multiple patches, 1 ARM and 1 AMD String patchId = "11100007"; String version = "12.2.1.4.0"; List aruPatches = AruUtil.rest().getPatches(patchId, null, null) @@ -472,4 +473,16 @@ void findArmPatch() throws Exception { assertNotNull(filePathFromCache, "Could not find new patch in cache"); assertEquals(filePath, filePathFromCache, "Patch in cache does not match"); } + + @Test + void illegalCacheEntry() throws Exception { + // 11100008 has multiple patches, 1 ARM, 1 AMD, and 1 GENERIC, generic and architecture specific cannot coexist + String patchId = "11100008"; + String version = "12.2.1.4.0"; + List aruPatches = AruUtil.rest().getPatches(patchId, null, null) + .filter(p -> p.isApplicableToTarget(Architecture.ARM64.getAruPlatform())) + .collect(Collectors.toList()); + assertThrows(IllegalStateException.class, + () -> AruPatch.selectPatch(aruPatches, version, null, version)); + } } diff --git a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntryTest.java b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntryTest.java index 107bbf27..e0538b40 100644 --- a/imagetool/src/test/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntryTest.java +++ b/imagetool/src/test/java/com/oracle/weblogic/imagetool/cli/cache/AddPatchEntryTest.java @@ -5,8 +5,11 @@ import java.io.PrintWriter; import java.io.StringWriter; +import java.util.Arrays; import com.oracle.weblogic.imagetool.api.model.CommandResponse; +import com.oracle.weblogic.imagetool.util.InvalidPatchIdFormatException; +import com.oracle.weblogic.imagetool.util.Utils; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import picocli.CommandLine; @@ -14,6 +17,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; @Tag("unit") class AddPatchEntryTest { @@ -33,7 +37,7 @@ void testMissingParameters() { // missing valid parameters should generate USAGE output int exitCode = cmd.execute("-x", "-y=123"); CommandResponse result = cmd.getExecutionResult(); - assertNull(result, "Should not have a response, picoli should intercept usage error"); + assertNull(result, "Should not have a response, picocli should intercept usage error"); assertEquals(CommandLine.ExitCode.USAGE, exitCode); } @@ -41,7 +45,7 @@ void testMissingParameters() { void testInvalidFileParameter() { CommandLine cmd = getCommand(); // invalid file (file does not exist), should generate an error response - int exitCode = cmd.execute("--patchId=12345678_12.2.1.3.0", "--path=/here/there"); + cmd.execute("--patchId=12345678_12.2.1.3.0", "--path=/here/there"); CommandResponse result = cmd.getExecutionResult(); assertNotNull(result, "Response missing from call to addPatch"); assertEquals(1, result.getStatus()); @@ -56,4 +60,24 @@ void testInvalidPatchId() { assertNotNull(result, "Response missing from call to addPatch"); assertEquals(1, result.getStatus()); } + + @Test + void validPatchIds() throws InvalidPatchIdFormatException { + String[] patchIds = {"12345678_12.2.1.4.0", "12345678_12.2.1.4.241001", "12345678_12.2.1.4.0_arm64"}; + Utils.validatePatchIds(Arrays.asList(patchIds), false); + } + + @Test + void invalidPatchIds1() { + String[] patchIds = {"12345678_12.2.1.4.0", "12345678", "12345678_12.2.1.4.0_arm64"}; + assertThrows(InvalidPatchIdFormatException.class, + () -> Utils.validatePatchIds(Arrays.asList(patchIds), false)); + } + + @Test + void invalidPatchIds2() { + String[] patchIds = {"12345678_12.2.1.4.0", "12345678_arm64", "12345678_12.2.1.4.0_arm64"}; + assertThrows(InvalidPatchIdFormatException.class, + () -> Utils.validatePatchIds(Arrays.asList(patchIds), false)); + } } diff --git a/installer/pom.xml b/installer/pom.xml index 3945847e..180f5bb1 100644 --- a/installer/pom.xml +++ b/installer/pom.xml @@ -13,7 +13,7 @@ imagetool-parent com.oracle.weblogic.lifecycle.imagetool - 1.14.0 + 1.14.1 ../pom.xml diff --git a/pom.xml b/pom.xml index 8f164472..d3a59bbb 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ 4.0.0 com.oracle.weblogic.lifecycle.imagetool imagetool-parent - 1.14.0 + 1.14.1 pom WebLogic Image Tool diff --git a/tests/pom.xml b/tests/pom.xml index 040a9f0b..31edfd4c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -12,7 +12,7 @@ imagetool-parent com.oracle.weblogic.lifecycle.imagetool - 1.14.0 + 1.14.1 ../pom.xml