Merge branch 'feature/2-refactor-setup' into 'main'
feat: Refactor setup See merge request qontainers/pipglr!39
This commit is contained in:
119
root/setup.sh
119
root/setup.sh
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
# This script is intended to be run during container-image build. Any
|
# This script is intended to be run during container-image build. Any
|
||||||
# other usage outside this context is likely to cause harm.
|
# other usage outside this context is likely to cause harm.
|
||||||
#
|
#
|
||||||
@@ -19,39 +21,61 @@
|
|||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
|
function die() {
|
||||||
|
echo -n '!! ERROR:' >&2
|
||||||
|
printf " %s\n" "$@" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_vars() {
|
||||||
for varname in PRUNE_INTERVAL RUNNER_VERSION TARGETARCH; do
|
for varname in PRUNE_INTERVAL RUNNER_VERSION TARGETARCH; do
|
||||||
if [[ -z "${!varname}" ]]; then
|
if [[ -z "${!varname}" ]]; then
|
||||||
echo "Error: \$$varname must be non-empty."
|
die "Env. variable '$varname' must be non-empty."
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
# Show what's happening to make debugging easier
|
||||||
|
set -x
|
||||||
|
|
||||||
# Make image smaller by not installing docs.
|
# Make image smaller by not installing docs.
|
||||||
DNF="dnf --setopt=tsflags=nodocs -y"
|
dnf=(dnf --setopt=tsflags=nodocs -y)
|
||||||
|
|
||||||
for rpm in $(egrep -v '^(# )+' </root/xpackages.txt); do
|
install_packages
|
||||||
x+="--exclude=$rpm "
|
setup_user
|
||||||
|
setup_service_podman
|
||||||
|
setup_service_runner
|
||||||
|
setup_gitlab_config
|
||||||
|
|
||||||
|
finalize_ownership
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_packages() {
|
||||||
|
readarray xpackages < <(grep -vE '^(# )+' </root/xpackages.txt)
|
||||||
|
local exclude_args=()
|
||||||
|
for rpm in "${xpackages[@]}"; do
|
||||||
|
exclude_args+=("--exclude=$rpm")
|
||||||
done
|
done
|
||||||
|
|
||||||
set -x # show what's happening to make debugging easier
|
|
||||||
|
|
||||||
# DNF itself or a dependence may need upgrading, take care of it first.
|
# DNF itself or a dependence may need upgrading, take care of it first.
|
||||||
$DNF upgrade
|
"${dnf[@]}" upgrade &&
|
||||||
|
"${dnf[@]}" "${exclude_args[@]}" install \
|
||||||
$DNF $x install \
|
|
||||||
podman \
|
podman \
|
||||||
systemd
|
systemd
|
||||||
|
|
||||||
# Gitlab-runner package contains scriptlets which do not function properly inside a
|
# Gitlab-runner package contains scriptlets which do not function properly inside a
|
||||||
# container-build environment where systemd is not active/running.
|
# container-build environment where systemd is not active/running.
|
||||||
|
|
||||||
if [[ ${ENABLE_FIPS} == true && $(cat /proc/sys/crypto/fips_enabled) == 1 ]]; then
|
if [[ ${ENABLE_FIPS} == true && $(cat /proc/sys/crypto/fips_enabled) == 1 ]]; then
|
||||||
PACKAGE_FILE="gitlab-runner_${TARGETARCH}-fips.rpm"
|
PACKAGE_FILE="gitlab-runner_${TARGETARCH}-fips.rpm"
|
||||||
else
|
else
|
||||||
PACKAGE_FILE="gitlab-runner_${TARGETARCH}.rpm"
|
PACKAGE_FILE="gitlab-runner_${TARGETARCH}.rpm"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$DNF $x --setopt=tsflags=noscripts install \
|
"${dnf[@]}" "${exclude_args[@]}" \
|
||||||
https://gitlab-runner-downloads.s3.amazonaws.com/$RUNNER_VERSION/rpm/${PACKAGE_FILE}
|
--setopt=tsflags=noscripts install \
|
||||||
|
"https://gitlab-runner-downloads.s3.amazonaws.com/$RUNNER_VERSION/rpm/${PACKAGE_FILE}"
|
||||||
|
|
||||||
|
|
||||||
# Allow removing dnf, sudo, etc. packages. Also don't start unnecessary or broken
|
# Allow removing dnf, sudo, etc. packages. Also don't start unnecessary or broken
|
||||||
# systemd services, like anything kernel related or login gettys.
|
# systemd services, like anything kernel related or login gettys.
|
||||||
@@ -65,69 +89,108 @@ rm -rf \
|
|||||||
/lib/systemd/system/multi-user.target.wants/{getty.target,systemd-ask-password-wall.path} \
|
/lib/systemd/system/multi-user.target.wants/{getty.target,systemd-ask-password-wall.path} \
|
||||||
/lib/systemd/system/sys-kernel*.mount
|
/lib/systemd/system/sys-kernel*.mount
|
||||||
|
|
||||||
|
# Allow removing dnf, sudo, etc. packages.
|
||||||
|
rm -rf \
|
||||||
|
/etc/dnf/protected.d/*
|
||||||
# Remove unnecessary packages, see xpackages.txt to learn how this list was generated.
|
# Remove unnecessary packages, see xpackages.txt to learn how this list was generated.
|
||||||
# This makes the image smaller and reduces the attack-surface.
|
# This makes the image smaller and reduces the attack-surface.
|
||||||
dnf remove -y $(egrep -v '^(# )+' /root/xpackages.txt)
|
dnf remove -y "${xpackages[@]}"
|
||||||
|
|
||||||
# Wipe out the DNF cache, then remove it entirely, again to make the image smaller.
|
# Wipe out the DNF cache, then remove it entirely, again to make the image smaller.
|
||||||
$DNF clean all
|
"${dnf[@]}" clean all
|
||||||
rm -rf /var/cache/dnf /var/log/dnf* /var/log/yum.*
|
rm -rf /var/cache/dnf /var/log/dnf* /var/log/yum.*
|
||||||
rpm -e dnf
|
rpm -e dnf
|
||||||
|
|
||||||
# Workaround https://bugzilla.redhat.com/show_bug.cgi?id=1995337
|
# Workaround base-image failing to confer capabilties properly on
|
||||||
|
# /usr/bin/new{u,g}idmap to `cap_set{u,g}id=ep` in new image layers.
|
||||||
rpm --setcaps shadow-utils
|
rpm --setcaps shadow-utils
|
||||||
|
}
|
||||||
|
|
||||||
# Prevent copying of skel since it can interfere with the gitlab-runner
|
function setup_user() {
|
||||||
mkdir -p /home/podman /home/runner
|
|
||||||
# Guarantee uid/gid 1000 for user 'podman' / 1001 for user 'runner'.
|
# Guarantee uid/gid 1000 for user 'podman' / 1001 for user 'runner'.
|
||||||
groupadd -g 1000 podman
|
groupadd -g 1000 podman
|
||||||
groupadd -g 1001 runner
|
groupadd -g 1001 runner
|
||||||
|
|
||||||
# Separate users for services to increase process isolation.
|
# Separate users for services to increase process isolation.
|
||||||
# The 'podman' user's socket service writes /home/runner/podman.socket
|
# The 'podman' user's socket service writes /home/runner/podman.socket
|
||||||
|
# Prevent copying of skel since it can interfere with the gitlab-runner
|
||||||
|
mkdir -p /home/podman /home/runner
|
||||||
useradd -M -u 1000 -g podman -G runner podman
|
useradd -M -u 1000 -g podman -G runner podman
|
||||||
useradd -M -u 1001 -g runner runner
|
useradd -M -u 1001 -g runner runner
|
||||||
# Allow 'podman' user to create socket file under /home/runner.
|
|
||||||
|
# Allow only podman in `/home/podman`.
|
||||||
|
chmod 700 /home/podman
|
||||||
|
# Allow 'podman' user to create socket file under `/home/runner`.
|
||||||
chmod 770 /home/runner
|
chmod 770 /home/runner
|
||||||
|
|
||||||
# Overwrite defaults, only user 'podman' permited to have a user-namespace
|
# Set permissions.
|
||||||
|
chown -R runner:runner /home/runner
|
||||||
|
chown -R podman:podman /home/podman
|
||||||
|
|
||||||
|
# Overwrite defaults, only user 'podman' permitted to have a user-namespace
|
||||||
# Split the namespaced ID's around the containers root (ID 0), podman (ID 1000), and
|
# Split the namespaced ID's around the containers root (ID 0), podman (ID 1000), and
|
||||||
# runner (ID 1001) such that the user-namespace of any nested containers cannot
|
# runner (ID 1001) such that the user-namespace of any nested containers cannot
|
||||||
# read or write any files owned by these users (and/or hijack nested container processes).
|
# read or write any files owned by these users (and/or hijack nested container processes).
|
||||||
# N/B: The range-end (999+64536) ensures a total of 65535 IDs are available for nested-containers.
|
# N/B: The range-end (999+64536) ensures a total of 65535 IDs are available for nested-containers.
|
||||||
# This requires the host provide a sufficiently large range, i.e. `pipglr:<start>:65539`
|
# This requires the host provide a sufficiently large range, i.e. `pipglr:<start>:65539`
|
||||||
echo -e "podman:1:999\npodman:1002:64536" | tee /etc/subuid >/etc/subgid
|
echo -e "podman:1:999\npodman:1002:64536" | tee /etc/subuid >/etc/subgid
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup_volumes() {
|
||||||
# Host volume mount necessary for nested-podman to use overlayfs2 for container & volume storage.
|
# Host volume mount necessary for nested-podman to use overlayfs2 for container & volume storage.
|
||||||
mkdir -p /home/podman/.local/share/containers
|
mkdir -p /home/podman/.local/share/containers
|
||||||
|
|
||||||
# Nested-container's local container-cache volume mount, recommended by gitlab-runner docs.
|
# Nested-container's local container-cache volume mount, recommended by gitlab-runner docs.
|
||||||
mkdir -p /cache
|
mkdir -p /cache
|
||||||
|
|
||||||
# Both the gitlab-runner and podman need access to the cache directory / volume mount.
|
# Both the gitlab-runner and podman need access to the cache directory / volume mount.
|
||||||
chown podman:runner /cache
|
chown podman:runner /cache
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup_service_podman() {
|
||||||
# Setup persistent 'podman' user services to start & run without a login.
|
# Setup persistent 'podman' user services to start & run without a login.
|
||||||
mkdir -p /var/lib/systemd/linger
|
mkdir -p /var/lib/systemd/linger
|
||||||
touch /var/lib/systemd/linger/podman
|
touch /var/lib/systemd/linger/podman
|
||||||
|
|
||||||
# Setup 'podman' socket and a container-storage pruning service for 'podman' user.
|
# Setup 'podman' socket and a container-storage pruning service for 'podman' user.
|
||||||
mkdir -p /home/podman/.config/systemd/user/{sockets.target.wants,default.target.wants}
|
mkdir -p /home/podman/.config/systemd/user/{sockets.target.wants,default.target.wants}
|
||||||
|
|
||||||
cd /home/podman/.config/systemd/user/
|
cd /home/podman/.config/systemd/user/
|
||||||
ln -s $PWD/podman.socket ./sockets.target.wants/ # Added from Containerfile
|
ln -s "$(pwd)/podman.socket" ./sockets.target.wants/ # Added from Containerfile
|
||||||
ln -s $PWD/prune.timer ./default.target.wants/ # also from Containerfile
|
ln -s "$(pwd)/prune.timer" ./default.target.wants/ # also from Containerfile
|
||||||
|
|
||||||
# Substitute value from --build-arg if specified, otherwise use default from Containerfile.
|
# Substitute value from --build-arg if specified, otherwise use default from Containerfile.
|
||||||
sed -i -e "s/@@@PRUNE_INTERVAL@@@/$PRUNE_INTERVAL/" ./prune.timer
|
sed -i -e "s/@@@PRUNE_INTERVAL@@@/$PRUNE_INTERVAL/" ./prune.timer
|
||||||
# Containerfile ADD instruction does not properly set ownership/permissions.
|
}
|
||||||
chown -R 1000:1000 /home/podman
|
|
||||||
chmod 700 /home/podman
|
|
||||||
|
|
||||||
|
function setup_service_runner() {
|
||||||
# Setup persistent 'runner' user services to start & run without a login.
|
# Setup persistent 'runner' user services to start & run without a login.
|
||||||
touch /var/lib/systemd/linger/runner
|
touch /var/lib/systemd/linger/runner
|
||||||
|
|
||||||
|
# Setup persistent 'runner' user services to start & run without a login.
|
||||||
mkdir -p /home/runner/.config/systemd/user/default.target.wants
|
mkdir -p /home/runner/.config/systemd/user/default.target.wants
|
||||||
|
|
||||||
cd /home/runner/.config/systemd/user/
|
cd /home/runner/.config/systemd/user/
|
||||||
# Does not depend on podman.socket file availablility, will retry if not present.
|
# Does not depend on podman.socket file availability, will retry if not present.
|
||||||
ln -s $PWD/runner.service ./default.target.wants/
|
ln -s "$(pwd)/runner.service" ./default.target.wants/
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup_gitlab_config() {
|
||||||
# gitlab-runner will create side-car '.runner_system_id' file next to 'config.toml'
|
# gitlab-runner will create side-car '.runner_system_id' file next to 'config.toml'
|
||||||
# on first startup. Ensure access is allowed. Also link to future config file
|
# on first startup. Ensure access is allowed. Also link to future config file
|
||||||
# presented as a container-secret.
|
# presented as a container-secret.
|
||||||
mkdir -p /home/runner/.gitlab-runner
|
mkdir -p /home/runner/.gitlab-runner
|
||||||
ln -s /var/run/secrets/config.toml /home/runner/.gitlab-runner/config.toml
|
ln -s /var/run/secrets/config.toml /home/runner/.gitlab-runner/config.toml
|
||||||
# Containerfile ADD instruction does not properly set ownership/permissions.
|
|
||||||
chown -R runner:runner /home/runner
|
|
||||||
chmod -R 700 /home/runner/.gitlab-runner
|
chmod -R 700 /home/runner/.gitlab-runner
|
||||||
|
}
|
||||||
|
|
||||||
|
function finalize_ownership() {
|
||||||
|
# Adjust ownership to all files created after `setup_user`.
|
||||||
|
# and also to the `ADD` instruction in the `Containerfile`.
|
||||||
|
chown -R runner:runner /home/runner
|
||||||
|
chown -R podman:podman /home/podman
|
||||||
|
}
|
||||||
|
|
||||||
|
check_vars
|
||||||
|
main
|
||||||
|
|||||||
Reference in New Issue
Block a user