@@ -66,7 +66,7 @@ source "${SCRIPT_DIR}/lib/common.sh"
6666set -E
6767
6868# Version, gated by update-scripts.sh like every other tracked file.
69- readonly SCRIPT_VERSION=" 1.1 .0"
69+ readonly SCRIPT_VERSION=" 1.2 .0"
7070
7171# Unified (target) identity -- mirrors lib/fallback.sh's canonical new-install names.
7272readonly SYSTEMD_DIR=" /etc/systemd/system"
@@ -82,6 +82,10 @@ LEGACY_UNIT="" # /etc/systemd/system/telcoin-<role>.service
8282LEGACY_WRAPPER=" " # /opt/telcoin/start-telcoin-<role>.sh (read from ExecStart)
8383LEGACY_CONFIG_DIR=" " # /etc/telcoin/<role>
8484LEGACY_DATA_DIR=" " # /var/lib/telcoin/<role> (or .node-meta DATA_DIR)
85+ EFFECTIVE_DATA_DIR=" " # where the data ENDS UP under the unified layout: /var/lib/telcoin for
86+ # a default role-suffixed install, or the operator's custom mount kept
87+ # AS-IS (a 2nd disk, e.g. /mnt/data) -- see detect_legacy.
88+ CUSTOM_DATA_DIR=false # true when the node lives on a custom mount (data preserved in place)
8589LEGACY_CONTAINER=" " # telcoin-<role>
8690RPC_PORT=" ${DEFAULT_RPC_PORT:- 8545} " # post-start verify port; the unified node runs with NO
8791 # --instance, so it serves RPC on the protocol default (8545), not 8541.
@@ -153,10 +157,14 @@ rollback() {
153157
154158 local base
155159 if [[ " $MOVED_DATA " == true ]]; then
160+ # Reverse from where the data was actually moved TO (EFFECTIVE_DATA_DIR). MOVED_DATA is
161+ # only ever true for the default layout (a custom mount no-ops the relocate: src==dst),
162+ # where EFFECTIVE_DATA_DIR == UNIFIED_DATA_DIR -- but key off EFFECTIVE so the reverse is
163+ # correct by construction.
156164 mkdir -p " $LEGACY_DATA_DIR "
157165 for base in " ${DATA_MOVED[@]} " ; do
158- [[ -e " ${UNIFIED_DATA_DIR } /${base} " ]] && \
159- mv " ${UNIFIED_DATA_DIR } /${base} " " ${LEGACY_DATA_DIR} /${base} "
166+ [[ -e " ${EFFECTIVE_DATA_DIR } /${base} " ]] && \
167+ mv " ${EFFECTIVE_DATA_DIR } /${base} " " ${LEGACY_DATA_DIR} /${base} "
160168 done
161169 # mkdir above (re)created the dir as root; restore the captured owner so the legacy
162170 # node can write to its datadir. Without this a "rolled-back" node still can't rotate
@@ -255,16 +263,19 @@ detect_legacy() {
255263 LEGACY_DATA_DIR=" ${UNIFIED_DATA_DIR} /${ROLE} "
256264 fi
257265
258- # Only the role-suffixed default (or an already-unified dir) is auto-relocated.
259- # A custom DATA_DIR (the setup wizard allows one) is NOT moved: it could be a
260- # slow, risky cross-filesystem copy of the multi-GB db, and the path subs only
261- # rewrite the default. Abort and let the operator handle it.
262- if [[ " $LEGACY_DATA_DIR " != " $UNIFIED_DATA_DIR " \
263- && " $LEGACY_DATA_DIR " != " ${UNIFIED_DATA_DIR} /${ROLE} " ]]; then
264- print_error " Custom data dir detected: ${LEGACY_DATA_DIR} "
265- print_info " This migration only relocates the default ${UNIFIED_DATA_DIR} /${ROLE} layout."
266- print_info " Move the data to ${UNIFIED_DATA_DIR} /${ROLE} first, or migrate manually."
267- exit 1
266+ # Where the data ENDS UP under the unified layout:
267+ # - Default role-suffixed (/var/lib/telcoin/<role>) or already-unified
268+ # (/var/lib/telcoin): collapse onto /var/lib/telcoin (the relocate below moves it).
269+ # - CUSTOM mount (a 2nd disk/SSD, e.g. /mnt/data -- setup-node.sh records the
270+ # operator's exact path as DATA_DIR, no role suffix): PRESERVE it in place. The
271+ # data never leaves its disk (no slow/risky cross-fs copy onto the boot disk),
272+ # and relocate_dir() no-ops it because src == dst. Only the NAMING is unified.
273+ if [[ " $LEGACY_DATA_DIR " == " $UNIFIED_DATA_DIR " \
274+ || " $LEGACY_DATA_DIR " == " ${UNIFIED_DATA_DIR} /${ROLE} " ]]; then
275+ EFFECTIVE_DATA_DIR=" $UNIFIED_DATA_DIR "
276+ else
277+ EFFECTIVE_DATA_DIR=" $LEGACY_DATA_DIR "
278+ CUSTOM_DATA_DIR=true
268279 fi
269280
270281 # Wrapper path: read the unit's ExecStart= (authoritative), else convention.
@@ -299,7 +310,11 @@ detect_legacy() {
299310 print_info " unit: ${UNIFIED_UNIT} "
300311 print_info " wrapper: ${UNIFIED_WRAPPER} "
301312 print_info " config dir: ${UNIFIED_CONFIG_DIR} "
302- print_info " data dir: ${UNIFIED_DATA_DIR} "
313+ if [[ " $CUSTOM_DATA_DIR " == true ]]; then
314+ print_info " data dir: ${EFFECTIVE_DATA_DIR} (custom mount -- preserved in place, no data moved)"
315+ else
316+ print_info " data dir: ${EFFECTIVE_DATA_DIR} "
317+ fi
303318 print_info " RPC port: ${RPC_PORT} (default; --observer/--instance removed)"
304319 echo " "
305320
@@ -507,11 +522,13 @@ update_meta() {
507522 : > " $meta "
508523 fi
509524 local ws_port=8546 # reth WS default with no --instance (legacy --instance 5 -> 8554)
510- print_step " Updating ${meta} (NODE_TYPE=observer, DATA_DIR=${UNIFIED_DATA_DIR } , RPC_PORT=${RPC_PORT} , WS_PORT=${ws_port} )"
525+ print_step " Updating ${meta} (NODE_TYPE=observer, DATA_DIR=${EFFECTIVE_DATA_DIR } , RPC_PORT=${RPC_PORT} , WS_PORT=${ws_port} )"
511526 # NODE_TYPE is only the default-view HINT; the UI promotes to the validator view
512527 # from on-chain tn_isValidator. Every migrated node is the same identity.
513528 meta_set NODE_TYPE observer " $meta "
514- meta_set DATA_DIR " $UNIFIED_DATA_DIR " " $meta "
529+ # EFFECTIVE_DATA_DIR: /var/lib/telcoin for a default install, or the operator's
530+ # preserved custom mount (2nd disk) -- so the node keeps finding its data.
531+ meta_set DATA_DIR " $EFFECTIVE_DATA_DIR " " $meta "
515532 # RPC + WS revert to their protocol defaults now that --instance is stripped (the legacy
516533 # observer's --instance 5 put them on 8541/8554). RPC_PORT/WS_PORT in .node-meta are read by
517534 # the local Node Manager UI, check-node.sh, and install-caddy.sh (operator-facing, this repo)
@@ -525,7 +542,7 @@ update_meta() {
525542 # Optional: record VALIDATOR_ADDRESS from node-info.yaml execution_address for
526543 # the UI's on-chain status card. NOT consumed at node launch (only by keygen /
527544 # staking and the post-start status check), so it is purely informational here.
528- local ni=" ${UNIFIED_DATA_DIR } /node-info.yaml" exec_addr=" "
545+ local ni=" ${EFFECTIVE_DATA_DIR } /node-info.yaml" exec_addr=" "
529546 if [[ -f " $ni " ]]; then
530547 exec_addr=" $( grep -E ' ^[[:space:]]*execution_address[[:space:]]*:' " $ni " 2> /dev/null \
531548 | head -n1 | sed -E ' s/.*:[[:space:]]*"?([0-9a-fA-Fx]+)"?.*/\1/' || true) "
@@ -644,7 +661,7 @@ report() {
644661 print_info " unit: ${UNIFIED_UNIT} "
645662 print_info " wrapper: ${UNIFIED_WRAPPER} "
646663 print_info " config dir: ${UNIFIED_CONFIG_DIR} "
647- print_info " data dir: ${UNIFIED_DATA_DIR} "
664+ print_info " data dir: ${EFFECTIVE_DATA_DIR} $( [[ " $CUSTOM_DATA_DIR " == true ]] && echo ' (custom mount, preserved) ' ) "
648665 print_info " NODE_TYPE: observer (presentation hint; on-chain tn_isValidator is authoritative)"
649666 echo " "
650667 print_info " Node RPC/WS now on ${RPC_PORT} /8546 (was 8541/8554 under --instance). The local"
@@ -674,7 +691,7 @@ main() {
674691 snapshot # step 2 (arms rollback)
675692 stop_legacy # step 3
676693 relocate_dir " $LEGACY_CONFIG_DIR " " $UNIFIED_CONFIG_DIR " CONFIG_MOVED config # step 4
677- relocate_dir " $LEGACY_DATA_DIR " " $UNIFIED_DATA_DIR " DATA_MOVED data # step 5
694+ relocate_dir " $LEGACY_DATA_DIR " " $EFFECTIVE_DATA_DIR " DATA_MOVED data # step 5 (no-op for a custom mount: src==dst)
678695 rewrite_unit # step 6
679696 rewrite_wrapper # step 7 (strip --observer and --instance)
680697 update_meta # step 8
0 commit comments