From 429d2b4291f460a8bced8880ef2f5cdd92bd419d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Fri, 29 Nov 2019 00:56:34 +0100 Subject: [PATCH] create a Makefile for running a bootnode under systemd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jakub SokoĊ‚owski --- BOOTNODE.md | 26 +++++ README.md | 2 +- _assets/compose/bootnode/Makefile | 8 +- _assets/systemd/bootnode/Makefile | 113 ++++++++++++++++++++++ _assets/systemd/bootnode/README.md | 46 +++++++++ _assets/systemd/bootnode/service.template | 15 +++ 6 files changed, 203 insertions(+), 7 deletions(-) create mode 100644 BOOTNODE.md create mode 100644 _assets/systemd/bootnode/Makefile create mode 100644 _assets/systemd/bootnode/README.md create mode 100644 _assets/systemd/bootnode/service.template diff --git a/BOOTNODE.md b/BOOTNODE.md new file mode 100644 index 000000000..117a4214e --- /dev/null +++ b/BOOTNODE.md @@ -0,0 +1,26 @@ +# Description + +This document describes the two easiest ways to start a Status Bootnode: + +* [Docker Compose](https://docs.docker.com/compose/) - More self-contained and portable +* [Systemd Service](https://www.freedesktop.org/wiki/Software/systemd/) - More local and configurable + +## Docker Compose + +The simplest way is to just use: +``` +make run-bootnode-docker +``` +This will generate the necessary config, compose and then start the container. + +For more details read the [README](_assets/compose/bootnode/README.md). + +## Systemd Service + +The other way is to run the `bootnode` under `systemd`: +``` +make run-bootnode-systemd +``` +This will generate the necessary config, define and then start the service. + +For more details read the [README](_assets/systemd/bootnode/README.md). diff --git a/README.md b/README.md index 2c073a529..4093d8ea6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ - [How to Build](https://status.im/build_status/status_go.html) - [How to Contribute](CONTRIBUTING.md) - [How to Release](RELEASING.md) -- [How to run a Bootnode](_assets/compose/bootnode) +- [How to run a Bootnode](BOOTNODE.md) - [How to run a Mailserver](MAILSERVER.md) - [How to configure status-go](/config) diff --git a/_assets/compose/bootnode/Makefile b/_assets/compose/bootnode/Makefile index ad3e22977..05a70cae2 100644 --- a/_assets/compose/bootnode/Makefile +++ b/_assets/compose/bootnode/Makefile @@ -13,12 +13,9 @@ GID = $(shell id -g) # Settings export LOG_LEVEL ?= 3 export LISTEN_PORT ?= 30303 -export RPC_PORT ?= 8545 export API_MODULES ?= eth,net,web3,admin export CONTAINER_NAME ?= status-go-bootnode export CONTAINER_IMAGE ?= statusteam/bootnode:latest -export TOOLS_IMAGE ?= ethereum/client-go:alltools-latest -export FLEET_NAME ?= eth.beta # Necessary to make bootnode available publicly export PUBLIC_IP ?= $(shell curl -s https://ipecho.net/plain) @@ -55,7 +52,6 @@ info: @echo "$(YELLOW)Make sure that address and UDP port are available from the internet!$(RESET)" @echo "$(GREEN)Your enode address is:$(RESET)" - keys: @mkdir -p keys @@ -64,7 +60,7 @@ keys/nodekey: keys ##@ Generate a node key -u $(UID):$(GID) \ --entrypoint=bootnode \ -v $(PWD)/keys:/keys:rw \ - $(TOOLS_IMAGE) \ + $(CONTAINER_IMAGE) \ -genkey=/keys/nodekey @echo "$(GREEN)Created key for Bootnode: keys/nodekey" @@ -73,7 +69,7 @@ keys/nodeaddr: keys ##@ Save node address for given key -u $(UID):$(GID) \ --entrypoint=sh \ -v $(PWD)/keys:/keys:rw \ - $(TOOLS_IMAGE) \ + $(CONTAINER_IMAGE) \ -c 'bootnode -writeaddress -nodekey=/keys/nodekey > /keys/nodeaddr' show: diff --git a/_assets/systemd/bootnode/Makefile b/_assets/systemd/bootnode/Makefile new file mode 100644 index 000000000..5c96cff17 --- /dev/null +++ b/_assets/systemd/bootnode/Makefile @@ -0,0 +1,113 @@ +export GIT_ROOT = $(shell git rev-parse --show-toplevel) + +RED := $(shell tput -Txterm setaf 1) +GRN := $(shell tput -Txterm setaf 2) +YLW := $(shell tput -Txterm setaf 3) +RST := $(shell tput -Txterm sgr0) +BLD := $(shell tput bold) + +# Settings +export SERVICE_NAME ?= bootnode +export SERVICE_DIR ?= $(HOME)/.config/systemd/user/ +export SERVICE_PATH ?= $(SERVICE_DIR)/$(SERVICE_NAME).service +export LOG_LEVEL ?= 3 +export LISTEN_PORT ?= 30303 +export DATA_PATH ?= /var/tmp/status-go-boot +export KEY_PATH ?= $(DATA_PATH)/nodekey +export ADDR_PATH ?= $(DATA_PATH)/nodeaddr +# Necessary to make bootnode available publicly +export PUBLIC_IP ?= $(shell curl -s https://ipecho.net/plain) + +# Info +STATUS = $(shell systemctl --user is-active $(SERVICE_NAME)) +NODE_ADDR = $(shell cat $(ADDR_PATH)) +ENODE = enode://$(NODE_ADDR)@$(PUBLIC_IP):$(LISTEN_PORT) + +define INFO_MSG +* $(GRN)Your bootnode is listening on:$(RST) $(BLD)$(PUBLIC_IP):$(LISTEN_PORT)$(RST) +* $(YLW)Make sure that IP and TCP port are available from the internet!$(RST) +$(GRN)Your enode address is:$(RST) +$(ENODE) +endef +export INFO_MSG + +all: checks build save-address service enable restart info + +clean: stop disable rm-service forget + +checks: +# this setup wont work without an os with systemd +ifeq (, $(shell which systemctl)) + $(error $(RED)Your system does not have systemd$(RST)) +endif +# if the service is already up just show some info +ifeq (active, $(STATUS)) + $(info $(INFO_MSG)) + $(error $(YLW)Service already started$(RST)) +endif + +info: + @echo "$$INFO_MSG" + +enode: + @echo "$(ENODE)" + +genkey: $(DATA_PATH) + @$(GIT_ROOT)/build/bin/bootnode -genkey=$(KEY_PATH) + +address: save-address + echo "$(NODE_ADDR)" + +save-address: + @$(GIT_ROOT)/build/bin/bootnode -nodekey=$(KEY_PATH) -writeaddress > $(ADDR_PATH) + +status: + systemctl --user status --no-pager $(SERVICE_NAME) + +logs: + journalctl --user-unit statusd + +enable: + @echo "* $(BLD)Enabling '$(SERVICE_NAME)' service...$(RST)" + systemctl --user enable $(SERVICE_NAME) + +disable: + @echo "* $(BLD)Disabling '$(SERVICE_NAME)' service...$(RST)" + systemctl --user disable "${SERVICE_NAME}" + +start: + @echo "* $(BLD)Starting '$(SERVICE_NAME)' service...$(RST)" + systemctl --user start $(SERVICE_NAME) + +restart: + @echo "* $(BLD)Restarting '$(SERVICE_NAME)' service...$(RST)" + systemctl --user restart $(SERVICE_NAME) + +stop: + @echo "* $(BLD)Stopping '$(SERVICE_NAME)' service...$(RST)" + systemctl --user stop "${SERVICE_NAME}" + +forget: + @echo "* $(BLD)Stopping '$(SERVICE_NAME)' service...$(RST)" + systemctl --user daemon-reload + systemctl --user reset-failed + +$(GIT_ROOT)/build/bin/bootnode: + @echo "* $(BLD)Building bootnode binary...$(RST)" + @cd "$(GIT_ROOT)" && make bootnode + +build: $(GIT_ROOT)/build/bin/bootnode +.PHONY: build + +$(SERVICE_DIR): + @mkdir -p $(SERVICE_DIR) + +service: $(SERVICE_DIR) + @echo "* $(BLD)Generating '$(SERVICE_NAME)' service...$(RST)" + @envsubst < ./service.template > $(SERVICE_PATH) + +$(DATA_PATH): + @mkdir -p $(DATA_PATH) + +rm-service: + rm -f $(SERVICE_PATH) diff --git a/_assets/systemd/bootnode/README.md b/_assets/systemd/bootnode/README.md new file mode 100644 index 000000000..6fcae70a1 --- /dev/null +++ b/_assets/systemd/bootnode/README.md @@ -0,0 +1,46 @@ +# Status Bootnode + +This folder contains setup for running your own Status Bootnode. +It uses [Systemd](https://www.freedesktop.org/wiki/Software/systemd/) for managing the Status Bootnode service. + +The steps it takes are: + +* Builds `bootnode` +* Generates & saves a private key +* Generates `systemd` service +* Starts the service + +# Usage + +To simply configure and start the service run `make`. + +In order to manage the new `statusd` service you use other `Makefile` targets: + +* `make info` - Info about service +* `make enode` - Get enode address +* `make start` - Start the service +* `make stop` - Stop the service +* `make status` - Check service status +* `make enable` - Enable the service +* `make disable` - Disable the service +* `make logs` - Read the service logs +* `make clean` - Stop service and remove it + +All the above commands are just wrappers around the [`systemctl`](http://man7.org/linux/man-pages/man1/systemctl.1.html) and [`journalctl`](http://man7.org/linux/man-pages/man1/journalctl.1.html) commands. + +# Settings + +All settings are passed through environment variables: + +* `SERVICE_NAME` - Name of the `systemd` service to be created. (Default: `statusd`) +* `PUBLIC_IP` - Your IP visible from the internet and advertised by the Bootnode. +* `LISTEN_PORT` - Bootnode TCP & UDP port, by default it's `30303` but you might want to use `443`. +* `DATA_PATH` - Location of Bootnode storage and keys. (Default: `/var/tmp/status-go-boot`) +* `KEY_PATH` - Location of Bootnode private key file. (Default: `/var/tmp/status-go-boot/nodekey`) +* `LOG_LEVEL` - Set level of log messages to show. (Values:`0-9`, Default: `3`)` + +# Known Issues + +* `No journal files were opened due to insufficient permissions.` from `systemctl` + - To see logs of a user systemd service you need to be a member of `systemd-journal` group. + - Use: `bash usermod -a -G systemd-journal ${USER}` diff --git a/_assets/systemd/bootnode/service.template b/_assets/systemd/bootnode/service.template new file mode 100644 index 000000000..c463dab9f --- /dev/null +++ b/_assets/systemd/bootnode/service.template @@ -0,0 +1,15 @@ +[Unit] +Description=Status.im Bootnode Service + +[Service] +Type=fork +Restart=on-failure +WatchdogSec=60s +WorkingDirectory=${DATA_PATH} +ExecStart=${GIT_ROOT}/build/bin/bootnode \ + -verbosity=${LOG_LEVEL} \ + -nodekey=${KEY_PATH} \ + -addr=:${LISTEN_PORT} + +[Install] +WantedBy=default.target