diff --git a/scripts/local-builder.sh b/scripts/local-builder.sh new file mode 100755 index 0000000..225648a --- /dev/null +++ b/scripts/local-builder.sh @@ -0,0 +1,195 @@ +#!/bin/bash + +set -e + +UNIT_FILE=false +SKIP_BUILD=false +EXECUTABLE_PATH="/usr/bin/" +SPECIFICATION_PATH="/etc/ghost/" +SPECIFICATION_NAME="casper" +TARGET="debug" + +CURRENT_PATH=$(pwd) +CURRENT_SCRIPT=$(realpath "$0") +SCRIPT_FOLDER=$(dirname "$CURRENT_SCRIPT") +PROJECT_FOLDER=("$SCRIPT_FOLDER/..") + +prompt() { + while true; do + printf "$1 [y/N]: " + read yn + case $yn in + [Yy]* ) return 0;; + * ) return 1;; + esac + done +} + +clear +echo " ____ _ _ _ _ _" +echo " / ___| |__ ___ ___| |_ | \ | | ___ __| | ___" +echo "| | _| '_ \ / _ \/ __| __| | \| |/ _ \ / _' |/ _ \\" +echo "| |_| | | | | (_) \__ \ |_ | |\ | (_) | (_| | __/" +echo " \____|_| |_|\___/|___/\__| |_| \_|\___/ \__,_|\___|" +echo -e "\n" + +while [ $# -gt 0 ]; do + case "$1" in + --unit-file|-u) + UNIT_FILE=true + ;; + --make-global|-m) + MAKE_GLOBAL=true + ;; + --arguments|-a) + ARGUMENTS=true + ;; + --release|-r) + RELEASE="--release" + TARGET="release" + ;; + --profile*|-p*) + if [[ "$1" != *=* ]]; then shift; fi + RELEASE="--profile=${1#*=}" + TARGET="${1#*=}" + ;; + --feature*|-f*) + if [[ "$1" != *=* ]]; then shift; fi + FEATURES="--features=${1#*=}" + ;; + --executable-path*|-e*) + if [[ "$1" != *=* ]]; then shift; fi + EXECUTABLE_PATH=$(echo ${1#*=}/ | tr -s /) + ;; + --specification-path*|-f*) + if [[ "$1" != *=* ]]; then shift; fi + SPECIFICATION_PATH=$(echo ${1#*=}/ | tr -s /) + ;; + --specification-name*|-n*) if [[ "$1" != *=* ]]; then shift; fi + SPECIFICATION_NAME="${1#*=}" + ;; + --help|-h) + echo "Ghost Node Build automation tool." + echo -e "Use wisely, the main purpose of this script is to help people not to mess up with pathes/folders to the ghost node.\n" + echo "Options:" + echo -e "-b, --skip-build\n\tSkip build only copying." + echo -e "-e, --executable-path\n\tPath to executable ('/usr/lib/' is default)." + echo -e "-a, --specification-path\n\tPath to specification ('/etc/ghost' is default)." + echo -e "-n, --specification-name\n\tSpecification name to be used ('casper' is default)." + echo -e "-r, --release\n\tBuild optimized artifacts with the release profile." + echo -e "-p, --profile\n\tBuild with the given and predefined profile." + echo -e "-h, --help\n\tPrints help information." + exit 0 + ;; + *) + echo -e "[-] Wrong arguments\n" + echo "Ghost Node Build automation tool." + echo -e "Use wisely, the main purpose of this script is to help people not to mess up with pathes/folders to the ghost node.\n" + echo "Options:" + echo -e "-b, --skip-build\n\tSkip build only copying." + echo -e "-e, --executable-path\n\tPath to executable ('/usr/lib/' is default)." + echo -e "-a, --specification-path\n\tPath to specification ('/etc/ghost' is default)." + echo -e "-n, --specification-name\n\tSpecification name to be used ('casper' is default)." + echo -e "-r, --release\n\tBuild optimized artifacts with the release profile." + echo -e "-p, --profile\n\tBuild with the given and predefined profile." + echo -e "-h, --help\n\tPrints help information." + exit 1 + ;; + esac + shift +done + +if [[ ! -z $RELEASE ]]; then + if prompt "[?] 'cargo build $RELEASE $FEATURES' is what you want?"; then + cd $PROJECT_FOLDER + echo "[+] Starting build in 3 seconds..." + sleep 3 + cargo build $RELEASE $FEATURES + fi +fi + +if [[ $MAKE_GLOBAL = true ]]; then + cd $PROJECT_FOLDER + sudo cp target/$TARGET/ghost $EXECUTABLE_PATH + cp service/chain-specs/$SPECIFICATION_NAME.json $SPECIFICATION_PATH + cd $SCRIPT_FOLDER + cp packaging/environment $SPECIFICATION_PATH + + echo "[+] ghost executable copied in '$EXECUTABLE_PATH' from '$TARGET'" + echo "[+] specification '$SPECIFICATION_NAME.json' copied to '$SPECIFICATION_PATH'" + echo "[+] default CLI arguments exported into '$SPECIFICATION_NAME'" +fi + +if [ $UNIT_FILE = true ]; then + cd $SCRIPT_FOLDER + read -p "[?] name for the unit file (default: ghost-node.service) " unit_name + if [ -z $unit_name ]; then + unit_name="ghost-node" + fi + unit_name=$(echo "$unit_name" | sed -e "s/.service//g") + unit_name="$unit_name.service" + + cp /packaging/template.service /etc/systemd/user + sudo systemctl daemon-reload + + if prompt "[?] do you want to start the $unit_name?"; then + sudo systemctl restart $unit_name + fi + + if prompt "[?] do you want to enable the $unit_name?"; then + sudo systemctl enable $unit_name + fi +fi + +if [[ $ARGUMENTS = true ]]; then + echo "[+] setting-up basic CLI arguments" + CLI_ARGS=() + + read -p "[?] specify p2p protocol TCP port (default: 30333): " port + CLI_ARGS+=("--port=${port:-30333}") + + read -p "[?] specify JSON-RPC server TCP port: (default: 9945): " rpc_port + CLI_ARGS+=("--rpc-port=${rpc_port:-9945}") + + read -p "[?] specify the chain specification (default: /etc/ghost/casper.json): " chain + CLI_ARGS+=("--chain=${chain:-/etc/ghost/casper.json}") + + read -p "[?] specify file from which to read the node's secret key for p2p networking (default: /etc/ghost/node-key): " node_key + CLI_ARGS+=("--node-key-file=${node_key:-/etc/ghost/node-key}") + + read -p "[?] specify name for the node (default: RANDOM_NAME): " node_name + if [[ ! -z $node_name ]]; then + CLI_ARGS+=("--name='$node_name'") + fi + + read -p "[?] specify custom base path for the node (default: /var/lib/ghost): " base_path + CLI_ARGS+=("--base-path=${base_path:-/var/lib/ghost}") + + if prompt "[?] enable validator mode?"; then + CLI_ARGS+=("--validator") + fi + + if prompt "[?] enable prometheus?"; then + read -p "[?] specify prometheus exporter TCP port: (default: 9615)" prometheus_port + CLI_ARGS+=("--prometheus-port=${prometheus_port:-9615}") + else + CLI_ARGS+=("--no-prometheus") + fi + + # default for now + CLI_ARGS+=("--state-prunning=archieve") + CLI_ARGS+=("--rpc-external=local") + CLI_ARGS+=("--rpc-methods=auto") + CLI_ARGS+=("--no-telemetry") + CLI_ARGS+=("--no-private-ip") + CLI_ARGS+=("--no-mdns") + CLI_ARGS+=("--no-hardware-benchmarks") + + sudo echo "GHOST_CLI_ARGS=\"$(IFS=' '; echo "${CLI_ARGS[*]}")\"" > /etc/default/ghost + echo "[+] new CLI arguments stored in '/etc/default/ghost'" + cat /etc/default/ghost +fi + +# back to the starting point +cd $CURRENT_PATH +echo "[+] execution finished" diff --git a/scripts/packaging/template.service b/scripts/packaging/template.service new file mode 100644 index 0000000..75836f8 --- /dev/null +++ b/scripts/packaging/template.service @@ -0,0 +1,38 @@ +[Unit] +Description=Ghost Node +After=network.target +Documentation=https://git.ghostchain.io/ghostchain/ghost-node + +[Service] +EnvironmentFile=-/etc/default/ghost +ExecStart=/usr/bin/ghost $GHOST_CLI_ARGS +User=ghost +Group=ghost +Restart=always +RestartSec=30 +TODO CapabilityBoundingSet= +LockPersonality=true +NoNewPrivileges=true +PrivateDevices=true +PrivateMounts=true +PrivateTmp=true +PrivateUsers=true +ProtectClock=true +ProtectControlGroups=true +ProtectHostname=true +ProtectKernelModules=true +ProtectKernelTunables=true +TODO ProtectSystem=strict +RemoveIPC=true +TODO RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX +gRestrictNamespaces=false +RestrictSUIDSGID=true +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=landlock_add_rule landlock_create_ruleset landlock_restrict_self seccomp mount umount2 +SystemCallFilter=~@clock @module @reboot @swap @privileged +SystemCallFilter=pivot_root +UMask=0027 + +[Install] +WantedBy=multi-user.target