ovtools 0.0.0-stage → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +121 -2
- package/assets/common/bond-inspect.sh +368 -0
- package/assets/common/config.sh +263 -0
- package/assets/common/extract-data.sh +197 -0
- package/assets/common/harden-host.sh +37 -0
- package/assets/common/install-deps.sh +93 -0
- package/assets/common/node-enroll.sh +65 -0
- package/assets/common/node-setup.sh +150 -0
- package/assets/common/node-start.sh +90 -0
- package/assets/common/node-stop.sh +18 -0
- package/assets/common/node-upgrade.sh +45 -0
- package/assets/common/pre-run.sh +497 -0
- package/assets/common/promote-validator.sh +104 -0
- package/assets/deploy/10-prepare-host.sh +98 -0
- package/assets/deploy/20-install-toolchain.sh +93 -0
- package/assets/deploy/30-setup-node.sh +82 -0
- package/assets/deploy/40-start-node.sh +75 -0
- package/assets/deploy/50-verify.sh +259 -0
- package/assets/deploy/60-enroll.sh +304 -0
- package/assets/deploy/70-promote.sh +152 -0
- package/assets/deploy/lib.sh +398 -0
- package/assets/manage/10-bond-increase.sh +149 -0
- package/assets/manage/10-diagnose-node.sh +169 -0
- package/assets/manage/20-exit-validator.sh +259 -0
- package/assets/manage/25-recover-node.sh +291 -0
- package/assets/manage/30-status.sh +64 -0
- package/assets/manage/40-exit-withdraw.sh +133 -0
- package/assets/manage/bond_inc.sh +318 -0
- package/assets/manage/dashboard_monitor/app.js +1544 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/base.css +113 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/content.css +133 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/controls.css +229 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/data.css +374 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/icons.css +35 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/motion.css +57 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/shell.css +51 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/sidebar.css +242 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/topbar.css +138 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/fonts.css +30 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/synteq-ui-v2.css +25 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/theme-dark.css +38 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/theme-light.css +36 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/tokens.css +61 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/fonts/GoogleSansCode-Medium.ttf +0 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/fonts/GoogleSansCode-Regular.ttf +0 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/fonts/GoogleSansCode-SemiBold.ttf +0 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/js/synteq-ui-v2.js +869 -0
- package/assets/manage/dashboard_monitor/deploy-dashboard.sh +230 -0
- package/assets/manage/dashboard_monitor/favicon.svg +13 -0
- package/assets/manage/dashboard_monitor/index.html +1197 -0
- package/assets/manage/dashboard_monitor/nginx-octra.conf +76 -0
- package/assets/manage/dashboard_monitor/octra-dashboard.service +29 -0
- package/assets/manage/dashboard_monitor/octra-node-prune.cron +12 -0
- package/assets/manage/dashboard_monitor/octra-node-prune.service +16 -0
- package/assets/manage/dashboard_monitor/octra-node-prune.timer +12 -0
- package/assets/manage/dashboard_monitor/prune-node-junk.sh +329 -0
- package/assets/manage/dashboard_monitor/server.py +1887 -0
- package/assets/manage/dashboard_monitor/ssl-certbot.sh +90 -0
- package/assets/manage/dashboard_monitor/styles.css +327 -0
- package/assets/manage/lib.sh +347 -0
- package/assets/manifest.json +143 -0
- package/assets/migrate/00-backup-identity.sh +67 -0
- package/assets/migrate/01-prepare-target.sh +145 -0
- package/assets/migrate/02-authorize-pull.sh +43 -0
- package/assets/migrate/03-pull-state.sh +102 -0
- package/assets/migrate/04-stop-source.sh +85 -0
- package/assets/migrate/05-finalize-target.sh +140 -0
- package/assets/migrate/06-start-target.sh +57 -0
- package/assets/migrate/07-verify.sh +237 -0
- package/assets/migrate/08-rollback.sh +54 -0
- package/assets/migrate/lib.sh +149 -0
- package/assets/upgrade/10-preflight.sh +120 -0
- package/assets/upgrade/20-upgrade.sh +142 -0
- package/assets/upgrade/30-manual-upgrade.sh +129 -0
- package/assets/upgrade/40-storage-prune.sh +65 -0
- package/assets/upgrade/50-status.sh +58 -0
- package/assets/upgrade/lib.sh +232 -0
- package/bin/ovtools.js +32 -0
- package/dist/api/checks.d.ts +6 -0
- package/dist/api/checks.d.ts.map +1 -0
- package/dist/api/checks.js +173 -0
- package/dist/api/checks.js.map +1 -0
- package/dist/api/hostkeys.d.ts +10 -0
- package/dist/api/hostkeys.d.ts.map +1 -0
- package/dist/api/hostkeys.js +58 -0
- package/dist/api/hostkeys.js.map +1 -0
- package/dist/api/jobs.d.ts +33 -0
- package/dist/api/jobs.d.ts.map +1 -0
- package/dist/api/jobs.js +486 -0
- package/dist/api/jobs.js.map +1 -0
- package/dist/api/nodes.d.ts +16 -0
- package/dist/api/nodes.d.ts.map +1 -0
- package/dist/api/nodes.js +126 -0
- package/dist/api/nodes.js.map +1 -0
- package/dist/api/server.d.ts +3 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +443 -0
- package/dist/api/server.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +301 -0
- package/dist/cli.js.map +1 -0
- package/dist/constants.d.ts +76 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +150 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/base.d.ts +52 -0
- package/dist/orchestrator/base.d.ts.map +1 -0
- package/dist/orchestrator/base.js +219 -0
- package/dist/orchestrator/base.js.map +1 -0
- package/dist/orchestrator/deploy.d.ts +33 -0
- package/dist/orchestrator/deploy.d.ts.map +1 -0
- package/dist/orchestrator/deploy.js +313 -0
- package/dist/orchestrator/deploy.js.map +1 -0
- package/dist/orchestrator/manage.d.ts +28 -0
- package/dist/orchestrator/manage.d.ts.map +1 -0
- package/dist/orchestrator/manage.js +267 -0
- package/dist/orchestrator/manage.js.map +1 -0
- package/dist/orchestrator/migrate.d.ts +31 -0
- package/dist/orchestrator/migrate.d.ts.map +1 -0
- package/dist/orchestrator/migrate.js +442 -0
- package/dist/orchestrator/migrate.js.map +1 -0
- package/dist/ssh/client.d.ts +39 -0
- package/dist/ssh/client.d.ts.map +1 -0
- package/dist/ssh/client.js +418 -0
- package/dist/ssh/client.js.map +1 -0
- package/dist/test/core.test.d.ts +2 -0
- package/dist/test/core.test.d.ts.map +1 -0
- package/dist/test/core.test.js +188 -0
- package/dist/test/core.test.js.map +1 -0
- package/dist/types.d.ts +267 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/assets.d.ts +28 -0
- package/dist/utils/assets.d.ts.map +1 -0
- package/dist/utils/assets.js +583 -0
- package/dist/utils/assets.js.map +1 -0
- package/dist/utils/browser.d.ts +2 -0
- package/dist/utils/browser.d.ts.map +1 -0
- package/dist/utils/browser.js +23 -0
- package/dist/utils/browser.js.map +1 -0
- package/dist/utils/dashboard.d.ts +16 -0
- package/dist/utils/dashboard.d.ts.map +1 -0
- package/dist/utils/dashboard.js +177 -0
- package/dist/utils/dashboard.js.map +1 -0
- package/dist/utils/helpers.d.ts +29 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +204 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/scripts.d.ts +60 -0
- package/dist/utils/scripts.d.ts.map +1 -0
- package/dist/utils/scripts.js +174 -0
- package/dist/utils/scripts.js.map +1 -0
- package/dist/utils/state.d.ts +12 -0
- package/dist/utils/state.d.ts.map +1 -0
- package/dist/utils/state.js +44 -0
- package/dist/utils/state.js.map +1 -0
- package/dist/utils/tar.d.ts +11 -0
- package/dist/utils/tar.d.ts.map +1 -0
- package/dist/utils/tar.js +93 -0
- package/dist/utils/tar.js.map +1 -0
- package/dist/utils/update.d.ts +9 -0
- package/dist/utils/update.d.ts.map +1 -0
- package/dist/utils/update.js +134 -0
- package/dist/utils/update.js.map +1 -0
- package/dist/utils/websocket.d.ts +10 -0
- package/dist/utils/websocket.d.ts.map +1 -0
- package/dist/utils/websocket.js +203 -0
- package/dist/utils/websocket.js.map +1 -0
- package/package.json +55 -4
- package/public/app.js +2736 -0
- package/public/assets/v2.2/css/base.css +113 -0
- package/public/assets/v2.2/css/components/content.css +133 -0
- package/public/assets/v2.2/css/components/controls.css +229 -0
- package/public/assets/v2.2/css/components/data.css +373 -0
- package/public/assets/v2.2/css/components/icons.css +35 -0
- package/public/assets/v2.2/css/components/motion.css +57 -0
- package/public/assets/v2.2/css/components/shell.css +51 -0
- package/public/assets/v2.2/css/components/sidebar.css +242 -0
- package/public/assets/v2.2/css/components/topbar.css +138 -0
- package/public/assets/v2.2/css/fonts.css +30 -0
- package/public/assets/v2.2/css/synteq-ui-v2.css +25 -0
- package/public/assets/v2.2/css/theme-dark.css +38 -0
- package/public/assets/v2.2/css/theme-light.css +36 -0
- package/public/assets/v2.2/css/tokens.css +61 -0
- package/public/assets/v2.2/fonts/GoogleSansCode-Medium.ttf +0 -0
- package/public/assets/v2.2/fonts/GoogleSansCode-Regular.ttf +0 -0
- package/public/assets/v2.2/fonts/GoogleSansCode-SemiBold.ttf +0 -0
- package/public/assets/v2.2/js/synteq-ui-v2.js +869 -0
- package/public/favicon.svg +13 -0
- package/public/index.html +1083 -0
- package/public/styles.css +580 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ===================================================================
|
|
3
|
+
# 20-upgrade.sh - update the node with the OFFICIAL tool
|
|
4
|
+
#
|
|
5
|
+
# The upstream README ("How to update (if you are already a validator)") names one
|
|
6
|
+
# command that monitors the repo, checks the packages, builds a fresh binary,
|
|
7
|
+
# restarts the node and waits until it is guaranteed to be operational:
|
|
8
|
+
#
|
|
9
|
+
# sh controls/upgrade.sh # test the mechanics, changes nothing
|
|
10
|
+
# sh controls/upgrade.sh --apply # do it
|
|
11
|
+
#
|
|
12
|
+
# This step runs the test first (the README recommends checking first), then the
|
|
13
|
+
# apply, and reads the verdict from what the tool prints:
|
|
14
|
+
#
|
|
15
|
+
# validator_active | observer_synced -> the node is online, the binary is the
|
|
16
|
+
# one just built, the head is caught up
|
|
17
|
+
# pending -> do NOT restart, the chain/build is not
|
|
18
|
+
# ready yet: soft stop, re-run later
|
|
19
|
+
# refused -> the reason is in the output (FAILED)
|
|
20
|
+
#
|
|
21
|
+
# It NEVER runs `--sync`, never touches config/network.env and never re-enrolls.
|
|
22
|
+
#
|
|
23
|
+
# Usage: sudo bash 20-upgrade.sh
|
|
24
|
+
# Env: UPGRADE_APPLY (1) - 0 = only the test run
|
|
25
|
+
# UPGRADE_WAIT_SECONDS (900) - passed to --wait-seconds
|
|
26
|
+
# UPGRADE_EXTRA - extra flags for the tool, e.g.
|
|
27
|
+
# "--public-commit <sha> --source-commit <sha>", or
|
|
28
|
+
# "--unit octra-node.service" / "--user-unit"
|
|
29
|
+
# UPGRADE_TEST_TIMEOUT (1800) / UPGRADE_TIMEOUT (5400)
|
|
30
|
+
# ===================================================================
|
|
31
|
+
|
|
32
|
+
set -euo pipefail
|
|
33
|
+
source "$(dirname "$0")/lib.sh"
|
|
34
|
+
|
|
35
|
+
require_root
|
|
36
|
+
set_status RUNNING "upgrade"
|
|
37
|
+
|
|
38
|
+
APPLY="${UPGRADE_APPLY:-1}"
|
|
39
|
+
WAIT="${UPGRADE_WAIT_SECONDS:-900}"
|
|
40
|
+
EXTRA="${UPGRADE_EXTRA:-}"
|
|
41
|
+
TOOL_OUT="${UPGRADE_DIR}/upgrade-tool.out"
|
|
42
|
+
|
|
43
|
+
[[ -f "${UPGRADE_SH}" ]] || die "controls/upgrade.sh is missing on this node - use the manual update (fallback phase)"
|
|
44
|
+
|
|
45
|
+
ensure_tool git git || die "git is missing and could not be installed"
|
|
46
|
+
read_state
|
|
47
|
+
[[ "${PROCESS}" == "online" || -z "${PROCESS}" ]] || warn "the node process is ${PROCESS} - the tool will start/restart it"
|
|
48
|
+
|
|
49
|
+
BEFORE_COMMIT=$(source_commit)
|
|
50
|
+
BEFORE_HEAD=$(git_head)
|
|
51
|
+
log "=== update with the official tool: controls/upgrade.sh${EXTRA:+ ${EXTRA}} --wait-seconds ${WAIT} ==="
|
|
52
|
+
log "before : SOURCE_COMMIT=${BEFORE_COMMIT:-unknown} git HEAD=${BEFORE_HEAD:-unknown} role=${ROLE:-?} rpc=${RPC:-?}"
|
|
53
|
+
log "repository: $(git_remote)"
|
|
54
|
+
log "the node is NOT re-synced and NOT re-enrolled (upstream rule)"
|
|
55
|
+
|
|
56
|
+
: > "${TOOL_OUT}"
|
|
57
|
+
|
|
58
|
+
run_tool() { # run_tool <timeout> <command...> -> streams into the console + the log, returns the tool's rc
|
|
59
|
+
local limit="$1" rc=0
|
|
60
|
+
shift
|
|
61
|
+
set +e
|
|
62
|
+
timeout "${limit}" su - "${NODE_USER}" -c "cd ${NODE_SRC_DIR} && $*" 2>&1 \
|
|
63
|
+
| tee -a "${TOOL_OUT}" | sed 's/^/ /'
|
|
64
|
+
rc=${PIPESTATUS[0]}
|
|
65
|
+
set -e
|
|
66
|
+
return "${rc}"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# --- 1. the test run (changes nothing) ---------------------------------
|
|
70
|
+
log "--- test run: sh controls/upgrade.sh (nothing is rebuilt or restarted) ---"
|
|
71
|
+
TEST_RC=0
|
|
72
|
+
run_tool "${UPGRADE_TEST_TIMEOUT:-1800}" "sh controls/upgrade.sh" || TEST_RC=$?
|
|
73
|
+
TEST_VERDICT=$(upgrade_verdict "${TOOL_OUT}")
|
|
74
|
+
if (( TEST_RC != 0 )); then
|
|
75
|
+
REASON=$(upgrade_reason "${TOOL_OUT}")
|
|
76
|
+
if [[ "${TEST_VERDICT}" == "pending" ]]; then
|
|
77
|
+
warn "the tool reports 'pending'${REASON:+ - ${REASON}}"
|
|
78
|
+
warn "do NOT restart the node manually: re-run this phase once the tool can finish"
|
|
79
|
+
set_status WAITING-UPGRADE "the test run is pending${REASON:+ - ${REASON}} - re-run the update later"
|
|
80
|
+
exit 2
|
|
81
|
+
fi
|
|
82
|
+
die "the test run refused (exit ${TEST_RC})${REASON:+: ${REASON}} - nothing was changed; see the output above"
|
|
83
|
+
fi
|
|
84
|
+
log "the test run passed${TEST_VERDICT:+ (${TEST_VERDICT})}"
|
|
85
|
+
|
|
86
|
+
if [[ "${APPLY}" != "1" ]]; then
|
|
87
|
+
log "UPGRADE_APPLY=0: test only - the node is untouched"
|
|
88
|
+
set_status DONE "test-only (SOURCE_COMMIT=${BEFORE_COMMIT:-unknown})"
|
|
89
|
+
exit 0
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# --- 2. apply -----------------------------------------------------------
|
|
93
|
+
# shellcheck disable=SC2086
|
|
94
|
+
ARGS="--apply --wait-seconds ${WAIT} ${EXTRA}"
|
|
95
|
+
log "--- apply: sh controls/upgrade.sh ${ARGS} (pull + build + restart + wait) ---"
|
|
96
|
+
APPLY_RC=0
|
|
97
|
+
run_tool "${UPGRADE_TIMEOUT:-5400}" "sh controls/upgrade.sh ${ARGS}" || APPLY_RC=$?
|
|
98
|
+
VERDICT=$(upgrade_verdict "${TOOL_OUT}")
|
|
99
|
+
REASON=$(upgrade_reason "${TOOL_OUT}")
|
|
100
|
+
|
|
101
|
+
case "${VERDICT}" in
|
|
102
|
+
pending)
|
|
103
|
+
warn "the tool reports 'pending'${REASON:+ - ${REASON}}"
|
|
104
|
+
warn "do NOT restart the node manually (upstream) - re-run this phase later"
|
|
105
|
+
set_status WAITING-UPGRADE "status pending${REASON:+ - ${REASON}} - re-run the update later"
|
|
106
|
+
exit 2
|
|
107
|
+
;;
|
|
108
|
+
refused)
|
|
109
|
+
die "the tool refused the update${REASON:+: ${REASON}} - see the output above"
|
|
110
|
+
;;
|
|
111
|
+
esac
|
|
112
|
+
|
|
113
|
+
# --- 3. verify what is running now -------------------------------------
|
|
114
|
+
AFTER_COMMIT=$(source_commit)
|
|
115
|
+
AFTER_HEAD=$(git_head)
|
|
116
|
+
read_state
|
|
117
|
+
log "after : SOURCE_COMMIT=${AFTER_COMMIT:-unknown} git HEAD=${AFTER_HEAD:-unknown} role=${ROLE:-?} process=${PROCESS:-?} rpc=${RPC:-?} voting=${VOTING:-?} epoch=${EPOCH:-?}"
|
|
118
|
+
log "binary : ${BINARY:-unknown}${PVAC:+ pvac ${PVAC}}"
|
|
119
|
+
|
|
120
|
+
if [[ "${PROCESS}" != "online" || "${RPC}" != "ready" ]]; then
|
|
121
|
+
warn "the node is not back yet (process=${PROCESS:-?} rpc=${RPC:-?})"
|
|
122
|
+
warn "check it with: su - ${NODE_USER} -c 'cd ${NODE_SRC_DIR} && sh controls/stat.sh --logs'"
|
|
123
|
+
set_status WAITING-UPGRADE "the update ran but the node is not ready yet (process=${PROCESS:-?} rpc=${RPC:-?}) - re-run the update or read stat.sh --logs"
|
|
124
|
+
exit 2
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
if (( APPLY_RC != 0 )); then
|
|
128
|
+
warn "the tool exited ${APPLY_RC} but the node is online as ${ROLE:-?}${VERDICT:+ (verdict ${VERDICT})}"
|
|
129
|
+
fi
|
|
130
|
+
if [[ -n "${AFTER_COMMIT}" && -n "${AFTER_HEAD}" && "${AFTER_COMMIT}" != "${AFTER_HEAD}" ]]; then
|
|
131
|
+
warn "SOURCE_COMMIT (${AFTER_COMMIT}) does not match git HEAD (${AFTER_HEAD}) - check the checkout"
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
if [[ -z "${VERDICT}" ]]; then
|
|
135
|
+
if [[ "${ACTIVE}" == "true" ]]; then VERDICT="validator_active"; else VERDICT="observer_synced"; fi
|
|
136
|
+
fi
|
|
137
|
+
if [[ "${ACTIVE}" == "true" ]]; then
|
|
138
|
+
log "=== the node is an ACTIVE validator again, running the binary it just built ==="
|
|
139
|
+
else
|
|
140
|
+
log "=== the node is online and synced (observer) with the freshly built binary ==="
|
|
141
|
+
fi
|
|
142
|
+
set_status DONE "verdict=${VERDICT} commit=${AFTER_HEAD:-unknown} role=${ROLE:-?} active=${ACTIVE:-?} epoch=${EPOCH:-?}"
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ===================================================================
|
|
3
|
+
# 30-manual-upgrade.sh - the documented MANUAL update (fallback)
|
|
4
|
+
#
|
|
5
|
+
# Upstream README, "Manual update (when the tool cannot run)":
|
|
6
|
+
#
|
|
7
|
+
# sudo -iu octra
|
|
8
|
+
# cd /opt/octra/libv_litecore
|
|
9
|
+
# git pull --ff-only
|
|
10
|
+
# cat SOURCE_COMMIT
|
|
11
|
+
# sh controls/check.sh
|
|
12
|
+
# SWITCH="$PWD/runtime_data/toolchains/ocaml"
|
|
13
|
+
# make -C mcl MCL_FP_BIT=256 MCL_FR_BIT=256 lib/libmcl.a
|
|
14
|
+
# opam exec --switch "$SWITCH" -- dune build --profile release \
|
|
15
|
+
# bin/octra_node.exe bin/octra_pvac_worker.exe \
|
|
16
|
+
# bin/octra_state_sync_client.exe bin/octra_state_sync_manifest.exe \
|
|
17
|
+
# bin/bft_control_tx.exe
|
|
18
|
+
# sh controls/stop.sh
|
|
19
|
+
# sh controls/run.sh --rebind-runtime
|
|
20
|
+
# sh controls/stat.sh
|
|
21
|
+
#
|
|
22
|
+
# Every command runs as the node user from the node directory (the checkout and
|
|
23
|
+
# the opam switch belong to it). This step NEVER runs `--sync`, never edits
|
|
24
|
+
# config/network.env and never re-enrolls - the node keeps its identity and its
|
|
25
|
+
# data, only the binary is replaced and the process restarted.
|
|
26
|
+
#
|
|
27
|
+
# Usage: sudo bash 30-manual-upgrade.sh
|
|
28
|
+
# Env: MANUAL_APPLY (1) - 0 = pull + check + build only (no stop/run)
|
|
29
|
+
# PULL_TIMEOUT (600) / CHECK_TIMEOUT (300) / MAKE_TIMEOUT (1800)
|
|
30
|
+
# BUILD_TIMEOUT (5400) / STOP_TIMEOUT (180) / RUN_TIMEOUT (900)
|
|
31
|
+
# ===================================================================
|
|
32
|
+
|
|
33
|
+
set -euo pipefail
|
|
34
|
+
source "$(dirname "$0")/lib.sh"
|
|
35
|
+
|
|
36
|
+
require_root
|
|
37
|
+
set_status RUNNING "manual-upgrade"
|
|
38
|
+
|
|
39
|
+
APPLY="${MANUAL_APPLY:-1}"
|
|
40
|
+
BUILD_LOG="${UPGRADE_DIR}/manual-build.out"
|
|
41
|
+
|
|
42
|
+
[[ -d "${NODE_SRC_DIR}/.git" ]] || die "${NODE_SRC_DIR} is not a git checkout - cannot pull"
|
|
43
|
+
[[ -f "${NODE_ENV}" ]] || die "node.env is missing (${NODE_ENV}) - this is not the node host"
|
|
44
|
+
|
|
45
|
+
ensure_build_tools
|
|
46
|
+
|
|
47
|
+
# the opam switch the toolchain step built (upstream: $PWD/runtime_data/toolchains/ocaml)
|
|
48
|
+
SWITCH="$(ocaml_switch_root 2>/dev/null || printf '%s' "${NODE_SRC_DIR}/runtime_data/toolchains/ocaml")"
|
|
49
|
+
[[ -d "${SWITCH}/_opam/.opam-switch" ]] || die "the opam switch is not built (${SWITCH}/_opam/.opam-switch missing) - run the toolchain step (scripts/deploy/20-install-toolchain.sh) first"
|
|
50
|
+
|
|
51
|
+
BEFORE_COMMIT=$(source_commit)
|
|
52
|
+
BEFORE_HEAD=$(git_head)
|
|
53
|
+
log "=== manual update on $(hostname) ==="
|
|
54
|
+
log "before : SOURCE_COMMIT=${BEFORE_COMMIT:-unknown} git HEAD=${BEFORE_HEAD:-unknown}"
|
|
55
|
+
log "opam switch: ${SWITCH}"
|
|
56
|
+
log "the node is NOT re-synced and NOT re-enrolled (upstream rule)"
|
|
57
|
+
|
|
58
|
+
run_as_node() { # run_as_node <timeout> <label> <command...>
|
|
59
|
+
local limit="$1" label="$2" rc=0
|
|
60
|
+
shift 2
|
|
61
|
+
log "--- ${label} ---"
|
|
62
|
+
set +e
|
|
63
|
+
timeout "${limit}" su - "${NODE_USER}" -c "cd ${NODE_SRC_DIR} && $*" 2>&1 \
|
|
64
|
+
| tee -a "${BUILD_LOG}" | sed 's/^/ /'
|
|
65
|
+
rc=${PIPESTATUS[0]}
|
|
66
|
+
set -e
|
|
67
|
+
return "${rc}"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
: > "${BUILD_LOG}"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# --- 1. pull + verify --------------------------------------------------
|
|
74
|
+
run_as_node "${PULL_TIMEOUT:-600}" "git pull --ff-only" "git pull --ff-only" \
|
|
75
|
+
|| die "git pull failed - see the output above (a dirty tree or a diverged branch stops here)"
|
|
76
|
+
|
|
77
|
+
AFTER_COMMIT=$(source_commit)
|
|
78
|
+
AFTER_HEAD=$(git_head)
|
|
79
|
+
log "after the pull: SOURCE_COMMIT=${AFTER_COMMIT:-unknown} git HEAD=${AFTER_HEAD:-unknown}"
|
|
80
|
+
|
|
81
|
+
if [[ -f "${CHECK_SH}" ]]; then
|
|
82
|
+
run_as_node "${CHECK_TIMEOUT:-300}" "controls/check.sh (verify the package)" "sh controls/check.sh" \
|
|
83
|
+
|| die "controls/check.sh reported a problem - fix it before building"
|
|
84
|
+
else
|
|
85
|
+
warn "controls/check.sh is missing - skipping the package verification"
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# --- 2. build ----------------------------------------------------------
|
|
89
|
+
run_as_node "${MAKE_TIMEOUT:-1800}" "make -C mcl (MCL_FP_BIT=256 MCL_FR_BIT=256)" \
|
|
90
|
+
"make -C mcl MCL_FP_BIT=256 MCL_FR_BIT=256 lib/libmcl.a" \
|
|
91
|
+
|| die "the mcl library did not build - see the output above"
|
|
92
|
+
|
|
93
|
+
run_as_node "${BUILD_TIMEOUT:-5400}" "dune build --profile release (node + pvac + sync + bft)" \
|
|
94
|
+
"opam exec --switch '${SWITCH}' -- dune build --profile release bin/octra_node.exe bin/octra_pvac_worker.exe bin/octra_state_sync_client.exe bin/octra_state_sync_manifest.exe bin/bft_control_tx.exe" \
|
|
95
|
+
|| die "the dune build failed - see the output above (the running node is untouched so far)"
|
|
96
|
+
|
|
97
|
+
log "the build finished - the node is still running the old binary"
|
|
98
|
+
|
|
99
|
+
if [[ "${APPLY}" != "1" ]]; then
|
|
100
|
+
log "MANUAL_APPLY=0: build only - the node was not restarted"
|
|
101
|
+
set_status DONE "build-only commit=${AFTER_HEAD:-unknown} (node still on the old binary)"
|
|
102
|
+
exit 0
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# --- 3. restart on the fresh binary ------------------------------------
|
|
106
|
+
run_as_node "${STOP_TIMEOUT:-180}" "controls/stop.sh" "sh controls/stop.sh" \
|
|
107
|
+
|| die "controls/stop.sh failed - the node may still be running; check it before retrying"
|
|
108
|
+
|
|
109
|
+
run_as_node "${RUN_TIMEOUT:-900}" "controls/run.sh --rebind-runtime" "sh controls/run.sh --rebind-runtime" \
|
|
110
|
+
|| warn "controls/run.sh reported an error - checking the node state anyway"
|
|
111
|
+
|
|
112
|
+
read_state
|
|
113
|
+
log "node after the restart: role=${ROLE:-?} process=${PROCESS:-?} rpc=${RPC:-?} voting=${VOTING:-?} epoch=${EPOCH:-?}"
|
|
114
|
+
log "binary : ${BINARY:-unknown}${PVAC:+ pvac ${PVAC}}"
|
|
115
|
+
|
|
116
|
+
if [[ "${PROCESS}" != "online" ]]; then
|
|
117
|
+
warn "the node process is ${PROCESS:-unknown} - the restart did not come up"
|
|
118
|
+
warn "read the log: su - ${NODE_USER} -c 'cd ${NODE_SRC_DIR} && sh controls/stat.sh --logs'"
|
|
119
|
+
set_status WAITING-UPGRADE "the manual build finished but the node is ${PROCESS:-unknown} - check stat.sh --logs"
|
|
120
|
+
exit 2
|
|
121
|
+
fi
|
|
122
|
+
if [[ "${RPC}" != "ready" ]]; then
|
|
123
|
+
warn "the node is online but its rpc is ${RPC:-unknown} - it is probably replaying; re-run to re-check"
|
|
124
|
+
set_status WAITING-RPC "the node is online again but rpc=${RPC:-unknown} - re-run the manual update to re-check"
|
|
125
|
+
exit 2
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
log "=== the node is back on the freshly built binary ==="
|
|
129
|
+
set_status DONE "manual-upgrade commit=${AFTER_HEAD:-unknown} role=${ROLE:-?} active=${ACTIVE:-?} epoch=${EPOCH:-?}"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ===================================================================
|
|
3
|
+
# 40-storage-prune.sh - "Remove preserved states" (upstream README)
|
|
4
|
+
#
|
|
5
|
+
# sh controls/storage.sh # report
|
|
6
|
+
# sh controls/storage.sh --prune-prior --yes # drop the previous states
|
|
7
|
+
# sh controls/storage.sh # report again
|
|
8
|
+
#
|
|
9
|
+
# A node keeps the states of the previous epochs ("prior"/preserved states) so it
|
|
10
|
+
# can serve peers that lag behind; they grow until the store is oversized. The
|
|
11
|
+
# documented maintenance is to drop them from time to time - which is also what
|
|
12
|
+
# the daily prune job on this host now does (dashboard/prune-node-junk.sh).
|
|
13
|
+
#
|
|
14
|
+
# Read-only when PRUNE_APPLY=0. Nothing else on the node is touched: no sync, no
|
|
15
|
+
# re-enroll, the node keeps running.
|
|
16
|
+
#
|
|
17
|
+
# Usage: sudo bash 40-storage-prune.sh
|
|
18
|
+
# Env: PRUNE_APPLY (1) - 0 = report only
|
|
19
|
+
# PRUNE_TIMEOUT (900) / STORAGE_TIMEOUT (180)
|
|
20
|
+
# ===================================================================
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
source "$(dirname "$0")/lib.sh"
|
|
24
|
+
|
|
25
|
+
require_root
|
|
26
|
+
set_status RUNNING "storage-prune"
|
|
27
|
+
|
|
28
|
+
APPLY="${PRUNE_APPLY:-1}"
|
|
29
|
+
[[ -f "${STORAGE_SH}" ]] || die "controls/storage.sh is missing on this node - update the node first (the tool does not exist on this version)"
|
|
30
|
+
|
|
31
|
+
log "=== preserved states on $(hostname) ==="
|
|
32
|
+
log "--- storage before ---"
|
|
33
|
+
BEFORE=$(storage_report)
|
|
34
|
+
printf '%s\n' "${BEFORE}" | sed 's/^/ /'
|
|
35
|
+
BEFORE_LINE=$(printf '%s\n' "${BEFORE}" | grep -iE 'preserved|reclaim|prior' | tail -1 || true)
|
|
36
|
+
|
|
37
|
+
if [[ "${APPLY}" != "1" ]]; then
|
|
38
|
+
log "PRUNE_APPLY=0: report only - nothing was pruned"
|
|
39
|
+
set_status DONE "report-only${BEFORE_LINE:+ - ${BEFORE_LINE}}"
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
read_state
|
|
44
|
+
log "node while pruning: process=${PROCESS:-?} rpc=${RPC:-?} role=${ROLE:-?} epoch=${EPOCH:-?}"
|
|
45
|
+
|
|
46
|
+
log "--- storage.sh --prune-prior --yes ---"
|
|
47
|
+
RC=0
|
|
48
|
+
OUT=$(prune_states) || RC=$?
|
|
49
|
+
printf '%s\n' "${OUT}" | sed 's/^/ /'
|
|
50
|
+
if (( RC != 0 )); then
|
|
51
|
+
REASON=$(printf '%s\n' "${OUT}" | grep -aiE 'error|refus|denied|not |missing|failed' | tail -1 || true)
|
|
52
|
+
die "controls/storage.sh --prune-prior refused (exit ${RC})${REASON:+: ${REASON}}"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
log "--- storage after ---"
|
|
56
|
+
AFTER=$(storage_report)
|
|
57
|
+
printf '%s\n' "${AFTER}" | sed 's/^/ /'
|
|
58
|
+
AFTER_LINE=$(printf '%s\n' "${AFTER}" | grep -iE 'preserved|reclaim|prior' | tail -1 || true)
|
|
59
|
+
|
|
60
|
+
read_state
|
|
61
|
+
log "node after pruning: process=${PROCESS:-?} rpc=${RPC:-?} role=${ROLE:-?} epoch=${EPOCH:-?}"
|
|
62
|
+
[[ "${PROCESS}" == "online" ]] || warn "the node process is ${PROCESS:-unknown} - check it with stat.sh --logs"
|
|
63
|
+
|
|
64
|
+
log "=== preserved states pruned ==="
|
|
65
|
+
set_status DONE "${AFTER_LINE:-pruned}${BEFORE_LINE:+ (before: ${BEFORE_LINE})}"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ===================================================================
|
|
3
|
+
# 50-status.sh - versions + storage of the running node (read-only)
|
|
4
|
+
#
|
|
5
|
+
# Prints what the console shows for the update program: the commit the checkout
|
|
6
|
+
# says it is (SOURCE_COMMIT), the git HEAD/branch (and whether the tree is dirty),
|
|
7
|
+
# the hashes of the BINARY that is actually running (stat.sh) and the storage
|
|
8
|
+
# report of the node's own tool. Nothing is pulled, built or restarted.
|
|
9
|
+
#
|
|
10
|
+
# Usage: sudo bash 50-status.sh
|
|
11
|
+
# ===================================================================
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
source "$(dirname "$0")/lib.sh"
|
|
15
|
+
|
|
16
|
+
require_root
|
|
17
|
+
set_status RUNNING "status"
|
|
18
|
+
|
|
19
|
+
ensure_tool git git || die "git is missing and could not be installed"
|
|
20
|
+
ensure_tool jq jq || warn "jq is missing - the wallet address cannot be read"
|
|
21
|
+
|
|
22
|
+
COMMIT=$(source_commit)
|
|
23
|
+
HEAD=$(git_head)
|
|
24
|
+
BRANCH=$(git_branch)
|
|
25
|
+
DIRTY=$(git_dirty)
|
|
26
|
+
REMOTE=$(git_remote)
|
|
27
|
+
read_state
|
|
28
|
+
ADDR=$(wallet_address || echo unknown)
|
|
29
|
+
|
|
30
|
+
log "=== update status: $(hostname) ==="
|
|
31
|
+
log "wallet : ${ADDR}"
|
|
32
|
+
log "repository: ${REMOTE}"
|
|
33
|
+
log "checkout : SOURCE_COMMIT=${COMMIT:-unknown} git HEAD=${HEAD:-unknown}${BRANCH:+ on ${BRANCH}}${DIRTY:+ (dirty working tree)}"
|
|
34
|
+
if [[ -n "${COMMIT}" && -n "${HEAD}" && "${COMMIT}" != "${HEAD}" ]]; then
|
|
35
|
+
log " SOURCE_COMMIT and git HEAD differ - the checkout was rebuilt from another commit"
|
|
36
|
+
fi
|
|
37
|
+
log "running : role=${ROLE:-?} process=${PROCESS:-?} rpc=${RPC:-?} voting=${VOTING:-?} epoch=${EPOCH:-?} uptime=${PROCESS_UP:-?}"
|
|
38
|
+
log "binary : ${BINARY:-unknown}"
|
|
39
|
+
log "pvac : ${PVAC:-unknown}"
|
|
40
|
+
log "membership: active=${ACTIVE:-?} scheduled=${SCHED:-?} enrollment=${ENROLL:-?}"
|
|
41
|
+
|
|
42
|
+
if [[ -f "${STORAGE_SH}" ]]; then
|
|
43
|
+
log "--- controls/storage.sh ---"
|
|
44
|
+
STORE=$(storage_report)
|
|
45
|
+
printf '%s\n' "${STORE}" | sed 's/^/ /'
|
|
46
|
+
STORAGE_LINE=$(storage_fields)
|
|
47
|
+
else
|
|
48
|
+
warn "controls/storage.sh is missing - this node version has no storage tool"
|
|
49
|
+
STORAGE_LINE=""
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
if [[ -f "${UPGRADE_SH}" ]]; then
|
|
53
|
+
log "official tool: controls/upgrade.sh present (sh controls/upgrade.sh / --apply)"
|
|
54
|
+
else
|
|
55
|
+
warn "controls/upgrade.sh is missing - use the manual update (fallback)"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
set_status DONE "commit=${HEAD:-unknown}${BRANCH:+ on ${BRANCH}} role=${ROLE:-?} active=${ACTIVE:-?}${STORAGE_LINE:+ - ${STORAGE_LINE}}"
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ===================================================================
|
|
3
|
+
# scripts/upgrade/lib.sh - shared helpers for the UPDATE-NODE actions
|
|
4
|
+
#
|
|
5
|
+
# The update actions of the console's "Manage active node" block (they are not a
|
|
6
|
+
# tab of their own since 2026-11-05): they do not create, move or operate the
|
|
7
|
+
# validator - they UPDATE the node that is already running, exactly as the
|
|
8
|
+
# upstream README describes ("How to update (if you are already a validator)"):
|
|
9
|
+
#
|
|
10
|
+
# * the official tool: controls/upgrade.sh (test, changes nothing)
|
|
11
|
+
# controls/upgrade.sh --apply (pull, build, restart,
|
|
12
|
+
# wait, verify)
|
|
13
|
+
# * the manual fallback: git pull --ff-only -> controls/check.sh -> make -C mcl
|
|
14
|
+
# -> dune build -> controls/stop.sh -> controls/run.sh
|
|
15
|
+
# --rebind-runtime -> controls/stat.sh
|
|
16
|
+
# * housekeeping: controls/storage.sh [--prune-prior --yes]
|
|
17
|
+
# ("Remove preserved states")
|
|
18
|
+
#
|
|
19
|
+
# NEVER (upstream, in capitals): do not run `--sync` again, do not change
|
|
20
|
+
# config/network.env, do not re-enroll the node. Every step here only pulls,
|
|
21
|
+
# builds, restarts and reads.
|
|
22
|
+
#
|
|
23
|
+
# /root/upgrade/ this program (/root/deploy, /root/migration, /root/manage)
|
|
24
|
+
# ===================================================================
|
|
25
|
+
set -euo pipefail
|
|
26
|
+
|
|
27
|
+
# Tool policy (check -> install -> continue) lives in scripts/config.sh, which is
|
|
28
|
+
# pushed to /root/config.sh next to these scripts.
|
|
29
|
+
CONFIG_FILE="${CONFIG_FILE:-/root/config.sh}"
|
|
30
|
+
if [[ -f "${CONFIG_FILE}" ]]; then
|
|
31
|
+
# shellcheck disable=SC1090
|
|
32
|
+
source "${CONFIG_FILE}"
|
|
33
|
+
fi
|
|
34
|
+
if ! declare -F ensure_tool >/dev/null 2>&1; then
|
|
35
|
+
ensure_tool() { command -v "$1" >/dev/null 2>&1 || die "tool $1 is missing and ${CONFIG_FILE} cannot install it (push the scripts again)"; }
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
UPGRADE_DIR="${UPGRADE_DIR:-/root/upgrade}"
|
|
39
|
+
UPGRADE_LOG="${UPGRADE_LOG:-${UPGRADE_DIR}/upgrade.log}"
|
|
40
|
+
UPGRADE_STATUS="${UPGRADE_STATUS:-${UPGRADE_DIR}/status}"
|
|
41
|
+
|
|
42
|
+
NODE_SRC_DIR="${NODE_SRC_DIR:-/opt/octra/libv_litecore}"
|
|
43
|
+
NODE_DATA_ROOT="${NODE_DATA_ROOT:-/var/lib/octra}"
|
|
44
|
+
NODE_DATA_DIR="${NODE_DATA_DIR:-${NODE_DATA_ROOT}/devnet}"
|
|
45
|
+
NODE_WALLET="${NODE_WALLET:-${NODE_SRC_DIR}/.keys/validator/wallet.json}"
|
|
46
|
+
NODE_ENV="${NODE_ENV:-${NODE_SRC_DIR}/.keys/validator/node.env}"
|
|
47
|
+
NODE_USER="${NODE_USER:-octra}"
|
|
48
|
+
NODE_LOG="${NODE_LOG:-${NODE_SRC_DIR}/data/operator_logs/node.log}"
|
|
49
|
+
# the control scripts the upstream README names
|
|
50
|
+
UPGRADE_SH="${UPGRADE_SH:-${NODE_SRC_DIR}/controls/upgrade.sh}"
|
|
51
|
+
STORAGE_SH="${STORAGE_SH:-${NODE_SRC_DIR}/controls/storage.sh}"
|
|
52
|
+
CHECK_SH="${CHECK_SH:-${NODE_SRC_DIR}/controls/check.sh}"
|
|
53
|
+
STOP_SH="${STOP_SH:-${NODE_SRC_DIR}/controls/stop.sh}"
|
|
54
|
+
RUN_SH="${RUN_SH:-${NODE_SRC_DIR}/controls/run.sh}"
|
|
55
|
+
# where SOURCE_COMMIT lives in the checkout (upstream ships it)
|
|
56
|
+
SOURCE_COMMIT_FILE="${SOURCE_COMMIT_FILE:-${NODE_SRC_DIR}/SOURCE_COMMIT}"
|
|
57
|
+
|
|
58
|
+
mkdir -p "${UPGRADE_DIR}"
|
|
59
|
+
|
|
60
|
+
log() { echo -e "[upgrade] $*" | tee -a "${UPGRADE_LOG}"; }
|
|
61
|
+
warn() { echo -e "[warn] $*" | tee -a "${UPGRADE_LOG}" >&2; }
|
|
62
|
+
err() { echo -e "[err] $*" | tee -a "${UPGRADE_LOG}" >&2; }
|
|
63
|
+
|
|
64
|
+
set_status() { # set_status <STATE> [detail...] - read by the Windows console
|
|
65
|
+
local state="$1" detail
|
|
66
|
+
shift || true
|
|
67
|
+
detail="$*"
|
|
68
|
+
printf '%s %s %s\n' "${state}" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "${detail}" > "${UPGRADE_STATUS}"
|
|
69
|
+
log "status = ${state} ${detail}"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
die() { err "$*"; set_status FAILED "$*"; exit 1; }
|
|
73
|
+
|
|
74
|
+
require_root() { [[ $EUID -eq 0 ]] || die "run as root"; }
|
|
75
|
+
|
|
76
|
+
# A step must never die leaving status = RUNNING: the console follows this file.
|
|
77
|
+
_upgrade_on_err() {
|
|
78
|
+
local rc="$1" line="$2" cmd="$3" state
|
|
79
|
+
state=$(awk 'NR==1 {print $1}' "${UPGRADE_STATUS}" 2>/dev/null || true)
|
|
80
|
+
case "${state}" in
|
|
81
|
+
DONE|FAILED|WAITING-*) return 0 ;;
|
|
82
|
+
esac
|
|
83
|
+
err "unexpected failure (exit ${rc}) at line ${line}: ${cmd}"
|
|
84
|
+
set_status FAILED "line ${line}: ${cmd} (exit ${rc})"
|
|
85
|
+
}
|
|
86
|
+
trap '_upgrade_on_err "$?" "$LINENO" "$BASH_COMMAND"' ERR
|
|
87
|
+
|
|
88
|
+
# --- the node's own controls (always as the octra user) ---------------
|
|
89
|
+
as_octra() { su - "${NODE_USER}" -c "$*"; }
|
|
90
|
+
|
|
91
|
+
# node_script <timeout> <command...>: run one of the node's control scripts from
|
|
92
|
+
# the node directory as the node user, bounded so a control script that waits on
|
|
93
|
+
# the chain can never freeze a step. stdout+stderr are merged (what the operator
|
|
94
|
+
# needs to read).
|
|
95
|
+
node_script() {
|
|
96
|
+
local limit="$1"
|
|
97
|
+
shift
|
|
98
|
+
timeout "${limit}" su - "${NODE_USER}" -c "cd ${NODE_SRC_DIR} && $*" 2>&1
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# like node_script, but the caller decides what a non-zero exit means
|
|
102
|
+
node_script_rc() { # node_script_rc <timeout> <command...> -> prints output, returns the rc
|
|
103
|
+
local limit="$1" rc
|
|
104
|
+
shift
|
|
105
|
+
set +e
|
|
106
|
+
timeout "${limit}" su - "${NODE_USER}" -c "cd ${NODE_SRC_DIR} && $*" 2>&1
|
|
107
|
+
rc=$?
|
|
108
|
+
set -e
|
|
109
|
+
return "${rc}"
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
stat_raw() { node_script "${STATE_TIMEOUT:-60}" "sh controls/stat.sh" || true; }
|
|
113
|
+
|
|
114
|
+
stat_field() { # an unreadable field is EMPTY, not the string "None" (see deploy/lib.sh)
|
|
115
|
+
awk -F' = ' -v k="$1" '$1 == k { if ($2 == "None" || $2 == "null") { print ""; exit } print $2; exit }'
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# read_state: the fields every step here cares about (never writes anything on the
|
|
119
|
+
# node - stat.sh is read-only)
|
|
120
|
+
read_state() {
|
|
121
|
+
SNAP=$(stat_raw)
|
|
122
|
+
ROLE=$(printf '%s\n' "${SNAP}" | stat_field role)
|
|
123
|
+
PROCESS=$(printf '%s\n' "${SNAP}" | stat_field process)
|
|
124
|
+
RPC=$(printf '%s\n' "${SNAP}" | stat_field rpc)
|
|
125
|
+
VOTING=$(printf '%s\n' "${SNAP}" | stat_field voting)
|
|
126
|
+
EPOCH=$(printf '%s\n' "${SNAP}" | stat_field epoch)
|
|
127
|
+
ACTIVE=$(printf '%s\n' "${SNAP}" | stat_field validator_active)
|
|
128
|
+
SCHED=$(printf '%s\n' "${SNAP}" | stat_field validator_scheduled)
|
|
129
|
+
ENROLL=$(printf '%s\n' "${SNAP}" | stat_field validator_enrollment)
|
|
130
|
+
BINARY=$(printf '%s\n' "${SNAP}" | stat_field binary)
|
|
131
|
+
PVAC=$(printf '%s\n' "${SNAP}" | stat_field pvac_worker)
|
|
132
|
+
PROCESS_UP=$(printf '%s\n' "${SNAP}" | stat_field uptime)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# --- the checkout: what is really there -------------------------------
|
|
136
|
+
# The clone belongs to the node user, so `git` as root refuses with "dubious
|
|
137
|
+
# ownership": ask with an explicit safe.directory (same as deploy/lib.sh).
|
|
138
|
+
git_node() { # git_node <args...>
|
|
139
|
+
git -c safe.directory="${NODE_SRC_DIR}" -C "${NODE_SRC_DIR}" "$@" 2>/dev/null || true
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
source_commit() { # the commit the checkout SAYS it is (upstream file)
|
|
143
|
+
local out=""
|
|
144
|
+
[[ -f "${SOURCE_COMMIT_FILE}" ]] && out=$(head -c 64 "${SOURCE_COMMIT_FILE}" 2>/dev/null | tr -d '[:space:]' || true)
|
|
145
|
+
printf '%s' "${out}"
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
git_head() { git_node rev-parse --short HEAD | head -1; }
|
|
149
|
+
git_branch() {
|
|
150
|
+
local out
|
|
151
|
+
out=$(git_node rev-parse --abbrev-ref HEAD | head -1)
|
|
152
|
+
[[ "${out}" == "HEAD" ]] && out=""
|
|
153
|
+
printf '%s' "${out}"
|
|
154
|
+
}
|
|
155
|
+
git_dirty() { # 1 when the working tree has local changes (a build might depend on them)
|
|
156
|
+
local out
|
|
157
|
+
out=$(git_node status --porcelain | head -1)
|
|
158
|
+
[[ -n "${out}" ]] && printf '1'
|
|
159
|
+
return 0
|
|
160
|
+
}
|
|
161
|
+
git_remote() {
|
|
162
|
+
local out
|
|
163
|
+
out=$(git_node config --get remote.origin.url | head -1)
|
|
164
|
+
printf '%s' "${out:-https://github.com/octra-labs/lite_node.git}"
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
# --- tools the two update paths need ----------------------------------
|
|
168
|
+
ensure_build_tools() {
|
|
169
|
+
ensure_tool git git || die "git is missing and could not be installed"
|
|
170
|
+
ensure_tool make make || die "make is missing and could not be installed"
|
|
171
|
+
ensure_tool opam opam || die "opam is missing and could not be installed"
|
|
172
|
+
# the manual build compiles the C++/mcl part and needs a compiler
|
|
173
|
+
if ! command -v g++ >/dev/null 2>&1 && ! command -v c++ >/dev/null 2>&1; then
|
|
174
|
+
ensure_package build-essential || true
|
|
175
|
+
fi
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
# --- storage.sh (preserved states) ------------------------------------
|
|
179
|
+
storage_report() { # read-only: what the store holds right now
|
|
180
|
+
node_script "${STORAGE_TIMEOUT:-180}" "sh controls/storage.sh" || true
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
storage_summary() { # one line out of the report, for the status detail
|
|
184
|
+
# optional text: a report this version does not match must never fail the caller
|
|
185
|
+
storage_report | grep -iE 'preserved|reclaim|prior|free|used|total' | tail -3 \
|
|
186
|
+
| tr '\n' ' ' | sed 's/ */ /g' || true
|
|
187
|
+
return 0
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
# The report is emitted as `event = storage data_bytes = ... prior_count = ...`
|
|
191
|
+
# lines; the status detail only needs the few numbers that matter. Like
|
|
192
|
+
# storage_summary this is OPTIONAL text and must never return non-zero.
|
|
193
|
+
storage_fields() {
|
|
194
|
+
storage_report | grep -oE '(prior_count|prior_bytes|free_bytes|data_bytes) = [0-9]+' \
|
|
195
|
+
| tr '\n' ' ' | sed -e 's/ = /=/g' -e 's/ *$//' || true
|
|
196
|
+
return 0
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# the wallet address of the node (read-only)
|
|
200
|
+
wallet_address() {
|
|
201
|
+
if [[ -f "${NODE_WALLET}" ]] && command -v jq >/dev/null 2>&1; then
|
|
202
|
+
jq -r '.address // empty' "${NODE_WALLET}" 2>/dev/null || true
|
|
203
|
+
fi
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
prune_states() { # the documented "Remove preserved states"
|
|
207
|
+
node_script_rc "${PRUNE_TIMEOUT:-900}" "sh controls/storage.sh --prune-prior --yes"
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
# --- what the upgrade tool answered -----------------------------------
|
|
211
|
+
# controls/upgrade.sh ends with a status line the README names: validator_active
|
|
212
|
+
# or observer_synced = fine, pending = do NOT restart and try later, refused =
|
|
213
|
+
# the reason is in the output.
|
|
214
|
+
upgrade_verdict() { # upgrade_verdict <output-file>
|
|
215
|
+
local file="$1"
|
|
216
|
+
[[ -f "${file}" ]] || return 0
|
|
217
|
+
awk '
|
|
218
|
+
/validator_active|observer_synced|status = pending|pending|refused/ {
|
|
219
|
+
if ($0 ~ /validator_active/) { print "validator_active"; exit }
|
|
220
|
+
if ($0 ~ /observer_synced/) { print "observer_synced"; exit }
|
|
221
|
+
if ($0 ~ /pending/) { print "pending"; exit }
|
|
222
|
+
if ($0 ~ /refused/) { print "refused"; exit }
|
|
223
|
+
}' "${file}" | tail -1
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
upgrade_reason() { # the last line that explains why (refused/pending)
|
|
227
|
+
local file="$1" line
|
|
228
|
+
[[ -f "${file}" ]] || return 0
|
|
229
|
+
line=$(grep -aiE 'status = (refused|pending)|reason = |error|denied|not allowed|dirty' "${file}" 2>/dev/null | tail -1 || true)
|
|
230
|
+
printf '%s' "${line##*: }"
|
|
231
|
+
}
|
|
232
|
+
|
package/bin/ovtools.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
|
|
7
|
+
const distPath = path.join(__dirname, '..', 'dist', 'cli.js');
|
|
8
|
+
if (!fs.existsSync(distPath)) {
|
|
9
|
+
console.error('ovtools is not built (dist/cli.js is missing). Run: npm run build');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let cli;
|
|
14
|
+
try {
|
|
15
|
+
cli = require(distPath);
|
|
16
|
+
} catch (err) {
|
|
17
|
+
console.error('ovtools failed to load:', err && err.message ? err.message : err);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const main = cli && typeof cli.main === 'function' ? cli.main : null;
|
|
22
|
+
if (!main) {
|
|
23
|
+
console.error('ovtools is corrupted: dist/cli.js does not export main()');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
main(process.argv.slice(2)).then(code => {
|
|
28
|
+
process.exitCode = typeof code === 'number' ? code : 0;
|
|
29
|
+
}).catch(err => {
|
|
30
|
+
console.error(`ERROR: ${err && err.message ? err.message : err}`);
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/api/checks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,UAAU,CAAC;AAsFhE,wBAAsB,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC,CAwGvF"}
|