Skip to content

Commit 0d34ba3

Browse files
committed
Add script to build images using buildah + Red Hat UBI base
1 parent f690852 commit 0d34ba3

File tree

4 files changed

+184
-3
lines changed

4 files changed

+184
-3
lines changed

Dockerfile.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ RUN mkdir -p $GOPATH/src $GOPATH/bin $GOPATH/pkg \
5959
# Location of the downloadable MQ client package \
6060
ENV RDURL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqdev/redist" \
6161
RDTAR="IBM-MQC-Redist-LinuxX64.tar.gz" \
62-
VRMF=9.2.2.0
62+
VRMF=9.2.3.0
6363

6464
# Install the MQ client from the Redistributable package. This also contains the
6565
# header files we need to compile against. Setup the subset of the package

Dockerfile.run

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ RUN apt-get update \
3131
# Location of the downloadable MQ client package \
3232
ENV RDURL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqdev/redist" \
3333
RDTAR="IBM-MQC-Redist-LinuxX64.tar.gz" \
34-
VRMF=9.2.2.0
34+
VRMF=9.2.3.0
3535

3636
# Install the MQ client from the Redistributable package. This also contains the
3737
# header files we need to compile against. Setup the subset of the package

scripts/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ YAML files go into `%GOPATH%\bin`.
2828
* `docker-compose.yaml`: A fragment of what might go into a larger composition file. In its current
2929
state it tries to pull an image from a repository even though it has been built and exists locally.
3030

31-
31+
* `buildBuildah.sh`: An alternative approach to building a runnable container image. It uses `buildah`, `podman`
32+
and the Red Hat UBI containers. It uses a multi-stage model, one to compile the code and a second phase that
33+
uses a slimmer runtime image.

scripts/buildBuildah.sh

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
#!/bin/bash
2+
3+
# © Copyright IBM Corporation 2021
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# This script builds and runs a container with the designated metrics collector.
18+
# It uses buildah+podman as an alternative approach to the Dockerfile mechanism shown
19+
# elsewhere in this repository. It also uses the Red Hat Universal Base Images as
20+
# the starting points.
21+
#
22+
# We first build the collector using a full-fat image. And then copy the compiled
23+
# code to a slimmer container which can then be deployed. This script uses
24+
# a combination of the supplied sample configuration file and some environment
25+
# variables. You might prefer to keep the config file outside of the running container
26+
# and just mount it into the system.
27+
28+
# Single parameter that can either be "CLEAN" or the name of one of the collectors.
29+
# The default is to build the Prometheus module.
30+
COLL="mq_prometheus"
31+
clean=false
32+
case "$1" in
33+
mq_*)
34+
COLL=$1
35+
;;
36+
CLEAN)
37+
clean=true
38+
;;
39+
*)
40+
if [ ! -z "$1" ]
41+
then
42+
echo "Only parameters are names of collectors (eg mq_prometheus) and 'CLEAN'"
43+
exit 1
44+
fi
45+
;;
46+
esac
47+
48+
# Set some variables.
49+
ORG="github.com/ibm-messaging"
50+
REPO="mq-metric-samples"
51+
VRMF=9.2.3.0
52+
db=`echo $COLL | sed "s/mq_//g"`
53+
#
54+
imgName="mq-metric-$db"
55+
imgNameRuntime=$imgName-runtime
56+
imgNameBuild=$imgName-build
57+
58+
# This is a convenient way to tidy up old images, espcially after experimenting
59+
if [ "$1" = "CLEAN" ]
60+
then
61+
buildah list -a -n | grep ubi-working-container | awk '{print $1}' | xargs buildah rm 2>/dev/null
62+
buildah list -a -n | grep ubi-minimal-working-container | awk '{print $1}' | xargs buildah rm 2>/dev/null
63+
buildah list -a -n | grep $imgName | awk '{print $1}' | xargs buildah rm 2>/dev/null
64+
buildah images -n | grep $imgName | awk '{print $3}' | xargs buildah rmi 2>/dev/null
65+
buildah images
66+
buildah list
67+
exit 0
68+
fi
69+
70+
###########################################################################
71+
# For normal operation, we start with a current UBI container. Unlike a
72+
# Dockerfile build, the scripted builds rerun every step each time. They do not
73+
# cache previous steps automatically.
74+
###########################################################################
75+
buildCtr=$(buildah from registry.access.redhat.com/ubi8/ubi)
76+
77+
# Install the Go package and a couple of other things. Failures here are going to be fatal
78+
# so we check that we were at least able to get started
79+
buildah run $buildCtr yum --disableplugin=subscription-manager -y install wget curl tar golang
80+
if [ $? -ne 0 ]
81+
then
82+
exit 1
83+
fi
84+
85+
# Set up the environment that's going to be needed to download the correct
86+
# MQ client libraries and to strip out unneeded components from that package.
87+
buildah config --env genmqpkg_incnls=1 \
88+
--env genmqpkg_incsdk=1 \
89+
--env genmqpkg_inctls=1 \
90+
--env RDURL="https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqdev/redist" \
91+
--env RDTAR="IBM-MQC-Redist-LinuxX64.tar.gz" \
92+
--env VRMF="$VRMF" \
93+
--env ORG="$ORG" \
94+
--env REPO="$REPO" \
95+
$buildCtr
96+
97+
# Get the MQ redistributable client downloaded and installed. Use the genmqpkg command
98+
# to delete parts we don't need.
99+
buildah run $buildCtr mkdir -p /opt/go/src/$ORG/$REPO /opt/bin /opt/config /opt/mqm
100+
buildah run $buildCtr /bin/bash -c 'cd /opt/mqm \
101+
&& curl -LO "$RDURL/$VRMF-$RDTAR" \
102+
&& tar -zxf ./*.tar.gz \
103+
&& rm -f ./*.tar.gz \
104+
&& bin/genmqpkg.sh -b /opt/mqm'
105+
106+
# Copy over the source tree
107+
buildah config --workingdir /opt/go/src/$ORG/$REPO $buildCtr
108+
buildah copy -q $buildCtr `pwd`/..
109+
110+
# The build process for the collector allows setting of some
111+
# external variables, useful for debug and logging. Set them here...
112+
buildStamp=`date +%Y%m%d-%H%M%S`
113+
gitCommit=`git rev-list -1 HEAD --abbrev-commit 2>/dev/null`
114+
if [ -z "$gitCommit" ]
115+
then
116+
gitCommit="Unknown"
117+
fi
118+
hw=`uname -i`
119+
os=`uname -s`
120+
bp="$os/$hw"
121+
122+
# ... and use them as part of compiling the program. We actually do this
123+
# by creating a script and copying it into the container where it gets run.
124+
# That helps with wildcard expansion as it refers to the container rather than
125+
# the local tree.
126+
tmpfile=/tmp/build.sh.$$
127+
cat << EOF > $tmpfile
128+
cat config.common.yaml cmd/$COLL/config.collector.yaml > /opt/config/$COLL.yaml
129+
go build -mod=vendor -o /opt/bin/$COLL \
130+
-ldflags "-X \"main.BuildStamp=$buildStamp\" -X \"main.BuildPlatform=$bp\" -X \"main.GitCommit=$gitCommit\"" \
131+
cmd/$COLL/*.go
132+
EOF
133+
134+
# Copy in the build command and remove it from the local machine. Then run it.
135+
echo "Copying source"
136+
buildah copy -q $buildCtr $tmpfile build.sh
137+
rm -f $tmpfile
138+
echo "Compiling program $COLL"
139+
buildah run $buildCtr /bin/bash ./build.sh
140+
echo "Compilation finished"
141+
142+
# We now have a container image with the compiled code. Complete its generation with a 'commit'
143+
echo "Comitting builder image"
144+
buildah commit -q --squash --rm $buildCtr $imgNameBuild
145+
146+
###########################################################################
147+
# Restart the image creation from a smaller base image
148+
###########################################################################
149+
runtimeCtr=$(buildah from registry.access.redhat.com/ubi8/ubi-minimal)
150+
151+
# Copy over the binaries that are going to be needed. Go doesn't have any
152+
# separate runtime; it builds standalone programs. All we need to add is the
153+
# MQ client code and the configuration file
154+
echo "Copying built objects to runtime container"
155+
buildah copy -q --from $imgNameBuild $runtimeCtr /opt/mqm /opt/mqm
156+
buildah copy -q --from $imgNameBuild $runtimeCtr /opt/bin /opt/bin
157+
buildah copy -q --from $imgNameBuild $runtimeCtr /opt/config /opt/config
158+
159+
buildah config --env IBMMQ_GLOBAL_CONFIGURATIONFILE=/opt/config/$COLL.yaml $runtimeCtr
160+
161+
# Complete the runtime container with an entrypoint
162+
buildah config --entrypoint /opt/bin/$COLL $runtimeCtr
163+
echo "Commiting runtime image"
164+
buildah commit -q --squash --rm $runtimeCtr $imgNameRuntime
165+
166+
# Now run the image. The assumption is that you have a queue manager running on this machine on port 1414.
167+
# But you can see how this run step can be modified. Using the environment variables overrides values in the
168+
# configuration file which makes it easy to have a basic common config with only container-specific overrides
169+
# provided via the env vars.
170+
# We also map the port number to something different - the Prometheus engine would be configured to connect
171+
# to 9158 even though the collector is listening on 9157 (the assigned number for MQ).
172+
# Rather than having the config file embedded in the container image, you might prefer to mount it from a real local
173+
# filesystem.
174+
podman run \
175+
-e IBMMQ_GLOBAL_LOGLEVEL=DEBUG \
176+
-e IBMMQ_CONNECTION_CONNNAME=`hostname` \
177+
-e IBMMQ_CONNECTION_CHANNEL=SYSTEM.DEF.SVRCONN \
178+
-p 9158:9157 \
179+
$imgNameRuntime

0 commit comments

Comments
 (0)