-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathawning.sh
More file actions
executable file
·245 lines (217 loc) · 8.73 KB
/
awning.sh
File metadata and controls
executable file
·245 lines (217 loc) · 8.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#!/bin/bash
# Awning v2: Bitcoin + Lightning Node Manager
# https://github.com/giovantenne/awning
# Strict mode: -u (error on undefined vars), -o pipefail (propagate pipe errors).
# Note: -e (errexit) is intentionally omitted because the interactive menu and
# subcommands must handle errors gracefully without killing the entire script.
set -uo pipefail
# Resolve project directory (where this script lives)
AWNING_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export AWNING_DIR
# Prevent concurrent executions (flock on file descriptor 9)
exec 9>"${AWNING_DIR}/.lock"
if ! flock -n 9; then
echo "Error: another instance of awning.sh is already running." >&2
exit 1
fi
# Source library modules
source "${AWNING_DIR}/lib/common.sh"
source "${AWNING_DIR}/lib/docker.sh"
source "${AWNING_DIR}/lib/setup.sh"
source "${AWNING_DIR}/lib/domain/status.sh"
source "${AWNING_DIR}/lib/domain/wallet.sh"
source "${AWNING_DIR}/lib/health.sh"
source "${AWNING_DIR}/lib/app/commands.sh"
source "${AWNING_DIR}/lib/ui/screens/system.sh"
source "${AWNING_DIR}/lib/ui/screens/wallet.sh"
source "${AWNING_DIR}/lib/ui/screens/backup.sh"
source "${AWNING_DIR}/lib/menu.sh"
# Load .env safely (do not execute shell expressions from config values)
load_env_file() {
local env_file="${AWNING_DIR}/.env"
[[ -f "$env_file" ]] || return 0
local key value
while IFS= read -r line || [[ -n "$line" ]]; do
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
[[ "$line" =~ ^[[:space:]]*([A-Z0-9_]+)=(.*)$ ]] || continue
key="${BASH_REMATCH[1]}"
value="${BASH_REMATCH[2]}"
value="${value%%[[:space:]]#*}"
# Strip surrounding double or single quotes
value="${value%\"}"
value="${value#\"}"
value="${value%\'}"
value="${value#\'}"
case "$key" in
HOST_UID|HOST_GID|BITCOIN_ARCH|LND_ARCH|BITCOIN_CORE_VERSION|LND_VERSION|ELECTRS_VERSION|RTL_VERSION|NODE_ALIAS|BITCOIN_RPC_USER|BITCOIN_RPC_PASSWORD|TOR_CONTROL_PASSWORD|RTL_PASSWORD|SCB_REPO|LND_REST_BIND|LND_REST_PORT|ELECTRS_SSL_BIND|ELECTRS_SSL_PORT|RTL_BIND|RTL_PORT|BITCOIN_MEM_LIMIT|BITCOIN_CPUS|LND_MEM_LIMIT|LND_CPUS|ELECTRS_MEM_LIMIT|ELECTRS_CPUS)
export "$key=$value"
;;
esac
done < "$env_file"
}
load_env_file
# Validate .env values after loading.
# Only runs when .env exists (i.e., after setup). Catches common misconfigurations
# early rather than letting them fail deep in Docker builds or at runtime.
validate_env() {
local env_file="${AWNING_DIR}/.env"
[[ -f "$env_file" ]] || return 0
local errors=0
# Helper: check that a variable is a positive integer
_check_int() {
local name="$1" val="$2"
if [[ -n "$val" ]] && ! [[ "$val" =~ ^[0-9]+$ ]]; then
echo " .env: ${name}='${val}' is not a valid integer" >&2
errors=$((errors + 1))
fi
}
# Helper: check port range (1-65535)
_check_port() {
local name="$1" val="$2"
if [[ -n "$val" ]]; then
if ! [[ "$val" =~ ^[0-9]+$ ]] || (( val < 1 || val > 65535 )); then
echo " .env: ${name}='${val}' is not a valid port (1-65535)" >&2
errors=$((errors + 1))
fi
fi
}
# UID/GID must be numeric
_check_int "HOST_UID" "${HOST_UID:-}"
_check_int "HOST_GID" "${HOST_GID:-}"
# Architecture must be known
if [[ -n "${BITCOIN_ARCH:-}" ]] && [[ "$BITCOIN_ARCH" != "x86_64" && "$BITCOIN_ARCH" != "aarch64" ]]; then
echo " .env: BITCOIN_ARCH='${BITCOIN_ARCH}' is not supported (x86_64 or aarch64)" >&2
errors=$((errors + 1))
fi
if [[ -n "${LND_ARCH:-}" ]] && [[ "$LND_ARCH" != "amd64" && "$LND_ARCH" != "arm64" ]]; then
echo " .env: LND_ARCH='${LND_ARCH}' is not supported (amd64 or arm64)" >&2
errors=$((errors + 1))
fi
# Versions must not be empty if set
local ver_var
for ver_var in BITCOIN_CORE_VERSION LND_VERSION ELECTRS_VERSION; do
local ver_val="${!ver_var:-}"
if [[ -n "$ver_val" ]] && [[ ! "$ver_val" =~ ^[0-9] ]]; then
echo " .env: ${ver_var}='${ver_val}' does not look like a version" >&2
errors=$((errors + 1))
fi
done
# Ports must be valid
_check_port "LND_REST_PORT" "${LND_REST_PORT:-}"
_check_port "ELECTRS_SSL_PORT" "${ELECTRS_SSL_PORT:-}"
_check_port "RTL_PORT" "${RTL_PORT:-}"
# Bind addresses must be valid IPv4
local bind_var
for bind_var in LND_REST_BIND ELECTRS_SSL_BIND RTL_BIND; do
local bind_val="${!bind_var:-}"
if [[ -n "$bind_val" ]] && ! [[ "$bind_val" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo " .env: ${bind_var}='${bind_val}' is not a valid IPv4 address" >&2
errors=$((errors + 1))
fi
done
if [[ "$errors" -gt 0 ]]; then
echo " Found ${errors} invalid value(s) in .env. Fix them or rerun: ./awning.sh setup" >&2
return 1
fi
}
validate_env
# Block setup flows only when another installation directory already owns
# the same container names. In-directory setup must remain allowed.
ensure_setup_can_run() {
# Keep conflict messaging consistent with other operational commands:
# when running from another directory, show both installation paths.
if ! check_container_conflicts; then
return 1
fi
return 0
}
# --- Main ---
main() {
local command="${1:-}"
local setup_ignore_disk_space=0
local env_file
env_file="$(awning_path .env)"
# If no .env exists and no command given, run auto-setup
if [[ -z "$command" && ! -f "$env_file" ]]; then
ensure_setup_can_run || return 1
if run_auto_setup "$setup_ignore_disk_space"; then
if check_container_conflicts; then
show_menu
else
return 1
fi
fi
return
fi
# Also handle: ./awning.sh --ignore-disk-space (no .env, triggers auto-setup)
if [[ ! -f "$env_file" ]] && [[ "$command" == "--ignore-disk-space" || "$command" == "--force" ]]; then
ensure_setup_can_run || return 1
if run_auto_setup 1; then
if check_container_conflicts; then
show_menu
else
return 1
fi
fi
return
fi
# Block operational commands until setup has generated .env
if [[ ! -f "$env_file" ]]; then
case "$command" in
setup|help|-h|--help|version)
;;
*)
print_fail "Node is not configured yet (.env not found)."
print_info "Run ${CYAN}./awning.sh setup${NC} first."
return 1
;;
esac
fi
# Prevent running operational commands from a different installation
# directory when another awning instance already owns these container names.
case "$command" in
setup|help|-h|--help|version)
;;
*)
if ! check_container_conflicts; then
return 1
fi
;;
esac
app_dispatch_command "$command" "$setup_ignore_disk_space" "${@:2}"
}
show_help() {
draw_header "AWNING v$(get_awning_version)" "Bitcoin + Lightning Node"
echo ""
echo -e " ${BOLD}Usage:${NC} ./awning.sh [command]"
echo ""
echo -e " ${BOLD}Commands:${NC}"
echo -e " ${CYAN}(none)${NC} Interactive menu (or setup on first run)"
echo -e " ${CYAN}setup${NC} Run the setup wizard"
echo -e " ${CYAN}setup --ignore-disk-space${NC} Run setup ignoring low disk space"
echo ""
echo -e " ${BOLD}Services:${NC}"
echo -e " ${CYAN}start${NC} Start all services"
echo -e " ${CYAN}stop${NC} Stop all services"
echo -e " ${CYAN}restart${NC} [svc] Restart services"
echo -e " ${CYAN}build${NC} [svc] Build Docker images"
echo -e " ${CYAN}rebuild${NC} Rebuild and restart all"
echo ""
echo -e " ${BOLD}Monitoring:${NC}"
echo -e " ${CYAN}status${NC} Service status and sync progress"
echo -e " ${CYAN}version${NC} Show Awning version"
echo -e " ${CYAN}logs${NC} [svc] Follow service logs"
echo -e " ${CYAN}connections${NC} Wallet connection info"
echo ""
echo -e " ${BOLD}Wallet:${NC}"
echo -e " ${CYAN}wallet-balance${NC} Show LND on-chain balance"
echo -e " ${CYAN}channel-balance${NC} Show LND Lightning balance"
echo -e " ${CYAN}new-address${NC} Generate a new on-chain address"
echo -e " ${CYAN}zeus-connect${NC} Generate Zeus connection URI"
echo ""
echo -e " ${BOLD}CLI:${NC}"
echo -e " ${CYAN}bitcoin-cli${NC} Run bitcoin-cli commands"
echo -e " ${CYAN}lncli${NC} Run lncli commands"
echo ""
}
main "$@"