diff --git a/Jenkinsfile b/Jenkinsfile index 1baa653a8..303b0fdc6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,14 +32,13 @@ pipeline { options { timeout(time: 30, unit: 'MINUTES') } environment { - DOCKER_HUB = credentials("${p['docker.credentials']}") ARTIFACTORY = credentials("${p['artifactory.credentials']}") + TESTCONTAINERS_IMAGE_SUBSTITUTOR = 'org.springframework.data.jdbc.ProxyImageNameSubstitutor' } steps { script { docker.image(p['docker.java.main.image']).inside(p['docker.java.inside.docker']) { - sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" sh "PROFILE=ci,all-dbs ci/test.sh" sh "ci/clean.sh" } @@ -63,14 +62,13 @@ pipeline { options { timeout(time: 30, unit: 'MINUTES') } environment { - DOCKER_HUB = credentials("${p['docker.credentials']}") ARTIFACTORY = credentials("${p['artifactory.credentials']}") + TESTCONTAINERS_IMAGE_SUBSTITUTOR = 'org.springframework.data.jdbc.ProxyImageNameSubstitutor' } steps { script { docker.image(p['docker.java.next.image']).inside(p['docker.java.inside.docker']) { - sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" sh "PROFILE=ci ci/test.sh" sh "ci/clean.sh" } @@ -85,14 +83,13 @@ pipeline { options { timeout(time: 30, unit: 'MINUTES') } environment { - DOCKER_HUB = credentials("${p['docker.credentials']}") ARTIFACTORY = credentials("${p['artifactory.credentials']}") + TESTCONTAINERS_IMAGE_SUBSTITUTOR = 'org.springframework.data.jdbc.ProxyImageNameSubstitutor' } steps { script { docker.image(p['docker.java.lts.image']).inside(p['docker.java.inside.docker']) { - sh "docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW}" sh "PROFILE=ci ci/test.sh" sh "ci/clean.sh" } diff --git a/ci/accept-third-party-license.sh b/ci/accept-third-party-license.sh index efc815ac4..4c58953b0 100755 --- a/ci/accept-third-party-license.sh +++ b/ci/accept-third-party-license.sh @@ -3,4 +3,5 @@ { echo "mcr.microsoft.com/mssql/server:2017-CU12" echo "ibmcom/db2:11.5.0.0a" -} > spring-data-jdbc/src/test/resources/container-license-acceptance.txt \ No newline at end of file + echo "harbor-repo.vmware.com/dockerhub-proxy-cache/ibmcom/db2:11.5.0.0a" +} > spring-data-jdbc/src/test/resources/container-license-acceptance.txt diff --git a/ci/test.sh b/ci/test.sh index b2421a696..da9b0bc57 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -3,6 +3,7 @@ set -euo pipefail ci/accept-third-party-license.sh + mkdir -p /tmp/jenkins-home chown -R 1001:1001 . MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" \ diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/ProxyImageNameSubstitutor.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/ProxyImageNameSubstitutor.java new file mode 100644 index 000000000..a80fae769 --- /dev/null +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/ProxyImageNameSubstitutor.java @@ -0,0 +1,84 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.jdbc; + +import java.util.Arrays; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.utility.DockerImageName; +import org.testcontainers.utility.ImageNameSubstitutor; + +/** + * An {@link ImageNameSubstitutor} only used on CI servers to leverage internal proxy solution, that needs to vary the + * prefix based on which container image is needed. + * + * @author Greg Turnquist + */ +public class ProxyImageNameSubstitutor extends ImageNameSubstitutor { + + private static final Logger LOG = LoggerFactory.getLogger(ProxyImageNameSubstitutor.class); + + private static final List NAMES_TO_PROXY_PREFIX = Arrays.asList("ryuk", "arm64v8/mariadb", "ibmcom/db2", + "gvenzl/oracle-xe"); + + private static final List NAMES_TO_LIBRARY_PROXY_PREFIX = Arrays.asList("mariadb", "mysql", "postgres"); + + private static final String PROXY_PREFIX = "harbor-repo.vmware.com/dockerhub-proxy-cache/"; + + private static final String LIBRARY_PROXY_PREFIX = PROXY_PREFIX + "library/"; + + @Override + public DockerImageName apply(DockerImageName dockerImageName) { + + if (NAMES_TO_PROXY_PREFIX.stream().anyMatch(s -> dockerImageName.asCanonicalNameString().contains(s))) { + + String transformedName = applyProxyPrefix(dockerImageName.asCanonicalNameString()); + LOG.info("Converting " + dockerImageName.asCanonicalNameString() + " to " + transformedName); + return DockerImageName.parse(transformedName); + } + + if (NAMES_TO_LIBRARY_PROXY_PREFIX.stream().anyMatch(s -> dockerImageName.asCanonicalNameString().contains(s))) { + + String transformedName = applyProxyAndLibraryPrefix(dockerImageName.asCanonicalNameString()); + LOG.info("Converting " + dockerImageName.asCanonicalNameString() + " to " + transformedName); + return DockerImageName.parse(transformedName); + } + + LOG.info("Not changing " + dockerImageName.asCanonicalNameString() + "..."); + return dockerImageName; + } + + @Override + protected String getDescription() { + return "Spring Data Proxy Image Name Substitutor"; + } + + /** + * Apply a non-library-based prefix. + */ + private static String applyProxyPrefix(String imageName) { + return PROXY_PREFIX + imageName; + } + + /** + * Apply a library based prefix. + */ + private static String applyProxyAndLibraryPrefix(String imageName) { + return LIBRARY_PROXY_PREFIX + imageName; + } +} diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index 69d2ef87d..31ace7bb7 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -84,6 +84,13 @@ test + + org.testcontainers + testcontainers + ${testcontainers} + test + +