Compare commits

..

2 Commits

Author SHA1 Message Date
Aaron Dewes
61f5f9f1e0
Citadel 0.0.7 (#76)
Co-authored-by: nolim1t - f6287b82CC84bcbd <nolim1t@users.noreply.github.com>
Co-authored-by: Aaron Dewes <aaron.dewes@protonmail.com>
Co-authored-by: Philipp Walter <philippwalter@pm.me>
2022-08-11 13:50:09 +02:00
Philipp Walter
07aa73b59e
feat: add Citadel CLI (#33)
add commands for:
- Show status for all services
- Run a command inside a (app) container
- Switch branch / update channel
- Switch Bitcoin/Electrum/Lightning implementation
- app commands
- debug command
- Fix update / backup / starting stuck
- Edit node configs (Bitcoin Core, LND)
- Edit app configs (Nextcloud etc.)
- Memory usage / System info
- Start
- Stop
- Restart
- Reboot
- Shutdown
- List all installed apps & services
- Logs
- Version
- Help
2022-07-15 13:26:23 +02:00
22 changed files with 892 additions and 78 deletions

4
.gitignore vendored
View File

@ -22,7 +22,7 @@ statuses/*
app-data
apps
electrs/*
fulcrumx/*
fulcrum/*
nginx/*
redis/*
docker-compose.override.yml
@ -43,7 +43,7 @@ db/citadel-seed/*
!db/.gitkeep
!nginx/.gitkeep
!redis/.gitkeep
!fulcrumx/.gitkeep
!fulcrum/.gitkeep
!**/*.license
services/installed.json

View File

@ -118,26 +118,6 @@ def getUserData():
userData = json.load(f)
return userData
def checkUpdateAvailable(name: str) -> bool:
latestAppYml = yaml.safe_load(getAppYml(name))
with open(os.path.join(appsDir, name, "app.yml"), "r") as f:
originalAppYml = yaml.safe_load(f)
if not "metadata" in latestAppYml or not "version" in latestAppYml["metadata"] or not "metadata" in originalAppYml or not "version" in originalAppYml["metadata"]:
print("App {} is not valid".format(name))
return False
return semver.compare(latestAppYml["metadata"]["version"], originalAppYml["metadata"]["version"]) > 0
def getAvailableUpdates():
availableUpdates = []
apps = findAndValidateApps(appsDir)
for app in apps:
try:
if checkUpdateAvailable(app):
availableUpdates.append(app)
except Exception:
print("Warning: Can't check app {} yet".format(app), file=sys.stderr)
return availableUpdates
def startInstalled():
# If userfile doesn't exist, just do nothing
userData = {}
@ -364,3 +344,59 @@ def updateRepos():
shutil.rmtree(tempDir)
with open(os.path.join(appsDir, "sourceMap.json"), "w") as f:
json.dump(sourceMap, f)
def getAvailableUpdates():
availableUpdates = {}
repos = []
ignoreApps = []
with open(sourcesList) as f:
repos = f.readlines()
try:
with open(updateIgnore) as f:
ignoreApps = f.readlines()
except: pass
# For each repo, clone the repo to a temporary dir, checkout the branch,
# and overwrite the current app dir with the contents of the temporary dir/apps/app
# Set this to ignoreApps. Normally, it keeps track of apps already installed from repos higher in the list,
# but apps specified in updateignore have the highest priority
alreadyDefined = [s.strip() for s in ignoreApps]
for repo in repos:
repo = repo.strip()
if repo == "":
continue
# Also ignore comments
if repo.startswith("#"):
continue
# Split the repo into the git url and the branch
repo = repo.split(" ")
if len(repo) != 2:
print("Error: Invalid repo format in " + sourcesList, file=sys.stderr)
exit(1)
gitUrl = repo[0]
branch = repo[1]
# Clone the repo to a temporary dir
tempDir = tempfile.mkdtemp()
# Git clone with a depth of 1 to avoid cloning the entire repo
# Don't print anything to stdout, as we don't want to see the git clone output
subprocess.run("git clone --depth 1 --branch {} {} {}".format(branch, gitUrl, tempDir), shell=True, stdout=subprocess.DEVNULL)
# Overwrite the current app dir with the contents of the temporary dir/apps/app
for app in os.listdir(os.path.join(tempDir, "apps")):
try:
# if the app is already installed (or a simple file instead of a valid app), skip it
if app in alreadyDefined or not os.path.isdir(os.path.join(tempDir, "apps", app)):
continue
with open(os.path.join(appsDir, app, "app.yml"), "r") as f:
originalAppYml = yaml.safe_load(f)
with open(os.path.join(tempDir, "apps", app, "app.yml"), "r") as f:
latestAppYml = yaml.safe_load(f)
if semver.compare(latestAppYml["metadata"]["version"], originalAppYml["metadata"]["version"]) > 0:
availableUpdates[app] = {
"updateFrom": originalAppYml["metadata"]["version"],
"updateTo": latestAppYml["metadata"]["version"]
}
except Exception:
print("Warning: Can't check app {} (yet)".format(app), file=sys.stderr)
# Remove the temporary dir
shutil.rmtree(tempDir)
return availableUpdates

1
bin/citadel Symbolic link
View File

@ -0,0 +1 @@
../cli/citadel

487
cli/citadel Executable file
View File

@ -0,0 +1,487 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2022 Citadel and contributors
#
# SPDX-License-Identifier: GPL-3.0-or-later
set -euo pipefail
CITADEL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/..)"
CLI_NAME="$(basename $0)"
CLI_VERSION="0.0.1"
CLI_DIR="$(dirname "$(readlink -f "$0")")"
SERVICE_NAME="citadel-startup"
EDITOR="${EDITOR:-micro}"
source $CLI_DIR/utils/functions.sh
source $CLI_DIR/utils/multiselect.sh
source $CLI_DIR/utils/spinner.sh
source $CLI_DIR/utils/helpers.sh
if [ -z ${1+x} ]; then
command=""
else
command="$1"
fi
# Check Citadel Status
if [[ "$command" = "status" ]]; then
POSITIONAL_ARGS=()
long=false
while [[ $# -gt 0 ]]; do
case $1 in
-l | --long)
long=true
shift
;;
-* | --*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1")
shift
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}"
free -m | awk 'NR==2{printf "Memory Usage: %s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }'
df -h | awk '$NF=="/"{printf "Disk Usage: %d/%dGB (%s)\n", $3,$2,$5}'
top -bn1 | grep load | awk '{printf "CPU Load: %.2f\n", $(NF-2)}'
echo
if $long; then
docker container ls --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
else
docker container ls --format "table {{.Names}}\t{{.Status}}"
fi
if [[ $(pgrep -f karen) ]]; then
printf "\nKaren is listening.\n"
else
printf "\nERROR: Karen is not listening.\n"
fi
exit
fi
# Update Citadel
if [[ "$command" = "update" ]]; then
POSITIONAL_ARGS=()
branch=$(get_update_channel)
force=false
while [[ $# -gt 0 ]]; do
case $1 in
-b | --branch)
branch="$2"
shift # past argument
shift # past value
;;
--force)
force=true
shift # past argument
;;
-* | --*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
if $force; then
sudo rm -f $CITADEL_ROOT/statuses/update-in-progress
fi
sudo $CITADEL_ROOT/scripts/update/update --repo runcitadel/core#$branch
exit
fi
# Start Citadel
if [[ "$command" = "start" ]]; then
if $(is_managed_by_systemd); then
if $(is_service_active); then
echo 'Citadel is already running.'
else
sudo systemctl start citadel-startup
fi
else
sudo $CITADEL_ROOT/scripts/start
fi
exit
fi
# Stop Citadel
if [[ "$command" = "stop" ]]; then
active=$(is_service_active)
if $(is_managed_by_systemd) && $active; then
if $(is_service_active); then
sudo systemctl stop citadel-startup
else
echo 'Citadel is not running.'
fi
else
sudo $CITADEL_ROOT/scripts/stop
fi
exit
fi
# Restart Citadel
if [[ "$command" = "restart" ]]; then
shift
# TODO: enable restarting services
if [ ! -z ${1+x} ]; then
echo "Too many arguments."
echo "Usage: \`$CLI_NAME $command\`"
exit 1
fi
if $(is_managed_by_systemd); then
sudo systemctl restart $SERVICE_NAME
else
sudo $CITADEL_ROOT/scripts/stop
sudo $CITADEL_ROOT/scripts/start
fi
exit
fi
# Reboot the system
if [[ "$command" = "reboot" ]]; then
$CLI_NAME stop || true
sudo reboot
exit
fi
# Shutdown the system
if [[ "$command" = "shutdown" ]]; then
$CLI_NAME stop || true
sudo shutdown now
exit
fi
# List all installed services apps
if [[ "$command" = "list" ]]; then
echo 'karen'
docker ps --format "{{.Names}}"
exit
fi
# Run a command inside a container
if [[ "$command" = "run" ]]; then
shift
if [ -z ${1+x} ]; then
echo "Specify an app or service."
echo "Usage: \`$CLI_NAME $command <service> \"<command>\"\`"
exit 1
fi
if [ -z ${2+x} ]; then
echo "Specify a command to run."
echo "Usage: \`$CLI_NAME $command <service> \"<command>\"\`"
exit 1
fi
docker exec -t $1 sh -c "$2" || {
echo "To see all installed services & apps use \`$CLI_NAME list\`"
echo "Usage: \`$CLI_NAME $command <service> \"<command>\"\`"
exit 1
}
exit
fi
# Configure Citadel
if [[ "$command" = "set" ]]; then
shift
if [ -z ${1+x} ]; then
echo "Missing subcommand."
echo "Usage: \`$CLI_NAME $command <subcommand>\`"
exit 1
else
subcommand="$1"
fi
# Switch update channel
if [[ "$subcommand" = "update-channel" ]]; then
if [ -z ${2+x} ]; then
echo "Specify an update channel to switch to."
echo "Usage: \`$CLI_NAME $subcommand <stable|beta|c-lightning>\`"
exit 1
fi
case $2 in "stable" | "beta" | "c-lightning")
# continue
;;
*)
echo "Not a valid update channel: \"$2\""
exit 1
;;
esac
sudo $CITADEL_ROOT/scripts/set-update-channel $2
$CLI_NAME update
exit
fi
# Switch Bitcoin/Electrum implementation
if [[ "$subcommand" = "implementation" ]] || [[ "$subcommand" = "impl" ]]; then
shift
sudo $CITADEL_ROOT/services/manage.py set $@
$CLI_NAME restart
exit
fi
# Switch Bitcoin network
if [[ "$subcommand" = "network" ]]; then
shift
if [ -z ${1+x} ]; then
echo "Specify a network to switch to."
echo "Usage: \`$CLI_NAME $subcommand <mainnet|signet|testnet|regtest>\`"
else
case $1 in
"mainnet" | "testnet" | "signet" | "regtest")
sudo $CITADEL_ROOT/scripts/stop
sudo OVERWRITE_NETWORK=$1 $CITADEL_ROOT/scripts/configure
sudo $CITADEL_ROOT/scripts/start
;;
*)
echo "Not a valid value for network"
exit 1
;;
esac
fi
exit
fi
echo "\"$subcommand\" is not a valid subcommand."
exit 1
fi
# App commands
if [[ "$command" = "app" ]]; then
shift
sudo $CITADEL_ROOT/scripts/app $@
exit
fi
# Edit common app configuration files
if [[ "$command" = "configure" ]]; then
if [ -z ${2+x} ]; then
echo "Specify an app or service to configure."
echo "Usage: \`$CLI_NAME $command <service>\`"
exit 1
fi
POSITIONAL_ARGS=()
persist=false
while [[ $# -gt 0 ]]; do
case $1 in
--persist)
persist=true
shift # past argument
;;
-* | --*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
# These service and app configs are already persisted
# TODO: add more apps
if [[ "$2" = "nextcloud" ]]; then
edit_file --priviledged $CITADEL_ROOT/app-data/nextcloud/data/nextcloud/config/config.php
prompt_apply_config nextcloud-web-1 false
exit
fi
if [[ "$2" = "nginx" ]]; then
edit_file $CITADEL_ROOT/nginx/nginx.conf
prompt_apply_config nginx false
exit
fi
if $persist; then
echo "NOTE: As of now persisted config changes will not be kept when updating Citadel."
else
echo "NOTE: Some changes to this configuration file may be overwritten the next time you start Citadel."
echo "To persist the changes run the command again with \`$CLI_NAME configure $2 --persist\`"
fi
read -p "Continue? [Y/n] " should_continue
echo
if [[ $should_continue =~ [Nn]$ ]]; then
exit
fi
# Service and app configs below may be overwritten
# TODO: check which implementation is running
# and do "bitcoin" / "lightning" / "electrum"
if [[ "$2" = "bitcoin" ]]; then
if $persist; then
edit_file $CITADEL_ROOT/templates/bitcoin-sample.conf
prompt_apply_config bitcoin true
else
edit_file $CITADEL_ROOT/bitcoin/bitcoin.conf
prompt_apply_config bitcoin false
fi
exit
fi
if [[ "$2" = "lnd" ]]; then
if $persist; then
edit_file $CITADEL_ROOT/templates/lnd-sample.conf
prompt_apply_config lightning true
else
edit_file $CITADEL_ROOT/lnd/lnd.conf
prompt_apply_config lightning false
fi
exit
fi
if [[ "$2" = "electrs" ]]; then
edit_file $CITADEL_ROOT/templates/electrs-sample.toml
prompt_apply_config electrum true
exit
fi
if [[ "$2" = "fulcrum" ]]; then
if $persist; then
edit_file $CITADEL_ROOT/templates/fulcrum-sample.conf
prompt_apply_config electrum true
else
edit_file $CITADEL_ROOT/fulcrum/fulcrum.conf
prompt_apply_config electrum false
fi
exit
fi
echo "No service or app \"$2\" not found."
exit 1
fi
# Show logs for apps & services
if [[ "$command" = "logs" ]]; then
shift
POSITIONAL_ARGS=()
follow=false
while [[ $# -gt 0 ]]; do
case $1 in
-f | --follow)
follow=true
shift # past argument
;;
-n | --tail)
number_of_lines="$2"
shift # past argument
shift # past value
;;
-* | --*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
# Set default number_of_lines if not set by user
if [ -z ${number_of_lines+x} ]; then
if [[ ${#POSITIONAL_ARGS[@]} == 0 ]] || [[ ${#POSITIONAL_ARGS[@]} == 1 ]]; then
number_of_lines=40
else
number_of_lines=10
fi
fi
if [ -z ${1+x} ] || [[ "$1" = "karen" ]]; then
if [[ ${#POSITIONAL_ARGS[@]} == 2 ]]; then
echo "Karen logs cannot be viewed together with other services."
echo "Usage: \`$CLI_NAME $command karen\`"
exit 1
fi
tail $($follow && echo "-f") -n $number_of_lines $CITADEL_ROOT/logs/karen.log
exit
fi
if [[ ${#POSITIONAL_ARGS[@]} == 1 ]]; then
docker logs $($follow && echo "-f") --tail $number_of_lines $@ || {
echo "To see all installed services & apps use \`$CLI_NAME list\`"
echo "Usage: \`$CLI_NAME $command <service>\`"
exit 1
}
else
# TODO: can only show logs for services in docker-compose.yml
docker compose logs $($follow && echo "-f") --tail $number_of_lines $@ || {
echo "To see all installed services & apps use \`$CLI_NAME list\`"
echo "Usage: \`$CLI_NAME $command <service>\`"
exit 1
}
fi
exit
fi
# Debug Citadel
if [[ "$command" = "debug" ]]; then
shift
sudo $CITADEL_ROOT/scripts/debug $@
exit
fi
# Show version information for this CLI
if [[ "$command" = "--version" ]] || [[ "$command" = "-v" ]]; then
citadel_version=$(jq -r '.version' $CITADEL_ROOT/info.json)
echo "Citadel v$citadel_version"
echo "citadel-cli v$CLI_VERSION"
exit
fi
# Show usage information for this CLI
if [[ "$command" = "--help" ]] || [[ "$command" = "-h" ]]; then
show_help
exit
fi
# If we get here it means no valid command was supplied
# Show help and exit
show_help
exit

111
cli/utils/functions.sh Normal file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env bash
set -euo pipefail
show_help() {
cat <<EOF
${CLI_NAME}-cli v${CLI_VERSION}
Manage your Citadel.
Usage: ${CLI_NAME} <command> [options]
Flags:
-h, --help Show this help message
-v, --version Show version information for this CLI
Commands:
status Check the status of all services
start Start the Citadel service
stop Stop the Citadel service safely
restart Restart the Citadel service
reboot Reboot the system
shutdown Shutdown the system
update Update Citadel
list List all installed services apps
run <service> "<command>" Run a command inside a container
set <command> Switch between Bitcoin & Lightning implementations
app <command> Install, update or restart apps
configure <service> Edit service & app configuration files
logs <service> Show logs for an app or service
debug View logs for troubleshooting
EOF
}
is_managed_by_systemd() {
if systemctl --all --type service | grep -q "$SERVICE_NAME"; then
echo true
else
echo false
fi
}
is_service_active() {
service_status=$(systemctl is-active $SERVICE_NAME)
if [[ "$service_status" = "active" ]]; then
echo true
else
echo false
fi
}
edit_file() {
if [[ $1 = "--priviledged" ]]; then
echo "Editing this file requires elevated priviledges."
if ! sudo test -f $2; then
echo "File not found."
exit 1
fi
if sudo test -w $2; then
sudo $EDITOR $2
else
echo "File not writable."
fi
else
if ! test -f $1; then
echo "File not found."
exit 1
fi
if test -w $1; then
$EDITOR $1
else
echo "File not writable."
fi
fi
}
get_update_channel() {
update_channel_line=$(cat $CITADEL_ROOT/.env | grep UPDATE_CHANNEL)
update_channel=(${update_channel_line//=/ })
if [ -z ${update_channel[1]+x} ]; then
# fall back to stable
echo "stable"
else
echo ${update_channel[1]}
fi
}
prompt_apply_config() {
service=$1
persisted=$2
read -p "Do you want to apply the changes now? [y/N] " should_restart
echo
if [[ $should_restart =~ [Yy]$ ]]; then
if $persisted; then
sudo $CITADEL_ROOT/scripts/configure
fi
printf "\nRestarting service \"$service\"...\n"
docker restart $service
echo "Done."
else
if $persisted; then
echo "To apply the changes, restart Citadel by running \`$CLI_NAME restart\`."
else
echo "To apply the changes, restart service \"$service\" by running \`docker restart $service\`."
fi
fi
}

11
cli/utils/helpers.sh Normal file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -euo pipefail
trim() {
local var="$*"
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "$var"
}

123
cli/utils/multiselect.sh Normal file
View File

@ -0,0 +1,123 @@
#!/usr/bin/env bash
set -euo pipefail
function multiselect() {
# little helpers for terminal print control and key input
ESC=$(printf "\033")
cursor_blink_on() { printf "$ESC[?25h"; }
cursor_blink_off() { printf "$ESC[?25l"; }
cursor_to() { printf "$ESC[$1;${2:-1}H"; }
print_inactive() { printf "$2 $1 "; }
print_active() { printf "$2 $ESC[7m $1 $ESC[27m"; }
get_cursor_row() {
IFS=';' read -sdR -p $'\E[6n' ROW COL
echo ${ROW#*[}
}
local return_value=$1
local -n options=$2
local -n defaults=$3
local selected=()
for ((i = 0; i < ${#options[@]}; i++)); do
if [[ ${defaults[i]} = "true" ]]; then
selected+=("true")
else
selected+=("false")
fi
printf "\n"
done
# determine current screen position for overwriting the options
local lastrow=$(get_cursor_row)
local startrow=$(($lastrow - ${#options[@]}))
# ensure cursor and input echoing back on upon a ctrl+c during read -s
trap "cursor_blink_on; stty echo; printf '\n'; exit" 2
cursor_blink_off
key_input() {
local key
IFS= read -rsn1 key 2>/dev/null >&2
if [[ $key = "" ]]; then echo enter; fi
if [[ $key = $'\x20' ]]; then echo space; fi
if [[ $key = "k" ]]; then echo up; fi
if [[ $key = "j" ]]; then echo down; fi
if [[ $key = $'\x1b' ]]; then
read -rsn2 key
if [[ $key = [A || $key = k ]]; then echo up; fi
if [[ $key = [B || $key = j ]]; then echo down; fi
fi
}
toggle_option() {
local option=$1
if [[ ${selected[option]} == true ]]; then
selected[option]=false
else
selected[option]=true
fi
}
print_options() {
# print options by overwriting the last lines
local idx=0
for option in "${options[@]}"; do
local prefix="[ ]"
if [[ ${selected[idx]} == true ]]; then
prefix="[\e[38;5;46m✔\e[0m]"
fi
cursor_to $(($startrow + $idx))
if [ $idx -eq $1 ]; then
print_active "$option" "$prefix"
else
print_inactive "$option" "$prefix"
fi
idx=$((idx + 1))
done
}
get_result() {
local result=()
for ((i = 0; i < ${#options[@]}; i++)); do
if ${selected[i]}; then
result+=(${options[i]})
fi
done
echo "${result[@]}"
}
local active=0
while true; do
print_options $active
# user key control
case $(key_input) in
space) toggle_option $active ;;
enter)
print_options -1
break
;;
up)
active=$((active - 1))
if [ $active -lt 0 ]; then active=$((${#options[@]} - 1)); fi
;;
down)
active=$((active + 1))
if [ $active -ge ${#options[@]} ]; then active=0; fi
;;
esac
done
# cursor position back to normal
cursor_to $lastrow
printf "\n"
cursor_blink_on
eval $return_value='("$(get_result)")'
}

87
cli/utils/spinner.sh Normal file
View File

@ -0,0 +1,87 @@
#!/bin/bash
# Author: Tasos Latsas
# spinner.sh
#
# Display an awesome 'spinner' while running your long shell commands
#
# Do *NOT* call _spinner function directly.
# Use {start,stop}_spinner wrapper functions
# usage:
# 1. source this script in your's
# 2. start the spinner:
# start_spinner [display-message-here]
# 3. run your command
# 4. stop the spinner:
# stop_spinner [your command's exit status]
#
# Also see: test.sh
function _spinner() {
# $1 start/stop
#
# on start: $2 display message
# on stop : $2 process exit status
# $3 spinner function pid (supplied from stop_spinner)
local on_success="DONE"
local on_fail="FAIL"
local white="\e[1;37m"
local green="\e[1;32m"
local red="\e[1;31m"
local nc="\e[0m"
case $1 in
start)
# display message with some space
echo -ne "${2} "
# start spinner
i=1
sp='\|/-'
delay=${SPINNER_DELAY:-0.15}
while :; do
printf "\b${sp:i++%${#sp}:1}"
sleep $delay
done
;;
stop)
if [[ -z ${3} ]]; then
echo "spinner is not running.."
exit 1
fi
kill $3 >/dev/null 2>&1
# inform the user upon success or failure
echo -en "\b["
if [[ $2 -eq 0 ]]; then
echo -en "${green}${on_success}${nc}"
else
echo -en "${red}${on_fail}${nc}"
fi
echo -e "]"
;;
*)
echo "invalid argument, try {start/stop}"
exit 1
;;
esac
}
function start_spinner() {
# $1 : msg to display
_spinner "start" "${1}" &
# set global spinner pid
_sp_pid=$!
disown
}
function stop_spinner() {
# $1 : command exit status
_spinner "stop" $1 $_sp_pid
unset _sp_pid
}

View File

@ -65,7 +65,7 @@ services:
ipv4_address: $NGINX_IP
bitcoin:
container_name: bitcoin
image: nolim1t/bitcoinknots:v22.0.knots20211108@sha256:a475da2b2ecda55fcc65ea23e1a36c58b2c10549f1c3d3bb3c31c7dda1127354
image: ghcr.io/runcitadel/bitcoinknots:main@sha256:5fbee0f6f0d09d42aacc11c373ffe6162210c42ce21e6eba294e547e3ad80219
depends_on:
- tor
volumes:
@ -79,7 +79,7 @@ services:
ipv4_address: $BITCOIN_IP
lightning:
container_name: lightning
image: lightninglabs/lnd:v0.14.3-beta@sha256:6a2234b0aad4caed3d993736816b198d6228f32c59b27ba2218d5ebf516ae905
image: lightninglabs/lnd:v0.15.0-beta@sha256:d227a9db0727ff56020c8d6604c8c369757123d238ab6ce679579c2dd0d0d259
user: 1000:1000
depends_on:
- tor

View File

@ -1,6 +1,6 @@
{
"version": "0.0.6",
"name": "Citadel 0.0.6",
"version": "0.0.7",
"name": "Citadel 0.0.7",
"requires": ">=0.0.1",
"notes": "This update fixes a security issue in Tor which could lead to slower Tor performance or your node being inaccessible via Tor."
"notes": "While we are busy with the next huge update, you may need to wait longer for updates. This update updates Bitcoin Knots and LND to their latest versions to ensure apps can utilize their latest features. In addition, this update includes the Citadel CLI. More information on that will be published soon."
}

2
scripts/configure vendored
View File

@ -334,7 +334,7 @@ templates_to_build = {
"./templates/bitcoin-sample.conf": "./bitcoin/bitcoin.conf",
"./templates/.env-sample": "./.env",
"./templates/electrs-sample.toml": "./electrs/electrs.toml",
"./templates/fulcrumx-sample.conf": "./fulcrumx/fulcrumx.conf",
"./templates/fulcrum-sample.conf": "./fulcrum/fulcrum.conf",
"./templates/nginx-sample.conf": "./nginx/nginx.conf"
}

View File

@ -94,7 +94,7 @@ pkill -f ./scripts/status-monitor || true
./scripts/status-monitor storage 60 &>> "${CITADEL_LOGS}/status-monitor.log" &
./scripts/status-monitor temperature 15 &>> "${CITADEL_LOGS}/status-monitor.log" &
./scripts/status-monitor uptime 15 &>> "${CITADEL_LOGS}/status-monitor.log" &
./scripts/status-monitor app-updates 300 &>> "${CITADEL_LOGS}/status-monitor.log" &
./scripts/status-monitor app-updates 600 &>> "${CITADEL_LOGS}/status-monitor.log" &
echo "Starting backup monitor..."
echo

View File

@ -12,4 +12,4 @@ nginx/*
services/installed.yml
apps/sourceMap.json
apps/.updateignore
fulcrumx/*
fulcrum/*

View File

@ -1,18 +0,0 @@
# SPDX-FileCopyrightText: 2021-2022 Citadel and contributors
#
# SPDX-License-Identifier: GPL-3.0-or-later
bitcoin:
container_name: bitcoin
image: ghcr.io/runcitadel/bitcoin-custom:main@sha256:d0af506f8dc92a434e845305ac4252d0601b699c4b3bc4443073a0a2e237f3a0
depends_on:
- tor
volumes:
- ${PWD}/bitcoin:/data/.bitcoin
restart: on-failure
stop_grace_period: 1m
ports:
- $BITCOIN_P2P_PORT:$BITCOIN_P2P_PORT
networks:
default:
ipv4_address: $BITCOIN_IP

View File

@ -4,7 +4,7 @@
bitcoin:
container_name: bitcoin
image: lncm/bitcoind:v22.0@sha256:37a1adb29b3abc9f972f0d981f45e41e5fca2e22816a023faa9fdc0084aa4507
image: lncm/bitcoind:v23.0@sha256:57317c90d89156a30327fe1b8e51b836e0fd1a8ba13721eb2e75e6b35a570e26
depends_on:
- tor
volumes:

View File

@ -4,7 +4,7 @@
bitcoin:
container_name: bitcoin
image: nolim1t/bitcoinknots:v22.0.knots20211108@sha256:a475da2b2ecda55fcc65ea23e1a36c58b2c10549f1c3d3bb3c31c7dda1127354
image: ghcr.io/runcitadel/bitcoinknots:main@sha256:5fbee0f6f0d09d42aacc11c373ffe6162210c42ce21e6eba294e547e3ad80219
depends_on:
- tor
volumes:

View File

@ -4,12 +4,12 @@
electrum:
container_name: electrum
image: ghcr.io/runcitadel/fulcrumx:latest@sha256:a74abdfe8397f02482faed6bd828477c452df071129f66ad6596d0ab8d29cf39
image: cculianu/fulcrum:latest@sha256:c0543f8b8a5bf6b0c447d8525d6b4360a6c07532f7741f19cc2c179968e71848
working_dir: /data
volumes:
- ${PWD}/bitcoin:/bitcoin:ro
- ${PWD}/fulcrumx:/data
command: /usr/bin/FulcrumX /data/fulcrumx.conf
- ${PWD}/fulcrum:/data
command: /usr/bin/Fulcrum /data/fulcrum.conf
restart: on-failure
stop_grace_period: 5m
ports:

View File

@ -1,19 +0,0 @@
# SPDX-FileCopyrightText: 2021-2022 Citadel and contributors
#
# SPDX-License-Identifier: GPL-3.0-or-later
electrum:
container_name: electrum
image: ghcr.io/runcitadel/fulcrumx:latest@sha256:557a54a5652b475b01c59eb6cffee3568f18b74d875c4cc125e5ac190c4b0706
working_dir: /data
volumes:
- ${PWD}/bitcoin:/bitcoin:ro
- ${PWD}/fulcrumx:/data
command: /usr/bin/FulcrumX /data/fulcrumx.conf
restart: on-failure
stop_grace_period: 5m
ports:
- "$ELECTRUM_PORT:$ELECTRUM_PORT"
networks:
default:
ipv4_address: $ELECTRUM_IP

View File

@ -1,6 +1,6 @@
lightning:
container_name: lightning
image: lightninglabs/lnd:v0.14.3-beta@sha256:6a2234b0aad4caed3d993736816b198d6228f32c59b27ba2218d5ebf516ae905
image: lightninglabs/lnd:v0.15.0-beta@sha256:d227a9db0727ff56020c8d6604c8c369757123d238ab6ce679579c2dd0d0d259
user: 1000:1000
depends_on:
- tor

View File

@ -65,9 +65,4 @@ tor.targetipaddress=<lnd-ip>
tor.password=<tor-password>
tor.v3=1
[healthcheck]
; Disable the chain backend health check
healthcheck.chainbackend.attempts=0
<bolt-db-options>