diff --git a/.github/workflows/pkg-rpm.yml b/.github/workflows/pkg-rpm.yml index ae7f99c..8bdae4f 100644 --- a/.github/workflows/pkg-rpm.yml +++ b/.github/workflows/pkg-rpm.yml @@ -130,11 +130,30 @@ jobs: # Build and strip Routinator as cargo generate-rpm doesn't do this for us cargo build --release --locked strip -s target/release/routinator + + # Fix the version string to be used for the RPM package sed -i -e "s/$ROUTINATOR_VER/$RPM_ROUTINATOR_VER/" Cargo.toml + + # Select the correct systemd service unit file for the target operating system + case ${MATRIX_IMAGE} in + centos:7) + SYSTEMD_SERVICE_UNIT_FILE="routinator-minimal.routinator.service" + ;; + *) + SYSTEMD_SERVICE_UNIT_FILE="routinator.routinator.service" + ;; + esac + + # Copy the chosen systemd service unit file to where Cargo.toml expects it to be + mkdir -p target/rpm + cp pkg/common/${SYSTEMD_SERVICE_UNIT_FILE} target/rpm/routinator.service + cargo generate-rpm + env: + MATRIX_IMAGE: ${{ matrix.image }} # See what rpmlint thinks of our package. - - name: Verify the DEB package + - name: Verify the RPM package run: | # cargo generate-rpm creates RPMs that rpmlint considers to have # errors so don't use the rpmlint exit code otherwise we will always @@ -180,8 +199,11 @@ jobs: # Get the operating system and release name (e.g. centos and 7) from # the image name (e.g. centos:7) by extracting only the parts before # and after but not including the colon: - echo "OS_NAME=${MATRIX_IMAGE%:*}" >> $GITHUB_ENV - echo "OS_REL=${MATRIX_IMAGE#*:}" >> $GITHUB_ENV + OS_NAME=${MATRIX_IMAGE%:*} + OS_REL=${MATRIX_IMAGE#*:} + + echo "OS_NAME=${OS_NAME}" >> $GITHUB_ENV + echo "OS_REL=${OS_REL}" >> $GITHUB_ENV echo "LXC_IMAGE=images:${OS_NAME}/${OS_REL}/cloud" >> $GITHUB_ENV env: MATRIX_IMAGE: ${{ matrix.image }} @@ -203,10 +225,15 @@ jobs: run: | sg lxd -c "lxc info" + # Use of IPv6 sometimes prevents yum update being able to resolve mirrorlist.centos.org + - name: Disable LXD assignment of IPv6 addresses + run: | + sg lxd -c "lxc network set lxdbr0 ipv6.address none" + - name: Launch LXC container run: | # security.nesting=true is needed to avoid error "Failed to set up mount - # namespacing: Permission denied" in a Debian 10 container. + # namespacing: Permission denied". sg lxd -c "lxc launch ${LXC_IMAGE} -c security.nesting=true testcon" # Run yum update and install man and sudo support (missing in some LXC/LXD @@ -248,7 +275,7 @@ jobs: sg lxd -c "lxc exec testcon -- systemctl status routinator || true" echo -e "\nINIT ROUTINATOR:" - sg lxd -c "lxc exec testcon -- sudo routinator-init --accept-arin-rpa" + sg lxd -c "lxc exec testcon -- routinator-init --accept-arin-rpa" echo -e "\nROUTINATOR DATA DIR AFTER INIT:" sg lxd -c "lxc exec testcon -- ls -la /var/lib/routinator" diff --git a/.github/workflows/pkg.yml b/.github/workflows/pkg.yml index 6fb4e05..a3fbaa5 100644 --- a/.github/workflows/pkg.yml +++ b/.github/workflows/pkg.yml @@ -1,4 +1,4 @@ -# GitHub Actions workflow for building and testing Routinator O/S packages. +# GitHub Actions workflow for building and testing Routinator O/S DEB packages. # Uses GitHub Actions caching to avoid rebuilding Rust cargo-deb and # Routinator dependencies on every run. # @@ -162,9 +162,12 @@ jobs: # Generate the changelog file that Debian packages are required to have. # See: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html#changelog - echo "routinator (${DEB_ROUTINATOR_VER}) unstable; urgency=medium" >debian/changelog - echo " * See: https://github.com/NLnetLabs/routinator/releases/tag/v${ROUTINATOR_VER}" >>debian/changelog - echo " -- maintainer ${MAINTAINER} ${RFC5322_TS}" >>debian/changelog + if [ ! -d target/debian ]; then + mkdir target/debian + fi + echo "routinator (${DEB_ROUTINATOR_VER}) unstable; urgency=medium" >target/debian/changelog + echo " * See: https://github.com/NLnetLabs/routinator/releases/tag/v${ROUTINATOR_VER}" >>target/debian/changelog + echo " -- maintainer ${MAINTAINER} ${RFC5322_TS}" >>target/debian/changelog DEB_VER="${DEB_ROUTINATOR_VER}-1${OS_REL}" if [[ "${VARIANT_NAME}" == "" ]]; then diff --git a/Cargo.toml b/Cargo.toml index 3f9a298..735521c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,7 +72,8 @@ statements about the association of Internet routing resources. \ In particular, it allows the holder of an IP address prefix to publish which \ AS number will be the origin of BGP route announcements for it. \ Routinator is a RPKI relying party software written in Rust. """ -depends = "$auto, rsync, adduser" +# ensure that the useradd and rsync tools are present by installing their respective packages +depends = "$auto, passwd, rsync" section = "net" priority = "optional" assets = [ @@ -81,13 +82,38 @@ assets = [ ["doc/misc.md", "usr/share/doc/routinator/misc.md", "644"], ["doc/routinator.1", "usr/share/man/man1/routinator.1", "644"], ["etc/routinator.conf.system-service", "etc/routinator/routinator.conf", "644"], - ["debian/service.preset", "/lib/systemd/system-preset/50-routinator.preset", "644"], - ["debian/routinator-init", "usr/bin/", "755"] + ["pkg/common/service.preset", "/lib/systemd/system-preset/50-routinator.preset", "644"], + ["pkg/common/routinator-init", "usr/bin/", "755"] ] -maintainer-scripts = "debian" -changelog = "debian/changelog" # this will be generated by the pkg workflow +maintainer-scripts = "pkg/debian" +changelog = "target/debian/changelog" # this will be generated by the pkg workflow copyright = "Copyright (c) 2020, NLnet Labs. All rights reserved." conf-files = ["/etc/routinator/routinator.conf"] -systemd-units = { unit-name = "routinator", enable = false } +systemd-units = { unit-name = "routinator", unit-scripts = "pkg/common", enable = false } [package.metadata.deb.variants.minimal] + +[package.metadata.generate-rpm] +# "BSD" alone is the 3-clause license. Inheriting "license" from above causes rpmlint to +# complain with "invalid-license". +# See: https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing +license = "BSD" +assets = [ + { source = "target/release/routinator", dest = "/usr/bin/routinator", mode = "755" }, + { source = "target/rpm/routinator.service", dest = "/lib/systemd/system/routinator.service", mode = "644" }, + { source = "doc/routinator.1", dest = "/usr/share/man/man1/routinator.1", mode = "644", doc = true }, + { source = "etc/routinator.conf.system-service", dest = "/etc/routinator/routinator.conf", mode = "644", config = true }, + { source = "pkg/common/routinator-init", dest = "/usr/bin/routinator-init", mode = "755" }, + { source = "pkg/common/service.preset", dest = "/lib/systemd/system-preset/50-routinator.preset", mode = "644" }, + { source = "pkg/rpm/postinst", dest = "/usr/share/routinator/rpm/postinst", mode = "755" }, + { source = "pkg/rpm/preuninst", dest = "/usr/share/routinator/rpm/preuninst", mode = "755" }, + { source = "pkg/rpm/postuninst", dest = "/usr/share/routinator/rpm/postuninst", mode = "755" }, +] +post_install_script = "/usr/share/routinator/rpm/postinst $*" +pre_uninstall_script = "/usr/share/routinator/rpm/preuninst $*" +post_uninstall_script = "/usr/share/routinator/rpm/postuninst $*" + +# ensure that the useradd and rsync tools are present by installing their respective packages +[package.metadata.generate-rpm.requires] +shadow-utils = "*" +rsync = "*" diff --git a/debian/routinator-init b/debian/routinator-init deleted file mode 100755 index c9f9b10..0000000 --- a/debian/routinator-init +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -sudo -u routinator routinator --config /etc/routinator/routinator.conf init "$@" diff --git a/pkg/common/routinator-init b/pkg/common/routinator-init new file mode 100755 index 0000000..d1ae17a --- /dev/null +++ b/pkg/common/routinator-init @@ -0,0 +1,21 @@ +#!/bin/bash +CMD="routinator --config /etc/routinator/routinator.conf init $@" + +if [[ $EUID -eq $(id -u routinator) ]]; then + # We are the routinator user, go! + echo "Running command: $CMD" + $CMD +elif [[ $EUID -eq 0 ]]; then + # We are root, become routinator then go! + echo "Running command as user routinator: $CMD" + su -s /bin/sh -c "$CMD" routinator +else + # We are some other user, is sudo installed? + if command -v sudo &> /dev/null; then + echo "Running command as user routinator via sudo: $CMD" + sudo -u routinator $CMD + else + echo >&2 "Error: Unable to become user 'routinator' to run command: $CMD" + exit 1 + fi +fi diff --git a/debian/routinator-minimal.routinator.service b/pkg/common/routinator-minimal.routinator.service similarity index 100% rename from debian/routinator-minimal.routinator.service rename to pkg/common/routinator-minimal.routinator.service diff --git a/debian/routinator.routinator.service b/pkg/common/routinator.routinator.service similarity index 100% rename from debian/routinator.routinator.service rename to pkg/common/routinator.routinator.service diff --git a/debian/service.preset b/pkg/common/service.preset similarity index 100% rename from debian/service.preset rename to pkg/common/service.preset diff --git a/debian/postinst b/pkg/debian/postinst similarity index 100% rename from debian/postinst rename to pkg/debian/postinst diff --git a/debian/postrm b/pkg/debian/postrm similarity index 100% rename from debian/postrm rename to pkg/debian/postrm diff --git a/pkg/rpm/postinst b/pkg/rpm/postinst new file mode 100755 index 0000000..39d49b5 --- /dev/null +++ b/pkg/rpm/postinst @@ -0,0 +1,30 @@ +#!/bin/bash -e +# Script based on the RPM %systemd_post scriptlet. See: +# - https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_systemd +# - https://cgit.freedesktop.org/systemd/systemd/tree/src/core/macros.systemd.in + +if [ $EUID -ne 0 ]; then + echo >&2 "ERROR: Routinator postinst script must be run as root" + exit 1 +fi + +if [ $1 -eq 1 ] ; then + # Initial installation + R_USER=routinator + R_GROUP=${R_USER} + R_HOME_DIR=/var/lib/routinator + R_HOME_DIR_PERMS=700 + + # According to the CentOS 7 useradd man page: + # --user-group causes a group by the same name as the user to be created + # --create-home should force creation of a home dir even for a system account. + useradd --system --home-dir ${R_HOME_DIR} --system --create-home --user-group ${R_USER} + + # Ensure that the home directory has the correct ownership + chown -R ${R_USER}:${R_GROUP} ${R_HOME_DIR} + + # Ensure that the home directory has the correct permissions + chmod ${R_HOME_DIR_PERMS} ${R_HOME_DIR} + + systemctl preset routinator.service 2>&1 || : +fi \ No newline at end of file diff --git a/pkg/rpm/postuninst b/pkg/rpm/postuninst new file mode 100755 index 0000000..8cda6ef --- /dev/null +++ b/pkg/rpm/postuninst @@ -0,0 +1,9 @@ +#!/bin/bash -e +# Script based on the RPM %systemd_postun scriptlet. See: +# - https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_systemd +# - https://cgit.freedesktop.org/systemd/systemd/tree/src/core/macros.systemd.in + +systemctl daemon-reload >/dev/null 2>&1 || : +if [ $1 -ge 1 ] ; then + systemctl try-restart routinator.service >/dev/null 2>&1 || : +fi \ No newline at end of file diff --git a/pkg/rpm/preuninst b/pkg/rpm/preuninst new file mode 100755 index 0000000..2d3be54 --- /dev/null +++ b/pkg/rpm/preuninst @@ -0,0 +1,10 @@ +#!/bin/bash -e +# Script based on the RPM %systemd_preun scriptlet. See: +# - https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_systemd +# - https://cgit.freedesktop.org/systemd/systemd/tree/src/core/macros.systemd.in + +if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + systemctl --no-reload disable routinator.service > /dev/null 2>&1 || : + systemctl stop routinator.service > /dev/null 2>&1 || : +fi \ No newline at end of file