Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcdd76cb55 | ||
|
|
b234eb33c8 | ||
|
|
a5f4bb624c | ||
|
|
a2f2c1fe3b | ||
|
|
ba59442c1c | ||
|
|
e0c3b36b61 | ||
|
|
4dbdc42ca5 | ||
|
|
4a9fd2965c | ||
|
|
ffd72e8b31 | ||
|
|
8182fc43ab | ||
|
|
63a05ad8e4 | ||
|
|
f6b1ff2afd | ||
|
|
8d996081cc | ||
|
|
15d21c594f | ||
|
|
bfd37e39c5 | ||
|
|
3adb91d9bb | ||
|
|
391f4b66d7 | ||
|
|
a8a281db5a | ||
|
|
05d63e3cbf | ||
|
|
467324dd26 | ||
|
|
8abe55b86c | ||
|
|
8db26ebbb0 | ||
|
|
34831f08a0 | ||
|
|
e9a3b79a90 | ||
|
|
c0a4fb9318 | ||
|
|
fb53af6e7b | ||
|
|
65a36fd896 | ||
|
|
b04ef21071 | ||
|
|
6acc28125f | ||
|
|
08c533ed99 | ||
|
|
45384755bb | ||
|
|
67b2a690c5 | ||
|
|
cdc2d0b16b | ||
|
|
4a66728b79 | ||
|
|
64e4976a43 | ||
|
|
1a45834865 | ||
|
|
2ff55a381b | ||
|
|
7c05f4cbcb | ||
|
|
6e10f3ba76 | ||
|
|
e7b641cb1b | ||
|
|
37187e5199 | ||
|
|
f86dcb1c36 | ||
|
|
ae82196402 | ||
|
|
bebb8e1559 | ||
|
|
a1eda64df3 | ||
|
|
813e1ac2dc | ||
|
|
3111d48330 | ||
|
|
b8dcbde7b7 | ||
|
|
c74cc13a3b | ||
|
|
35cc716fcb | ||
|
|
163873d7a8 | ||
|
|
0e18f17dc9 | ||
|
|
d6ea28ee6b | ||
|
|
093c6be85a | ||
|
|
28faa252a2 | ||
|
|
334df22cfd | ||
|
|
b32963854b | ||
|
|
ad153a3fc2 | ||
|
|
caa0fd6904 | ||
|
|
bd7e1193bf | ||
|
|
7c4d95aa2d | ||
|
|
7f8ffbf914 | ||
|
|
d3c543a42e | ||
|
|
4931e43b67 | ||
|
|
4e26150542 | ||
|
|
bf3d8dd26d | ||
|
|
7c58e2bea2 | ||
|
|
ae5b736f40 | ||
|
|
c1b092e0b1 | ||
|
|
adf7582e8b | ||
|
|
544c2d1e41 | ||
|
|
c3f60c5e24 | ||
|
|
b16246455e | ||
|
|
fdc447761c | ||
|
|
7f5563fa97 | ||
|
|
767381b2a0 | ||
|
|
3ad3e7ea16 | ||
|
|
f6fbc71092 | ||
|
|
0943d420bc | ||
|
|
48cac4fb6c | ||
|
|
c56ec8cd79 |
90
.travis.yml
90
.travis.yml
@@ -18,18 +18,16 @@ sudo: required
|
||||
language: go
|
||||
|
||||
go:
|
||||
- "1.16.12"
|
||||
- "1.17.12"
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
env:
|
||||
global:
|
||||
- MAIN_BRANCH=private-master
|
||||
- MQ_LTS_VERSION=9.2.0.4
|
||||
- MAIN_BRANCH=v9.3.1
|
||||
- TAGCACHE_FILE=tagcache
|
||||
- RELEASE=r1
|
||||
- RELEASE_LTS=r1
|
||||
|
||||
go_import_path: "github.com/ibm-messaging/mq-container"
|
||||
|
||||
@@ -40,114 +38,56 @@ go_import_path: "github.com/ibm-messaging/mq-container"
|
||||
jobs:
|
||||
include:
|
||||
- stage: basic-build
|
||||
if: branch != private-master AND tag IS blank
|
||||
if: branch != v9.3.1 AND tag IS blank
|
||||
name: "Basic AMD64 build"
|
||||
os: linux
|
||||
env:
|
||||
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_925_ARCHIVE_REPOSITORY_DEV_AMD64
|
||||
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_931_ARCHIVE_REPOSITORY_DEV_AMD64
|
||||
script: bash -e travis-build-scripts/run.sh
|
||||
|
||||
# CD Build
|
||||
|
||||
- stage: global-tag
|
||||
if: branch = private-master AND type != pull_request OR tag =~ ^release-candidate*
|
||||
if: branch = v9.3.1 AND type != pull_request OR tag =~ ^release-candidate*
|
||||
name: "Generate Global Tag"
|
||||
os: linux
|
||||
script: bash -e travis-build-scripts/global-tag.sh
|
||||
- stage: build
|
||||
if: branch = private-master OR tag =~ ^release-candidate*
|
||||
if: branch = v9.3.1 OR tag =~ ^release-candidate*
|
||||
name: "Multi-Arch AMD64 build"
|
||||
os: linux
|
||||
env:
|
||||
- BUILD_ALL=true
|
||||
- MQ_ARCHIVE_REPOSITORY=$MQ_925_ARCHIVE_REPOSITORY_AMD64
|
||||
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_925_ARCHIVE_REPOSITORY_DEV_AMD64
|
||||
- MQ_ARCHIVE_REPOSITORY=$MQ_931_ARCHIVE_REPOSITORY_AMD64
|
||||
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_931_ARCHIVE_REPOSITORY_DEV_AMD64
|
||||
script: bash -e travis-build-scripts/run.sh
|
||||
- stage: build
|
||||
if: branch = private-master OR tag =~ ^release-candidate*
|
||||
if: branch = v9.3.1 OR tag =~ ^release-candidate*
|
||||
name: "Multi-Arch S390X build"
|
||||
os: linux-s390
|
||||
env:
|
||||
- BUILD_ALL=true
|
||||
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
|
||||
- MQ_ARCHIVE_REPOSITORY=$MQ_925_ARCHIVE_REPOSITORY_S390X
|
||||
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_925_ARCHIVE_REPOSITORY_DEV_S390X
|
||||
- MQ_ARCHIVE_REPOSITORY=$MQ_931_ARCHIVE_REPOSITORY_S390X
|
||||
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_931_ARCHIVE_REPOSITORY_DEV_S390X
|
||||
script: bash -e travis-build-scripts/run.sh
|
||||
- stage: build
|
||||
if: branch = private-master OR tag =~ ^release-candidate*
|
||||
if: branch = v9.3.1 OR tag =~ ^release-candidate*
|
||||
name: "Multi-Arch PPC64LE build"
|
||||
os: linux-ppc64le
|
||||
env:
|
||||
- BUILD_ALL=true
|
||||
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
|
||||
- MQ_ARCHIVE_REPOSITORY=$MQ_925_ARCHIVE_REPOSITORY_PPC64LE
|
||||
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_925_ARCHIVE_REPOSITORY_DEV_PPC64LE
|
||||
- MQ_ARCHIVE_REPOSITORY=$MQ_931_ARCHIVE_REPOSITORY_PPC64LE
|
||||
- MQ_ARCHIVE_REPOSITORY_DEV=$MQ_931_ARCHIVE_REPOSITORY_DEV_PPC64LE
|
||||
script: bash -e travis-build-scripts/run.sh
|
||||
- stage: push-manifest
|
||||
if: branch = private-master AND type != pull_request OR tag =~ ^release-candidate*
|
||||
if: branch = v9.3.1 AND type != pull_request OR tag =~ ^release-candidate*
|
||||
name: "Push Manifest-list to registry"
|
||||
env:
|
||||
- PUSH_MANIFEST_ONLY=true
|
||||
script: bash -e travis-build-scripts/run.sh
|
||||
|
||||
# LTS Build
|
||||
|
||||
- stage: global-tag
|
||||
if: branch = private-master AND type != pull_request OR tag =~ ^release-candidate*
|
||||
name: "Generate Global Tag"
|
||||
os: linux
|
||||
env:
|
||||
- LTS=true
|
||||
- TAGCACHE_FILE=tagcache-lts
|
||||
- MQ_VERSION=$MQ_LTS_VERSION
|
||||
- RELEASE=$RELEASE_LTS
|
||||
script: bash -e travis-build-scripts/global-tag.sh
|
||||
- stage: build
|
||||
if: branch = private-master OR tag =~ ^release-candidate*
|
||||
name: "Multi-Arch AMD64 build"
|
||||
os: linux
|
||||
env:
|
||||
- LTS=true
|
||||
- TAGCACHE_FILE=tagcache-lts
|
||||
- MQ_VERSION=$MQ_LTS_VERSION
|
||||
- MQ_ARCHIVE_REPOSITORY=$MQ_9204_EUS_ARCHIVE_REPOSITORY_AMD64
|
||||
- RELEASE=$RELEASE_LTS
|
||||
script: bash -e travis-build-scripts/run.sh
|
||||
- stage: build
|
||||
if: branch = private-master OR tag =~ ^release-candidate*
|
||||
name: "Multi-Arch S390X build"
|
||||
os: linux-s390
|
||||
env:
|
||||
- LTS=true
|
||||
- TAGCACHE_FILE=tagcache-lts
|
||||
- MQ_VERSION=$MQ_LTS_VERSION
|
||||
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
|
||||
- MQ_ARCHIVE_REPOSITORY=$MQ_9204_EUS_ARCHIVE_REPOSITORY_S390X
|
||||
- RELEASE=$RELEASE_LTS
|
||||
script: bash -e travis-build-scripts/run.sh
|
||||
- stage: build
|
||||
if: branch = private-master OR tag =~ ^release-candidate*
|
||||
name: "Multi-Arch PPC64LE build"
|
||||
os: linux-ppc64le
|
||||
env:
|
||||
- LTS=true
|
||||
- TAGCACHE_FILE=tagcache-lts
|
||||
- MQ_VERSION=$MQ_LTS_VERSION
|
||||
- TEST_OPTS_DOCKER="-run TestGoldenPathWithMetrics"
|
||||
- MQ_ARCHIVE_REPOSITORY=$MQ_9204_EUS_ARCHIVE_REPOSITORY_PPC64LE
|
||||
- RELEASE=$RELEASE_LTS
|
||||
script: bash -e travis-build-scripts/run.sh
|
||||
- stage: push-manifest
|
||||
if: branch = private-master AND type != pull_request OR tag =~ ^release-candidate*
|
||||
name: "Push Manifest-list to registry"
|
||||
env:
|
||||
- LTS=true
|
||||
- TAGCACHE_FILE=tagcache-lts
|
||||
- MQ_VERSION=$MQ_LTS_VERSION
|
||||
- PUSH_MANIFEST_ONLY=true
|
||||
- RELEASE=$RELEASE_LTS
|
||||
script: bash -e travis-build-scripts/run.sh
|
||||
|
||||
before_install:
|
||||
- make install-build-deps
|
||||
- make install-credential-helper
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"settingsInheritedFrom": "whitesource-config/whitesource-config@master",
|
||||
"scanSettings": {
|
||||
"baseBranches": ["private-master", "v9.2.0.x-eus"]
|
||||
}
|
||||
"baseBranches": ["private-master", "v9.2.0.x-eus", "v9.3.0.x"]
|
||||
},
|
||||
"issueSettings": {
|
||||
"issueRepoName": "whitesource-scan-issues"
|
||||
}
|
||||
}
|
||||
|
||||
26
CHANGELOG.md
26
CHANGELOG.md
@@ -1,10 +1,32 @@
|
||||
# Change log
|
||||
|
||||
## 9.2.5.0 (2021-12-06)
|
||||
## 9.3.1.1 (2023-01)
|
||||
|
||||
* Updated to MQ version 9.3.1.1
|
||||
|
||||
## 9.3.1.0-r2 (2022-11)
|
||||
|
||||
* Queue manager attribute SSLKEYR is now set to blank instead of '/run/runmqserver/tls/key' if key and certificate are not supplied.
|
||||
|
||||
## 9.3.1.0 (2022-10)
|
||||
|
||||
* Updated to MQ version 9.3.1.0
|
||||
|
||||
## 9.3.0.0 (2022-06)
|
||||
|
||||
* Updated to MQ version 9.3.0.0
|
||||
* Use `registry.access.redhat.com` instead of `registry.redhat.io`, so that you don't need to login with a Red Hat account.
|
||||
* Updated default developer config to use TLS cipher `ANY_TLS12_OR_HIGHER` instead of `ANY_TLS12`
|
||||
* Added default `jvm.options` file fix issue with missing preferences file causing an error in the web server log.
|
||||
* Updated to allow building image from Podman on macOS (requires Podman 4.1)
|
||||
* Container builds are now faster
|
||||
* Updated signal handling to use a buffer, as recommended by the Go 1.17 vetting tool
|
||||
|
||||
## 9.2.5.0 (2022-03)
|
||||
|
||||
* Updated to MQ version 9.2.5.0
|
||||
|
||||
## 9.2.4.0 (2021-09-06)
|
||||
## 9.2.4.0 (2021-11)
|
||||
|
||||
* Updated to MQ version 9.2.4.0
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Copyright IBM Corporation 2015, 2021
|
||||
# © Copyright IBM Corporation 2015, 2022
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -12,12 +12,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARG BASE_IMAGE=registry.redhat.io/ubi8/ubi-minimal
|
||||
ARG BASE_TAG=8.5-240
|
||||
ARG BUILDER_IMAGE=registry.redhat.io/ubi8/go-toolset
|
||||
ARG BUILDER_TAG=1.16.12-7
|
||||
ARG BASE_IMAGE=registry.access.redhat.com/ubi8/ubi-minimal
|
||||
ARG BASE_TAG=8.7-1031
|
||||
ARG BUILDER_IMAGE=registry.access.redhat.com/ubi8/go-toolset
|
||||
ARG BUILDER_TAG=1.17.12-11
|
||||
ARG GO_WORKDIR=/opt/app-root/src/go/src/github.com/ibm-messaging/mq-container
|
||||
ARG MQ_URL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/9.2.5.0-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz"
|
||||
ARG MQ_URL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/9.3.1.1-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz"
|
||||
###############################################################################
|
||||
# Build stage to build Go code
|
||||
###############################################################################
|
||||
@@ -30,11 +30,10 @@ ARG IMAGE_SOURCE="Not specified"
|
||||
ARG IMAGE_TAG="Not specified"
|
||||
ARG GO_WORKDIR
|
||||
USER 0
|
||||
COPY install-mq.sh /usr/local/bin/
|
||||
RUN mkdir /opt/mqm \
|
||||
&& chmod a+x /usr/local/bin/install-mq.sh \
|
||||
&& sleep 1 \
|
||||
&& INSTALL_SDK=1 install-mq.sh \
|
||||
WORKDIR /opt/mqm
|
||||
# Download and extract MQ files, to get the MQ client needed to compile.
|
||||
# Only extract certain MQ files to make the build quicker
|
||||
RUN curl --fail --location $MQ_URL | tar --extract --gunzip \
|
||||
&& chown -R 1001:root /opt/mqm/*
|
||||
WORKDIR $GO_WORKDIR/
|
||||
COPY go.mod go.sum ./
|
||||
@@ -43,21 +42,21 @@ COPY internal/ ./internal
|
||||
COPY pkg/ ./pkg
|
||||
COPY vendor/ ./vendor
|
||||
ENV CGO_CFLAGS="-I/opt/mqm/inc/" \
|
||||
CGO_LDFLAGS_ALLOW="-Wl,-rpath.*"
|
||||
ENV PATH="${PATH}:/opt/mqm/bin"
|
||||
RUN go build -ldflags "-X \"main.ImageCreated=$(date --iso-8601=seconds)\" -X \"main.ImageRevision=$IMAGE_REVISION\" -X \"main.ImageSource=$IMAGE_SOURCE\" -X \"main.ImageTag=$IMAGE_TAG\"" ./cmd/runmqserver/
|
||||
RUN go build ./cmd/chkmqready/
|
||||
RUN go build ./cmd/chkmqhealthy/
|
||||
RUN go build ./cmd/chkmqstarted/
|
||||
RUN go build ./cmd/runmqdevserver/
|
||||
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 ./cmd/chkmqstarted/
|
||||
RUN go test -v ./pkg/...
|
||||
RUN go test -v ./internal/...
|
||||
RUN go vet ./cmd/... ./internal/...
|
||||
CGO_LDFLAGS_ALLOW="-Wl,-rpath.*" \
|
||||
PATH="${PATH}:/opt/mqm/bin"
|
||||
RUN go build -ldflags "-X \"main.ImageCreated=$(date --iso-8601=seconds)\" -X \"main.ImageRevision=$IMAGE_REVISION\" -X \"main.ImageSource=$IMAGE_SOURCE\" -X \"main.ImageTag=$IMAGE_TAG\"" ./cmd/runmqserver/ \
|
||||
&& go build ./cmd/chkmqready/ \
|
||||
&& go build ./cmd/chkmqhealthy/ \
|
||||
&& go build ./cmd/chkmqstarted/ \
|
||||
&& go build ./cmd/runmqdevserver/ \
|
||||
&& go test -v ./cmd/runmqdevserver/... \
|
||||
&& go test -v ./cmd/runmqserver/ \
|
||||
&& go test -v ./cmd/chkmqready/ \
|
||||
&& go test -v ./cmd/chkmqhealthy/ \
|
||||
&& go test -v ./cmd/chkmqstarted/ \
|
||||
&& go test -v ./pkg/... \
|
||||
&& go test -v ./internal/... \
|
||||
&& go vet ./cmd/... ./internal/...
|
||||
|
||||
###############################################################################
|
||||
# Main build stage, to build MQ image
|
||||
@@ -68,18 +67,18 @@ ARG MQ_URL
|
||||
ARG BASE_IMAGE
|
||||
ARG BASE_TAG
|
||||
ARG GO_WORKDIR
|
||||
LABEL summary="IBM MQ Advanced Server"
|
||||
LABEL description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the world’s most successful enterprises"
|
||||
LABEL vendor="IBM"
|
||||
LABEL maintainer="IBM"
|
||||
LABEL distribution-scope="private"
|
||||
LABEL authoritative-source-url="https://www.ibm.com/software/passportadvantage/"
|
||||
LABEL url="https://www.ibm.com/products/mq/advanced"
|
||||
LABEL io.openshift.tags="mq messaging"
|
||||
LABEL io.k8s.display-name="IBM MQ Advanced Server"
|
||||
LABEL io.k8s.description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the world’s most successful enterprises"
|
||||
LABEL base-image=$BASE_IMAGE
|
||||
LABEL base-image-release=$BASE_TAG
|
||||
LABEL summary="IBM MQ Advanced Server" \
|
||||
description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the world’s most successful enterprises" \
|
||||
vendor="IBM" \
|
||||
maintainer="IBM" \
|
||||
distribution-scope="private" \
|
||||
authoritative-source-url="https://www.ibm.com/software/passportadvantage/" \
|
||||
url="https://www.ibm.com/products/mq/advanced" \
|
||||
io.openshift.tags="mq messaging" \
|
||||
io.k8s.display-name="IBM MQ Advanced Server" \
|
||||
io.k8s.description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the world’s most successful enterprises" \
|
||||
base-image=$BASE_IMAGE \
|
||||
base-image-release=$BASE_TAG
|
||||
COPY install-mq.sh /usr/local/bin/
|
||||
COPY install-mq-server-prereqs.sh /usr/local/bin/
|
||||
# Install MQ. To avoid a "text file busy" error here, we sleep before installing.
|
||||
@@ -91,9 +90,6 @@ RUN env \
|
||||
&& install-mq.sh \
|
||||
&& /opt/mqm/bin/security/amqpamcf \
|
||||
&& chown -R 1001:root /opt/mqm/*
|
||||
# Create a directory for runtime data from runmqserver
|
||||
RUN mkdir -p /run/runmqserver \
|
||||
&& chown 1001:root /run/runmqserver
|
||||
COPY --from=builder $GO_WORKDIR/runmqserver /usr/local/bin/
|
||||
COPY --from=builder $GO_WORKDIR/chkmq* /usr/local/bin/
|
||||
COPY NOTICES.txt /opt/mqm/licenses/notices-container.txt
|
||||
@@ -123,20 +119,14 @@ ENTRYPOINT ["runmqserver"]
|
||||
###############################################################################
|
||||
# Build stage to build C code for custom authorization service (developer-only)
|
||||
###############################################################################
|
||||
FROM registry.redhat.io/rhel8/gcc-toolset-9-toolchain as cbuilder
|
||||
# Use the Go toolset image, which already includes gcc and the MQ SDK
|
||||
FROM builder as cbuilder
|
||||
# The URL to download the MQ installer from in tar.gz format
|
||||
# This assumes an archive containing the MQ Non-Install packages
|
||||
ARG MQ_URL
|
||||
USER 0
|
||||
# Install the Apache Portable Runtime code (used for htpasswd hash checking)
|
||||
RUN yum -y install apr-devel apr-util-openssl apr-util-devel
|
||||
# Install MQ client
|
||||
COPY install-mq.sh /usr/local/bin/
|
||||
RUN mkdir /opt/mqm \
|
||||
&& chmod a+x /usr/local/bin/install-mq.sh \
|
||||
&& sleep 1 \
|
||||
&& INSTALL_SDK=1 install-mq.sh \
|
||||
&& chown -R 1001:root /opt/mqm/*
|
||||
RUN yum --assumeyes --disableplugin=subscription-manager install apr-devel apr-util-openssl apr-util-devel
|
||||
COPY authservice/ /opt/app-root/src/authservice/
|
||||
WORKDIR /opt/app-root/src/authservice/mqhtpass
|
||||
RUN make all
|
||||
@@ -148,31 +138,25 @@ FROM mq-server AS mq-dev-server
|
||||
ARG BASE_IMAGE
|
||||
ARG BASE_TAG
|
||||
ARG GO_WORKDIR
|
||||
# Enable MQ developer default configuration
|
||||
ENV MQ_DEV=true
|
||||
LABEL summary="IBM MQ Advanced for Developers Server"
|
||||
LABEL description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the world’s most successful enterprises"
|
||||
LABEL vendor="IBM"
|
||||
LABEL distribution-scope="private"
|
||||
LABEL authoritative-source-url="https://www.ibm.com/software/passportadvantage/"
|
||||
LABEL url="https://www.ibm.com/products/mq/advanced"
|
||||
LABEL io.openshift.tags="mq messaging"
|
||||
LABEL io.k8s.display-name="IBM MQ Advanced for Developers Server"
|
||||
LABEL io.k8s.description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the world’s most successful enterprises"
|
||||
LABEL base-image=$BASE_IMAGE
|
||||
LABEL base-image-release=$BASE_TAG
|
||||
LABEL summary="IBM MQ Advanced for Developers Server" \
|
||||
description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the world’s most successful enterprises" \
|
||||
vendor="IBM" \
|
||||
distribution-scope="private" \
|
||||
authoritative-source-url="https://www.ibm.com/software/passportadvantage/" \
|
||||
url="https://www.ibm.com/products/mq/advanced" \
|
||||
io.openshift.tags="mq messaging" \
|
||||
io.k8s.display-name="IBM MQ Advanced for Developers Server" \
|
||||
io.k8s.description="Simplify, accelerate and facilitate the reliable exchange of data with a security-rich messaging solution — trusted by the world’s most successful enterprises" \
|
||||
base-image=$BASE_IMAGE \
|
||||
base-image-release=$BASE_TAG
|
||||
USER 0
|
||||
COPY --from=cbuilder /opt/app-root/src/authservice/mqhtpass/build/mqhtpass.so /opt/mqm/lib64/
|
||||
COPY etc/mqm/*.ini /etc/mqm/
|
||||
COPY etc/mqm/mq.htpasswd /etc/mqm/
|
||||
RUN chmod 0660 /etc/mqm/mq.htpasswd
|
||||
COPY incubating/mqadvanced-server-dev/install-extra-packages.sh /usr/local/bin/
|
||||
RUN chmod u+x /usr/local/bin/install-extra-packages.sh \
|
||||
&& sleep 1 \
|
||||
&& install-extra-packages.sh
|
||||
# Create a directory for runtime data from runmqserver
|
||||
RUN mkdir -p /run/runmqdevserver \
|
||||
&& chown 1001:root /run/runmqdevserver
|
||||
COPY --from=builder $GO_WORKDIR/runmqdevserver /usr/local/bin/
|
||||
# Copy template files
|
||||
COPY incubating/mqadvanced-server-dev/*.tpl /etc/mqm/
|
||||
@@ -181,10 +165,13 @@ COPY incubating/mqadvanced-server-dev/web /etc/mqm/web
|
||||
RUN chown -R 1001:root /etc/mqm/* \
|
||||
&& chmod -R g+w /etc/mqm/web \
|
||||
&& chmod +x /usr/local/bin/runmq* \
|
||||
&& chmod 0660 /etc/mqm/mq.htpasswd \
|
||||
&& install --directory --mode 2775 --owner 1001 --group root /run/runmqdevserver
|
||||
ENV MQ_ENABLE_EMBEDDED_WEB_SERVER=1 MQ_GENERATE_CERTIFICATE_HOSTNAME=localhost
|
||||
ENV LD_LIBRARY_PATH=/opt/mqm/lib64
|
||||
ENV MQ_CONNAUTH_USE_HTP=true
|
||||
ENV MQS_PERMIT_UNKNOWN_ID=true
|
||||
ENV MQ_DEV=true \
|
||||
MQ_ENABLE_EMBEDDED_WEB_SERVER=1 \
|
||||
MQ_GENERATE_CERTIFICATE_HOSTNAME=localhost \
|
||||
LD_LIBRARY_PATH=/opt/mqm/lib64 \
|
||||
MQ_CONNAUTH_USE_HTP=true \
|
||||
MQS_PERMIT_UNKNOWN_ID=true
|
||||
USER 1001
|
||||
ENTRYPOINT ["runmqdevserver"]
|
||||
|
||||
216
Makefile
216
Makefile
@@ -1,4 +1,4 @@
|
||||
# © Copyright IBM Corporation 2017, 2021
|
||||
# © Copyright IBM Corporation 2017, 2022
|
||||
#
|
||||
# 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,15 @@
|
||||
###############################################################################
|
||||
|
||||
include config.env
|
||||
include source-branch.env
|
||||
|
||||
# arch_uname is the platform architecture according to the uname program. Can be differ by OS, e.g. `arm64` on macOS, but `aarch64` on Linux.
|
||||
arch_uname := $(shell uname -m)
|
||||
# arch_go is the platform architecture in Go-style (e.g. amd64, ppc64le, s390x or arm64).
|
||||
arch_go := $(if $(findstring x86_64,$(arch_uname)),amd64,$(if $(findstring aarch64,$(arch_uname)),arm64,$(arch_uname)))
|
||||
# ARCH is the platform architecture in Go-style (e.g. amd64, ppc64le, s390x or arm64).
|
||||
# Override this to build an image for a different architecture. Note that RUN instructions will not be able to succeed without the help of emulation provided by packages like qemu-user-static.
|
||||
ARCH ?= $(arch_go)
|
||||
# RELEASE shows what release of the container code has been built
|
||||
RELEASE ?=
|
||||
# MQ_ARCHIVE_REPOSITORY is a remote repository from which to pull the MQ_ARCHIVE (if required)
|
||||
@@ -59,12 +67,6 @@ MQ_DELIVERY_REGISTRY_NAMESPACE ?=
|
||||
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))
|
||||
# LTS is a boolean value to enable/disable LTS container build
|
||||
LTS ?= false
|
||||
# VOLUME_MOUNT_OPTIONS is used when bind-mounting files from the "downloads" directory into the container. By default, SELinux labels are automatically re-written, but this doesn't work on some filesystems with extended attributes (xattrs). You can turn off the label re-writing by setting this variable to be blank.
|
||||
@@ -75,11 +77,15 @@ VOLUME_MOUNT_OPTIONS ?= :Z
|
||||
###############################################################################
|
||||
# Build doesn't work if BuildKit is enabled
|
||||
DOCKER_BUILDKIT=0
|
||||
# Lock Docker API version for compatibility with Podman and with the Docker version in Travis' Ubuntu Bionic
|
||||
DOCKER_API_VERSION=1.40
|
||||
GO_PKG_DIRS = ./cmd ./internal ./test
|
||||
MQ_ARCHIVE_TYPE=LINUX
|
||||
MQ_ARCHIVE_DEV_TYPE=Linux
|
||||
# BUILD_SERVER_CONTAINER is the name of the web server container used at build time
|
||||
BUILD_SERVER_CONTAINER=build-server
|
||||
# BUILD_SERVER_NETWORK is the name of the network to use for the web server container used at build time
|
||||
BUILD_SERVER_NETWORK=build
|
||||
# NUM_CPU is the number of CPUs available to Docker. Used to control how many
|
||||
# test run in parallel
|
||||
NUM_CPU ?= $(or $(shell $(COMMAND) info --format "{{ .NCPU }}"),2)
|
||||
@@ -107,12 +113,22 @@ endif
|
||||
|
||||
# Try to figure out which archive to use from the architecture
|
||||
ifeq "$(ARCH)" "amd64"
|
||||
MQ_ARCHIVE_ARCH=X86-64
|
||||
MQ_ARCHIVE_DEV_ARCH=X64
|
||||
MQ_ARCHIVE_ARCH:=X86-64
|
||||
MQ_ARCHIVE_DEV_ARCH:=X64
|
||||
else ifeq "$(ARCH)" "ppc64le"
|
||||
MQ_ARCHIVE_ARCH=PPC64LE
|
||||
MQ_ARCHIVE_ARCH:=PPC64LE
|
||||
MQ_ARCHIVE_DEV_ARCH:=PPC64LE
|
||||
else ifeq "$(ARCH)" "s390x"
|
||||
MQ_ARCHIVE_ARCH=S390X
|
||||
MQ_ARCHIVE_ARCH:=S390X
|
||||
MQ_ARCHIVE_DEV_ARCH:=S390X
|
||||
else ifeq "$(ARCH)" "arm64"
|
||||
MQ_ARCHIVE_ARCH:=ARM64
|
||||
MQ_ARCHIVE_DEV_ARCH:=ARM64
|
||||
endif
|
||||
|
||||
# If this is a fake master build, push images to alternative location (pipeline wont consider these images GA candidates)
|
||||
ifeq ($(shell [ "$(TRAVIS)" = "true" ] && [ -n "$(MAIN_BRANCH)" ] && [ -n "$(SOURCE_BRANCH)" ] && [ "$(MAIN_BRANCH)" != "$(SOURCE_BRANCH)" ] && echo "true"), true)
|
||||
MQ_DELIVERY_REGISTRY_NAMESPACE="master-fake"
|
||||
endif
|
||||
|
||||
# LTS_TAG is the tag modifier for an LTS container build
|
||||
@@ -162,6 +178,13 @@ ifeq ($(shell [ ! -z $(TRAVIS) ] && [ "$(TRAVIS_PULL_REQUEST)" = "false" ] && [
|
||||
MQ_MANIFEST_TAG_SUFFIX=.$(TIMESTAMPFLAT).$(GIT_COMMIT)
|
||||
endif
|
||||
|
||||
# Make sure we don't use VOLUME_MOUNT_OPTIONS for Podman on macOS
|
||||
ifeq "$(COMMAND)" "podman"
|
||||
ifeq "$(shell uname -s)" "Darwin"
|
||||
VOLUME_MOUNT_OPTIONS:=
|
||||
endif
|
||||
endif
|
||||
|
||||
PATH_TO_MQ_TAG_CACHE=$(TRAVIS_BUILD_DIR)/.tagcache
|
||||
ifneq "$(TRAVIS)" "$(EMPTY)"
|
||||
ifneq ("$(wildcard $(PATH_TO_MQ_TAG_CACHE))","")
|
||||
@@ -216,16 +239,16 @@ downloads/$(MQ_ARCHIVE_DEV):
|
||||
mkdir -p downloads
|
||||
ifneq "$(BUILD_RSYNC_SERVER)" "$(EMPTY)"
|
||||
# Use key which is not stored in the repository to fetch the files from the fileserver
|
||||
curl -L $(BUILD_RSYNC_ENCRYPTED_KEY_URL) -o ./host.key.gpg
|
||||
curl --fail --location $(BUILD_RSYNC_ENCRYPTED_KEY_URL) --output ./host.key.gpg
|
||||
@echo $(BUILD_RSYNC_ENCRYPTION_PASSWORD)|gpg --batch --passphrase-fd 0 ./host.key.gpg
|
||||
chmod 600 ./host.key
|
||||
rsync -rv -e "ssh -o BatchMode=yes -q -o StrictHostKeyChecking=no -i ./host.key" --include="*/" --include="*.tar.gz" --exclude="*" $(BUILD_RSYNC_USER)@$(BUILD_RSYNC_SERVER):"$(BUILD_RSYNC_PATH)" downloads/$(MQ_ARCHIVE_DEV)
|
||||
-@rm host.key.gpg host.key
|
||||
else
|
||||
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)
|
||||
curl --fail --user $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) --request GET "$(MQ_ARCHIVE_REPOSITORY_DEV)" --output 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)
|
||||
curl --fail --location https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/$(MQ_ARCHIVE_DEV) --output downloads/$(MQ_ARCHIVE_DEV)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -235,14 +258,14 @@ downloads/$(MQ_ARCHIVE):
|
||||
ifneq "$(BUILD_RSYNC_SERVER)" "$(EMPTY)"
|
||||
# Use key which is not stored in the repository to fetch the files from the fileserver
|
||||
-@rm host.key.gpg host.key
|
||||
curl -L $(BUILD_RSYNC_ENCRYPTED_KEY_URL) -o ./host.key.gpg
|
||||
curl --fail --location $(BUILD_RSYNC_ENCRYPTED_KEY_URL) --output ./host.key.gpg
|
||||
@echo $(BUILD_RSYNC_ENCRYPTION_PASSWORD)|gpg --batch --passphrase-fd 0 ./host.key.gpg
|
||||
chmod 600 ./host.key
|
||||
rsync -rv -e "ssh -o BatchMode=yes -q -o StrictHostKeyChecking=no -i ./host.key" --include="*/" --include="*.tar.gz" --exclude="*" $(BUILD_RSYNC_USER)@$(BUILD_RSYNC_SERVER):"$(BUILD_RSYNC_PATH)" downloads/$(MQ_ARCHIVE)
|
||||
-@rm host.key.gpg host.key
|
||||
else
|
||||
ifneq "$(MQ_ARCHIVE_REPOSITORY)" "$(EMPTY)"
|
||||
curl -u $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) -X GET "$(MQ_ARCHIVE_REPOSITORY)" -o downloads/$(MQ_ARCHIVE)
|
||||
curl --fail --user $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) --request GET "$(MQ_ARCHIVE_REPOSITORY)" --output downloads/$(MQ_ARCHIVE)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -253,6 +276,10 @@ downloads: downloads/$(MQ_ARCHIVE_DEV) downloads/$(MQ_SDK_ARCHIVE)
|
||||
cache-mq-tag:
|
||||
@printf "MQ_MANIFEST_TAG=$(MQ_MANIFEST_TAG)\n" | tee $(PATH_TO_MQ_TAG_CACHE)
|
||||
|
||||
###############################################################################
|
||||
# Test targets
|
||||
###############################################################################
|
||||
|
||||
# Vendor Go dependencies for the Docker tests
|
||||
test/docker/vendor:
|
||||
cd test/docker && go mod vendor
|
||||
@@ -266,10 +293,10 @@ test-unit:
|
||||
test-advancedserver: test/docker/vendor
|
||||
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) on $(shell $(COMMAND) --version)"$(END)))
|
||||
$(COMMAND) inspect $(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)
|
||||
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) EXPECTED_LICENSE=Production go test -parallel $(NUM_CPU) -timeout $(TEST_TIMEOUT_DOCKER) $(TEST_OPTS_DOCKER)
|
||||
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG) EXPECTED_LICENSE=Production DOCKER_API_VERSION=$(DOCKER_API_VERSION) go test -parallel $(NUM_CPU) -timeout $(TEST_TIMEOUT_DOCKER) $(TEST_OPTS_DOCKER)
|
||||
|
||||
.PHONY: build-devjmstest
|
||||
build-devjmstest: registry-login
|
||||
build-devjmstest:
|
||||
$(info $(SPACER)$(shell printf $(TITLE)"Build JMS tests for developer config"$(END)))
|
||||
cd test/messaging && docker build --tag $(DEV_JMS_IMAGE) .
|
||||
|
||||
@@ -277,7 +304,7 @@ build-devjmstest: registry-login
|
||||
test-devserver: test/docker/vendor
|
||||
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_DEVSERVER):$(MQ_TAG) on $(shell $(COMMAND) --version)"$(END)))
|
||||
$(COMMAND) inspect $(MQ_IMAGE_DEVSERVER):$(MQ_TAG)
|
||||
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_DEVSERVER):$(MQ_TAG) EXPECTED_LICENSE=Developer DEV_JMS_IMAGE=$(DEV_JMS_IMAGE) IBMJRE=true go test -parallel $(NUM_CPU) -timeout $(TEST_TIMEOUT_DOCKER) -tags mqdev $(TEST_OPTS_DOCKER)
|
||||
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_DEVSERVER):$(MQ_TAG) EXPECTED_LICENSE=Developer DEV_JMS_IMAGE=$(DEV_JMS_IMAGE) IBMJRE=false DOCKER_API_VERSION=$(DOCKER_API_VERSION) go test -parallel $(NUM_CPU) -timeout $(TEST_TIMEOUT_DOCKER) -tags mqdev $(TEST_OPTS_DOCKER)
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
@@ -297,7 +324,7 @@ test-advancedserver-cover: test/docker/vendor coverage
|
||||
rm -f ./test/docker/coverage/*.cov
|
||||
rm -f ./coverage/docker.*
|
||||
mkdir -p ./test/docker/coverage/
|
||||
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)-cover TEST_COVER=true go test $(TEST_OPTS_DOCKER)
|
||||
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER):$(MQ_TAG)-cover TEST_COVER=true DOCKER_API_VERSION=$(DOCKER_API_VERSION) go test $(TEST_OPTS_DOCKER)
|
||||
echo 'mode: count' > ./coverage/docker.cov
|
||||
tail -q -n +2 ./test/docker/coverage/*.cov >> ./coverage/docker.cov
|
||||
go tool cover -html=./coverage/docker.cov -o ./coverage/docker.html
|
||||
@@ -306,16 +333,18 @@ 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
|
||||
$(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):/opt/app-root/src$(VOLUME_MOUNT_OPTIONS) --detach registry.redhat.io/ubi8/nginx-118 nginx -g "daemon off;",)
|
||||
$(eval EXTRA_ARGS=$(if $(findstring docker,$(COMMAND)), --network build --build-arg MQ_URL=http://build:8080/$4, --volume $(DOWNLOADS_DIR):/var/downloads$(VOLUME_MOUNT_OPTIONS) --build-arg MQ_URL=file:///var/downloads/$4))
|
||||
# Build the new image
|
||||
###############################################################################
|
||||
# Build functions
|
||||
###############################################################################
|
||||
|
||||
# Command to build the image
|
||||
# Args: imageName, imageTag, dockerfile, extraArgs, dockerfileTarget
|
||||
# If the ARCH variable has been changed from the default value (arch_go variable), then the `--platform` parameter is added
|
||||
define build-mq-command
|
||||
$(COMMAND) build \
|
||||
--tag $1:$2 \
|
||||
--file $3 \
|
||||
$(EXTRA_ARGS) \
|
||||
$4 \
|
||||
--build-arg IMAGE_REVISION="$(IMAGE_REVISION)" \
|
||||
--build-arg IMAGE_SOURCE="$(IMAGE_SOURCE)" \
|
||||
--build-arg IMAGE_TAG="$1:$2" \
|
||||
@@ -327,32 +356,71 @@ define build-mq
|
||||
--label vcs-ref=$(IMAGE_REVISION) \
|
||||
--label vcs-type=git \
|
||||
--label vcs-url=$(IMAGE_SOURCE) \
|
||||
$(if $(findstring $(arch_go),$(ARCH)),,--platform=linux/$(ARCH)) \
|
||||
$(EXTRA_LABELS) \
|
||||
--target $5 \
|
||||
.
|
||||
$(if $(findstring docker,$(COMMAND)), @docker kill $(BUILD_SERVER_CONTAINER))
|
||||
$(if $(findstring docker,$(COMMAND)), @docker network rm build)
|
||||
.
|
||||
endef
|
||||
|
||||
COMMAND_SERVER_VERSION=$(shell $(COMMAND) version --format "{{ .Server.Version }}")
|
||||
COMMAND_CLIENT_VERSION=$(shell $(COMMAND) version --format "{{ .Client.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 ., ,$(COMMAND_CLIENT_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker client 17.05 or greater is required" && exit 1)
|
||||
@test "$(word 1,$(subst ., ,$(COMMAND_SERVER_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(COMMAND_SERVER_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker server 17.05 or greater is required" && exit 1)
|
||||
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
|
||||
# Build using a separate container to host the MQ download files.
|
||||
# To minimize the layers in the resulting image, the download files can't be part of the build context.
|
||||
# The "docker build" command (and "podman build" on macOS) don't allow you to mount a directory into the build, so a
|
||||
# separate container is used to host a web server.
|
||||
# Note that for Podman, this means that you need to be using the "rootful" mode, because the rootless mode doesn't allow
|
||||
# much control of networking, so the containers can't talk to each other.
|
||||
define build-mq-using-web-server
|
||||
$(COMMAND) network create $(BUILD_SERVER_NETWORK)
|
||||
$(COMMAND) run \
|
||||
--rm \
|
||||
--name $(BUILD_SERVER_CONTAINER) \
|
||||
--network $(BUILD_SERVER_NETWORK) \
|
||||
--volume $(DOWNLOADS_DIR):/opt/app-root/src$(VOLUME_MOUNT_OPTIONS) \
|
||||
--detach \
|
||||
registry.access.redhat.com/ubi8/nginx-120 nginx -g "daemon off;" || ($(COMMAND) network rm $(BUILD_SERVER_NETWORK) && exit 1)
|
||||
BUILD_SERVER_IP=$$($(COMMAND) inspect -f '{{ .NetworkSettings.Networks.$(BUILD_SERVER_NETWORK).IPAddress }}' $(BUILD_SERVER_CONTAINER)); \
|
||||
$(call build-mq-command,$1,$2,$3,--network build --build-arg MQ_URL=http://$$BUILD_SERVER_IP:8080/$4,$5) || ($(COMMAND) rm -f $(BUILD_SERVER_CONTAINER) && $(COMMAND) network rm $(BUILD_SERVER_NETWORK) && exit 1)
|
||||
$(COMMAND) rm -f $(BUILD_SERVER_CONTAINER)
|
||||
$(COMMAND) network rm $(BUILD_SERVER_NETWORK)
|
||||
endef
|
||||
|
||||
# When building with Docker, always use the web server build because you can't use bind-mounted volumes.
|
||||
# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget
|
||||
define build-mq-docker
|
||||
$(call build-mq-using-web-server,$1,$2,$3,$4,$5)
|
||||
endef
|
||||
|
||||
# When building with Podman on macOS (Darwin), use the web server build because you can't use bind-mounted volumes with `podman build` on macOS
|
||||
# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget
|
||||
define build-mq-podman-Darwin
|
||||
$(call build-mq-using-web-server,$1,$2,$3,$4,$5)
|
||||
endef
|
||||
|
||||
# When building with Podman on Linux, just pass the downloads directory as a volume
|
||||
# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget
|
||||
define build-mq-podman-Linux
|
||||
$(call build-mq-command,$1,$2,$3,--volume $(DOWNLOADS_DIR):/var/downloads$(VOLUME_MOUNT_OPTIONS) --build-arg MQ_URL=file:///var/downloads/$4,$5)
|
||||
endef
|
||||
|
||||
# When building with Podman, just pass the downloads directory as a volume
|
||||
# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget
|
||||
define build-mq-podman
|
||||
$(call build-mq-podman-$(shell uname -s),$1,$2,$3,$4,$5)
|
||||
endef
|
||||
|
||||
# Build an MQ image. The commands used are slightly different between Docker and Podman
|
||||
# Args: imageName, imageTag, dockerfile, mqArchive, dockerfileTarget
|
||||
define build-mq
|
||||
$(call build-mq-$(COMMAND),$1,$2,$3,$4,$5)
|
||||
endef
|
||||
|
||||
###############################################################################
|
||||
# Build targets
|
||||
###############################################################################
|
||||
.PHONY: build-advancedserver-host
|
||||
build-advancedserver-host: build-advancedserver
|
||||
|
||||
.PHONY: build-advancedserver
|
||||
build-advancedserver: registry-login log-build-env downloads/$(MQ_ARCHIVE) command-version
|
||||
build-advancedserver: 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)
|
||||
|
||||
@@ -360,40 +428,39 @@ build-advancedserver: registry-login log-build-env downloads/$(MQ_ARCHIVE) comma
|
||||
build-devserver-host: build-devserver
|
||||
|
||||
.PHONY: build-devserver
|
||||
build-devserver: registry-login log-build-env downloads/$(MQ_ARCHIVE_DEV) command-version
|
||||
build-devserver: 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-advancedserver-cover
|
||||
build-advancedserver-cover: registry-login command-version
|
||||
build-advancedserver-cover: 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: registry-login downloads/$(MQ_ARCHIVE_DEV)
|
||||
build-explorer: 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: registry-login downloads/$(MQ_ARCHIVE_DEV)
|
||||
build-sdk: 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: registry-login
|
||||
registry-login:
|
||||
ifneq ($(REGISTRY_USER),)
|
||||
$(COMMAND) login -u $(REGISTRY_USER) -p $(REGISTRY_PASS) registry.redhat.io
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
# Logging targets
|
||||
###############################################################################
|
||||
.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_ARCHIVE=$(MQ_ARCHIVE)
|
||||
@echo arch_uname=$(arch_uname)
|
||||
@echo arch_go=$(arch_go)
|
||||
@echo "ARCH=$(ARCH) (origin:$(origin ARCH))"
|
||||
@echo MQ_VERSION="$(MQ_VERSION) (origin:$(origin MQ_VERSION))"
|
||||
@echo MQ_ARCHIVE="$(MQ_ARCHIVE) (origin:$(origin MQ_ARCHIVE))"
|
||||
@echo MQ_ARCHIVE_DEV_ARCH=$(MQ_ARCHIVE_DEV_ARCH)
|
||||
@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 REGISTRY_USER=$(REGISTRY_USER)
|
||||
|
||||
.PHONY: log-build-env
|
||||
log-build-env: log-build-vars
|
||||
@@ -403,16 +470,22 @@ log-build-env: log-build-vars
|
||||
|
||||
include formatting.mk
|
||||
|
||||
###############################################################################
|
||||
# Push/pull targets
|
||||
###############################################################################
|
||||
.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)
|
||||
curl --fail --user $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) --request GET "$(MQ_ARCHIVE_REPOSITORY)" --output 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)
|
||||
curl --fail --user $(MQ_ARCHIVE_REPOSITORY_USER):$(MQ_ARCHIVE_REPOSITORY_CREDENTIAL) --request GET "$(MQ_ARCHIVE_REPOSITORY_DEV)" --output downloads/$(MQ_ARCHIVE_DEV)
|
||||
|
||||
.PHONY: push-advancedserver
|
||||
push-advancedserver:
|
||||
@if [ $(MQ_DELIVERY_REGISTRY_NAMESPACE) = "master-fake" ]; then\
|
||||
echo "Detected fake master build. Note that the push destination is set to the fake master namespace: $(MQ_DELIVERY_REGISTRY_FULL_PATH)";\
|
||||
fi
|
||||
$(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)
|
||||
@@ -420,6 +493,9 @@ push-advancedserver:
|
||||
|
||||
.PHONY: push-devserver
|
||||
push-devserver:
|
||||
@if [ $(MQ_DELIVERY_REGISTRY_NAMESPACE) = "master-fake" ]; then\
|
||||
echo "Detected fake master build. Note that the push destination is set to the fake master namespace: $(MQ_DELIVERY_REGISTRY_FULL_PATH)";\
|
||||
fi
|
||||
$(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)
|
||||
@@ -467,6 +543,10 @@ endif
|
||||
build-skopeo-container:
|
||||
$(COMMAND) images | grep -q "skopeo"; if [ $$? != 0 ]; then $(COMMAND) build -t skopeo:latest ./docker-builds/skopeo/; fi
|
||||
|
||||
###############################################################################
|
||||
# Other targets
|
||||
###############################################################################
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf ./coverage
|
||||
@@ -528,8 +608,6 @@ gosec:
|
||||
printf "\ngosec found no LOW severity issues\n" ;\
|
||||
fi ;\
|
||||
|
||||
include formatting.mk
|
||||
|
||||
.PHONY: update-release-information
|
||||
update-release-information:
|
||||
sed -i.bak 's/ARG MQ_URL=.*-LinuxX64.tar.gz"/ARG MQ_URL="https:\/\/public.dhe.ibm.com\/ibmdl\/export\/pub\/software\/websphere\/messaging\/mqadv\/$(MQ_VERSION)-IBM-MQ-Advanced-for-Developers-Non-Install-LinuxX64.tar.gz"/g' Dockerfile-server && rm Dockerfile-server.bak
|
||||
@@ -542,3 +620,17 @@ update-release-information:
|
||||
sed -i.bak 's/knowledgecenter\/SSFKSJ_.*\/com/knowledgecenter\/SSFKSJ_${MQ_VERSION_2}.0\/com/g' docs/usage.md && rm docs/usage.md.bak
|
||||
$(eval MQ_VERSION_3=$(shell echo '${MQ_VERSION_1}' | sed "s/\.//g"))
|
||||
sed -i.bak 's/MQ_..._ARCHIVE_REPOSITORY/MQ_${MQ_VERSION_3}_ARCHIVE_REPOSITORY/g' .travis.yml && rm .travis.yml.bak
|
||||
|
||||
COMMAND_SERVER_VERSION=$(shell $(COMMAND) version --format "{{ .Server.Version }}")
|
||||
COMMAND_CLIENT_VERSION=$(shell $(COMMAND) version --format "{{ .Client.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 ., ,$(COMMAND_CLIENT_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker client 17.05 or greater is required" && exit 1)
|
||||
@test "$(word 1,$(subst ., ,$(COMMAND_SERVER_VERSION)))" -ge "17" || ("$(word 1,$(subst ., ,$(COMMAND_SERVER_VERSION)))" -eq "17" && "$(word 2,$(subst ., ,$(COMMAND_CLIENT_VERSION)))" -ge "05") || (echo "Error: Docker server 17.05 or greater is required" && exit 1)
|
||||
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
|
||||
|
||||
@@ -34,7 +34,7 @@ See the [default developer configuration docs](docs/developer-config.md) for the
|
||||
|
||||
### Kubernetes
|
||||
|
||||
If you want to use IBM MQ in [Kubernetes](https://kubernetes.io), you can find an example [Helm](https://helm.sh/) chart here: [IBM charts](https://github.com/IBM/charts). This can be used to run the container on a cluster, such as [IBM Cloud Private](https://www.ibm.com/cloud-computing/products/ibm-cloud-private/) or the [IBM Cloud Kubernetes Service](https://www.ibm.com/cloud/container-service).
|
||||
If you want to use IBM MQ on [Kubernetes](https://kubernetes.io), you can find an example [Helm](https://helm.sh/) chart here: [IBM MQ Sample Helm Chart](https://github.com/ibm-messaging/mq-helm). This can be used to run the container on a Kubernetes cluster, such as the [IBM Cloud Kubernetes Service](https://www.ibm.com/cloud/container-service).
|
||||
|
||||
## Issues and contributions
|
||||
|
||||
@@ -45,12 +45,12 @@ For issues relating specifically to the container image or Helm chart, please us
|
||||
The Dockerfiles and associated code and scripts are licensed under the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).
|
||||
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-BYHCL7) (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-BZDDDY) (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.
|
||||
- [IBM MQ Advanced for Developers](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=Z125-3301-14&li_formnum=L-APIG-CAUEQC) (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-CAUEBE) (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.
|
||||
|
||||
|
||||
## Copyright
|
||||
|
||||
© Copyright IBM Corporation 2015, 2020
|
||||
© Copyright IBM Corporation 2015, 2022
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Copyright IBM Corporation 2017, 2020
|
||||
# © Copyright IBM Corporation 2017, 2022
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -20,19 +20,31 @@
|
||||
|
||||
SRC_DIR = src
|
||||
BUILD_DIR = ./build
|
||||
ARCH ?= $(if $(findstring x86_64,$(shell uname -m)),amd64,$(if $(findstring aarch64,$(shell uname -m)),aarch64,$(shell uname -m)))
|
||||
|
||||
# Flags passed to the C compiler. Need to use gnu11 to get POSIX functions needed for file locking.
|
||||
CFLAGS += -std=gnu11 -fPIC -Wall -m64
|
||||
CFLAGS.amd64 := -m64
|
||||
CFLAGS.ppc64le := -m64
|
||||
CFLAGS.s390x := -m64
|
||||
# -m64 is not a valid compiler option on aarch64/arm64 (ARM)
|
||||
CFLAGS.arm64 :=
|
||||
CFLAGS += -std=gnu11 -fPIC -Wall ${CFLAGS.${ARCH}}
|
||||
|
||||
LIB_APR = -L/usr/lib64 -lapr-1 -laprutil-1
|
||||
LIB_MQ = -L/opt/mqm/lib64 -lmqm_r
|
||||
|
||||
all: $(BUILD_DIR)/mqhtpass.so $(BUILD_DIR)/htpass_test
|
||||
all: $(BUILD_DIR)/mqhtpass.so $(BUILD_DIR)/htpass_test $(BUILD_DIR)/log_test
|
||||
|
||||
$(BUILD_DIR)/log.o : $(SRC_DIR)/log.c $(SRC_DIR)/log.h
|
||||
mkdir -p ${dir $@}
|
||||
gcc $(CFLAGS) -c $(SRC_DIR)/log.c -o $@
|
||||
|
||||
$(BUILD_DIR)/log_test : $(BUILD_DIR)/log.o
|
||||
mkdir -p ${dir $@}
|
||||
gcc $(CFLAGS) $(SRC_DIR)/log_test.c $^ -o $@
|
||||
# Run Logging tests, and print log if they fail
|
||||
$@ || (cat log_test*.log && exit 1)
|
||||
|
||||
$(BUILD_DIR)/htpass.o : $(SRC_DIR)/htpass.c $(SRC_DIR)/htpass.h
|
||||
mkdir -p ${dir $@}
|
||||
gcc $(CFLAGS) -c $(SRC_DIR)/htpass.c -I /usr/include/apr-1 -o $@
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2021
|
||||
© Copyright IBM Corporation 2021, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -124,7 +124,7 @@ void log_printf(const char *source_file, int source_line, const char *level, con
|
||||
if (strftime(date_buf, sizeof date_buf, "%FT%T", utc))
|
||||
{
|
||||
// Round microseconds down to milliseconds, for consistency
|
||||
cur += snprintf(cur, end-cur, ", \"ibm_datetime\":\"%s.%03ldZ\"", date_buf, now.tv_usec / 1000);
|
||||
cur += snprintf(cur, end-cur, ", \"ibm_datetime\":\"%s.%03ldZ\"", date_buf, now.tv_usec / (long)1000);
|
||||
}
|
||||
cur += snprintf(cur, end-cur, ", \"ibm_processId\":\"%d\"", pid);
|
||||
cur += snprintf(cur, end-cur, ", \"host\":\"%s\"", hostname);
|
||||
@@ -146,7 +146,17 @@ void log_printf(const char *source_file, int source_line, const char *level, con
|
||||
|
||||
// Important: Just do one file write, to prevent problems with multi-threading.
|
||||
// This only works if the log message is not too long for the buffer.
|
||||
fprintf(fp, buf);
|
||||
fprintf(fp, "%s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
int trimmed_len(char *s, int max_len)
|
||||
{
|
||||
int i;
|
||||
for (i = max_len - 1; i >= 0; i--)
|
||||
{
|
||||
if (s[i] != ' ')
|
||||
break;
|
||||
}
|
||||
return i+1;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2021
|
||||
© Copyright IBM Corporation 2021, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -59,5 +59,12 @@ void log_close();
|
||||
*/
|
||||
#define log_debugf(format,...) log_printf(__FILE__, __LINE__, "DEBUG", format, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Return the length of the string when trimmed of trailing spaces.
|
||||
* IBM MQ uses fixed length strings, so this function can be used to print
|
||||
* a trimmed version of a string using the "%.*s" printf format string.
|
||||
* For example, `log_printf("%.*s", trimmed_len(fw_str, 48), fw_str)`
|
||||
*/
|
||||
int trimmed_len(char *s, int);
|
||||
|
||||
#endif
|
||||
120
authservice/mqhtpass/src/log_test.c
Normal file
120
authservice/mqhtpass/src/log_test.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2022
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "log.h"
|
||||
|
||||
// Headers for multi-threaded tests
|
||||
#include <pthread.h>
|
||||
|
||||
// Start a test and log the function name
|
||||
#define test_start() printf("=== RUN: %s\n", __func__)
|
||||
|
||||
// Indicate test has passed
|
||||
#define test_pass() printf("--- PASS: %s\n", __func__)
|
||||
|
||||
// The length of strings used in the tests
|
||||
#define STR_LEN 5
|
||||
|
||||
// Indicate test has failed
|
||||
void test_fail(const char *test_name)
|
||||
{
|
||||
printf("--- FAIL: %s\n", test_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Print a fixed-width string in hexadecimal
|
||||
void print_hex(char fw_string[STR_LEN])
|
||||
{
|
||||
printf("[");
|
||||
for (int i=0; i<STR_LEN; i++)
|
||||
{
|
||||
printf("%02x", fw_string[i]);
|
||||
if (i < STR_LEN-1)
|
||||
printf(",");
|
||||
}
|
||||
printf("]");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tests for string manipulation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void test_trimmed_len(const char *test_name, char fw_string[STR_LEN], int expected_len)
|
||||
{
|
||||
printf("=== RUN: %s\n", test_name);
|
||||
int len;
|
||||
// Create a copy of the fixed-width string
|
||||
char fw_string2[STR_LEN];
|
||||
memcpy(fw_string2, fw_string, STR_LEN * sizeof(char));
|
||||
// Call the function under test
|
||||
len = trimmed_len(fw_string, STR_LEN);
|
||||
// Check the result is correct
|
||||
if (len != expected_len)
|
||||
{
|
||||
printf("%s: Expected result to be %d; got %d\n", __func__, expected_len, len);
|
||||
test_fail(test_name);
|
||||
}
|
||||
// Check that the original string has not been changed
|
||||
for (int i=0; i<STR_LEN; i++)
|
||||
{
|
||||
if (fw_string[i] != fw_string2[i])
|
||||
{
|
||||
printf("%c-%c\n", fw_string[i], fw_string2[i]);
|
||||
printf("%s: Expected string to be identical to input hex ", __func__);
|
||||
print_hex(fw_string2);
|
||||
printf("; got hex ");
|
||||
print_hex(fw_string);
|
||||
printf("\n");
|
||||
test_fail(test_name);
|
||||
}
|
||||
}
|
||||
printf("--- PASS: %s\n", test_name);
|
||||
}
|
||||
|
||||
void test_trimmed_len_normal()
|
||||
{
|
||||
char fw_string[STR_LEN] = {'a','b','c',' ',' '};
|
||||
test_trimmed_len(__func__, fw_string, 3);
|
||||
}
|
||||
|
||||
void test_trimmed_len_full()
|
||||
{
|
||||
char fw_string[STR_LEN] = {'a','b','c','d','e'};
|
||||
test_trimmed_len(__func__, fw_string, 5);
|
||||
}
|
||||
|
||||
void test_trimmed_len_empty()
|
||||
{
|
||||
char fw_string[STR_LEN] = {' ',' ',' ',' ',' '};
|
||||
test_trimmed_len(__func__, fw_string, 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int main()
|
||||
{
|
||||
// Turn on debugging for the tests
|
||||
setenv("DEBUG", "true", true);
|
||||
log_init("log_test.log");
|
||||
test_trimmed_len_normal();
|
||||
test_trimmed_len_full();
|
||||
test_trimmed_len_empty();
|
||||
log_close();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2021
|
||||
© Copyright IBM Corporation 2021, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -34,8 +34,6 @@ static MQZ_TERM_AUTHORITY mqhtpass_terminate;
|
||||
#define HTPASSWD_FILE "/etc/mqm/mq.htpasswd"
|
||||
#define NAME "MQ Advanced for Developers custom authentication service"
|
||||
|
||||
static char *trim(char *s);
|
||||
|
||||
/**
|
||||
* Initialization and entrypoint for the dynamically loaded
|
||||
* authorization installable service. It registers the addresses of the
|
||||
@@ -80,7 +78,7 @@ void MQENTRY MQStart(
|
||||
{
|
||||
log_infof("Initializing %s", NAME);
|
||||
}
|
||||
log_debugf("MQStart options=%s qmgr=%s", ((Options == MQZIO_SECONDARY) ? "Secondary" : "Primary"), trim(QMgrName));
|
||||
log_debugf("MQStart options=%s qmgr=%.*s", ((Options == MQZIO_SECONDARY) ? "Secondary" : "Primary"), trimmed_len(QMgrName, MQ_Q_MGR_NAME_LENGTH), QMgrName);
|
||||
|
||||
if (!htpass_valid_file(HTPASSWD_FILE))
|
||||
{
|
||||
@@ -176,11 +174,14 @@ static void MQENTRY mqhtpass_authenticate_user_csp(
|
||||
// Tell the queue manager to continue trying other authorization services, as they might have the user.
|
||||
*pContinuation = MQZCI_CONTINUE;
|
||||
log_debugf(
|
||||
"User authentication failed due to invalid user. user=%s effuser=%s applname=%s csp_user=%s cc=%d reason=%d",
|
||||
trim(pIdentityContext->UserIdentifier),
|
||||
trim(pApplicationContext->EffectiveUserID),
|
||||
trim(pApplicationContext->ApplName),
|
||||
trim(csp_user),
|
||||
"User authentication failed due to invalid user. user=%.*s effuser=%.*s applname=%.*s csp_user=%s cc=%d reason=%d",
|
||||
trimmed_len(pIdentityContext->UserIdentifier, MQ_USER_ID_LENGTH),
|
||||
pIdentityContext->UserIdentifier,
|
||||
trimmed_len(pApplicationContext->EffectiveUserID, MQ_USER_ID_LENGTH),
|
||||
pApplicationContext->EffectiveUserID,
|
||||
trimmed_len(pApplicationContext->ApplName, MQ_APPL_NAME_LENGTH),
|
||||
pApplicationContext->ApplName,
|
||||
csp_user,
|
||||
*pCompCode,
|
||||
*pReason);
|
||||
}
|
||||
@@ -192,11 +193,14 @@ static void MQENTRY mqhtpass_authenticate_user_csp(
|
||||
// Tell the queue manager to stop trying other authorization services.
|
||||
*pContinuation = MQZCI_STOP;
|
||||
log_debugf(
|
||||
"User authentication failed due to invalid password. user=%s effuser=%s applname=%s csp_user=%s cc=%d reason=%d",
|
||||
trim(pIdentityContext->UserIdentifier),
|
||||
trim(pApplicationContext->EffectiveUserID),
|
||||
trim(pApplicationContext->ApplName),
|
||||
trim(csp_user),
|
||||
"User authentication failed due to invalid password. user=%.*s effuser=%.*s applname=%.*s csp_user=%s cc=%d reason=%d",
|
||||
trimmed_len(pIdentityContext->UserIdentifier, MQ_USER_ID_LENGTH),
|
||||
pIdentityContext->UserIdentifier,
|
||||
trimmed_len(pApplicationContext->EffectiveUserID, MQ_USER_ID_LENGTH),
|
||||
pApplicationContext->EffectiveUserID,
|
||||
trimmed_len(pApplicationContext->ApplName, MQ_APPL_NAME_LENGTH),
|
||||
pApplicationContext->ApplName,
|
||||
csp_user,
|
||||
*pCompCode,
|
||||
*pReason);
|
||||
}
|
||||
@@ -227,7 +231,6 @@ static void MQENTRY mqhtpass_authenticate_user(
|
||||
PMQLONG pReason)
|
||||
{
|
||||
char *spuser = NULL;
|
||||
char *sppass = NULL;
|
||||
// By default, return a warning, which indicates to MQ that this
|
||||
// authorization service hasn't authenticated the user.
|
||||
*pCompCode = MQCC_WARNING;
|
||||
@@ -276,11 +279,14 @@ static void MQENTRY mqhtpass_authenticate_user(
|
||||
else
|
||||
{
|
||||
log_debugf(
|
||||
"User authentication failed user=%s effuser=%s applname=%s cspuser=%s cc=%d reason=%d",
|
||||
trim(pIdentityContext->UserIdentifier),
|
||||
trim(pApplicationContext->EffectiveUserID),
|
||||
trim(pApplicationContext->ApplName),
|
||||
trim(spuser),
|
||||
"User authentication failed user=%.*s effuser=%.*s applname=%.*s cspuser=%s cc=%d reason=%d",
|
||||
trimmed_len(pIdentityContext->UserIdentifier, MQ_USER_ID_LENGTH),
|
||||
pIdentityContext->UserIdentifier,
|
||||
trimmed_len(pApplicationContext->EffectiveUserID, MQ_USER_ID_LENGTH),
|
||||
pApplicationContext->EffectiveUserID,
|
||||
trimmed_len(pApplicationContext->ApplName, MQ_APPL_NAME_LENGTH),
|
||||
pApplicationContext->ApplName,
|
||||
spuser,
|
||||
*pCompCode,
|
||||
*pReason);
|
||||
}
|
||||
@@ -334,18 +340,3 @@ static void MQENTRY mqhtpass_terminate(
|
||||
*pReason = MQRC_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove trailing spaces from a string.
|
||||
*/
|
||||
static char *trim(char *s)
|
||||
{
|
||||
int i;
|
||||
for (i = strlen(s) - 1; i >= 0; i--)
|
||||
{
|
||||
if (s[i] == ' ')
|
||||
s[i] = 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2017, 2020
|
||||
© Copyright IBM Corporation 2017, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,22 +18,24 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"strings"
|
||||
|
||||
"github.com/ibm-messaging/mq-container/pkg/name"
|
||||
)
|
||||
|
||||
func queueManagerHealthy() (bool, error) {
|
||||
func queueManagerHealthy(ctx context.Context) (bool, error) {
|
||||
name, err := name.GetQueueManagerName()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// Specify the queue manager name, just in case someone's created a second queue manager
|
||||
// #nosec G204
|
||||
cmd := exec.Command("dspmq", "-n", "-m", name)
|
||||
cmd := exec.CommandContext(ctx, "dspmq", "-n", "-m", name)
|
||||
// Run the command and wait for completion
|
||||
out, err := cmd.CombinedOutput()
|
||||
fmt.Printf("%s", out)
|
||||
@@ -47,13 +49,20 @@ func queueManagerHealthy() (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
healthy, err := queueManagerHealthy()
|
||||
func doMain() int {
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
||||
defer cancel()
|
||||
|
||||
healthy, err := queueManagerHealthy(ctx)
|
||||
if err != nil {
|
||||
os.Exit(2)
|
||||
return 2
|
||||
}
|
||||
if !healthy {
|
||||
os.Exit(1)
|
||||
return 1
|
||||
}
|
||||
os.Exit(0)
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
os.Exit(doMain())
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2017, 2019
|
||||
© Copyright IBM Corporation 2017, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,44 +18,54 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"github.com/ibm-messaging/mq-container/internal/ready"
|
||||
"github.com/ibm-messaging/mq-container/pkg/name"
|
||||
)
|
||||
|
||||
func main() {
|
||||
func doMain() int {
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
||||
defer cancel()
|
||||
|
||||
// Check if runmqserver has indicated that it's finished configuration
|
||||
r, err := ready.Check()
|
||||
if !r || err != nil {
|
||||
os.Exit(1)
|
||||
return 1
|
||||
}
|
||||
name, err := name.GetQueueManagerName()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Check if the queue manager has a running listener
|
||||
if active, _ := ready.IsRunningAsActiveQM(name); active {
|
||||
if active, _ := ready.IsRunningAsActiveQM(ctx, name); active {
|
||||
conn, err := net.Dial("tcp", "127.0.0.1:1414")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
return 1
|
||||
}
|
||||
err = conn.Close()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
} else if standby, _ := ready.IsRunningAsStandbyQM(name); standby {
|
||||
} else if standby, _ := ready.IsRunningAsStandbyQM(ctx, name); standby {
|
||||
fmt.Printf("Detected queue manager running in standby mode")
|
||||
os.Exit(10)
|
||||
} else if replica, _ := ready.IsRunningAsReplicaQM(name); replica {
|
||||
return 10
|
||||
} else if replica, _ := ready.IsRunningAsReplicaQM(ctx, name); replica {
|
||||
fmt.Printf("Detected queue manager running in replica mode")
|
||||
os.Exit(20)
|
||||
return 20
|
||||
} else {
|
||||
os.Exit(1)
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
os.Exit(doMain())
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2021
|
||||
© Copyright IBM Corporation 2021, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,22 +18,24 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"strings"
|
||||
|
||||
"github.com/ibm-messaging/mq-container/pkg/name"
|
||||
)
|
||||
|
||||
func queueManagerStarted() (bool, error) {
|
||||
func queueManagerStarted(ctx context.Context) (bool, error) {
|
||||
name, err := name.GetQueueManagerName()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// Specify the queue manager name, just in case someone's created a second queue manager
|
||||
// #nosec G204
|
||||
cmd := exec.Command("dspmq", "-n", "-m", name)
|
||||
cmd := exec.CommandContext(ctx, "dspmq", "-n", "-m", name)
|
||||
// Run the command and wait for completion
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
@@ -46,13 +48,20 @@ func queueManagerStarted() (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
started, err := queueManagerStarted()
|
||||
func doMain() int {
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
||||
defer cancel()
|
||||
|
||||
started, err := queueManagerStarted(ctx)
|
||||
if err != nil {
|
||||
os.Exit(2)
|
||||
return 2
|
||||
}
|
||||
if !started {
|
||||
os.Exit(1)
|
||||
return 1
|
||||
}
|
||||
os.Exit(0)
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
os.Exit(doMain())
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2017, 2021
|
||||
© Copyright IBM Corporation 2017, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -165,7 +165,7 @@ func configureLogger(name string) (mirrorFunc, error) {
|
||||
if err != nil {
|
||||
log.Printf("Failed to unmarshall JSON in log message - %v", err)
|
||||
} else {
|
||||
fmt.Printf(formatBasic(obj))
|
||||
fmt.Print(formatBasic(obj))
|
||||
}
|
||||
} else {
|
||||
// The log being mirrored isn't JSON, so just print it.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2017, 2020
|
||||
© Copyright IBM Corporation 2017, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -131,7 +132,7 @@ func startQueueManager(name string) error {
|
||||
func stopQueueManager(name string) error {
|
||||
log.Println("Stopping queue manager")
|
||||
qmGracePeriod := os.Getenv("MQ_GRACE_PERIOD")
|
||||
isStandby, err := ready.IsRunningAsStandbyQM(name)
|
||||
isStandby, err := ready.IsRunningAsStandbyQM(context.Background(), name)
|
||||
if err != nil {
|
||||
log.Printf("Error getting status for queue manager %v: %v", name, err.Error())
|
||||
return err
|
||||
@@ -141,7 +142,7 @@ func stopQueueManager(name string) error {
|
||||
if isStandby {
|
||||
args = []string{"-x", name}
|
||||
} else {
|
||||
args = []string{"-s", "-w", "-r", "-tp", qmGracePeriod, name}
|
||||
args = []string{"-s", "-w", "-tp", qmGracePeriod, name}
|
||||
}
|
||||
}
|
||||
out, rc, err := command.Run("endmqm", args...)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2017, 2018
|
||||
© Copyright IBM Corporation 2017, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -33,8 +33,8 @@ func signalHandler(qmgr string) chan int {
|
||||
control := make(chan int)
|
||||
// Use separate channels for the signals, to avoid SIGCHLD signals swamping
|
||||
// the buffer, and preventing other signals.
|
||||
stopSignals := make(chan os.Signal)
|
||||
reapSignals := make(chan os.Signal)
|
||||
stopSignals := make(chan os.Signal, 1)
|
||||
reapSignals := make(chan os.Signal, 1)
|
||||
signal.Notify(stopSignals, syscall.SIGTERM, syscall.SIGINT)
|
||||
go func() {
|
||||
for {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
###########################################################################################################################################################
|
||||
|
||||
# MQ_VERSION is the fully qualified MQ version number to build
|
||||
MQ_VERSION ?= 9.2.5.0
|
||||
MQ_VERSION ?= 9.3.1.1
|
||||
|
||||
###########################################################################################################################################################
|
||||
|
||||
34
docs/building.md
Normal file → Executable file
34
docs/building.md
Normal file → Executable file
@@ -4,54 +4,40 @@
|
||||
|
||||
You need to have the following tools installed:
|
||||
|
||||
* [Docker](https://www.docker.com/) V17.06.1 or later, or [Podman](https://podman.io) V1.0 or later
|
||||
* [Docker](https://www.docker.com/) 17.06.1 or later, or [Podman](https://podman.io) 1.0 or later (Podman 4.1 on macOS). If using Podman on macOS, the you need to be in "rootful" mode to allow the use of a network during builds. Run `podman machine init --rootful`.
|
||||
* [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
|
||||
|
||||
From MQ 9.2.X, the MQ container adds support for MQ Long Term Support (LTS) **production licensed** releases.
|
||||
|
||||
### MQ Continuous Delivery (CD)
|
||||
### Building MQ 9.3 Long Term Support (LTS) and Continuous Delivery (CD)
|
||||
|
||||
This procedure works for building the MQ Continuous Delivery release, on `amd64`, `ppc64le` and `s390x` architectures.
|
||||
**Note**: MQ 9.3 is the latest MQ version with MQ Long Term Support (LTS), as well as being the latest Continuous Delivery (CD) version.
|
||||
|
||||
The procedure below is for building the 9.3 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.2.5_LINUX_X86-64_NOINST.tar.gz`) in the `downloads` directory
|
||||
3. Login to the Red Hat Registry: `docker login registry.redhat.io` using your Customer Portal credentials.
|
||||
2. Download MQ from [IBM Passport Advantage](https://www.ibm.com/software/passportadvantage/). Identify the correct 'Long Term Support Release for Containers' eImage part number for your architecture from the 9.3.0 LTS tab at https://www.ibm.com/support/pages/downloading-ibm-mq-930
|
||||
3. Ensure the `tar.gz` file is in the `downloads` directory
|
||||
4. Run `make build-advancedserver`
|
||||
|
||||
> **Warning**: Note that from MQ 9.2.X CD, the MQ container build uses a 'No-Install' MQ Package, available under `IBM MQ V9.2.x Continuous Delivery Release components eAssembly, part no. CJ7CNML`
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
MQ_ARCHIVE=mq-1.2.3.4.tar.gz MQ_VERSION=1.2.3.4 make build-advancedserver
|
||||
```
|
||||
|
||||
### MQ Long Term Support (LTS)
|
||||
### Building previous MQ Long Term Support (LTS)
|
||||
|
||||
This procedure works for building the MQ Long Term Support release, on `amd64`, `ppc64le` and `s390x` architectures.
|
||||
**Note**: MQ 9.3 is the latest MQ version with MQ Long Term Support (LTS), as well as being the latest Continuous Delivery (CD) version. Therefore, to build build 9.3.0.X, follow the [instructions above for MQ 9.3](#building-mq-93-long-term-support-lts-and-continuous-delivery-cd).
|
||||
|
||||
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, `9.2.0.4-IBM-MQ-Advanced-Non-Install-LinuxX86.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 `LTS=true make build-advancedserver`
|
||||
|
||||
> **Warning**: Note that from MQ 9.2 LTS, the MQ container build uses a 'No-Install' MQ Package, available under `IBM MQ V9.2 Long Term Support Release components eAssembly, part no. CXXXXXX`
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
MQ_ARCHIVE=mq-1.2.3.4.tar.gz MQ_VERSION=1.2.3.4 LTS=true make build-advancedserver
|
||||
```
|
||||
However, if you wish to build the previous MQ LTS, use the [instructions](https://github.ibm.com/mq-cloudpak/mq-container/blob/v9.2.0.x-eus/docs/building.md#mq-long-term-support-lts) in the `v9.2.0.x-eus` branch.
|
||||
|
||||
## 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).
|
||||
|
||||
@@ -34,7 +34,7 @@ Two channels are created, one for administration, the other for normal messaging
|
||||
|
||||
## 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.
|
||||
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.
|
||||
|
||||
When you navigate to this page you may be presented with a security exception warning. This happens because, by default, the web console creates a self-signed certificate to use for the HTTPS operations. This certificate is not trusted by your browser and has an incorrect distinguished name.
|
||||
|
||||
|
||||
@@ -16,5 +16,5 @@ docker run \
|
||||
--env LICENSE=accept \
|
||||
--env MQ_QMGR_NAME=QM1 \
|
||||
--detach \
|
||||
ibm-mqadvanced-server:9.2.5.0-amd64
|
||||
ibm-mqadvanced-server:9.3.1.1-amd64
|
||||
```
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
## Prerequisites
|
||||
You need to ensure you have the following tools installed:
|
||||
* [Docker](https://www.docker.com/)
|
||||
* [Docker](https://www.docker.com/) 19.03 or higher (API version 1.40)
|
||||
* [GNU make](https://www.gnu.org/software/make/)
|
||||
* [Go](https://golang.org/) - only needed for running the tests
|
||||
* [dep](https://github.com/golang/dep) (official Go dependency management tool) - needed to prepare for running the tests
|
||||
|
||||
## Running the tests
|
||||
There are two main sets of tests:
|
||||
@@ -18,14 +17,14 @@ There are two main sets of tests:
|
||||
The Docker tests can be run locally on a machine with Docker. For example:
|
||||
|
||||
```
|
||||
make devserver
|
||||
make advancedserver
|
||||
make test-devserver
|
||||
make test-advancedserver
|
||||
```
|
||||
|
||||
You can specify the image to use directly by using the `MQ_IMAGE_ADVANCEDSERVER` or `MQ_IMAGE_DEVSERVER` variables, for example:
|
||||
|
||||
```
|
||||
MQ_IMAGE_ADVANCEDSERVER=ibm-mqadvanced-server:9.2.5.0-amd64 make test-advancedserver
|
||||
MQ_IMAGE_ADVANCEDSERVER=ibm-mqadvanced-server:9.3.1.1-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:
|
||||
|
||||
@@ -14,7 +14,7 @@ docker run \
|
||||
--publish 1414:1414 \
|
||||
--publish 9443:9443 \
|
||||
--detach \
|
||||
ibmcom/mq
|
||||
icr.io/ibm-messaging/mq
|
||||
```
|
||||
|
||||
## Running with the default configuration and a volume
|
||||
@@ -34,7 +34,7 @@ docker run \
|
||||
--publish 9443:9443 \
|
||||
--detach \
|
||||
--volume qm1data:/mnt/mqm \
|
||||
ibmcom/mq
|
||||
icr.io/ibm-messaging/mq
|
||||
```
|
||||
|
||||
The Docker image always uses `/mnt/mqm` for MQ data, which is correctly linked for you under `/var/mqm` at runtime. This is to handle problems with file permissions on some platforms.
|
||||
@@ -51,7 +51,7 @@ docker run \
|
||||
--publish 9443:9443 \
|
||||
--publish 9157:9157 \
|
||||
--detach \
|
||||
ibmcom/mq
|
||||
icr.io/ibm-messaging/mq
|
||||
```
|
||||
|
||||
## Customizing the queue manager configuration
|
||||
@@ -60,14 +60,14 @@ You can customize the configuration in several ways:
|
||||
|
||||
1. For getting started, you can use the [default developer configuration](developer-config.md), which is available out-of-the-box for the MQ Advanced for Developers image
|
||||
2. By creating your own image and adding your own MQSC file into the `/etc/mqm` directory on the image. This file will be run when your queue manager is created.
|
||||
3. By using [remote MQ administration](https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.2.0/com.ibm.mq.adm.doc/q021090_.htm), via an MQ command server, the MQ HTTP APIs, or using a tool such as the MQ web console or MQ Explorer.
|
||||
3. By using [remote MQ administration](https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.3.0/com.ibm.mq.adm.doc/q021090_.htm), via an MQ command server, the MQ HTTP APIs, or using a tool such as the MQ web console or MQ Explorer.
|
||||
|
||||
Note that a listener is always created on port 1414 inside the container. This port can be mapped to any port on the Docker host.
|
||||
|
||||
The following is an *example* `Dockerfile` for creating your own pre-configured image, which adds a custom MQ configuration file:
|
||||
|
||||
```dockerfile
|
||||
FROM ibmcom/mq
|
||||
FROM icr.io/ibm-messaging/mq
|
||||
USER 1001
|
||||
COPY 20-config.mqsc /etc/mqm/
|
||||
```
|
||||
|
||||
4
go.mod
4
go.mod
@@ -8,7 +8,7 @@ require (
|
||||
github.com/prometheus/client_golang v1.11.1
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1
|
||||
software.sslmate.com/src/go-pkcs12 v0.0.0-20200830195227-52f69702a001
|
||||
)
|
||||
|
||||
14
go.sum
14
go.sum
@@ -97,14 +97,15 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f h1:aZp0e2vLN4MToVqnjNEYEtrEA8RH8U8FN1CU7JgqsPU=
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -115,17 +116,20 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
* © Copyright IBM Corporation 2018, 2019
|
||||
* © Copyright IBM Corporation 2018, 2022
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,5 +14,5 @@
|
||||
* limitations under the License.
|
||||
|
||||
* Set the cipherspec for dev channels
|
||||
ALTER CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12) SSLCAUTH(OPTIONAL)
|
||||
ALTER CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12) SSLCAUTH(OPTIONAL)
|
||||
ALTER CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12_OR_HIGHER) SSLCAUTH(OPTIONAL)
|
||||
ALTER CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ANY_TLS12_OR_HIGHER) SSLCAUTH(OPTIONAL)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh -*-
|
||||
# © Copyright IBM Corporation 2015, 2021
|
||||
# © Copyright IBM Corporation 2015, 2022
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -22,6 +22,7 @@ test -f /usr/bin/yum && YUM=true || YUM=false
|
||||
test -f /usr/bin/microdnf && MICRODNF=true || MICRODNF=false
|
||||
test -f /usr/bin/rpm && RPM=true || RPM=false
|
||||
test -f /usr/bin/apt-get && UBUNTU=true || UBUNTU=false
|
||||
CPU_ARCH=$(uname -m)
|
||||
|
||||
if ($UBUNTU); then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
@@ -29,8 +30,7 @@ if ($UBUNTU); then
|
||||
# This ensures no unsupported code gets installed, and makes the build faster
|
||||
source /etc/os-release
|
||||
# Figure out the correct apt URL based on the CPU architecture
|
||||
CPU_ARCH=$(uname -p)
|
||||
if [ ${CPU_ARCH} == "x86_64" ]; then
|
||||
if [ "${CPU_ARCH}" == "x86_64" ]; then
|
||||
APT_URL="http://archive.ubuntu.com/ubuntu/"
|
||||
else
|
||||
APT_URL="http://ports.ubuntu.com/ubuntu-ports/"
|
||||
@@ -41,29 +41,22 @@ if ($UBUNTU); then
|
||||
echo "deb ${APT_URL} ${UBUNTU_CODENAME}-updates main restricted" >> /etc/apt/sources.list
|
||||
echo "deb ${APT_URL} ${UBUNTU_CODENAME}-security main restricted" >> /etc/apt/sources.list
|
||||
# Install additional packages required by MQ, this install process and the runtime scripts
|
||||
EXTRA_DEBS="bash bc ca-certificates coreutils curl debianutils file findutils gawk grep libc-bin mount passwd procps sed tar util-linux"
|
||||
# On ARM CPUs, there is no IBM JRE, so install another one
|
||||
if [ "${CPU_ARCH}" == "aarch64" ]; then
|
||||
EXTRA_DEBS="${EXTRA_DEBS} openjdk-8-jre"
|
||||
fi
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends \
|
||||
bash \
|
||||
bc \
|
||||
ca-certificates \
|
||||
coreutils \
|
||||
curl \
|
||||
debianutils \
|
||||
file \
|
||||
findutils \
|
||||
gawk \
|
||||
grep \
|
||||
libc-bin \
|
||||
mount \
|
||||
passwd \
|
||||
procps \
|
||||
sed \
|
||||
tar \
|
||||
util-linux
|
||||
apt-get install -y --no-install-recommends ${EXTRA_DEBS}
|
||||
fi
|
||||
|
||||
if ($RPM); then
|
||||
EXTRA_RPMS="bash bc ca-certificates file findutils gawk glibc-common grep ncurses-compat-libs passwd procps-ng sed shadow-utils tar util-linux which"
|
||||
# On ARM CPUs, there is no IBM JRE, so install another one
|
||||
if [ "${CPU_ARCH}" == "aarch64" ]; then
|
||||
EXTRA_RPMS="${EXTRA_RPMS} java-1.8.0-openjdk-headless"
|
||||
fi
|
||||
|
||||
# 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 --disableplugin=subscription-manager install ${EXTRA_RPMS}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh -*-
|
||||
# © Copyright IBM Corporation 2015, 2020
|
||||
# © Copyright IBM Corporation 2015, 2022
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -21,17 +21,11 @@ set -ex
|
||||
test -f /usr/bin/rpm && RPM=true || RPM=false
|
||||
test -f /usr/bin/apt-get && UBUNTU=true || UBUNTU=false
|
||||
|
||||
# Only install the SDK package as part of the build stage
|
||||
INSTALL_SDK=${INSTALL_SDK:-0}
|
||||
|
||||
# Download and extract the MQ unzippable server
|
||||
DIR_TMP=/tmp/mq
|
||||
mkdir -p ${DIR_TMP}
|
||||
cd ${DIR_TMP}
|
||||
curl -LO $MQ_URL
|
||||
|
||||
tar -xzf ./*.tar.gz
|
||||
rm -f ./*.tar.gz
|
||||
curl --fail --location $MQ_URL | tar --extract --gunzip
|
||||
ls -la ${DIR_TMP}
|
||||
|
||||
# Generate MQ package in INSTALLATION_DIR
|
||||
@@ -53,7 +47,7 @@ export genmqpkg_incmqxr=0
|
||||
export genmqpkg_incnls=1
|
||||
export genmqpkg_incras=1
|
||||
export genmqpkg_incsamp=1
|
||||
export genmqpkg_incsdk=$INSTALL_SDK
|
||||
export genmqpkg_incsdk=0
|
||||
export genmqpkg_inctls=1
|
||||
export genmqpkg_incunthrd=0
|
||||
export genmqpkg_incweb=1
|
||||
@@ -97,8 +91,8 @@ $RPM && PAM_FILE=/etc/pam.d/password-auth
|
||||
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/' $PAM_FILE
|
||||
|
||||
# List all the installed packages, for the build log
|
||||
$RPM && rpm -q --all || true
|
||||
$UBUNTU && dpkg --list || true
|
||||
$RPM && (rpm -q --all | sort) || true
|
||||
$UBUNTU && (dpkg --list | sort) || 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2017, 2020
|
||||
© Copyright IBM Corporation 2017, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ limitations under the License.
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
)
|
||||
@@ -27,9 +28,13 @@ import (
|
||||
// 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) {
|
||||
return RunContext(context.Background(), name, arg...)
|
||||
}
|
||||
|
||||
func RunContext(ctx context.Context, name string, arg ...string) (string, int, error) {
|
||||
// Run the command and wait for completion
|
||||
// #nosec G204
|
||||
cmd := exec.Command(name, arg...)
|
||||
cmd := exec.CommandContext(ctx, name, arg...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
rc := cmd.ProcessState.ExitCode()
|
||||
if err != nil {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2018, 2020
|
||||
© Copyright IBM Corporation 2018, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -171,8 +171,8 @@ func (ks *KeyStore) GetCertificateLabels() ([]string, error) {
|
||||
var labels []string
|
||||
for scanner.Scan() {
|
||||
s := scanner.Text()
|
||||
if strings.HasPrefix(s, "-") || strings.HasPrefix(s, "*-") {
|
||||
s := strings.TrimLeft(s, "-*")
|
||||
if strings.HasPrefix(s, "-") || strings.HasPrefix(s, "*-") || strings.HasPrefix(s, "!") {
|
||||
s := strings.TrimLeft(s, "-*!")
|
||||
labels = append(labels, strings.TrimSpace(s))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2018, 2019
|
||||
© Copyright IBM Corporation 2018, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -43,7 +43,7 @@ func GatherMetrics(qmName string, log *logger.Logger) {
|
||||
|
||||
// If running in standby mode - wait until the queue manager becomes active
|
||||
for {
|
||||
active, _ := ready.IsRunningAsActiveQM(qmName)
|
||||
active, _ := ready.IsRunningAsActiveQM(context.Background(), qmName)
|
||||
if active {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2018, 2019
|
||||
© Copyright IBM Corporation 2018, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ limitations under the License.
|
||||
package ready
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -67,22 +68,22 @@ func Check() (bool, error) {
|
||||
}
|
||||
|
||||
// IsRunningAsActiveQM returns true if the queue manager is running in active mode
|
||||
func IsRunningAsActiveQM(name string) (bool, error) {
|
||||
return isRunningQM(name, "(RUNNING)")
|
||||
func IsRunningAsActiveQM(ctx context.Context, name string) (bool, error) {
|
||||
return isRunningQM(ctx, name, "(RUNNING)")
|
||||
}
|
||||
|
||||
// IsRunningAsStandbyQM returns true if the queue manager is running in standby mode
|
||||
func IsRunningAsStandbyQM(name string) (bool, error) {
|
||||
return isRunningQM(name, "(RUNNING AS STANDBY)")
|
||||
func IsRunningAsStandbyQM(ctx context.Context, name string) (bool, error) {
|
||||
return isRunningQM(ctx, name, "(RUNNING AS STANDBY)")
|
||||
}
|
||||
|
||||
// IsRunningAsReplicaQM returns true if the queue manager is running in replica mode
|
||||
func IsRunningAsReplicaQM(name string) (bool, error) {
|
||||
return isRunningQM(name, "(REPLICA)")
|
||||
func IsRunningAsReplicaQM(ctx context.Context, name string) (bool, error) {
|
||||
return isRunningQM(ctx, name, "(REPLICA)")
|
||||
}
|
||||
|
||||
func isRunningQM(name string, status string) (bool, error) {
|
||||
out, _, err := command.Run("dspmq", "-n", "-m", name)
|
||||
func isRunningQM(ctx context.Context, name string, status string) (bool, error) {
|
||||
out, _, err := command.RunContext(ctx, "dspmq", "-n", "-m", name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2019, 2021
|
||||
© Copyright IBM Corporation 2019, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -76,18 +76,20 @@ type TLSStore struct {
|
||||
Truststore KeyStoreData
|
||||
}
|
||||
|
||||
func configureTLSKeystores(keystoreDir, keyDir, trustDir string, p12TruststoreRequired bool) (string, KeyStoreData, KeyStoreData, error) {
|
||||
|
||||
func configureTLSKeystores(keystoreDir, keyDir, trustDir string, p12TruststoreRequired bool, nativeTLSHA bool) (string, KeyStoreData, KeyStoreData, error) {
|
||||
var keyLabel string
|
||||
// Create the CMS Keystore & PKCS#12 Truststore (if required)
|
||||
tlsStore, err := generateAllKeystores(keystoreDir, p12TruststoreRequired)
|
||||
tlsStore, err := generateAllKeystores(keystoreDir, p12TruststoreRequired, nativeTLSHA)
|
||||
if err != nil {
|
||||
return "", tlsStore.Keystore, tlsStore.Truststore, err
|
||||
}
|
||||
|
||||
// Process all keys - add them to the CMS KeyStore
|
||||
keyLabel, err := processKeys(&tlsStore, keystoreDir, keyDir)
|
||||
if err != nil {
|
||||
return "", tlsStore.Keystore, tlsStore.Truststore, err
|
||||
if tlsStore.Keystore.Keystore != nil {
|
||||
// Process all keys - add them to the CMS KeyStore
|
||||
keyLabel, err = processKeys(&tlsStore, keystoreDir, keyDir)
|
||||
if err != nil {
|
||||
return "", tlsStore.Keystore, tlsStore.Truststore, err
|
||||
}
|
||||
}
|
||||
|
||||
// Process all trust certificates - add them to the CMS KeyStore & PKCS#12 Truststore (if required)
|
||||
@@ -101,13 +103,13 @@ func configureTLSKeystores(keystoreDir, keyDir, trustDir string, p12TruststoreRe
|
||||
|
||||
// ConfigureDefaultTLSKeystores configures the CMS Keystore & PKCS#12 Truststore
|
||||
func ConfigureDefaultTLSKeystores() (string, KeyStoreData, KeyStoreData, error) {
|
||||
return configureTLSKeystores(keystoreDirDefault, keyDirDefault, trustDirDefault, true)
|
||||
return configureTLSKeystores(keystoreDirDefault, keyDirDefault, trustDirDefault, true, false)
|
||||
}
|
||||
|
||||
// ConfigureHATLSKeystore configures the CMS Keystore & PKCS#12 Truststore
|
||||
func ConfigureHATLSKeystore() (string, KeyStoreData, KeyStoreData, error) {
|
||||
// *.crt files mounted to the HA TLS dir keyDirHA will be processed as trusted in the CMS keystore
|
||||
return configureTLSKeystores(keystoreDirHA, keyDirHA, keyDirHA, false)
|
||||
return configureTLSKeystores(keystoreDirHA, keyDirHA, keyDirHA, false, true)
|
||||
}
|
||||
|
||||
// ConfigureTLS configures TLS for the queue manager
|
||||
@@ -115,9 +117,18 @@ func ConfigureTLS(keyLabel string, cmsKeystore KeyStoreData, devMode bool, log *
|
||||
|
||||
const mqsc string = "/etc/mqm/15-tls.mqsc"
|
||||
const mqscTemplate string = mqsc + ".tpl"
|
||||
sslKeyRing := ""
|
||||
|
||||
// Don't set SSLKEYR if no keys or crts are not supplied
|
||||
// Key label will be blank if no certs were added during processing keys and certs.
|
||||
if cmsKeystore.Keystore != nil {
|
||||
certList, _ := cmsKeystore.Keystore.ListAllCertificates()
|
||||
if len(certList) > 0 {
|
||||
sslKeyRing = strings.TrimSuffix(cmsKeystore.Keystore.Filename, ".kdb")
|
||||
}
|
||||
}
|
||||
err := mqtemplate.ProcessTemplateFile(mqscTemplate, mqsc, map[string]string{
|
||||
"SSLKeyR": strings.TrimSuffix(cmsKeystore.Keystore.Filename, ".kdb"),
|
||||
"SSLKeyR": sslKeyRing,
|
||||
"CertificateLabel": keyLabel,
|
||||
}, log)
|
||||
if err != nil {
|
||||
@@ -159,7 +170,7 @@ func configureTLSDev(log *logger.Logger) error {
|
||||
}
|
||||
|
||||
// generateAllKeystores creates the CMS Keystore & PKCS#12 Truststore (if required)
|
||||
func generateAllKeystores(keystoreDir string, p12TruststoreRequired bool) (TLSStore, error) {
|
||||
func generateAllKeystores(keystoreDir string, p12TruststoreRequired bool, nativeTLSHA bool) (TLSStore, error) {
|
||||
|
||||
var cmsKeystore, p12Truststore KeyStoreData
|
||||
|
||||
@@ -175,11 +186,19 @@ func generateAllKeystores(keystoreDir string, p12TruststoreRequired bool) (TLSSt
|
||||
return TLSStore{cmsKeystore, p12Truststore}, fmt.Errorf("Failed to create Keystore directory: %v", err)
|
||||
}
|
||||
|
||||
// Create the CMS Keystore
|
||||
cmsKeystore.Keystore = keystore.NewCMSKeyStore(filepath.Join(keystoreDir, cmsKeystoreName), cmsKeystore.Password)
|
||||
err = cmsKeystore.Keystore.Create()
|
||||
if err != nil {
|
||||
return TLSStore{cmsKeystore, p12Truststore}, fmt.Errorf("Failed to create CMS Keystore: %v", err)
|
||||
// Search the default keys directory for any keys/certs.
|
||||
keysDirectory := keyDirDefault
|
||||
// Change to default native HA TLS directory if we are configuring nativeHA
|
||||
if nativeTLSHA {
|
||||
keysDirectory = keyDirHA
|
||||
}
|
||||
// Create the CMS Keystore if we have been provided keys and certificates
|
||||
if haveKeysAndCerts(keysDirectory) || haveKeysAndCerts(trustDirDefault) {
|
||||
cmsKeystore.Keystore = keystore.NewCMSKeyStore(filepath.Join(keystoreDir, cmsKeystoreName), cmsKeystore.Password)
|
||||
err = cmsKeystore.Keystore.Create()
|
||||
if err != nil {
|
||||
return TLSStore{cmsKeystore, p12Truststore}, fmt.Errorf("Failed to create CMS Keystore: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create the PKCS#12 Truststore (if required)
|
||||
@@ -203,7 +222,6 @@ func processKeys(tlsStore *TLSStore, keystoreDir string, keyDir string) (string,
|
||||
// Process all keys
|
||||
keyList, err := ioutil.ReadDir(keyDir)
|
||||
if err == nil && len(keyList) > 0 {
|
||||
|
||||
// Process each set of keys - each set should contain files: *.key & *.crt
|
||||
for _, keySet := range keyList {
|
||||
keys, _ := ioutil.ReadDir(filepath.Join(keyDir, keySet.Name()))
|
||||
@@ -602,3 +620,23 @@ func writeCertificatesToFile(file string, certificates []*pem.Block) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Search the specified directory for .key and .crt files.
|
||||
// Return true if at least one .key or .crt file is found else false
|
||||
func haveKeysAndCerts(keyDir string) bool {
|
||||
fileList, err := os.ReadDir(keyDir)
|
||||
if err == nil && len(fileList) > 0 {
|
||||
for _, fileInfo := range fileList {
|
||||
// Keys and certs will be supplied in an user defined subdirectory.
|
||||
// Do a listing of the subdirectory and then search for .key and .cert files
|
||||
keys, _ := ioutil.ReadDir(filepath.Join(keyDir, fileInfo.Name()))
|
||||
for _, key := range keys {
|
||||
if strings.Contains(key.Name(), ".key") || strings.Contains(key.Name(), ".crt") {
|
||||
// We found at least one key/crt file.
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -65,7 +65,6 @@ func ConfigureWebKeystore(p12Truststore KeyStoreData, webKeystore string) (strin
|
||||
// Check if a new self-signed certificate should be generated
|
||||
genHostName := os.Getenv("MQ_GENERATE_CERTIFICATE_HOSTNAME")
|
||||
if genHostName != "" {
|
||||
|
||||
// Create the Web Keystore
|
||||
newWebKeystore := keystore.NewPKCS12KeyStore(webKeystoreFile, p12Truststore.Password)
|
||||
err := newWebKeystore.Create()
|
||||
|
||||
7
source-branch.env
Normal file
7
source-branch.env
Normal file
@@ -0,0 +1,7 @@
|
||||
###########################################################################################################################################################
|
||||
|
||||
# SOURCE_BRANCH is the repository branch name for this release stream.
|
||||
# It should be updated when a new release fork is created but not for testing of personal builds or pre-fork updates.
|
||||
SOURCE_BRANCH ?= v9.3.1
|
||||
|
||||
###########################################################################################################################################################
|
||||
@@ -1,7 +1,8 @@
|
||||
//go:build mqdev
|
||||
// +build mqdev
|
||||
|
||||
/*
|
||||
© Copyright IBM Corporation 2018, 2021
|
||||
© Copyright IBM Corporation 2018, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +35,7 @@ import (
|
||||
func TestDevGoldenPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -51,8 +52,10 @@ func TestDevGoldenPath(t *testing.T) {
|
||||
waitForReady(t, cli, id)
|
||||
waitForWebReady(t, cli, id, insecureTLSConfig)
|
||||
t.Run("JMS", func(t *testing.T) {
|
||||
// Run the JMS tests, with no password specified
|
||||
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS)
|
||||
// Run the JMS tests, with no password specified.
|
||||
// Use OpenJDK JRE for running testing, pass false for 7th parameter.
|
||||
// Last parameter is blank as the test doesn't use TLS.
|
||||
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS, "false", "")
|
||||
})
|
||||
t.Run("REST admin", func(t *testing.T) {
|
||||
testRESTAdmin(t, cli, id, insecureTLSConfig)
|
||||
@@ -69,7 +72,7 @@ func TestDevGoldenPath(t *testing.T) {
|
||||
func TestDevSecure(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -115,7 +118,9 @@ func TestDevSecure(t *testing.T) {
|
||||
waitForWebReady(t, cli, ctr.ID, createTLSConfig(t, cert, tlsPassPhrase))
|
||||
|
||||
t.Run("JMS", func(t *testing.T) {
|
||||
runJMSTests(t, cli, ctr.ID, true, "app", appPassword)
|
||||
// OpenJDK is used for running tests, hence pass "false" for 7th parameter.
|
||||
// Cipher name specified is compliant with non-IBM JRE naming.
|
||||
runJMSTests(t, cli, ctr.ID, true, "app", appPassword, "false", "TLS_RSA_WITH_AES_256_CBC_SHA256")
|
||||
})
|
||||
t.Run("REST admin", func(t *testing.T) {
|
||||
testRESTAdmin(t, cli, ctr.ID, insecureTLSConfig)
|
||||
@@ -131,7 +136,7 @@ func TestDevSecure(t *testing.T) {
|
||||
func TestDevWebDisabled(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -153,7 +158,9 @@ func TestDevWebDisabled(t *testing.T) {
|
||||
})
|
||||
t.Run("JMS", func(t *testing.T) {
|
||||
// Run the JMS tests, with no password specified
|
||||
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS)
|
||||
// OpenJDK is used for running tests, hence pass "false" for 7th parameter.
|
||||
// Last parameter is blank as the test doesn't use TLS.
|
||||
runJMSTests(t, cli, id, false, "app", defaultAppPasswordOS, "false", "")
|
||||
})
|
||||
// Stop the container cleanly
|
||||
stopContainer(t, cli, id)
|
||||
@@ -162,7 +169,7 @@ func TestDevWebDisabled(t *testing.T) {
|
||||
func TestDevConfigDisabled(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -184,3 +191,131 @@ func TestDevConfigDisabled(t *testing.T) {
|
||||
// Stop the container cleanly
|
||||
stopContainer(t, cli, id)
|
||||
}
|
||||
|
||||
// Test if SSLKEYR and CERTLABL attributes are not set when key and certificate
|
||||
// are not supplied.
|
||||
func TestSSLKEYRBlank(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
containerConfig := container.Config{
|
||||
Env: []string{
|
||||
"LICENSE=accept",
|
||||
"MQ_QMGR_NAME=qm1",
|
||||
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
|
||||
},
|
||||
}
|
||||
id := runContainerWithPorts(t, cli, &containerConfig, []int{9443})
|
||||
defer cleanContainer(t, cli, id)
|
||||
waitForReady(t, cli, id)
|
||||
// execute runmqsc to display qmgr SSLKEYR and CERTLABL attibutes.
|
||||
// Search the console output for exepcted values
|
||||
_, sslkeyROutput := execContainer(t, cli, id, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL' | runmqsc"})
|
||||
if !strings.Contains(sslkeyROutput, "SSLKEYR( )") && !strings.Contains(sslkeyROutput, "CERTLABL( )") {
|
||||
t.Errorf("Expected SSLKEYR to be blank but it is not; got \"%v\"", sslkeyROutput)
|
||||
}
|
||||
|
||||
// Stop the container cleanly
|
||||
stopContainer(t, cli, id)
|
||||
}
|
||||
|
||||
// Test if SSLKEYR and CERTLABL attributes are set when key and certificate
|
||||
// are supplied.
|
||||
func TestSSLKEYRWithSuppliedKeyAndCert(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
containerConfig := container.Config{
|
||||
Env: []string{
|
||||
"LICENSE=accept",
|
||||
"MQ_QMGR_NAME=QM1",
|
||||
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
|
||||
},
|
||||
Image: imageName(),
|
||||
}
|
||||
hostConfig := container.HostConfig{
|
||||
Binds: []string{
|
||||
coverageBind(t),
|
||||
tlsDir(t, false) + ":/etc/mqm/pki/keys/default",
|
||||
},
|
||||
}
|
||||
networkingConfig := network.NetworkingConfig{}
|
||||
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer cleanContainer(t, cli, ctr.ID)
|
||||
startContainer(t, cli, ctr.ID)
|
||||
waitForReady(t, cli, ctr.ID)
|
||||
// execute runmqsc to display qmgr SSLKEYR and CERTLABL attibutes.
|
||||
// Search the console output for exepcted values
|
||||
_, sslkeyROutput := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL' | runmqsc"})
|
||||
if !strings.Contains(sslkeyROutput, "SSLKEYR(/run/runmqserver/tls/key)") && !strings.Contains(sslkeyROutput, "CERTLABL(default)") {
|
||||
t.Errorf("Expected SSLKEYR to be '/run/runmqserver/tls/key' but it is not; got \"%v\"", sslkeyROutput)
|
||||
}
|
||||
|
||||
// Stop the container cleanly
|
||||
stopContainer(t, cli, ctr.ID)
|
||||
}
|
||||
|
||||
// Test with CA cert
|
||||
func TestSSLKEYRWithCACert(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
containerConfig := container.Config{
|
||||
Env: []string{
|
||||
"LICENSE=accept",
|
||||
"MQ_QMGR_NAME=QM1",
|
||||
"MQ_ENABLE_EMBEDDED_WEB_SERVER=false",
|
||||
},
|
||||
Image: imageName(),
|
||||
}
|
||||
hostConfig := container.HostConfig{
|
||||
Binds: []string{
|
||||
coverageBind(t),
|
||||
tlsDirWithCA(t, false) + ":/etc/mqm/pki/keys/QM1CA",
|
||||
},
|
||||
// Assign a random port for the web server on the host
|
||||
PortBindings: nat.PortMap{
|
||||
"9443/tcp": []nat.PortBinding{
|
||||
{
|
||||
HostIP: "0.0.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
networkingConfig := network.NetworkingConfig{}
|
||||
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer cleanContainer(t, cli, ctr.ID)
|
||||
startContainer(t, cli, ctr.ID)
|
||||
waitForReady(t, cli, ctr.ID)
|
||||
|
||||
// execute runmqsc to display qmgr SSLKEYR and CERTLABL attibutes.
|
||||
// Search the console output for exepcted values
|
||||
_, sslkeyROutput := execContainer(t, cli, ctr.ID, "", []string{"bash", "-c", "echo 'DISPLAY QMGR SSLKEYR CERTLABL' | runmqsc"})
|
||||
if !strings.Contains(sslkeyROutput, "SSLKEYR(/run/runmqserver/tls/key)") {
|
||||
t.Errorf("Expected SSLKEYR to be '/run/runmqserver/tls/key' but it is not; got \"%v\"", sslkeyROutput)
|
||||
}
|
||||
|
||||
if !strings.Contains(sslkeyROutput, "CERTLABL(QM1CA)") {
|
||||
t.Errorf("Expected CERTLABL to be 'QM1CA' but it is not; got \"%v\"", sslkeyROutput)
|
||||
}
|
||||
|
||||
// Stop the container cleanly
|
||||
stopContainer(t, cli, ctr.ID)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//go:build mqdev
|
||||
// +build mqdev
|
||||
|
||||
/*
|
||||
© Copyright IBM Corporation 2018, 2021
|
||||
© Copyright IBM Corporation 2018, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +19,7 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
@@ -26,8 +28,8 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -80,15 +82,19 @@ func tlsDir(t *testing.T, unixPath bool) string {
|
||||
return filepath.Join(getCwd(t, unixPath), "../tls")
|
||||
}
|
||||
|
||||
func tlsDirWithCA(t *testing.T, unixPath bool) string {
|
||||
return filepath.Join(getCwd(t, unixPath), "../tlscacert")
|
||||
}
|
||||
|
||||
// runJMSTests runs a container with a JMS client, which connects to the queue manager container with the specified ID
|
||||
func runJMSTests(t *testing.T, cli *client.Client, ID string, tls bool, user, password string) {
|
||||
func runJMSTests(t *testing.T, cli *client.Client, ID string, tls bool, user, password string, ibmjre string, cipherName string) {
|
||||
containerConfig := container.Config{
|
||||
// -e MQ_PORT_1414_TCP_ADDR=9.145.14.173 -e MQ_USERNAME=app -e MQ_PASSWORD=passw0rd -e MQ_CHANNEL=DEV.APP.SVRCONN -e MQ_TLS_TRUSTSTORE=/tls/test.p12 -e MQ_TLS_PASSPHRASE=passw0rd -v /Users/arthurbarr/go/src/github.com/ibm-messaging/mq-container/test/tls:/tls msgtest
|
||||
Env: []string{
|
||||
"MQ_PORT_1414_TCP_ADDR=" + getIPAddress(t, cli, ID),
|
||||
"MQ_USERNAME=" + user,
|
||||
"MQ_CHANNEL=DEV.APP.SVRCONN",
|
||||
"IBMJRE=" + os.Getenv("IBMJRE"),
|
||||
"IBMJRE=" + ibmjre,
|
||||
},
|
||||
Image: imageNameDevJMS(),
|
||||
}
|
||||
@@ -101,6 +107,7 @@ func runJMSTests(t *testing.T, cli *client.Client, ID string, tls bool, user, pa
|
||||
containerConfig.Env = append(containerConfig.Env, []string{
|
||||
"MQ_TLS_TRUSTSTORE=/var/tls/client-trust.jks",
|
||||
"MQ_TLS_PASSPHRASE=passw0rd",
|
||||
"MQ_TLS_CIPHER=" + cipherName,
|
||||
}...)
|
||||
}
|
||||
hostConfig := container.HostConfig{
|
||||
@@ -119,9 +126,57 @@ func runJMSTests(t *testing.T, cli *client.Client, ID string, tls bool, user, pa
|
||||
if rc != 0 {
|
||||
t.Errorf("JUnit container failed with rc=%v", rc)
|
||||
}
|
||||
|
||||
// Get console output of the container and process the lines
|
||||
// to see if we have any failures
|
||||
scanner := bufio.NewScanner(strings.NewReader(inspectLogs(t, cli, ctr.ID)))
|
||||
for scanner.Scan() {
|
||||
s := scanner.Text()
|
||||
if processJunitLogLine(s) {
|
||||
t.Errorf("JUnit container tests failed. Reason: %s", s)
|
||||
}
|
||||
}
|
||||
|
||||
defer cleanContainer(t, cli, ctr.ID)
|
||||
}
|
||||
|
||||
// Parse JUnit log line and return true if line contains failed or aborted tests
|
||||
func processJunitLogLine(outputLine string) bool {
|
||||
var failedLine bool
|
||||
// Sample JUnit test run output
|
||||
//[ 2 containers found ]
|
||||
//[ 0 containers skipped ]
|
||||
//[ 2 containers started ]
|
||||
//[ 0 containers aborted ]
|
||||
//[ 2 containers successful ]
|
||||
//[ 0 containers failed ]
|
||||
//[ 0 tests found ]
|
||||
//[ 0 tests skipped ]
|
||||
//[ 0 tests started ]
|
||||
//[ 0 tests aborted ]
|
||||
//[ 0 tests successful ]
|
||||
//[ 0 tests failed ]
|
||||
|
||||
// Consider only those lines that begin with '[' and with ']'
|
||||
if strings.HasPrefix(outputLine, "[") && strings.HasSuffix(outputLine, "]") {
|
||||
// Strip off [] and whitespaces
|
||||
trimmed := strings.Trim(outputLine, "[] ")
|
||||
if strings.Contains(trimmed, "aborted") || strings.Contains(trimmed, "failed") {
|
||||
// Tokenize on whitespace
|
||||
tokens := strings.Split(trimmed, " ")
|
||||
// Determine the count of aborted or failed tests
|
||||
count, err := strconv.Atoi(tokens[0])
|
||||
if err == nil {
|
||||
if count > 0 {
|
||||
failedLine = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return failedLine
|
||||
}
|
||||
|
||||
// createTLSConfig creates a tls.Config which trusts the specified certificate
|
||||
func createTLSConfig(t *testing.T, certFile, password string) *tls.Config {
|
||||
// Get the SystemCertPool, continue with an empty pool on error
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2017, 2020
|
||||
© Copyright IBM Corporation 2017, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -38,7 +38,7 @@ import (
|
||||
func TestLicenseNotSet(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -52,10 +52,12 @@ func TestLicenseNotSet(t *testing.T) {
|
||||
expectTerminationMessage(t, cli, id)
|
||||
}
|
||||
|
||||
//Start container with LICENSE environment variable set to view.
|
||||
//Check that container starts and display license text
|
||||
func TestLicenseView(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -79,7 +81,7 @@ func TestLicenseView(t *testing.T) {
|
||||
//Check that when the container is stopped that the command endmqm has option -tp and x
|
||||
func TestEndMQMOpts(t *testing.T) {
|
||||
t.Parallel()
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -114,7 +116,7 @@ func TestGoldenPathNoMetrics(t *testing.T) {
|
||||
|
||||
// Actual test function for TestGoldenPathNoMetrics & TestGoldenPathWithMetrics
|
||||
func goldenPath(t *testing.T, metric bool) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -132,46 +134,10 @@ func goldenPath(t *testing.T, metric bool) {
|
||||
stopContainer(t, cli, id)
|
||||
}
|
||||
|
||||
// TestSecurityVulnerabilities checks for any vulnerabilities in the image, as reported
|
||||
// by Red Hat
|
||||
func TestSecurityVulnerabilities(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rc, _ := runContainerOneShot(t, cli, "bash", "-c", "command -v microdnf && test -e /etc/yum.repos.d/ubi.repo")
|
||||
if rc != 0 {
|
||||
t.Skip("Skipping test because container is based on ubi-minimal, which doesn't include yum")
|
||||
}
|
||||
// id, _, err := command.Run("sudo", "buildah", "from", imageName())
|
||||
// if err != nil {
|
||||
// t.Log(id)
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// id = strings.TrimSpace(id)
|
||||
// defer command.Run("buildah", "rm", id)
|
||||
// mnt, _, err := command.Run("sudo", "buildah", "mount", id)
|
||||
// if err != nil {
|
||||
// t.Log(mnt)
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// mnt = strings.TrimSpace(mnt)
|
||||
// out, _, err := command.Run("bash", "-c", "sudo cp /etc/yum.repos.d/* "+filepath.Join(mnt, "/etc/yum.repos.d/"))
|
||||
// if err != nil {
|
||||
// t.Log(out)
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// out, ret, _ := command.Run("bash", "-c", "yum --installroot="+mnt+" updateinfo list sec | grep /Sec")
|
||||
// if ret != 1 {
|
||||
// t.Errorf("Expected no vulnerabilities, found the following:\n%v", out)
|
||||
// }
|
||||
}
|
||||
|
||||
func utilTestNoQueueManagerName(t *testing.T, hostName string, expectedName string) {
|
||||
search := "QMNAME(" + expectedName + ")"
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -187,6 +153,7 @@ func utilTestNoQueueManagerName(t *testing.T, hostName string, expectedName stri
|
||||
t.Errorf("Expected result of running dspmq to contain name=%v, got name=%v", search, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoQueueManagerName(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -217,7 +184,7 @@ func TestWithVolumeNoMetrics(t *testing.T) {
|
||||
|
||||
// Actual test function for TestWithVolumeNoMetrics & TestWithVolumeAndMetrics
|
||||
func withVolume(t *testing.T, metric bool) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -261,7 +228,7 @@ func withVolume(t *testing.T, metric bool) {
|
||||
|
||||
// TestWithSplitVolumesLogsData starts a queue manager with separate log/data mounts
|
||||
func TestWithSplitVolumesLogsData(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -281,7 +248,7 @@ func TestWithSplitVolumesLogsData(t *testing.T) {
|
||||
|
||||
// TestWithSplitVolumesLogsOnly starts a queue manager with a separate log mount
|
||||
func TestWithSplitVolumesLogsOnly(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -299,7 +266,7 @@ func TestWithSplitVolumesLogsOnly(t *testing.T) {
|
||||
|
||||
// TestWithSplitVolumesDataOnly starts a queue manager with a separate data mount
|
||||
func TestWithSplitVolumesDataOnly(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -320,7 +287,7 @@ func TestWithSplitVolumesDataOnly(t *testing.T) {
|
||||
func TestNoVolumeWithRestart(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -340,7 +307,7 @@ func TestNoVolumeWithRestart(t *testing.T) {
|
||||
// where `runmqserver -i` is run to initialize the storage. Then the
|
||||
// container can be run as normal.
|
||||
func TestVolumeRequiresRoot(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -403,7 +370,7 @@ func TestVolumeRequiresRoot(t *testing.T) {
|
||||
func TestCreateQueueManagerFail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -436,7 +403,7 @@ func TestCreateQueueManagerFail(t *testing.T) {
|
||||
func TestStartQueueManagerFail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -472,7 +439,7 @@ func TestStartQueueManagerFail(t *testing.T) {
|
||||
func TestVolumeUnmount(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -521,7 +488,7 @@ func TestVolumeUnmount(t *testing.T) {
|
||||
func TestZombies(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -558,7 +525,7 @@ func TestZombies(t *testing.T) {
|
||||
func TestMQSC(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -605,7 +572,7 @@ func TestMQSC(t *testing.T) {
|
||||
func TestLargeMQSC(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -657,7 +624,7 @@ func TestLargeMQSC(t *testing.T) {
|
||||
func TestRedactValidMQSC(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -735,7 +702,7 @@ func TestRedactValidMQSC(t *testing.T) {
|
||||
func TestRedactInvalidMQSC(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -808,7 +775,7 @@ func TestRedactInvalidMQSC(t *testing.T) {
|
||||
// tries to start a container based on that image, and checks that container terminates
|
||||
func TestInvalidMQSC(t *testing.T) {
|
||||
t.Parallel()
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -842,7 +809,7 @@ func TestInvalidMQSC(t *testing.T) {
|
||||
|
||||
func TestSimpleMQIniMerge(t *testing.T) {
|
||||
t.Parallel()
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -880,7 +847,7 @@ func TestSimpleMQIniMerge(t *testing.T) {
|
||||
}
|
||||
func TestMultipleIniMerge(t *testing.T) {
|
||||
t.Parallel()
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -929,7 +896,7 @@ func TestMultipleIniMerge(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1027,7 +994,7 @@ func TestMQIniMergeOnTheSameVolumeButTwoContainers(t *testing.T) {
|
||||
func TestReadiness(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1090,7 +1057,7 @@ func TestErrorLogRotation(t *testing.T) {
|
||||
t.Skipf("Skipping %v until test defect fixed", t.Name())
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1180,7 +1147,7 @@ func TestJSONLogFormatNoMetrics(t *testing.T) {
|
||||
|
||||
// Actual test function for TestJSONLogFormatWithMetrics & TestJSONLogFormatNoMetrics
|
||||
func jsonLogFormat(t *testing.T, metric bool) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1216,7 +1183,7 @@ func jsonLogFormat(t *testing.T, metric bool) {
|
||||
func TestBadLogFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1240,7 +1207,7 @@ func TestBadLogFormat(t *testing.T) {
|
||||
func TestMQJSONDisabled(t *testing.T) {
|
||||
t.SkipNow()
|
||||
t.Parallel()
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1268,7 +1235,7 @@ func TestCorrectLicense(t *testing.T) {
|
||||
t.Fatal("Required test environment variable 'EXPECTED_LICENSE' was not set.")
|
||||
}
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1293,7 +1260,7 @@ func TestCorrectLicense(t *testing.T) {
|
||||
func TestVersioning(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1414,7 +1381,7 @@ func TestVersioning(t *testing.T) {
|
||||
func TestTraceStrmqm(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1439,7 +1406,7 @@ func TestTraceStrmqm(t *testing.T) {
|
||||
// privileges enabled or disabled. Otherwise the same as the golden path tests.
|
||||
func utilTestHealthCheck(t *testing.T, nonewpriv bool) {
|
||||
t.Parallel()
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1480,7 +1447,7 @@ func TestHealthCheckWithNewPrivileges(t *testing.T) {
|
||||
// privileges enabled or disabled. Otherwise the same as the golden path tests.
|
||||
func utilTestStartedCheck(t *testing.T, nonewpriv bool) {
|
||||
t.Parallel()
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2017, 2021
|
||||
© Copyright IBM Corporation 2017, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -548,9 +548,14 @@ func getCoverageExitCode(t *testing.T, orig int64) int64 {
|
||||
func waitForContainer(t *testing.T, cli *client.Client, ID string, timeout time.Duration) int64 {
|
||||
c, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
rc, err := cli.ContainerWait(c, ID)
|
||||
if err != nil {
|
||||
t.Logf("Waiting for container for %s", timeout)
|
||||
okC, errC := cli.ContainerWait(c, ID, container.WaitConditionNotRunning)
|
||||
var rc int64
|
||||
select {
|
||||
case err := <-errC:
|
||||
t.Fatal(err)
|
||||
case ok := <-okC:
|
||||
rc = ok.StatusCode
|
||||
}
|
||||
if coverage() {
|
||||
// COVERAGE: When running coverage, the exit code is written to a file,
|
||||
@@ -579,7 +584,7 @@ func execContainer(t *testing.T, cli *client.Client, ID string, user string, cmd
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hijack, err := cli.ContainerExecAttach(context.Background(), resp.ID, config)
|
||||
hijack, err := cli.ContainerExecAttach(context.Background(), resp.ID, types.ExecStartCheck{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -686,7 +691,7 @@ func removeNetwork(t *testing.T, cli *client.Client, ID string) {
|
||||
}
|
||||
|
||||
func createVolume(t *testing.T, cli *client.Client, name string) types.Volume {
|
||||
v, err := cli.VolumeCreate(context.Background(), volume.VolumesCreateBody{
|
||||
v, err := cli.VolumeCreate(context.Background(), volume.VolumeCreateBody{
|
||||
Driver: "local",
|
||||
DriverOpts: map[string]string{},
|
||||
Labels: map[string]string{},
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
module github.com/ibm-messaging/mq-container/test/docker
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.14 // indirect
|
||||
github.com/Sirupsen/logrus v1.0.5 // indirect
|
||||
github.com/docker/distribution v2.8.0+incompatible // indirect
|
||||
github.com/docker/docker v1.13.2-0.20170601211448-f5ec1e2936dc
|
||||
github.com/containerd/containerd v1.6.6 // indirect
|
||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||
// Note: This is not actually Docker v17.12!
|
||||
// Go modules require the use of semver, but Docker does not use semver and has not
|
||||
// [opted-in to use Go modules](https://github.com/golang/go/wiki/Modules#can-a-module-consume-a-package-that-has-not-opted-in-to-modules)
|
||||
// This means that when you `go get` Docker, you need to do so based on a commit,
|
||||
// e.g. `go get -v github.com/docker/docker@420b1d36250f9cfdc561f086f25a213ecb669b6f`,
|
||||
// which uses the commit for [Docker v19.03.15](https://github.com/moby/moby/releases/tag/v19.03.15)
|
||||
// Go will then find the latest tag with a semver-compatible tag. In Docker's case,
|
||||
// v17.12.0 is valid semver, but v18.09 and v19.03 are not.
|
||||
// Also note: Docker v20.10 is valid semver, but the v20.10 client API requires use of Docker API
|
||||
// version 1.41 on the server, which is currently too new for the version of Docker in Travis (Ubuntu Bionic)
|
||||
github.com/docker/docker v17.12.0-ce-rc1.0.20210128214336-420b1d36250f+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/onsi/ginkgo v1.14.1 // indirect
|
||||
github.com/onsi/gomega v1.10.2 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/stretchr/testify v1.3.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect
|
||||
google.golang.org/grpc v1.46.0 // indirect
|
||||
)
|
||||
|
||||
1376
test/docker/go.sum
1376
test/docker/go.sum
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2019, 2020
|
||||
© Copyright IBM Corporation 2019, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -33,7 +34,7 @@ var miEnv = []string{
|
||||
// and starts/stop them checking we always have an active and standby
|
||||
func TestMultiInstanceStartStop(t *testing.T) {
|
||||
t.Skipf("Skipping %v until test defect fixed", t.Name())
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -75,7 +76,7 @@ func TestMultiInstanceStartStop(t *testing.T) {
|
||||
// TestMultiInstanceContainerStop starts 2 containers in a multi instance queue manager configuration,
|
||||
// stops the active queue manager, then checks to ensure the backup queue manager becomes active
|
||||
func TestMultiInstanceContainerStop(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -92,15 +93,28 @@ func TestMultiInstanceContainerStop(t *testing.T) {
|
||||
waitForReady(t, cli, qm1aId)
|
||||
waitForReady(t, cli, qm1bId)
|
||||
|
||||
err, active, standby := getActiveStandbyQueueManager(t, cli, qm1aId, qm1bId)
|
||||
err, originalActive, originalStandby := getActiveStandbyQueueManager(t, cli, qm1aId, qm1bId)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stopContainer(t, cli, active)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
stopContainer(t, cli, originalActive)
|
||||
|
||||
if status := getQueueManagerStatus(t, cli, standby, "QM1"); strings.Compare(status, "Running") != 0 {
|
||||
t.Fatalf("Expected QM1 to be running as active queue manager, dspmq returned status of %v", status)
|
||||
for {
|
||||
status := getQueueManagerStatus(t, cli, originalStandby, "QM1")
|
||||
select {
|
||||
case <-time.After(1 * time.Second):
|
||||
if status == "Running" {
|
||||
t.Logf("Original standby is now the active")
|
||||
return
|
||||
} else if status == "Starting" {
|
||||
t.Logf("Original standby is starting")
|
||||
}
|
||||
case <-ctx.Done():
|
||||
t.Fatalf("%s Timed out waiting for standby to become the active. Status=%v", time.Now().Format(time.RFC3339), status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +123,7 @@ func TestMultiInstanceContainerStop(t *testing.T) {
|
||||
func TestMultiInstanceRace(t *testing.T) {
|
||||
t.Skipf("Skipping %v until file lock is implemented", t.Name())
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -155,7 +169,7 @@ func TestMultiInstanceRace(t *testing.T) {
|
||||
// mounts, then checks to ensure that the container terminates with the expected message
|
||||
func TestMultiInstanceNoSharedMounts(t *testing.T) {
|
||||
t.Parallel()
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -174,7 +188,7 @@ func TestMultiInstanceNoSharedMounts(t *testing.T) {
|
||||
// TestMultiInstanceNoSharedLogs starts 2 multi instance queue managers without providing a shared log
|
||||
// mount, then checks to ensure that the container terminates with the expected message
|
||||
func TestMultiInstanceNoSharedLogs(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -196,7 +210,7 @@ func TestMultiInstanceNoSharedLogs(t *testing.T) {
|
||||
// TestMultiInstanceNoSharedData starts 2 multi instance queue managers without providing a shared data
|
||||
// mount, then checks to ensure that the container terminates with the expected message
|
||||
func TestMultiInstanceNoSharedData(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -218,7 +232,7 @@ func TestMultiInstanceNoSharedData(t *testing.T) {
|
||||
// TestMultiInstanceNoMounts starts 2 multi instance queue managers without providing a shared data
|
||||
// mount, then checks to ensure that the container terminates with the expected message
|
||||
func TestMultiInstanceNoMounts(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2019
|
||||
© Copyright IBM Corporation 2019, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -77,6 +77,7 @@ func getActiveStandbyQueueManager(t *testing.T, cli *client.Client, qm1aId strin
|
||||
|
||||
func getQueueManagerStatus(t *testing.T, cli *client.Client, containerID string, queueManagerName string) string {
|
||||
_, dspmqOut := execContainer(t, cli, containerID, "", []string{"bash", "-c", "dspmq", "-m", queueManagerName})
|
||||
t.Logf("dspmq for %v (%v) returned: %v", containerID, queueManagerName, dspmqOut)
|
||||
regex := regexp.MustCompile(`STATUS\(.*\)`)
|
||||
status := regex.FindString(dspmqOut)
|
||||
status = strings.TrimSuffix(strings.TrimPrefix(status, "STATUS("), ")")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2021
|
||||
© Copyright IBM Corporation 2021, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
// TestNativeHABasic creates 3 containers in a Native HA queue manager configuration
|
||||
// and ensures the queue manger and replicas start as expected
|
||||
func TestNativeHABasic(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func TestNativeHABasic(t *testing.T) {
|
||||
// queue manager comes back as a replica
|
||||
func TestNativeHAFailover(t *testing.T) {
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -132,7 +132,7 @@ func TestNativeHAFailover(t *testing.T) {
|
||||
// TestNativeHASecure creates 3 containers in a Native HA queue manager configuration
|
||||
// with HA TLS enabled, and ensures the queue manger and replicas start as expected
|
||||
func TestNativeHASecure(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -177,7 +177,7 @@ func TestNativeHASecure(t *testing.T) {
|
||||
// with HA TLS enabled, overrides the default CipherSpec, and ensures the queue manger
|
||||
// and replicas start as expected
|
||||
func TestNativeHASecureCipherSpec(t *testing.T) {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2018, 2019
|
||||
© Copyright IBM Corporation 2018, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
func TestGoldenPathMetric(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func TestGoldenPathMetric(t *testing.T) {
|
||||
func TestMetricNames(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -100,7 +100,7 @@ func TestMetricLabels(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
requiredLabels := []string{"qmgr"}
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func TestMetricLabels(t *testing.T) {
|
||||
func TestRapidFirePrometheus(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -182,7 +182,7 @@ func TestRapidFirePrometheus(t *testing.T) {
|
||||
func TestSlowPrometheus(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -213,7 +213,7 @@ func TestSlowPrometheus(t *testing.T) {
|
||||
func TestContainerRestart(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -261,7 +261,7 @@ func TestContainerRestart(t *testing.T) {
|
||||
func TestQMRestart(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -319,7 +319,7 @@ func TestQMRestart(t *testing.T) {
|
||||
func TestValidValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -355,7 +355,7 @@ func TestValidValues(t *testing.T) {
|
||||
func TestChangingValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Copyright IBM Corporation 2018, 2021
|
||||
# © Copyright IBM Corporation 2018, 2022
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -15,24 +15,24 @@
|
||||
###############################################################################
|
||||
# Application build environment (Maven)
|
||||
###############################################################################
|
||||
FROM registry.redhat.io/ubi8/openjdk-8 as builder
|
||||
COPY pom.xml .
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-8 as builder
|
||||
COPY pom.xml ./
|
||||
#WORKDIR /usr/src/mymaven
|
||||
# Download dependencies separately, so Docker caches them
|
||||
RUN mvn dependency:go-offline install
|
||||
# Copy source
|
||||
COPY src .
|
||||
COPY src ./src
|
||||
# Run the main build
|
||||
RUN mvn --offline install
|
||||
# Print a list of all the files (useful for debugging)
|
||||
RUN find .
|
||||
RUN find ./
|
||||
|
||||
###############################################################################
|
||||
# Application runtime (JRE only, no build environment)
|
||||
###############################################################################
|
||||
# OpenJDK is not technically supported with the MQ client, but is good enough for these tests
|
||||
FROM registry.redhat.io/ubi8/openjdk-8-runtime
|
||||
FROM registry.access.redhat.com/ubi8/openjdk-8-runtime
|
||||
COPY --from=builder /home/jboss/target/*.jar /opt/app/
|
||||
COPY --from=builder /home/jboss/target/lib/*.jar /opt/app/
|
||||
USER 1001
|
||||
ENTRYPOINT ["java", "-classpath", "/opt/app/*", "org.junit.platform.console.ConsoleLauncher", "-p", "com.ibm.mqcontainer.test", "--details", "verbose"]
|
||||
ENTRYPOINT ["java", "-classpath", "/opt/app/*", "org.junit.platform.console.ConsoleLauncher", "--fail-if-no-tests", "-p", "com.ibm.mqcontainer.test", "--details", "verbose"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--
|
||||
© Copyright IBM Corporation 2018, 2021
|
||||
© Copyright IBM Corporation 2018, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -26,25 +26,25 @@ limitations under the License.
|
||||
<dependency>
|
||||
<groupId>com.ibm.mq</groupId>
|
||||
<artifactId>com.ibm.mq.allclient</artifactId>
|
||||
<version>9.2.0.0</version>
|
||||
<version>9.3.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.5.2</version>
|
||||
<version>5.8.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.5.2</version>
|
||||
<version>5.8.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-console-standalone</artifactId>
|
||||
<version>1.5.2</version>
|
||||
<version>1.8.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2018, 2021
|
||||
© Copyright IBM Corporation 2018, 2022
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -82,11 +82,10 @@ class JMSTests {
|
||||
boolean ibmjre = System.getenv("IBMJRE").equals("true");
|
||||
if (ibmjre){
|
||||
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "true");
|
||||
factory.setSSLCipherSuite("SSL_RSA_WITH_AES_128_CBC_SHA256");
|
||||
} else {
|
||||
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false");
|
||||
factory.setSSLCipherSuite("TLS_RSA_WITH_AES_128_CBC_SHA256");
|
||||
}
|
||||
factory.setSSLCipherSuite(System.getenv("MQ_TLS_CIPHER"));
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
23
test/tlscacert/cacert.crt
Normal file
23
test/tlscacert/cacert.crt
Normal file
@@ -0,0 +1,23 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDxTCCAq2gAwIBAgIUc5EKoPi8cg2M2n+SqCPn44LFjoAwDQYJKoZIhvcNAQEL
|
||||
BQAwcjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQHDAhOZXcgWW9y
|
||||
azEMMAoGA1UECgwDSUJNMQwwCgYDVQQLDANJQk0xDDAKBgNVBAMMA0lCTTEZMBcG
|
||||
CSqGSIb3DQEJARYKbXFAaWJtLmNvbTAeFw0yMjEwMDYxMzA2NTVaFw0zMjEwMDMx
|
||||
MzA2NTVaMHIxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOWTERMA8GA1UEBwwITmV3
|
||||
IFlvcmsxDDAKBgNVBAoMA0lCTTEMMAoGA1UECwwDSUJNMQwwCgYDVQQDDANJQk0x
|
||||
GTAXBgkqhkiG9w0BCQEWCm1xQGlibS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||
DwAwggEKAoIBAQCls3oNIDxzKct0NXVsoz1Hng3BcaDPcBRYCNgAEwDOVe3rEEbZ
|
||||
d2KFliDgCG3hCHMM1Yaabx3iTVsKklubBxr1JFmyDtgb4z9mJpMVYXS+gsKsZOs/
|
||||
vNSmzpt5VlbEadHKJ/aFf/EWxvoOP80UiEeUJt36aWFUTyjjyArd2xS8fD1DATFB
|
||||
U2bteaWfkpuLeFiTtwftZhsLv1s5T35+Ex087eX1tkm/TArxZsNl/9RrSWsbJh/t
|
||||
bjiRKn+fCZdirFsurP3Si5Jd9laCW0RBKAKYEh40XYDgjLhvcazDPTBueTHXQPG5
|
||||
S0hCOhCJiCWpPCsh8rIOCz0D9YIByZADR1WvAgMBAAGjUzBRMB0GA1UdDgQWBBS5
|
||||
OsiPqZXlMwpMqGKczUg3qVvy0zAfBgNVHSMEGDAWgBS5OsiPqZXlMwpMqGKczUg3
|
||||
qVvy0zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBfwYRcckke
|
||||
/NzDHlFb8TBlUDqERmlT/qTWamVZO2Zuo4Y0BFOYFEA23F5sQU2s2MFSEZcAKe5v
|
||||
mJroFE2rr4aY4bJ4Z0UXlOAYyqNxVOTI4MIxwbg3GVr8c8oWBnAmgqI9W9OpgZ52
|
||||
/bN24XL9s6I3TeOTtYI9z5O70Kl/E3nG8GcfMw0EtNIy0UPUWvJH8FgEsotsRO9v
|
||||
tPtlZklEK/D+Keozbs2shdNhKgVnDatpdTBqvwLztb1+te5AckuOnJsnG+iIrG2D
|
||||
Ehoq2O3gktIVdAk4sv2BoONzegLWB+GSxGVZsemfYF4PkN9/w+znz0LK/ATAtabK
|
||||
rikk0yC+Xg8z
|
||||
-----END CERTIFICATE-----
|
||||
34
test/tlscacert/generate-test-cert.sh
Normal file
34
test/tlscacert/generate-test-cert.sh
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash -ex
|
||||
# -*- mode: sh -*-
|
||||
# © Copyright IBM Corporation 2018, 2022
|
||||
#
|
||||
# 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.
|
||||
|
||||
KEY=server.key
|
||||
CERT=server.crt
|
||||
CACERT=cacert.crt
|
||||
CAPEM=rootcakey.pem
|
||||
|
||||
# Create a private key and certificate in PEM format, for the server to use
|
||||
openssl req \
|
||||
-newkey rsa:2048 -nodes -keyout ${KEY} \
|
||||
-subj "/CN=localhost" \
|
||||
-addext "subjectAltName = DNS:localhost" \
|
||||
-x509 -days 3650 -out ${CERT}
|
||||
|
||||
# Generate the private key of the root CA
|
||||
openssl genrsa -out ${CAPEM} 2048
|
||||
|
||||
#Generate the self-signed root CA certificate. Manual input is required when prompted
|
||||
openssl req -x509 -sha256 -new -nodes -key ${CAPEM} -days 3650 -out ${CACERT}
|
||||
|
||||
27
test/tlscacert/rootcakey.pem
Normal file
27
test/tlscacert/rootcakey.pem
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEApbN6DSA8cynLdDV1bKM9R54NwXGgz3AUWAjYABMAzlXt6xBG
|
||||
2XdihZYg4Aht4QhzDNWGmm8d4k1bCpJbmwca9SRZsg7YG+M/ZiaTFWF0voLCrGTr
|
||||
P7zUps6beVZWxGnRyif2hX/xFsb6Dj/NFIhHlCbd+mlhVE8o48gK3dsUvHw9QwEx
|
||||
QVNm7Xmln5Kbi3hYk7cH7WYbC79bOU9+fhMdPO3l9bZJv0wK8WbDZf/Ua0lrGyYf
|
||||
7W44kSp/nwmXYqxbLqz90ouSXfZWgltEQSgCmBIeNF2A4Iy4b3Gswz0wbnkx10Dx
|
||||
uUtIQjoQiYglqTwrIfKyDgs9A/WCAcmQA0dVrwIDAQABAoIBAQCcL9ZltPMF4mlh
|
||||
+lnasuu6K+LvafmYTh7+9CcVutPRqfF+1nLR3NRC8sW+JnPb36kCeepMe1yByUR9
|
||||
bINoV4QzebYKPi+56bQCx21wg9IVGRACi4WrKISRTsIB1z4mGVCj6pNWNsi7HYbq
|
||||
E31tUx+VKCWoOdiCLbNvMUn84Npk5npK9P9F86qypSJqJv3HORgOa58x7qZiD2fk
|
||||
TroLuGHKFWGtSiK1vvgax8gBwMi9JvWoPhwHagINh0WwT820+3/4KbqcsvRNSIu8
|
||||
qA+ltk/Vt0ftwPMpxPYnvRFrSvzYIRE04fbWqA3mxhPr/oP3xXrwyd1hnX6GzPIR
|
||||
KXeX1i7BAoGBANGV6XtL8cq8tu/4emOYDn4tncMRICQ8uMWZqnIQAvX8PBx1w9E2
|
||||
Wbkl0oBHJ/gDtU+feDvbHI0JBvXerce2cxj4+793TGLUl980dgq776x2fcxHjvYZ
|
||||
uZjJd4M95Lh+IhtWGZQ1FviiylDg62w+mrNydX8WiFjLGYPydQqCIAAxAoGBAMpl
|
||||
m/MDqpgPxiDU1O9DAq8C/0MQUOc/p+67aGsYxmPDdCouBLA/zckQh6Cp9Wo3n7MF
|
||||
X5UHOqn72q/4ahNEx+3YQoaLqRKTjUHl3r3zj+MsM0hIDp1uOxVzbANxazuLuqqA
|
||||
C+yJTmRU7uvNPH1AMFJBKRSmhd3MJwoHF/KZAhvfAoGAFaGPU3ZnIjGP//x5RUYw
|
||||
WL2EhtmBo7vQpjRR7yvP4muCGL3e0/z0DbPloe+2JFbdo7Ylxqe6rqO74Cx3ayFd
|
||||
h7pK4VwCukCO3C6h8EGtXvNr0GWiT6wgB7DjcNw2ewQpqQCd6zn/gPHsR6SvJ6De
|
||||
fp7VmaRNtjxgCcpAYjFD9EECgYAhEPaofjnZvAH/jSX4rPb8Rr4TY9AD58d03lNR
|
||||
4+tNkzogRgJoFRR2u+ecnQfGQa4qnj8eZt7ztHzm8OvLmBodxo4f0yNdMJQMZxS7
|
||||
7dXdJHSAY51XpRGsEH5eFaKSSOLHRkIsc8ZF6AZcqdwvDlSWq6SdhhMqyFa8cao8
|
||||
7TiF+wKBgADNZ4HoZDfnuH5jUvf7y+YlxDX3jxWR+BUTLCJmt082uT+8Xg5SALec
|
||||
B8GP5s6VKglD5Wzj8IhxvpQ5yzH9DRHwEeu3vFLBinIUlWdBiXwtnbmY0E9r3PSb
|
||||
pZQH5RZ5PyrJicIVBJSqdFu2HDl4heeLJE0LGh7SQnFaexxXn397
|
||||
-----END RSA PRIVATE KEY-----
|
||||
19
test/tlscacert/server.crt
Normal file
19
test/tlscacert/server.crt
Normal file
@@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDHzCCAgegAwIBAgIUUFCo8fUglrbfDY8ZUDnzAfWeq54wDQYJKoZIhvcNAQEL
|
||||
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIyMTAwNjEzMDYwMloXDTMyMTAw
|
||||
MzEzMDYwMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAxcja4TbshPj4tWgbRP73eDs2382j6Km5TNej6To13PJq
|
||||
Wyezg081ctmgFEMlgbRiowZmecpYOKjDKuVDtfLE6nZMmN+PjXXuOMGIPu67fx/4
|
||||
tnaMDYw96WIBEFNVZ7dC/pceaTIRbnjma89o1/mTudTAYPLAvKpeBqpJJFWPMDhz
|
||||
nK3NKeydTdUYc9jmEJWiFCI4bUdyvyUjp+7QrDbdODXo27/nVAV0Ih+OuU4ZnxT5
|
||||
cf1fzVV1ZqHd8jbLm25ZoAmkk+9DSXFNA2hbSepf70mRVD/Qyn8U6b5A2v+mWIfs
|
||||
B1+iAlPl7IX88W1Q9q1yu0uT8YWGWpeTbeOnJ4WJ8wIDAQABo2kwZzAdBgNVHQ4E
|
||||
FgQUEjp6AtPmpuLQyBPeiW4pW+VGb2wwHwYDVR0jBBgwFoAUEjp6AtPmpuLQyBPe
|
||||
iW4pW+VGb2wwDwYDVR0TAQH/BAUwAwEB/zAUBgNVHREEDTALgglsb2NhbGhvc3Qw
|
||||
DQYJKoZIhvcNAQELBQADggEBAL2bTWfTqxfN0YbBPjG05sR4nO8mhbNSGHDuGeiO
|
||||
OP0wPxkgAueScTpyhHWEAJmMQOMUM9KhByZj7LnqW8XY9BBS3zPAyzAdia8/o6Vl
|
||||
7El+M2JCfqz7hSupRK8M+r+XUq3hyEFjPLt+KO6D5VNzXiTM+36UueeQD3aaxxyo
|
||||
LpHSPeXFBkOrT/wt6FHi4NHvWls95PllncWZVYjxPMUUF/o30tOxSmgXwjUknrI8
|
||||
29ADKM1IbFuXd4vKYG9V+ukI6n5F86PYrN2ajPBKIidvTqU8tPzMHuJZ3YiIiv8p
|
||||
TARE2b5YLWuu+aF2z/V71MmIWr0uyOk6pZVGOCw7fwHx/wg=
|
||||
-----END CERTIFICATE-----
|
||||
28
test/tlscacert/server.key
Normal file
28
test/tlscacert/server.key
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDFyNrhNuyE+Pi1
|
||||
aBtE/vd4OzbfzaPoqblM16PpOjXc8mpbJ7ODTzVy2aAUQyWBtGKjBmZ5ylg4qMMq
|
||||
5UO18sTqdkyY34+Nde44wYg+7rt/H/i2dowNjD3pYgEQU1Vnt0L+lx5pMhFueOZr
|
||||
z2jX+ZO51MBg8sC8ql4GqkkkVY8wOHOcrc0p7J1N1Rhz2OYQlaIUIjhtR3K/JSOn
|
||||
7tCsNt04Nejbv+dUBXQiH465ThmfFPlx/V/NVXVmod3yNsubblmgCaST70NJcU0D
|
||||
aFtJ6l/vSZFUP9DKfxTpvkDa/6ZYh+wHX6ICU+XshfzxbVD2rXK7S5PxhYZal5Nt
|
||||
46cnhYnzAgMBAAECggEBAKLRsZZbf6QLzbqRBHntJ04b+RWOlVOQfRHMJ4x1Nig4
|
||||
i+OUsEv1pftxOj3T9QlstRKdzziNociq7VffurkLLJ4TWwUybVu37K9easncABAs
|
||||
ArQ6rRruC32YB2YoJBOoowcw4oEZDY6TCqVP7nB1be46PVDSJmZqHdOA1YuKv8Ci
|
||||
FbzLZEKYy6QGmHp9xMzc3usQ+KRNIFcR3NJb0eCbfAXb0tP3F12i4ygnxifkOVQS
|
||||
hukTJlZVbAO3W9uUEzLh5bkLoPfob6Vrwv1tGQ48uFgzgPXc4bWOUDFXHW5+vQLD
|
||||
1MKFboozrNhRR+Q5xvbRnaWEv4hMHlUNggc5ErRj6CkCgYEA5m5f1VfhfqSvEF2c
|
||||
XcIfUDiCzREpllY2ZdBSfUlz/GA6f0QUyFJBCdd4ypipQcggn60de9DoKDcNcq32
|
||||
rfVfANpsciJq9s4+xLL8MGtUuoi4HK8LHP3tc8aJaAcCVjBFbz0orKXDUOcue6A5
|
||||
Z5riDjiXOE56XSLSSNSRjWh4psUCgYEA27sfaM4J0YkdFuth/Qu+X9PeroUZyC0T
|
||||
3glMN/7PU4jZg+2v4Psfe61gj8qOt0catuWvsD0wQTy3jt+svY/KfkbspK6/7CEG
|
||||
fKx1AB1xeMr4JuQp9POFVhKRn4sBUMbHOkbjzlNpGmUI2arlLRTwT8YpuMDjCK4l
|
||||
ZuUYB/IHOVcCgYAqexqryCHIKTAlAjz7g/gl3+UtTQavsoEg0AEFG++IDW17XN+/
|
||||
9noLCHA6WV6KxAxPo6iV1POXxl5yT+P0OhIjpCDuAa5ahbdIp/6aJo9ePCpFD3gr
|
||||
Bh0qhOV8Ch7CKPAEC/Bds8mINrZ5EBbFJOab3I70UHN6jBrcVmPm/+WOSQKBgQCW
|
||||
AbBWt1qCnu2qCPWzcAH+n8DFOf645vVKPuS20ZEuwR1l8K2ClU4P+/QRFkLKIpO9
|
||||
Sx7e3VcFInNZ6Z+fJfwiqz7AysAhbwZjtMSHWJJv2XkB7AAsxtc/RJv/5ED4qUu3
|
||||
oE/DOrRlHZamKwIb/dB1VZ6ED8Ku2VyVW09FlViTLwKBgEU21xqvP1+TXzsrZNGm
|
||||
/Hj/RAaA8B6tyo5Dj9glV80oakMSaxBsLP9xHkoZjkHaJnoFosKBQSnCcPnEY4gP
|
||||
22WEyGshu8sujLibLKWhARqjeubatXv+XBxiDdMbgcd/XTwbI4HTjXy5LF0o47UI
|
||||
W6itMOg9uCfBJM/i2jrAkmQR
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -26,7 +26,18 @@ mkdir -p $GOPATH/src/github.com/docker
|
||||
cd $GOPATH/src/github.com/docker
|
||||
git clone https://github.com/docker/docker-credential-helpers
|
||||
cd docker-credential-helpers
|
||||
make pass
|
||||
|
||||
# After https://github.com/docker/docker-credential-helpers/commit/fd0197473f0ecb29e73ccef9028057194ff463bc go 1.18 is required... Pin commit if earlier go installed
|
||||
go_version="$(go version | cut -f3 -d' ')"
|
||||
IFS=. read -a go_version_parts <<<"$go_version"
|
||||
go_major="${go_version_parts[0]##go}"
|
||||
go_minor="${go_version_parts[1]}"
|
||||
if [[ "$go_major" -eq 1 && "$go_minor" -lt 18 ]]; then
|
||||
echo "Go version ${go_major}.${go_minor} < 1.18... Pinning credential-helper commit"
|
||||
git checkout ab7fd12c67d83193072fa91e5648b036547f6323
|
||||
fi
|
||||
|
||||
make pass
|
||||
cp bin/docker-credential-pass $GOPATH/bin/docker-credential-pass
|
||||
mkdir -p /home/travis/.docker
|
||||
echo '{ "credsStore": "pass" }' | tee /home/travis/.docker/config.json
|
||||
|
||||
@@ -55,5 +55,5 @@ else
|
||||
fi
|
||||
|
||||
if [ "$LTS" = true ] ; then
|
||||
./travis-build-scripts/push.sh production
|
||||
printf '\nIn CD stream but building LTS image. Do not push LTS image to artifactory\n'
|
||||
fi
|
||||
|
||||
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
@@ -36,12 +36,12 @@ github.com/prometheus/procfs/internal/util
|
||||
# github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
|
||||
## explicit
|
||||
github.com/syndtr/gocapability/capability
|
||||
# golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f
|
||||
# golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
||||
## explicit
|
||||
golang.org/x/crypto/bcrypt
|
||||
golang.org/x/crypto/blowfish
|
||||
golang.org/x/crypto/pbkdf2
|
||||
# golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40
|
||||
# golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1
|
||||
## explicit
|
||||
golang.org/x/sys/internal/unsafeheader
|
||||
golang.org/x/sys/unix
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-Djava.util.prefs.userRoot=/tmp
|
||||
-Djava.util.prefs.systemRoot=/tmp
|
||||
Reference in New Issue
Block a user