MQ 9.1.5 image changes (#62)

* Upgraded to MQ 9.1.5, upgraded to unzippable install, run as random UID (1001 by default)

* Updated docker tests for MQ 915 random UID

* Added warning to crtmqdir for 10 rc, added trace option to crtmqdir

* Removed dev users from dockerfile
This commit is contained in:
Luke J Powlett
2020-03-03 15:02:36 +00:00
parent 1a7a9236b7
commit c9bac5b544
22 changed files with 153 additions and 311 deletions

View File

@@ -1,4 +1,4 @@
# © Copyright IBM Corporation 2018, 2019 # © Copyright IBM Corporation 2018, 2020
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -41,15 +41,15 @@ jobs:
if: branch != private-master AND tag IS blank if: branch != private-master AND tag IS blank
os: linux os: linux
env: env:
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_914_ARCHIVE_REPOSITORY_DEV_AMD64 - MQ_ARCHIVE_REPOSITORY_DEV=$MQ_915_ARCHIVE_REPOSITORY_DEV_AMD64
script: bash -e travis-build-scripts/run.sh script: bash -e travis-build-scripts/run.sh
- if: branch = private-master OR tag =~ ^pre-release* - if: branch = private-master OR tag =~ ^pre-release*
name: "Multi-Arch AMD64 build" name: "Multi-Arch AMD64 build"
os: linux os: linux
env: env:
- BUILD_ALL=true - BUILD_ALL=true
- MQ_ARCHIVE_REPOSITORY=$MQ_914_ARCHIVE_REPOSITORY_AMD64 - MQ_ARCHIVE_REPOSITORY=$MQ_915_ARCHIVE_REPOSITORY_AMD64
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_914_ARCHIVE_REPOSITORY_DEV_AMD64 - MQ_ARCHIVE_REPOSITORY_DEV=$MQ_915_ARCHIVE_REPOSITORY_DEV_AMD64
script: bash -e travis-build-scripts/run.sh script: bash -e travis-build-scripts/run.sh
- if: branch = private-master OR tag =~ ^pre-release* - if: branch = private-master OR tag =~ ^pre-release*
name: "Multi-Arch PPC64LE build" name: "Multi-Arch PPC64LE build"
@@ -57,8 +57,8 @@ jobs:
env: env:
- BUILD_ALL=true - BUILD_ALL=true
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics" - TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
- MQ_ARCHIVE_REPOSITORY=$MQ_914_ARCHIVE_REPOSITORY_PPC64LE - MQ_ARCHIVE_REPOSITORY=$MQ_915_ARCHIVE_REPOSITORY_PPC64LE
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_914_ARCHIVE_REPOSITORY_DEV_PPC64LE - MQ_ARCHIVE_REPOSITORY_DEV=$MQ_915_ARCHIVE_REPOSITORY_DEV_PPC64LE
script: bash -e travis-build-scripts/run.sh script: bash -e travis-build-scripts/run.sh
- if: branch = private-master OR tag =~ ^pre-release* - if: branch = private-master OR tag =~ ^pre-release*
name: "Multi-Arch S390X build" name: "Multi-Arch S390X build"
@@ -66,8 +66,8 @@ jobs:
env: env:
- BUILD_ALL=true - BUILD_ALL=true
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics" - TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
- MQ_ARCHIVE_REPOSITORY=$MQ_914_ARCHIVE_REPOSITORY_S390X - MQ_ARCHIVE_REPOSITORY=$MQ_915_ARCHIVE_REPOSITORY_S390X
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_914_ARCHIVE_REPOSITORY_DEV_S390X - MQ_ARCHIVE_REPOSITORY_DEV=$MQ_915_ARCHIVE_REPOSITORY_DEV_S390X
script: bash -e travis-build-scripts/run.sh script: bash -e travis-build-scripts/run.sh
- stage: deploy - stage: deploy
name: "Pre-release deploy" name: "Pre-release deploy"

View File

@@ -1,5 +1,10 @@
# Change log # Change log
## 9.1.5.0 (2020-04-02)
* Updated to MQ version 9.1.5.0
* Can now run as a random user, instead of the "mqm" user, which has now been removed. This adds compatability for the [Red Hat OpenShift restricted SCC](https://docs.openshift.com/container-platform/4.3/authentication/managing-security-context-constraints.html#security-context-constraints-about_configuring-internal-oauth). The default image UID is `1001`.
## 9.1.4.0 (2019-12-06) ## 9.1.4.0 (2019-12-06)
* Updated to MQ version 9.1.4.0 * Updated to MQ version 9.1.4.0

View File

@@ -25,12 +25,13 @@ ARG MQ_URL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messa
ARG IMAGE_REVISION="Not specified" ARG IMAGE_REVISION="Not specified"
ARG IMAGE_SOURCE="Not specified" ARG IMAGE_SOURCE="Not specified"
ARG IMAGE_TAG="Not specified" ARG IMAGE_TAG="Not specified"
ARG MQM_UID=888
USER 0 USER 0
COPY install-mq.sh /usr/local/bin/ COPY install-mq.sh /usr/local/bin/
RUN chmod a+x /usr/local/bin/install-mq.sh \ RUN mkdir /opt/mqm \
&& chmod a+x /usr/local/bin/install-mq.sh \
&& sleep 1 \ && sleep 1 \
&& MQ_PACKAGES="MQSeriesRuntime-*.rpm MQSeriesSDK-*.rpm MQSeriesSamples*.rpm" install-mq.sh $MQM_UID && install-mq.sh \
&& chown -R 1001:root /opt/mqm/*
WORKDIR /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/ WORKDIR /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/
COPY cmd/ ./cmd COPY cmd/ ./cmd
COPY internal/ ./internal COPY internal/ ./internal
@@ -59,7 +60,6 @@ FROM $BASE_IMAGE:$BASE_TAG AS mq-server
ARG MQ_URL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/mqadv_dev914_linux_x86-64.tar.gz" ARG MQ_URL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/mqadv_dev914_linux_x86-64.tar.gz"
ARG MQ_PACKAGES="MQSeriesRuntime-*.rpm MQSeriesServer-*.rpm MQSeriesJava*.rpm MQSeriesJRE*.rpm MQSeriesGSKit*.rpm MQSeriesMsg*.rpm MQSeriesSamples*.rpm MQSeriesWeb*.rpm MQSeriesAMS-*.rpm" ARG MQ_PACKAGES="MQSeriesRuntime-*.rpm MQSeriesServer-*.rpm MQSeriesJava*.rpm MQSeriesJRE*.rpm MQSeriesGSKit*.rpm MQSeriesMsg*.rpm MQSeriesSamples*.rpm MQSeriesWeb*.rpm MQSeriesAMS-*.rpm"
#ARG MQ_PACKAGES="ibmmq-server ibmmq-java ibmmq-jre ibmmq-gskit ibmmq-msg-.* ibmmq-samples ibmmq-web ibmmq-ams" #ARG MQ_PACKAGES="ibmmq-server ibmmq-java ibmmq-jre ibmmq-gskit ibmmq-msg-.* ibmmq-samples ibmmq-web ibmmq-ams"
ARG MQM_UID=888
ARG BASE_IMAGE ARG BASE_IMAGE
ARG BASE_TAG ARG BASE_TAG
LABEL summary="IBM MQ Advanced Server" LABEL summary="IBM MQ Advanced Server"
@@ -76,13 +76,17 @@ LABEL base-image-release=$BASE_TAG
COPY install-mq.sh /usr/local/bin/ COPY install-mq.sh /usr/local/bin/
COPY install-mq-server-prereqs.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. # Install MQ. To avoid a "text file busy" error here, we sleep before installing.
RUN env && chmod u+x /usr/local/bin/install-*.sh \ RUN env \
&& mkdir /opt/mqm \
&& chmod u+x /usr/local/bin/install-*.sh \
&& sleep 1 \ && sleep 1 \
&& install-mq-server-prereqs.sh $MQM_UID \ && install-mq-server-prereqs.sh \
&& install-mq.sh $MQM_UID && install-mq.sh \
&& /opt/mqm/bin/security/amqpamcf \
&& chown -R 1001:root /opt/mqm/*
# Create a directory for runtime data from runmqserver # Create a directory for runtime data from runmqserver
RUN mkdir -p /run/runmqserver \ RUN mkdir -p /run/runmqserver \
&& chown mqm:mqm /run/runmqserver && chown 1001:root /run/runmqserver
COPY --from=builder /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/runmqserver /usr/local/bin/ COPY --from=builder /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/runmqserver /usr/local/bin/
COPY --from=builder /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/chkmq* /usr/local/bin/ COPY --from=builder /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/chkmq* /usr/local/bin/
COPY NOTICES.txt /opt/mqm/licenses/notices-container.txt COPY NOTICES.txt /opt/mqm/licenses/notices-container.txt
@@ -90,31 +94,30 @@ COPY NOTICES.txt /opt/mqm/licenses/notices-container.txt
COPY web /etc/mqm/web COPY web /etc/mqm/web
COPY etc/mqm/*.tpl /etc/mqm/ COPY etc/mqm/*.tpl /etc/mqm/
RUN chmod ug+x /usr/local/bin/runmqserver \ RUN chmod ug+x /usr/local/bin/runmqserver \
&& chown mqm:mqm /usr/local/bin/*mq* \ && chown 1001:root /usr/local/bin/*mq* \
&& chmod ug+xs /usr/local/bin/chkmq* \ && chmod ug+xs /usr/local/bin/chkmq* \
&& chown -R mqm:mqm /etc/mqm/* \ && chown -R 1001:root /etc/mqm/* \
&& install --directory --mode 0775 --owner mqm --group root /run/runmqserver \ && install --directory --mode 0775 --owner 1001 --group root /run/runmqserver \
&& touch /run/termination-log \ && touch /run/termination-log \
&& chown mqm:root /run/termination-log \ && chown 1001:root /run/termination-log \
&& chmod 0660 /run/termination-log && chmod 0660 /run/termination-log
# Always use port 1414 for MQ & 9157 for the metrics # Always use port 1414 for MQ & 9157 for the metrics
EXPOSE 1414 9157 9443 EXPOSE 1414 9157 9443
ENV MQ_OVERRIDE_DATA_PATH=/mnt/mqm/data MQ_INSTALLATION_NAME=Installation1 MQ_USER_NAME="mqm" PATH="${PATH}:/opt/mqm/bin"
ENV MQ_GRACE_PERIOD=30 ENV MQ_GRACE_PERIOD=30
ENV LANG=en_US.UTF-8 AMQ_DIAGNOSTIC_MSG_SEVERITY=1 AMQ_ADDITIONAL_JSON_LOG=1 LOG_FORMAT=basic ENV LANG=en_US.UTF-8 AMQ_DIAGNOSTIC_MSG_SEVERITY=1 AMQ_ADDITIONAL_JSON_LOG=1 LOG_FORMAT=basic
USER $MQM_UID # We can run as any UID
USER 1001
ENTRYPOINT ["runmqserver"] ENTRYPOINT ["runmqserver"]
############################################################################### ###############################################################################
# Add default developer config # Add default developer config
############################################################################### ###############################################################################
FROM mq-server AS mq-dev-server FROM mq-server AS mq-dev-server
ARG MQM_UID=888
ARG BASE_IMAGE ARG BASE_IMAGE
ARG BASE_TAG ARG BASE_TAG
# Enable MQ developer default configuration # Enable MQ developer default configuration
ENV MQ_DEV=true ENV MQ_DEV=true
# Default administrator password
ENV MQ_ADMIN_PASSWORD=passw0rd
LABEL summary="IBM MQ Advanced for Developers Server" LABEL summary="IBM MQ Advanced for Developers Server"
LABEL description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises" LABEL description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the worlds most successful enterprises"
LABEL vendor="IBM" LABEL vendor="IBM"
@@ -131,25 +134,17 @@ COPY incubating/mqadvanced-server-dev/install-extra-packages.sh /usr/local/bin/
RUN chmod u+x /usr/local/bin/install-extra-packages.sh \ RUN chmod u+x /usr/local/bin/install-extra-packages.sh \
&& sleep 1 \ && sleep 1 \
&& install-extra-packages.sh && install-extra-packages.sh
# WARNING: This is what allows the mqm user to change the password of any other user
# It's used by runmqdevserver to change the admin/app passwords.
RUN echo "mqm ALL = NOPASSWD: /usr/sbin/chpasswd" > /etc/sudoers.d/mq-dev-config
## Add admin and app users, and set a default password for admin
RUN useradd admin -G mqm \
&& groupadd mqclient \
&& useradd app -G mqclient \
&& echo admin:$MQ_ADMIN_PASSWORD | chpasswd
# Create a directory for runtime data from runmqserver # Create a directory for runtime data from runmqserver
RUN mkdir -p /run/runmqdevserver \ RUN mkdir -p /run/runmqdevserver \
&& chown mqm:mqm /run/runmqdevserver && chown 1001:root /run/runmqdevserver
COPY --from=builder /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/runmqdevserver /usr/local/bin/ COPY --from=builder /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/runmqdevserver /usr/local/bin/
# Copy template files # Copy template files
COPY incubating/mqadvanced-server-dev/*.tpl /etc/mqm/ COPY incubating/mqadvanced-server-dev/*.tpl /etc/mqm/
# Copy web XML files for default developer configuration # Copy web XML files for default developer configuration
COPY incubating/mqadvanced-server-dev/web /etc/mqm/web COPY incubating/mqadvanced-server-dev/web /etc/mqm/web
RUN chown -R mqm:mqm /etc/mqm/* \ RUN chown -R 1001:root /etc/mqm/* \
&& chmod +x /usr/local/bin/runmq* \ && chmod +x /usr/local/bin/runmq* \
&& install --directory --mode 0775 --owner mqm --group root /run/runmqdevserver && install --directory --mode 0775 --owner 1001 --group root /run/runmqdevserver
ENV MQ_ENABLE_EMBEDDED_WEB_SERVER=1 MQ_GENERATE_CERTIFICATE_HOSTNAME=localhost ENV MQ_ENABLE_EMBEDDED_WEB_SERVER=1 MQ_GENERATE_CERTIFICATE_HOSTNAME=localhost
USER $MQM_UID USER 1001
ENTRYPOINT ["runmqdevserver"] ENTRYPOINT ["runmqdevserver"]

View File

@@ -1,4 +1,4 @@
# © Copyright IBM Corporation 2017, 2019 # © Copyright IBM Corporation 2017, 2020
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
# RELEASE shows what release of the container code has been built # RELEASE shows what release of the container code has been built
RELEASE ?= RELEASE ?=
# MQ_VERSION is the fully qualified MQ version number to build # MQ_VERSION is the fully qualified MQ version number to build
MQ_VERSION ?= 9.1.4.0 MQ_VERSION ?= 9.1.5.0
# MQ_ARCHIVE_REPOSITORY is a remote repository from which to pull the MQ_ARCHIVE (if required) # MQ_ARCHIVE_REPOSITORY is a remote repository from which to pull the MQ_ARCHIVE (if required)
MQ_ARCHIVE_REPOSITORY ?= MQ_ARCHIVE_REPOSITORY ?=
# MQ_ARCHIVE_REPOSITORY_DEV is a remote repository from which to pull the MQ_ARCHIVE_DEV (if required) # MQ_ARCHIVE_REPOSITORY_DEV is a remote repository from which to pull the MQ_ARCHIVE_DEV (if required)
@@ -45,10 +45,6 @@ MQ_IMAGE_ADVANCEDSERVER ?=ibm-mqadvanced-server
MQ_IMAGE_DEVSERVER ?=ibm-mqadvanced-server-dev MQ_IMAGE_DEVSERVER ?=ibm-mqadvanced-server-dev
# MQ_TAG is the tag of the built MQ Advanced image & MQ Advanced for Developers image # MQ_TAG is the tag of the built MQ Advanced image & MQ Advanced for Developers image
MQ_TAG ?=$(MQ_VERSION)-$(ARCH) MQ_TAG ?=$(MQ_VERSION)-$(ARCH)
# MQ_PACKAGES specifies the MQ packages (.deb or .rpm) to install. Defaults vary on base image.
MQ_PACKAGES ?=MQSeriesRuntime-*.rpm MQSeriesServer-*.rpm MQSeriesJava*.rpm MQSeriesJRE*.rpm MQSeriesGSKit*.rpm MQSeriesMsg*.rpm MQSeriesSamples*.rpm MQSeriesWeb*.rpm MQSeriesAMS-*.rpm
# MQM_UID is the UID to use for the "mqm" user
MQM_UID ?= 888
# COMMAND is the container command to run. "podman" or "docker" # COMMAND is the container command to run. "podman" or "docker"
COMMAND ?=$(shell type -p podman 2>&1 >/dev/null && echo podman || echo docker) COMMAND ?=$(shell type -p podman 2>&1 >/dev/null && echo podman || echo docker)
# MQ_DELIVERY_REGISTRY_HOSTNAME is a remote registry to push the MQ Image to (if required) # MQ_DELIVERY_REGISTRY_HOSTNAME is a remote registry to push the MQ Image to (if required)
@@ -88,7 +84,7 @@ IMAGE_REVISION=$(shell git rev-parse HEAD)
IMAGE_SOURCE=$(shell git config --get remote.origin.url) IMAGE_SOURCE=$(shell git config --get remote.origin.url)
EMPTY:= EMPTY:=
SPACE:= $(EMPTY) $(EMPTY) SPACE:= $(EMPTY) $(EMPTY)
# MQ_VERSION_VRM is MQ_VERSION with only the Version, Release and Modifier fields (no Fix field). e.g. 9.1.4 instead of 9.1.4.0 # MQ_VERSION_VRM is MQ_VERSION with only the Version, Release and Modifier fields (no Fix field). e.g. 9.1.5 instead of 9.1.5.0
MQ_VERSION_VRM=$(subst $(SPACE),.,$(wordlist 1,3,$(subst .,$(SPACE),$(MQ_VERSION)))) MQ_VERSION_VRM=$(subst $(SPACE),.,$(wordlist 1,3,$(subst .,$(SPACE),$(MQ_VERSION))))
ifneq (,$(findstring Microsoft,$(shell uname -r))) ifneq (,$(findstring Microsoft,$(shell uname -r)))
@@ -116,6 +112,7 @@ MQ_ARCHIVE_DEV_9.1.1.0=mqadv_dev911_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).ta
MQ_ARCHIVE_DEV_9.1.2.0=mqadv_dev912_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).tar.gz MQ_ARCHIVE_DEV_9.1.2.0=mqadv_dev912_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).tar.gz
MQ_ARCHIVE_DEV_9.1.3.0=mqadv_dev913_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).tar.gz MQ_ARCHIVE_DEV_9.1.3.0=mqadv_dev913_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).tar.gz
MQ_ARCHIVE_DEV_9.1.4.0=mqadv_dev914_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).tar.gz MQ_ARCHIVE_DEV_9.1.4.0=mqadv_dev914_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).tar.gz
MQ_ARCHIVE_DEV_9.1.5.0=mqadv_dev915_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).tar.gz
ifneq "$(MQ_DELIVERY_REGISTRY_NAMESPACE)" "$(EMPTY)" ifneq "$(MQ_DELIVERY_REGISTRY_NAMESPACE)" "$(EMPTY)"
MQ_DELIVERY_REGISTRY_FULL_PATH=$(MQ_DELIVERY_REGISTRY_HOSTNAME)/$(MQ_DELIVERY_REGISTRY_NAMESPACE) MQ_DELIVERY_REGISTRY_FULL_PATH=$(MQ_DELIVERY_REGISTRY_HOSTNAME)/$(MQ_DELIVERY_REGISTRY_NAMESPACE)
@@ -236,11 +233,9 @@ define build-mq
--tag $1:$2 \ --tag $1:$2 \
--file $3 \ --file $3 \
$(EXTRA_ARGS) \ $(EXTRA_ARGS) \
--build-arg MQ_PACKAGES="$(MQ_PACKAGES)" \
--build-arg IMAGE_REVISION="$(IMAGE_REVISION)" \ --build-arg IMAGE_REVISION="$(IMAGE_REVISION)" \
--build-arg IMAGE_SOURCE="$(IMAGE_SOURCE)" \ --build-arg IMAGE_SOURCE="$(IMAGE_SOURCE)" \
--build-arg IMAGE_TAG="$1:$2" \ --build-arg IMAGE_TAG="$1:$2" \
--build-arg MQM_UID=$(MQM_UID) \
--label version=$(MQ_VERSION) \ --label version=$(MQ_VERSION) \
--label name=$1 \ --label name=$1 \
--label build-date=$(shell date +%Y-%m-%dT%H:%M:%S%z) \ --label build-date=$(shell date +%Y-%m-%dT%H:%M:%S%z) \
@@ -315,7 +310,6 @@ log-build-vars:
@echo MQ_IMAGE_DEVSERVER=$(MQ_IMAGE_DEVSERVER) @echo MQ_IMAGE_DEVSERVER=$(MQ_IMAGE_DEVSERVER)
@echo MQ_IMAGE_ADVANCEDSERVER=$(MQ_IMAGE_ADVANCEDSERVER) @echo MQ_IMAGE_ADVANCEDSERVER=$(MQ_IMAGE_ADVANCEDSERVER)
@echo COMMAND=$(COMMAND) @echo COMMAND=$(COMMAND)
@echo MQM_UID=$(MQM_UID)
@echo REGISTRY_USER=$(REGISTRY_USER) @echo REGISTRY_USER=$(REGISTRY_USER)
.PHONY: log-build-env .PHONY: log-build-env

View File

@@ -1,5 +1,5 @@
/* /*
© Copyright IBM Corporation 2017, 2019 © Copyright IBM Corporation 2017, 2020
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -17,14 +17,10 @@ package main
import ( import (
"os" "os"
"runtime"
"syscall"
"github.com/ibm-messaging/mq-container/internal/command"
) )
func createVolume(dataPath string) error { func createVolume(dataPath string) error {
fi, err := os.Stat(dataPath) _, err := os.Stat(dataPath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
// #nosec G301 // #nosec G301
@@ -36,25 +32,5 @@ func createVolume(dataPath string) error {
return err return err
} }
} }
fi, err = os.Stat(dataPath)
if err != nil {
return err
}
sys := fi.Sys()
if sys != nil && runtime.GOOS == "linux" {
stat := sys.(*syscall.Stat_t)
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
return err
}
log.Debugf("mqm user is %v (%v)", mqmUID, mqmGID)
if int(stat.Uid) != mqmUID || int(stat.Gid) != mqmGID {
err = os.Chown(dataPath, mqmUID, mqmGID)
if err != nil {
log.Printf("Error: Unable to change ownership of %v", dataPath)
return err
}
}
}
return nil return nil
} }

View File

@@ -112,12 +112,29 @@ func doMain() error {
return err return err
} }
enableTraceCrtmqdir := os.Getenv("MQ_ENABLE_TRACE_CRTMQDIR")
if enableTraceCrtmqdir == "true" || enableTraceCrtmqdir == "1" {
err = startMQTrace()
if err != nil {
logTermination(err)
return err
}
}
err = createDirStructure() err = createDirStructure()
if err != nil { if err != nil {
logTermination(err) logTermination(err)
return err return err
} }
if enableTraceCrtmqdir == "true" || enableTraceCrtmqdir == "1" {
err = endMQTrace()
if err != nil {
logTermination(err)
return err
}
}
// If init flag is set, exit now // If init flag is set, exit now
if *initFlag { if *initFlag {
return nil return nil
@@ -149,6 +166,7 @@ func doMain() error {
logTermination(err) logTermination(err)
return err return err
} }
var wg sync.WaitGroup var wg sync.WaitGroup
defer func() { defer func() {
log.Debug("Waiting for log mirroring to complete") log.Debug("Waiting for log mirroring to complete")

View File

@@ -32,10 +32,14 @@ import (
// createDirStructure creates the default MQ directory structure under /var/mqm // createDirStructure creates the default MQ directory structure under /var/mqm
func createDirStructure() error { func createDirStructure() error {
out, _, err := command.Run("/opt/mqm/bin/crtmqdir", "-f", "-a") out, rc, err := command.Run("/opt/mqm/bin/crtmqdir", "-f", "-a")
if err != nil { if err != nil {
log.Printf("Error creating directory structure: %v\n", string(out)) if rc == 10 {
return err log.Printf("Warning creating directory structure: %v\n", string(out))
} else {
log.Printf("Error creating directory structure: %v\n", string(out))
return err
}
} }
log.Println("Created directory structure under /var/mqm") log.Println("Created directory structure under /var/mqm")
return nil return nil

View File

@@ -19,13 +19,9 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"os/user"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"syscall"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/copy" "github.com/ibm-messaging/mq-container/internal/copy"
"github.com/ibm-messaging/mq-container/internal/mqtemplate" "github.com/ibm-messaging/mq-container/internal/mqtemplate"
"github.com/ibm-messaging/mq-container/internal/tls" "github.com/ibm-messaging/mq-container/internal/tls"
@@ -55,24 +51,6 @@ func startWebServer(webKeystore, webkeystorePW, webTruststoreRef string) error {
cmd.Env = append(cmd.Env, "AMQ_WEBKEYSTOREPW="+webkeystorePW) cmd.Env = append(cmd.Env, "AMQ_WEBKEYSTOREPW="+webkeystorePW)
cmd.Env = append(cmd.Env, "AMQ_WEBTRUSTSTOREREF="+webTruststoreRef) cmd.Env = append(cmd.Env, "AMQ_WEBTRUSTSTOREREF="+webTruststoreRef)
} }
uid, gid, err := command.LookupMQM()
if err != nil {
return err
}
u, err := user.Current()
if err != nil {
return err
}
currentUID, err := strconv.Atoi(u.Uid)
if err != nil {
return fmt.Errorf("Error converting UID to string: %v", err)
}
// Add credentials to run as 'mqm', only if we aren't already 'mqm'
if currentUID != uid {
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
}
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
rc := cmd.ProcessState.ExitCode() rc := cmd.ProcessState.ExitCode()
if err != nil { if err != nil {
@@ -162,10 +140,6 @@ func configureWebServer(keyLabel string, p12Truststore tls.KeyStoreData) (string
} }
return "", err return "", err
} }
uid, gid, err := command.LookupMQM()
if err != nil {
return "", err
}
const prefix string = "/etc/mqm/web" const prefix string = "/etc/mqm/web"
err = filepath.Walk(prefix, func(from string, info os.FileInfo, err error) error { err = filepath.Walk(prefix, func(from string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
@@ -202,10 +176,6 @@ func configureWebServer(keyLabel string, p12Truststore tls.KeyStoreData) (string
return err return err
} }
} }
err = os.Chown(to, uid, gid)
if err != nil {
return err
}
return nil return nil
}) })

View File

@@ -4,7 +4,7 @@
### User ### User
The MQ server image is run using the "mqm" user, with a fixed UID and GID of 888. The MQ server image is run using with UID 1001, though this can be any UID, with a fixed GID of 0 (root).
### Capabilities ### Capabilities
@@ -16,7 +16,7 @@ docker run \
--env LICENSE=accept \ --env LICENSE=accept \
--env MQ_QMGR_NAME=QM1 \ --env MQ_QMGR_NAME=QM1 \
--detach \ --detach \
ibm-mqadvanced-server:9.1.4.0-amd64 ibm-mqadvanced-server:9.1.5.0-amd64
``` ```
The MQ Advanced for Developers image does require the "chown", "setuid", "setgid" and "audit_write" capabilities (plus "dac_override" if you're using an image based on Red Hat Enterprise Linux). This is because it uses the "sudo" command to change passwords inside the container. For example, in Docker, you could do the following: The MQ Advanced for Developers image does require the "chown", "setuid", "setgid" and "audit_write" capabilities (plus "dac_override" if you're using an image based on Red Hat Enterprise Linux). This is because it uses the "sudo" command to change passwords inside the container. For example, in Docker, you could do the following:
@@ -31,5 +31,5 @@ docker run \
--env LICENSE=accept \ --env LICENSE=accept \
--env MQ_QMGR_NAME=QM1 \ --env MQ_QMGR_NAME=QM1 \
--detach \ --detach \
ibm-mqadvanced-server-dev:9.1.4.0-amd64 ibm-mqadvanced-server-dev:9.1.5.0-amd64
``` ```

View File

@@ -24,19 +24,18 @@ make test-advancedserver
You can specify the image to use directly by using the `MQ_IMAGE_ADVANCEDSERVER` or `MQ_IMAGE_DEVSERVER` variables, for example: You can specify the image to use directly by using the `MQ_IMAGE_ADVANCEDSERVER` or `MQ_IMAGE_DEVSERVER` variables, for example:
``` ```
MQ_IMAGE_ADVANCEDSERVER=ibm-mqadvanced-server:9.1.4.0-amd64 make test-advancedserver MQ_IMAGE_ADVANCEDSERVER=ibm-mqadvanced-server:9.1.5.0-amd64 make test-advancedserver
```
You can pass parameters to `go test` with an environment variable. For example, to run the "TestGoldenPath" test, run the following command:: You can pass parameters to `go test` with an environment variable. For example, to run the "TestGoldenPath" test, run the following command:
``` ```
TEST_OPTS_DOCKER="-run TestGoldenPath" make test-advancedserver TEST_OPTS_DOCKER="-run TestGoldenPath" make test-advancedserver
``` ```
You can also use the same environment variables you specified when [building](./building), for example, the following will try and test an image called `ibm-mqadvanced-server:9.1.4.0-amd64`: You can also use the same environment variables you specified when [building](./building), for example, the following will try and test an image called `ibm-mqadvanced-server:9.1.5.0-amd64`:
``` ```
MQ_VERSION=9.1.4.0 make test-advancedserver MQ_VERSION=9.1.5.0 make test-advancedserver
``` ```
### Running the Docker tests with code coverage ### Running the Docker tests with code coverage
@@ -48,12 +47,3 @@ make test-advancedserver-cover
``` ```
In order to generate code coverage metrics from the Docker tests, the build step creates a new Docker image with an instrumented version of the code. Each test is then run individually, producing a coverage report each under `test/docker/coverage/`. These individual reports are then combined. The combined report is written to the `coverage` directory. In order to generate code coverage metrics from the Docker tests, the build step creates a new Docker image with an instrumented version of the code. Each test is then run individually, producing a coverage report each under `test/docker/coverage/`. These individual reports are then combined. The combined report is written to the `coverage` directory.
### Running the Kubernetes tests
For the Kubernetes tests, you need to have built the Docker image, and pushed it to the registry used by your Kubernetes cluster. Most of the configuration used by the tests is picked up from your `kubectl` configuration, but you will typically need to specify the image details. For example:
```bash
MQ_IMAGE=mycluster.icp:8500/default/mq-devserver make test-kubernetes-devserver
```

View File

@@ -71,7 +71,7 @@ FROM ibmcom/mq
USER root USER root
RUN useradd alice -G mqm && \ RUN useradd alice -G mqm && \
echo alice:passw0rd | chpasswd echo alice:passw0rd | chpasswd
USER mqm USER 1001
COPY 20-config.mqsc /etc/mqm/ COPY 20-config.mqsc /etc/mqm/
``` ```

View File

@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# -*- mode: sh -*- # -*- mode: sh -*-
# © Copyright IBM Corporation 2015, 2019 # © Copyright IBM Corporation 2015, 2020
# #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,74 +18,44 @@
# Fail on any non-zero return code # Fail on any non-zero return code
set -ex set -ex
mqm_uid=${1:-888}
test -f /usr/bin/yum && YUM=true || YUM=false
test -f /usr/bin/microdnf && MICRODNF=true || MICRODNF=false
test -f /usr/bin/rpm && RPM=true || RPM=false test -f /usr/bin/rpm && RPM=true || RPM=false
test -f /usr/bin/apt-get && UBUNTU=true || UBUNTU=false test -f /usr/bin/apt-get && UBUNTU=true || UBUNTU=false
# Download and extract the MQ installation files # Download and extract the MQ unzippable server
DIR_EXTRACT=/tmp/mq DIR_TMP=/tmp/mq
mkdir -p ${DIR_EXTRACT} mkdir -p ${DIR_TMP}
cd ${DIR_EXTRACT} cd ${DIR_TMP}
curl -LO $MQ_URL curl -LO $MQ_URL
tar -zxf ./*.tar.gz
# Recommended: Create the mqm user ID with a fixed UID and group, so that the file permissions work between different images INSTALLATION_DIR=/opt/mqm
groupadd --system --gid ${mqm_uid} mqm tar -C ${INSTALLATION_DIR} -xzf ./*.tar.gz
useradd --system --uid ${mqm_uid} --gid mqm --groups 0 mqm ls -la ${INSTALLATION_DIR}
rm -rf ${DIR_TMP}
# Find directory containing .deb files
$UBUNTU && DIR_DEB=$(find ${DIR_EXTRACT} -name "*.deb" -printf "%h\n" | sort -u | head -1)
$RPM && DIR_RPM=$(find ${DIR_EXTRACT} -name "*.rpm" -printf "%h\n" | sort -u | head -1)
# Find location of mqlicense.sh
MQLICENSE=$(find ${DIR_EXTRACT} -name "mqlicense.sh")
# Accept the MQ license # Accept the MQ license
${MQLICENSE} -text_only -accept ${INSTALLATION_DIR}/bin/mqlicense -accept
$UBUNTU && echo "deb [trusted=yes] file:${DIR_DEB} ./" > /etc/apt/sources.list.d/IBM_MQ.list
# Install MQ using the DEB packages
$UBUNTU && apt-get update
$UBUNTU && apt-get install -y $MQ_PACKAGES
$RPM && cd $DIR_RPM && rpm -ivh $MQ_PACKAGES
# Remove 32-bit libraries from 64-bit container # Remove 32-bit libraries from 64-bit container
# The "file" utility isn't installed by default in UBI, so only try this if it's installed # The "file" utility isn't installed by default in UBI, so only try this if it's installed
which file && find /opt/mqm /var/mqm -type f -exec file {} \; | awk -F: '/ELF 32-bit/{print $1}' | xargs --no-run-if-empty rm -f which file && find ${INSTALLATION_DIR} /var/mqm -type f -exec file {} \; | awk -F: '/ELF 32-bit/{print $1}' | xargs --no-run-if-empty rm -f
# Remove tar.gz files unpacked by RPM postinst scripts
find /opt/mqm -name '*.tar.gz' -delete
# Recommended: Set the default MQ installation (makes the MQ commands available on the PATH)
/opt/mqm/bin/setmqinst -p /opt/mqm -i
# Clean up all the downloaded files
$UBUNTU && rm -f /etc/apt/sources.list.d/IBM_MQ.list
rm -rf ${DIR_EXTRACT}
# Optional: Update the command prompt with the MQ version # Optional: Update the command prompt with the MQ version
$UBUNTU && echo "mq:$(dspmqver -b -f 2)" > /etc/debian_chroot $UBUNTU && echo "mq:$(dspmqver -b -f 2)" > /etc/debian_chroot
# Remove the directory structure under /var/mqm which was created by the installer
rm -rf /var/mqm
# Create the mount point for volumes, ensuring MQ has permissions to all directories # Create the mount point for volumes, ensuring MQ has permissions to all directories
install --directory --mode 0775 --owner mqm --group root /mnt install --directory --mode 0775 --owner 1001 --group root /mnt
install --directory --mode 0775 --owner mqm --group root /mnt/mqm install --directory --mode 0775 --owner 1001 --group root /mnt/mqm
install --directory --mode 0775 --owner mqm --group root /mnt/mqm/data install --directory --mode 0775 --owner 1001 --group root /mnt/mqm/data
install --directory --mode 0775 --owner mqm --group root /mnt/mqm-log install --directory --mode 0775 --owner 1001 --group root /mnt/mqm-log
install --directory --mode 0775 --owner mqm --group root /mnt/mqm-log/log install --directory --mode 0775 --owner 1001 --group root /mnt/mqm-log/log
install --directory --mode 0775 --owner mqm --group root /mnt/mqm-data install --directory --mode 0775 --owner 1001 --group root /mnt/mqm-data
install --directory --mode 0775 --owner mqm --group root /mnt/mqm-data/qmgrs install --directory --mode 0775 --owner 1001 --group root /mnt/mqm-data/qmgrs
# Create the directory for MQ configuration files # Create the directory for MQ configuration files
install --directory --mode 0775 --owner mqm --group root /etc/mqm install --directory --mode 0775 --owner 1001 --group root /etc/mqm
# Create the directory for MQ runtime files # Create the directory for MQ runtime files
install --directory --mode 0775 --owner mqm --group root /run/mqm install --directory --mode 2775 --owner 1001 --group root /run/mqm
# Create a symlink for /var/mqm -> /mnt/mqm/data # Create a symlink for /var/mqm -> /mnt/mqm/data
ln -s /mnt/mqm/data /var/mqm ln -s /mnt/mqm/data /var/mqm
@@ -110,4 +80,3 @@ sed -i 's/v7.0/v8.0/g' /opt/mqm/licenses/non_ibm_license.txt
# Copy MQ Licenses into the correct location # Copy MQ Licenses into the correct location
mkdir -p /licenses mkdir -p /licenses
cp /opt/mqm/licenses/*.txt /licenses/ cp /opt/mqm/licenses/*.txt /licenses/

View File

@@ -1,5 +1,5 @@
/* /*
© Copyright IBM Corporation 2017, 2018 © Copyright IBM Corporation 2017, 2020
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -20,9 +20,6 @@ package command
import ( import (
"fmt" "fmt"
"os/exec" "os/exec"
"os/user"
"strconv"
"syscall"
) )
// Run runs an OS command. On Linux it waits for the command to // Run runs an OS command. On Linux it waits for the command to
@@ -40,33 +37,3 @@ func Run(name string, arg ...string) (string, int, error) {
} }
return string(out), rc, nil return string(out), rc, nil
} }
// RunAsMQM runs the specified command as the mqm user
func RunAsMQM(name string, arg ...string) (string, int, error) {
// #nosec G204
cmd := exec.Command(name, arg...)
cmd.SysProcAttr = &syscall.SysProcAttr{}
uid, gid, err := LookupMQM()
if err != nil {
return "", 0, err
}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
return Run(name, arg...)
}
// LookupMQM looks up the UID & GID of the mqm user
func LookupMQM() (int, int, error) {
mqm, err := user.Lookup("mqm")
if err != nil {
return -1, -1, err
}
mqmUID, err := strconv.Atoi(mqm.Uid)
if err != nil {
return -1, -1, err
}
mqmGID, err := strconv.Atoi(mqm.Gid)
if err != nil {
return -1, -1, err
}
return mqmUID, mqmGID, nil
}

View File

@@ -1,5 +1,5 @@
/* /*
© Copyright IBM Corporation 2018, 2019 © Copyright IBM Corporation 2018, 2020
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -105,14 +105,6 @@ func (ks *KeyStore) Create() error {
return fmt.Errorf("error running \"%v -keydb -create\": %v %s", ks.command, err, out) return fmt.Errorf("error running \"%v -keydb -create\": %v %s", ks.command, err, out)
} }
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
return err
}
err = os.Chown(ks.Filename, mqmUID, mqmGID)
if err != nil {
return err
}
return nil return nil
} }
@@ -130,14 +122,6 @@ func (ks *KeyStore) CreateStash() error {
} }
return err return err
} }
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
return err
}
err = os.Chown(stashFile, mqmUID, mqmGID)
if err != nil {
return err
}
return nil return nil
} }

View File

@@ -1,5 +1,5 @@
/* /*
© Copyright IBM Corporation 2018, 2019 © Copyright IBM Corporation 2018, 2020
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import (
"path" "path"
"text/template" "text/template"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/pkg/logger" "github.com/ibm-messaging/mq-container/pkg/logger"
) )
@@ -45,16 +44,6 @@ func ProcessTemplateFile(templateFile, destFile string, data interface{}, log *l
log.Error(err) log.Error(err)
return err return err
} }
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(dir, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
} else { } else {
return err return err
} }
@@ -67,15 +56,5 @@ func ProcessTemplateFile(templateFile, destFile string, data interface{}, log *l
log.Error(err) log.Error(err)
return err return err
} }
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(destFile, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
return nil return nil
} }

View File

@@ -20,7 +20,6 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/keystore" "github.com/ibm-messaging/mq-container/internal/keystore"
) )
@@ -51,14 +50,6 @@ func ConfigureWebTLS(keyLabel string) error {
if err != nil { if err != nil {
return fmt.Errorf("Failed to create symlink %s->%s: %v", newTLSConfig, tlsConfig, err) return fmt.Errorf("Failed to create symlink %s->%s: %v", newTLSConfig, tlsConfig, err)
} }
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
return fmt.Errorf("Failed to find mqm user or group: %v", err)
}
err = os.Chown(tlsConfig, mqmUID, mqmGID)
if err != nil {
return fmt.Errorf("Failed to change ownership of %s to mqm: %v", tlsConfig, err)
}
return nil return nil
} }

View File

@@ -143,7 +143,7 @@ func TestDevWebDisabled(t *testing.T) {
defer cleanContainer(t, cli, id) defer cleanContainer(t, cli, id)
waitForReady(t, cli, id) waitForReady(t, cli, id)
t.Run("Web", func(t *testing.T) { t.Run("Web", func(t *testing.T) {
_, dspmqweb := execContainer(t, cli, id, "mqm", []string{"dspmqweb"}) _, dspmqweb := execContainer(t, cli, id, "", []string{"dspmqweb"})
if !strings.Contains(dspmqweb, "Server mqweb is not running.") && !strings.Contains(dspmqweb, "MQWB1125I") { if !strings.Contains(dspmqweb, "Server mqweb is not running.") && !strings.Contains(dspmqweb, "MQWB1125I") {
t.Errorf("Expected dspmqweb to say 'Server is not running' or 'MQWB1125I'; got \"%v\"", dspmqweb) t.Errorf("Expected dspmqweb to say 'Server is not running' or 'MQWB1125I'; got \"%v\"", dspmqweb)
} }
@@ -174,7 +174,7 @@ func TestDevConfigDisabled(t *testing.T) {
defer cleanContainer(t, cli, id) defer cleanContainer(t, cli, id)
waitForReady(t, cli, id) waitForReady(t, cli, id)
waitForWebReady(t, cli, id, insecureTLSConfig) waitForWebReady(t, cli, id, insecureTLSConfig)
rc, _ := execContainer(t, cli, id, "mqm", []string{"bash", "-c", "echo 'display qlocal(DEV*)' | runmqsc"}) rc, _ := execContainer(t, cli, id, "", []string{"bash", "-c", "echo 'display qlocal(DEV*)' | runmqsc"})
if rc == 0 { if rc == 0 {
t.Errorf("Expected DEV queues to be missing") t.Errorf("Expected DEV queues to be missing")
} }

View File

@@ -91,7 +91,7 @@ func TestEndMQMOpts(t *testing.T) {
defer cleanContainer(t, cli, id) defer cleanContainer(t, cli, id)
waitForReady(t, cli, id) waitForReady(t, cli, id)
killContainer(t, cli, id, "SIGTERM") killContainer(t, cli, id, "SIGTERM")
_, out := execContainer(t, cli, id, "mqm", []string{"bash", "-c", "ps -ef | grep 'endmqm -w -r -tp 27'"}) _, out := execContainer(t, cli, id, "", []string{"bash", "-c", "ps -ef | grep 'endmqm -w -r -tp 27'"})
t.Log(out) t.Log(out)
if !strings.Contains(out, "endmqm -w -r -tp 27") { if !strings.Contains(out, "endmqm -w -r -tp 27") {
t.Errorf("Expected endmqm options endmqm -w -r -tp 27; got \"%v\"", out) t.Errorf("Expected endmqm options endmqm -w -r -tp 27; got \"%v\"", out)
@@ -182,7 +182,7 @@ func utilTestNoQueueManagerName(t *testing.T, hostName string, expectedName stri
id := runContainer(t, cli, &containerConfig) id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id) defer cleanContainer(t, cli, id)
waitForReady(t, cli, id) waitForReady(t, cli, id)
_, out := execContainer(t, cli, id, "mqm", []string{"dspmq"}) _, out := execContainer(t, cli, id, "", []string{"dspmq"})
if !strings.Contains(out, search) { if !strings.Contains(out, search) {
t.Errorf("Expected result of running dspmq to contain name=%v, got name=%v", search, out) t.Errorf("Expected result of running dspmq to contain name=%v, got name=%v", search, out)
} }
@@ -414,9 +414,7 @@ func TestCreateQueueManagerFail(t *testing.T) {
FROM %v FROM %v
USER root USER root
RUN echo '#!/bin/bash\nexit 999' > /opt/mqm/bin/crtmqm RUN echo '#!/bin/bash\nexit 999' > /opt/mqm/bin/crtmqm
RUN chown mqm:mqm /opt/mqm/bin/crtmqm USER 1001`, imageName())},
RUN chmod 6550 /opt/mqm/bin/crtmqm
USER mqm`, imageName())},
} }
tag := createImage(t, cli, files) tag := createImage(t, cli, files)
defer deleteImage(t, cli, tag) defer deleteImage(t, cli, tag)
@@ -449,9 +447,7 @@ func TestStartQueueManagerFail(t *testing.T) {
FROM %v FROM %v
USER root USER root
RUN echo '#!/bin/bash\ndltmqm $@ && strmqm $@' > /opt/mqm/bin/strmqm RUN echo '#!/bin/bash\ndltmqm $@ && strmqm $@' > /opt/mqm/bin/strmqm
RUN chown mqm:mqm /opt/mqm/bin/strmqm USER 1001`, imageName())},
RUN chmod 6550 /opt/mqm/bin/strmqm
USER mqm`, imageName())},
} }
tag := createImage(t, cli, files) tag := createImage(t, cli, files)
defer deleteImage(t, cli, tag) defer deleteImage(t, cli, tag)
@@ -510,12 +506,12 @@ func TestVolumeUnmount(t *testing.T) {
t.Fatalf("Expected umount to work with rc=0, got %v. Output was: %s", rc, out) t.Fatalf("Expected umount to work with rc=0, got %v. Output was: %s", rc, out)
} }
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
rc, _ = execContainer(t, cli, ctr.ID, "mqm", []string{"chkmqhealthy"}) rc, _ = execContainer(t, cli, ctr.ID, "", []string{"chkmqhealthy"})
if rc == 0 { if rc == 0 {
t.Errorf("Expected chkmqhealthy to fail") t.Errorf("Expected chkmqhealthy to fail")
_, df := execContainer(t, cli, ctr.ID, "mqm", []string{"df"}) _, df := execContainer(t, cli, ctr.ID, "", []string{"df"})
t.Logf(df) t.Logf(df)
_, ps := execContainer(t, cli, ctr.ID, "mqm", []string{"ps", "-ef"}) _, ps := execContainer(t, cli, ctr.ID, "", []string{"ps", "-ef"})
t.Logf(ps) t.Logf(ps)
} }
} }
@@ -541,14 +537,14 @@ func TestZombies(t *testing.T) {
waitForReady(t, cli, id) waitForReady(t, cli, id)
// Kill an MQ process with children. After it is killed, its children // Kill an MQ process with children. After it is killed, its children
// will be adopted by PID 1, and should then be reaped when they die. // will be adopted by PID 1, and should then be reaped when they die.
_, out := execContainer(t, cli, id, "mqm", []string{"pkill", "--signal", "kill", "-c", "amqzxma0"}) _, out := execContainer(t, cli, id, "", []string{"pkill", "--signal", "kill", "-c", "amqzxma0"})
if out == "0" { if out == "0" {
t.Log("Failed to kill process 'amqzxma0'") t.Log("Failed to kill process 'amqzxma0'")
_, out := execContainer(t, cli, id, "root", []string{"ps", "-lA"}) _, out := execContainer(t, cli, id, "", []string{"ps", "-lA"})
t.Fatalf("Here is a list of currently running processes:\n%s", out) t.Fatalf("Here is a list of currently running processes:\n%s", out)
} }
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
_, out = execContainer(t, cli, id, "mqm", []string{"bash", "-c", "ps -lA | grep '^. Z'"}) _, out = execContainer(t, cli, id, "", []string{"bash", "-c", "ps -lA | grep '^. Z'"})
if out != "" { if out != "" {
count := strings.Count(out, "\n") + 1 count := strings.Count(out, "\n") + 1
t.Errorf("Expected zombies=0, got %v", count) t.Errorf("Expected zombies=0, got %v", count)
@@ -575,7 +571,7 @@ func TestMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/ ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())}, USER 1001`, imageName())},
{"test.mqsc", "DEFINE QLOCAL(test)"}, {"test.mqsc", "DEFINE QLOCAL(test)"},
} }
tag := createImage(t, cli, files) tag := createImage(t, cli, files)
@@ -588,7 +584,7 @@ func TestMQSC(t *testing.T) {
id := runContainer(t, cli, &containerConfig) id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id) defer cleanContainer(t, cli, id)
waitForReady(t, cli, id) waitForReady(t, cli, id)
rc, mqscOutput := execContainer(t, cli, id, "mqm", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test)' | runmqsc"}) rc, mqscOutput := execContainer(t, cli, id, "", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test)' | runmqsc"})
if rc != 0 { if rc != 0 {
r := regexp.MustCompile("AMQ[0-9][0-9][0-9][0-9]E") r := regexp.MustCompile("AMQ[0-9][0-9][0-9][0-9]E")
t.Fatalf("Expected runmqsc to exit with rc=0, got %v with error %v", rc, r.FindString(mqscOutput)) t.Fatalf("Expected runmqsc to exit with rc=0, got %v with error %v", rc, r.FindString(mqscOutput))
@@ -618,7 +614,7 @@ func TestLargeMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/ ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())}, USER 1001`, imageName())},
{"test.mqsc", buf.String()}, {"test.mqsc", buf.String()},
} }
tag := createImage(t, cli, files) tag := createImage(t, cli, files)
@@ -632,7 +628,7 @@ func TestLargeMQSC(t *testing.T) {
defer cleanContainer(t, cli, id) defer cleanContainer(t, cli, id)
waitForReady(t, cli, id) waitForReady(t, cli, id)
rc, mqscOutput := execContainer(t, cli, id, "mqm", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test" + strconv.Itoa(numQueues) + ")' | runmqsc"}) rc, mqscOutput := execContainer(t, cli, id, "", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test" + strconv.Itoa(numQueues) + ")' | runmqsc"})
if rc != 0 { if rc != 0 {
r := regexp.MustCompile("AMQ[0-9][0-9][0-9][0-9]E") r := regexp.MustCompile("AMQ[0-9][0-9][0-9][0-9]E")
t.Fatalf("Expected runmqsc to exit with rc=0, got %v with error %v", rc, r.FindString(mqscOutput)) t.Fatalf("Expected runmqsc to exit with rc=0, got %v with error %v", rc, r.FindString(mqscOutput))
@@ -690,7 +686,7 @@ func TestRedactValidMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/ ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())}, USER 1001`, imageName())},
{"test.mqsc", buf.String()}, {"test.mqsc", buf.String()},
} }
tag := createImage(t, cli, files) tag := createImage(t, cli, files)
@@ -762,7 +758,7 @@ func TestRedactInvalidMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/ ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())}, USER 1001`, imageName())},
{"test.mqsc", buf.String()}, {"test.mqsc", buf.String()},
} }
tag := createImage(t, cli, files) tag := createImage(t, cli, files)
@@ -808,7 +804,7 @@ func TestInvalidMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc RUN rm -f /etc/mqm/*.mqsc
ADD mqscTest.mqsc /etc/mqm/ ADD mqscTest.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/mqscTest.mqsc RUN chmod 0660 /etc/mqm/mqscTest.mqsc
USER mqm`, imageName())}, USER 1001`, imageName())},
{"mqscTest.mqsc", "DEFINE INVALIDLISTENER('TEST.LISTENER.TCP') TRPTYPE(TCP) PORT(1414) CONTROL(QMGR) REPLACE"}, {"mqscTest.mqsc", "DEFINE INVALIDLISTENER('TEST.LISTENER.TCP') TRPTYPE(TCP) PORT(1414) CONTROL(QMGR) REPLACE"},
} }
tag := createImage(t, cli, files) tag := createImage(t, cli, files)
@@ -841,7 +837,7 @@ func TestSimpleMQIniMerge(t *testing.T) {
USER root USER root
ADD test1.ini /etc/mqm/ ADD test1.ini /etc/mqm/
RUN chmod 0660 /etc/mqm/test1.ini RUN chmod 0660 /etc/mqm/test1.ini
USER mqm`, imageName())}, USER 1001`, imageName())},
{"test1.ini", {"test1.ini",
"Log:\n LogSecondaryFiles=28"}, "Log:\n LogSecondaryFiles=28"},
} }
@@ -857,7 +853,7 @@ func TestSimpleMQIniMerge(t *testing.T) {
waitForReady(t, cli, id) waitForReady(t, cli, id)
catIniFileCommand := fmt.Sprintf("cat /var/mqm/qmgrs/qm1/qm.ini") catIniFileCommand := fmt.Sprintf("cat /var/mqm/qmgrs/qm1/qm.ini")
_, test := execContainer(t, cli, id, "mqm", []string{"bash", "-c", catIniFileCommand}) _, test := execContainer(t, cli, id, "", []string{"bash", "-c", catIniFileCommand})
merged := strings.Contains(test, "LogSecondaryFiles=28") merged := strings.Contains(test, "LogSecondaryFiles=28")
if !merged { if !merged {
@@ -883,7 +879,7 @@ func TestMultipleIniMerge(t *testing.T) {
RUN chmod 0660 /etc/mqm/test1.ini RUN chmod 0660 /etc/mqm/test1.ini
RUN chmod 0660 /etc/mqm/test2.ini RUN chmod 0660 /etc/mqm/test2.ini
RUN chmod 0660 /etc/mqm/test3.ini RUN chmod 0660 /etc/mqm/test3.ini
USER mqm`, imageName())}, USER 1001`, imageName())},
{"test1.ini", {"test1.ini",
"Log:\n LogSecondaryFiles=28"}, "Log:\n LogSecondaryFiles=28"},
{"test2.ini", {"test2.ini",
@@ -903,7 +899,7 @@ func TestMultipleIniMerge(t *testing.T) {
waitForReady(t, cli, id) waitForReady(t, cli, id)
catIniFileCommand := fmt.Sprintf("cat /var/mqm/qmgrs/qm1/qm.ini") catIniFileCommand := fmt.Sprintf("cat /var/mqm/qmgrs/qm1/qm.ini")
_, test := execContainer(t, cli, id, "mqm", []string{"bash", "-c", catIniFileCommand}) _, test := execContainer(t, cli, id, "", []string{"bash", "-c", catIniFileCommand})
//checks that no duplicates are created by adding 2 ini files with the same line //checks that no duplicates are created by adding 2 ini files with the same line
numberOfDuplicates := strings.Count(test, "LogSecondaryFiles=28") numberOfDuplicates := strings.Count(test, "LogSecondaryFiles=28")
@@ -929,7 +925,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
USER root USER root
ADD test1.ini /etc/mqm/ ADD test1.ini /etc/mqm/
RUN chmod 0660 /etc/mqm/test1.ini RUN chmod 0660 /etc/mqm/test1.ini
USER mqm`, imageName())}, USER 1001`, imageName())},
{"test1.ini", {"test1.ini",
"ApplicationTrace:\n ApplName=amqsact*\n Trace=OFF"}, "ApplicationTrace:\n ApplName=amqsact*\n Trace=OFF"},
} }
@@ -959,7 +955,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
waitForReady(t, cli, ctr1.ID) waitForReady(t, cli, ctr1.ID)
catIniFileCommand := fmt.Sprintf("cat /var/mqm/qmgrs/qm1/qm.ini") catIniFileCommand := fmt.Sprintf("cat /var/mqm/qmgrs/qm1/qm.ini")
_, test := execContainer(t, cli, ctr1.ID, "mqm", []string{"bash", "-c", catIniFileCommand}) _, test := execContainer(t, cli, ctr1.ID, "", []string{"bash", "-c", catIniFileCommand})
addedStanza := strings.Contains(test, "ApplicationTrace:\n ApplName=amqsact*\n Trace=OFF") addedStanza := strings.Contains(test, "ApplicationTrace:\n ApplName=amqsact*\n Trace=OFF")
if addedStanza != true { if addedStanza != true {
@@ -976,7 +972,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
USER root USER root
ADD test1.ini /etc/mqm/ ADD test1.ini /etc/mqm/
RUN chmod 0660 /etc/mqm/test1.ini RUN chmod 0660 /etc/mqm/test1.ini
USER mqm`, imageName())}, USER 1001`, imageName())},
{"test1.ini", {"test1.ini",
"Log:\n LogFilePages=5000"}, "Log:\n LogFilePages=5000"},
} }
@@ -997,7 +993,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
startContainer(t, cli, ctr2.ID) startContainer(t, cli, ctr2.ID)
waitForReady(t, cli, ctr2.ID) waitForReady(t, cli, ctr2.ID)
_, test2 := execContainer(t, cli, ctr2.ID, "mqm", []string{"bash", "-c", catIniFileCommand}) _, test2 := execContainer(t, cli, ctr2.ID, "", []string{"bash", "-c", catIniFileCommand})
changedStanza := strings.Contains(test2, "LogFilePages=5000") changedStanza := strings.Contains(test2, "LogFilePages=5000")
//check if stanza that was merged in the first container doesnt exist in this one. //check if stanza that was merged in the first container doesnt exist in this one.
firstMergedStanza := strings.Contains(test2, "ApplicationTrace:\n ApplName=amqsact*\n Trace=OFF") firstMergedStanza := strings.Contains(test2, "ApplicationTrace:\n ApplName=amqsact*\n Trace=OFF")
@@ -1032,7 +1028,7 @@ func TestReadiness(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/ ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())}, USER 1001`, imageName())},
{"test.mqsc", buf.String()}, {"test.mqsc", buf.String()},
} }
tag := createImage(t, cli, files) tag := createImage(t, cli, files)
@@ -1045,11 +1041,11 @@ func TestReadiness(t *testing.T) {
id := runContainer(t, cli, &containerConfig) id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id) defer cleanContainer(t, cli, id)
queueCheckCommand := fmt.Sprintf("echo 'DISPLAY QLOCAL(test%v)' | runmqsc", numQueues) queueCheckCommand := fmt.Sprintf("echo 'DISPLAY QLOCAL(test%v)' | runmqsc", numQueues)
_, mqsc := execContainer(t, cli, id, "root", []string{"cat", "/etc/mqm/test.mqsc"}) _, mqsc := execContainer(t, cli, id, "", []string{"cat", "/etc/mqm/test.mqsc"})
t.Log(mqsc) t.Log(mqsc)
for { for {
readyRC, _ := execContainer(t, cli, id, "mqm", []string{"chkmqready"}) readyRC, _ := execContainer(t, cli, id, "", []string{"chkmqready"})
queueCheckRC, queueCheckOut := execContainer(t, cli, id, "mqm", []string{"bash", "-c", queueCheckCommand}) queueCheckRC, queueCheckOut := execContainer(t, cli, id, "", []string{"bash", "-c", queueCheckCommand})
t.Logf("readyRC=%v,queueCheckRC=%v\n", readyRC, queueCheckRC) t.Logf("readyRC=%v,queueCheckRC=%v\n", readyRC, queueCheckRC)
if readyRC == 0 { if readyRC == 0 {
@@ -1058,7 +1054,7 @@ func TestReadiness(t *testing.T) {
t.Fatalf("Runmqsc returned %v with error %v. chkmqready returned %v when MQSC had not finished", queueCheckRC, r.FindString(queueCheckOut), readyRC) t.Fatalf("Runmqsc returned %v with error %v. chkmqready returned %v when MQSC had not finished", queueCheckRC, r.FindString(queueCheckOut), readyRC)
} else { } else {
// chkmqready says OK, and the last queue exists, so return // chkmqready says OK, and the last queue exists, so return
_, runmqsc := execContainer(t, cli, id, "root", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test1)' | runmqsc"}) _, runmqsc := execContainer(t, cli, id, "", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test1)' | runmqsc"})
t.Log(runmqsc) t.Log(runmqsc)
return return
} }
@@ -1107,7 +1103,7 @@ func TestErrorLogRotation(t *testing.T) {
for { for {
execContainer(t, cli, id, "fred", []string{"bash", "-c", "/opt/mqm/samp/bin/amqsput FAKE"}) execContainer(t, cli, id, "fred", []string{"bash", "-c", "/opt/mqm/samp/bin/amqsput FAKE"})
_, atoiStr := execContainer(t, cli, id, "mqm", []string{"bash", "-c", "wc -c < " + filepath.Join(dir, "AMQERR02.json")}) _, atoiStr := execContainer(t, cli, id, "", []string{"bash", "-c", "wc -c < " + filepath.Join(dir, "AMQERR02.json")})
amqerr02size, _ := strconv.Atoi(atoiStr) amqerr02size, _ := strconv.Atoi(atoiStr)
if amqerr02size > 0 { if amqerr02size > 0 {
@@ -1115,7 +1111,7 @@ func TestErrorLogRotation(t *testing.T) {
break break
} }
} }
_, out := execContainer(t, cli, id, "root", []string{"ls", "-l", dir}) _, out := execContainer(t, cli, id, "", []string{"ls", "-l", dir})
t.Log(out) t.Log(out)
stopContainer(t, cli, id) stopContainer(t, cli, id)
b := copyFromContainer(t, cli, id, filepath.Join(dir, "AMQERR01.json")) b := copyFromContainer(t, cli, id, filepath.Join(dir, "AMQERR01.json"))
@@ -1259,7 +1255,7 @@ func TestCorrectLicense(t *testing.T) {
defer cleanContainer(t, cli, id) defer cleanContainer(t, cli, id)
waitForReady(t, cli, id) waitForReady(t, cli, id)
rc, license := execContainer(t, cli, id, "mqm", []string{"dspmqver", "-f", "8192", "-b"}) rc, license := execContainer(t, cli, id, "", []string{"dspmqver", "-f", "8192", "-b"})
if rc != 0 { if rc != 0 {
t.Fatalf("Failed to get license string. RC=%d. Output=%s", rc, license) t.Fatalf("Failed to get license string. RC=%d. Output=%s", rc, license)
} }
@@ -1408,7 +1404,7 @@ func TestTraceStrmqm(t *testing.T) {
defer cleanContainer(t, cli, id) defer cleanContainer(t, cli, id)
waitForReady(t, cli, id) waitForReady(t, cli, id)
rc, _ := execContainer(t, cli, id, "mqm", []string{"bash", "-c", "ls -A /var/mqm/trace | grep .TRC"}) rc, _ := execContainer(t, cli, id, "", []string{"bash", "-c", "ls -A /var/mqm/trace | grep .TRC"})
if rc != 0 { if rc != 0 {
t.Fatalf("No trace files found in trace directory /var/mqm/trace. RC=%d.", rc) t.Fatalf("No trace files found in trace directory /var/mqm/trace. RC=%d.", rc)
} }

View File

@@ -1,5 +1,5 @@
/* /*
© Copyright IBM Corporation 2017, 2019 © Copyright IBM Corporation 2017, 2020
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"math/rand"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@@ -259,6 +260,13 @@ func cleanContainer(t *testing.T, cli *client.Client, ID string) {
} }
} }
func generateRandomUID() string {
rand.Seed(time.Now().UnixNano())
min := 1000
max := 9999
return fmt.Sprint(rand.Intn(max-min) + min)
}
// runContainerWithPorts creates and starts a container, exposing the specified ports on the host. // runContainerWithPorts creates and starts a container, exposing the specified ports on the host.
// If no image is specified in the container config, then the image name is retrieved from the TEST_IMAGE // If no image is specified in the container config, then the image name is retrieved from the TEST_IMAGE
// environment variable. // environment variable.
@@ -266,9 +274,9 @@ func runContainerWithPorts(t *testing.T, cli *client.Client, containerConfig *co
if containerConfig.Image == "" { if containerConfig.Image == "" {
containerConfig.Image = imageName() containerConfig.Image = imageName()
} }
// Always run as the "mqm" user, unless the test has specified otherwise // Always run as a random user, unless the test has specified otherwise
if containerConfig.User == "" { if containerConfig.User == "" {
containerConfig.User = "mqm" containerConfig.User = generateRandomUID()
} }
// if coverage // if coverage
containerConfig.Env = append(containerConfig.Env, "COVERAGE_FILE="+t.Name()+".cov") containerConfig.Env = append(containerConfig.Env, "COVERAGE_FILE="+t.Name()+".cov")
@@ -281,15 +289,9 @@ func runContainerWithPorts(t *testing.T, cli *client.Client, containerConfig *co
CapDrop: []string{ CapDrop: []string{
"ALL", "ALL",
}, },
Privileged: false,
} }
if devImage(t, cli) { if devImage(t, cli) {
t.Logf("Detected MQ Advanced for Developers image — adding extra Linux capabilities to container")
hostConfig.CapAdd = []string{
"CHOWN",
"SETUID",
"SETGID",
"AUDIT_WRITE",
}
// Only needed for a RHEL-based image // Only needed for a RHEL-based image
if baseImage(t, cli) != "ubuntu" { if baseImage(t, cli) != "ubuntu" {
hostConfig.CapAdd = append(hostConfig.CapAdd, "DAC_OVERRIDE") hostConfig.CapAdd = append(hostConfig.CapAdd, "DAC_OVERRIDE")
@@ -592,13 +594,15 @@ func execContainer(t *testing.T, cli *client.Client, ID string, user string, cmd
} }
func waitForReady(t *testing.T, cli *client.Client, ID string) { func waitForReady(t *testing.T, cli *client.Client, ID string) {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel() defer cancel()
for { for {
select { select {
case <-time.After(1 * time.Second): case <-time.After(1 * time.Second):
rc, _ := execContainer(t, cli, ID, "mqm", []string{"chkmqready"}) rc, _ := execContainer(t, cli, ID, "", []string{"chkmqready"})
if rc == 0 { if rc == 0 {
t.Log("MQ is ready") t.Log("MQ is ready")
return return

View File

@@ -1,5 +1,5 @@
/* /*
© Copyright IBM Corporation 2019 © Copyright IBM Corporation 2019, 2020
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@@ -76,7 +76,7 @@ func getActiveStandbyQueueManager(t *testing.T, cli *client.Client, qm1aId strin
} }
func getQueueManagerStatus(t *testing.T, cli *client.Client, containerID string, queueManagerName string) string { func getQueueManagerStatus(t *testing.T, cli *client.Client, containerID string, queueManagerName string) string {
_, dspmqOut := execContainer(t, cli, containerID, "mqm", []string{"bash", "-c", "dspmq", "-m", queueManagerName}) _, dspmqOut := execContainer(t, cli, containerID, "", []string{"bash", "-c", "dspmq", "-m", queueManagerName})
regex := regexp.MustCompile(`STATUS\(.*\)`) regex := regexp.MustCompile(`STATUS\(.*\)`)
status := regex.FindString(dspmqOut) status := regex.FindString(dspmqOut)
status = strings.TrimSuffix(strings.TrimPrefix(status, "STATUS("), ")") status = strings.TrimSuffix(strings.TrimPrefix(status, "STATUS("), ")")

View File

@@ -286,12 +286,12 @@ func TestQMRestart(t *testing.T) {
// Restart just the QM (to simulate a lost connection) // Restart just the QM (to simulate a lost connection)
t.Log("Stopping queue manager\n") t.Log("Stopping queue manager\n")
rc, out := execContainer(t, cli, id, "mqm", []string{"endmqm", "-w", "-r", defaultMetricQMName}) rc, out := execContainer(t, cli, id, "", []string{"endmqm", "-w", "-r", defaultMetricQMName})
if rc != 0 { if rc != 0 {
t.Fatalf("Failed to stop the queue manager. rc=%d, err=%s", rc, out) t.Fatalf("Failed to stop the queue manager. rc=%d, err=%s", rc, out)
} }
t.Log("starting queue manager\n") t.Log("starting queue manager\n")
rc, out = execContainer(t, cli, id, "mqm", []string{"strmqm", defaultMetricQMName}) rc, out = execContainer(t, cli, id, "", []string{"strmqm", defaultMetricQMName})
if rc != 0 { if rc != 0 {
t.Fatalf("Failed to start the queue manager. rc=%d, err=%s", rc, out) t.Fatalf("Failed to start the queue manager. rc=%d, err=%s", rc, out)
} }