Compare commits

...

36 Commits

Author SHA1 Message Date
Luke Powlett
8a40b6a5dd Curl manifest tool 2019-12-06 14:23:17 +00:00
Luke Powlett
dd62bc39f4 Release changes for dockerhub/store 2019-12-06 14:02:56 +00:00
Luke J Powlett
61c909f551 Override default makefile image name and tag for release (#46)
* Override default makefile image name and tag for release
2019-12-05 18:31:02 +00:00
Luke J Powlett
ffda647cdf Fixed docker images labels (#45) 2019-12-05 16:07:11 +00:00
Luke Powlett
5897d6a644 Update the license information in the readme 2019-12-05 11:44:33 +00:00
Luke J Powlett
34f7a57c5d Pipeline changes for travis release (#43)
* Added changes for travis release process

* Renamed build scripts directory

* Don't run basic build if tag is set

* Pull production images from staging on production-release
2019-12-04 19:45:57 +00:00
Luke Powlett
5b5951ec3c Changed sed for password minlen replacement due to change in UBI8 2019-12-04 10:18:23 +00:00
Amrit K Kandola
b20761cea0 Removed error code logic and replaced with library function (#39)
* Removed error code logic and replaced with library function

* Added the gosecignore comment to prevent gosec failing
2019-12-03 16:13:36 +00:00
Amrit K Kandola
5449622d2a Remove developer listener and remove actions to stop and alter system listener (#41) 2019-12-03 16:13:00 +00:00
Luke J Powlett
dd31fb37c3 Changes for MQ 9.1.4.0 (#37)
* Changes for MQ 9.1.4.0

* Only run p and z builds for production build
2019-12-03 15:58:02 +00:00
Stephen Marshall
2e453f2257 Fix web certificate for dev image 2019-12-03 15:24:05 +00:00
Luke J Powlett
1f4528d597 Pipeline changes for Entitled Registry (#38)
* Added makefile targets/variables to pull mq archive from remote

* Updated makefile and travis build for multi arch dev/prod builds

* Updated build deps to use arch specific dep

* Removed glide for dependency management

* Removed `MQ_SDK_ARCHIVE` download target

* Make ARCH overridable in makefile

* Only run golden path test on Power and Z builds

* Only run gosec on amd64 build

* Increased go to 1.12 in travis
2019-12-03 13:16:30 +00:00
Amrit Kandola
c83aeb17c0 Updated toolset 2019-11-28 11:30:27 +00:00
Amrit K Kandola
5a18280057 Updated UBI to UBI8 (#35)
* Updated UBI to UBI8

* Updated the README to include the redhat login

* Updated to use non-deprecated registry

* Added sed filter into docker file to remove ubi7

* Added automatic login into the makefile based on env variables, also removed nodocs from mq-explorer

* Minor typo fix
2019-11-27 09:32:38 +00:00
Amrit K Kandola
8e380b94f4 Closes #242 - update jmstests to use latest version (#33)
* Closes #242 - update jmstests to use latest version
* added class files to git ignore
2019-10-23 15:59:04 +01:00
Stephen Marshall
ebe8b7a6f0 Add required security settings when creating self-signed certificates 2019-10-21 13:13:00 +01:00
Stephen Marshall
ed4466d934 Remove iFrame support, now using header-as-a-service 2019-10-17 17:31:09 +01:00
Luke Powlett
37601187b2 Removed release from makefile, will be set on internal build only 2019-10-11 10:48:20 +01:00
Luke Powlett
366d406f57 Updated manifest for r3 fix release 2019-10-03 15:06:41 +01:00
Arthur Barr
68ad98fc49 Enable INI merging 2019-09-30 14:37:40 +01:00
Luke Powlett
65edac267e Removed ARGs for go-toolset 2019-09-27 13:20:04 +01:00
Arthur Barr
ad0046ab01 Fix gosec for writeFileIfChanged 2019-09-26 16:47:48 +01:00
Arthur Barr
c3fbc5816e Only write INI file if changed 2019-09-26 16:47:48 +01:00
Luke Powlett
11890d887b Added args for go toolset image and tag, fixed issue with logger 2019-09-23 17:08:40 +01:00
Arthur Barr
ac50d46c78 Don't call INI merging code 2019-09-19 11:03:40 +01:00
Arthur Barr
de298a4aad Don't run dspmqinf before crtmqdir 2019-09-19 09:29:04 +01:00
KIRAN DARBHA
4de32ab8d2 fix for double merge issue
update unit-test data

fix gosec

fix gosec

fix gosec
2019-09-18 16:36:47 +01:00
Arthur Barr
8505579b37 Move some packages to pkg directory 2019-09-17 11:08:42 +01:00
Luke Powlett
7c59d647f5 Added gosec scan to end of travis build, upgraded travis go to v1.11 2019-09-12 16:17:50 +01:00
Luke Powlett
8d8e4e4403 error handling and gosec fixes 2019-09-10 15:22:46 +01:00
Stephen Marshall
52b4eeea32 Fix MIQM 2019-08-30 11:44:45 +01:00
Rob Parker
28291306cb set CipherSpec to ANY_TLS12 and refresh security (#362) 2019-08-29 11:58:51 +01:00
Luke Powlett
4da7c60aee Update to UBI 7.7-98 2019-08-29 11:58:51 +01:00
Arthur Barr
1ae24263ad Temporarily remove Docker 1.12 test in Travis 2019-08-29 11:58:51 +01:00
Arthur Barr
d6248424a1 Use podman build if available 2019-08-29 11:58:51 +01:00
Luke Powlett
455c67ad3d increment release in makefile 2019-08-29 11:58:51 +01:00
85 changed files with 1343 additions and 1562 deletions

View File

@@ -18,7 +18,7 @@ sudo: required
language: go
go:
- "1.10"
- "1.12"
services:
- docker
@@ -29,52 +29,60 @@ cache:
directories:
- downloads
env:
global:
- RELEASE=""
jobs:
include:
- stage: build and test
- stage: build
name: "Basic build"
if: branch != private-master AND tag IS blank
os: linux
env:
- BASE_IMAGE=ubuntu:16.04
- DOCKER_DOWNGRADE="echo nothing to be done"
- env:
- BASE_IMAGE=centos:7
- DOCKER_DOWNGRADE="echo nothing to be done"
- if: type IN (pull_request) OR tag IS present
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_914_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:
- BASE_IMAGE=ubuntu:16.04
- DOCKER_DOWNGRADE="docker save -o images.tar mqadvanced-server-dev mq-dev-jms-test &&
sudo apt-get autoremove -y docker-ce &&
curl -fsSL \"https://apt.dockerproject.org/gpg\" | sudo apt-key add - &&
sudo apt-add-repository \"deb https://apt.dockerproject.org/repo ubuntu-$(lsb_release -cs) main\" &&
sudo apt-get update &&
sudo apt-get install docker-engine=1.12.6-0~ubuntu-$(lsb_release -cs) &&
docker load -q -i images.tar &&
export DOCKER_API_VERSION=\"1.24\""
- BUILD_ALL=true
- MQ_ARCHIVE_REPOSITORY=$MQ_914_ARCHIVE_REPOSITORY_AMD64
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_914_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"
os: linux-ppc64le
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
script: bash -e travis-build-scripts/run.sh
- if: branch = private-master OR tag =~ ^pre-release*
name: "Multi-Arch S390X build"
os: linux-s390
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
script: bash -e travis-build-scripts/run.sh
- stage: deploy
name: "Pre-release deploy"
if: tag =~ ^pre-release*
script: bash -e travis-build-scripts/release.sh staging
- name: "Production release deploy"
if: tag =~ ^production-release*
script: bash -e travis-build-scripts/release.sh production
before_install:
- ./install-build-deps-ubuntu.sh
- make install-build-deps
install:
- echo nothing
before_script:
- echo 'Downloading Go dependencies...' && echo -en 'travis_fold:start:deps\\r'
- make deps
- echo -en 'travis_fold:end:deps\\r'
- echo 'Building Developer image...' && echo -en 'travis_fold:start:build-devserver\\r'
# Use the containerized build explicitly
- make build-devserver-ctr
- echo -en 'travis_fold:end:build-devserver\\r'
- echo 'Building Developer JMS test image...' && echo -en 'travis_fold:start:build-devjmstest\\r'
- make build-devjmstest
- echo -en 'travis_fold:end:build-devjmstest\\r'
script:
- echo 'Downgrading Docker (if necessary)...' && echo -en 'travis_fold:start:docker-downgrade\\r'
- eval "$DOCKER_DOWNGRADE"
- echo -en 'travis_fold:end:docker-downgrade\\r'
- echo 'Testing Developer image...' && echo -en 'travis_fold:start:test-devserver\\r'
- make test-devserver
- echo -en 'travis_fold:end:test-devserver\\r'
before_script: echo nothing
after_success:
- make lint

View File

@@ -1,5 +1,11 @@
# Change log
## 9.1.4.0 (2019-12-06)
* Updated to MQ version 9.1.4.0
* Updated to use UBI8 as base image
* Added required security settings to self signed certificates to align with macOS Catalina requirements
## 9.1.3.0 (2019-07-19)
* Updated to MQ version 9.1.3.0

View File

@@ -12,12 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ARG BASE_IMAGE=registry.access.redhat.com/ubi7/ubi-minimal
ARG BASE_TAG=7.6-237
ARG BASE_IMAGE=registry.redhat.io/ubi8/ubi-minimal
ARG BASE_TAG=8.1-279
###############################################################################
# Build stage to build Go code
###############################################################################
FROM registry.access.redhat.com/devtools/go-toolset-7-rhel7 as builder
FROM registry.redhat.io/rhel8/go-toolset:1.12.8-11 as builder
# FROM docker.io/centos/go-toolset-7-centos7 as builder
# The URL to download the MQ installer from in tar.gz format
# This assumes an archive containing the MQ RPM install packages
@@ -34,8 +34,9 @@ RUN chmod a+x /usr/local/bin/install-mq.sh \
WORKDIR /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/
COPY cmd/ ./cmd
COPY internal/ ./internal
COPY pkg/ ./pkg
COPY vendor/ ./vendor
ENV PATH="${PATH}:/opt/rh/go-toolset-7/root/usr/bin" \
ENV PATH="${PATH}:/opt/rh/go-toolset-1.11/root/usr/bin" \
CGO_CFLAGS="-I/opt/mqm/inc/" \
CGO_LDFLAGS_ALLOW="-Wl,-rpath.*"
RUN go build -ldflags "-X \"main.ImageCreated=$(date --iso-8601=seconds)\" -X \"main.ImageRevision=$IMAGE_REVISION\" -X \"main.ImageSource=$IMAGE_SOURCE\" -X \"main.ImageTag=$IMAGE_TAG\"" ./cmd/runmqserver/
@@ -46,6 +47,7 @@ RUN go test -v ./cmd/runmqdevserver/...
RUN go test -v ./cmd/runmqserver/
RUN go test -v ./cmd/chkmqready/
RUN go test -v ./cmd/chkmqhealthy/
RUN go test -v ./pkg/...
RUN go test -v ./internal/...
RUN go vet ./cmd/... ./internal/...
@@ -54,7 +56,7 @@ RUN go vet ./cmd/... ./internal/...
###############################################################################
FROM $BASE_IMAGE:$BASE_TAG AS mq-server
# The MQ packages to install - see install-mq.sh for default value
ARG MQ_URL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/mqadv_dev912_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="ibmmq-server ibmmq-java ibmmq-jre ibmmq-gskit ibmmq-msg-.* ibmmq-samples ibmmq-web ibmmq-ams"
ARG MQM_UID=888
@@ -147,6 +149,6 @@ COPY incubating/mqadvanced-server-dev/web /etc/mqm/web
RUN chown -R mqm:mqm /etc/mqm/* \
&& chmod +x /usr/local/bin/runmq* \
&& install --directory --mode 0775 --owner mqm --group root /run/runmqdevserver
ENV MQ_ENABLE_EMBEDDED_WEB_SERVER=1
ENV MQ_ENABLE_EMBEDDED_WEB_SERVER=1 MQ_GENERATE_CERTIFICATE_HOSTNAME=localhost
USER $MQM_UID
ENTRYPOINT ["runmqdevserver"]

258
Makefile
View File

@@ -16,10 +16,18 @@
# Conditional variables - you can override the values of these variables from
# the command line
###############################################################################
# MQ_VERSION is the fully qualified MQ version number to build
MQ_VERSION ?= 9.1.3.0
# RELEASE shows what release of the container code has been built
RELEASE ?= 1
RELEASE ?=
# MQ_VERSION is the fully qualified MQ version number to build
MQ_VERSION ?= 9.1.4.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)
MQ_ARCHIVE_REPOSITORY_DEV ?=
# MQ_ARCHIVE_REPOSITORY_USER is the user for the remote repository (if required)
MQ_ARCHIVE_REPOSITORY_USER ?=
# MQ_ARCHIVE_REPOSITORY_CREDENTIAL is the password/API key for the remote repository (if required)
MQ_ARCHIVE_REPOSITORY_CREDENTIAL ?=
# MQ_ARCHIVE is the name of the file, under the downloads directory, from which MQ Advanced can
# be installed. The default value is derived from MQ_VERSION, BASE_IMAGE and architecture
# Does not apply to MQ Advanced for Developers.
@@ -37,12 +45,26 @@ MQ_IMAGE_ADVANCEDSERVER ?=mqadvanced-server
MQ_IMAGE_DEVSERVER ?=mqadvanced-server-dev
# MQ_TAG is the tag of the built MQ Advanced image & MQ Advanced for Developers image
MQ_TAG ?=$(MQ_VERSION)-$(ARCH)
# DOCKER is the Docker command to run. Defaults to "podman" if it's available, otherwise "docker"
DOCKER ?= $(shell type -p podman || echo docker)
# 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)
MQ_DELIVERY_REGISTRY_HOSTNAME ?=
# MQ_DELIVERY_REGISTRY_NAMESPACE is the namespace/path on the delivery registry (if required)
MQ_DELIVERY_REGISTRY_NAMESPACE ?=
# MQ_DELIVERY_REGISTRY_USER is the user for the remote registry (if required)
MQ_DELIVERY_REGISTRY_USER ?=
# MQ_DELIVERY_REGISTRY_CREDENTIAL is the password/API key for the remote registry (if required)
MQ_DELIVERY_REGISTRY_CREDENTIAL ?=
# REGISTRY_USER is the username used to login to the Red Hat registry
REGISTRY_USER ?=
# REGISTRY_PASS is the password used to login to the Red Hat registry
REGISTRY_PASS ?=
# ARCH is the platform architecture (e.g. amd64, ppc64le or s390x)
ARCH ?= $(if $(findstring x86_64,$(shell uname -m)),amd64,$(shell uname -m))
###############################################################################
# Other variables
@@ -50,8 +72,6 @@ MQM_UID ?= 888
GO_PKG_DIRS = ./cmd ./internal ./test
MQ_ARCHIVE_TYPE=LINUX
MQ_ARCHIVE_DEV_PLATFORM=linux
# ARCH is the platform architecture (e.g. amd64, ppc64le or s390x)
ARCH=$(if $(findstring x86_64,$(shell uname -m)),amd64,$(shell uname -m))
# BUILD_SERVER_CONTAINER is the name of the web server container used at build time
BUILD_SERVER_CONTAINER=build-server
# NUM_CPU is the number of CPUs available to Docker. Used to control how many
@@ -68,17 +88,9 @@ 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.3 instead of 9.1.3.0
# 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=$(subst $(SPACE),.,$(wordlist 1,3,$(subst .,$(SPACE),$(MQ_VERSION))))
# Set variable if running on a Red Hat Enterprise Linux host
ifneq ($(wildcard /etc/redhat-release),)
REDHAT_RELEASE = $(shell cat /etc/redhat-release)
ifeq "$(findstring Red Hat,$(REDHAT_RELEASE))" "Red Hat"
RHEL_HOST = "true"
endif
endif
ifneq (,$(findstring Microsoft,$(shell uname -r)))
DOWNLOADS_DIR=$(patsubst /mnt/c%,C:%,$(realpath ./downloads/))
else ifneq (,$(findstring Windows,$(shell echo ${OS})))
@@ -103,18 +115,34 @@ MQ_ARCHIVE_DEV_9.1.0.0=mqadv_dev910_$(MQ_ARCHIVE_DEV_PLATFORM)_$(MQ_DEV_ARCH).ta
MQ_ARCHIVE_DEV_9.1.1.0=mqadv_dev911_$(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.4.0=mqadv_dev914_$(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)
else
MQ_DELIVERY_REGISTRY_FULL_PATH=$(MQ_DELIVERY_REGISTRY_HOSTNAME)
endif
ifneq "$(RELEASE)" "$(EMPTY)"
MQ_IMAGE_ADVANCEDSERVER=ibm-mqadvanced-server
MQ_IMAGE_DEVSERVER=ibm-mqadvanced-server-dev
MQ_TAG=$(MQ_VERSION)-$(RELEASE)-$(ARCH)
EXTRA_LABELS=--label release=$(RELEASE)
endif
MQ_IMAGE_FULL_RELEASE_NAME=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)
MQ_IMAGE_DEV_FULL_RELEASE_NAME=$(MQ_IMAGE_DEVSERVER):$(MQ_TAG)
ifeq "$(MQ_DELIVERY_REGISTRY_HOSTNAME)" "ibmcom"
MQ_IMAGE_DEVSERVER_DOCKERHUB=mq
else ifeq "$(MQ_DELIVERY_REGISTRY_HOSTNAME)" "ibmcorp"
MQ_IMAGE_DEVSERVER_DOCKERHUB=mqadvanced-server-dev
endif
###############################################################################
# Build targets
###############################################################################
.PHONY: vars
vars:
@echo $(MQ_ARCHIVE_ARCH)
@echo $(MQ_ARCHIVE_TYPE)
@echo $(MQ_ARCHIVE)
.PHONY: default
default: build-devserver test
default: build-devserver
# Build all components (except incubating ones)
.PHONY: all
@@ -133,12 +161,18 @@ incubating: build-explorer
downloads/$(MQ_ARCHIVE_DEV):
$(info $(SPACER)$(shell printf $(TITLE)"Downloading IBM MQ Advanced for Developers "$(MQ_VERSION)$(END)))
mkdir -p downloads
cd downloads; curl -LO https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/$(MQ_ARCHIVE_DEV)
ifneq "$(MQ_ARCHIVE_REPOSITORY_DEV)" "$(EMPTY)"
curl -u $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -X GET "$(MQ_ARCHIVE_REPOSITORY_DEV)" -o downloads/$(MQ_ARCHIVE_DEV)
else
curl -L https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/$(MQ_ARCHIVE_DEV) -o downloads/$(MQ_ARCHIVE_DEV)
endif
downloads/$(MQ_SDK_ARCHIVE):
$(info $(SPACER)$(shell printf $(TITLE)"Downloading IBM MQ Advanced for Developers "$(MQ_VERSION)$(END)))
downloads/$(MQ_ARCHIVE):
$(info $(SPACER)$(shell printf $(TITLE)"Downloading IBM MQ Advanced "$(MQ_VERSION)$(END)))
mkdir -p downloads
cd downloads; curl -LO https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/$(MQ_SDK_ARCHIVE)
ifneq "$(MQ_ARCHIVE_REPOSITORY)" "$(EMPTY)"
curl -u $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -X GET "$(MQ_ARCHIVE_REPOSITORY)" -o downloads/$(MQ_ARCHIVE)
endif
.PHONY: downloads
downloads: downloads/$(MQ_ARCHIVE_DEV) downloads/$(MQ_SDK_ARCHIVE)
@@ -196,24 +230,16 @@ test-advancedserver-cover: test/docker/vendor coverage
tail -q -n +2 ./coverage/unit.cov ./coverage/docker.cov >> ./coverage/combined.cov
go tool cover -html=./coverage/combined.cov -o ./coverage/combined.html
# Build an MQ image. The commands used are slightly different between Docker and Podman
define build-mq
# Create a temporary network to use for the build
$(DOCKER) network create build
# Start a web server to host the MQ downloadable (tar.gz) file
$(DOCKER) run \
--rm \
--name $(BUILD_SERVER_CONTAINER) \
--network build \
--network-alias build \
--volume $(DOWNLOADS_DIR):/usr/share/nginx/html:ro \
--detach \
docker.io/nginx:alpine
$(if $(findstring docker,$(COMMAND)), @docker network create build,)
$(if $(findstring docker,$(COMMAND)), @docker run --rm --name $(BUILD_SERVER_CONTAINER) --network build --network-alias build --volume $(DOWNLOADS_DIR):/usr/share/nginx/html:ro --detach docker.io/nginx:alpine,)
$(eval EXTRA_ARGS=$(if $(findstring docker,$(COMMAND)), --network build --build-arg MQ_URL=http://build:80/$4, --volume $(DOWNLOADS_DIR):/var/downloads --build-arg MQ_URL=file:///var/downloads/$4))
# Build the new image
$(DOCKER) build \
$(COMMAND) build \
--tag $1:$2 \
--file $3 \
--network build \
--build-arg MQ_URL=http://build:80/$4 \
$(EXTRA_ARGS) \
--build-arg MQ_PACKAGES="$(MQ_PACKAGES)" \
--build-arg IMAGE_REVISION="$(IMAGE_REVISION)" \
--build-arg IMAGE_SOURCE="$(IMAGE_SOURCE)" \
@@ -222,112 +248,140 @@ define build-mq
--label version=$(MQ_VERSION) \
--label name=$1 \
--label build-date=$(shell date +%Y-%m-%dT%H:%M:%S%z) \
--label release="$(RELEASE)" \
--label architecture="$(ARCH)" \
--label run="docker run -d -e LICENSE=accept $1:$2" \
--label vcs-ref=$(IMAGE_REVISION) \
--label vcs-type=git \
--label vcs-url=$(IMAGE_SOURCE) \
$(EXTRA_LABELS) \
--target $5 \
. ; $(DOCKER) kill $(BUILD_SERVER_CONTAINER) && $(DOCKER) network rm build
endef
define build-mq-ctr
buildah/mq-buildah $1 $2 \
--file /src/Dockerfile-server \
--build-arg MQ_URL="file:///src/downloads/$3" \
--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) \
--label release="$(RELEASE)" \
--label architecture="$(ARCH)" \
--label run="docker run -d -e LICENSE=accept $1:$2" \
--label vcs-ref=$(IMAGE_REVISION) \
--label vcs-type=git \
--label vcs-url=$(IMAGE_SOURCE) \
--target $4
.
$(if $(findstring docker,$(COMMAND)), @docker kill $(BUILD_SERVER_CONTAINER))
$(if $(findstring docker,$(COMMAND)), @docker network rm build)
endef
DOCKER_SERVER_VERSION=$(shell docker version --format "{{ .Server.Version }}")
DOCKER_CLIENT_VERSION=$(shell docker version --format "{{ .Client.Version }}")
.PHONY: docker-version
docker-version:
PODMAN_VERSION=$(shell podman version --format "{{ .Version }}")
.PHONY: command-version
command-version:
# If we're using Docker, then check it's recent enough to support multi-stage builds
ifneq (,$(findstring docker,$(COMMAND)))
@test "$(word 1,$(subst ., ,$(DOCKER_CLIENT_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(DOCKER_CLIENT_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(DOCKER_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker client 17.05 or greater is required" && exit 1)
@test "$(word 1,$(subst ., ,$(DOCKER_SERVER_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(DOCKER_SERVER_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(DOCKER_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker server 17.05 or greater is required" && exit 1)
.PHONY: build-advancedserver
ifdef RHEL_HOST
# Build using Buildah inside a container on RHEL hosts
build-advancedserver: build-advancedserver-ctr
else
build-advancedserver: build-advancedserver-host
endif
ifneq (,$(findstring podman,$(COMMAND)))
@test "$(word 1,$(subst ., ,$(PODMAN_VERSION)))" -ge "1" || (echo "Error: Podman version 1.0 or greater is required" && exit 1)
endif
.PHONY: build-advancedserver-host
build-advancedserver-host: downloads/$(MQ_ARCHIVE) docker-version
build-advancedserver-host: build-advancedserver
.PHONY: build-advancedserver
build-advancedserver: registry-login log-build-env downloads/$(MQ_ARCHIVE) command-version
$(info $(SPACER)$(shell printf $(TITLE)"Build $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)"$(END)))
$(call build-mq,$(MQ_IMAGE_ADVANCEDSERVER),$(MQ_TAG),Dockerfile-server,$(MQ_ARCHIVE),mq-server)
.PHONY: build-advancedserver-ctr
build-advancedserver-ctr: downloads/$(MQ_ARCHIVE)
$(info $(shell printf $(TITLE)"Build $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) in a container"$(END)))
$(call build-mq-ctr,$(MQ_IMAGE_ADVANCEDSERVER),$(MQ_TAG),$(MQ_ARCHIVE),mq-server)
.PHONY: build-devserver-host
build-devserver-host: build-devserver
.PHONY: build-devserver
ifdef RHEL_HOST
# Build using Buildah inside a container on RHEL hosts
build-devserver: build-devserver-ctr
else
build-devserver: build-devserver-host
endif
.PHONY: build-devserver-host
build-devserver-host: downloads/$(MQ_ARCHIVE_DEV) docker-version
build-devserver: registry-login log-build-env downloads/$(MQ_ARCHIVE_DEV) command-version
$(info $(shell printf $(TITLE)"Build $(MQ_IMAGE_DEVSERVER):$(MQ_TAG)"$(END)))
$(call build-mq,$(MQ_IMAGE_DEVSERVER),$(MQ_TAG),Dockerfile-server,$(MQ_ARCHIVE_DEV),mq-dev-server)
.PHONY: build-devserver-ctr
build-devserver-ctr: downloads/$(MQ_ARCHIVE_DEV)
$(info $(shell printf $(TITLE)"Build $(MQ_IMAGE_DEVSERVER):$(MQ_TAG) in a container"$(END)))
$(call build-mq-ctr,$(MQ_IMAGE_DEVSERVER),$(MQ_TAG),$(MQ_ARCHIVE_DEV),mq-dev-server)
.PHONY: build-advancedserver-cover
build-advancedserver-cover: docker-version
$(DOCKER) build --build-arg BASE_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) -t $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)-cover -f Dockerfile-server.cover .
build-advancedserver-cover: registry-login command-version
$(COMMAND) build --build-arg BASE_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) -t $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)-cover -f Dockerfile-server.cover .
.PHONY: build-explorer
build-explorer: downloads/$(MQ_ARCHIVE_DEV)
build-explorer: registry-login downloads/$(MQ_ARCHIVE_DEV)
$(call build-mq,mq-explorer,latest-$(ARCH),incubating/mq-explorer/Dockerfile,$(MQ_ARCHIVE_DEV),mq-explorer)
.PHONY: build-sdk
build-sdk: downloads/$(MQ_ARCHIVE_DEV)
build-sdk: registry-login downloads/$(MQ_ARCHIVE_DEV)
$(info $(shell printf $(TITLE)"Build $(MQ_IMAGE_SDK)"$(END)))
$(call build-mq,mq-sdk,$(MQ_TAG),incubating/mq-sdk/Dockerfile,$(MQ_SDK_ARCHIVE),mq-sdk)
.PHONY: debug-vars
debug-vars:
.PHONY: registry-login
registry-login:
ifneq ($(REGISTRY_USER),)
$(COMMAND) login -u $(REGISTRY_USER) -p $(REGISTRY_PASS) registry.redhat.io
endif
.PHONY: log-build-env
log-build-vars:
$(info $(SPACER)$(shell printf $(TITLE)"Build environment"$(END)))
@echo ARCH=$(ARCH)
@echo MQ_VERSION=$(MQ_VERSION)
@echo MQ_VERSION_VRM=$(MQ_VERSION_VRM)
@echo MQ_ARCHIVE=$(MQ_ARCHIVE)
@echo MQ_ARCHIVE_DEV=$(MQ_ARCHIVE_DEV)
@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
log-build-env: log-build-vars
$(info $(SPACER)$(shell printf $(TITLE)"Build environment - $(COMMAND) info"$(END)))
@echo Command version: $(shell $(COMMAND) --version)
$(COMMAND) info
include formatting.mk
.PHONY: pull-mq-archive
pull-mq-archive:
curl -u $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -X GET "$(MQ_ARCHIVE_REPOSITORY)" -o downloads/$(MQ_ARCHIVE)
.PHONY: pull-mq-archive-dev
pull-mq-archive-dev:
curl -u $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -X GET "$(MQ_ARCHIVE_REPOSITORY_DEV)" -o downloads/$(MQ_ARCHIVE_DEV)
.PHONY: push-advancedserver
push-advancedserver:
$(info $(SPACER)$(shell printf $(TITLE)"Push production image to $(MQ_DELIVERY_REGISTRY_FULL_PATH)"$(END)))
$(COMMAND) login $(MQ_DELIVERY_REGISTRY_HOSTNAME) -u $(MQ_DELIVERY_REGISTRY_USER) -p $(MQ_DELIVERY_REGISTRY_CREDENTIAL)
$(COMMAND) tag $(MQ_IMAGE_ADVANCEDSERVER)\:$(MQ_TAG) $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_FULL_RELEASE_NAME)
$(COMMAND) push $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_FULL_RELEASE_NAME)
.PHONY: push-devserver
push-devserver:
$(info $(SPACER)$(shell printf $(TITLE)"Push developer image to $(MQ_DELIVERY_REGISTRY_FULL_PATH)"$(END)))
$(COMMAND) login $(MQ_DELIVERY_REGISTRY_HOSTNAME) -u $(MQ_DELIVERY_REGISTRY_USER) -p $(MQ_DELIVERY_REGISTRY_CREDENTIAL)
$(COMMAND) tag $(MQ_IMAGE_DEVSERVER)\:$(MQ_TAG) $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_DEV_FULL_RELEASE_NAME)
$(COMMAND) push $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_DEV_FULL_RELEASE_NAME)
.PHONY: push-devserver-dockerhub
push-devserver-dockerhub:
$(info $(SPACER)$(shell printf $(TITLE)"Push developer image to $(MQ_DELIVERY_REGISTRY_FULL_PATH)"$(END)))
$(COMMAND) login -u $(MQ_DELIVERY_REGISTRY_USER) -p $(MQ_DELIVERY_REGISTRY_CREDENTIAL)
$(COMMAND) tag $(MQ_IMAGE_DEVSERVER)\:$(MQ_TAG) $(MQ_DELIVERY_REGISTRY_HOSTNAME)/$(MQ_IMAGE_DEVSERVER_DOCKERHUB):$(MQ_TAG)
$(COMMAND) push $(MQ_DELIVERY_REGISTRY_HOSTNAME)/$(MQ_IMAGE_DEVSERVER_DOCKERHUB):$(MQ_TAG)
.PHONY: pull-advancedserver
pull-advancedserver:
$(info $(SPACER)$(shell printf $(TITLE)"Pull production image from $(MQ_DELIVERY_REGISTRY_FULL_PATH)"$(END)))
$(COMMAND) login $(MQ_DELIVERY_REGISTRY_HOSTNAME) -u $(MQ_DELIVERY_REGISTRY_USER) -p $(MQ_DELIVERY_REGISTRY_CREDENTIAL)
$(COMMAND) pull $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_FULL_RELEASE_NAME)
$(COMMAND) tag $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_FULL_RELEASE_NAME) $(MQ_IMAGE_ADVANCEDSERVER)\:$(MQ_TAG)
.PHONY: pull-devserver
pull-devserver:
$(info $(SPACER)$(shell printf $(TITLE)"Pull developer image from $(MQ_DELIVERY_REGISTRY_FULL_PATH)"$(END)))
$(COMMAND) login $(MQ_DELIVERY_REGISTRY_HOSTNAME) -u $(MQ_DELIVERY_REGISTRY_USER) -p $(MQ_DELIVERY_REGISTRY_CREDENTIAL)
$(COMMAND) pull $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_DEV_FULL_RELEASE_NAME)
$(COMMAND) tag $(MQ_DELIVERY_REGISTRY_FULL_PATH)/$(MQ_IMAGE_DEV_FULL_RELEASE_NAME) $(MQ_IMAGE_DEVSERVER)\:$(MQ_TAG)
.PHONY: clean
clean:
rm -rf ./coverage
rm -rf ./build
rm -rf ./deps
.PHONY: deps
deps:
glide install --strip-vendor
.PHONY: install-build-deps
install-build-deps:
ARCH=$(ARCH) ./install-build-deps.sh
.PHONY: build-cov
build-cov:

View File

@@ -45,8 +45,7 @@ The Dockerfiles and associated code and scripts are licensed under the [Apache L
Licenses for the products installed within the images are as follows:
- [IBM MQ Advanced for Developers](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=Z125-3301-14&li_formnum=L-APIG-BBZHCQ) (International License Agreement for Non-Warranted Programs). This license may be viewed from an image using the `LICENSE=view` environment variable as described above or by following the link above.
- [IBM MQ Advanced](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=Z125-3301-14&li_formnum=L-APIG-BBSHJL) (International Program License Agreement). This license may be viewed from an image using the `LICENSE=view` environment variable as described above or by following the link above.
- License information for Ubuntu packages may be found in `/usr/share/doc/${package}/copyright`
- [IBM MQ Advanced](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=Z125-3301-14&li_formnum=L-APIG-BGMHFW) (International Program License Agreement). This license may be viewed from an image using the `LICENSE=view` environment variable as described above or by following the link above.
Note: The IBM MQ Advanced for Developers license does not permit further distribution and the terms restrict usage to a developer machine.

View File

@@ -1,41 +0,0 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2019
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Build a container image from a Dockerfile using Buildah
# If the Docker socket is available, the image will be pushed to Docker once built.
readonly IMAGE=$1:$2
shift
shift
readonly SRC="/src"
readonly OCI_DIR="/var/oci"
echo "****************************************"
echo " Inside the Buildah container"
echo "****************************************"
set -ex
# Build using the supplied options. Always pass the source directory in, and
# use it as the build context
buildah build-using-dockerfile --tag ${IMAGE} --volume /src:/src "$@" /src
if [ -e ${OCI_DIR} ]; then
buildah push ${IMAGE} oci-archive:${OCI_DIR}/${IMAGE}
fi
if [ -e /var/run/docker.sock ]; then
buildah push ${IMAGE} docker-daemon:${IMAGE}
fi

View File

@@ -1,51 +0,0 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2019
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Build and run a container image with Buildah installed
if [ $# -eq 0 ]; then
echo "Usage: $0 imageName imageTag buildah-options"
exit 1
fi
readonly SCRIPT_DIR="$( cd "$(dirname "$0")" ; pwd -P )"
readonly DIR=${SCRIPT_DIR}/..
readonly BUILDAH_IMAGE=mq-buildah
RUN_OPTS="--volume ${DIR}:/src --cap-add SYS_ADMIN --rm --interactive --tty"
CMD="docker"
# If Docker is installed, then map the Docker socket into the container, to
# allow buildah to push the resulting image into Docker's image store
# WARNING: This means that the buildah container can do anything the "docker"
# can do.
command -v docker
if [[ $? == 0 && -e /var/run/docker.sock ]]; then
RUN_OPTS="${RUN_OPTS} --volume /var/run/docker.sock:/var/run/docker.sock"
fi
command -v podman
if [[ $? -eq 0 ]]; then
CMD="podman"
OCI_DIR="/tmp/mq-buildah"
mkdir -p ${OCI_DIR}
RUN_OPTS="${RUN_OPTS} --volume ${OCI_DIR}:/var/oci"
echo "Image archives will be written to ${OCI_DIR}"
fi
${CMD} build --tag ${BUILDAH_IMAGE} --file ${SCRIPT_DIR}/Dockerfile ${SCRIPT_DIR}
set -x
${CMD} run ${RUN_OPTS} ${BUILDAH_IMAGE} "$@"

View File

@@ -23,7 +23,7 @@ import (
"os/exec"
"strings"
"github.com/ibm-messaging/mq-container/internal/name"
"github.com/ibm-messaging/mq-container/pkg/name"
)
func queueManagerHealthy() (bool, error) {

View File

@@ -22,8 +22,8 @@ import (
"net"
"os"
"github.com/ibm-messaging/mq-container/internal/name"
"github.com/ibm-messaging/mq-container/internal/ready"
"github.com/ibm-messaging/mq-container/pkg/name"
)
func main() {

View File

@@ -22,11 +22,10 @@ import (
"os/exec"
"syscall"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/containerruntimelogger"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/internal/mqtemplate"
"github.com/ibm-messaging/mq-container/internal/name"
"github.com/ibm-messaging/mq-container/pkg/containerruntimelogger"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/ibm-messaging/mq-container/pkg/name"
)
var log *logger.Logger
@@ -43,7 +42,7 @@ func setPassword(user string, password string) error {
if err != nil {
log.Errorf("Error closing password stdin: %v", err)
}
out, _, err := command.RunCmd(cmd)
out, err := cmd.CombinedOutput()
if err != nil {
// Include the command output in the error
return fmt.Errorf("%v: %v", err.Error(), out)
@@ -172,7 +171,7 @@ func main() {
} else {
// Replace this process with runmqserver
// #nosec G204
err = syscall.Exec("/usr/local/bin/runmqserver", []string{"runmqserver", "-dev"}, os.Environ())
err = syscall.Exec("/usr/local/bin/runmqserver", []string{"runmqserver", "-nologruntime", "-dev"}, os.Environ())
if err != nil {
log.Errorf("Error replacing this process with runmqserver: %v", err)
}

View File

@@ -27,8 +27,8 @@ import (
"sync"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/internal/mqini"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/ibm-messaging/mq-container/pkg/mqini"
)
// var debug = false

View File

@@ -24,18 +24,19 @@ import (
"os"
"sync"
"github.com/ibm-messaging/mq-container/internal/containerruntimelogger"
"github.com/ibm-messaging/mq-container/internal/metrics"
"github.com/ibm-messaging/mq-container/internal/name"
"github.com/ibm-messaging/mq-container/internal/mqinimerge"
"github.com/ibm-messaging/mq-container/internal/ready"
"github.com/ibm-messaging/mq-container/internal/tls"
"github.com/ibm-messaging/mq-container/internal/mqini"
"github.com/ibm-messaging/mq-container/pkg/containerruntimelogger"
"github.com/ibm-messaging/mq-container/pkg/name"
)
func doMain() error {
var initFlag = flag.Bool("i", false, "initialize volume only, then exit")
var infoFlag = flag.Bool("info", false, "Display debug info, then exit")
var devFlag = flag.Bool("dev", false, "used when running this program from runmqdevserver to control log output")
var noLogRuntimeFlag = flag.Bool("nologruntime", false, "used when running this program from another program, to control log output")
var devFlag = flag.Bool("dev", false, "used when running this program from runmqdevserver to control how TLS is configured")
flag.Parse()
name, nameErr := name.GetQueueManagerName()
@@ -88,7 +89,7 @@ func doMain() error {
// Enable diagnostic collecting on failure
collectDiagOnFail = true
if *devFlag == false {
if *noLogRuntimeFlag == false {
err = containerruntimelogger.LogContainerDetails(log)
if err != nil {
logTermination(err)
@@ -176,7 +177,7 @@ func doMain() error {
return err
}
err = mqini.AddStanzas(name)
err = mqinimerge.AddStanzas(name)
if err != nil {
logTermination(err)
return err

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2018
© Copyright IBM Corporation 2017, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import (
"strconv"
"testing"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
)
var test *bool

View File

@@ -30,10 +30,15 @@ func postInit(name, keylabel string, p12Trust tls.KeyStoreData) error {
if err != nil {
return err
}
// If trust-store is empty, set reference to point to the key-store
p12TrustStoreRef := "MQWebTrustStore"
if len(p12Trust.TrustedCerts) == 0 {
p12TrustStoreRef = "MQWebKeyStore"
}
// Start the web server, in the background (if installed)
// WARNING: No error handling or health checking available for the web server
go func() {
err = startWebServer(keystore, p12Trust.Password)
err = startWebServer(keystore, p12Trust.Password, p12TrustStoreRef)
if err != nil {
log.Printf("Error starting web server: %v", err)
}

View File

@@ -175,7 +175,7 @@ func stopQueueManager(name string) error {
log.Println("Stopping queue manager")
isStandby, err := ready.IsRunningAsStandbyQM(name)
if err != nil {
log.Printf("Error getting status for queue manager %v: ", name, err.Error())
log.Printf("Error getting status for queue manager %v: %v", name, err.Error())
return err
}
args := []string{"-w", "-r", name}

View File

@@ -73,12 +73,9 @@ func configureWebTLS(label string) error {
func configureTLSDev() error {
const mqsc string = "/etc/mqm/20-dev-tls.mqsc"
const mqscTemplate string = mqsc + ".tpl"
const sslCipherSpec string = "TLS_RSA_WITH_AES_128_CBC_SHA256"
if os.Getenv("MQ_DEV") == "true" {
err := mqtemplate.ProcessTemplateFile(mqscTemplate, mqsc, map[string]string{
"SSLCipherSpec": sslCipherSpec,
}, log)
err := mqtemplate.ProcessTemplateFile(mqscTemplate, mqsc, map[string]string{}, log)
if err != nil {
return err
}
@@ -121,11 +118,11 @@ func configureTLS(certLabel string, cmsKeystore tls.KeyStoreData, devmode bool)
return nil
}
// configureSSOTLS configures MQ Console TLS for Single Sign-On
func configureSSOTLS(p12TrustStore tls.KeyStoreData) (string, error) {
// configureWebKeyStore configures the key stores for the web console
func configureWebKeyStore(p12TrustStore tls.KeyStoreData) (string, error) {
// TODO find way to supply this
// Override the webstore variables to hard coded defaults
webKeyStoreName := tls.IntegrationDefaultLabel + ".p12"
webKeyStoreName := tls.WebDefaultLabel + ".p12"
// Check keystore exists
ks := filepath.Join(keyStoreDir, webKeyStoreName)

View File

@@ -31,7 +31,7 @@ import (
"github.com/ibm-messaging/mq-container/internal/tls"
)
func startWebServer(keystore, keystorepw string) error {
func startWebServer(keystore, keystorepw, p12TrustStoreRef string) error {
_, err := os.Stat("/opt/mqm/bin/strmqweb")
if err != nil && os.IsNotExist(err) {
log.Debug("Skipping web server, because it's not installed")
@@ -53,6 +53,7 @@ func startWebServer(keystore, keystorepw string) error {
if keystore != "" {
cmd.Env = append(cmd.Env, "AMQ_WEBKEYSTORE="+keystore)
cmd.Env = append(cmd.Env, "AMQ_WEBKEYSTOREPW="+keystorepw)
cmd.Env = append(cmd.Env, "AMQ_WEBTRUSTSTOREREF="+p12TrustStoreRef)
}
uid, gid, err := command.LookupMQM()
@@ -72,7 +73,8 @@ func startWebServer(keystore, keystorepw string) error {
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
}
out, rc, err := command.RunCmd(cmd)
out, err := cmd.CombinedOutput()
rc := cmd.ProcessState.ExitCode()
if err != nil {
log.Printf("Error %v starting web server: %v", rc, string(out))
return err
@@ -117,11 +119,12 @@ func configureSSO(p12TrustStore tls.KeyStoreData) (string, error) {
}
// Configure SSO TLS
return configureSSOTLS(p12TrustStore)
return configureWebKeyStore(p12TrustStore)
}
func configureWebServer(keyLabel string, p12Trust tls.KeyStoreData) (string, error) {
var keystore string
// Configure TLS for Web Console first if we have a certificate to use
err := configureWebTLS(keyLabel)
if err != nil {
@@ -138,7 +141,10 @@ func configureWebServer(keyLabel string, p12Trust tls.KeyStoreData) (string, err
if err != nil {
return keystore, err
}
} else if keyLabel == "" && os.Getenv("MQ_GENERATE_CERTIFICATE_HOSTNAME") != "" {
keystore, err = configureWebKeyStore(p12Trust)
}
_, err = os.Stat("/opt/mqm/bin/strmqweb")
if err != nil {
if os.IsNotExist(err) {

View File

@@ -4,26 +4,23 @@
You need to have the following tools installed:
* [Docker](https://www.docker.com/) V17.06.1 or later
* [Docker](https://www.docker.com/) V17.06.1 or later, or [Podman](https://podman.io) V1.0 or later
* [GNU make](https://www.gnu.org/software/make/)
If you are working in the Windows Subsystem for Linux, follow [this guide by Microsoft to set up Docker](https://blogs.msdn.microsoft.com/commandline/2017/12/08/cross-post-wsl-interoperability-with-docker/) first.
You will also need a [Red Hat Account](https://access.redhat.com) to be able to access the Red Hat Registry.
## Building a production image
This procedure works for building the MQ Continuous Delivery release, on `amd64`, `ppc64le` and `s390x` architectures.
1. Create a `downloads` directory in the root of this repository
2. Download MQ from [IBM Passport Advantage](https://www.ibm.com/software/passportadvantage/) or [IBM Fix Central](https://www.ibm.com/support/fixcentral), and place the downloaded file (for example, `IBM_MQ_9.1.3_LINUX_X86-64.tar.gz`) in the `downloads` directory
3. Run `make build-advancedserver`
2. Download MQ from [IBM Passport Advantage](https://www.ibm.com/software/passportadvantage/) or [IBM Fix Central](https://www.ibm.com/support/fixcentral), and place the downloaded file (for example, `IBM_MQ_9.1.4_LINUX_X86-64.tar.gz`) in the `downloads` directory
3. Login to the Red Hat Registry: `docker login registry.redhat.io` using your Customer Portal credentials.
4. Run `make build-advancedserver`
> **Warning**: Note that MQ offers two different sets of packaging on Linux: one is called "MQ for Linux" and contains RPM files for installing on Red Hat Enterprise Linux and SUSE Linux Enterprise Server. The MQ container build uses a Red Hat Universal Base Image, so you need the "MQ for Linux" RPM files.
You can build a different version of MQ by setting the `MQ_VERSION` environment variable, for example:
```bash
MQ_VERSION=9.1.0.0 make build-advancedserver
```
> **Warning**: Note that MQ offers two different sets of packaging on Linux: one is called "MQ for Linux" and contains RPM files for installing on Red Hat Enterprise Linux and SUSE Linux Enterprise Server; the other is for Ubuntu. The MQ container build uses a Red Hat Universal Base Image, so you need the "MQ for Linux" RPM files.
If you have an MQ archive file with a different file name, you can specify a particular file (which must be in the `downloads` directory). You should also specify the MQ version, so that the resulting image is tagged correctly, for example:
@@ -32,15 +29,12 @@ MQ_ARCHIVE=mq-1.2.3.4.tar.gz MQ_VERSION=1.2.3.4 make build-advancedserver
```
## Building a developer image
Login to the Red Hat Registry: `docker login registry.redhat.io` using your Customer Portal credentials.
Run `make build-devserver`, which will download the latest version of MQ Advanced for Developers from IBM developerWorks. This is currently only available on the `amd64` architecture.
You can use the environment variable `MQ_ARCHIVE_DEV` to specify an alternative local file to install from (which must be in the `downloads` directory).
## Building from a Red Hat Enterprise Linux host
Red Hat Enterprise Linux (RHEL) offers a suite of container tools, including Buildah for building container images, and Podman for running containers. Buildah can accept input described in a [Dockerfile](https://docs.docker.com/engine/reference/builder/). This MQ sample uses a multi-stage build, which requires a recent version of Podman, which is not yet available in Red Hat Enterprise Linux V7. Therefore, if you are on a RHEL host, then the `build-devserver` and `build-advancedserver` targets are run using a more recent version of Buildah from inside a container.
The containerized build process on a RHEL host will write an OCI compliant archive file to `/tmp/mq-buildah`. If a version of Docker is installed on the host, it will also push the image into Docker's internal image registry.
## Installed components
This image includes the core MQ server, Java, language packs, GSKit, and web server. This can be configured by setting the `MQ_PACKAGES` argument to `make`.

View File

@@ -34,11 +34,6 @@ Two channels are created, one for administration, the other for normal messaging
* DEV.ADMIN.SVRCONN - configured to only allow the `admin` user to connect into it. A user and password must be supplied.
* DEV.APP.SVRCONN - does not allow administrative users to connect. Password is optional unless you choose a password for app users.
A new listener is created (the SYSTEM listener is fine, but system objects are not shown by default in the web console):
* DEV.LISTENER.TCP - listens on port 1414.
## Web Console
By default the MQ Advanced for Developers image will start the IBM MQ Web Console that allows you to administer your Queue Manager running on your container. When the web console has been started, you can access it by opening a web browser and navigating to https://<Container IP>:9443/ibmmq/console. Where <Container IP> is replaced by the IP address of your running container.

View File

@@ -16,7 +16,7 @@ docker run \
--env LICENSE=accept \
--env MQ_QMGR_NAME=QM1 \
--detach \
mqadvanced-server:9.1.3.0-amd64
mqadvanced-server:9.1.4.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,7 +31,7 @@ docker run \
--env LICENSE=accept \
--env MQ_QMGR_NAME=QM1 \
--detach \
mqadvanced-server-dev:9.1.3.0-amd64
mqadvanced-server-dev:9.1.4.0-amd64
```
### SELinux

View File

@@ -24,7 +24,7 @@ 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=mqadvanced-server:9.1.3.0-amd64 make test-advancedserver
MQ_IMAGE_ADVANCEDSERVER=mqadvanced-server:9.1.4.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::
@@ -33,10 +33,10 @@ You can pass parameters to `go test` with an environment variable. For example,
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 `mqadvanced-server:9.1.3.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 `mqadvanced-server:9.1.4.0-amd64`:
```
MQ_VERSION=9.1.3.0 make test-advancedserver
MQ_VERSION=9.1.4.0 make test-advancedserver
```
### Running the Docker tests with code coverage

View File

@@ -2,6 +2,8 @@
In order to use the image, it is necessary to accept the terms of the IBM MQ license. This is achieved by specifying the environment variable `LICENSE` equal to `accept` when running the image. You can also view the license terms by setting this variable to `view`. Failure to set the variable will result in the termination of the container with a usage statement. You can view the license in a different language by also setting the `LANG` environment variable.
> **Note**: You can use `podman` instead of `docker` in any of the examples on this page.
## Running with the default configuration
You can run a queue manager with the default configuration and a listener on port 1414 using the following command. For example, the following command creates and starts a queue manager called `QM1`, and maps port 1414 on the host to the MQ listener on port 1414 inside the container, as well as port 9443 on the host to the web console on port 9443 inside the container:

View File

@@ -16,4 +16,4 @@
* Set the keystore location for the queue manager
ALTER QMGR SSLKEYR('{{ .SSLKeyR }}')
ALTER QMGR CERTLABL('{{ .CertificateLabel }}')
REFRESH SECURITY(*) TYPE(SSL)

57
glide.lock generated
View File

@@ -1,57 +0,0 @@
hash: 6ebd5fb1c39729378c7256da6f312e9699bff1ddff9941d3c8c1ba785e22acfd
updated: 2019-05-21T10:38:01.227081+01:00
imports:
- name: github.com/beorn7/perks
version: 3a771d992973f24aa725d07868b467d1ddfceafb
subpackages:
- quantile
- name: github.com/genuinetools/amicontained
version: fcae88544f0212fbb1e20699c41566655b68679b
subpackages:
- container
- name: github.com/golang/protobuf
version: 70b3af33377e7aa25ae42977bed93cc6b90f0373
subpackages:
- proto
- name: github.com/ibm-messaging/mq-golang
version: 1b2a2ad95ba3c555944be28097d392c27bda4071
subpackages:
- ibmmq
- mqmetric
- name: github.com/matttproud/golang_protobuf_extensions
version: c12348ce28de40eed0136aa2b644d0ee0650e56c
subpackages:
- pbutil
- name: github.com/prometheus/client_golang
version: c5b7fccd204277076155f10851dad72b76a49317
subpackages:
- prometheus
- name: github.com/prometheus/client_model
version: 5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f
subpackages:
- go
- name: github.com/prometheus/common
version: 7600349dcfe1abd18d72d3a1770870d9800a7801
subpackages:
- expfmt
- internal/bitbucket.org/ww/goautoneg
- model
- name: github.com/prometheus/procfs
version: ae68e2d4c00fed4943b5f6698d504a5fe083da8a
subpackages:
- internal/util
- nfs
- xfs
- name: github.com/syndtr/gocapability
version: 33e07d32887e1e06b7c025f27ce52f62c7990bc0
subpackages:
- capability
- name: golang.org/x/sys
version: 1b2967e3c290b7c545b3db0deeda16e9be4f98a2
subpackages:
- unix
- name: software.sslmate.com/src/go-pkcs12
version: 6e380ad96778cc63c6ea17649a9b74224bceafe9
subpackages:
- internal/rc2
testImports: []

View File

@@ -1,30 +0,0 @@
# © Copyright IBM Corporation 2017, 2019
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
package: github.com/ibm-messaging/mq-container
license: Apache-2.0
excludeDirs:
- build
- coverage
- test
import:
- package: golang.org/x/sys/unix
- package: github.com/prometheus/client_golang
version: 0.8.0
- package: github.com/ibm-messaging/mq-golang
version: 2.0.0
- package: github.com/genuinetools/amicontained
version: 0.4.0
- package: software.sslmate.com/src/go-pkcs12
commit: 6e380ad96778cc63c6ea17649a9b74224bceafe9

View File

@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
FROM registry.access.redhat.com/ubi7/ubi-minimal AS mq-explorer
FROM registry.redhat.io/ubi8/ubi-minimal AS mq-explorer
# The URL to download the MQ installer from in tar.gz format
ARG MQ_URL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/mqadv_dev912_linux_x86-64.tar.gz"
@@ -22,7 +22,7 @@ ENV MQ_PACKAGES="MQSeriesRuntime*.rpm MQSeriesJRE*.rpm MQSeriesExplorer*.rpm"
ARG MQM_UID=888
RUN microdnf install -y --nodocs gtk2 libXtst \
RUN microdnf install -y gtk2 libXtst \
&& microdnf clean all
ADD install-mq.sh /usr/local/bin/

View File

@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
FROM registry.access.redhat.com/rhscl/devtoolset-7-toolchain-rhel7 AS mq-sdk
FROM registry.redhat.io/rhel8/llvm-toolset:8.0.1-10 AS mq-sdk
#FROM docker.io/centos/devtoolset-7-toolchain-centos7 AS mq-sdk
# The URL to download the MQ installer from in tar.gz format

View File

@@ -13,9 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
STOP LISTENER('SYSTEM.LISTENER.TCP.1') IGNSTATE(YES)
ALTER LISTENER('SYSTEM.LISTENER.TCP.1') TRPTYPE(TCP) CONTROL(MANUAL)
* Developer queues
DEFINE QLOCAL('DEV.QUEUE.1') REPLACE
DEFINE QLOCAL('DEV.QUEUE.2') REPLACE
@@ -48,7 +45,3 @@ SET CHLAUTH('DEV.ADMIN.SVRCONN') TYPE(USERMAP) CLNTUSER('admin') USERSRC(CHANNEL
SET AUTHREC GROUP('mqclient') OBJTYPE(QMGR) AUTHADD(CONNECT,INQ)
SET AUTHREC PROFILE('DEV.**') GROUP('mqclient') OBJTYPE(QUEUE) AUTHADD(BROWSE,GET,INQ,PUT)
SET AUTHREC PROFILE('DEV.**') GROUP('mqclient') OBJTYPE(TOPIC) AUTHADD(PUB,SUB)
* Developer listener
DEFINE LISTENER('DEV.LISTENER.TCP') TRPTYPE(TCP) PORT(1414) CONTROL(QMGR) REPLACE
START LISTENER('DEV.LISTENER.TCP') IGNSTATE(YES)

View File

@@ -14,5 +14,5 @@
* limitations under the License.
* Set the cipherspec for dev channels
ALTER CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH({{ .SSLCipherSpec }}) SSLCAUTH(OPTIONAL)
ALTER CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH({{ .SSLCipherSpec }}) SSLCAUTH(OPTIONAL)
ALTER CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12) SSLCAUTH(OPTIONAL)
ALTER CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12) SSLCAUTH(OPTIONAL)

View File

@@ -15,6 +15,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# Fail on any non-zero return code
set -ex
test -f /usr/bin/yum && YUM=true || YUM=false
test -f /usr/bin/microdnf && MICRODNF=true || MICRODNF=false
test -f /usr/bin/apt-get && UBUNTU=true || UBUNTU=false
@@ -33,6 +36,6 @@ if ($YUM); then
fi
if ($MICRODNF); then
microdnf install --nodocs sudo
microdnf install sudo
microdnf clean all
fi

View File

@@ -19,8 +19,8 @@
set -ex
curl https://glide.sh/get | sh
sudo curl -Lo /usr/local/bin/dep https://github.com/golang/dep/releases/download/v0.5.0/dep-linux-amd64
sudo curl -Lo /usr/local/bin/dep https://github.com/golang/dep/releases/download/v0.5.1/dep-linux-$ARCH
sudo chmod +x /usr/local/bin/dep
go get -u golang.org/x/lint/golint
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $GOPATH/bin 2.0.0 || echo "Gosec not installed. Platform may not be supported."

View File

@@ -63,10 +63,10 @@ if ($UBUNTU); then
fi
if ($RPM); then
EXTRA_RPMS="bash bc ca-certificates coreutils file findutils gawk glibc-common grep passwd procps-ng sed shadow-utils tar util-linux which"
EXTRA_RPMS="bash bc ca-certificates file findutils gawk glibc-common grep passwd procps-ng sed shadow-utils tar util-linux which"
# Install additional packages required by MQ, this install process and the runtime scripts
$YUM && yum -y install --setopt install_weak_deps=false ${EXTRA_RPMS}
$MICRODNF && microdnf install --nodocs ${EXTRA_RPMS}
$MICRODNF && microdnf install ${EXTRA_RPMS}
fi
# Apply any bug fixes not included in base Ubuntu or MQ image.

View File

@@ -94,7 +94,7 @@ ln -s /mnt/mqm/data /var/mqm
sed -i 's/PASS_MAX_DAYS\t99999/PASS_MAX_DAYS\t90/' /etc/login.defs
sed -i 's/PASS_MIN_DAYS\t0/PASS_MIN_DAYS\t1/' /etc/login.defs
sed -i 's/PASS_MIN_LEN\t5/PASS_MIN_LEN\t8/' /etc/login.defs
sed -i 's/# minlen = 9/minlen = 8/' /etc/security/pwquality.conf
$RPM && sed -i 's/# minlen/minlen/' /etc/security/pwquality.conf
$UBUNTU && PAM_FILE=/etc/pam.d/common-password
$RPM && PAM_FILE=/etc/pam.d/password-auth
@@ -104,6 +104,10 @@ sed -i 's/password\t\[success=1 default=ignore\]\tpam_unix\.so obscure sha512/pa
$RPM && rpm -q --all || true
$UBUNTU && dpkg --list || true
#Update the license file to include UBI 8 instead of UBI 7
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

@@ -21,40 +21,24 @@ import (
"fmt"
"os/exec"
"os/user"
"runtime"
"strconv"
"syscall"
)
// RunCmd runs an OS command. On Linux it waits for the command to
// complete and returns the exit status (return code).
// Do not use this function to run shell built-ins (like "cd"), because
// the error handling works differently
func RunCmd(cmd *exec.Cmd) (string, int, error) {
// Run the command and wait for completion
out, err := cmd.CombinedOutput()
if err != nil {
// Assert that this is an ExitError
exiterr, ok := err.(*exec.ExitError)
// If the type assertion was correct, and we're on Linux
if ok && runtime.GOOS == "linux" {
status, ok := exiterr.Sys().(syscall.WaitStatus)
if ok {
return string(out), status.ExitStatus(), fmt.Errorf("%v: %v", cmd.Path, err)
}
}
return string(out), -1, err
}
return string(out), 0, nil
}
// Run runs an OS command. On Linux it waits for the command to
// complete and returns the exit status (return code).
// Do not use this function to run shell built-ins (like "cd"), because
// the error handling works differently
func Run(name string, arg ...string) (string, int, error) {
// Run the command and wait for completion
// #nosec G204
return RunCmd(exec.Command(name, arg...))
cmd := exec.Command(name, arg...)
out, err := cmd.CombinedOutput()
rc := cmd.ProcessState.ExitCode()
if err != nil {
return string(out), rc, fmt.Errorf("%v: %v", cmd.Path, err)
}
return string(out), rc, nil
}
// RunAsMQM runs the specified command as the mqm user
@@ -67,7 +51,7 @@ func RunAsMQM(name string, arg ...string) (string, int, error) {
return "", 0, err
}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
return RunCmd(cmd)
return Run(name, arg...)
}
// LookupMQM looks up the UID & GID of the mqm user

View File

@@ -152,7 +152,7 @@ func (ks *KeyStore) Import(inputFile, password string) error {
// CreateSelfSignedCertificate creates a self-signed certificate in the keystore
func (ks *KeyStore) CreateSelfSignedCertificate(label, dn, hostname string) error {
out, _, err := command.Run(ks.command, "-cert", "-create", "-db", ks.Filename, "-pw", ks.Password, "-label", label, "-dn", dn, "-san_dnsname", hostname)
out, _, err := command.Run(ks.command, "-cert", "-create", "-db", ks.Filename, "-pw", ks.Password, "-label", label, "-dn", dn, "-san_dnsname", hostname, "-size 2048 -sig_alg sha256 -eku serverAuth")
if err != nil {
return fmt.Errorf("error running \"%v -cert -create\": %v %s", ks.command, err, out)
}
@@ -207,7 +207,7 @@ func (ks *KeyStore) RenameCertificate(from, to string) error {
// #nosec G204
cmd := exec.Command("/opt/mqm/gskit8/bin/gsk8capicmd_64", "-cert", "-rename", "-db", ks.Filename, "-pw", ks.Password, "-label", from, "-new_label", to)
cmd.Env = append(os.Environ(), "LD_LIBRARY_PATH=/opt/mqm/gskit8/lib64/:/opt/mqm/gskit8/lib")
out, _, err := command.RunCmd(cmd)
out, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("error running \"%v -cert -rename\": %v %s", "/opt/mqm/gskit8/bin/gsk8capicmd_64", err, out)
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© Copyright IBM Corporation 2018, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ limitations under the License.
package metrics
import (
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/prometheus/client_golang/prometheus"
)

View File

@@ -23,7 +23,7 @@ import (
"net/http"
"time"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/ibm-messaging/mq-container/internal/ready"
"github.com/prometheus/client_golang/prometheus"
)

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© Copyright IBM Corporation 2018, 2019
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,7 @@ import (
"strings"
"time"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/ibm-messaging/mq-golang/ibmmq"
"github.com/ibm-messaging/mq-golang/mqmetric"
)

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© Copyright IBM Corporation 2018, 2019
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 @@ import (
"os"
"testing"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
"github.com/ibm-messaging/mq-golang/mqmetric"
)

View File

@@ -1,328 +0,0 @@
/*
© Copyright IBM Corporation 2018, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package mqini provides information about queue managers
package mqini
import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/ibm-messaging/mq-container/internal/command"
)
// QueueManager describe high-level configuration information for a queue manager
type QueueManager struct {
Name string
Prefix string
Directory string
DataPath string
InstallationName string
}
var qmgrDir string
var stanzasQMINI []string
var stanzasMQATINI []string
// getQueueManagerFromStanza parses a queue manager stanza
func getQueueManagerFromStanza(stanza string) (*QueueManager, error) {
scanner := bufio.NewScanner(strings.NewReader(stanza))
qm := QueueManager{}
for scanner.Scan() {
l := scanner.Text()
l = strings.TrimSpace(l)
t := strings.Split(l, "=")
switch t[0] {
case "Name":
qm.Name = t[1]
case "Prefix":
qm.Prefix = t[1]
case "Directory":
qm.Directory = t[1]
case "DataPath":
qm.DataPath = t[1]
case "InstallationName":
qm.InstallationName = t[1]
}
}
return &qm, scanner.Err()
}
// GetQueueManager returns queue manager configuration information
func GetQueueManager(name string) (*QueueManager, error) {
// dspmqinf essentially returns a subset of mqs.ini, but it's simpler to parse
out, _, err := command.Run("dspmqinf", "-o", "stanza", name)
if err != nil {
return nil, err
}
return getQueueManagerFromStanza(out)
}
// GetErrorLogDirectory returns the directory holding the error logs for the
// specified queue manager
func GetErrorLogDirectory(qm *QueueManager) string {
if qm.DataPath != "" {
return filepath.Join(qm.DataPath, "errors")
}
return filepath.Join(qm.Prefix, "qmgrs", qm.Directory, "errors")
}
//AddStanzas Reads supplied mq ini configuration files and updates the stanzas
//into queue manager's ini configuration files.
func AddStanzas(qmname string) error {
//find the qmgr directory.
qm, err := GetQueueManager(qmname)
if err != nil {
return err
}
qmgrDir = filepath.Join(qm.Prefix, "qmgrs", qm.Directory)
//Find the users ini configuration file
files := getIniFileList()
if len(files) > 1 {
msg := fmt.Sprintf("[ %v ]", files)
return errors.New("Only a single ini file can be provided. Following ini files are found:" + msg)
}
if len(files) == 0 {
//no ini file update required.
return nil
}
iniFileBytes, err := ioutil.ReadFile(files[0])
if err != nil {
return err
}
userconfig := string(iniFileBytes)
if len(userconfig) == 0 {
return nil
}
//Prepare a list of all supported stanzas
PopulateAllAvailableStanzas()
//Update the qmgr ini file with user config.
qmConfig, atConfig, err := PrepareConfigStanzasToWrite(userconfig)
if err != nil {
return err
}
err = writeConfigStanzas(qmConfig, atConfig)
if err != nil {
return err
}
return nil
}
// PopulateAllAvailableStanzas initializes the ini stanzas prescribed by mq specification.
func PopulateAllAvailableStanzas() {
stanzasQMINI = []string{"ExitPath",
"Log",
"Service",
"ServiceComponent",
"Channels",
"TCP",
"ApiExitLocal",
"AccessMode",
"RestrictedMode",
"XAResourceManager",
"DefaultBindType",
"SSL",
"DiagnosticMessages",
"Filesystem",
"Security",
"TuningParameters",
"ExitPropertiesLocal",
"LU62",
"NETBIOS"}
stanzasMQATINI = []string{"AllActivityTrace", "ApplicationTrace"}
}
// getIniFileList Checks for the user supplied ini file in /etc/mqm directory.
func getIniFileList() []string {
fileList := []string{}
filepath.Walk("/etc/mqm", func(path string, f os.FileInfo, err error) error {
if strings.HasSuffix(path, ".ini") {
fileList = append(fileList, path)
}
return nil
})
return fileList
}
//PrepareConfigStanzasToWrite Reads through the user supplied ini config file and prepares list of
//updates to be written into corresponding mq ini files (qm.ini and/or mqat.ini files.)
func PrepareConfigStanzasToWrite(userconfig string) (string, string, error) {
var qminiConfigStr string
var mqatiniConfigStr string
//read the initial version.
iniFileBytes, err := ioutil.ReadFile(filepath.Join(qmgrDir, "qm.ini"))
if err != nil {
return "", "", err
}
qminiConfigStr = string(iniFileBytes)
iniFileBytes, err = ioutil.ReadFile(filepath.Join(qmgrDir, "mqat.ini"))
if err != nil {
return "", "", err
}
mqatiniConfigStr = string(iniFileBytes)
stanzaListMerge := make(map[string]strings.Builder)
stanzaListAppend := make(map[string]strings.Builder)
var sbAppend strings.Builder
var sbMerger strings.Builder
scanner := bufio.NewScanner(strings.NewReader(userconfig))
scanner.Split(bufio.ScanLines)
consumetoAppend := false
consumeToMerge := false
var stanza string
//read through the user file and prepare what we want.
for scanner.Scan() {
if strings.Contains(scanner.Text(), ":") {
consumetoAppend = false
consumeToMerge = false
stanza = scanner.Text()
//check if this stanza exists in the qm.ini/mqat.ini files
if strings.Contains(qminiConfigStr, stanza) ||
(strings.Contains(mqatiniConfigStr, stanza) && !(strings.Contains(stanza, "ApplicationTrace"))) {
consumeToMerge = true
sbMerger = strings.Builder{}
stanzaListMerge[stanza] = sbMerger
} else {
consumetoAppend = true
sbAppend = strings.Builder{}
stanzaListAppend[stanza] = sbAppend
}
} else {
if consumetoAppend {
sb := stanzaListAppend[stanza]
sb.WriteString(scanner.Text() + "\n")
stanzaListAppend[stanza] = sb
}
if consumeToMerge {
sb := stanzaListMerge[stanza]
sb.WriteString(scanner.Text() + "\n")
stanzaListMerge[stanza] = sb
}
}
}
//merge if stanza exits.
if len(stanzaListMerge) > 0 {
for key := range stanzaListMerge {
toWrite, filename := ValidateStanzaToWrite(key)
if toWrite {
attrList := stanzaListMerge[key]
switch filename {
case "qm.ini":
qminiConfigStr = prepareStanzasToMerge(key, attrList, qminiConfigStr)
case "mqat.ini":
mqatiniConfigStr = prepareStanzasToMerge(key, attrList, mqatiniConfigStr)
default:
}
}
}
}
//append new stanzas.
if len(stanzaListAppend) > 0 {
for key := range stanzaListAppend {
attrList := stanzaListAppend[key]
if strings.Contains(strings.Join(stanzasMQATINI, ", "), strings.TrimSuffix(strings.TrimSpace(key), ":")) {
mqatiniConfigStr = prepareStanzasToAppend(key, attrList, mqatiniConfigStr)
} else {
qminiConfigStr = prepareStanzasToAppend(key, attrList, qminiConfigStr)
}
}
}
return qminiConfigStr, mqatiniConfigStr, nil
}
//ValidateStanzaToWrite Validates stanza to be written and the file it belongs to.
func ValidateStanzaToWrite(stanza string) (bool, string) {
stanza = strings.TrimSpace(stanza)
if strings.Contains(stanza, ":") {
stanza = stanza[:len(stanza)-1]
}
if strings.Contains(strings.Join(stanzasQMINI, ", "), stanza) {
return true, "qm.ini"
} else if strings.Contains(strings.Join(stanzasMQATINI, ", "), stanza) {
return true, "mqat.ini"
} else {
return false, ""
}
}
//prepareStanzasToAppend Prepares list of stanzas that are to be appended into qm ini files(qm.ini/mqat.ini)
func prepareStanzasToAppend(key string, attrList strings.Builder, iniConfig string) string {
newVal := key + "\n" + attrList.String()
iniConfig = iniConfig + newVal
return iniConfig
}
//prepareStanzasToMerge Prepares list of stanzas that are to be updated into qm ini files(qm.ini/mqat.ini)
//These stanzas are already present in mq ini files and their values have to be updated with user supplied ini.
func prepareStanzasToMerge(key string, attrList strings.Builder, iniConfig string) string {
lineScanner := bufio.NewScanner(strings.NewReader(attrList.String()))
lineScanner.Split(bufio.ScanLines)
for lineScanner.Scan() {
attrLine := lineScanner.Text()
keyvalue := strings.Split(attrLine, "=")
//this line present in qm.ini, update value.
if strings.Contains(iniConfig, keyvalue[0]) {
re := regexp.MustCompile(keyvalue[0] + "=.*")
iniConfig = re.ReplaceAllString(iniConfig, attrLine)
} else { //this line not present in qm.ini file, add it.
re := regexp.MustCompile(key)
newVal := key + "\n" + attrLine
iniConfig = re.ReplaceAllString(iniConfig, newVal)
}
}
return iniConfig
}
//writeConfigStanzas Writes the ini file updates into corresponding mq ini files.
func writeConfigStanzas(qmConfig string, atConfig string) error {
err := ioutil.WriteFile(filepath.Join(qmgrDir, "qm.ini"), []byte(qmConfig), 0644)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(qmgrDir, "mqat.ini"), []byte(atConfig), 0644)
if err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,352 @@
/*
© Copyright IBM Corporation 2018, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package mqinimerge merges user-supplied INI files into qm.ini and mqat.ini
package mqinimerge
import (
"bufio"
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/ibm-messaging/mq-container/pkg/mqini"
)
var qmgrDir string
var stanzasQMINI []string
var stanzasMQATINI []string
// AddStanzas reads supplied MQ INI configuration files and updates the stanzas
// in the queue manager's INI configuration files.
func AddStanzas(qmname string) error {
// Find the qmgr directory.
qm, err := mqini.GetQueueManager(qmname)
if err != nil {
return err
}
qmgrDir = mqini.GetDataDirectory(qm)
// Find the users ini configuration file
files, err := getIniFileList()
if err != nil {
return err
}
if len(files) > 1 {
msg := fmt.Sprintf("[ %v ]", files)
return errors.New("Only a single INI file can be provided. Following INI files were found:" + msg)
}
if len(files) == 0 {
// No INI file update required.
return nil
}
//read user supplied config file.
iniFileBytes, err := ioutil.ReadFile(files[0])
if err != nil {
return err
}
userconfig := string(iniFileBytes)
if len(userconfig) == 0 {
return nil
}
// Prepare a list of all supported stanzas
PopulateAllAvailableStanzas()
// Update the qmgr ini file with user config.
qminiConfiglist, qmatConfiglist, err := PrepareConfigStanzasToWrite(userconfig)
if err != nil {
return err
}
err = writeConfigStanzas(qminiConfiglist, qmatConfiglist)
if err != nil {
return err
}
return nil
}
// PopulateAllAvailableStanzas initializes the INI stanzas prescribed by MQ specification.
func PopulateAllAvailableStanzas() {
stanzasQMINI = []string{"ExitPath",
"Log",
"Service",
"ServiceComponent",
"Channels",
"TCP",
"ApiExitLocal",
"AccessMode",
"RestrictedMode",
"XAResourceManager",
"DefaultBindType",
"SSL",
"DiagnosticMessages",
"Filesystem",
"Security",
"TuningParameters",
"ExitPropertiesLocal",
"LU62",
"NETBIOS"}
stanzasMQATINI = []string{"AllActivityTrace", "ApplicationTrace"}
}
// getIniFileList checks for the user supplied INI file in `/etc/mqm` directory.
func getIniFileList() ([]string, error) {
fileList := []string{}
err := filepath.Walk("/etc/mqm", func(path string, f os.FileInfo, err error) error {
if strings.HasSuffix(path, ".ini") {
fileList = append(fileList, path)
}
return nil
})
if err != nil {
return nil, err
}
return fileList, nil
}
// PrepareConfigStanzasToWrite Reads through the user supplied INI config file and prepares list of
// updates to be written into corresponding mq ini files (qm.ini and/or mqat.ini files)
func PrepareConfigStanzasToWrite(userconfig string) ([]string, []string, error) {
var qminiConfigStr string
var mqatiniConfigStr string
//read the initial version.
// #nosec G304 - qmgrDir filepath is derived from dspmqinf
iniFileBytes, err := ioutil.ReadFile(filepath.Join(qmgrDir, "qm.ini"))
if err != nil {
return nil, nil, err
}
qminiConfigStr = string(iniFileBytes)
qminiConfiglist := strings.Split(qminiConfigStr, "\n")
// #nosec G304 - qmgrDir filepath is derived from dspmqinf
iniFileBytes, err = ioutil.ReadFile(filepath.Join(qmgrDir, "mqat.ini"))
if err != nil {
return nil, nil, err
}
mqatiniConfigStr = string(iniFileBytes)
qmatConfiglist := strings.Split(mqatiniConfigStr, "\n")
stanzaListMerge := make(map[string]strings.Builder)
stanzaListAppend := make(map[string]strings.Builder)
var sbAppend strings.Builder
var sbMerger strings.Builder
scanner := bufio.NewScanner(strings.NewReader(userconfig))
scanner.Split(bufio.ScanLines)
consumetoAppend := false
consumeToMerge := false
var stanza string
// Read through the user file and prepare what we want.
for scanner.Scan() {
//if this is comment or an empty line, ignore it.
if strings.HasPrefix(scanner.Text(), "#") || len(strings.TrimSpace(scanner.Text())) == 0 {
continue
}
//thumb rule - all stanzas have ":".
if strings.Contains(scanner.Text(), ":") {
stanza = strings.TrimSpace(scanner.Text())
consumetoAppend = false
consumeToMerge = false
// Check if this stanza exists in the qm.ini/mqat.ini files
if strings.Contains(qminiConfigStr, stanza) ||
(strings.Contains(mqatiniConfigStr, stanza) && !(strings.Contains(stanza, "ApplicationTrace"))) {
consumeToMerge = true
sbMerger = strings.Builder{}
stanzaListMerge[stanza] = sbMerger
} else {
consumetoAppend = true
sbAppend = strings.Builder{}
stanzaListAppend[stanza] = sbAppend
}
} else {
if consumetoAppend {
sb := stanzaListAppend[stanza]
_, err := sb.WriteString(scanner.Text() + "\n")
if err != nil {
return nil, nil, err
}
stanzaListAppend[stanza] = sb
}
if consumeToMerge {
sb := stanzaListMerge[stanza]
_, err := sb.WriteString(scanner.Text() + "\n")
if err != nil {
return nil, nil, err
}
stanzaListMerge[stanza] = sb
}
}
}
// do merge.
if len(stanzaListMerge) > 0 {
for key := range stanzaListMerge {
toWrite, filename := ValidateStanzaToWrite(key)
if toWrite {
attrList := stanzaListMerge[key]
switch filename {
case "qm.ini":
qminiConfiglist, err = prepareStanzasToMerge(key, attrList, qminiConfiglist)
if err != nil {
return nil, nil, err
}
case "mqat.ini":
qmatConfiglist, err = prepareStanzasToMerge(key, attrList, qmatConfiglist)
if err != nil {
return nil, nil, err
}
default:
}
}
}
}
// do append.
if len(stanzaListAppend) > 0 {
for key := range stanzaListAppend {
attrList := stanzaListAppend[key]
if strings.Contains(strings.Join(stanzasMQATINI, ", "), strings.TrimSuffix(strings.TrimSpace(key), ":")) {
qmatConfiglist = prepareStanzasToAppend(key, attrList, qmatConfiglist)
} else {
qminiConfiglist = prepareStanzasToAppend(key, attrList, qminiConfiglist)
}
}
}
return qminiConfiglist, qmatConfiglist, nil
}
// ValidateStanzaToWrite validates stanza to be written and the file it belongs to.
func ValidateStanzaToWrite(stanza string) (bool, string) {
stanza = strings.TrimSuffix(strings.TrimSpace(stanza), ":")
if strings.Contains(strings.Join(stanzasQMINI, ", "), stanza) {
return true, "qm.ini"
} else if strings.Contains(strings.Join(stanzasMQATINI, ", "), stanza) {
return true, "mqat.ini"
} else {
return false, ""
}
}
// prepareStanzasToAppend Prepares list of stanzas that are to be appended into qm ini files(qm.ini/mqat.ini)
func prepareStanzasToAppend(key string, attrList strings.Builder, iniConfigList []string) []string {
newVal := key + "\n" + attrList.String()
list := strings.Split(newVal, "\n")
iniConfigList = append(iniConfigList, list...)
return iniConfigList
}
// prepareStanzasToMerge Prepares list of stanzas that are to be updated into qm ini files(qm.ini/mqat.ini)
// These stanzas are already present in mq ini files and their values have to be updated with user supplied ini.
func prepareStanzasToMerge(key string, attrList strings.Builder, iniConfigList []string) ([]string, error) {
pos := -1
//find the index of current stanza in qm's ini file.
for i := 0; i < len(iniConfigList); i++ {
if strings.Contains(iniConfigList[i], key) {
pos = i
break
}
}
var appList strings.Builder
lineScanner := bufio.NewScanner(strings.NewReader(attrList.String()))
lineScanner.Split(bufio.ScanLines)
//Now go through the array and merge the values.
for lineScanner.Scan() {
attrLine := lineScanner.Text()
keyvalue := strings.Split(attrLine, "=")
merged := false
for i := pos + 1; i < len(iniConfigList); i++ {
if strings.HasPrefix(iniConfigList[i], "#") {
continue
}
if strings.Contains(iniConfigList[i], ":") {
break
}
if strings.Contains(iniConfigList[i], keyvalue[0]) {
iniConfigList[i] = attrLine
merged = true
break
}
}
//If this is not merged, then its a new parameter in existing stanza.
if !merged && len(strings.TrimSpace(attrLine)) > 0 {
_, err := appList.WriteString(attrLine)
if err != nil {
return nil, err
}
merged = false
}
if len(appList.String()) > 0 {
temp := make([]string, pos+1)
for i := 0; i < pos+1; i++ {
temp[i] = iniConfigList[i]
}
list := strings.Split(appList.String(), "\n")
temp = append(temp, list...)
temp1 := iniConfigList[pos+1:]
iniConfigList = append(temp, temp1...)
}
}
return iniConfigList, nil
}
// writeFileIfChanged writes the specified data to the specified file path
// (just like ioutil.WriteFile), but first checks if this is needed
func writeFileIfChanged(path string, data []byte, perm os.FileMode) error {
// #nosec G304 - internal utility using file name derived from dspmqinf
current, err := ioutil.ReadFile(path)
if err != nil {
return err
}
// Only write the new file if the it's different from the current file
if !bytes.Equal(current, data) {
err = ioutil.WriteFile(path, data, perm)
if err != nil {
return err
}
}
return nil
}
// writeConfigStanzas writes the INI file updates into corresponding MQ INI files.
func writeConfigStanzas(qmConfig []string, atConfig []string) error {
err := writeFileIfChanged(filepath.Join(qmgrDir, "qm.ini"), []byte(strings.Join(qmConfig, "\n")), 0644)
if err != nil {
return err
}
err = writeFileIfChanged(filepath.Join(qmgrDir, "mqat.ini"), []byte(strings.Join(atConfig, "\n")), 0644)
if err != nil {
return err
}
return nil
}

View File

@@ -13,58 +13,19 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mqini
package mqinimerge
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
var getQueueManagerTests = []struct {
file string
name string
prefix string
directory string
errorLogDir string
}{
{"dspmqinf1.txt", "foo", "/var/mqm", "foo", "/var/mqm/qmgrs/foo/errors"},
{"dspmqinf2.txt", "a/b", "/var/mqm", "a&b", "/var/mqm/qmgrs/a&b/errors"},
{"dspmqinf3.txt", "..", "/var/mqm", "!!", "/var/mqm/qmgrs/!!/errors"},
}
func TestGetQueueManager(t *testing.T) {
for _, table := range getQueueManagerTests {
t.Run(table.file, func(t *testing.T) {
b, err := ioutil.ReadFile(table.file)
if err != nil {
t.Fatal(err)
}
qm, err := getQueueManagerFromStanza(string(b))
if err != nil {
t.Fatal(err)
}
t.Logf("%#v", qm)
if qm.Name != table.name {
t.Errorf("Expected name=%v; got %v", table.name, qm.Name)
}
if qm.Prefix != table.prefix {
t.Errorf("Expected prefix=%v; got %v", table.prefix, qm.Prefix)
}
if qm.Directory != table.directory {
t.Errorf("Expected directory=%v; got %v", table.directory, qm.Directory)
}
// Test
d := GetErrorLogDirectory(qm)
if d != table.errorLogDir {
t.Errorf("Expected error log directory=%v; got %v", table.errorLogDir, d)
}
})
}
}
func TestIniFileStanzas(t *testing.T) {
PopulateAllAvailableStanzas()
@@ -87,7 +48,6 @@ func TestIniFileStanzas(t *testing.T) {
}
func TestIniFile1Update(t *testing.T) {
iniFileBytes, err := ioutil.ReadFile("test1qm.ini")
if err != nil {
t.Errorf("Unexpected error: [%s]\n", err.Error())
@@ -104,19 +64,20 @@ func TestIniFile1Update(t *testing.T) {
t.Errorf("Expected stanza file not found: qm.ini\n")
}
scanner := bufio.NewScanner(strings.NewReader(userconfig))
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
line := scanner.Text()
if !strings.Contains(qmConfig, line) {
t.Errorf("Expected stanza line not found in updated string. line=%s\n, Stanza:%s\n", line, qmConfig)
break
count := 0
//we want this line to be present exactly one.
for _, item := range qmConfig {
item = strings.TrimSpace(item)
if strings.Contains(item, "mylib") {
count++
}
}
if count != 1 {
t.Errorf("Expected stanza line not found or appeared more than once in updated string. line=mylib\n config=%s\n count=%d\n", strings.Join(qmConfig, "\n"), count)
}
}
func TestIniFile2Update(t *testing.T) {
iniFileBytes, err := ioutil.ReadFile("test2qm.ini")
if err != nil {
t.Errorf("Unexpected error: [%s]\n", err.Error())
@@ -133,19 +94,20 @@ func TestIniFile2Update(t *testing.T) {
t.Errorf("Expected stanza file not found: qm.ini\n")
}
scanner := bufio.NewScanner(strings.NewReader(userconfig))
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
line := scanner.Text()
if !strings.Contains(atConfig, line) {
t.Errorf("Expected stanza line not found in updated string. line=%s\n, Stanza:%s\n", line, qmConfig)
break
count := 0
//we want this line to be present exactly one.
for _, item := range atConfig {
item = strings.TrimSpace(item)
if strings.Contains(item, "amqsget") {
count++
}
}
if count != 1 {
t.Errorf("Expected stanza line not found or appeared more than once in updated string. line=amqsget, Config:%s\n", strings.Join(atConfig, "\n"))
}
}
func TestIniFile3Update(t *testing.T) {
i := 0
iniFileBytes, err := ioutil.ReadFile("test3qm.ini")
if err != nil {
@@ -163,6 +125,9 @@ func TestIniFile3Update(t *testing.T) {
t.Errorf("Expected stanza file not found: mqat.ini\n")
}
qmConfigStr := strings.Join(qmConfig, "\n")
atConfigStr := strings.Join(atConfig, "\n")
scanner := bufio.NewScanner(strings.NewReader(userconfig))
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
@@ -170,19 +135,63 @@ func TestIniFile3Update(t *testing.T) {
i++
//first 20 lines of test3qm.ini shall go into qm.ini file and rest into mqat.ini file.
if i < 20 {
if !strings.Contains(qmConfig, line) {
t.Errorf("Expected stanza line not found in updated string. line=%s\n, Stanza:%s\n", line, qmConfig)
if !strings.Contains(qmConfigStr, strings.TrimSpace(line)) {
t.Errorf("Expected stanza line not found in updated string. line=%s\n, Stanza:%s\n", line, qmConfigStr)
}
} else if i > 20 {
if !strings.Contains(atConfig, line) {
t.Errorf("Expected stanza line not found in updated string. line=%s\n, Stanza:%s\n", line, qmConfig)
if !strings.Contains(atConfigStr, line) {
t.Errorf("Expected stanza line not found in updated string. line=%s\n, Stanza:%s\n", line, atConfigStr)
}
}
}
}
func TestIniFile4Update(t *testing.T) {
iniFileBytes, err := ioutil.ReadFile("test1qm.ini")
if err != nil {
t.Errorf("Unexpected error: [%s]\n", err.Error())
}
//First merge
userconfig := string(iniFileBytes)
qmConfig, atConfig, err := PrepareConfigStanzasToWrite(userconfig)
if err != nil {
t.Errorf("Unexpected error: [%s]\n", err.Error())
}
if len(atConfig) == 0 {
t.Errorf("Expected stanza file not found: mqat.ini\n")
}
if len(qmConfig) == 0 {
t.Errorf("Expected stanza file not found: qm.ini\n")
}
//second merge.
qmConfig, atConfig, err = PrepareConfigStanzasToWrite(userconfig)
if err != nil {
t.Errorf("Unexpected error: [%s]\n", err.Error())
}
if len(atConfig) == 0 {
t.Errorf("Expected stanza file not found: mqat.ini\n")
}
if len(qmConfig) == 0 {
t.Errorf("Expected stanza file not found: qm.ini\n")
}
count := 0
//we just did a double merge, however we want this line to be present exactly one.
for _, item := range qmConfig {
item = strings.TrimSpace(item)
if strings.Contains(item, "mylib") {
count++
}
}
if count != 1 {
t.Errorf("Expected stanza line not found or appeared more than once in updated string. line=mylib\n config=%s\n count=%d\n", strings.Join(qmConfig, "\n"), count)
}
}
func checkReturns(stanza string, isqmini bool, shouldexist bool, t *testing.T) {
exists, filename := ValidateStanzaToWrite(stanza)
if exists != shouldexist {
t.Errorf("Stanza should exist %t but found was %t", shouldexist, exists)
@@ -200,3 +209,48 @@ func checkReturns(stanza string, isqmini bool, shouldexist bool, t *testing.T) {
}
}
}
var writeFileIfChangedTests = []struct {
before []byte
after []byte
same bool
}{
{[]byte("ABC€"), []byte("ABC€"), true},
{[]byte("ABC€"), []byte("ABC$"), false},
{[]byte("ABC€"), []byte("BBC€"), false},
}
func TestWriteFileIfChanged(t *testing.T) {
tmpFile := filepath.Join(os.TempDir(), t.Name())
t.Logf("Using temp file %v", tmpFile)
for i, table := range writeFileIfChangedTests {
t.Run(fmt.Sprintf("%v", i), func(t *testing.T) {
err := ioutil.WriteFile(tmpFile, table.before, 0600)
time.Sleep(time.Second * 1)
defer os.Remove(tmpFile)
fi, err := os.Stat(tmpFile)
if err != nil {
t.Fatal(err)
}
beforeMod := fi.ModTime()
err = writeFileIfChanged(tmpFile, table.after, 0600)
if err != nil {
t.Error(err)
}
fi, err = os.Stat(tmpFile)
if err != nil {
t.Error(err)
}
afterMod := fi.ModTime()
if table.same {
if beforeMod != afterMod {
t.Errorf("Expected file timestamps to be the same (%v); got %v", beforeMod, afterMod)
}
} else {
if beforeMod == afterMod {
t.Errorf("Expected file timestamp to be different got %v and %v", beforeMod, afterMod)
}
}
})
}
}

View File

@@ -1,5 +1,5 @@
ApiExitLocal:   
Sequence=1
Function=EntryPoint
Module=/opt/mylibs/mylib.so
Module=/opt/mqm/exitlib.so
Name=mylib

View File

@@ -1,8 +1,8 @@
ApiExitLocal:   
Sequence=1
Function=EntryPoint
Module=/opt/MQOpenTracing/MQOpenTracingExit.so
Name=MQOpenTracingExit
Module=/opt/foo/foo.so
Name=FooExit
Channels:
MQIBindType=FASTPATH
Log:

View File

@@ -23,7 +23,7 @@ import (
"text/template"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/pkg/logger"
)
// ProcessTemplateFile takes a Go templateFile, and processes it with the

View File

@@ -35,8 +35,8 @@ import (
pkcs "software.sslmate.com/src/go-pkcs12"
)
// IntegrationDefaultLabel is the default certificate label used by Cloud Integration Platform
const IntegrationDefaultLabel = "default"
// WebDefaultLabel is the default certificate label for the web console
const WebDefaultLabel = "default"
// P12TrustStoreName is the name of the PKCS#12 truststore used by the webconsole
const P12TrustStoreName = "trust.p12"

View File

@@ -12,17 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
image: ibmcom/mq:9.1.3.0-r2
image: ibmcom/mq:9.1.3.0-r3
manifests:
- image: ibmcom/mq:9.1.3.0-r2-amd64
- image: ibmcom/mq:9.1.3.0-r3-amd64
platform:
architecture: amd64
os: linux
- image: ibmcom/mq:9.1.3.0-r2-ppc64le
- image: ibmcom/mq:9.1.3.0-r3-ppc64le
platform:
architecture: ppc64le
os: linux
- image: ibmcom/mq:9.1.3.0-r2-s390x
- image: ibmcom/mq:9.1.3.0-r3-s390x
platform:
architecture: s390x
os: linux

View File

@@ -12,12 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# Fedora includes more recent versions of buildah (need buildah V1.7 to get
# multi-stage builds to work properly)
FROM docker.io/fedora:29
RUN yum install -y buildah
COPY build.sh /usr/local/bin/build
RUN chmod +x /usr/local/bin/build
ENV STORAGE_DRIVER=vfs
ENV BUILDAH_ISOLATION=chroot
ENTRYPOINT ["build"]
image: ibmcom/mq:9.1.4.0-r1
manifests:
- image: ibmcom/mq:9.1.4.0-r1-amd64
platform:
architecture: amd64
os: linux
- image: ibmcom/mq:9.1.4.0-r1-ppc64le
platform:
architecture: ppc64le
os: linux
- image: ibmcom/mq:9.1.4.0-r1-s390x
platform:
architecture: s390x
os: linux

View File

@@ -14,15 +14,15 @@
image: ibmcom/mq:latest
manifests:
- image: ibmcom/mq:9.1.3.0-r2-amd64
- image: ibmcom/mq:9.1.4.0-r1-amd64
platform:
architecture: amd64
os: linux
- image: ibmcom/mq:9.1.3.0-r2-ppc64le
- image: ibmcom/mq:9.1.4.0-r1-ppc64le
platform:
architecture: ppc64le
os: linux
- image: ibmcom/mq:9.1.3.0-r2-s390x
- image: ibmcom/mq:9.1.4.0-r1-s390x
platform:
architecture: s390x
os: linux

View File

@@ -12,17 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
image: ibmcorp/mqadvanced-server-dev:9.1.3.0-r2
image: ibmcorp/mqadvanced-server-dev:9.1.3.0-r3
manifests:
- image: ibmcorp/mqadvanced-server-dev:9.1.3.0-r2-amd64
- image: ibmcorp/mqadvanced-server-dev:9.1.3.0-r3-amd64
platform:
architecture: amd64
os: linux
- image: ibmcorp/mqadvanced-server-dev:9.1.3.0-r2-ppc64le
- image: ibmcorp/mqadvanced-server-dev:9.1.3.0-r3-ppc64le
platform:
architecture: ppc64le
os: linux
- image: ibmcorp/mqadvanced-server-dev:9.1.3.0-r2-s390x
- image: ibmcorp/mqadvanced-server-dev:9.1.3.0-r3-s390x
platform:
architecture: s390x
os: linux

View File

@@ -1,7 +1,4 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2018, 2019
#
# © Copyright IBM Corporation 2019
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,16 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# Copy in licenses from installed packages
set -e
rm -f /licenses/installed_package_notices
for p in $(rpm -qa | sort)
do
rpm -qi $p >> /licenses/installed_package_notices
printf "\n" >> /licenses/installed_package_notices
done
chmod 0444 /licenses/installed_package_notices
image: ibmcorp/mqadvanced-server-dev:9.1.4.0-r1
manifests:
- image: ibmcorp/mqadvanced-server-dev:9.1.4.0-r1-amd64
platform:
architecture: amd64
os: linux
- image: ibmcorp/mqadvanced-server-dev:9.1.4.0-r1-ppc64le
platform:
architecture: ppc64le
os: linux
- image: ibmcorp/mqadvanced-server-dev:9.1.4.0-r1-s390x
platform:
architecture: s390x
os: linux

View File

@@ -1,5 +0,0 @@
# RHEL-based container build
Build scripts for building a container image based on Red Hat Enterprise Linux (RHEL), using the [`buildah`](https://github.com/containers/buildah) tool. buildah is supported on RHEL V7.5 and greater.
WARNING: The code in this directory is not currently in use, pending deletion. The MQ container is now built using a Red Hat UBI image, using "podman build".

View File

@@ -1,49 +0,0 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2018, 2019
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Builds and tests the golang programs used by the MQ image.
set -ex
# Handle a GOPATH with multiple entries (just choose the first one)
IFS=':' read -ra DIR <<< "$GOPATH"
cd ${DIR[0]}/src/github.com/ibm-messaging/mq-container/
# Build and test the Go code
mkdir -p build
cd build
rm -f chkmqready chkmqhealthy runmqserver runmqdevserver
if [ "$MQDEV" = "TRUE" ]; then
# Build and test the Go code
go build -ldflags "-X \"main.ImageCreated=$(date --iso-8601=seconds)\" -X \"main.ImageRevision=$IMAGE_REVISION\" -X \"main.ImageSource=$IMAGE_SOURCE\"" --tags 'mqdev' ../cmd/runmqserver/
go build ../cmd/runmqdevserver/
else
go build -ldflags "-X \"main.ImageCreated=$(date --iso-8601=seconds)\" -X \"main.ImageRevision=$IMAGE_REVISION\" -X \"main.ImageSource=$IMAGE_SOURCE\"" ../cmd/runmqserver/
fi
go build ../cmd/chkmqready/
go build ../cmd/chkmqhealthy/
go test -v ../cmd/runmqserver/
go test -v ../cmd/chkmqready/
go test -v ../cmd/chkmqhealthy/
if [ "$MQDEV" = "TRUE" ]; then
go test -v ../cmd/runmqdevserver
fi
go test -v ../internal/...
go vet ../cmd/... ../internal/...

View File

@@ -1,49 +0,0 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2018, 2019
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Run the Go build script inside the Go container, mounting the source
# directory in
function usage {
echo "Usage: $0 TAG DevModeFlag"
exit 20
}
if [ "$#" -ne 2 ]; then
echo "ERROR: Invalid number of parameters"
usage
fi
readonly tag=$1
readonly dev=$2
IMAGE_REVISION=${IMAGE_REVISION:="Not Applicable"}
IMAGE_SOURCE=${IMAGE_SOURCE:="Not Applicable"}
# Run the build in a container
# Note the ":Z" on the volume is to allow the container to access the files when SELinux is enabled
# Note the "podman" network is used explicitly, to avoid problems other CNI networks (e.g. on an OpenShift node)
podman run \
--volume ${PWD}:/opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/:Z \
--env IMAGE_REVISION="$IMAGE_REVISION" \
--env IMAGE_SOURCE="$IMAGE_SOURCE" \
--env MQDEV=${dev} \
--user $(id -u) \
--rm \
--network podman \
${tag} \
bash -c "cd /opt/app-root/src/go/src/github.com/ibm-messaging/mq-container/ && ./mq-advanced-server-rhel/go-build.sh"

View File

@@ -1,88 +0,0 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2018, 2019
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Install one or more MQ components into a buildah container
set -ex
function usage {
echo "Usage: $0 MQContainer MountLocation ARCHIVENAME PACKAGES"
exit 20
}
if [ "$#" -ne 4 ]; then
echo "ERROR: Invalid number of parameters"
usage
fi
readonly ctr_mq=$1
readonly mnt_mq=$2
readonly archive=$3
readonly mq_packages=$4
readonly dir_extract=/tmp/extract
readonly mqm_uid=888
readonly mqm_gid=888
if [ ! -d ${dir_extract}/MQServer ]; then
mkdir -p ${dir_extract}
echo Extracting $archive
tar -zxf $archive -C ${dir_extract}
echo Extracting finished
fi
# Accept the MQ license
buildah run --user root --volume ${dir_extract}:/mnt/mq-download:Z $ctr_mq -- /mnt/mq-download/MQServer/mqlicense.sh -text_only -accept
# Install MQ
buildah run --user root --volume ${dir_extract}:/mnt/mq-download:Z $ctr_mq -- bash -c "cd /mnt/mq-download/MQServer && rpm -ivh $mq_packages"
rm -rf ${dir_extract}/MQServer
# Remove 32-bit libraries from 64-bit container
find $mnt_mq/opt/mqm $mnt_mq/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 $mnt_mq/opt/mqm -name '*.tar.gz' -delete
# Recommended: Set the default MQ installation (makes the MQ commands available on the PATH)
buildah run $ctr_mq -- /opt/mqm/bin/setmqinst -p /opt/mqm -i
mkdir -p $mnt_mq/run/runmqserver
chown ${mqm_uid}:${mqm_gid} $mnt_mq/run/runmqserver
# Remove the directory structure under /var/mqm which was created by the installer
rm -rf $mnt_mq/var/mqm
# Create the mount point for volumes, ensuring MQ has permissions to all directories
mkdir -p $mnt_mq/mnt/mqm
install --directory --mode 0775 --owner ${mqm_uid} --group root $mnt_mq/mnt
install --directory --mode 0775 --owner ${mqm_uid} --group root $mnt_mq/mnt/mqm
install --directory --mode 0775 --owner ${mqm_uid} --group root $mnt_mq/mnt/mqm/data
# Create the directory for MQ configuration files
mkdir -p /etc/mqm
install --directory --mode 0775 --owner ${mqm_uid} --group root $mnt_mq/etc/mqm
# Create a symlink for /var/mqm -> /mnt/mqm/data
buildah run --user root $ctr_mq -- ln -s /mnt/mqm/data /var/mqm
# Optional: Set these values for the IBM Cloud Vulnerability Report
sed -i 's/PASS_MAX_DAYS\t99999/PASS_MAX_DAYS\t90/' $mnt_mq/etc/login.defs
sed -i 's/PASS_MIN_DAYS\t0/PASS_MIN_DAYS\t1/' $mnt_mq/etc/login.defs
sed -i 's/password\t\[success=1 default=ignore\]\tpam_unix\.so obscure sha512/password\t[success=1 default=ignore]\tpam_unix.so obscure sha512 minlen=8/' $mnt_mq/etc/pam.d/password-auth
buildah run $ctr_mq -- cp -rs /opt/mqm/licenses/ /

View File

@@ -1,173 +0,0 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2018, 2019
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Build a RHEL image, using the buildah tool
set -x
set -e
function usage {
echo "Usage: $0 ARCHIVE-NAME PACKAGES TAG VERSION MQDevFlag"
exit 20
}
if [ "$#" -ne 5 ]; then
echo "ERROR: Invalid number of parameters"
usage
fi
###############################################################################
# Setup MQ server working container
###############################################################################
# Use RHEL 7 minimal container (which doesn't include things like Python or Yum)
readonly ctr_mq=$(buildah from rhel7-minimal)
if [ -z "$ctr_mq" ]
then
echo "ERROR: ctr_mq is empty. Check above output for errors"
exit 50
fi
readonly mnt_mq=$(buildah mount $ctr_mq)
if [ -z "$mnt_mq" ]
then
echo "ERROR: mnt_mq is empty. Check above output for errors"
exit 50
fi
readonly archive=downloads/$1
readonly packages=$2
readonly tag=$3
readonly version=$4
readonly mqdev=$5
readonly mqm_uid=888
readonly mqm_gid=888
###############################################################################
# Install MQ server
###############################################################################
microdnf_opts="--nodocs"
# Check whether the host is registered with Red Hat
if subscription-manager status ; then
# Host is subscribed, but the minimal image has no enabled repos
# Note that the "bc" package is the only one in "extras"
microdnf_opts="${microdnf_opts} --enablerepo=rhel-7-server-rpms --enablerepo=rhel-7-server-extras-rpms"
else
# Use the Yum repositories configured on the host
cp -R /etc/yum.repos.d/* ${mnt_mq}/etc/yum.repos.d/
fi
buildah run ${ctr_mq} -- microdnf ${microdnf_opts} install \
bash \
bc \
coreutils \
file \
findutils \
gawk \
glibc-common \
grep \
passwd \
procps-ng \
sed \
shadow-utils \
tar \
util-linux \
which
# Install "sudo" if using MQ Advanced for Developers
if [ "$mqdev" = "TRUE" ]; then
buildah run ${ctr_mq} -- microdnf ${microdnf_opts} install sudo
fi
# Clean up cached files
buildah run ${ctr_mq} -- microdnf ${microdnf_opts} clean all
rm -rf ${mnt_mq}/etc/yum.repos.d/*
buildah run --user root $ctr_mq -- groupadd --system --gid ${mqm_gid} mqm
buildah run --user root $ctr_mq -- useradd --system --uid ${mqm_uid} --gid mqm --groups 0 mqm
# Install MQ server packages into the MQ builder image
./mq-advanced-server-rhel/install-mq-rhel.sh ${ctr_mq} "${mnt_mq}" "${archive}" "${packages}"
# Create the directory for MQ configuration files
mkdir -p ${mnt_mq}/etc/mqm
chown ${mqm_uid}:${mqm_gid} ${mnt_mq}/etc/mqm
# Install the Go binaries into the image
install --mode 0750 --owner ${mqm_uid} --group 0 ./build/runmqserver ${mnt_mq}/usr/local/bin/
install --mode 6750 --owner ${mqm_uid} --group 0 ./build/chk* ${mnt_mq}/usr/local/bin/
install --mode 0750 --owner ${mqm_uid} --group 0 ./NOTICES.txt ${mnt_mq}/opt/mqm/licenses/notices-container.txt
install --directory --mode 0775 --owner ${mqm_uid} --group 0 ${mnt_mq}/run/runmqserver
buildah run --user root $ctr_mq -- touch /run/termination-log
buildah run --user root $ctr_mq -- chown mqm:root /run/termination-log
buildah run --user root $ctr_mq -- chmod 0660 /run/termination-log
# Copy in licenses from installed packages
install --mode 0550 --owner root --group root ./mq-advanced-server-rhel/writePackages.sh ${mnt_mq}/usr/local/bin/writePackages
buildah run --user root $ctr_mq -- /usr/local/bin/writePackages
# Copy web XML files
cp -R web ${mnt_mq}/etc/mqm/web
# Make "mqm" the owner of all the config files
chown --recursive ${mqm_uid}:${mqm_gid} ${mnt_mq}/etc/mqm/*
chmod --recursive 0750 ${mnt_mq}/etc/mqm/*
###############################################################################
# Final Buildah commands
###############################################################################
if [ "$mqdev" = "TRUE" ]; then
OSTAG="mq messaging developer"
DISNAME="IBM MQ Advanced Server Developer Edition"
PID="98102d16795c4263ad9ca075190a2d4d"
else
OSTAG="mq messaging"
DISNAME="IBM MQ Advanced Server"
PID="4486e8c4cc9146fd9b3ce1f14a2dfc5b"
fi
buildah config \
--port 1414/tcp \
--port 9157/tcp \
--port 9443/tcp \
--os linux \
--label architecture=amd64 \
--label io.openshift.tags="$OSTAG" \
--label io.k8s.display-name="$DISNAME" \
--label io.k8s.description="IBM MQ is messaging middleware that simplifies and accelerates the integration of diverse applications and business data across multiple platforms. It uses message queues to facilitate the exchanges of information and offers a single messaging solution for cloud, mobile, Internet of Things (IoT) and on-premises environments." \
--label name="${tag%:*}" \
--label vendor="IBM" \
--label version="$version" \
--label release="1" \
--label run="docker run -d -e LICENSE=accept --name ibm-mq ${tag%:*}" \
--label summary="$DISNAME" \
--label description="IBM MQ is messaging middleware that simplifies and accelerates the integration of diverse applications and business data across multiple platforms. It uses message queues to facilitate the exchanges of information and offers a single messaging solution for cloud, mobile, Internet of Things (IoT) and on-premises environments." \
--label IBM_PRODUCT_ID="$PID" \
--label IBM_PRODUCT_NAME="$DISNAME" \
--label IBM_PRODUCT_VERSION="$version" \
--env AMQ_ADDITIONAL_JSON_LOG=1 \
--env LANG=en_US.UTF-8 \
--env LOG_FORMAT=basic \
--entrypoint runmqserver \
--user ${mqm_uid} \
$ctr_mq
buildah unmount $ctr_mq
buildah commit $ctr_mq $tag
buildah rm $ctr_mq

View File

@@ -1,65 +0,0 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2018, 2019
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Build a RHEL image for building Go programs which use MQ
set -ex
function usage {
echo "Usage: $0 REDIST-ARCHIVE-NAME TAG"
exit 20
}
if [ "$#" -ne 2 ]; then
echo "ERROR: Invalid number of parameters"
usage
fi
readonly mq_redist_archive=downloads/$1
readonly tag=$2
# Use Red Hat's Go toolset image as the base
readonly ctr_mq=$(buildah from devtools/go-toolset-7-rhel7)
if [ -z "$ctr_mq" ]
then
echo "ERROR: ctr_mq is empty. Check above output for errors"
exit 50
fi
readonly mnt_mq_go=$(buildah mount $ctr_mq)
if [ -z "$mnt_mq_go" ]
then
echo "ERROR: mnt_mq_go is empty. Check above output for errors"
exit 50
fi
# Install the MQ redistributable client (including header files) into the Go builder image
mkdir -p ${mnt_mq_go}/opt/mqm
tar -xzf ${mq_redist_archive} -C ${mnt_mq_go}/opt/mqm
# Clean up Yum files
rm -rf ${mnt_mq_go}/etc/yum.repos.d/*
buildah unmount ${ctr_mq}
# Set environment variables for MQ/Go compilation
buildah config \
--os linux \
--env CGO_CFLAGS="-I/opt/mqm/inc/" \
--env CGO_LDFLAGS_ALLOW="-Wl,-rpath.*" \
${ctr_mq}
buildah commit ${ctr_mq} ${tag}
buildah rm ${ctr_mq}

View File

@@ -1,121 +0,0 @@
#!/bin/bash
# -*- mode: sh -*-
# © Copyright IBM Corporation 2018, 2019
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Build a RHEL image of MQ Advanced for Developers, using the buildah tool
set -x
set -e
function usage {
echo "Usage: $0 BASETAG TAG VERSION"
exit 20
}
if [ "$#" -ne 3 ]; then
echo "ERROR: Invalid number of parameters"
usage
fi
###############################################################################
# Setup MQ server working container
###############################################################################
# Use a "scratch" container, so the resulting image has minimal files
# Resulting image won't have yum, for example
readonly basetag=$1
readonly ctr_mq=$(buildah from $basetag)
if [ -z "$ctr_mq" ]
then
echo "ERROR: ctr_mq is empty. Check above output for errors"
exit 50
fi
readonly mnt_mq=$(buildah mount $ctr_mq)
if [ -z "$mnt_mq" ]
then
echo "ERROR: mnt_mq is empty. Check above output for errors"
exit 50
fi
readonly tag=$2
readonly version=$3
readonly mqm_uid=888
readonly mqm_gid=888
# 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.
echo "mqm ALL = NOPASSWD: /usr/sbin/chpasswd" > $mnt_mq/etc/sudoers.d/mq-dev-config
# Run these commands inside the container so that the SELinux context is handled correctly
buildah run --user root $ctr_mq -- useradd --gid mqm admin
buildah run --user root $ctr_mq -- groupadd --system mqclient
buildah run --user root $ctr_mq -- useradd --gid mqclient app
buildah run --user root $ctr_mq -- bash -c "echo admin:passw0rd | chpasswd"
mkdir --parents $mnt_mq/run/runmqdevserver
chown ${mqm_uid}:${mqm_gid} $mnt_mq/run/runmqdevserver
# Copy runmqdevserver program
install --mode 0750 --owner ${mqm_uid} --group ${mqm_gid} ./build/runmqdevserver ${mnt_mq}/usr/local/bin/
install --directory --mode 0775 --owner ${mqm_uid} --group 0 ${mnt_mq}/run/runmqdevserver
# Copy template files
cp ./incubating/mqadvanced-server-dev/*.tpl ${mnt_mq}/etc/mqm/
# Copy web XML files for default developer configuration
cp -R incubating/mqadvanced-server-dev/web/ ${mnt_mq}/etc/mqm/web
# Make "mqm" the owner of all the config files
chown --recursive ${mqm_uid}:${mqm_gid} ${mnt_mq}/etc/mqm/*
chmod --recursive 0750 ${mnt_mq}/etc/mqm/*
###############################################################################
# Final Buildah commands
###############################################################################
buildah config \
--port 1414/tcp \
--port 9157/tcp \
--port 9443/tcp \
--os linux \
--label architecture=amd64 \
--label io.openshift.tags="mq messaging developer" \
--label io.k8s.display-name="IBM MQ Advanced Server Developer Edition" \
--label io.k8s.description="IBM MQ is messaging middleware that simplifies and accelerates the integration of diverse applications and business data across multiple platforms. It uses message queues to facilitate the exchanges of information and offers a single messaging solution for cloud, mobile, Internet of Things (IoT) and on-premises environments." \
--label name="${tag%:*}" \
--label vendor="IBM" \
--label version="$version" \
--label release="1" \
--label run="docker run -d -e LICENSE=accept --name ibm-mq-dev ${tag%:*}" \
--label summary="IBM MQ Advanced Server Developer Edition" \
--label description="IBM MQ is messaging middleware that simplifies and accelerates the integration of diverse applications and business data across multiple platforms. It uses message queues to facilitate the exchanges of information and offers a single messaging solution for cloud, mobile, Internet of Things (IoT) and on-premises environments." \
--label IBM_PRODUCT_ID="98102d16795c4263ad9ca075190a2d4d" \
--label IBM_PRODUCT_NAME="IBM MQ Advanced Server Developer Edition" \
--label IBM_PRODUCT_VERSION="$version" \
--env AMQ_ADDITIONAL_JSON_LOG=1 \
--env LANG=en_US.UTF-8 \
--env LOG_FORMAT=basic \
--env MQ_ADMIN_PASSWORD=passw0rd \
--env MQ_DEV=true \
--entrypoint runmqdevserver \
--user ${mqm_uid} \
$ctr_mq
buildah unmount $ctr_mq
buildah commit $ctr_mq $tag
buildah rm $ctr_mq

View File

@@ -22,8 +22,8 @@ import (
"strings"
"github.com/ibm-messaging/mq-container/internal/containerruntime"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/internal/user"
"github.com/ibm-messaging/mq-container/pkg/logger"
)
// LogContainerDetails logs details about the container runtime

View File

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

92
pkg/mqini/mqini.go Normal file
View File

@@ -0,0 +1,92 @@
/*
© Copyright IBM Corporation 2018, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package mqini provides information about queue managers
package mqini
import (
"bufio"
"errors"
"os"
"path/filepath"
"strings"
"github.com/ibm-messaging/mq-container/internal/command"
)
// QueueManager describe high-level configuration information for a queue manager
type QueueManager struct {
Name string
Prefix string
Directory string
DataPath string
InstallationName string
}
// getQueueManagerFromStanza parses a queue manager stanza
func getQueueManagerFromStanza(stanza string) (*QueueManager, error) {
scanner := bufio.NewScanner(strings.NewReader(stanza))
qm := QueueManager{}
for scanner.Scan() {
l := scanner.Text()
l = strings.TrimSpace(l)
t := strings.Split(l, "=")
switch t[0] {
case "Name":
qm.Name = t[1]
case "Prefix":
qm.Prefix = t[1]
case "Directory":
qm.Directory = t[1]
case "DataPath":
qm.DataPath = t[1]
case "InstallationName":
qm.InstallationName = t[1]
}
}
return &qm, scanner.Err()
}
// GetQueueManager returns queue manager configuration information
func GetQueueManager(name string) (*QueueManager, error) {
_, err := os.Stat("/var/mqm/mqs.ini")
if err != nil {
// Don't run dspmqinf, which will generate an FDC if mqs.ini isn't there yet
return nil, errors.New("dspmqinf should not be run before crtmqdir")
}
// dspmqinf essentially returns a subset of mqs.ini, but it's simpler to parse
out, _, err := command.Run("dspmqinf", "-o", "stanza", name)
if err != nil {
return nil, err
}
return getQueueManagerFromStanza(out)
}
// GetErrorLogDirectory returns the directory holding the error logs for the
// specified queue manager
func GetErrorLogDirectory(qm *QueueManager) string {
return filepath.Join(GetDataDirectory(qm), "errors")
}
// GetDataDirectory returns the data directory for the specified queue manager
func GetDataDirectory(qm *QueueManager) string {
if qm.DataPath != "" {
// Data path has been set explicitly (e.g. for multi-instance queue manager)
return qm.DataPath
} else {
return filepath.Join(qm.Prefix, "qmgrs", qm.Directory)
}
}

64
pkg/mqini/mqini_test.go Normal file
View File

@@ -0,0 +1,64 @@
/*
© Copyright IBM Corporation 2018, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mqini
import (
"io/ioutil"
"testing"
)
var getQueueManagerTests = []struct {
file string
name string
prefix string
directory string
errorLogDir string
}{
{"dspmqinf1.txt", "foo", "/var/mqm", "foo", "/var/mqm/qmgrs/foo/errors"},
{"dspmqinf2.txt", "a/b", "/var/mqm", "a&b", "/var/mqm/qmgrs/a&b/errors"},
{"dspmqinf3.txt", "..", "/var/mqm", "!!", "/var/mqm/qmgrs/!!/errors"},
}
func TestGetQueueManager(t *testing.T) {
for _, table := range getQueueManagerTests {
t.Run(table.file, func(t *testing.T) {
b, err := ioutil.ReadFile(table.file)
if err != nil {
t.Fatal(err)
}
qm, err := getQueueManagerFromStanza(string(b))
if err != nil {
t.Fatal(err)
}
t.Logf("%#v", qm)
if qm.Name != table.name {
t.Errorf("Expected name=%v; got %v", table.name, qm.Name)
}
if qm.Prefix != table.prefix {
t.Errorf("Expected prefix=%v; got %v", table.prefix, qm.Prefix)
}
if qm.Directory != table.directory {
t.Errorf("Expected directory=%v; got %v", table.directory, qm.Directory)
}
// Test
d := GetErrorLogDirectory(qm)
if d != table.errorLogDir {
t.Errorf("Expected error log directory=%v; got %v", table.errorLogDir, d)
}
})
}
}

View File

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

View File

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

View File

@@ -1,19 +0,0 @@
* © Copyright IBM Corporation 2017
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
DEFINE CHANNEL(PASSWORD.SVRCONN) CHLTYPE(SVRCONN) REPLACE
SET CHLAUTH(PASSWORD.SVRCONN) TYPE(BLOCKUSER) USERLIST('nobody') DESCR('Allow privileged users on this channel')
SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) DESCR('BackStop rule')
SET CHLAUTH(PASSWORD.SVRCONN) TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(CHANNEL) CHCKCLNT(REQUIRED)
ALTER AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS) AUTHTYPE(IDPWOS) ADOPTCTX(YES)

View File

@@ -1,15 +0,0 @@
* © Copyright IBM Corporation 2017
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
REFRESH SECURITY TYPE(CONNAUTH)

View File

@@ -1,18 +0,0 @@
# © Copyright IBM Corporation 2015, 2017
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM mqadvanced
RUN useradd alice -G mqm && \
echo alice:passw0rd | chpasswd
COPY *.mqsc /etc/mqm/

View File

@@ -380,6 +380,78 @@ func runContainerOneShotWithVolume(t *testing.T, cli *client.Client, bind string
return rc, out
}
func startMultiVolumeQueueManager(t *testing.T, cli *client.Client, dataVol bool, qmsharedlogs string, qmshareddata string, env []string) (error, string, string) {
id := strconv.FormatInt(time.Now().UnixNano(), 10)
qmdata := createVolume(t, cli, id)
containerConfig := container.Config{
Image: imageName(),
Env: env,
}
var hostConfig container.HostConfig
if !dataVol {
hostConfig = container.HostConfig{}
} else if qmsharedlogs == "" && qmshareddata == "" {
hostConfig = getHostConfig(t, 1, "", "", qmdata.Name)
} else if qmsharedlogs == "" {
hostConfig = getHostConfig(t, 2, "", qmshareddata, qmdata.Name)
} else if qmshareddata == "" {
hostConfig = getHostConfig(t, 3, qmsharedlogs, "", qmdata.Name)
} else {
hostConfig = getHostConfig(t, 4, qmsharedlogs, qmshareddata, qmdata.Name)
}
networkingConfig := network.NetworkingConfig{}
qm, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name()+id)
if err != nil {
return err, "", ""
}
startContainer(t, cli, qm.ID)
return nil, qm.ID, qmdata.Name
}
func getHostConfig(t *testing.T, mounts int, qmsharedlogs string, qmshareddata string, qmdata string) container.HostConfig {
var hostConfig container.HostConfig
switch mounts {
case 1:
hostConfig = container.HostConfig{
Binds: []string{
coverageBind(t),
qmdata + ":/mnt/mqm",
},
}
case 2:
hostConfig = container.HostConfig{
Binds: []string{
coverageBind(t),
qmdata + ":/mnt/mqm",
qmshareddata + ":/mnt/mqm-data",
},
}
case 3:
hostConfig = container.HostConfig{
Binds: []string{
coverageBind(t),
qmdata + ":/mnt/mqm",
qmsharedlogs + ":/mnt/mqm-log",
},
}
case 4:
hostConfig = container.HostConfig{
Binds: []string{
coverageBind(t),
qmdata + ":/mnt/mqm",
qmsharedlogs + ":/mnt/mqm-log",
qmshareddata + ":/mnt/mqm-data",
},
}
}
return hostConfig
}
func startContainer(t *testing.T, cli *client.Client, ID string) {
t.Logf("Starting container: %v", ID)
startOptions := types.ContainerStartOptions{}

View File

@@ -19,13 +19,10 @@ import (
"context"
"fmt"
"regexp"
"strconv"
"strings"
"testing"
"time"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
)
@@ -65,78 +62,6 @@ func singleMultiInstanceQueueManager(t *testing.T, cli *client.Client, qmsharedl
qmsChannel <- QMChan{QMId: qmId, QMData: qmData}
}
func getHostConfig(t *testing.T, mounts int, qmsharedlogs string, qmshareddata string, qmdata string) container.HostConfig {
var hostConfig container.HostConfig
switch mounts {
case 1:
hostConfig = container.HostConfig{
Binds: []string{
coverageBind(t),
qmdata + ":/mnt/mqm",
},
}
case 2:
hostConfig = container.HostConfig{
Binds: []string{
coverageBind(t),
qmdata + ":/mnt/mqm",
qmshareddata + ":/mnt/mqm-data",
},
}
case 3:
hostConfig = container.HostConfig{
Binds: []string{
coverageBind(t),
qmdata + ":/mnt/mqm",
qmsharedlogs + ":/mnt/mqm-log",
},
}
case 4:
hostConfig = container.HostConfig{
Binds: []string{
coverageBind(t),
qmdata + ":/mnt/mqm",
qmsharedlogs + ":/mnt/mqm-log",
qmshareddata + ":/mnt/mqm-data",
},
}
}
return hostConfig
}
func startMultiVolumeQueueManager(t *testing.T, cli *client.Client, dataVol bool, qmsharedlogs string, qmshareddata string, env []string) (error, string, string) {
id := strconv.FormatInt(time.Now().UnixNano(), 10)
qmdata := createVolume(t, cli, id)
containerConfig := container.Config{
Image: imageName(),
Env: env,
}
var hostConfig container.HostConfig
if !dataVol {
hostConfig = container.HostConfig{}
} else if qmsharedlogs == "" && qmshareddata == "" {
hostConfig = getHostConfig(t, 1, "", "", qmdata.Name)
} else if qmsharedlogs == "" {
hostConfig = getHostConfig(t, 2, "", qmshareddata, qmdata.Name)
} else if qmshareddata == "" {
hostConfig = getHostConfig(t, 3, qmsharedlogs, "", qmdata.Name)
} else {
hostConfig = getHostConfig(t, 4, qmsharedlogs, qmshareddata, qmdata.Name)
}
networkingConfig := network.NetworkingConfig{}
qm, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name()+id)
if err != nil {
return err, "", ""
}
startContainer(t, cli, qm.ID)
return nil, qm.ID, qmdata.Name
}
func getActiveStandbyQueueManager(t *testing.T, cli *client.Client, qm1aId string, qm1bId string) (error, string, string) {
qm1aStatus := getQueueManagerStatus(t, cli, qm1aId, "QM1")
qm1bStatus := getQueueManagerStatus(t, cli, qm1bId, "QM1")

View File

@@ -1,5 +1,6 @@
.classpath
.gradle
*.class
.project
.settings
bin

View File

@@ -26,25 +26,25 @@ limitations under the License.
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.0.5.0</version>
<version>9.1.3.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.2</version>
<version>5.5.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.2</version>
<version>5.5.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-console-standalone</artifactId>
<version>1.3.2</version>
<version>1.5.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>

29
travis-build-scripts/build.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
# © Copyright IBM Corporation 2019
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
echo 'Building Developer JMS test image...' && echo -en 'travis_fold:start:build-devjmstest\\r'
make build-devjmstest
echo -en 'travis_fold:end:build-devjmstest\\r'
echo 'Building Developer image...' && echo -en 'travis_fold:start:build-devserver\\r'
make build-devserver
echo -en 'travis_fold:end:build-devserver\\r'
if [ "$BUILD_ALL" = true ] ; then
echo 'Building Production image...' && echo -en 'travis_fold:start:build-advancedserver\\r'
make build-advancedserver
echo -en 'travis_fold:end:build-advancedserver\\r'
fi

54
travis-build-scripts/push.sh Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/bash
# © Copyright IBM Corporation 2019
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
echo "Not pushing as we are a pull request"
exit 0
fi
if [ ! -z $2 ]; then
export ARCH=$2
fi
function push_developer {
echo 'Pushing Developer image...' && echo -en 'travis_fold:start:push-devserver\\r'
make push-devserver
echo -en 'travis_fold:end:push-devserver\\r'
}
function push_production {
echo 'Pushing Production image...' && echo -en 'travis_fold:start:push-advancedserver\\r'
make push-advancedserver
echo -en 'travis_fold:end:push-advancedserver\\r'
}
# call relevant push function
if [ ! -z $1 ]; then
case "$1" in
developer) push_developer
;;
production) push_production
;;
*) echo "ERROR: Type ( developer | production ) must be passed to push.sh"
exit 1
;;
esac
else
echo "ERROR: Type ( developer | production ) must be passed to push.sh"
exit 1
fi

124
travis-build-scripts/release.sh Executable file
View File

@@ -0,0 +1,124 @@
#!/bin/bash
# © Copyright IBM Corporation 2019
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
# staging or production
TYPE=""
MANIFEST_FILE=manifest-9.1.4.yaml
# set type of release
if [ ! -z $1 ]; then
case "$1" in
staging) TYPE=$1
;;
production) TYPE=$1
;;
*) echo "ERROR: Release type ( staging | production ) must passed to release.sh"
exit 1
;;
esac
else
echo "ERROR: Release type ( staging | production ) must passed to release.sh"
exit 1
fi
## Pull all images from default repository
ARCH=amd64 make pull-devserver
ARCH=ppc64le make pull-devserver
ARCH=s390x make pull-devserver
ARCH=amd64 make pull-advancedserver
ARCH=ppc64le make pull-advancedserver
ARCH=s390x make pull-advancedserver
function set_staging_registry {
export MQ_DELIVERY_REGISTRY_HOSTNAME=$MQ_STAGING_REGISTRY
export MQ_DELIVERY_REGISTRY_NAMESPACE=""
export MQ_DELIVERY_REGISTRY_USER=$MQ_STAGING_REGISTRY_USER
export MQ_DELIVERY_REGISTRY_CREDENTIAL=$MQ_STAGING_REGISTRY_CREDENTIAL
}
function set_docker_hub {
export MQ_DELIVERY_REGISTRY_HOSTNAME=ibmcom
export MQ_DELIVERY_REGISTRY_NAMESPACE=""
export MQ_DELIVERY_REGISTRY_USER=$MQ_DOCKERHUB_REGISTRY_USER
export MQ_DELIVERY_REGISTRY_CREDENTIAL=$MQ_DOCKERHUB_REGISTRY_CREDENTIAL
}
function set_docker_store {
export MQ_DELIVERY_REGISTRY_HOSTNAME=ibmcorp
export MQ_DELIVERY_REGISTRY_NAMESPACE=""
export MQ_DELIVERY_REGISTRY_USER=$MQ_DOCKERHUB_REGISTRY_USER
export MQ_DELIVERY_REGISTRY_CREDENTIAL=$MQ_DOCKERHUB_REGISTRY_CREDENTIAL
}
function set_production_registry {
export MQ_DELIVERY_REGISTRY_HOSTNAME=$MQ_PRODUCTION_REGISTRY
export MQ_DELIVERY_REGISTRY_NAMESPACE=""
export MQ_DELIVERY_REGISTRY_USER=$MQ_PRODUCTION_REGISTRY_USER
export MQ_DELIVERY_REGISTRY_CREDENTIAL=$MQ_PRODUCTION_REGISTRY_CREDENTIAL
}
if [ "$TYPE" = "staging" ]; then
set_staging_registry
# push production images to staging registy
./travis-build-scripts/push.sh production amd64
./travis-build-scripts/push.sh production ppc64le
./travis-build-scripts/push.sh production s390x
elif [ "$TYPE" = "production" ]; then
# pull production images from staging
set_staging_registry
ARCH=amd64 make pull-advancedserver
ARCH=ppc64le make pull-advancedserver
ARCH=s390x make pull-advancedserver
# release developer images with fat manifests
set_docker_hub
ARCH=amd64 make push-devserver-dockerhub
ARCH=ppc64le make push-devserver-dockerhub
ARCH=s390x make push-devserver-dockerhub
curl -LO https://github.com/estesp/manifest-tool/releases/download/v0.9.0/manifest-tool-linux-amd64
chmod a+x manifest-tool-linux-amd64
docker login --username $MQ_DOCKERHUB_REGISTRY_USER --password $MQ_DOCKERHUB_REGISTRY_CREDENTIAL
./manifest-tool-linux-amd64 push from-spec manifests/dockerhub/$MANIFEST_FILE
./manifest-tool-linux-amd64 push from-spec manifests/dockerhub/manifest-latest.yaml
set_docker_store
ARCH=amd64 make push-devserver-dockerhub
ARCH=ppc64le make push-devserver-dockerhub
ARCH=s390x make push-devserver-dockerhub
docker login --username $MQ_DOCKERHUB_REGISTRY_USER --password $MQ_DOCKERHUB_REGISTRY_CREDENTIAL
./manifest-tool-linux-amd64 push from-spec manifests/dockerstore/$MANIFEST_FILE
# release production image
set_production_registry
./travis-build-scripts/push.sh production amd64
./travis-build-scripts/push.sh production ppc64le
./travis-build-scripts/push.sh production s390x
fi

36
travis-build-scripts/run.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
# © Copyright IBM Corporation 2019
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
if [ "$(uname -m)" = "x86_64" ] ; then export ARCH="amd64" ; else export ARCH=$(uname -m) ; fi
echo 'Downgrading Docker (if necessary)...' && echo -en 'travis_fold:start:docker-downgrade\\r'
eval "$DOCKER_DOWNGRADE"
echo -en 'travis_fold:end:docker-downgrade\\r'
## Build images
./travis-build-scripts/build.sh
## Test images
./travis-build-scripts/test.sh
## Push images
if [ "$BUILD_ALL" = true ] ; then
./travis-build-scripts/push.sh developer
./travis-build-scripts/push.sh production
fi

33
travis-build-scripts/test.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/bash
# © Copyright IBM Corporation 2019
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
echo 'Testing Developer image...' && echo -en 'travis_fold:start:test-devserver\\r'
make test-devserver
echo -en 'travis_fold:end:test-devserver\\r'
if [ "$BUILD_ALL" = true ] ; then
echo 'Testing Production image...' && echo -en 'travis_fold:start:test-advancedserver\\r'
make test-advancedserver
echo -en 'travis_fold:end:test-advancedserver\\r'
fi
echo 'Running gosec scan...' && echo -en 'travis_fold:start:gosec-scan\\r'
if [ "$ARCH" = "amd64" ] ; then
make gosec
else
echo "Gosec not available on ppc64le/s390x...skipping gosec scan"
fi
echo -en 'travis_fold:end:gosec-scan\\r'

View File

@@ -38,7 +38,6 @@
</openidConnectClient>
<variable name="httpHost" value="*"/>
<variable name="managementMode" value="externallyprovisioned"/>
<variable name="mqConsoleFrameAncestors" value="${env.MQ_HOSTS}"/>
<httpDispatcher enableWelcomePage="false" appOrContextRootMissingMessage='&lt;script&gt;document.location.href="/ibmmq/console";&lt;/script&gt;' />
<include location="tls.xml"/>
</server>

View File

@@ -2,6 +2,6 @@
<server>
<keyStore id="MQWebKeyStore" location="/run/runmqserver/tls/${env.AMQ_WEBKEYSTORE}" type="PKCS12" password="${env.AMQ_WEBKEYSTOREPW}"/>
<keyStore id="MQWebTrustStore" location="/run/runmqserver/tls/trust.p12" type="PKCS12" password="${env.AMQ_WEBKEYSTOREPW}"/>
<ssl id="thisSSLConfig" clientAuthenticationSupported="true" keyStoreRef="MQWebKeyStore" trustStoreRef="MQWebTrustStore" sslProtocol="TLSv1.2"/>
<ssl id="thisSSLConfig" clientAuthenticationSupported="true" keyStoreRef="MQWebKeyStore" trustStoreRef="${env.AMQ_WEBTRUSTSTOREREF}" sslProtocol="TLSv1.2"/>
<sslDefault sslRef="thisSSLConfig"/>
</server>