Add RPM packaging
Relates to https://git.canopsis.net/canopsis/canopsis-pro/-/issues/5252
Implementation of the RPM packaging
Config defaults
The connector configuration has been modified to add working defaults in the RPM environment:
- A default AMQP target:
amqp://cpsrabbit:canopsis@localhost/canopsis
- A default, required, bearer_token
In docker mode, environment variables already override those defaults.
Makefile for building RPMs
The MR adds the dist directory with a Makefile to build RPMs. The main recipes are:
-
prep-rpm
: calls top level Makefiledist
to create the release archive and builds directory tree required forrpmbuild
-
rpm
: starts the docker mock-builder image, building the RPM -
clean
: cleans up the build directory
Additionally, the following rules have been added to the top Makefile:
-
dist
: standard recipe for creating release archive -
clean
: standard recipe for cleaning building artifacts -
rpm
: calls dist Makefile with this recipe -
install
: standard recipe for installing files -
check
: standard recipe for tests (here a noop) -
all
: standard default recipe, runsbuild
Renaming binary
To avoid confusion as to which project the connector belongs to, the binary has been renamed to canopsis-connector-prometheus
.
Version handling
git describe
is now used to generate version info. It has the advantage of being able to generate both release and development version:
Example:
$ git tag -s v3 -m "v3"
$ git describe --abbrev=4 HEAD
v3
$ git ci -m empty --allow-empty
$ git describe --abbrev=4 HEAD
v3-1-g9eca
git describe
will generate a predictable increasing version number for each new development commit.
The version is further processed to convert v3-1-g9eca
to v3.1-g9eca
.
For RPM building, the version is then refined to replace -
by _
and prefixed development tags with ~
(rc
or preview
for instance).
Finally, the building process is able to retrieve version information from the .version
file in case of using a release tarball instead of a development repository for building.
Mock builder
The docker image mock-builder
is used to build RPM. It requires a specific directory tree, and from a .spec
file and a source release tarball, it will produce binary and source RPM.
Mock builder requires privileged execution, network access and uses a cached volume for build chroot. The builder is called once for every target OS.
Two variables are passed to the .spec
file: Version_safe
and Version
. One for the tarball filename and the other for the actual RPM version.
Spec file
Most of the rules from the spec file are quite standard (thanks for the standard modifications to the build process). However, the following tweaks are worth mentioning:
- Usage of
Version_safe
andVersion
in the header - Disabling of debugging packages, doesn't work for GO
- The GO version installed for building is taken from the
go.mod
file - In order to make the various post processing binary steps (stripping, binary checks), the GO binary have to be built linking to the glibc and with PIE mode (this is a security feature required for RPM binaries)
The last point justify changes to the top level Makefile to LDFLAGS
and GOFLAGS
. Note that the trimpath
option has been added as well to ensure reproducibility of the binary.
Systemd service
The systemd service canopsis-connector-prometheus
optionally loads environment configuration from /etc/sysconfig/canopsis-connector-prometheus
, starts the binary /usr/bin/canopsis-connector-prometheus
with the additional $ARGS passed on the command line.
The configuration file is loaded from /etc/canopsis-connectors/prometheus/config.yml
and the service runs as the canopsis
user (from canopsis-common
RPM package).
Finally, note that, in order to allow multiple connector to run on the same host, a default unique port has been internally allocated to the connector: 18401
.
CI
CI stages/jobs are now:
- source
- source-rpm: builds the source required for building RPM (release tarball and directory tree)
- packaging
- build-docker: builds docker image
- rpm: builds source and binary RPM
- release only on tag
- release-docker: pushes to registry
- release-rpm: pushes to repository
Note that the release-rpm
job uses the publish-rpm image. RPM_REPO_USER
and RPM_REPO_PASSWORD
have been added to the CI configuration as masked variables.
The docker login/logout for the release-docker
job has been removed in favor of the DOCKER_AUTH_CONFIG
variable defined in the runner configuration.
In the source-rpm
a chown
workaround is applied because the mock builder fails to work due to a conflict of user uid/gid.
Dockerfile
Since the GO binary is now PIE and links to the glibc, the docker image cannot continue to build in a Debian based image and run in an Apline, missing glibc, image.
Therefor, we switch from the alpine image to the glibc compatible busybox image. As a nice side effect, the busybox image comes with a lot of debugging tools and is actually smaller than the Apline image. (17Mb compared to 19MB).
An Apline image is still used to retrieve certificate from (since the busybox image does not contain a package manager).