RPM/DEB for systemd-based systems (#3034)

* RPM/DEB for systemd-based systems

Similar to https://github.com/status-im/nimbus-eth2/pull/2691, this PR
introduces packaging for nimbus beacon node.

Instead of relying on interactive prompts, a default configuration is
included that connects to mainnet and expects there to be an execution
client running with websockets enabled on the same host, on the standard
websocket port.

Should the user need to configure their nimbus after installation (for
example with a different web3 url), the "standard" way of doing so via
`systemctl` edit is recommended.
This commit is contained in:
Jacek Sieka 2021-12-07 14:23:57 +01:00 committed by GitHub
parent 89d6a1b403
commit e2a2157370
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 263 additions and 0 deletions

1
.gitignore vendored
View File

@ -26,6 +26,7 @@ build/
*.su
/scripts/testnet*.sh
/scripts/package_image/usr/bin
# State sim # TODO - move in another folder
0000-*.json

3
scripts/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.rpm
*.deb

149
scripts/make_packages.sh Executable file
View File

@ -0,0 +1,149 @@
#!/bin/bash
# Copyright (c) 2020-2021 Status Research & Development GmbH. Licensed under
# either of:
# - Apache License, version 2.0
# - MIT license
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
set -e
####################
# argument parsing #
####################
GETOPT_BINARY="getopt"
if uname | grep -qi darwin; then
# macOS
GETOPT_BINARY="/usr/local/opt/gnu-getopt/bin/getopt"
[[ -f "$GETOPT_BINARY" ]] || { echo "GNU getopt not installed. Please run 'brew install gnu-getopt'. Aborting."; exit 1; }
fi
! ${GETOPT_BINARY} --test > /dev/null
if [ ${PIPESTATUS[0]} != 4 ]; then
echo '`getopt --test` failed in this environment.'
exit 1
fi
OPTS="ht:"
LONGOPTS="help,tarball:"
# default values
TARBALL=""
PKG_ARCH=""
print_help() {
cat <<EOF
Usage: $(basename "$0") --tarball dist/nimbus-eth2_Linux_amd64_1.5.4_382be3fd.tar.gz
-h, --help this help message
-t, --tarball tarball produced by "make dist-..."
EOF
}
! PARSED=$(${GETOPT_BINARY} --options=${OPTS} --longoptions=${LONGOPTS} --name "$0" -- "$@")
if [ ${PIPESTATUS[0]} != 0 ]; then
# getopt has complained about wrong arguments to stdout
exit 1
fi
# read getopt's output this way to handle the quoting right
eval set -- "$PARSED"
while true; do
case "$1" in
-h|--help)
print_help
exit
;;
-t|--tarball)
TARBALL="$2"
shift 2
;;
--)
shift
break
;;
*)
echo "argument parsing error"
print_help
exit 1
esac
done
case "${TARBALL}" in
*_Linux_amd64_*)
PKG_ARCH_DEB="amd64"
PKG_ARCH_RPM="x86_64"
;;
*_Linux_arm32v7_*)
PKG_ARCH_DEB="armhf"
PKG_ARCH_RPM="armv7hl"
;;
*_Linux_arm64v8_*)
PKG_ARCH_DEB="arm64"
PKG_ARCH_RPM="aarch64"
;;
*)
echo "unsupported tarball type"
exit 1
;;
esac
SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
PKG_NAME="nimbus_beacon_node"
PKG_IMG_DIR="${SCRIPT_DIR}/package_image"
BINARIES="nimbus_beacon_node"
PKG_VERSION="$(echo "${TARBALL}" | sed 's/^.*_\([^_]\+\)_[^_]\+$/\1/')"
TARBALL_TOP_DIR="$(echo "${TARBALL}" | sed 's#^.*/\([^/]\+\)\.tar\.gz$#\1#')"
PKG_PATH_DEB="${SCRIPT_DIR}/../build/${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH_DEB}.deb"
PKG_PATH_RPM="${SCRIPT_DIR}/../build/${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH_RPM}.rpm"
if ! command -v fpm &> /dev/null;then
printf "Please install FPM! \nhttps://fpm.readthedocs.io/en/latest/installation.html\n"
exit 1
fi
BIN_DIR="${PKG_IMG_DIR}/usr/bin"
rm -rf "${BIN_DIR}"
mkdir -p "${BIN_DIR}"
for BINARY in ${BINARIES}; do
tar -xzf "${TARBALL}" --strip-components 2 -C "${BIN_DIR}" "${TARBALL_TOP_DIR}/build/${BINARY}"
done
# delete existing packages
rm -f "${PKG_PATH_DEB}" "${PKG_PATH_RPM}"
fpm -s dir -t deb -n "${PKG_NAME}" \
--deb-no-default-config-files \
-v "${PKG_VERSION}" \
-C "${PKG_IMG_DIR}" \
-p "${PKG_PATH_DEB}" \
--depends lsb-release \
--after-install "${PKG_IMG_DIR}/after_install" \
--before-remove "${PKG_IMG_DIR}/before_remove" \
--after-remove "${PKG_IMG_DIR}/after_remove" \
--after-upgrade "${PKG_IMG_DIR}/after_upgrade" \
--deb-after-purge "${PKG_IMG_DIR}/deb_after_purge" \
--license "Apache 2.0 + MIT" \
--maintainer "The Nimbus Team" \
--description "Nimbus Beacon Chain / Ethereum Consensus client" \
--url "https://nimbus.team/" \
2>/dev/null
fpm -s dir -t rpm -n "${PKG_NAME}" \
-v "${PKG_VERSION}" \
-C "${PKG_IMG_DIR}" \
-p "${PKG_PATH_RPM}" \
--depends redhat-lsb-core \
--after-install "${PKG_IMG_DIR}/after_install" \
--before-remove "${PKG_IMG_DIR}/before_remove" \
--after-remove "${PKG_IMG_DIR}/after_remove" \
--after-upgrade "${PKG_IMG_DIR}/after_upgrade" \
--license "Apache 2.0 + MIT" \
--maintainer "The Nimbus Team" \
--description "Nimbus Beacon Chain / Ethereum Consensus client" \
--url "https://nimbus.team/" \
2>/dev/null
ls -l "${PKG_PATH_DEB}" "${PKG_PATH_RPM}"

View File

@ -0,0 +1,23 @@
#!/bin/bash
set -e
DISTRO=$(lsb_release -si)
if ! id -u nimbus > /dev/null 2>&1; then
case $DISTRO in
Ubuntu|Debian)
adduser --system --no-create-home --group nimbus
;;
Fedora|CentOS*|RedHat*|Scientific|Amazon*|Oracle*)
adduser --system --no-create-home --user-group nimbus
;;
*) # blind shot... ToDo: add more DISTRO cases here
adduser --system --no-create-home --group nimbus
;;
esac
fi
mkdir -p /var/lib/nimbus
chown nimbus:nimbus /var/lib/nimbus
systemctl daemon-reload

View File

@ -0,0 +1,6 @@
#!/bin/sh
set -e
# We don't do anything here since a normal "uninstall" should generally not
# remove data - debian has "purge" to deal with this, others don't.

View File

@ -0,0 +1,6 @@
#!/bin/sh
set -e
systemctl is-active --quiet nimbus_beacon_node.service &&
echo "Nimbus has been upgraded, don't forget to restart with 'sudo systemctl restart nimbus_beacon_node.service'!"

View File

@ -0,0 +1,6 @@
#!/bin/sh
set -e
systemctl stop 'nimbus_beacon_node.service'
systemctl disable 'nimbus_beacon_node.service'

View File

@ -0,0 +1,9 @@
#!/bin/sh
set -e
rm -rf /var/lib/nimbus
if id -u nimbus > /dev/null 2>&1; then
userdel nimbus # userdel will also delete the nimbus group
fi

View File

@ -0,0 +1,60 @@
# To configure the service, use `systemctl edit nimbus_beacon_node.service`
# and override the environment variables in this file:
# [Service]
# Environment="WEB3_URL=wss://provider/"
#
# To completely override the start command (to add custom parameters such as
# graffitti), override the `ExecStart` value instead:
#
# [Service]
# ExecStart=/usr/bin/nimbus_beacon_node --network=${NETWORK} \
# --data-dir="${DATA_DIR_PREFIX}/shared_${NETWORK}_${NODE_ID}" \
# --graffiti=123
#
# See https://nimbus.guide/ for more information
[Unit]
Description=Nimbus Beacon Node (Ethereum consensus client)
Wants=network-online.target
After=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
# Network - use `prater` to connect to the prater testnet
Environment=NETWORK=mainnet
# You need to have have access to an execution client - by default, we assume
# a compatible execution client is running on the same machine on the default
# websocket port.
Environment=WEB3_URL=ws://127.0.0.1:8546
# Where to store chain data
Environment=DATA_DIR_PREFIX=/var/lib/nimbus
# Default ports - if you want to run multiple instances of nimbus, for example
# to run both prater and mainnet, separate ports must be used
Environment=TCP_PORT=9000
Environment=UDP_PORT=9000
Environment=REST_PORT=5052
Environment=METRICS_PORT=8008
# Interaction and monitoring
Environment=REST_ENABLED=Yes
Environment=METRICS_ENABLED=Yes
# Default group = nimbus
User=nimbus
WorkingDirectory=/var/lib/nimbus
TimeoutSec=1200
Restart=always
ExecStart=/usr/bin/nimbus_beacon_node \
--network=${NETWORK} \
--data-dir="${DATA_DIR_PREFIX}/shared_${NETWORK}_0" \
--tcp-port=${TCP_PORT} \
--udp-port=${UDP_PORT} \
--rest=${REST_ENABLED} --rest-port=${REST_PORT} \
--metrics=${METRICS_ENABLED} --metrics-port=${METRICS_PORT} \
--web3-url=${WEB3_URL}