Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

packaging: build rpm packages #4632

Merged
merged 19 commits into from
Oct 10, 2024
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
6 changes: 5 additions & 1 deletion .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ steps:
- exit_status: 255 # Forced agent shutdown
timeout_in_minutes: 10
- wait
- label: "Package :debian: :openwrt:"
- label: "Package :debian: :openwrt: :rpm:"
command: |
make dist-deb BFLAGS="--file_name_version=${SCION_VERSION}"
make dist-openwrt BFLAGS="--file_name_version=${SCION_VERSION}"
make dist-rpm BFLAGS="--file_name_version=${SCION_VERSION}"
artifact_paths:
- "installables/scion_*.tar.gz"
plugins:
Expand All @@ -42,6 +43,7 @@ steps:
tar -chaf scion_${SCION_VERSION}_deb_i386.tar.gz *_${SCION_VERSION}_i386.deb
tar -chaf scion_${SCION_VERSION}_deb_armel.tar.gz *_${SCION_VERSION}_armel.deb
tar -chaf scion_${SCION_VERSION}_openwrt_x86_64.tar.gz *_${SCION_VERSION}_x86_64.ipk
tar -chaf scion_${SCION_VERSION}_rpm_x86_64.tar.gz *_${SCION_VERSION}_x86_64.rpm
popd
ls installables
post-artifact: |
Expand All @@ -53,6 +55,8 @@ steps:
- <a href="artifact://installables/scion_${SCION_VERSION}_deb_armel.tar.gz">armel</a>
#### Packages :openwrt:
- <a href="artifact://installables/scion_${SCION_VERSION}_openwrt_x86_64.tar.gz">x86_64</a>
#### Packages :rpm:
- <a href="artifact://installables/scion_${SCION_VERSION}_rpm_x86_64.tar.gz">x86_64</a>
EOF
key: dist
retry: *automatic-retry
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ dist-openwrt-testing:
@ mkdir -p installables
@ cd installables ; ln -sfv ../bazel-out/*/bin/dist/*.ipk .

dist-rpm:
bazel build //dist:rpm_all $(BFLAGS)
@ # These artefacts have unique names but varied locations. Link them somewhere convenient.
@ mkdir -p installables
@ cd installables ; ln -sfv ../bazel-out/*/bin/dist/*.rpm .

# all: performs the code-generation steps and then builds; the generated code
# is git controlled, and therefore this is only necessary when changing the
# sources for the code generation.
Expand Down
9 changes: 9 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ oci_pull(
repository = "library/debian",
)

# Debian packaging
http_archive(
name = "rules_debian_packages",
sha256 = "0ae3b332f9d894e57693ce900769d2bd1b693e1f5ea1d9cdd82fa4479c93bcc8",
Expand All @@ -206,6 +207,14 @@ load("@tester_debian10_packages//:packages.bzl", tester_debian_packages_install_

tester_debian_packages_install_deps()

# RPM packaging
load("@rules_pkg//toolchains/rpm:rpmbuild_configure.bzl", "find_system_rpmbuild")

find_system_rpmbuild(
name = "rules_pkg_rpmbuild",
verbose = False,
)

# Buf CLI
http_archive(
name = "buf",
Expand Down
120 changes: 118 additions & 2 deletions dist/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
load(":package.bzl", "scion_pkg_deb")
load(":package.bzl", "scion_pkg_ipk")
load(":package.bzl", "scion_pkg_deb", "scion_pkg_ipk", "scion_pkg_rpm")
load(":platform.bzl", "multiplatform_filegroup")
load(":git_version.bzl", "git_version")

Expand All @@ -10,6 +9,10 @@ DEB_PLATFORMS = [
"@io_bazel_rules_go//go/toolchain:linux_arm",
]

RPM_PLATFORMS = [
"@io_bazel_rules_go//go/toolchain:linux_amd64",
]

# TODO([email protected]):
# For now only a single openwrt platform can be in this list. If we allow several, they get
# built in parallel, which breaks on non-reentrant openwrt makefiles. For a single platform
Expand Down Expand Up @@ -221,3 +224,116 @@ multiplatform_filegroup(
target_platforms = OPENWRT_PLATFORMS,
visibility = ["//dist:__subpackages__"],
)

scion_pkg_rpm(
name = "router_rpm",
depends = [
"/sbin/adduser",
],
description = "SCION inter-domain network architecture border router",
executables = {
"//router/cmd/router:router": "scion-router",
},
package = "scion-router",
postinst = "rpm/scion.postinst",
systemds = ["systemd/[email protected]"],
version_file = ":git_version",
)

scion_pkg_rpm(
name = "control_rpm",
configs = [],
depends = [
"/sbin/adduser",
"scion-dispatcher",
],
description = "SCION inter-domain network architecture control service",
executables = {
"//control/cmd/control:control": "scion-control",
},
package = "scion-control",
systemds = ["systemd/[email protected]"],
version_file = ":git_version",
)

scion_pkg_rpm(
name = "dispatcher_rpm",
configs = ["conffiles/dispatcher.toml"],
depends = [
"/sbin/adduser",
],
description = "SCION dispatcher",
executables = {
"//dispatcher/cmd/dispatcher:dispatcher": "scion-dispatcher",
},
package = "scion-dispatcher",
postinst = "rpm/scion.postinst",
systemds = ["systemd/scion-dispatcher.service"],
version_file = ":git_version",
)

scion_pkg_rpm(
name = "daemon_rpm",
configs = ["conffiles/daemon.toml"],
depends = [
"/sbin/adduser",
],
description = "SCION daemon",
executables = {
"//daemon/cmd/daemon:daemon": "scion-daemon",
},
package = "scion-daemon",
postinst = "rpm/scion.postinst",
systemds = ["systemd/scion-daemon.service"],
version_file = ":git_version",
)

scion_pkg_rpm(
name = "gateway_rpm",
configs = [
"conffiles/gateway.json",
"conffiles/gateway.toml",
],
depends = [
"/sbin/adduser",
"scion-dispatcher",
"scion-daemon",
],
description = "SCION-IP Gateway",
executables = {
"//gateway/cmd/gateway:gateway": "scion-ip-gateway",
},
package = "scion-ip-gateway",
systemds = ["systemd/scion-ip-gateway.service"],
version_file = ":git_version",
)

scion_pkg_rpm(
name = "tools_rpm",
depends = [
"/sbin/adduser",
"scion-dispatcher",
"scion-daemon",
],
description = "SCION tools",
executables = {
"//scion/cmd/scion:scion": "scion",
"//scion-pki/cmd/scion-pki:scion-pki": "scion-pki",
},
package = "scion-tools",
version_file = ":git_version",
)

multiplatform_filegroup(
name = "rpm",
srcs = [
"control_rpm",
"daemon_rpm",
"dispatcher_rpm",
"gateway_rpm",
"router_rpm",
"tools_rpm",
],
target_platforms = RPM_PLATFORMS,
visibility = ["//dist:__subpackages__"],
)
102 changes: 102 additions & 0 deletions dist/package.bzl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
load("@rules_pkg//pkg:pkg.bzl", "pkg_deb", "pkg_tar")
load("@rules_pkg//pkg:rpm.bzl", "pkg_rpm")
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
load("@rules_pkg//pkg:providers.bzl", "PackageVariablesInfo")
load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_files")

SCION_PKG_HOMEPAGE = "https://github.com/scionproto/scion"
SCION_PKG_MAINTAINER = "SCION Contributors"
Expand Down Expand Up @@ -30,6 +32,106 @@ name_elems = rule(
},
)

def scion_pkg_rpm(name, package, executables = {}, systemds = [], configs = [], **kwargs):
"""
The package content, the _data_ arg for the pkg_rpm rule, is assembled from:

- executables: Map Label (the executable) -> string, the basename of the executable in the package
Executables are installed to /usr/bin/
- systemds: List[string], the systemd unit files to be installed in /lib/systemd/system/
- configs: List[string], the configuration files to be installed in /etc/scion/

The values for the following pkg_rpm args are set to a default value:
- url
- license
- architecture, set based on the platform.

The caller needs to set:
- package: the name of the package (e.g. scion-router)
- description: one-liner
- version/version_file: One can use the label ":git_version"
and any of the optional control directives.

The version string gets edited to meet rpm requirements: dashes are replaced with ^.
"""

kwargs.setdefault("url", SCION_PKG_HOMEPAGE)
kwargs.setdefault("license", SCION_PKG_LICENSE)

if "architecture" not in kwargs:
kwargs["architecture"] = select({
"@platforms//cpu:x86_64": "x86_64",
"@platforms//cpu:x86_32": "i386",
"@platforms//cpu:aarch64": "arm64",
"@platforms//cpu:armv7": "armel",
"@platforms//cpu:s390x": "s390x",
# Note: some rules_go toolchains don't (currently) seem to map (cleanly) to @platforms//cpu.
# "@platforms//cpu:ppc": "ppc64",
# "@platforms//cpu:ppc64le": "ppc64le",
})

name_elems(
name = "package_file_naming_" + name,
file_name_version = "@@//:file_name_version",
architecture = kwargs["architecture"],
package = package,
)

# Note that our "executables" parameter is a dictionary label->file_name; exactly what pkg_files
# wants for its "renames" param.
pkg_files(name = "%s_configs" % name, prefix = "/etc/scion/", srcs = configs)
pkg_files(name = "%s_systemds" % name, prefix = "/lib/systemd/system/", srcs = systemds)
pkg_files(
name = "%s_execs" % name,
prefix = "/usr/bin/",
srcs = executables.keys(),
attributes = pkg_attributes(mode = "0755"),
renames = executables,
)

if kwargs.get("version_file"):
native.genrule(
name = "%s_version" % name,
srcs = [kwargs["version_file"]],
outs = ["%s_version_file" % name],
cmd = "sed 's/-/^/g' < $< > $@",
)
kwargs.pop("version_file")
elif kwargs.get("version"):
native.genrule(
name = "%s_version" % name,
srcs = [],
outs = ["%s_version_file" % name],
cmd = "echo \"%s\" | sed 's/-/^/g' > $@" % kwargs["version"],
)
kwargs.pop("version")

# Use the same attributes as scion_pkg_deb, in view of may-be simplifying BUILD.bazel later.
deps = kwargs.get("depends")
if deps:
kwargs.pop("depends")
else:
deps = []

post = kwargs.get("postinst")
if post:
kwargs.pop("postinst")

pkg_rpm(
name = name,
summary = kwargs["description"],
srcs = ["%s_configs" % name, "%s_systemds" % name, "%s_execs" % name],
target_compatible_with = ["@platforms//os:linux"],
package_file_name = "{package}_{file_name_version}_{architecture}.rpm",
package_variables = ":package_file_naming_" + name,
package_name = package,
release = "%autorelease",
version_file = ":%s_version" % name,
requires = deps,
post_scriptlet_file = post,
**kwargs
)

def scion_pkg_deb(name, executables = {}, systemds = [], configs = [], **kwargs):
"""
The package content, the _data_ arg for the pkg_deb rule, is assembled from:
Expand Down
13 changes: 13 additions & 0 deletions dist/rpm/scion.postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
set -e

# Create system user/group
groupadd --system -f scion
useradd --system --gid scion -M -s /sbin/nologin scion >& /dev/null || true

# Create configuration directory
mkdir /etc/scion/ >& /dev/null || true
mkdir /var/lib/scion/ >& /dev/null || true
chown scion:scion /etc/scion/ /var/lib/scion


16 changes: 16 additions & 0 deletions dist/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,19 @@ sh_test(
"integration",
],
)

sh_test(
name = "rpm_test",
srcs = ["rpm_test.sh"],
data = [
"Dockerfile.rpm",
"//dist:rpm",
],
env = {
"SCION_RPM_PACKAGES": "$(locations //dist:rpm)",
},
tags = [
"exclusive",
"integration",
],
)
8 changes: 8 additions & 0 deletions dist/test/Dockerfile.rpm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM fedora:40

RUN dnf --assumeyes install systemd

ENV container docker

# Only "boot" a minimal system with journald and nothing else
CMD ["/usr/lib/systemd/systemd", "--unit", "systemd-journald.service"]
Loading
Loading