From a00ed1a9afa553cb8984acb30ce81f277596bc00 Mon Sep 17 00:00:00 2001 From: Bryan Latten Date: Mon, 6 Dec 2021 15:28:58 -0500 Subject: [PATCH] CPU Arch: added helper script for simple string replacements (#66) * CPU Arch: added helper script for simple string replacements * Archstring: remaining type from testing * Archstring: now with named parameters * README: updates * Archstring: cleanup * Archstring: extraneous a * Archstring: EOF newline * Goss: testing shorthand parameters * Archstring: detect and filter bad arguments * Goss: fixed missing EOL * Archstring: removed extraneous semicolon * Archstring: bracket consistency Co-authored-by: Bryan Latten --- Dockerfile-alpine | 1 + Dockerfile-centos-7 | 1 + Dockerfile-centos-8 | 1 + Dockerfile-ubuntu-18.04 | 1 + Dockerfile-ubuntu-20.04 | 1 + README.md | 13 ++++-- container/root/goss.base.yaml | 35 ++++++++++++++ container/root/scripts/install_goss.sh | 17 ++----- container/root/scripts/install_s6.sh | 10 +--- container/root/usr/local/bin/archstring | 62 +++++++++++++++++++++++++ 10 files changed, 117 insertions(+), 25 deletions(-) create mode 100755 container/root/usr/local/bin/archstring diff --git a/Dockerfile-alpine b/Dockerfile-alpine index a4ab2a7..16b03ac 100644 --- a/Dockerfile-alpine +++ b/Dockerfile-alpine @@ -4,6 +4,7 @@ FROM alpine:3.14 as base # Ensure scripts are available for use in next command COPY ./container/root/scripts/* /scripts/ +COPY ./container/root/usr/local/bin/* /usr/local/bin/ # - Symlink variant-specific scripts to default location # - Add additional repositories to pull packages from diff --git a/Dockerfile-centos-7 b/Dockerfile-centos-7 index e0010c1..6d646e8 100644 --- a/Dockerfile-centos-7 +++ b/Dockerfile-centos-7 @@ -4,6 +4,7 @@ FROM centos:7 as base # Ensure scripts are available for use in next command COPY ./container/root/scripts/* /scripts/ +COPY ./container/root/usr/local/bin/* /usr/local/bin/ # - Symlink variant-specific scripts to default location # - Upgrade base security packages, then clean packaging leftover diff --git a/Dockerfile-centos-8 b/Dockerfile-centos-8 index 74ad8fb..b353049 100644 --- a/Dockerfile-centos-8 +++ b/Dockerfile-centos-8 @@ -4,6 +4,7 @@ FROM centos:8 as base # Ensure scripts are available for use in next command COPY ./container/root/scripts/* /scripts/ +COPY ./container/root/usr/local/bin/* /usr/local/bin/ # - Symlink variant-specific scripts to default location # - Upgrade base security packages, then clean packaging leftover diff --git a/Dockerfile-ubuntu-18.04 b/Dockerfile-ubuntu-18.04 index 696a58a..12481f8 100644 --- a/Dockerfile-ubuntu-18.04 +++ b/Dockerfile-ubuntu-18.04 @@ -4,6 +4,7 @@ FROM ubuntu:18.04 as base # Ensure scripts are available for use in next command COPY ./container/root/scripts/* /scripts/ +COPY ./container/root/usr/local/bin/* /usr/local/bin/ # - Symlink variant-specific scripts to default location # - Upgrade base security packages, then clean packaging leftover diff --git a/Dockerfile-ubuntu-20.04 b/Dockerfile-ubuntu-20.04 index 4c25200..dc1c396 100644 --- a/Dockerfile-ubuntu-20.04 +++ b/Dockerfile-ubuntu-20.04 @@ -4,6 +4,7 @@ FROM ubuntu:20.04 as base # Ensure scripts are available for use in next command COPY ./container/root/scripts/* /scripts/ +COPY ./container/root/usr/local/bin/* /usr/local/bin/ # - Symlink variant-specific scripts to default location # - Upgrade base security packages, then clean packaging leftover diff --git a/README.md b/README.md index 06b66bd..a525364 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ Provides base OS, security patches, and tools for quick and easy spinup. * Centos 7 builds available, tagged as `-centos-7` * Centos 8 builds available, tagged as `-centos-8` - ### Tools * [S6](https://github.com/just-containers/s6-overlay) process supervisor is used for `only` for zombie reaping (as PID 1), boot coordination, and termination signal translation @@ -57,19 +56,26 @@ S6_KILL_FINISH_MAXTIME | S6_KILL_FINISH_MAXTIME=55000 | The maximum time (in ms) S6_KILL_GRACETIME | S6_KILL_GRACETIME=500 | Wait time (in ms) for S6 finish scripts before sending kill signal. This value has a max of 65535 on Alpine variants. * `with-contenv` tool, which is used to expose environment variables across scripts, has a limitation that it cannot read beyond 4k characters for environment variable values. To work around this issue, use the script `/scripts/with-bigcontenv` instead of `with-contenv`. You'll need to remove the `with-contenv` from the shebang line, and add `source /scripts/with-bigcontenv` in the next line after the shebang line. + ### Startup/Runtime Modification To inject changes just before runtime, shell scripts may be placed into the `/etc/cont-init.d` folder. As part of the process manager, these scripts are run in advance of the supervised processes. @see https://github.com/just-containers/s6-overlay#executing-initialization-andor-finalization-tasks +### Processor Architectures + +All variants are tested on x64 and arm64. +The convenience script `archstring` is provided to switch between strings based on the current machine. +Usage: +```archstring --x64 intel --arm64 arm``` +Which will return "intel" when on x64 and arm when on arm64. This is handy when package names or download paths need to be modified per architecture. + ### Testing - Container tests itself as part of build process using [goss](https://github.com/aelsabbahy/goss) validator. To add additional build-time tests, overwrite (or extend) the `./container/root/goss.base.yaml` file. - To initiate run-time validation, please execute `test.sh`. It uses [dgoss](https://github.com/aelsabbahy/goss/tree/master/extras/dgoss) validator. To add additional run-time tests, extend `./test.sh` and `./goss.yaml` file. - - ### Advanced Modification More advanced changes can take effect using the `run.d` system. Similar to the `/etc/cont-init.d/` script system, any shell scripts (ending in .sh) in the `/run.d/` folder will be executed ahead of the S6 initialization. @@ -77,7 +83,6 @@ More advanced changes can take effect using the `run.d` system. Similar to the ` - If a `run.d` script terminates with a non-zero exit code, container will stop, terminating with the script's exit code, unless... - If script terminates with exit code of $SIGNAL_BUILD_STOP (99), this will signal the container to stop cleanly. This can be used for a multi-stage build process - ### Shutdown Behavior #### Sequence of events for a crashed supervised service: diff --git a/container/root/goss.base.yaml b/container/root/goss.base.yaml index 99e867f..a04b0cc 100644 --- a/container/root/goss.base.yaml +++ b/container/root/goss.base.yaml @@ -4,3 +4,38 @@ command: exit-status: 0 stderr: [] stdout: [] + # Validate binary installation and availability + # Unfortunately cannot rely on any test architecture to prove its working + archstring --x64 example --arm64 example: + exit-status: 0 + stdout: + - example + archstring -i example -a example: + exit-status: 0 + stdout: + - example + archstring --x64 example: + exit-status: 1 + stdout: + - /--arm64/ + archstring -i example: + exit-status: 1 + stdout: + - /--arm64/ + archstring --arm64 example: + exit-status: 1 + stdout: + - /--x64/ + archstring -a example: + exit-status: 1 + stdout: + - /--x64/ + # uneven number of parameters (shift overrun) + archstring -a a -i i -x: + exit-status: 1 + stdout: + - /usage/ + archstring -a a -i i -x a: + exit-status: 1 + stdout: + - /usage/ diff --git a/container/root/scripts/install_goss.sh b/container/root/scripts/install_goss.sh index dd5ed8c..e10eee7 100644 --- a/container/root/scripts/install_goss.sh +++ b/container/root/scripts/install_goss.sh @@ -9,19 +9,12 @@ GOSS_VERSION=v0.3.16 # Locate manually and commit below from https://github.com/aelsabbahy/goss/releases/download/${GOSS_VERSION}/goss-linux-${ARCH}.sha256 -GOSS_SHA256="" # Determined automatically to correctly select binary -ARCH="" - -if [[ "$(uname -m)" = "x86_64" ]]; then - echo "[goss install] Detected x86_64 architecture" - ARCH="amd64" - GOSS_SHA256=827e354b48f93bce933f5efcd1f00dc82569c42a179cf2d384b040d8a80bfbfb -elif [[ "$(uname -m)" = "aarch64" ]]; then - echo "[goss install] Detected ARM architecture" - ARCH="arm" - GOSS_SHA256=67c1e6185759a25bf9db334a9fe795a25708f2b04abe808a87d72edd6cd393fd -fi; +ARCH="$(archstring --arm64 arm --x64 amd64)" +GOSS_SHA256="$(archstring \ + --x64 827e354b48f93bce933f5efcd1f00dc82569c42a179cf2d384b040d8a80bfbfb \ + --arm64 67c1e6185759a25bf9db334a9fe795a25708f2b04abe808a87d72edd6cd393fd \ +)" curl -fL https://github.com/aelsabbahy/goss/releases/download/${GOSS_VERSION}/goss-linux-${ARCH} -o /usr/local/bin/goss diff --git a/container/root/scripts/install_s6.sh b/container/root/scripts/install_s6.sh index 0639c0a..ba62e74 100755 --- a/container/root/scripts/install_s6.sh +++ b/container/root/scripts/install_s6.sh @@ -7,15 +7,7 @@ # Requires curl, gpg (or gnupg on Alpine), and tar to be present # Determined automatically to correctly select binary -ARCH="" - -if [[ "$(uname -m)" = "x86_64" ]]; then - echo "[s6 install] Detected x86_64 architecture" - ARCH="amd64" -elif [[ "$(uname -m)" = "aarch64" ]]; then - echo "[s6 install] Detected ARM architecture" - ARCH="aarch64" -fi; +ARCH="$(archstring --x64 amd64 --arm64 aarch64)" S6_NAME=s6-overlay-${ARCH}.tar.gz S6_VERSION=v2.2.0.3 diff --git a/container/root/usr/local/bin/archstring b/container/root/usr/local/bin/archstring new file mode 100755 index 0000000..f4bca22 --- /dev/null +++ b/container/root/usr/local/bin/archstring @@ -0,0 +1,62 @@ +#!/bin/bash + +# Script to detect processor architecture and output one of the two input parameters +# Example: when a download path requires an arch-specific package name +# +# --x64 {value}: output if an x86_64 architecture is detected +# --arm64 {value}: output if an arm64 or aarch64 architecture is detected +function usage() { + echo "usage: $(basename $0) --x64 value --arm64 value" + exit 1 +} + +if [[ "$#" -eq 0 ]]; then + usage +fi + +while [[ "$#" -gt 0 ]] +do + case $1 in + -i|--x64) + declare x64="$2" + ;; + -a|--arm64) + declare arm64="$2" + ;; + *) + usage + ;; + esac + # shift 2, since we consumed the arch specifier and the value + shift 2 + # assert there are positional parameters remaining + if [[ "$?" -ne 0 ]]; then + usage + fi; +done + +if [[ -z "$x64" ]]; then + echo "error: missing --x64 input" + exit 1 +fi + +if [[ -z "$arm64" ]]; then + echo "error: missing --arm64 input" + exit 1 +fi + +DETECTED_ARCH="$(uname -m)" +ARCH_X64='x86_64' +ARCH_ARM64='aarch64' +ARCH_ARM64_ALT='arm64' + +if [[ $DETECTED_ARCH == $ARCH_X64 ]]; then + echo $x64 +elif [[ $DETECTED_ARCH == $ARCH_ARM64 ]]; then + echo $arm64 +elif [[ $DETECTED_ARCH == $ARCH_ARM64_ALT ]]; then + echo $arm64 +else + echo "failure: $DETECTED_ARCH not supported" + exit 1 +fi;