Skip to content

Commit 97691c0

Browse files
jdbaldrypracucci
andauthored
Add RPM and deb packaging for cortex binary (cortexproject#2838)
* Use docker containers to build RPM and deb packages for cortex Signed-off-by: Jack Baldry <[email protected]> * Add DISABLE_CLEANUP variable to prevent the removal of testing containers Signed-off-by: Jack Baldry <[email protected]> * Updated RELEASE doc Signed-off-by: Marco Pracucci <[email protected]> Co-authored-by: Marco Pracucci <[email protected]>
1 parent d8edc95 commit 97691c0

File tree

15 files changed

+320
-2
lines changed

15 files changed

+320
-2
lines changed

Makefile

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ endif
190190

191191
clean:
192192
$(SUDO) docker rmi $(IMAGE_NAMES) >/dev/null 2>&1 || true
193-
rm -rf $(UPTODATE_FILES) $(EXES) .cache
193+
rm -rf -- $(UPTODATE_FILES) $(EXES) .cache $(PACKAGES) dist/*
194194
go clean ./...
195195

196196
clean-protos:
@@ -232,7 +232,7 @@ web-serve:
232232
cd website && hugo --config config.toml -v server
233233

234234
# Generate binaries for a Cortex release
235-
dist:
235+
dist dist/cortex-linux-amd64 dist/cortex-darwin-amd64 dist/query-tee-linux-amd64 dist/query-tee-darwin-amd64 dist/cortex-linux-amd64-sha-256 dist/cortex-darwin-amd64-sha-256 dist/query-tee-linux-amd64-sha-256 dist/query-tee-darwin-amd64-sha-256:
236236
rm -fr ./dist
237237
mkdir -p ./dist
238238
GOOS="linux" GOARCH="amd64" CGO_ENABLED=0 go build $(GO_FLAGS) -o ./dist/cortex-linux-amd64 ./cmd/cortex
@@ -243,3 +243,50 @@ dist:
243243
shasum -a 256 ./dist/cortex-linux-amd64 | cut -d ' ' -f 1 > ./dist/cortex-linux-amd64-sha-256
244244
shasum -a 256 ./dist/query-tee-darwin-amd64 | cut -d ' ' -f 1 > ./dist/query-tee-darwin-amd64-sha-256
245245
shasum -a 256 ./dist/query-tee-linux-amd64 | cut -d ' ' -f 1 > ./dist/query-tee-linux-amd64-sha-256
246+
247+
# Generate packages for a Cortex release.
248+
FPM_OPTS := fpm -s dir -v $(VERSION) -n cortex -f \
249+
--license "Apache 2.0" \
250+
--url "https://github.com/cortexproject/cortex"
251+
252+
FPM_ARGS := dist/cortex-linux-amd64=/usr/local/bin/cortex \
253+
docs/configuration/single-process-config.yaml=/etc/cortex/single-process-config.yaml\
254+
255+
PACKAGES := dist/cortex-$(VERSION).rpm dist/cortex-$(VERSION).deb
256+
PACKAGE_IN_CONTAINER := true
257+
PACKAGE_IMAGE ?= $(IMAGE_PREFIX)fpm
258+
ifeq ($(PACKAGE_IN_CONTAINER), true)
259+
260+
.PHONY: packages
261+
packages: dist/cortex-linux-amd64 packaging/fpm/$(UPTODATE)
262+
@mkdir -p $(shell pwd)/.pkg
263+
@mkdir -p $(shell pwd)/.cache
264+
@echo ">>>> Entering build container: $@"
265+
@$(SUDO) time docker run $(RM) $(TTY) \
266+
-v $(shell pwd):/src/github.com/cortexproject/cortex:delegated \
267+
-i $(PACKAGE_IMAGE) $@;
268+
269+
else
270+
271+
packages: $(PACKAGES)
272+
273+
dist/%.deb: dist/cortex-linux-amd64 $(wildcard packaging/deb/**)
274+
$(FPM_OPTS) -t deb \
275+
--after-install packaging/deb/control/postinst \
276+
--before-remove packaging/deb/control/prerm \
277+
--package $@ $(FPM_ARGS) \
278+
packaging/deb/default/cortex=/etc/default/cortex \
279+
packaging/deb/systemd/cortex.service=/etc/systemd/system/cortex.service
280+
281+
dist/%.rpm: dist/cortex-linux-amd64 $(wildcard packaging/rpm/**)
282+
$(FPM_OPTS) -t rpm \
283+
--after-install packaging/rpm/control/post \
284+
--before-remove packaging/rpm/control/preun \
285+
--package $@ $(FPM_ARGS) \
286+
packaging/rpm/sysconfig/cortex=/etc/sysconfig/cortex \
287+
packaging/rpm/systemd/cortex.service=/etc/systemd/system/cortex.service
288+
endif
289+
290+
.PHONY: test-packages
291+
test-packages: packages packaging/rpm/centos-systemd/$(UPTODATE) packaging/deb/debian-systemd/$(UPTODATE)
292+
./tools/packaging/test-packages $(IMAGE_PREFIX) $(VERSION)

RELEASE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ To publish a release candidate:
8989
3. Create a pre-release in GitHub
9090
- Write the release notes (including a copy-paste of the changelog)
9191
- Build binaries with `make dist` and attach them to the release
92+
- Build packages with `make packages`, test them with `make test-packages` and attach them to the release
9293

9394
### Publish a stable release
9495

@@ -101,6 +102,7 @@ To publish a stable release:
101102
5. Create a release in GitHub
102103
- Write the release notes (including a copy-paste of the changelog)
103104
- Build binaries with `make dist` and attach them to the release
105+
- Build packages with `make packages`, test them with `make test-packages` and attach them to the release
104106
6. Merge the release branch `release-x.y` to `master`
105107
- Merge to `master` in the local checkout
106108
- Fix any conflict and `git commit -s`

packaging/deb/control/postinst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
[ -f /etc/sysconfig/cortex ] && . /etc/default/cortex
6+
7+
# Initial installation: $1 == configure
8+
# Upgrade: $1 == 2, and configured to restart on upgrade
9+
case "$1" in
10+
configure)
11+
[ -z "$CORTEX_USER" ] && CORTEX_USER="cortex"
12+
[ -z "$CORTEX_GROUP" ] && CORTEX_GROUP="cortex"
13+
if ! getent group "$CORTEX_GROUP" > /dev/null 2>&1 ; then
14+
groupadd -r "$CORTEX_GROUP"
15+
fi
16+
if ! getent passwd "$CORTEX_USER" > /dev/null 2>&1 ; then
17+
useradd -m -r -g cortex -d /var/lib/cortex -s /sbin/nologin -c "cortex user" cortex
18+
fi
19+
20+
chmod 640 /etc/cortex/single-process-config.yaml
21+
chown root:$CORTEX_GROUP /etc/cortex/single-process-config.yaml
22+
23+
if [ -z ${2+x} ] && [ "$RESTART_ON_UPGRADE" == "true" ]; then
24+
if command -v systemctl 2>/dev/null; then
25+
systemctl daemon-reload
26+
fi
27+
fi
28+
esac

packaging/deb/control/prerm

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
[ -f /etc/default/cortex ] && . /etc/default/cortex
6+
7+
# Final uninstallation $1=0
8+
# If other copies of this RPM are installed, then $1>0
9+
if [ $1 -eq 0 ] ; then
10+
if command -v systemctl 2>/dev/null; then
11+
systemctl stop cortex.service > /dev/null 2>&1 || :
12+
fi
13+
fi
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM debian:10
2+
ENV container docker
3+
ENV LC_ALL C
4+
ENV DEBIAN_FRONTEND noninteractive
5+
RUN apt-get update \
6+
&& apt-get install -y systemd \
7+
&& apt-get clean \
8+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
9+
RUN rm -f /lib/systemd/system/multi-user.target.wants/* \
10+
/etc/systemd/system/*.wants/* \
11+
/lib/systemd/system/local-fs.target.wants/* \
12+
/lib/systemd/system/sockets.target.wants/*udev* \
13+
/lib/systemd/system/sockets.target.wants/*initctl* \
14+
/lib/systemd/system/sysinit.target.wants/systemd-tmpfiles-setup* \
15+
/lib/systemd/system/systemd-update-utmp*
16+
17+
VOLUME [ "/sys/fs/cgroup" ]
18+
CMD ["/lib/systemd/systemd"]

packaging/deb/default/cortex

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Log level. Valid levels: [debug, info, warn, error]. Default: "info"
2+
LOG_LEVEL="info"
3+
4+
# Path to Cortex YAML configuration file.
5+
CONFIG_FILE="/etc/cortex/single-process-config.yaml"
6+
7+
# Custom user defined arguments.
8+
CUSTOM_ARGS=""
9+
10+
# Restart on system upgrade. Default: "true".
11+
RESTART_ON_UPGRADE="true"

packaging/deb/systemd/cortex.service

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[Unit]
2+
Description=Horizontally scalable, highly available, multi-tenant, long term Prometheus.
3+
Documentation=https://cortexmetrics.io/docs
4+
Wants=network-online.target
5+
After=network-online.target
6+
7+
[Service]
8+
Restart=always
9+
User=cortex
10+
EnvironmentFile=/etc/default/cortex
11+
ExecStart=/usr/local/bin/cortex --config.file $CONFIG_FILE --log.level $LOG_LEVEL $CUSTOM_ARGS
12+
ExecReload=/bin/kill -HUP $MAINPID
13+
TimeoutStopSec=20s
14+
SendSIGKILL=no
15+
WorkingDirectory=/var/lib/cortex
16+
17+
[Install]
18+
WantedBy=multi-user.target

packaging/fpm/Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM alpine:3.8
2+
3+
RUN apk add --no-cache \
4+
ruby \
5+
ruby-dev \
6+
ruby-etc \
7+
gcc \
8+
git \
9+
libc-dev \
10+
libffi-dev \
11+
make \
12+
rpm \
13+
tar \
14+
&& gem install --no-ri --no-rdoc fpm
15+
16+
COPY package.sh /
17+
ENTRYPOINT ["/package.sh"]
18+
19+
ARG revision
20+
LABEL org.opencontainers.image.title="fpm" \
21+
# TODO: should this label point to the fpm source code?
22+
org.opencontainers.image.source="https://github.com/cortexproject/cortex/tree/master/packaging/fpm" \
23+
org.opencontainers.image.revision="${revision}"

packaging/fpm/package.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/sh
2+
3+
set -eu
4+
5+
SRC_PATH=/src/github.com/cortexproject/cortex
6+
7+
# If we run make directly, any files created on the bind mount
8+
# will have awkward ownership. So we switch to a user with the
9+
# same user and group IDs as source directory. We have to set a
10+
# few things up so that sudo works without complaining later on.
11+
uid=$(stat -c "%u" $SRC_PATH)
12+
gid=$(stat -c "%g" $SRC_PATH)
13+
echo "cortex:x:$uid:$gid::$SRC_PATH:/bin/sh" >>/etc/passwd
14+
echo "cortex:*:::::::" >>/etc/shadow
15+
echo "cortex ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers
16+
17+
su cortex -c "PATH=$PATH make -C $SRC_PATH PACKAGE_IN_CONTAINER=false $*"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM centos:8
2+
ENV container docker
3+
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
4+
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
5+
rm -f /lib/systemd/system/multi-user.target.wants/*; \
6+
rm -f /etc/systemd/system/*.wants/*; \
7+
rm -f /lib/systemd/system/local-fs.target.wants/*; \
8+
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
9+
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
10+
rm -f /lib/systemd/system/basic.target.wants/*; \
11+
rm -f /lib/systemd/system/anaconda.target.wants/*;
12+
13+
VOLUME [ "/sys/fs/cgroup"]
14+
CMD ["/usr/sbin/init"]

packaging/rpm/control/post

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
[ -f /etc/sysconfig/cortex ] && . /etc/sysconfig/cortex
6+
7+
# Initial installation: $1 == 1
8+
# Upgrade: $1 == 2, and configured to restart on upgrade
9+
if [ $1 -eq 1 ] ; then
10+
[ -z "$CORTEX_USER" ] && CORTEX_USER="cortex"
11+
[ -z "$CORTEX_GROUP" ] && CORTEX_GROUP="cortex"
12+
if ! getent group "$CORTEX_GROUP" > /dev/null 2>&1 ; then
13+
groupadd -r "$CORTEX_GROUP"
14+
fi
15+
if ! getent passwd "$CORTEX_USER" > /dev/null 2>&1 ; then
16+
useradd -m -r -g cortex -d /var/lib/cortex -s /sbin/nologin -c "cortex user" cortex
17+
fi
18+
19+
chmod 640 /etc/cortex/single-process-config.yaml
20+
chown root:$CORTEX_GROUP /etc/cortex/single-process-config.yaml
21+
22+
elif [ $1 -ge 2 ] ; then
23+
if [ "$RESTART_ON_UPGRADE" == "true" ]; then
24+
if command -v systemctl 2>/dev/null; then
25+
systemctl daemon-reload
26+
fi
27+
fi
28+
fi

packaging/rpm/control/preun

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
[ -f /etc/sysconfig/cortex ] && . /etc/sysconfig/cortex
6+
7+
# Final uninstallation $1=0
8+
# If other copies of this RPM are installed, then $1>0
9+
if [ $1 -eq 0 ] ; then
10+
if command -v systemctl 2>/dev/null; then
11+
systemctl stop cortex.service > /dev/null 2>&1 || :
12+
fi
13+
fi

packaging/rpm/sysconfig/cortex

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Log level. Valid levels: [debug, info, warn, error]. Default: "info"
2+
LOG_LEVEL="info"
3+
4+
# Path to Cortex YAML configuration file.
5+
CONFIG_FILE="/etc/cortex/single-process-config.yaml"
6+
7+
# Custom user defined arguments.
8+
CUSTOM_ARGS=""
9+
10+
# Restart on system upgrade. Default: "true".
11+
RESTART_ON_UPGRADE="true"

packaging/rpm/systemd/cortex.service

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[Unit]
2+
Description=Horizontally scalable, highly available, multi-tenant, long term Prometheus.
3+
Documentation=https://cortexmetrics.io/docs
4+
Wants=network-online.target
5+
After=network-online.target
6+
7+
[Service]
8+
Restart=always
9+
User=cortex
10+
EnvironmentFile=/etc/sysconfig/cortex
11+
ExecStart=/usr/local/bin/cortex --config.file $CONFIG_FILE --log.level $LOG_LEVEL $CUSTOM_ARGS
12+
ExecReload=/bin/kill -HUP $MAINPID
13+
TimeoutStopSec=20s
14+
SendSIGKILL=no
15+
WorkingDirectory=/var/lib/cortex
16+
17+
[Install]
18+
WantedBy=multi-user.target

tools/packaging/test-packages

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env bash
2+
3+
set -euf -o pipefail
4+
5+
readonly IMAGE_PREFIX=$1
6+
readonly VERSION=$2
7+
readonly DISABLE_CLEANUP=${DISABLE_CLEANUP:-0}
8+
9+
declare -a CONTAINERS=()
10+
11+
function error() {
12+
echo "$@"; exit 1
13+
}
14+
15+
function cleanup() {
16+
if [[ "${DISABLE_CLEANUP}" -ne 1 ]]; then
17+
docker rm --force "${CONTAINERS[@]}" &>/dev/null
18+
fi
19+
}
20+
21+
function ready() {
22+
local -ri max_attempts=$1
23+
local -ri sleep_interval=$2
24+
local -ri port=$3
25+
local -i attempt=1
26+
27+
sleep "${sleep_interval}"
28+
until curl -s localhost:"${port}"/ready | grep -q ready; do
29+
if [[ ${attempt} -eq ${max_attempts} ]]; then
30+
echo "Cortex not ready in ${max_attempts} attempts"
31+
return 1
32+
else
33+
(( attempt++ ))
34+
fi
35+
sleep "${sleep_interval}"
36+
done
37+
}
38+
39+
trap cleanup EXIT
40+
41+
function test_with_systemd() {
42+
local -r image=$1
43+
local -r install_command=$2
44+
local container
45+
46+
container=$(docker run --tmpfs /run --tmpfs /run/lock -v /sys/fs/cgroup:/sys/fs/cgroup:ro -itd -v "$(pwd)"/dist:/opt/cortex -p 9009 "${image}")
47+
CONTAINERS+=("${container}")
48+
49+
port=$(docker inspect --format='{{(index (index .NetworkSettings.Ports "9009/tcp") 0).HostPort}}' "${container}")
50+
51+
docker exec -it "${container}" /bin/bash -c "${install_command}; systemctl start cortex.service; systemctl enable cortex.service"
52+
53+
ready 10 1 "${port}" || error "Testing image: ${image} with command: '${install_command}' failed"
54+
}
55+
56+
test_with_systemd "${IMAGE_PREFIX}"debian-systemd "dpkg -i /opt/cortex/cortex-${VERSION}.deb"
57+
test_with_systemd "${IMAGE_PREFIX}"centos-systemd "rpm -i /opt/cortex/cortex-${VERSION}.rpm"

0 commit comments

Comments
 (0)