14 Commits

Author SHA1 Message Date
Chris Evich
da6feaf093 Merge branch 'configuration-directory-fix' into 'main'
Update runner installation and attempt to fix storage volume errors

See merge request qontainers/pipglr!51
2025-01-06 16:48:31 +00:00
Lester Amoin Espiritu
b44ceb5418 Add some placeholders to the volume directories to try and fix erratic ownership changes 2025-01-03 22:01:32 +08:00
Lester Amoin Espiritu
5251497dc2 Explicitly indicate the root user for some runlabels 2025-01-03 22:00:13 +08:00
Lester Amoin Espiritu
d371873d07 Update runner download URLs 2025-01-03 21:58:34 +08:00
Lester Amoin Espiritu
c6c510b22a Include missing helper package for installation 2025-01-01 06:24:42 +08:00
Lester Amoin Espiritu
87a3bb5cb7 Update file .gitlab-ci.yml 2024-12-31 20:54:44 +00:00
Lester Amoin Espiritu
b9cfac3b27 Update file Containerfile 2024-12-31 20:46:38 +00:00
Chris Evich
233a989178 Merge branch 'feature/add-build-type-behavior' into 'main'
fix: add missing build type behavior

See merge request qontainers/pipglr!50
2024-07-31 19:21:45 +00:00
Gabriel Nützi
dc5da18118 fix: add missing build type behavior
- Add argument to container file.

Signed-off-by: Gabriel Nützi <gnuetzi@gmail.com>
2024-07-22 09:16:13 +02:00
Chris Evich
09b3d7876b Merge branch 'gabyx_add-better-tooling' into 'main'
feat: Add better tooling and CI

See merge request qontainers/pipglr!49
2024-07-10 14:13:03 +00:00
Gabriel Nützi
6dd52a3783 feat: Add better tooling and CI
- Improve the build of the image by introducing `build.sh`.
  It can be used with `podman` or `buildah` and
  also provides a way of building a `dev` or `prod`
  image for development purposes by
  `build.sh [dev|prod]`.

- CI runs this script as well with `buildah`.

Signed-off-by: Gabriel Nützi <gnuetzi@gmail.com>
2024-07-10 10:03:34 -04:00
Chris Evich
fe7deb1b10 Merge branch 'update_docs' into 'main'
Update setup docs

See merge request qontainers/pipglr!48
2024-05-08 15:19:31 +00:00
Chris Evich
adf47d94a5 Update setup docs
* Simplify the overview, include minimum podman version.
* Clarify linger setup
* Overhaul user-namespace setup section
* Rename "registration" to "activation" (gitlab 16+)

Signed-off-by: Chris Evich <cevich@redhat.com>
2024-05-08 11:15:11 -04:00
Chris Evich
be51686020 Permit pipelines running for tags
Signed-off-by: Chris Evich <cevich@redhat.com>
2024-05-07 15:28:04 -04:00
5 changed files with 173 additions and 96 deletions

View File

@@ -1,5 +1,4 @@
--- ---
default: default:
image: quay.io/buildah/stable:v1.32 image: quay.io/buildah/stable:v1.32
tags: tags:
@@ -11,6 +10,7 @@ workflow:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never when: never
- if: $CI_COMMIT_BRANCH - if: $CI_COMMIT_BRANCH
- if: $CI_COMMIT_TAG
include: include:
- component: gitlab.com/blue42u/ci.pre-commit/lite@0.2.0 - component: gitlab.com/blue42u/ci.pre-commit/lite@0.2.0
@@ -29,7 +29,7 @@ commit_check:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_PIPELINE_SOURCE == "merge_request_event"
- when: never - when: never
variables: variables:
BADRX: '^(squash!)|(fixup!)' BADRX: "^(squash!)|(fixup!)"
script: | script: |
dnf install -y git dnf install -y git
shortlogtmp=$(mktemp -p '' commit_check_tmp_XXXX) shortlogtmp=$(mktemp -p '' commit_check_tmp_XXXX)
@@ -44,29 +44,11 @@ build:
- saas-linux-medium-amd64 - saas-linux-medium-amd64
stage: deploy stage: deploy
variables: variables:
FF_GITLAB_REGISTRY_HELPER_IMAGE: 0
BUILDAH_FORMAT: docker BUILDAH_FORMAT: docker
BUILDAH_ISOLATION: chroot BUILDAH_ISOLATION: chroot
STORAGE_DRIVER: vfs STORAGE_DRIVER: vfs
before_script: before_script:
- echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY - echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
script: script:
# N/B: There could be more than one merge-request open with this branch's HEAD - scripts/build.sh
- |
IMAGE_TAG="${CI_COMMIT_REF_SLUG}";
if [[ -n "$CI_COMMIT_TAG" ]]; then
IMAGE_TAG="${CI_COMMIT_TAG}";
elif [[ -n "$CI_OPEN_MERGE_REQUESTS" ]]; then
IMAGE_TAG=mr$(echo "${CI_OPEN_MERGE_REQUESTS}" | cut -d, -f -1 | cut -d\! -f 2);
elif [[ "$CI_COMMIT_BRANCH" == "main" ]]; then
IMAGE_TAG="latest";
fi
echo "Building/Pushing to: ${CI_REGISTRY_IMAGE}:${IMAGE_TAG}";
- >-
buildah build \
--label "org.opencontainers.image.source=${CI_PROJECT_URL}" \
--label "org.opencontainers.image.revision=$CI_COMMIT_SHA" \
--label "org.opencontainers.image.created=$CI_JOB_STARTED_AT" \
--label "org.opencontainers.image.version=${IMAGE_TAG}" \
-t "${CI_REGISTRY_IMAGE}:${IMAGE_TAG}" "$CI_PROJECT_DIR"
- buildah images
- buildah push "${CI_REGISTRY_IMAGE}:${IMAGE_TAG}"

View File

@@ -20,6 +20,10 @@ ADD /root/ /root/
ADD /etc/ /etc/ ADD /etc/ /etc/
ADD /home/ /home/ ADD /home/ /home/
# The build type: either `dev` or `prod`
# In `dev` mode: the package manager will not be deleted.
ARG BUILD_TYPE=prod
# Allow image-builders to choose another version besides "latest" should # Allow image-builders to choose another version besides "latest" should
# an incompatible change be introduced. # an incompatible change be introduced.
ARG RUNNER_VERSION=latest ARG RUNNER_VERSION=latest
@@ -35,9 +39,11 @@ ARG TARGETARCH=amd64
ARG PRUNE_INTERVAL=daily # see systemd.timer for allowable values ARG PRUNE_INTERVAL=daily # see systemd.timer for allowable values
# All-in-one packaging/image-setup script to keep things simple. # All-in-one packaging/image-setup script to keep things simple.
RUN PRUNE_INTERVAL=${PRUNE_INTERVAL} \ RUN \
RUNNER_VERSION=${RUNNER_VERSION} \ PRUNE_INTERVAL=${PRUNE_INTERVAL} \
bash /root/setup.sh RUNNER_VERSION=${RUNNER_VERSION} \
BUILD_TYPE=${BUILD_TYPE} \
bash /root/setup.sh
VOLUME /cache /home/podman/.local/share/containers VOLUME /cache /home/podman/.local/share/containers
ENTRYPOINT /lib/systemd/systemd ENTRYPOINT /lib/systemd/systemd
@@ -64,6 +70,7 @@ ARG ENABLE_FIPS=true
# may be changed if you know what you're doing. # may be changed if you know what you're doing.
LABEL register="podman run -it --rm \ LABEL register="podman run -it --rm \
--secret=REGISTRATION_TOKEN,type=env \ --secret=REGISTRATION_TOKEN,type=env \
--user=root \
-v ./config.toml:/etc/gitlab-runner/config.toml:Z \ -v ./config.toml:/etc/gitlab-runner/config.toml:Z \
-e REGISTER_NON_INTERACTIVE=true \ -e REGISTER_NON_INTERACTIVE=true \
-e CI_SERVER_URL=${GITLAB_URL} \ -e CI_SERVER_URL=${GITLAB_URL} \
@@ -89,6 +96,7 @@ LABEL setupcache="podman volume create --opt o=uid=1000,gid=1001 pipglr-cache"
# Helper to extract the current configuration secret to allow editing. # Helper to extract the current configuration secret to allow editing.
LABEL dumpconfig="podman run -it --rm \ LABEL dumpconfig="podman run -it --rm \
--user=root \
--secret config.toml --entrypoint=/bin/cat \ --secret config.toml --entrypoint=/bin/cat \
\$IMAGE /var/run/secrets/config.toml" \$IMAGE /var/run/secrets/config.toml"
@@ -97,6 +105,7 @@ LABEL dumpconfig="podman run -it --rm \
# Note: The contents of the volumes are not critical, they may be removed # Note: The contents of the volumes are not critical, they may be removed
# and re-created (see above) to quickly free-up disk space. # and re-created (see above) to quickly free-up disk space.
LABEL run="podman run -dt --name pipglr \ LABEL run="podman run -dt --name pipglr \
--user=root \
--secret config.toml,uid=1001,gid=1001 \ --secret config.toml,uid=1001,gid=1001 \
-v pipglr-storage:/home/podman/.local/share/containers \ -v pipglr-storage:/home/podman/.local/share/containers \
-v pipglr-cache:/cache \ -v pipglr-cache:/cache \

View File

@@ -36,79 +36,55 @@ container. While it's possible to use the container with your own command-line,
it's highly recommended to base them off of one of the labels. See the examples it's highly recommended to base them off of one of the labels. See the examples
below for more information. below for more information.
**_Note:_** Some older versions of podman don't support the `container runlabel` *_Only podman versions 4.8.x and later are supported by pipglr._*
sub-command. If this is the case, you may simulate it with the following,
substituting `<label>` with one of the predefined values (i.e. `register`,
`setupconfig`, etc.):
```bash
$ IMAGE="registry.gitlab.com/qontainers/pipglr:latest"
$ eval $(podman inspect --format=json $IMAGE | jq -r .[].Labels.<label>)
```
#### Persistent Containers (step 1) #### Persistent Containers (step 1)
By default on many distributions, regular users aren't permitted to leave By default on many distributions, regular users aren't permitted to leave
background processes running after they log out. Since this is likely desired background processes running after they log out. Since this is likely desired
for running the pipglr container long-term, `systemd` needs to be configured to for running the pipglr container long-term, `systemd` needs to be configured to
override this policy. For this, you (`$USER`) will need root access on the override this policy. Doing so requires root or `sudo` access on the
system. system. Assuming the user `johndoe` will be executing the pipglr container,
linger may be enabled (as the admin user or root) with a command like:
```bash ```bash
$ sudo loginctl enable-linger $USER $ sudo loginctl enable-linger `johndoe`
``` ```
Side-effect: This will allow your user to persist other user-level systemd Side-effect: This will allow the user (`johndoe` for example) to persist
services as well. For example `podman.socket` is handy to enable for other user-level systemd services as well. For example `podman.socket` is
`podman remote` access. You could also handy to enable for `podman remote` access. You could also
[setup quadlet](https://www.redhat.com/sysadmin/quadlet-podman) or a systemd [setup quadlet](https://www.redhat.com/sysadmin/quadlet-podman) or a systemd
unit so pipglr starts up on system boot. unit so pipglr starts up on system boot.
#### Expanded User-Namespace (step 2) **_This is probably important_** #### Expanded Host-system User-Namespace (step 2)
As an added protection/safety measure, pipglr excludes three UID/GIDs from being **_This is really important and frequently the cause of pipglr issues_**
used by job-level containers. One for `root`, another for `runner` and a third
for `podman`. However, some container images you may want to use for jobs
(mainly Debian/Ubuntu), assign one/more essential users a high UID/GID value
(like `65535`).
At the same time, most distributions also set `65536` as the default maximum On the host, as root, edit the two files `/etc/subuid` and `/etc/subgid` to
number (including ID `0`) of IDs to allocate for user-namespaces (via expand the pipglr user's ID allocation by 3. For example if the host user
`/etc/login.defs`). This creates a problem you won't realize until the runner running the pipglr container is named `johndoe`, this entry in the files should
actually picks up a job. The main symptom of this issue will be messages in be edited like:
the pipglr containers log, similar to (abbreviated):
```text
...cut...
running `/usr/bin/newuidmap ...cut...`: newuidmap: write to uid_map failed: Operation not permitted
Error: cannot set up namespace using "/usr/bin/newuidmap": exit status 1
...cut...
```
or
```text
E: setgroups 65534 failed - setgroups (22: Invalid argument)
```
**_The good news is, working around this is relatively simple:_**
As root, edit the two files `/etc/subuid` and `/etc/subgid` to expand the by 3
IDs. For example assuming a user running the pipglr container is called
`johndoe`, the contents of these files should be edited to allocate `65539` IDs
like:
`johndoe:<some number>:65539` `johndoe:<some number>:65539`
Where `<some number>` was set by your OS when the `johndoe` user was created Where `<some number>` was set by the OS when the `johndoe` user was created
(you can ignore this). Only the last number needs to be increased. This change (you can ignore this). Only the last number needs to be increased by three.
will be effective on next login, or immediately by running: This change will be effective on the user's next login, or immediately
by running (as the host pipglr user):
`podman system migrate` `podman system migrate`
_Note:_ This will stop any currently running containers. _Note:_ This will stop any currently running containers.
#### Runner Registration (step 3) _Details:_ As an added protection/safety measure, pipglr excludes three UID/GIDs
from being used by job-level (nested) containers. One for `root`, another for
`runner` and a third for `podman`. This necessitates expanding the number of
available UIDs/GIDs from the host machine, to the pipglr container. This way,
the full set of 65535 UIDs/GIDs may be utilized by job-level (nested)
sub-containers.
#### Runner Activation/Registration (step 3)
All runners must be connected to a project or group runner configuration on your All runners must be connected to a project or group runner configuration on your
gitlab instance (or `gitlab.com`). This is done using a special registration gitlab instance (or `gitlab.com`). This is done using a special registration
@@ -238,6 +214,9 @@ version of the gitlab runner.
Several build arguments are available to control the output image: Several build arguments are available to control the output image:
- `BUILD_TYPE`: The build type, either `prod` or `dev`. In `dev` mode, the package
manager is not deleted for development and debugging purposes. Please see
[`build.sh`](scripts/build.sh) for more details.
- `PRUNE_INTERVAL`: A systemd.timer compatible `OnCalendar` value that - `PRUNE_INTERVAL`: A systemd.timer compatible `OnCalendar` value that
determines how often to prune Podman's storage of disused containers and determines how often to prune Podman's storage of disused containers and
images. Defaults to `daily`, but should be adjusted based on desired images. Defaults to `daily`, but should be adjusted based on desired
@@ -257,6 +236,9 @@ Several build arguments are available to control the output image:
containers running in `--privileged` mode. This will affect the ability to containers running in `--privileged` mode. This will affect the ability to
build container images in CI jobs using tools like podman or buildah. build container images in CI jobs using tools like podman or buildah.
Additional build-args are available as well. See the `Containerfile` comments
for more details.
### Environment Variables ### Environment Variables
Nearly every option to every gitlab-runner sub-command may be specified via Nearly every option to every gitlab-runner sub-command may be specified via

View File

@@ -33,6 +33,10 @@ function check_vars() {
die "Env. variable '$varname' must be non-empty." die "Env. variable '$varname' must be non-empty."
fi fi
done done
if [[ ! "$BUILD_TYPE" =~ dev|prod ]]; then
die "Build type must be 'dev' or 'prod': '$BUILD_TYPE'."
fi
} }
function main() { function main() {
@@ -47,10 +51,15 @@ function main() {
setup_service_podman setup_service_podman
setup_service_runner setup_service_runner
setup_gitlab_config setup_gitlab_config
setup_volumes
finalize_ownership finalize_ownership
} }
function is_release() {
[ "$BUILD_TYPE" = "prod" ] || return 1
}
function install_packages() { function install_packages() {
readarray xpackages < <(grep -vE '^(# )+' </root/xpackages.txt) readarray xpackages < <(grep -vE '^(# )+' </root/xpackages.txt)
local exclude_args=() local exclude_args=()
@@ -67,27 +76,30 @@ function install_packages() {
# 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_FILES=(
"https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/$RUNNER_VERSION/rpm/gitlab-runner_${TARGETARCH}-fips.rpm"
)
else else
PACKAGE_FILE="gitlab-runner_${TARGETARCH}.rpm" PACKAGE_FILES=(
"https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/$RUNNER_VERSION/rpm/gitlab-runner_${TARGETARCH}.rpm"
"https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/$RUNNER_VERSION/rpm/gitlab-runner-helper-images.rpm"
)
fi fi
"${dnf[@]}" "${exclude_args[@]}" \ "${dnf[@]}" "${exclude_args[@]}" \
--setopt=tsflags=noscripts install \ --setopt=tsflags=noscripts install \
"https://gitlab-runner-downloads.s3.amazonaws.com/$RUNNER_VERSION/rpm/${PACKAGE_FILE}" ${PACKAGE_FILES[@]}
# 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. rm -rf \
rm -rf \ /etc/systemd/system/getty.target.wants/* \
/etc/dnf/protected.d/* \ /etc/systemd/system/multi-user.target.wants/* \
/etc/systemd/system/getty.target.wants/* \ /etc/systemd/system/sysinit.target.wants/* \
/etc/systemd/system/multi-user.target.wants/* \ /etc/systemd/system/timers.target.wants/* \
/etc/systemd/system/sysinit.target.wants/* \ /lib/systemd/system/graphical.target.wants/* \
/etc/systemd/system/timers.target.wants/* \ /lib/systemd/system/multi-user.target.wants/{getty.target,systemd-ask-password-wall.path} \
/lib/systemd/system/graphical.target.wants/* \ /lib/systemd/system/sys-kernel*.mount
/lib/systemd/system/multi-user.target.wants/{getty.target,systemd-ask-password-wall.path} \
/lib/systemd/system/sys-kernel*.mount
# Allow removing dnf, sudo, etc. packages. # Allow removing dnf, sudo, etc. packages.
rm -rf \ rm -rf \
@@ -96,13 +108,16 @@ rm -rf \
# This makes the image smaller and reduces the attack-surface. # This makes the image smaller and reduces the attack-surface.
dnf remove -y "${xpackages[@]}" dnf remove -y "${xpackages[@]}"
# Wipe out the DNF cache, then remove it entirely, again to make the image smaller. if is_release; then
"${dnf[@]}" clean all # Wipe out the DNF cache, then remove it entirely, again to make the image smaller.
rm -rf /var/cache/dnf /var/log/dnf* /var/log/yum.* "${dnf[@]}" clean all
rpm -e dnf rm -rf /var/cache/dnf /var/log/dnf* /var/log/yum.*
rpm -e dnf
fi
# Workaround base-image failing to confer capabilties properly on # Workaround https://bugzilla.redhat.com/show_bug.cgi?id=1995337
# /usr/bin/new{u,g}idmap to `cap_set{u,g}id=ep` in new image layers. # Base-image failing to confer capabilities 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
} }
@@ -139,9 +154,11 @@ function setup_user() {
function setup_volumes() { 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
touch /home/podman/.local/share/containers/.placeholder
# 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
touch /cache/.placeholder
# 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

87
scripts/build.sh Executable file
View File

@@ -0,0 +1,87 @@
#!/usr/bin/env bash
# Usage: build.sh [<build-type>]
#
# If the build type (second arg. `<build-type>`) is `prod`
# the images are build in `release` mode. For all other build types
# the images are build for development and testing purposes
# By default the build type is `prod`.
set -eu
set -o pipefail
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)/.."
cd "$ROOT_DIR"
function ci_running() {
[ "${CI:-}" = "true" ] && return 0
return 1
}
# Define the image tag depending on the context.
function get_image_tag() {
local build_type="$1"
local image_tag="${build_type}-latest"
# Define image tag.
if ci_running; then
# The image tag gets adjusted depending on
# if it is a merge request or build on the
# main branch or on a tag.
image_tag="${CI_COMMIT_REF_SLUG:-}"
if [[ -n "${CI_COMMIT_TAG:-}" ]]; then
image_tag="${CI_COMMIT_TAG}"
elif [[ -n "${CI_OPEN_MERGE_REQUESTS:-}" ]]; then
image_tag=mr$(echo "${CI_OPEN_MERGE_REQUESTS}" | cut -d, -f -1 | cut -d\! -f 2)
elif [[ "${CI_COMMIT_BRANCH:-}" == "main" ]]; then
image_tag="latest"
fi
fi
echo "$image_tag"
}
function main() {
# Define common build variables.
local container_mgr=${CI_CONTAINER_MGR:-buildah}
local project_dir=${CI_PROJECT_DIR:-.}
local registry_name=${CI_REGISTRY_IMAGE:-"containers-storage:pipglr"}
local build_type=${CI_BUILD_TYPE:-${1:-prod}}
# Define image name and tag.
local image_tag image_name
image_tag=$(get_image_tag "$build_type")
image_name="${registry_name}:${image_tag}"
# Define OpenContainers labels.
local oc_project_url=${CI_PROJECT_URL:-file://$ROOT_DIR}
local oc_commit_sha=${CI_COMMIT_SHA:-$(git rev-parse HEAD)}
local oc_job_started_at=${CI_JOB_STARTED_AT:-$(date -u --iso-8601=seconds)}
local oc_version="${image_tag}"
BUILD_CMD=(
"${container_mgr}" build
--label "org.opencontainers.image.source=${oc_project_url}"
--label "org.opencontainers.image.revision=${oc_commit_sha}"
--label "org.opencontainers.image.created=${oc_job_started_at}"
--label "org.opencontainers.image.version=${oc_version}"
--build-arg "BUILD_TYPE=${build_type}"
-t "$image_name"
"${project_dir}")
echo "Build image: '$image_name'"
echo -e "Build command:\n" "${BUILD_CMD[@]}"
"${BUILD_CMD[@]}"
echo "Images are:"
"${container_mgr}" images
if ci_running; then
echo "Pushing image: ${image_name}"
"${container_mgr}" push "${image_name}"
fi
}
main "$@"