mirror of https://github.com/apache/lucene.git
SOLR-15075: Solr docker gradle improvements (#2197)
* Removed docker plugin from gradle builds. * Removed package docker image. * Tasks now have correct inputs/outputs/dependencies. * Move gradle help text to docker folder. * Reduce duplicated Docker layer by doing file removal and chmod in another stage. Co-authored-by: David Smiley <dsmiley@apache.org>
This commit is contained in:
parent
6c72e2e17b
commit
2b8d7bcd6a
|
@ -38,6 +38,8 @@ jobs:
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-gradle-docker-
|
${{ runner.os }}-gradle-docker-
|
||||||
${{ runner.os }}-gradle-
|
${{ runner.os }}-gradle-
|
||||||
|
- name: Initialize gradle settings
|
||||||
|
run: ./gradlew localSettings
|
||||||
- name: Build Docker image with Gradle
|
- name: Build Docker image with Gradle
|
||||||
run: ./gradlew solr:docker:docker
|
run: ./gradlew solr:docker:docker
|
||||||
- name: Run tests on Docker image
|
- name: Run tests on Docker image
|
||||||
|
|
|
@ -25,7 +25,6 @@ plugins {
|
||||||
id 'de.thetaphi.forbiddenapis' version '3.1' apply false
|
id 'de.thetaphi.forbiddenapis' version '3.1' apply false
|
||||||
id "de.undercouch.download" version "4.0.2" apply false
|
id "de.undercouch.download" version "4.0.2" apply false
|
||||||
id "net.ltgt.errorprone" version "1.2.1" apply false
|
id "net.ltgt.errorprone" version "1.2.1" apply false
|
||||||
id "com.palantir.docker" version "0.25.0" apply false
|
|
||||||
id 'com.diffplug.spotless' version "5.8.2" apply false
|
id 'com.diffplug.spotless' version "5.8.2" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ configure(rootProject) {
|
||||||
["Git", "help/git.txt", "Git assistance and guides."],
|
["Git", "help/git.txt", "Git assistance and guides."],
|
||||||
["ValidateLogCalls", "help/validateLogCalls.txt", "How to use logging calls efficiently."],
|
["ValidateLogCalls", "help/validateLogCalls.txt", "How to use logging calls efficiently."],
|
||||||
["IDEs", "help/IDEs.txt", "IDE support."],
|
["IDEs", "help/IDEs.txt", "IDE support."],
|
||||||
["Docker", "help/docker.txt", "Building Solr Docker images."],
|
["Docker", "solr/docker/gradle-help.txt", "Building Solr Docker images."],
|
||||||
]
|
]
|
||||||
|
|
||||||
helpFiles.each { section, path, sectionInfo ->
|
helpFiles.each { section, path, sectionInfo ->
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
Docker Images for Solr
|
|
||||||
======================
|
|
||||||
|
|
||||||
Solr docker images are built using Palantir's Docker Gradle plugin, https://github.com/palantir/gradle-docker.
|
|
||||||
|
|
||||||
Common Inputs
|
|
||||||
-------------
|
|
||||||
|
|
||||||
The docker image and its tag can be customized via the following options, all accepted via both Environment Variables and Gradle Properties.
|
|
||||||
|
|
||||||
Docker Image Repository:
|
|
||||||
Default: "apache/solr"
|
|
||||||
EnvVar: SOLR_DOCKER_IMAGE_REPO
|
|
||||||
Gradle Property: -Psolr.docker.imageRepo
|
|
||||||
|
|
||||||
Docker Image Tag:
|
|
||||||
Default: the Solr version, e.g. "9.0.0-SNAPSHOT"
|
|
||||||
EnvVar: SOLR_DOCKER_IMAGE_TAG
|
|
||||||
Gradle Property: -Psolr.docker.imageTag
|
|
||||||
|
|
||||||
Docker Image Name: (Use this to explicitly set a whole image name. If given, the image repo and image version options above are ignored.)
|
|
||||||
Default: {image_repo}/{image_tag} (both options provided above, with defaults)
|
|
||||||
EnvVar: SOLR_DOCKER_IMAGE_NAME
|
|
||||||
Gradle Property: -Psolr.docker.imageName
|
|
||||||
|
|
||||||
Building
|
|
||||||
--------
|
|
||||||
|
|
||||||
In order to build the Solr Docker image, run:
|
|
||||||
|
|
||||||
gradlew docker
|
|
||||||
|
|
||||||
The docker build task accepts the following inputs, in addition to the common inputs listed above:
|
|
||||||
|
|
||||||
Base Docker Image: (The docker image used for the "FROM" in the Solr Dockerfile)
|
|
||||||
Default: "openjdk:11-jre-slim"
|
|
||||||
EnvVar: SOLR_DOCKER_BASE_IMAGE
|
|
||||||
Gradle Property: -Psolr.docker.baseImage
|
|
||||||
|
|
||||||
Github URL or Mirror: (The URL of github or a mirror of github releases. This is of use when building the docker image behind a firewall that does not have access to external Github.)
|
|
||||||
Default: "github.com"
|
|
||||||
EnvVar: SOLR_DOCKER_GITHUB_URL
|
|
||||||
Gradle Property: -Psolr.docker.githubUrl
|
|
||||||
|
|
||||||
Testing
|
|
||||||
-------
|
|
||||||
|
|
||||||
To test the docker image, run:
|
|
||||||
|
|
||||||
gradlew dockerTest
|
|
||||||
|
|
||||||
If a custom docker image name was used, via one of the common inputs described above, then the same input must be used while testing.
|
|
||||||
|
|
||||||
You can also specify an explicit list of tests to run, or an explicit list of tests to ignore.
|
|
||||||
Both inputs are optional, and by default all tests will be run.
|
|
||||||
|
|
||||||
gradlew testDocker --tests create_core,demo
|
|
||||||
gradlew testDocker --ignore demo-tini,initdb
|
|
|
@ -74,4 +74,3 @@ include "solr:example"
|
||||||
include "solr:documentation"
|
include "solr:documentation"
|
||||||
include "solr:packaging"
|
include "solr:packaging"
|
||||||
include "solr:docker"
|
include "solr:docker"
|
||||||
include "solr:docker:package"
|
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
ARG SOLR_PACKAGE_IMAGE
|
|
||||||
ARG BASE_IMAGE=openjdk:11-jre-slim
|
ARG BASE_IMAGE=openjdk:11-jre-slim
|
||||||
|
|
||||||
FROM $SOLR_PACKAGE_IMAGE as solr_package
|
FROM $BASE_IMAGE as input
|
||||||
|
ARG SOLR_VERSION
|
||||||
|
|
||||||
FROM $BASE_IMAGE as runtime
|
# ADD extracts tgz !
|
||||||
|
ADD /releases/solr-$SOLR_VERSION.tgz /opt/
|
||||||
|
COPY /scripts /scripts
|
||||||
|
|
||||||
|
# remove what we don't want; ensure permissions are right
|
||||||
|
# TODO; arguably these permissions should have been set correctly previously in the TAR
|
||||||
|
RUN set -ex; \
|
||||||
|
rm -Rf /opt/solr-$SOLR_VERSION/docs /opt/solr-$SOLR_VERSION/dist/{solr-solrj-$SOLR_VERSION.jar,solrj-lib,solr-test-framework-$SOLR_VERSION.jar,test-framework}; \
|
||||||
|
find "/opt/solr-$SOLR_VERSION" -type d -print0 | xargs -0 chmod 0755; \
|
||||||
|
find "/opt/solr-$SOLR_VERSION" -type f -print0 | xargs -0 chmod 0644; \
|
||||||
|
chmod -R 0755 /scripts "/opt/solr-$SOLR_VERSION/bin" "/opt/solr-$SOLR_VERSION/contrib/prometheus-exporter/bin/solr-exporter" "/opt/solr-$SOLR_VERSION/server/scripts/cloud-scripts"
|
||||||
|
|
||||||
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
LABEL maintainer="The Apache Lucene/Solr Project"
|
LABEL maintainer="The Apache Lucene/Solr Project"
|
||||||
LABEL repository="https://github.com/apache/lucene-solr"
|
LABEL repository="https://github.com/apache/lucene-solr"
|
||||||
|
@ -13,7 +25,7 @@ ARG GITHUB_URL=github.com
|
||||||
|
|
||||||
RUN set -ex; \
|
RUN set -ex; \
|
||||||
apt-get update; \
|
apt-get update; \
|
||||||
apt-get -y install acl dirmngr gpg lsof procps wget netcat gosu tini; \
|
apt-get -y install acl dirmngr lsof procps wget netcat gosu tini; \
|
||||||
rm -rf /var/lib/apt/lists/*; \
|
rm -rf /var/lib/apt/lists/*; \
|
||||||
cd /usr/local/bin; wget -nv https://${GITHUB_URL}/apangin/jattach/releases/download/v1.5/jattach; chmod 755 jattach; \
|
cd /usr/local/bin; wget -nv https://${GITHUB_URL}/apangin/jattach/releases/download/v1.5/jattach; chmod 755 jattach; \
|
||||||
echo >jattach.sha512 "d8eedbb3e192a8596c08efedff99b9acf1075331e1747107c07cdb1718db2abe259ef168109e46bd4cf80d47d43028ff469f95e6ddcbdda4d7ffa73a20e852f9 jattach"; \
|
echo >jattach.sha512 "d8eedbb3e192a8596c08efedff99b9acf1075331e1747107c07cdb1718db2abe259ef168109e46bd4cf80d47d43028ff469f95e6ddcbdda4d7ffa73a20e852f9 jattach"; \
|
||||||
|
@ -35,34 +47,25 @@ RUN set -ex; \
|
||||||
groupadd -r --gid "$SOLR_GID" "$SOLR_GROUP"; \
|
groupadd -r --gid "$SOLR_GID" "$SOLR_GROUP"; \
|
||||||
useradd -r --uid "$SOLR_UID" --gid "$SOLR_GID" "$SOLR_USER"
|
useradd -r --uid "$SOLR_UID" --gid "$SOLR_GID" "$SOLR_USER"
|
||||||
|
|
||||||
COPY --chown=0:0 scripts /opt/docker-solr/scripts
|
COPY --from=input scripts /opt/docker-solr/scripts
|
||||||
|
|
||||||
ARG SOLR_VERSION
|
ARG SOLR_VERSION
|
||||||
|
|
||||||
# Used by solr-fg
|
# Used by solr-fg
|
||||||
ENV SOLR_VERSION $SOLR_VERSION
|
ENV SOLR_VERSION $SOLR_VERSION
|
||||||
|
|
||||||
COPY --from=solr_package "/opt/solr-$SOLR_VERSION.tgz" "/opt/solr-$SOLR_VERSION.tgz"
|
COPY --from=input /opt/solr-$SOLR_VERSION /opt/solr-$SOLR_VERSION
|
||||||
|
|
||||||
RUN set -ex; \
|
RUN set -ex; \
|
||||||
tar -C /opt --extract --file "/opt/solr-$SOLR_VERSION.tgz" && \
|
|
||||||
rm "/opt/solr-$SOLR_VERSION.tgz"; \
|
|
||||||
(cd /opt; ln -s "solr-$SOLR_VERSION" solr); \
|
(cd /opt; ln -s "solr-$SOLR_VERSION" solr); \
|
||||||
rm -Rf /opt/solr/docs/ /opt/solr/dist/{solr-solrj-$SOLR_VERSION.jar,solrj-lib,solr-test-framework-$SOLR_VERSION.jar,test-framework}; \
|
mkdir -p /opt/solr/server/solr/lib /docker-entrypoint-initdb.d; \
|
||||||
mkdir -p /opt/solr/server/solr/lib /docker-entrypoint-initdb.d /opt/docker-solr; \
|
|
||||||
chown -R 0:0 "/opt/solr-$SOLR_VERSION"; \
|
|
||||||
find "/opt/solr-$SOLR_VERSION" -type d -print0 | xargs -0 chmod 0755; \
|
|
||||||
find "/opt/solr-$SOLR_VERSION" -type f -print0 | xargs -0 chmod 0644; \
|
|
||||||
chmod -R 0755 "/opt/solr-$SOLR_VERSION/bin" "/opt/solr-$SOLR_VERSION/contrib/prometheus-exporter/bin/solr-exporter" /opt/solr-$SOLR_VERSION/server/scripts/cloud-scripts; \
|
|
||||||
cp /opt/solr/bin/solr.in.sh /etc/default/solr.in.sh; \
|
cp /opt/solr/bin/solr.in.sh /etc/default/solr.in.sh; \
|
||||||
mv /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig; \
|
mv /opt/solr/bin/solr.in.sh /opt/solr/bin/solr.in.sh.orig; \
|
||||||
mv /opt/solr/bin/solr.in.cmd /opt/solr/bin/solr.in.cmd.orig; \
|
mv /opt/solr/bin/solr.in.cmd /opt/solr/bin/solr.in.cmd.orig; \
|
||||||
chown root:0 /etc/default/solr.in.sh; \
|
|
||||||
chmod 0664 /etc/default/solr.in.sh; \
|
chmod 0664 /etc/default/solr.in.sh; \
|
||||||
mkdir -p -m0770 /var/solr; \
|
mkdir -p -m0770 /var/solr; \
|
||||||
sed -i -e "s/\"\$(whoami)\" == \"root\"/\$(id -u) == 0/" /opt/solr/bin/solr; \
|
sed -i -e "s/\"\$(whoami)\" == \"root\"/\$(id -u) == 0/" /opt/solr/bin/solr; \
|
||||||
sed -i -e 's/lsof -PniTCP:/lsof -t -PniTCP:/' /opt/solr/bin/solr; \
|
sed -i -e 's/lsof -PniTCP:/lsof -t -PniTCP:/' /opt/solr/bin/solr; \
|
||||||
chown -R "0:0" /opt/solr-$SOLR_VERSION /docker-entrypoint-initdb.d /opt/docker-solr; \
|
|
||||||
chown -R "$SOLR_USER:0" /var/solr;
|
chown -R "$SOLR_USER:0" /var/solr;
|
||||||
|
|
||||||
VOLUME /var/solr
|
VOLUME /var/solr
|
||||||
|
|
|
@ -76,7 +76,7 @@ If you want to persist the data, mount a volume or directory on `/var/solr`.
|
||||||
Solr expects some files and directories in `/var/solr`; if you use your own directory or volume you can either pre-populate them, or let Solr docker copy them for you. See [init-var-solr](scripts/init-var-solr).
|
Solr expects some files and directories in `/var/solr`; if you use your own directory or volume you can either pre-populate them, or let Solr docker copy them for you. See [init-var-solr](scripts/init-var-solr).
|
||||||
If you want to use custom configuration, mount it in the appropriate place. See below for examples.
|
If you want to use custom configuration, mount it in the appropriate place. See below for examples.
|
||||||
|
|
||||||
The Solr docker distribution adds [scripts](include/scripts) in `/opt/docker-solr/scripts` to make it easier to use under Docker, for example to create cores on container startup.
|
The Solr docker distribution adds [scripts](scripts) in `/opt/docker-solr/scripts` to make it easier to use under Docker, for example to create cores on container startup.
|
||||||
|
|
||||||
## Creating cores
|
## Creating cores
|
||||||
|
|
||||||
|
|
|
@ -18,106 +18,192 @@
|
||||||
import com.google.common.base.Preconditions
|
import com.google.common.base.Preconditions
|
||||||
import com.google.common.base.Strings
|
import com.google.common.base.Strings
|
||||||
|
|
||||||
apply plugin: 'base'
|
|
||||||
apply plugin: 'com.palantir.docker'
|
|
||||||
|
|
||||||
subprojects {
|
|
||||||
apply plugin: 'base'
|
|
||||||
apply plugin: 'com.palantir.docker'
|
|
||||||
}
|
|
||||||
|
|
||||||
description = 'Solr Docker image'
|
description = 'Solr Docker image'
|
||||||
|
|
||||||
def dockerPackage = project(':solr:docker:package')
|
apply plugin: 'base'
|
||||||
|
|
||||||
dependencies {
|
|
||||||
docker dockerPackage
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Solr Docker inputs
|
||||||
def dockerImageRepo = propertyOrEnvOrDefault("solr.docker.imageRepo", "SOLR_DOCKER_IMAGE_REPO", "apache/solr")
|
def dockerImageRepo = propertyOrEnvOrDefault("solr.docker.imageRepo", "SOLR_DOCKER_IMAGE_REPO", "apache/solr")
|
||||||
def dockerImageTag = propertyOrEnvOrDefault("solr.docker.imageTag", "SOLR_DOCKER_IMAGE_TAG", "${version}")
|
def dockerImageTag = propertyOrEnvOrDefault("solr.docker.imageTag", "SOLR_DOCKER_IMAGE_TAG", "${version}")
|
||||||
def dockerImageName = propertyOrEnvOrDefault("solr.docker.imageName", "SOLR_DOCKER_IMAGE_NAME", "${dockerImageRepo}:${dockerImageTag}")
|
def dockerImageName = propertyOrEnvOrDefault("solr.docker.imageName", "SOLR_DOCKER_IMAGE_NAME", "${dockerImageRepo}:${dockerImageTag}")
|
||||||
def baseDockerImage = propertyOrEnvOrDefault("solr.docker.baseImage", "SOLR_DOCKER_BASE_IMAGE", 'openjdk:11-jre-slim')
|
def baseDockerImage = propertyOrEnvOrDefault("solr.docker.baseImage", "SOLR_DOCKER_BASE_IMAGE", 'openjdk:11-jre-slim')
|
||||||
def githubUrlOrMirror = propertyOrEnvOrDefault("solr.docker.githubUrl", "SOLR_DOCKER_GITHUB_URL", 'github.com')
|
def githubUrlOrMirror = propertyOrEnvOrDefault("solr.docker.githubUrl", "SOLR_DOCKER_GITHUB_URL", 'github.com')
|
||||||
|
|
||||||
docker {
|
// Build directory locations
|
||||||
name = dockerImageName
|
def dockerBuildDistribution = "$buildDir/distributions"
|
||||||
files file('include')
|
def imageIdFile = "$buildDir/image-id"
|
||||||
buildArgs(['BASE_IMAGE' : baseDockerImage, 'SOLR_PACKAGE_IMAGE' : 'apache/solr-build:local-package', 'SOLR_VERSION': "${version}", 'GITHUB_URL': githubUrlOrMirror])
|
|
||||||
|
configurations {
|
||||||
|
packaging {
|
||||||
|
canBeResolved = true
|
||||||
|
}
|
||||||
|
dockerImage {
|
||||||
|
canBeResolved = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.docker {
|
dependencies {
|
||||||
// In order to create the solr docker image, the solr package image must be created first.
|
packaging project(path: ":solr:packaging", configuration: 'archives')
|
||||||
dependsOn(dockerPackage.tasks.docker)
|
|
||||||
|
dockerImage files(imageIdFile) {
|
||||||
|
builtBy 'dockerBuild'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task dockerTar(type: Tar) {
|
||||||
|
group = 'Docker'
|
||||||
|
description = 'Package docker context to prepare for docker build'
|
||||||
|
|
||||||
|
dependsOn configurations.packaging
|
||||||
|
into('scripts') {
|
||||||
|
from file('scripts')
|
||||||
|
fileMode 755
|
||||||
|
}
|
||||||
|
into('releases') {
|
||||||
|
from configurations.packaging
|
||||||
|
include '*.tgz'
|
||||||
|
}
|
||||||
|
from file('Dockerfile')
|
||||||
|
destinationDirectory = file(dockerBuildDistribution)
|
||||||
|
extension 'tgz'
|
||||||
|
compression = Compression.GZIP
|
||||||
|
}
|
||||||
|
|
||||||
|
task dockerBuild(dependsOn: tasks.dockerTar) {
|
||||||
|
group = 'Docker'
|
||||||
|
description = 'Build Solr docker image'
|
||||||
|
|
||||||
|
// Ensure that the docker image is rebuilt on build-arg changes or changes in the docker context
|
||||||
|
inputs.properties([
|
||||||
|
baseDockerImage: baseDockerImage,
|
||||||
|
githubUrlOrMirror: githubUrlOrMirror,
|
||||||
|
version: version
|
||||||
|
])
|
||||||
|
inputs.dir(dockerBuildDistribution)
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
exec {
|
||||||
|
standardInput = tasks.dockerTar.outputs.files.singleFile.newDataInputStream()
|
||||||
|
commandLine "docker", "build",
|
||||||
|
"--iidfile", imageIdFile,
|
||||||
|
"--build-arg", "BASE_IMAGE=${inputs.properties.baseDockerImage}",
|
||||||
|
"--build-arg", "SOLR_VERSION=${version}",
|
||||||
|
"--build-arg", "GITHUB_URL=${inputs.properties.githubUrlOrMirror}",
|
||||||
|
"-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Print information on the image after it has been created
|
// Print information on the image after it has been created
|
||||||
doLast {
|
doLast {
|
||||||
|
def dockerImageId = file(imageIdFile).text
|
||||||
project.logger.lifecycle("Solr Docker Image Created")
|
project.logger.lifecycle("Solr Docker Image Created")
|
||||||
project.logger.lifecycle("\tName: $dockerImageName")
|
project.logger.lifecycle("\tID: \t$dockerImageId")
|
||||||
project.logger.lifecycle("\tBase Image: $baseDockerImage")
|
project.logger.lifecycle("\tBase Image: \t$baseDockerImage")
|
||||||
|
project.logger.lifecycle("\tSolr Version: \t$version")
|
||||||
|
}
|
||||||
|
|
||||||
|
outputs.files(imageIdFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
task dockerTag(dependsOn: tasks.dockerBuild) {
|
||||||
|
group = 'Docker'
|
||||||
|
description = 'Tag Solr docker image'
|
||||||
|
|
||||||
|
def dockerImageIdFile = file(imageIdFile)
|
||||||
|
// Ensure that the docker image is re-tagged if the image ID or desired tag changes
|
||||||
|
inputs.properties([
|
||||||
|
dockerImageName: dockerImageName,
|
||||||
|
])
|
||||||
|
inputs.file(dockerImageIdFile)
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
def dockerImageId = dockerImageIdFile.text
|
||||||
|
|
||||||
|
exec {
|
||||||
|
commandLine "docker", "tag", dockerImageId, inputs.properties.dockerImageName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print information on the image after it has been created
|
||||||
|
project.logger.lifecycle("Solr Docker Image Tagged")
|
||||||
|
project.logger.lifecycle("\tID: \t$dockerImageId")
|
||||||
|
project.logger.lifecycle("\tTag: \t$dockerImageName")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DockerTestSuite extends DefaultTask {
|
task testDocker(dependsOn: tasks.dockerBuild) {
|
||||||
private String solrImageName = null;
|
group = 'Docker'
|
||||||
private List<String> tests = new ArrayList<>();
|
description = 'Test Solr docker image'
|
||||||
private List<String> ignore = new ArrayList<>();
|
|
||||||
|
|
||||||
@OutputDirectory
|
def inputDir = "tests/cases"
|
||||||
abstract DirectoryProperty getOutputDir()
|
def outputDir = "$buildDir/tmp/tests"
|
||||||
|
|
||||||
public void setSolrImageName(String solrImageName) {
|
// Ensure that the docker image is re-tested if the image ID changes or the test files change
|
||||||
this.solrImageName = solrImageName
|
inputs.properties([
|
||||||
}
|
includeTests: new HashSet(Arrays.asList(propertyOrEnvOrDefault("solr.docker.tests.include", "SOLR_DOCKER_TESTS_INCLUDE", ",").split(","))),
|
||||||
|
excludeTests: new HashSet(Arrays.asList(propertyOrEnvOrDefault("solr.docker.tests.exclude", "SOLR_DOCKER_TESTS_EXCLUDE", ",").split(",")))
|
||||||
|
])
|
||||||
|
inputs.file(imageIdFile)
|
||||||
|
inputs.dir(inputDir)
|
||||||
|
|
||||||
public String getSolrImageName() {
|
doLast {
|
||||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(solrImageName), "solrImageName is a required dockerTests configuration item.")
|
def solrImageId = tasks.dockerBuild.outputs.files.singleFile.text
|
||||||
return solrImageName
|
def solrImageName = solrImageId.substring(7, 14)
|
||||||
}
|
|
||||||
|
|
||||||
@Option(option = "tests", description = "Only run these specified tests, comma separated.")
|
|
||||||
public void setTests(List<String> tests) {
|
|
||||||
this.tests = tests;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Input
|
|
||||||
public List<String> getTests() {
|
|
||||||
return tests;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Option(option = "ignore", description = "Ignore these tests, comma separated.")
|
|
||||||
public void setIgnore(List<String> ignore) {
|
|
||||||
this.ignore = ignore;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Input
|
|
||||||
public List<String> getIgnore() {
|
|
||||||
return ignore;
|
|
||||||
}
|
|
||||||
|
|
||||||
@TaskAction
|
|
||||||
void execute() {
|
|
||||||
// Print information on the image before it is tested
|
// Print information on the image before it is tested
|
||||||
project.logger.lifecycle("Testing Solr Image: $solrImageName\n")
|
logger.lifecycle("Testing Solr Image:")
|
||||||
def sourceDir = project.file("tests/cases")
|
logger.lifecycle("\tID: $solrImageId\n")
|
||||||
|
|
||||||
|
// Run the tests
|
||||||
|
def sourceDir = file(inputDir)
|
||||||
sourceDir.eachFile { file ->
|
sourceDir.eachFile { file ->
|
||||||
def testName = file.getName()
|
def testName = file.getName()
|
||||||
def testCaseBuildDir = outputDir.dir(testName).get().toString()
|
def testCaseBuildDir = "${outputDir}/${testName}"
|
||||||
|
|
||||||
// If specific tests are specified, only run those. Otherwise run all that are not ignored.
|
// If specific tests are specified, only run those. Otherwise run all that are not ignored.
|
||||||
def runTest = !this.tests.isEmpty() ? tests.contains(testName) : !ignore.contains(testName)
|
def runTest = !inputs.properties.includeTests.isEmpty() ? inputs.properties.includeTests.contains(testName) : !inputs.properties.excludeTests.contains(testName)
|
||||||
if (runTest) {
|
if (runTest) {
|
||||||
project.exec {
|
exec {
|
||||||
environment "TEST_DIR", "$file"
|
environment "TEST_DIR", file
|
||||||
environment "BUILD_DIR", "$testCaseBuildDir"
|
environment "BUILD_DIR", testCaseBuildDir
|
||||||
commandLine "bash", "$file/test.sh", solrImageName
|
commandLine "bash", "$file/test.sh", solrImageName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outputs.dir(outputDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
task testDocker(type: DockerTestSuite) {
|
task dockerPush(dependsOn: tasks.dockerTag) {
|
||||||
outputDir = project.file("$buildDir/tmp/tests")
|
group = 'Docker'
|
||||||
solrImageName = dockerImageName
|
description = 'Push Solr docker image'
|
||||||
|
|
||||||
|
// Ensure that the docker image is re-pushed if the image ID or tag changes
|
||||||
|
inputs.properties([
|
||||||
|
dockerImageName: dockerImageName,
|
||||||
|
])
|
||||||
|
inputs.file(imageIdFile)
|
||||||
|
|
||||||
|
// We don't want to push a docker image unless the tests have passed
|
||||||
|
mustRunAfter tasks.testDocker
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
exec {
|
||||||
|
commandLine "docker", "push", dockerImageName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print information on the image after it has been created
|
||||||
|
project.logger.lifecycle("Solr Docker Image Pushed: \t$dockerImageName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// One task to build and tag a Solr docker image
|
||||||
|
task docker {
|
||||||
|
dependsOn tasks.dockerBuild, tasks.dockerTag
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacts {
|
||||||
|
dockerImage(tasks.dockerBuild.outputs.files.singleFile) {
|
||||||
|
builtBy(tasks.dockerBuild)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
Docker Images for Solr
|
||||||
|
======================
|
||||||
|
|
||||||
|
In order to build and tag a Solr docker image, merely run the following command:
|
||||||
|
|
||||||
|
gradlew docker
|
||||||
|
|
||||||
|
This calls the dockerBuild and dockerTag tasks, which have inputs that are described below.
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
|
In order to build the Solr Docker image, run:
|
||||||
|
|
||||||
|
gradlew dockerBuild
|
||||||
|
|
||||||
|
The docker build task accepts the following inputs, all accepted via both Environment Variables and Gradle Properties.
|
||||||
|
|
||||||
|
Base Docker Image: (The docker image used for the "FROM" in the Solr Dockerfile)
|
||||||
|
Default: "openjdk:11-jre-slim"
|
||||||
|
EnvVar: SOLR_DOCKER_BASE_IMAGE
|
||||||
|
Gradle Property: -Psolr.docker.baseImage
|
||||||
|
|
||||||
|
Github URL or Mirror: (The URL of github or a mirror of github releases. This is of use when building the docker image behind a firewall that does not have access to external Github.)
|
||||||
|
Default: "github.com"
|
||||||
|
EnvVar: SOLR_DOCKER_GITHUB_URL
|
||||||
|
Gradle Property: -Psolr.docker.githubUrl
|
||||||
|
|
||||||
|
Tagging and Pushing
|
||||||
|
-------
|
||||||
|
|
||||||
|
To tag the docker image, run the following command.
|
||||||
|
This will also ensure that the docker image has been built as per the inputs detailed above.
|
||||||
|
|
||||||
|
gradlew dockerTag
|
||||||
|
|
||||||
|
And to push the image with the given tag, run the following command.
|
||||||
|
Gradle will ensure that the docker image is built and tagged as the inputs describe before being pushed.
|
||||||
|
|
||||||
|
gradlew dockerPush
|
||||||
|
|
||||||
|
The docker image tag can be customized via the following options, all accepted via both Environment Variables and Gradle Properties.
|
||||||
|
|
||||||
|
Docker Image Repository:
|
||||||
|
Default: "apache/solr"
|
||||||
|
EnvVar: SOLR_DOCKER_IMAGE_REPO
|
||||||
|
Gradle Property: -Psolr.docker.imageRepo
|
||||||
|
|
||||||
|
Docker Image Tag:
|
||||||
|
Default: the Solr version, e.g. "9.0.0-SNAPSHOT"
|
||||||
|
EnvVar: SOLR_DOCKER_IMAGE_TAG
|
||||||
|
Gradle Property: -Psolr.docker.imageTag
|
||||||
|
|
||||||
|
Docker Image Name: (Use this to explicitly set a whole image name. If given, the image repo and image version options above are ignored.)
|
||||||
|
Default: {image_repo}/{image_tag} (both options provided above, with defaults)
|
||||||
|
EnvVar: SOLR_DOCKER_IMAGE_NAME
|
||||||
|
Gradle Property: -Psolr.docker.imageName
|
||||||
|
|
||||||
|
Testing
|
||||||
|
-------
|
||||||
|
|
||||||
|
To test the docker image, run the following command.
|
||||||
|
This will also ensure that the docker image has been built as per the inputs detailed above in the "Building" section.
|
||||||
|
|
||||||
|
gradlew testDocker
|
||||||
|
|
||||||
|
If a docker image build parameters were used during building, then the same inputs must be used while testing.
|
||||||
|
Otherwise a new docker image will be built for the tests to run with.
|
||||||
|
|
||||||
|
You can also specify an explicit list of tests to run, or an explicit list of tests to ignore.
|
||||||
|
Both inputs are optional, and by default all tests will be run.
|
||||||
|
Each input tasks a comma separated list of test names.
|
||||||
|
|
||||||
|
Run specific tests:
|
||||||
|
EnvVar: SOLR_DOCKER_TESTS_INCLUDE
|
||||||
|
Gradle Property: -Psolr.docker.tests.include
|
||||||
|
|
||||||
|
Exclude specific tests:
|
||||||
|
EnvVar: SOLR_DOCKER_TESTS_EXCLUDE
|
||||||
|
Gradle Property: -Psolr.docker.tests.exclude
|
|
@ -1,3 +0,0 @@
|
||||||
FROM scratch
|
|
||||||
|
|
||||||
COPY releases/ /opt/
|
|
|
@ -1,74 +0,0 @@
|
||||||
ARG BASE_IMAGE=openjdk:11-jre
|
|
||||||
|
|
||||||
FROM $BASE_IMAGE as downloader
|
|
||||||
|
|
||||||
ARG SOLR_VERSION
|
|
||||||
ARG SOLR_SHA512
|
|
||||||
ARG SOLR_KEYS
|
|
||||||
# If specified, this will override SOLR_DOWNLOAD_SERVER and all ASF mirrors. Typically used downstream for custom builds
|
|
||||||
ARG SOLR_DOWNLOAD_URL
|
|
||||||
|
|
||||||
# Override the solr download location with e.g.:
|
|
||||||
# docker build -t mine --build-arg SOLR_DOWNLOAD_SERVER=http://www-eu.apache.org/dist/lucene/solr .
|
|
||||||
ARG SOLR_DOWNLOAD_SERVER
|
|
||||||
# This is only applicable when SOLR_DOWNLOAD_URL is not provided. Skips the GPG check for Solr downloads.
|
|
||||||
ARG SKIP_GPG_CHECK="true"
|
|
||||||
|
|
||||||
ENV SOLR_CLOSER_URL="http://www.apache.org/dyn/closer.lua?filename=lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz&action=download" \
|
|
||||||
SOLR_DIST_URL="https://www.apache.org/dist/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz" \
|
|
||||||
SOLR_ARCHIVE_URL="https://archive.apache.org/dist/lucene/solr/$SOLR_VERSION/solr-$SOLR_VERSION.tgz"
|
|
||||||
|
|
||||||
RUN set -ex; \
|
|
||||||
apt-get update; \
|
|
||||||
apt-get -y install dirmngr gpg wget; \
|
|
||||||
rm -rf /var/lib/apt/lists/*;
|
|
||||||
|
|
||||||
RUN set -ex; \
|
|
||||||
export GNUPGHOME="/tmp/gnupg_home"; \
|
|
||||||
mkdir -p "$GNUPGHOME"; \
|
|
||||||
chmod 700 "$GNUPGHOME"; \
|
|
||||||
echo "disable-ipv6" >> "$GNUPGHOME/dirmngr.conf"; \
|
|
||||||
for key in $SOLR_KEYS; do \
|
|
||||||
found=''; \
|
|
||||||
for server in \
|
|
||||||
ha.pool.sks-keyservers.net \
|
|
||||||
hkp://keyserver.ubuntu.com:80 \
|
|
||||||
hkp://p80.pool.sks-keyservers.net:80 \
|
|
||||||
pgp.mit.edu \
|
|
||||||
; do \
|
|
||||||
echo " trying $server for $key"; \
|
|
||||||
gpg --batch --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$key" && found=yes && break; \
|
|
||||||
gpg --batch --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$key" && found=yes && break; \
|
|
||||||
done; \
|
|
||||||
test -z "$found" && echo >&2 "error: failed to fetch $key from several disparate servers -- network issues?" && exit 1; \
|
|
||||||
done; \
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
RUN set -ex; \
|
|
||||||
export GNUPGHOME="/tmp/gnupg_home"; \
|
|
||||||
MAX_REDIRECTS=1; \
|
|
||||||
if [ -n "$SOLR_DOWNLOAD_URL" ]; then \
|
|
||||||
# If a custom URL is defined, we download from non-ASF mirror URL and allow more redirects and skip GPG step
|
|
||||||
# This takes effect only if the SOLR_DOWNLOAD_URL build-arg is specified, typically in downstream Dockerfiles
|
|
||||||
MAX_REDIRECTS=4; \
|
|
||||||
SKIP_GPG_CHECK="true"; \
|
|
||||||
elif [ -n "$SOLR_DOWNLOAD_SERVER" ]; then \
|
|
||||||
SOLR_DOWNLOAD_URL="$SOLR_DOWNLOAD_SERVER/$SOLR_VERSION/solr-$SOLR_VERSION.tgz"; \
|
|
||||||
fi; \
|
|
||||||
for url in $SOLR_DOWNLOAD_URL $SOLR_CLOSER_URL $SOLR_DIST_URL $SOLR_ARCHIVE_URL; do \
|
|
||||||
if [ -f "/opt/solr-$SOLR_VERSION.tgz" ]; then break; fi; \
|
|
||||||
echo "downloading $url"; \
|
|
||||||
if wget -t 10 --max-redirect $MAX_REDIRECTS --retry-connrefused -nv "$url" -O "/opt/solr-$SOLR_VERSION.tgz"; then break; else rm -f "/opt/solr-$SOLR_VERSION.tgz"; fi; \
|
|
||||||
done; \
|
|
||||||
if [ ! -f "/opt/solr-$SOLR_VERSION.tgz" ]; then echo "failed all download attempts for solr-$SOLR_VERSION.tgz"; exit 1; fi; \
|
|
||||||
if [ "$SKIP_GPG_CHECK" != "true" ]; then \
|
|
||||||
echo "downloading $SOLR_ARCHIVE_URL.asc"; \
|
|
||||||
wget -nv "$SOLR_ARCHIVE_URL.asc" -O "/opt/solr-$SOLR_VERSION.tgz.asc"; \
|
|
||||||
echo "$SOLR_SHA512 */opt/solr-$SOLR_VERSION.tgz" | sha512sum -c -; \
|
|
||||||
(>&2 ls -l "/opt/solr-$SOLR_VERSION.tgz" "/opt/solr-$SOLR_VERSION.tgz.asc"); \
|
|
||||||
gpg --batch --verify "/opt/solr-$SOLR_VERSION.tgz.asc" "/opt/solr-$SOLR_VERSION.tgz"; \
|
|
||||||
else \
|
|
||||||
echo "Skipping GPG validation due to non-Apache build"; \
|
|
||||||
fi; \
|
|
||||||
{ command -v gpgconf; gpgconf --kill all || :; }; \
|
|
||||||
rm -r "$GNUPGHOME";
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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
|
|
||||||
*
|
|
||||||
* http://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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
description = 'Solr Docker Package image'
|
|
||||||
|
|
||||||
// The solr package docker image relies on the output of the solr:packaging project.
|
|
||||||
Project solrPackaging = project(':solr:packaging')
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
docker solrPackaging
|
|
||||||
}
|
|
||||||
|
|
||||||
docker {
|
|
||||||
name = 'apache/solr-build:local-package'
|
|
||||||
dockerfile file('Dockerfile.local-package')
|
|
||||||
files(solrPackaging.tasks.distTar.outputs)
|
|
||||||
getCopySpec().into('releases')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only allow the following docker tasks
|
|
||||||
def availableDockerTasks = ["docker", "dockerClean", "dockerPrepare", "dockerfileZip"]
|
|
||||||
project.tasks.configureEach { t -> t.enabled = t.getGroup() != "Docker" || availableDockerTasks.contains(t.getName()) }
|
|
|
@ -59,7 +59,7 @@ fi
|
||||||
container_cleanup "$container_name"
|
container_cleanup "$container_name"
|
||||||
|
|
||||||
# chown it back
|
# chown it back
|
||||||
docker run --rm --user 0:0 -d -e VERBOSE=yes \
|
docker run --rm --user 0:0 -e VERBOSE=yes \
|
||||||
-v "$myvarsolr:/myvarsolr" "$tag" \
|
-v "$myvarsolr:/myvarsolr" "$tag" \
|
||||||
bash -c "chown -R $(id -u):$(id -g) /myvarsolr; ls -ld /myvarsolr"
|
bash -c "chown -R $(id -u):$(id -g) /myvarsolr; ls -ld /myvarsolr"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue