Skip to content

Commit

Permalink
Cleanup Dockerfile and convert non-distributable handling to ONBUILD (#…
Browse files Browse the repository at this point in the history
…179)

### What does this PR do

Bunch of minor (imo) clean ups to the Dockerfile and
scripts/install-non-distributable.sh to start.
Then converts the whole fetching of non-distributable files from at
ironlib image build time to `ONBUILD` and thus when consumers build
their own images based off of ironlib's image.

This looks similar to how we used to do things before except there's
better handling for skipping all of it by keeping what we do today of
requiring a build-arg to opt in to proprietary deps. The old ONBBUILD
setup used to check for presence of the fetcher script to decide to run
the fetch. That was annoying because consumers would need a whole
Dockerfile/repo setup just to have the script.

### How can this change be tested by a PR reviewer?

Build this docker image with/without the args to opt-in to proprietary
binaries, there should be no difference between the 2 images. Lets
assume you tag it `my-local-ironlib`.

Now do the same with/without build using the following Dockerfile:
```
FROM ghcr.io/metal-toolbox/vogelkop:v0.4.0 AS vogelkop

FROM my-local-ironlib
COPY --from=vogelkop /usr/sbin/vogelkop /usr/sbin/vogelkop
```

Running `docker build --build-arg INSTALL_NON_DISTRIBUTABLE=true` will
fail and complain about missing AWS creds. Build again with the
build-arg and it will complete. Also note that since no `ARG` is present
in this example Dockerfile the secrets do not leak into the final image
(verification left up to reader).
  • Loading branch information
mmlb authored Sep 4, 2024
2 parents 22957b5 + f909b99 commit e153616
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 153 deletions.
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.md
.chainguard
.github
.golangci.yaml
Dockerfile
bin/
renovate.json
148 changes: 61 additions & 87 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,131 +1,105 @@
# build ironlib wrapper binaries
FROM golang:1.22-alpine AS stage0
FROM golang:1.22-alpine AS helper-binaries

WORKDIR /workspace

# copy the go modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
COPY go.mod go.sum ./

# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go mod download

# copy ironlib go sources
# copy rest of go sources
COPY . .

# build helper util
ARG TARGETOS TARGETARCH
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
go build -o getbiosconfig examples/biosconfig/biosconfig.go && \
install -m 755 -D getbiosconfig /usr/sbin/
ENV CGO_ENABLED=0
RUN go build -o /usr/sbin/getbiosconfig examples/biosconfig/biosconfig.go
RUN go build -o /usr/sbin/getinventory examples/inventory/inventory.go

RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
go build -o getinventory examples/inventory/inventory.go && \
install -m 755 -D getinventory /usr/sbin/
FROM almalinux:9-minimal AS base
FROM base AS deps

FROM almalinux:9-minimal as stage1
ARG TARGETOS TARGETARCH

# copy ironlib wrapper binaries
COPY --from=stage0 /usr/sbin/getbiosconfig /usr/sbin/getbiosconfig
COPY --from=stage0 /usr/sbin/getinventory /usr/sbin/getinventory
# Configure microdnf to avoid installing unwanted packages
RUN printf 'install_weak_deps=0\ntsflags=nodocs\n' >>/etc/dnf/dnf.conf

# import and install tools
RUN curl -sO https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
RUN microdnf install -y --setopt=tsflags=nodocs crypto-policies-scripts && \
RUN microdnf install -y crypto-policies-scripts && \
update-crypto-policies --set DEFAULT:SHA1 && \
rpm -ivh epel-release-latest-9.noarch.rpm && \
rm -f epel-release-latest-9.noarch.rpm

## Prerequisite directories for Dell, ASRR, Supermicro
## /lib/firmware required for Dell updates to be installed successfullly
RUN mkdir -p /lib/firmware /opt/asrr /usr/libexec/dell_dup /opt/supermicro/sum/
RUN mkdir -p /lib/firmware /opt/asrr /opt/supermicro/sum/ /usr/libexec/dell_dup

ARG TARGETARCH
RUN echo "Target ARCH is $TARGETARCH"

# Bootstrap Dell DSU repository
# Install Dell idracadm7 to enable collecting BIOS configuration and use install_weak_deps=0 to avoid pulling extra packages
RUN if [[ $TARGETARCH = "amd64" ]] ; then \
curl -O https://linux.dell.com/repo/hardware/dsu/bootstrap.cgi && \
bash bootstrap.cgi && rm -f bootstrap.cgi && \
microdnf install -y --setopt=tsflags=nodocs --setopt=install_weak_deps=0 \
srvadmin-idracadm7 ; fi
RUN if [[ $TARGETARCH == "amd64" ]]; then \
curl -O https://linux.dell.com/repo/hardware/dsu/bootstrap.cgi && \
bash bootstrap.cgi && \
rm -f bootstrap.cgi && \
microdnf install -y srvadmin-idracadm7; \
fi

# update dependencies
RUN microdnf update -y --setopt=tsflags=nodocs --setopt=install_weak_deps=0 \
--setopt=keepcache=0 && microdnf clean all
RUN microdnf update -y && microdnf clean all

# install misc support packages
RUN microdnf install -y --setopt=tsflags=nodocs --setopt=install_weak_deps=0 \
dmidecode \
dosfstools \
e2fsprogs \
gdisk \
gzip \
hdparm \
kmod \
libssh2-devel \
lshw \
mdadm \
nvme-cli \
pciutils \
smartmontools \
tar \
udev \
unzip \
util-linux \
python \
python-devel \
python-pip \
python-setuptools \
which && \
RUN microdnf install -y \
dmidecode \
dosfstools \
e2fsprogs \
gdisk \
gzip \
hdparm \
kmod \
libssh2-devel \
lshw \
mdadm \
nvme-cli \
pciutils \
python \
python-devel \
python-pip \
python-setuptools \
smartmontools \
tar \
udev \
unzip \
util-linux \
which \
&& \
microdnf clean all && \
ln -s /usr/bin/microdnf /usr/bin/yum

RUN pip install uefi_firmware==v1.11

# Install our custom flashrom package
ADD https://github.com/metal-toolbox/flashrom/releases/download/v1.3.99/flashrom-1.3.99-0.el9.x86_64.rpm /tmp
RUN if [[ $TARGETARCH = "amd64" ]] ; then \
rpm -ivh /tmp/flashrom*.rpm ; fi
RUN if [[ $TARGETARCH == "amd64" ]] ; then \
rpm -ivh /tmp/flashrom*.rpm; \
fi

# Delete /tmp/* as we don't need those included in the image.
RUN rm -rf /tmp/*

# Install non-distributable files when the env var is set.
#
# The non-distributable files are executables provided by hardware vendors.
ARG INSTALL_NON_DISTRIBUTABLE=false
ENV INSTALL_NON_DISTRIBUTABLE=$INSTALL_NON_DISTRIBUTABLE

# S3_BUCKET_ALIAS is the alias set on the S3 bucket, for details refer to the minio
# client guide https://github.com/minio/mc/blob/master/docs/minio-client-complete-guide.md
ARG S3_BUCKET_ALIAS=utils
ENV S3_BUCKET_ALIAS=$S3_BUCKET_ALIAS

# S3_PATH is the path in the s3 bucket where the non-distributable files are located
# note, this generally includes the s3 bucket alias
ARG S3_PATH
ENV S3_PATH=$S3_PATH

ARG ACCESS_KEY
ENV ACCESS_KEY=$ACCESS_KEY

ARG SECRET_KEY
ENV SECRET_KEY=$SECRET_KEY

COPY scripts scripts
RUN if [[ $INSTALL_NON_DISTRIBUTABLE = "true" ]]; then \
mkdir -p non-distributable && \
cp scripts/install-non-distributable.sh ./non-distributable/install.sh && \
cd ./non-distributable/ && \
./install.sh $S3_BUCKET_ALIAS && \
cd .. && rm -rf non-distributable; fi
RUN rm -rf scripts/

# Build a lean image with dependencies installed.
FROM scratch
COPY --from=stage1 / /

ENTRYPOINT [ "/bin/bash", "-l", "-c" ]
# Use same base image used by deps so that we keep all the meta-vars (CMD, PATH, ...)
FROM base
# copy ironlib wrapper binaries
COPY --from=helper-binaries /usr/sbin/getbiosconfig /usr/sbin/getinventory /usr/sbin/
# copy installed packages
COPY --from=deps / /

# Install non-distributable files when the env var is set, left for downstream consumers
COPY scripts/install-non-distributable.sh non-distributable/
ONBUILD ARG AWS_ACCESS_KEY_ID
ONBUILD ARG AWS_SECRET_ACCESS_KEY
ONBUILD ARG BUCKET
ONBUILD ARG INSTALL_NON_DISTRIBUTABLE
ONBUILD RUN cd non-distributable && ./install-non-distributable.sh
133 changes: 67 additions & 66 deletions scripts/install-non-distributable.sh
Original file line number Diff line number Diff line change
@@ -1,98 +1,99 @@
#!/bin/bash
set -eux

ARCH=$(uname -m)
export WORKDIR="non-distributable"

# a few checks before proceeding
PARENT_DIR="$(basename "$(pwd)")"
#!/usr/bin/env bash

[[ "$PARENT_DIR" != "${WORKDIR}" ]] && echo "expected to be executed from within ${WORKDIR} directory" && exit 1
[[ "${ARCH}" != "x86_64" ]] && echo "nothing to be done for arch: ${ARCH}" && exit 0
set -eux

# minio client s3 parameters
# https://github.com/minio/mc/blob/master/docs/minio-client-complete-guide.md#specify-temporary-host-configuration-through-environment-variable
export MC_HOST_${S3_BUCKET_ALIAS}="https://${ACCESS_KEY}:${SECRET_KEY}@s3.amazonaws.com"
INSTALL_NON_DISTRIBUTABLE=${INSTALL_NON_DISTRIBUTABLE:-}
if ! [[ ${INSTALL_NON_DISTRIBUTABLE,,} =~ ^(1|on|true|y|yes)$ ]]; then
echo not installing non-distributable files >&2
exit 0
fi

export ASRDEV_KERNEL_MODULE=asrdev-5.4.0-73-generic.ko
set -v +x

# set minio client url
OS=$(uname -s)
ARCH=$(uname -m)
if [[ -z ${AWS_ACCESS_KEY_ID:-} ]]; then
echo AWS_ACCESS_KEY_ID env var is missing >&2
exit 1
fi

MC_ARCH=$ARCH
if [[ -z ${AWS_SECRET_ACCESS_KEY:-} ]]; then
echo AWS_SECRET_ACCESS_KEY env var is missing >&2
exit 1
fi

MC_ARCH=$ARCH
set +v -x

case $ARCH in
aarch64 | arm64)
MC_ARCH=arm64
;;
x86_64)
MC_ARCH=amd64
;;
*)
echo "unsupported ARCH; $ARCH"
if [[ -z ${BUCKET:-} ]]; then
echo BUCKET env var is missing >&2
exit 1
;;
esac
fi

case $OS in
Darwin*)
MC_URL="https://dl.min.io/client/mc/release/darwin-${MC_ARCH}/mc"
;;
Linux*)
MC_URL="https://dl.min.io/client/mc/release/linux-${MC_ARCH}/mc"
;;
*)
echo "unsupported OS: $OS"
# a few checks before proceeding
if [[ $(basename "${PWD}") != non-distributable ]]; then
echo "expected to be executed from within non-distributable directory"
exit 1
;;
esac
fi

# install minio client to fetch firmware tooling artifacts
curl "${MC_URL}" -o mc && chmod +x mc
ARCH=$(uname -m)
if [[ $ARCH != "x86_64" ]]; then
echo "nothing to be done for arch: $ARCH"
exit 0
fi

# install s5cmd to fetch firmware tooling artifacts
s5cmd_url=https://github.com/peak/s5cmd/releases/download/v2.2.2/s5cmd_2.2.2_
case $(uname -s):$ARCH in
Darwin:arm64) s5cmd_url+=macOS-arm64 ;;
Darwin:x86_64) s5cmd_url+=macOS-64bit ;;
Linux:aarch64) s5cmd_url+=Linux-arm64 ;;
Linux:x86_64) s5cmd_url+=Linux-64bit ;;
esac
s5cmd_url+=.tar.gz
curl --fail --location --silent "$s5cmd_url" | tar -xz s5cmd
chmod +x s5cmd

# fetch vendor tools
./mc cp "${S3_PATH}"/mlxup .
./mc cp "${S3_PATH}"/msecli_Linux.run .
./mc cp "${S3_PATH}"/IPMICFG_1.32.0_build.200910.zip .
./mc cp "${S3_PATH}"/sum_2.10.0_Linux_x86_64_20221209.tar.gz .
./mc cp "${S3_PATH}"/SW_Broadcom_Unified_StorCLI_v007.1316.0000.0000_20200428.ZIP .
./mc cp "${S3_PATH}"/asrr/BIOSControl_v1.0.3.zip .
./mc cp "${S3_PATH}"/asrr/asrr_bios_kernel_module/$ASRDEV_KERNEL_MODULE .
./mc cp "${S3_PATH}"/mvcli-4.1.13.31_A01.zip .
cat <<-EOF | ./s5cmd run
cp s3://${BUCKET}/IPMICFG_1.32.0_build.200910.zip .
cp s3://${BUCKET}/SW_Broadcom_Unified_StorCLI_v007.1316.0000.0000_20200428.ZIP .
cp s3://${BUCKET}/asrr/BIOSControl_v1.0.3.zip .
cp s3://${BUCKET}/asrr/asrr_bios_kernel_module/asrdev-5.4.0-73-generic.ko .
cp s3://${BUCKET}/mlxup .
cp s3://${BUCKET}/msecli_Linux.run .
cp s3://${BUCKET}/mvcli-4.1.13.31_A01.zip .
cp s3://${BUCKET}/sum_2.10.0_Linux_x86_64_20221209.tar.gz .
EOF

# install dependencies
#

# install Mellanox mlxup
install -m 755 -D mlxup /usr/sbin/

# install SMC sum 2.10.0
tar -xvzf sum_2.10.0_Linux_x86_64_20221209.tar.gz &&
install -m 755 -D sum_2.10.0_Linux_x86_64/sum /usr/sbin/
tar -xvzf sum_2.10.0_Linux_x86_64_20221209.tar.gz
install -m 755 -D sum_2.10.0_Linux_x86_64/sum /usr/sbin/

# install SMC ipmicfg
unzip IPMICFG_1.32.0_build.200910.zip &&
install -m 755 -D IPMICFG_1.32.0_build.200910/Linux/64bit/IPMICFG-Linux.x86_64 /usr/sbin/smc-ipmicfg
unzip IPMICFG_1.32.0_build.200910.zip
install -m 755 -D IPMICFG_1.32.0_build.200910/Linux/64bit/IPMICFG-Linux.x86_64 /usr/sbin/smc-ipmicfg

# install Broadcom storcli
unzip SW_Broadcom_Unified_StorCLI_v007.1316.0000.0000_20200428.ZIP &&
rpm --import Unified_storcli_all_os/Linux/pubKey.asc &&
rpm -ivh Unified_storcli_all_os/Linux/storcli-007.1316.0000.0000-1.noarch.rpm
unzip SW_Broadcom_Unified_StorCLI_v007.1316.0000.0000_20200428.ZIP
rpm --import Unified_storcli_all_os/Linux/pubKey.asc
rpm -ivh Unified_storcli_all_os/Linux/storcli-007.1316.0000.0000-1.noarch.rpm

# install AsRockRack BIOSControl and copy kernel module
unzip BIOSControl_v1.0.3.zip &&
install -m 755 -D BIOSControl /usr/sbin/asrr-bioscontrol &&
cp asrdev*.*.ko /opt/asrr/
unzip BIOSControl_v1.0.3.zip
install -m 755 -D BIOSControl /usr/sbin/asrr-bioscontrol
cp asrdev*.*.ko /opt/asrr/

# install Marvell mvcli
unzip mvcli-4.1.13.31_A01.zip &&
install -m 755 -D mvcli-4.1.13.31_A01/x64/cli/mvcli /usr/sbin/mvcli &&
install -m 755 -D mvcli-4.1.13.31_A01/x64/cli/libmvraid.so /usr/lib/libmvraid.so
unzip mvcli-4.1.13.31_A01.zip
install -m 755 -D mvcli-4.1.13.31_A01/x64/cli/mvcli /usr/sbin/mvcli
install -m 755 -D mvcli-4.1.13.31_A01/x64/cli/libmvraid.so /usr/lib/libmvraid.so

# install Dell msecli
chmod 755 msecli_Linux.run && ./msecli_Linux.run --mode unattended
chmod 755 msecli_Linux.run
./msecli_Linux.run --mode unattended

# Add symlink to location where OSIE expects vendor tools to be
ln -s /usr/sbin/sum /opt/supermicro/sum/sum
Expand Down

0 comments on commit e153616

Please sign in to comment.