Skip to content

Add RPM packaging

Baptiste BEAUPLAT requested to merge build/rpm into master

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 Makefile dist to create the release archive and builds directory tree required for rpmbuild
  • 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, runs build

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 and Version 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).

Edited by Baptiste BEAUPLAT

Merge request reports