Skip to content
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
14 changes: 14 additions & 0 deletions images/rhel/assets/post-gen/cleanup-logs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

# journalctl
if command -v journalctl; then
journalctl --rotate
journalctl --vacuum-time=1s
fi

# delete all .gz and rotated file
find /var/log -type f -regex ".*\.gz$" -delete
find /var/log -type f -regex ".*\.[0-9]$" -delete

# wipe log files
find /var/log/ -type f -exec cp /dev/null {} \;
6 changes: 6 additions & 0 deletions images/rhel/assets/post-gen/environment-variables.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

# Replace $HOME with the default user's home directory for environmental variables related to the default user home directory

homeDir=$(cut -d: -f6 /etc/passwd | tail -1)
sed -i "s|\$HOME|$homeDir|g" /etc/environment
5 changes: 5 additions & 0 deletions images/rhel/assets/post-gen/systemd-linger.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

# Enable user session on boot, not on login
UserId=$(cut -d: -f3 /etc/passwd | tail -1)
loginctl enable-linger "$UserId"
42 changes: 42 additions & 0 deletions images/rhel/scripts/build/cleanup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash -e
################################################################################
## File: cleanup.sh
## Desc: Perform cleanup for RHEL
################################################################################

# before cleanup
before=$(df / -Pm | awk 'NR==2{print $4}')

# Clear the local repository of retrieved package files
yum clean all
rm -rf /var/cache/yum/*
rm -rf /tmp/*
rm -rf /root/.cache

# Rotate and vacuum journal logs if `journalctl` is available
if command -v journalctl; then
journalctl --rotate
journalctl --vacuum-time=1s
fi

# Delete all .gz and rotated files
find /var/log -type f -regex ".*\.gz$" -delete
find /var/log -type f -regex ".*\.[0-9]$" -delete

# Wipe log files
find /var/log/ -type f -exec cp /dev/null {} \;

# Remove mock binaries for yum/dnf
prefix=/usr/local/bin
for tool in yum dnf; do
rm -f $prefix/$tool
done

# after cleanup
after=$(df / -Pm | awk 'NR==2{print $4}')

# Display size
echo "Before: $before MB"
echo "After : $after MB"
# shellcheck disable=SC2004
echo "Delta : $(($after - $before)) MB"
35 changes: 35 additions & 0 deletions images/rhel/scripts/build/configure-dnf.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash -e
################################################################################
## File: configure-dnf.sh
## Desc: Configure dnf/yum, install jq package, and improve package management behavior.
################################################################################
# Source the helpers for use with the script
# shellcheck disable=SC1091
source "$HELPER_SCRIPTS"/install.sh
# Enable retries for DNF (maximum retries set to 10)
# shellcheck disable=SC2129
echo "retries=10" >> /etc/dnf/dnf.conf

# Automatically assume 'yes' for prompts in DNF
echo "assumeyes=True" >> /etc/dnf/dnf.conf

# Configure DNF to always consider phased updates
echo "phased_updates=1" >> /etc/dnf/dnf.conf

# Fix potential bad proxy or HTTP headers settings
cat <<EOF >> /etc/dnf/dnf.conf
http_caching=none
EOF

# Remove unattended-upgrade equivalents if present (e.g., dnf-automatic)
dnf remove -y dnf-automatic

# Display DNF repository configurations
echo 'DNF/YUM repositories:'
dnf repolist

# Update repositories and install jq
install_dnfpkgs jq

# Optional: Configure parallel downloads to speed up package installation
echo "max_parallel_downloads=10" >> /etc/dnf/dnf.conf
25 changes: 25 additions & 0 deletions images/rhel/scripts/build/configure-dnfpkg.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash -e
################################################################################
## File: configure-dnfpkg.sh
## Desc: Configure dnf and package management settings
################################################################################

# Source the helpers for use with the script
# shellcheck disable=SC1091
source "$HELPER_SCRIPTS"/etc-environment.sh

# Configure dnf to automatically answer 'yes' for package installation
# This replaces the non-interactive mode typically set in DEBIAN_FRONTEND
# shellcheck disable=SC2129
echo "assumeyes=True" >> /etc/dnf/dnf.conf

# Prevent dnf from prompting for confirmation on replacing configuration files
# Equivalent to dpkg's --force-confdef --force-confold
echo "override_install_langs=en_US.UTF-8" >> /etc/dnf/dnf.conf

# Hide information about packages that are no longer required
# dnf has an autoremove feature, but it can be configured to prevent auto removal prompts
echo "clean_requirements_on_remove=True" >> /etc/dnf/dnf.conf

# Configure dnf to automatically clean up unused packages and dependencies
echo "autoclean_metadata=True" >> /etc/dnf/dnf.conf
59 changes: 59 additions & 0 deletions images/rhel/scripts/build/configure-environment.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash -e
################################################################################
## File: configure-environment.sh
## Desc: Configure system and environment
################################################################################
# Source the helpers for use with the script
# shellcheck disable=SC1091
source "$HELPER_SCRIPTS"/os.sh
source "$HELPER_SCRIPTS"/etc-environment.sh

# Set ImageVersion and ImageOS env variables
set_etc_environment_variable "ImageVersion" "${IMAGE_VERSION}"
set_etc_environment_variable "ImageOS" "${IMAGE_OS}"

# Set the ACCEPT_EULA variable to Y value to confirm your acceptance of the End-User Licensing Agreement
set_etc_environment_variable "ACCEPT_EULA" "Y"

# This directory is supposed to be created in $HOME and owned by user(https://github.com/actions/runner-images/issues/491)
mkdir -p /etc/skel/.config/configstore
# shellcheck disable=SC2016
set_etc_environment_variable "XDG_CONFIG_HOME" '$HOME/.config'

# Change waagent entries to use /mnt for swap file
# sed -i 's/ResourceDisk.Format=n/ResourceDisk.Format=y/g' /etc/waagent.conf
# sed -i 's/ResourceDisk.EnableSwap=n/ResourceDisk.EnableSwap=y/g' /etc/waagent.conf
# sed -i 's/ResourceDisk.SwapSizeMB=0/ResourceDisk.SwapSizeMB=4096/g' /etc/waagent.conf

# Add localhost alias to ::1 IPv6
sed -i 's/::1 ip6-localhost ip6-loopback/::1 localhost ip6-localhost ip6-loopback/g' /etc/hosts

# Prepare directory and env variable for toolcache
AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache
mkdir -p $AGENT_TOOLSDIRECTORY && echo "Directory created." || echo "Directory already exists."
set_etc_environment_variable "AGENT_TOOLSDIRECTORY" "${AGENT_TOOLSDIRECTORY}"
set_etc_environment_variable "RUNNER_TOOL_CACHE" "${AGENT_TOOLSDIRECTORY}"
chmod -R 777 $AGENT_TOOLSDIRECTORY

# https://github.com/orgs/community/discussions/47563
echo 'net.ipv6.conf.all.disable_ipv6=1' | tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.default.disable_ipv6=1' | tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.lo.disable_ipv6=1' | tee -a /etc/sysctl.conf

# https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html
# https://www.suse.com/support/kb/doc/?id=000016692
echo 'vm.max_map_count=262144' | tee -a /etc/sysctl.conf

# https://kind.sigs.k8s.io/docs/user/known-issues/#pod-errors-due-to-too-many-open-files
echo 'fs.inotify.max_user_watches=655360' | tee -a /etc/sysctl.conf
echo 'fs.inotify.max_user_instances=1280' | tee -a /etc/sysctl.conf

# https://github.com/actions/runner-images/issues/9491
echo 'vm.mmap_rnd_bits=28' | tee -a /etc/sysctl.conf

# https://github.com/actions/runner-images/pull/7860
netfilter_rule='/etc/udev/rules.d/50-netfilter.rules'
rules_directory="$(dirname "${netfilter_rule}")"
mkdir -p "$rules_directory"
touch $netfilter_rule
echo 'ACTION=="add", SUBSYSTEM=="module", KERNEL=="nf_conntrack", RUN+="/usr/sbin/sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1"' | tee -a $netfilter_rule
60 changes: 60 additions & 0 deletions images/rhel/scripts/build/configure-image-data.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash -e
################################################################################
## File: configure-image-data.sh
## Desc: Create a file with image data and documentation links
################################################################################
# shellcheck disable=SC2153
imagedata_file="$IMAGEDATA_FILE"
image_version="$IMAGE_VERSION"
image_version_major=${image_version/.*/} # Extract the major version
image_version_minor=$(echo "$image_version" | cut -d "." -f 2) # Extract the minor version

# Determine OS name and version for CentOS
# shellcheck disable=SC2002
os_name=$(cat /etc/redhat-release | sed "s/ /\\\n/g") # Get OS name
# shellcheck disable=SC1083
os_version=$(rpm -E %{rhel}) # Get CentOS version
image_label="centos-${os_version}" # Set image label

REPO_OWNER="IBM"
REPO_NAME="action-runner-image-pz"
BRANCH="main"

api_release_response=$(curl -s ${GITHUB_TOKEN:+-H "Authorization: Bearer ${GITHUB_TOKEN}"} "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases/latest")
git_tag=$(echo "$api_release_response" | jq -r .tag_name)

build_sha=$(curl -s ${GITHUB_TOKEN:+-H "Authorization: Bearer ${GITHUB_TOKEN}"} "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/commits/${BRANCH}" | jq -r .sha)

github_url="https://github.com/${REPO_OWNER}/${REPO_NAME}/blob/${BRANCH}/images"
software_url="${github_url}/centos/toolsets/toolset-${image_version_major}${image_version_minor}.json"

if [ "$git_tag" != "null" ] && [ -n "$git_tag" ]; then
echo "Release found: ${git_tag}"
tag_slug=${git_tag//\//%2F} # URL encode slashes
releaseUrl="https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/tag/${tag_slug}"
else
echo "Warning: No release found. Falling back to commit SHA: ${build_sha}"
releaseUrl="https://github.com/${REPO_OWNER}/${REPO_NAME}/tree/${build_sha}"
fi

runner_image_version="$(date +%Y%m%d)"
image_build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
image_builder_id=$(cat /etc/machine-id 2>/dev/null || hostname -s 2>/dev/null)

# Create the image data JSON file
cat <<EOF > "$imagedata_file"
[
{
"group": "Runner Image Provisioner",
"detail": "Commit: ${build_sha}\nBuild Date: ${image_build_date}\nBuilder ID: ${image_builder_id}"
},
{
"group": "Operating System",
"detail": "${os_name}"
},
{
"group": "Runner Image",
"detail": "Image: ${image_label}\nVersion: ${runner_image_version}\nIncluded Software: ${software_url}\nImage Release: ${releaseUrl}"
}
]
EOF
18 changes: 18 additions & 0 deletions images/rhel/scripts/build/configure-limits.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash -e
################################################################################
## File: configure-limits.sh
## Desc: Configure limits
################################################################################
echo 'session required pam_limits.so' >> /etc/pam.d/system-auth
echo 'session required pam_limits.so' >> /etc/pam.d/password-auth
echo 'DefaultLimitNOFILE=65536' >> /etc/systemd/system.conf
echo 'DefaultLimitSTACK=16M:infinity' >> /etc/systemd/system.conf

# Raise Number of File Descriptors
# shellcheck disable=SC2129
echo '* soft nofile 65536' >> /etc/security/limits.conf
echo '* hard nofile 65536' >> /etc/security/limits.conf

# Double stack size from default 8192KB
echo '* soft stack 16384' >> /etc/security/limits.conf
echo '* hard stack 16384' >> /etc/security/limits.conf
104 changes: 104 additions & 0 deletions images/rhel/scripts/build/configure-runner.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/bin/bash

set -euo pipefail

header() {
TS=$(date +"%Y-%m-%dT%H:%M:%S%:z")
echo "${TS} +--------------------------------------------+"
echo "${TS} | $*"
echo "${TS} +--------------------------------------------+"
echo
}

msg() {
# shellcheck disable=SC2046
echo $(date +"%Y-%m-%dT%H:%M:%S%:z") "$*"
}

check_idempotency() {
header "Checking Idempotency"

msg "Fetching latest upstream version from ${RUNNERREPO}..."
UPSTREAM_TAG=$(git ls-remote --tags --refs --sort='v:refname' "${RUNNERREPO}" | tail -n1 | awk -F/ '{print $NF}')

UPSTREAM_VER="${UPSTREAM_TAG#v}"
msg "Latest Upstream Version: ${UPSTREAM_VER}"

CURRENT_VER="none"
if [ -f "/opt/runner-cache/bin/Runner.Listener" ]; then
CURRENT_VER=$(/opt/runner-cache/bin/Runner.Listener --version 2>/dev/null || echo "error")
fi

msg "Current Installed Version: ${CURRENT_VER}"

if [ "${UPSTREAM_VER}" == "${CURRENT_VER}" ]; then
header "Versions match (${UPSTREAM_VER}). Skipping build."
exit 0
else
msg "Versions do not match or runner not installed. Proceeding with build..."
fi
}

patch_runner() {
header "Cloning repo and Patching runner"
cd /tmp
git clone --tags -q "${RUNNERREPO}"
cd runner
# shellcheck disable=SC2046
git checkout $(git tag --sort=-v:refname | grep '^v[0-9]' | head -n1)
git apply --whitespace=nowarn "${IMAGE_FOLDER}"/runner-sdk-8.patch
sed -i'' -e '/version/s/8......"$/8.0.100"/' src/global.json
}

build_runner() {
export DOTNET_NUGET_SIGNATURE_VERIFICATION=false
header "Building runner binary"
cd src

msg "Running dev layout"
./dev.sh layout Release

msg "Creating package"
./dev.sh package Release

msg "Running tests"
./dev.sh test
}

install_runner() {
header "Installing runner"
mkdir -p /opt/runner-cache
tar -xf /tmp/runner/_package/*.tar.gz -C /opt/runner-cache
}

pre_cleanup() {
rm -rf /tmp/runner /opt/runner-cache
}

post_cleanup() {
rm -rf "${IMAGE_FOLDER}"/runner-sdk-8.patch \
/tmp/preseed-yaml /home/ubuntu/.nuget \
/home/runner/.local/share
}

run() {
check_idempotency
pre_cleanup
patch_runner
build_runner
install_runner
post_cleanup
}

RUNNERREPO="https://github.com/actions/runner"

# Parse arguments
while getopts "a:" opt; do
case ${opt} in
a) RUNNERREPO=${OPTARG} ;;
*) exit 1 ;;
esac
done
shift $(( OPTIND - 1 ))

run
Loading