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");
# 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
os: linux
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
- if: branch = private-master OR tag =~ ^pre-release*
name: "Multi-Arch AMD64 build"
os: linux
env:
- BUILD_ALL=true
- MQ_ARCHIVE_REPOSITORY=$MQ_914_ARCHIVE_REPOSITORY_AMD64
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_914_ARCHIVE_REPOSITORY_DEV_AMD64
- MQ_ARCHIVE_REPOSITORY=$MQ_915_ARCHIVE_REPOSITORY_AMD64
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_915_ARCHIVE_REPOSITORY_DEV_AMD64
script: bash -e travis-build-scripts/run.sh
- if: branch = private-master OR tag =~ ^pre-release*
name: "Multi-Arch PPC64LE build"
@@ -57,8 +57,8 @@ jobs:
env:
- BUILD_ALL=true
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
- MQ_ARCHIVE_REPOSITORY=$MQ_914_ARCHIVE_REPOSITORY_PPC64LE
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_914_ARCHIVE_REPOSITORY_DEV_PPC64LE
- MQ_ARCHIVE_REPOSITORY=$MQ_915_ARCHIVE_REPOSITORY_PPC64LE
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_915_ARCHIVE_REPOSITORY_DEV_PPC64LE
script: bash -e travis-build-scripts/run.sh
- if: branch = private-master OR tag =~ ^pre-release*
name: "Multi-Arch S390X build"
@@ -66,8 +66,8 @@ jobs:
env:
- BUILD_ALL=true
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
- MQ_ARCHIVE_REPOSITORY=$MQ_914_ARCHIVE_REPOSITORY_S390X
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_914_ARCHIVE_REPOSITORY_DEV_S390X
- MQ_ARCHIVE_REPOSITORY=$MQ_915_ARCHIVE_REPOSITORY_S390X
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_915_ARCHIVE_REPOSITORY_DEV_S390X
script: bash -e travis-build-scripts/run.sh
- stage: deploy
name: "Pre-release deploy"

View File

@@ -1,5 +1,10 @@
# 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)
* 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_SOURCE="Not specified"
ARG IMAGE_TAG="Not specified"
ARG MQM_UID=888
USER 0
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 \
&& 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/
COPY cmd/ ./cmd
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_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 MQM_UID=888
ARG BASE_IMAGE
ARG BASE_TAG
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-server-prereqs.sh /usr/local/bin/
# 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 \
&& install-mq-server-prereqs.sh $MQM_UID \
&& install-mq.sh $MQM_UID
&& install-mq-server-prereqs.sh \
&& install-mq.sh \
&& /opt/mqm/bin/security/amqpamcf \
&& chown -R 1001:root /opt/mqm/*
# Create a directory for runtime data from 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/chkmq* /usr/local/bin/
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 etc/mqm/*.tpl /etc/mqm/
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* \
&& chown -R mqm:mqm /etc/mqm/* \
&& install --directory --mode 0775 --owner mqm --group root /run/runmqserver \
&& chown -R 1001:root /etc/mqm/* \
&& install --directory --mode 0775 --owner 1001 --group root /run/runmqserver \
&& touch /run/termination-log \
&& chown mqm:root /run/termination-log \
&& chown 1001:root /run/termination-log \
&& chmod 0660 /run/termination-log
# Always use port 1414 for MQ & 9157 for the metrics
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 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"]
###############################################################################
# Add default developer config
###############################################################################
FROM mq-server AS mq-dev-server
ARG MQM_UID=888
ARG BASE_IMAGE
ARG BASE_TAG
# Enable MQ developer default configuration
ENV MQ_DEV=true
# Default administrator password
ENV MQ_ADMIN_PASSWORD=passw0rd
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 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 \
&& sleep 1 \
&& 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
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 template files
COPY incubating/mqadvanced-server-dev/*.tpl /etc/mqm/
# Copy web XML files for default developer configuration
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* \
&& 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
USER $MQM_UID
USER 1001
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");
# 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 ?=
# 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 ?=
# 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_TAG is the tag of the built MQ Advanced image & MQ Advanced for Developers image
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 ?=$(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)
@@ -88,7 +84,7 @@ IMAGE_REVISION=$(shell git rev-parse HEAD)
IMAGE_SOURCE=$(shell git config --get remote.origin.url)
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))))
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.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.5.0=mqadv_dev915_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).tar.gz
ifneq "$(MQ_DELIVERY_REGISTRY_NAMESPACE)" "$(EMPTY)"
MQ_DELIVERY_REGISTRY_FULL_PATH=$(MQ_DELIVERY_REGISTRY_HOSTNAME)/$(MQ_DELIVERY_REGISTRY_NAMESPACE)
@@ -236,11 +233,9 @@ define build-mq
--tag $1:$2 \
--file $3 \
$(EXTRA_ARGS) \
--build-arg MQ_PACKAGES="$(MQ_PACKAGES)" \
--build-arg IMAGE_REVISION="$(IMAGE_REVISION)" \
--build-arg IMAGE_SOURCE="$(IMAGE_SOURCE)" \
--build-arg IMAGE_TAG="$1:$2" \
--build-arg MQM_UID=$(MQM_UID) \
--label version=$(MQ_VERSION) \
--label name=$1 \
--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_ADVANCEDSERVER=$(MQ_IMAGE_ADVANCEDSERVER)
@echo COMMAND=$(COMMAND)
@echo MQM_UID=$(MQM_UID)
@echo REGISTRY_USER=$(REGISTRY_USER)
.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");
you may not use this file except in compliance with the License.
@@ -17,14 +17,10 @@ package main
import (
"os"
"runtime"
"syscall"
"github.com/ibm-messaging/mq-container/internal/command"
)
func createVolume(dataPath string) error {
fi, err := os.Stat(dataPath)
_, err := os.Stat(dataPath)
if err != nil {
if os.IsNotExist(err) {
// #nosec G301
@@ -36,25 +32,5 @@ func createVolume(dataPath string) error {
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
}

View File

@@ -112,12 +112,29 @@ func doMain() error {
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()
if err != nil {
logTermination(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 *initFlag {
return nil
@@ -149,6 +166,7 @@ func doMain() error {
logTermination(err)
return err
}
var wg sync.WaitGroup
defer func() {
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
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 {
log.Printf("Error creating directory structure: %v\n", string(out))
return err
if rc == 10 {
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")
return nil

View File

@@ -19,13 +19,9 @@ import (
"fmt"
"os"
"os/exec"
"os/user"
"path/filepath"
"strconv"
"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/mqtemplate"
"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_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()
rc := cmd.ProcessState.ExitCode()
if err != nil {
@@ -162,10 +140,6 @@ func configureWebServer(keyLabel string, p12Truststore tls.KeyStoreData) (string
}
return "", err
}
uid, gid, err := command.LookupMQM()
if err != nil {
return "", err
}
const prefix string = "/etc/mqm/web"
err = filepath.Walk(prefix, func(from string, info os.FileInfo, err error) error {
if err != nil {
@@ -202,10 +176,6 @@ func configureWebServer(keyLabel string, p12Truststore tls.KeyStoreData) (string
return err
}
}
err = os.Chown(to, uid, gid)
if err != nil {
return err
}
return nil
})

View File

@@ -4,7 +4,7 @@
### 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
@@ -16,7 +16,7 @@ docker run \
--env LICENSE=accept \
--env MQ_QMGR_NAME=QM1 \
--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:
@@ -31,5 +31,5 @@ docker run \
--env LICENSE=accept \
--env MQ_QMGR_NAME=QM1 \
--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:
```
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
```
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
@@ -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.
### 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
RUN useradd alice -G mqm && \
echo alice:passw0rd | chpasswd
USER mqm
USER 1001
COPY 20-config.mqsc /etc/mqm/
```

View File

@@ -1,6 +1,6 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2015, 2019
# © Copyright IBM Corporation 2015, 2020
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,74 +18,44 @@
# Fail on any non-zero return code
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/apt-get && UBUNTU=true || UBUNTU=false
# Download and extract the MQ installation files
DIR_EXTRACT=/tmp/mq
mkdir -p ${DIR_EXTRACT}
cd ${DIR_EXTRACT}
# Download and extract the MQ unzippable server
DIR_TMP=/tmp/mq
mkdir -p ${DIR_TMP}
cd ${DIR_TMP}
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
groupadd --system --gid ${mqm_uid} mqm
useradd --system --uid ${mqm_uid} --gid mqm --groups 0 mqm
# 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")
INSTALLATION_DIR=/opt/mqm
tar -C ${INSTALLATION_DIR} -xzf ./*.tar.gz
ls -la ${INSTALLATION_DIR}
rm -rf ${DIR_TMP}
# Accept the MQ license
${MQLICENSE} -text_only -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
${INSTALLATION_DIR}/bin/mqlicense -accept
# 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
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
# 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}
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
# Optional: Update the command prompt with the MQ version
$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
install --directory --mode 0775 --owner mqm --group root /mnt
install --directory --mode 0775 --owner mqm --group root /mnt/mqm
install --directory --mode 0775 --owner mqm --group root /mnt/mqm/data
install --directory --mode 0775 --owner mqm --group root /mnt/mqm-log
install --directory --mode 0775 --owner mqm --group root /mnt/mqm-log/log
install --directory --mode 0775 --owner mqm --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
install --directory --mode 0775 --owner 1001 --group root /mnt/mqm
install --directory --mode 0775 --owner 1001 --group root /mnt/mqm/data
install --directory --mode 0775 --owner 1001 --group root /mnt/mqm-log
install --directory --mode 0775 --owner 1001 --group root /mnt/mqm-log/log
install --directory --mode 0775 --owner 1001 --group root /mnt/mqm-data
install --directory --mode 0775 --owner 1001 --group root /mnt/mqm-data/qmgrs
# 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
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
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
mkdir -p /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");
you may not use this file except in compliance with the License.
@@ -20,9 +20,6 @@ package command
import (
"fmt"
"os/exec"
"os/user"
"strconv"
"syscall"
)
// 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
}
// 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");
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)
}
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
return err
}
err = os.Chown(ks.Filename, mqmUID, mqmGID)
if err != nil {
return err
}
return nil
}
@@ -130,14 +122,6 @@ func (ks *KeyStore) CreateStash() error {
}
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
}

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");
you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import (
"path"
"text/template"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/pkg/logger"
)
@@ -45,16 +44,6 @@ func ProcessTemplateFile(templateFile, destFile string, data interface{}, log *l
log.Error(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 {
return err
}
@@ -67,15 +56,5 @@ func ProcessTemplateFile(templateFile, destFile string, data interface{}, log *l
log.Error(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
}

View File

@@ -20,7 +20,6 @@ import (
"os"
"path/filepath"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/keystore"
)
@@ -51,14 +50,6 @@ func ConfigureWebTLS(keyLabel string) error {
if err != nil {
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
}

View File

@@ -143,7 +143,7 @@ func TestDevWebDisabled(t *testing.T) {
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
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") {
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)
waitForReady(t, cli, id)
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 {
t.Errorf("Expected DEV queues to be missing")
}

View File

@@ -91,7 +91,7 @@ func TestEndMQMOpts(t *testing.T) {
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
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)
if !strings.Contains(out, "endmqm -w -r -tp 27") {
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)
defer cleanContainer(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) {
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
USER root
RUN echo '#!/bin/bash\nexit 999' > /opt/mqm/bin/crtmqm
RUN chown mqm:mqm /opt/mqm/bin/crtmqm
RUN chmod 6550 /opt/mqm/bin/crtmqm
USER mqm`, imageName())},
USER 1001`, imageName())},
}
tag := createImage(t, cli, files)
defer deleteImage(t, cli, tag)
@@ -449,9 +447,7 @@ func TestStartQueueManagerFail(t *testing.T) {
FROM %v
USER root
RUN echo '#!/bin/bash\ndltmqm $@ && strmqm $@' > /opt/mqm/bin/strmqm
RUN chown mqm:mqm /opt/mqm/bin/strmqm
RUN chmod 6550 /opt/mqm/bin/strmqm
USER mqm`, imageName())},
USER 1001`, imageName())},
}
tag := createImage(t, cli, files)
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)
}
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 {
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)
_, ps := execContainer(t, cli, ctr.ID, "mqm", []string{"ps", "-ef"})
_, ps := execContainer(t, cli, ctr.ID, "", []string{"ps", "-ef"})
t.Logf(ps)
}
}
@@ -541,14 +537,14 @@ func TestZombies(t *testing.T) {
waitForReady(t, cli, id)
// 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.
_, 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" {
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)
}
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 != "" {
count := strings.Count(out, "\n") + 1
t.Errorf("Expected zombies=0, got %v", count)
@@ -575,7 +571,7 @@ func TestMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())},
USER 1001`, imageName())},
{"test.mqsc", "DEFINE QLOCAL(test)"},
}
tag := createImage(t, cli, files)
@@ -588,7 +584,7 @@ func TestMQSC(t *testing.T) {
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(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 {
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))
@@ -618,7 +614,7 @@ func TestLargeMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())},
USER 1001`, imageName())},
{"test.mqsc", buf.String()},
}
tag := createImage(t, cli, files)
@@ -632,7 +628,7 @@ func TestLargeMQSC(t *testing.T) {
defer cleanContainer(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 {
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))
@@ -690,7 +686,7 @@ func TestRedactValidMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())},
USER 1001`, imageName())},
{"test.mqsc", buf.String()},
}
tag := createImage(t, cli, files)
@@ -762,7 +758,7 @@ func TestRedactInvalidMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())},
USER 1001`, imageName())},
{"test.mqsc", buf.String()},
}
tag := createImage(t, cli, files)
@@ -808,7 +804,7 @@ func TestInvalidMQSC(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc
ADD mqscTest.mqsc /etc/mqm/
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"},
}
tag := createImage(t, cli, files)
@@ -841,7 +837,7 @@ func TestSimpleMQIniMerge(t *testing.T) {
USER root
ADD test1.ini /etc/mqm/
RUN chmod 0660 /etc/mqm/test1.ini
USER mqm`, imageName())},
USER 1001`, imageName())},
{"test1.ini",
"Log:\n LogSecondaryFiles=28"},
}
@@ -857,7 +853,7 @@ func TestSimpleMQIniMerge(t *testing.T) {
waitForReady(t, cli, id)
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")
if !merged {
@@ -883,7 +879,7 @@ func TestMultipleIniMerge(t *testing.T) {
RUN chmod 0660 /etc/mqm/test1.ini
RUN chmod 0660 /etc/mqm/test2.ini
RUN chmod 0660 /etc/mqm/test3.ini
USER mqm`, imageName())},
USER 1001`, imageName())},
{"test1.ini",
"Log:\n LogSecondaryFiles=28"},
{"test2.ini",
@@ -903,7 +899,7 @@ func TestMultipleIniMerge(t *testing.T) {
waitForReady(t, cli, id)
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
numberOfDuplicates := strings.Count(test, "LogSecondaryFiles=28")
@@ -929,7 +925,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
USER root
ADD test1.ini /etc/mqm/
RUN chmod 0660 /etc/mqm/test1.ini
USER mqm`, imageName())},
USER 1001`, imageName())},
{"test1.ini",
"ApplicationTrace:\n ApplName=amqsact*\n Trace=OFF"},
}
@@ -959,7 +955,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
waitForReady(t, cli, ctr1.ID)
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")
if addedStanza != true {
@@ -976,7 +972,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
USER root
ADD test1.ini /etc/mqm/
RUN chmod 0660 /etc/mqm/test1.ini
USER mqm`, imageName())},
USER 1001`, imageName())},
{"test1.ini",
"Log:\n LogFilePages=5000"},
}
@@ -997,7 +993,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
startContainer(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")
//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")
@@ -1032,7 +1028,7 @@ func TestReadiness(t *testing.T) {
RUN rm -f /etc/mqm/*.mqsc
ADD test.mqsc /etc/mqm/
RUN chmod 0660 /etc/mqm/test.mqsc
USER mqm`, imageName())},
USER 1001`, imageName())},
{"test.mqsc", buf.String()},
}
tag := createImage(t, cli, files)
@@ -1045,11 +1041,11 @@ func TestReadiness(t *testing.T) {
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
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)
for {
readyRC, _ := execContainer(t, cli, id, "mqm", []string{"chkmqready"})
queueCheckRC, queueCheckOut := execContainer(t, cli, id, "mqm", []string{"bash", "-c", queueCheckCommand})
readyRC, _ := execContainer(t, cli, id, "", []string{"chkmqready"})
queueCheckRC, queueCheckOut := execContainer(t, cli, id, "", []string{"bash", "-c", queueCheckCommand})
t.Logf("readyRC=%v,queueCheckRC=%v\n", readyRC, queueCheckRC)
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)
} else {
// 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)
return
}
@@ -1107,7 +1103,7 @@ func TestErrorLogRotation(t *testing.T) {
for {
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)
if amqerr02size > 0 {
@@ -1115,7 +1111,7 @@ func TestErrorLogRotation(t *testing.T) {
break
}
}
_, out := execContainer(t, cli, id, "root", []string{"ls", "-l", dir})
_, out := execContainer(t, cli, id, "", []string{"ls", "-l", dir})
t.Log(out)
stopContainer(t, cli, id)
b := copyFromContainer(t, cli, id, filepath.Join(dir, "AMQERR01.json"))
@@ -1259,7 +1255,7 @@ func TestCorrectLicense(t *testing.T) {
defer cleanContainer(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 {
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)
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 {
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");
you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import (
"fmt"
"io"
"io/ioutil"
"math/rand"
"os"
"os/exec"
"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.
// If no image is specified in the container config, then the image name is retrieved from the TEST_IMAGE
// environment variable.
@@ -266,9 +274,9 @@ func runContainerWithPorts(t *testing.T, cli *client.Client, containerConfig *co
if containerConfig.Image == "" {
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 == "" {
containerConfig.User = "mqm"
containerConfig.User = generateRandomUID()
}
// if coverage
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{
"ALL",
},
Privileged: false,
}
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
if baseImage(t, cli) != "ubuntu" {
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) {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
for {
select {
case <-time.After(1 * time.Second):
rc, _ := execContainer(t, cli, ID, "mqm", []string{"chkmqready"})
rc, _ := execContainer(t, cli, ID, "", []string{"chkmqready"})
if rc == 0 {
t.Log("MQ is ready")
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");
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 {
_, 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\(.*\)`)
status := regex.FindString(dspmqOut)
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)
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 {
t.Fatalf("Failed to stop the queue manager. rc=%d, err=%s", rc, out)
}
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 {
t.Fatalf("Failed to start the queue manager. rc=%d, err=%s", rc, out)
}