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
47 changes: 47 additions & 0 deletions .github/workflows/cd-rockylinux9-rpm-builder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: CD for rockylinux9-rpm-builder

on:
push:
branches: ['main']
paths: ['rockylinux9-rpm-builder/**', '!**/*.md']

env:
REGISTRY: ghcr.io
IMAGE_NAME: urbdyn/rockylinux9-rpm-builder

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: ./rockylinux9-rpm-builder
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
47 changes: 47 additions & 0 deletions .github/workflows/ci-rockylinux9-rpm-builder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: CI for rockylinux9-rpm-builder

on:
pull_request:
branches: ['main']
paths: ['rockylinux9-rpm-builder/**', '!**/*.md']

env:
REGISTRY: ghcr.io
IMAGE_NAME: urbdyn/rockylinux9-rpm-builder

jobs:
build-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: read

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Build Docker image
uses: docker/build-push-action@v6
with:
context: ./rockylinux9-rpm-builder
push: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ This repo is a collection of utilities for building software as used by Urban Dy
2. [centos7-rpm-builder](./centos7-rpm-builder/)
3. [rockylinux8-rpm-builder](./rockylinux8-rpm-builder/)
4. [rockylinux9-builder](./rockylinux9-builder/)
5. [rockylinux9-rpm-builder](./rockylinux9-rpm-builder/)
15 changes: 15 additions & 0 deletions rockylinux9-rpm-builder/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file builds an RPM build image for Rocky Linux 9

# Using Rock Linux 9 as base image to support rpmbuild
FROM rockylinux:9

# Installing tools needed for rpmbuild
RUN dnf install -y rpm-build rpmlint rpmdevtools systemd sudo selinux-policy-devel && \
dnf clean all

# Copy over helper scripts
COPY setup_rpm_users /usr/bin/setup_rpm_users
COPY build_rpm_from_env_vars /usr/bin/build_rpm_from_env_vars

# Setup commend to run by default
CMD build_rpm_from_env_vars run
47 changes: 47 additions & 0 deletions rockylinux9-rpm-builder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# urbdyn/rockylinux9-rpm-builder

This is a Docker container for building Rocky Linux 9 RPM packages.

It has the benefit of providing all the needed boiler plate and avoiding the long waits in CI needed to install the full build toolchain in a clean container.

Our recommended use of it is to build your own container with it to ensure the user/group of the person running the container matches that of the internal container user.
This means you can easily copy files and mount directories between the host and container without issue.

## Creating container with this container

```Dockerfile
FROM urbdyn/rockylinux9-rpm-builder:latest

# Accept user input when building container with fallback to common Linux user pattern
ARG _USER_ID
ARG _GROUP_ID
ENV _USER_ID ${_USER_ID:-1001}
ENV _GROUP_ID ${_GROUP_ID:-1002}

# Run script to create users and declare new user as default
RUN setup_rpm_users
USER $_USER_ID:$_GROUP_ID

# Install any needed packages here
# ...
```

## Running container

```bash
docker create -it \
--user "$_uid:$_gid" \
--name "$container_builder_container" \
-v "$build_dir/:/home/builder/rpmbuild/" \
-e SPEC_FILE_NAMES="foobar.spec" \
-e PACKAGE_NAME="foobar" \
-e PACKAGE_VERSION="1.2.3" \
-e PACKAGE_LICENSE="MY LICENSE" \
-e PACKAGE_SOURCE="foobar.tar.gz" \
"$container_builder_image"
```


## Change Log

TODO: Add this after initial PR is merged.
87 changes: 87 additions & 0 deletions rockylinux9-rpm-builder/build_rpm_from_env_vars
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env bash

set -e

help_text="
build_rpm_from_env_args [COMMAND]

When run, this script will run 'rpm-setuptree' followed by 'rpmbuild'
with all given environmental variables. See below for details and print
out of current variables detected.

COMMANDS:
run - Do the build (details above)
help - Print this help menu

ENV VARIABLES:
SPEC_FILE_NAMES - File names of '.spec' file in ~/rpmbuild/SPECS/ used (REQUIRED, comma delimited)
PACKAGE_NAME - Provided to 'rpmbuild' as variable: package_name
PACKAGE_VERSION - Provided to 'rpmbuild' as variable: package_version
PACKAGE_LICENSE - Provided to 'rpmbuild' as variable: package_license
PACKAGE_SOURCE - Provided to 'rpmbuild' as variable: package_source

DETECTED VARIABLE VALUES:
SPEC_FILE_NAMES - $SPEC_FILE_NAMES
PACKAGE_NAME - $PACKAGE_NAME
PACKAGE_VERSION - $PACKAGE_VERSION
PACKAGE_LICENSE - $PACKAGE_LICENSE
PACKAGE_SOURCE - $PACKAGE_SOURCE
"

function detect_env_var() {
var_name="$1"
var_value="${!var_name}"
required="$2"

if [[ "$required" = "true" ]] && [[ "$var_value" = "" ]]; then
echo "Required variable '$var_name' not detected! Exiting."
exit 1
elif [[ "$var_value" = "" ]]; then
echo "No value detected for variable '$var_name'"
else
echo "Value detected for variable '$var_name' = $var_value"
fi
}

function do_run() {
detect_env_var "SPEC_FILE_NAMES" true
detect_env_var "PACKAGE_NAME"
detect_env_var "PACKAGE_VERSION"
detect_env_var "PACKAGE_LICENSE"
detect_env_var "PACKAGE_SOURCE"

echo -e "\Running rpmdev-setuptree:"
sudo rpmdev-setuptree

# Split SPEC_FILE_NAMES by ',' for loop
for SPEC_FILE_NAME in ${SPEC_FILE_NAMES//,/ }; do
echo -e "\nBuilding rpm file for $SPEC_FILE_NAME:"
rpmbuild -ba \
--define "package_version $PACKAGE_VERSION" \
--define "package_name $PACKAGE_NAME" \
--define "package_license $PACKAGE_LICENSE" \
--define "package_source $PACKAGE_SOURCE" \
~/rpmbuild/SPECS/"$SPEC_FILE_NAME"

echo -e "\n\nBuild code: $?\n"
done
}

function main() {
case "$1" in
"run")
do_run
exit 0
;;
""|"help"|"--help"|"-h")
echo "$help_text"
exit 0
;;
*)
echo "Command not recognized: $1"
exit 1
;;
esac
}

main $@
92 changes: 92 additions & 0 deletions rockylinux9-rpm-builder/setup_rpm_users
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env bash

set -e

help_text="
setup_rpm_user

Takes two environmental variables (_USER_ID and _GROUP_ID) and creates
a new user with which is added so the sudo'er list through membership
in 'builder' group.

COMMANDS:
run - Do the build (details above)
help - Print this help menu

ENV VARIABLES:
_USER_ID - Name of new user to run script for (REQUIRED)
_GROUP_ID - Name of new group to run script for (REQUIRED)

DETECTED VARIABLE VALUES:
_USER_ID - $_USER_ID
_GROUP_ID - $_GROUP_ID
"

function detect_env_var() {
var_name="$1"
var_value="${!var_name}"
required="$2"

if [[ "$required" = "true" ]] && [[ "$var_value" = "" ]]; then
echo "Required variable '$var_name' not detected! Exiting."
exit 1
elif [[ "$var_value" = "" ]]; then
echo "No value detected for variable '$var_name'"
else
echo "Value detected for variable '$var_name' = $var_value"
fi
}

function do_run() {
detect_env_var "_USER_ID" true
detect_env_var "_GROUP_ID" true

echo "Adding builder user/group ($_USER_ID:$_GROUP_ID) ..."
# Detecting existing user and group
set +e
existing_group_name="$(getent group "$_GROUP_ID" | cut -d: -f1)"
existing_user_name="$(getent passwd "$_USER_ID" | cut -d: -f1)"
set -e
# Group creation
if [ "$existing_group_name" != "" ]; then
echo "Skipping creating builder group as group with desired ID $_GROUP_ID already exists: $existing_group_name"
else
echo "Creating builder group ..."
groupadd -g "$_GROUP_ID" builder
fi
final_group_name="$(getent group "$_GROUP_ID" | cut -d: -f1)"
# User creation
if [ "$existing_user_name" != "" ]; then
echo "Skipping creating builder user as user with desired ID $_USER_ID already exists: $existing_user_name"
echo "Attempting to add existing user to group $final_group_name ($_GROUP_ID) ..."
usermod -a -G "$final_group_name" "$existing_user_name"
else
echo "Creating builder user ..."
useradd -u "$_USER_ID" -g "$_GROUP_ID" builder
fi
# Add to sudoers
final_user_name="$(getent passwd "$_USER_ID" | cut -d: -f1)"
echo "$final_user_name ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

echo "Id for container user:"
id "$_USER_ID"
}

function main() {
case "$1" in
"run")
do_run
exit 0
;;
""|"help"|"--help"|"-h")
echo "$help_text"
exit 0
;;
*)
echo "Command not recognized: $1"
exit 1
;;
esac
}

main $@