diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index d1824c6..0000000 --- a/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -downloads -.git \ No newline at end of file diff --git a/.gitignore b/.gitignore index 01381c3..3bf5454 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.dockerignore .DS_Store .vscode test/docker/coverage diff --git a/Dockerfile-server b/Dockerfile-server index dfa80f7..f14225d 100644 --- a/Dockerfile-server +++ b/Dockerfile-server @@ -1,4 +1,4 @@ -# © Copyright IBM Corporation 2015, 2022 +# © Copyright IBM Corporation 2015, 2023 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,33 +17,28 @@ ARG BASE_TAG=8.7-1031 ARG BUILDER_IMAGE=registry.access.redhat.com/ubi8/go-toolset ARG BUILDER_TAG=1.17.12-11 ARG GO_WORKDIR=/opt/app-root/src/go/src/github.com/ibm-messaging/mq-container -ARG MQ_URL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/9.3.2.0-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz" +ARG MQ_ARCHIVE="downloads/9.3.2.0-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz" + ############################################################################### # Build stage to build Go code ############################################################################### FROM $BUILDER_IMAGE:$BUILDER_TAG as builder -# The URL to download the MQ installer from in tar.gz format -# This assumes an archive containing the MQ Non-Install packages -ARG MQ_URL ARG IMAGE_REVISION="Not specified" ARG IMAGE_SOURCE="Not specified" ARG IMAGE_TAG="Not specified" ARG GO_WORKDIR +ARG MQ_ARCHIVE USER 0 -WORKDIR /opt/mqm -# Download and extract MQ files, to get the MQ client needed to compile. -# Only extract certain MQ files to make the build quicker -RUN curl --fail --location $MQ_URL | tar --extract --gunzip \ - && chown -R 1001:root /opt/mqm/* WORKDIR $GO_WORKDIR/ +ADD $MQ_ARCHIVE /opt/mqm +ENV CGO_CFLAGS="-I/opt/mqm/inc/" \ + CGO_LDFLAGS_ALLOW="-Wl,-rpath.*" \ + PATH="${PATH}:/opt/mqm/bin" COPY go.mod go.sum ./ COPY cmd/ ./cmd COPY internal/ ./internal COPY pkg/ ./pkg COPY vendor/ ./vendor -ENV CGO_CFLAGS="-I/opt/mqm/inc/" \ - CGO_LDFLAGS_ALLOW="-Wl,-rpath.*" \ - PATH="${PATH}:/opt/mqm/bin" RUN go build -ldflags "-X \"main.ImageCreated=$(date --iso-8601=seconds)\" -X \"main.ImageRevision=$IMAGE_REVISION\" -X \"main.ImageSource=$IMAGE_SOURCE\" -X \"main.ImageTag=$IMAGE_TAG\"" ./cmd/runmqserver/ \ && go build ./cmd/chkmqready/ \ && go build ./cmd/chkmqhealthy/ \ @@ -58,11 +53,44 @@ RUN go build -ldflags "-X \"main.ImageCreated=$(date --iso-8601=seconds)\" -X \" && go test -v ./internal/... \ && go vet ./cmd/... ./internal/... +############################################################################### +# Build stage to reduce MQ packages included using genmqpkg +############################################################################### +FROM $BASE_IMAGE:$BASE_TAG AS mq-redux +ARG BASE_IMAGE +ARG BASE_TAG +ARG MQ_ARCHIVE +WORKDIR /tmp/mq +ENV genmqpkg_inc32=0 \ + genmqpkg_incadm=1 \ + genmqpkg_incamqp=0 \ + genmqpkg_incams=1 \ + genmqpkg_inccbl=0 \ + genmqpkg_inccics=0 \ + genmqpkg_inccpp=0 \ + genmqpkg_incdnet=0 \ + genmqpkg_incjava=1 \ + genmqpkg_incjre=1 \ + genmqpkg_incman=0 \ + genmqpkg_incmqbc=0 \ + genmqpkg_incmqft=0 \ + genmqpkg_incmqsf=0 \ + genmqpkg_incmqxr=0 \ + genmqpkg_incnls=1 \ + genmqpkg_incras=1 \ + genmqpkg_incsamp=1 \ + genmqpkg_incsdk=0 \ + genmqpkg_inctls=1 \ + genmqpkg_incunthrd=0 \ + genmqpkg_incweb=1 +ADD $MQ_ARCHIVE /opt/mqm-noinstall +# Run genmqpkg to reduce the MQ packages included +RUN /opt/mqm-noinstall/bin/genmqpkg.sh -b /opt/mqm-redux + ############################################################################### # Main build stage, to build MQ image ############################################################################### FROM $BASE_IMAGE:$BASE_TAG AS mq-server -# The MQ packages to install - see install-mq.sh for default value ARG MQ_URL ARG BASE_IMAGE ARG BASE_TAG @@ -79,15 +107,14 @@ LABEL summary="IBM MQ Advanced Server" \ io.k8s.description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the world’s most successful enterprises" \ base-image=$BASE_IMAGE \ base-image-release=$BASE_TAG -COPY install-mq.sh /usr/local/bin/ +COPY --from=mq-redux /opt/mqm-redux/ /opt/mqm/ +COPY setup-image.sh /usr/local/bin/ COPY install-mq-server-prereqs.sh /usr/local/bin/ -# Install MQ. To avoid a "text file busy" error here, we sleep before installing. RUN env \ - && mkdir /opt/mqm \ && chmod u+x /usr/local/bin/install-*.sh \ - && sleep 1 \ + && chmod u+x /usr/local/bin/setup-image.sh \ && install-mq-server-prereqs.sh \ - && install-mq.sh \ + && setup-image.sh \ && /opt/mqm/bin/security/amqpamcf \ && chown -R 1001:root /opt/mqm/* COPY --from=builder $GO_WORKDIR/runmqserver /usr/local/bin/ @@ -121,9 +148,6 @@ ENTRYPOINT ["runmqserver"] ############################################################################### # Use the Go toolset image, which already includes gcc and the MQ SDK FROM builder as cbuilder -# The URL to download the MQ installer from in tar.gz format -# This assumes an archive containing the MQ Non-Install packages -ARG MQ_URL USER 0 # Install the Apache Portable Runtime code (used for htpasswd hash checking) RUN yum --assumeyes --disableplugin=subscription-manager install apr-devel apr-util-openssl apr-util-devel diff --git a/Makefile b/Makefile index fbe42b8..67d4cc3 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# © Copyright IBM Corporation 2017, 2022 +# © Copyright IBM Corporation 2017, 2023 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -75,8 +75,6 @@ VOLUME_MOUNT_OPTIONS ?= :Z ############################################################################### # Other variables ############################################################################### -# Build doesn't work if BuildKit is enabled -DOCKER_BUILDKIT=0 # Lock Docker API version for compatibility with Podman and with the Docker version in Travis' Ubuntu Bionic DOCKER_API_VERSION=1.40 GO_PKG_DIRS = ./cmd ./internal ./test @@ -340,14 +338,16 @@ test-advancedserver-cover: test/docker/vendor coverage # Command to build the image # Args: imageName, imageTag, dockerfile, extraArgs, dockerfileTarget # If the ARCH variable has been changed from the default value (arch_go variable), then the `--platform` parameter is added -define build-mq-command +# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget +define build-mq + rm -f .dockerignore && echo ".git\ndownloads\n!downloads/$4" > .dockerignore $(COMMAND) build \ --tag $1:$2 \ --file $3 \ - $4 \ --build-arg IMAGE_REVISION="$(IMAGE_REVISION)" \ --build-arg IMAGE_SOURCE="$(IMAGE_SOURCE)" \ --build-arg IMAGE_TAG="$1:$2" \ + --build-arg MQ_ARCHIVE="downloads/$4" \ --label version=$(MQ_VERSION) \ --label name=$1 \ --label build-date=$(shell date +%Y-%m-%dT%H:%M:%S%z) \ @@ -362,57 +362,6 @@ define build-mq-command . endef -# Build using a separate container to host the MQ download files. -# To minimize the layers in the resulting image, the download files can't be part of the build context. -# The "docker build" command (and "podman build" on macOS) don't allow you to mount a directory into the build, so a -# separate container is used to host a web server. -# Note that for Podman, this means that you need to be using the "rootful" mode, because the rootless mode doesn't allow -# much control of networking, so the containers can't talk to each other. -define build-mq-using-web-server - $(COMMAND) network create $(BUILD_SERVER_NETWORK) - $(COMMAND) run \ - --rm \ - --name $(BUILD_SERVER_CONTAINER) \ - --network $(BUILD_SERVER_NETWORK) \ - --volume $(DOWNLOADS_DIR):/opt/app-root/src$(VOLUME_MOUNT_OPTIONS) \ - --detach \ - registry.access.redhat.com/ubi8/nginx-120 nginx -g "daemon off;" || ($(COMMAND) network rm $(BUILD_SERVER_NETWORK) && exit 1) - BUILD_SERVER_IP=$$($(COMMAND) inspect -f '{{ .NetworkSettings.Networks.$(BUILD_SERVER_NETWORK).IPAddress }}' $(BUILD_SERVER_CONTAINER)); \ - $(call build-mq-command,$1,$2,$3,--network build --build-arg MQ_URL=http://$$BUILD_SERVER_IP:8080/$4,$5) || ($(COMMAND) rm -f $(BUILD_SERVER_CONTAINER) && $(COMMAND) network rm $(BUILD_SERVER_NETWORK) && exit 1) - $(COMMAND) rm -f $(BUILD_SERVER_CONTAINER) - $(COMMAND) network rm $(BUILD_SERVER_NETWORK) -endef - -# When building with Docker, always use the web server build because you can't use bind-mounted volumes. -# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget -define build-mq-docker - $(call build-mq-using-web-server,$1,$2,$3,$4,$5) -endef - -# When building with Podman on macOS (Darwin), use the web server build because you can't use bind-mounted volumes with `podman build` on macOS -# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget -define build-mq-podman-Darwin - $(call build-mq-using-web-server,$1,$2,$3,$4,$5) -endef - -# When building with Podman on Linux, just pass the downloads directory as a volume -# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget -define build-mq-podman-Linux - $(call build-mq-command,$1,$2,$3,--volume $(DOWNLOADS_DIR):/var/downloads$(VOLUME_MOUNT_OPTIONS) --build-arg MQ_URL=file:///var/downloads/$4,$5) -endef - -# When building with Podman, just pass the downloads directory as a volume -# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget -define build-mq-podman - $(call build-mq-podman-$(shell uname -s),$1,$2,$3,$4,$5) -endef - -# Build an MQ image. The commands used are slightly different between Docker and Podman -# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget -define build-mq - $(call build-mq-$(COMMAND),$1,$2,$3,$4,$5) -endef - ############################################################################### # Build targets ############################################################################### @@ -610,7 +559,6 @@ fi ;\ .PHONY: update-release-information update-release-information: - sed -i.bak 's/ARG MQ_URL=.*-LinuxX64.tar.gz"/ARG MQ_URL="https:\/\/public.dhe.ibm.com\/ibmdl\/export\/pub\/software\/websphere\/messaging\/mqadv\/$(MQ_VERSION)-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz"/g' Dockerfile-server && rm Dockerfile-server.bak $(eval MQ_VERSION_1=$(shell echo '${MQ_VERSION}' | rev | cut -c 3- | rev)) sed -i.bak 's/IBM_MQ_.*_LINUX_X86-64_NOINST.tar.gz/IBM_MQ_${MQ_VERSION_1}_LINUX_X86-64_NOINST.tar.gz/g' docs/building.md && rm docs/building.md.bak sed -i.bak 's/ibm-mqadvanced-server:.*-amd64/ibm-mqadvanced-server:$(MQ_VERSION)-amd64/g' docs/security.md diff --git a/docs/building.md b/docs/building.md index b462a11..b098c8c 100755 --- a/docs/building.md +++ b/docs/building.md @@ -4,7 +4,7 @@ You need to have the following tools installed: -* [Docker](https://www.docker.com/) 17.06.1 or later, or [Podman](https://podman.io) 1.0 or later (Podman 4.1 on macOS). If using Podman on macOS, the you need to be in "rootful" mode to allow the use of a network during builds. Run `podman machine init --rootful`. +* [Docker](https://www.docker.com/) 17.06.1 or later, or [Podman](https://podman.io) 1.0 or later (Podman 4.1 on macOS). * [GNU make](https://www.gnu.org/software/make/) If you are working in the Windows Subsystem for Linux, follow [this guide by Microsoft to set up Docker](https://blogs.msdn.microsoft.com/commandline/2017/12/08/cross-post-wsl-interoperability-with-docker/) first. @@ -44,4 +44,4 @@ You can use the environment variable `MQ_ARCHIVE_DEV` to specify an alternative ## Installed components -This image includes the core MQ server, Java, language packs, GSKit, and web server. This is configured in the `Generate MQ package in INSTALLATION_DIR` section [here](../install-mq.sh), with the configured options being picked up at build time. +This image includes the core MQ server, Java, language packs, GSKit, and web server. This is configured in the `mq-redux` build stage in `Dockerfile-server`. diff --git a/install-mq.sh b/setup-image.sh similarity index 73% rename from install-mq.sh rename to setup-image.sh index eb6af92..f565b81 100644 --- a/install-mq.sh +++ b/setup-image.sh @@ -1,6 +1,6 @@ #!/bin/bash # -*- mode: sh -*- -# © Copyright IBM Corporation 2015, 2022 +# © Copyright IBM Corporation 2015, 2023 # # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,43 +21,8 @@ set -ex test -f /usr/bin/rpm && RPM=true || RPM=false test -f /usr/bin/apt-get && UBUNTU=true || UBUNTU=false -# Download and extract the MQ unzippable server -DIR_TMP=/tmp/mq -mkdir -p ${DIR_TMP} -cd ${DIR_TMP} -curl --fail --location $MQ_URL | tar --extract --gunzip -ls -la ${DIR_TMP} - -# Generate MQ package in INSTALLATION_DIR -export genmqpkg_inc32=0 -export genmqpkg_incadm=1 -export genmqpkg_incamqp=0 -export genmqpkg_incams=1 -export genmqpkg_inccbl=0 -export genmqpkg_inccics=0 -export genmqpkg_inccpp=0 -export genmqpkg_incdnet=0 -export genmqpkg_incjava=1 -export genmqpkg_incjre=1 -export genmqpkg_incman=0 -export genmqpkg_incmqbc=0 -export genmqpkg_incmqft=0 -export genmqpkg_incmqsf=0 -export genmqpkg_incmqxr=0 -export genmqpkg_incnls=1 -export genmqpkg_incras=1 -export genmqpkg_incsamp=1 -export genmqpkg_incsdk=0 -export genmqpkg_inctls=1 -export genmqpkg_incunthrd=0 -export genmqpkg_incweb=1 -export INSTALLATION_DIR=/opt/mqm -${DIR_TMP}/bin/genmqpkg.sh -b ${INSTALLATION_DIR} -ls -la ${INSTALLATION_DIR} -rm -rf ${DIR_TMP} - # Accept the MQ license -${INSTALLATION_DIR}/bin/mqlicense -accept +/opt/mqm/bin/mqlicense -accept # Optional: Update the command prompt with the MQ version $UBUNTU && echo "mq:$(dspmqver -b -f 2)" > /etc/debian_chroot