Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dockerfile: add support to build non-dist image #124

Merged
merged 2 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 31 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ 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 stage1
ARG TARGETOS TARGETARCH

Expand Down Expand Up @@ -94,14 +93,39 @@ RUN if [[ $TARGETARCH = "amd64" ]] ; then \
# 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 / /

# Provide hook to include extra dependencies in the image
ONBUILD ARG DEPDIR="dependencies"
ONBUILD COPY "${DEPDIR}" dependencies
ONBUILD RUN if [[ -f ${DEPDIR}/install-extra-deps.sh ]]; then cd ${DEPDIR} && bash install-extra-deps.sh; fi
ONBUILD RUN rm -rf "${DEPDIR}"

ENTRYPOINT [ "/bin/bash", "-l", "-c" ]
29 changes: 18 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ For the available methods,
- The supported actions interface and method docs can be found [here](https://pkg.go.dev/github.com/metal-toolbox/ironlib/actions)
- The supported utilities and its methods can be found [here](https://pkg.go.dev/github.com/metal-toolbox/ironlib/utils)


## Currently supported hardware

- Dell
Expand Down Expand Up @@ -109,19 +108,27 @@ IRONLIB_UTIL_STORECLI

Check out this [snippet](examples/dependencies/main.go) to determine if all required dependencies are available to ironlib.

# ironlib docker image
### Build image without the non-distributable files.

A github workflow builds and releases a docker image based off the Dockerfile in this repository.
```sh
docker build -f Dockerfile -t ironlib:devel .
```

The Dockerfile provides `ONBUILD` hooks so downstream users can build their own images including any further dependencies required (i.e. proprietary vendor tools). To use the `ONBUILD` functionality in a downstream docker image, add the extra tools to a `dependencies` directory and provide a script `install-extra-deps.sh` to install those within the image.
### Build image with non-distributable files

Downstream `Dockerfile` can be as simple as:
ironlib will attempt to execute proprietary vendor executables based on the hardware its run on,
to build docker image with executables like `mvcli`, `mlxup`, SMCI `sum` etc follow the steps below.

```
# Use base ironlib image with ONBUILD instructions to include extra deps
FROM ghcr.io/metal-toolbox/ironlib:latest as stage0
- Ensure the executable files are made available in an s3 bucket, update the `S3_BUCKET_ALIAS` and `S3_PATH` in the snippet below.
- The list of files expected can be found within the [install-non-distributable.sh](scripts/install-non-distributable.sh) script.
- Build image with the `ACCESS_KEY`, `SECRET_KEY` values defined.

# Keep image lean after all extra deps are installed
FROM scratch
COPY --from=stage0 / /
```sh
docker build -f Dockerfile \
--build-arg INSTALL_NON_DISTRIBUTABLE=true
--build-arg S3_BUCKET_ALIAS="tools"
--build-arg S3_PATH="tools/bucket-name/path/non-dist"
--build-arg ACCESS_KEY=<>
--build-arg SECRET_KEY=<>
-t ironlib:devel-non-dist .
```
102 changes: 102 additions & 0 deletions scripts/install-non-distributable.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/bin/bash
set -eux

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

# a few checks before proceeding
PARENT_DIR="$(basename "$(pwd)")"

[[ "$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

# 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"

export ASRDEV_KERNEL_MODULE=asrdev-5.4.0-73-generic.ko

# set minio client url
OS=$(uname -s)
ARCH=$(uname -m)

MC_ARCH=$ARCH

MC_ARCH=$ARCH

case $ARCH in
aarch64 | arm64)
MC_ARCH=arm64
;;
x86_64)
MC_ARCH=amd64
;;
*)
echo "unsupported ARCH; $ARCH"
exit 1
;;
esac

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"
exit 1
;;
esac

# install minio client to fetch firmware tooling artifacts
curl "${MC_URL}" -o mc && chmod +x mc

# 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 .

# 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/

# 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

# 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

# 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/

# 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

# install Dell msecli
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
ln -s /usr/sbin/asrr-bioscontrol /usr/sbin/BIOSControl

# run ldconfig to update ld.so cache
ldconfig
Loading