diff --git a/generate-genesis.sh b/generate-genesis.sh index 3faf484..85a31f9 100755 --- a/generate-genesis.sh +++ b/generate-genesis.sh @@ -90,6 +90,7 @@ VALIDATOR_CONFIG_FILE="$GENESIS_DIR/validator-config.yaml" SKIP_KEY_GEN="true" DEPLOYMENT_MODE="local" # Default to local mode GENESIS_TIME_OFFSET="" # Will be set based on mode or --offset flag +DOCKER_CMD="docker" # Set to "sudo docker" via --dockerWithSudo (hosts where the docker socket needs root) shift while [[ $# -gt 0 ]]; do case "$1" in @@ -128,6 +129,10 @@ while [[ $# -gt 0 ]]; do exit 1 fi ;; + --dockerWithSudo) + DOCKER_CMD="sudo docker" + shift + ;; *) shift ;; @@ -274,9 +279,9 @@ else CURRENT_GID=$(id -g) # Pull latest image first - docker pull "$HASH_SIG_CLI_IMAGE" || true + $DOCKER_CMD pull "$HASH_SIG_CLI_IMAGE" || true - docker run --rm --pull=never \ + $DOCKER_CMD run --rm --pull=never \ --user "$CURRENT_UID:$CURRENT_GID" \ -v "$GENESIS_DIR_ABS:/genesis" \ "$HASH_SIG_CLI_IMAGE" \ @@ -469,9 +474,9 @@ echo " Executing docker command..." # Pull latest image first echo " Pulling latest image: $PK_DOCKER_IMAGE" -docker pull "$PK_DOCKER_IMAGE" || true +$DOCKER_CMD pull "$PK_DOCKER_IMAGE" || true -docker run --rm --pull=never \ +$DOCKER_CMD run --rm --pull=never \ --user "$CURRENT_UID:$CURRENT_GID" \ -v "$PARENT_DIR_ABS:/data" \ "$PK_DOCKER_IMAGE" \ diff --git a/parse-env.sh b/parse-env.sh index 50fc46c..3aff399 100755 --- a/parse-env.sh +++ b/parse-env.sh @@ -134,6 +134,12 @@ while [[ $# -gt 0 ]]; do enableLogs=true shift ;; + --detach) + # Run local docker nodes detached (-d --restart unless-stopped) and let + # spin-node.sh exit without tearing them down. Local docker mode only. + detachNodes=true + shift + ;; *) # unknown option shift # past argument ;; @@ -191,3 +197,4 @@ echo "dryRun = ${dryRun:-false}" echo "replaceWith = ${replaceWith:-}" echo "networkName = $networkName" echo "enableLogs = ${enableLogs:-false}" +echo "detachNodes = ${detachNodes:-false}" diff --git a/set-up.sh b/set-up.sh index c9c3362..afec67c 100755 --- a/set-up.sh +++ b/set-up.sh @@ -33,8 +33,13 @@ if [ -n "$generateGenesis" ] || [ ! -f "$configDir/validators.yaml" ] || [ ! -f _validator_config_flag="--validator-config $validatorConfig" fi + # Forward the sudo preference so the genesis keygen/tool docker calls work on + # hosts where the docker socket needs root (user not in the docker group). + _docker_sudo_flag="" + [ -n "$dockerWithSudo" ] && _docker_sudo_flag="--dockerWithSudo" + # Run the generator with deployment mode - if ! $genesis_generator "$configDir" --mode "$deployment_mode" $FORCE_KEYGEN_FLAG $_validator_config_flag; then + if ! $genesis_generator "$configDir" --mode "$deployment_mode" $FORCE_KEYGEN_FLAG $_validator_config_flag $_docker_sudo_flag; then echo "❌ Genesis generation failed!" exit 1 fi diff --git a/spin-node.sh b/spin-node.sh index 7270190..901f696 100755 --- a/spin-node.sh +++ b/spin-node.sh @@ -908,6 +908,15 @@ for item in "${spin_nodes[@]}"; do echo "$sourceCmd" eval $sourceCmd + # --detach only supports docker nodes: it relies on `docker run -d + # --restart unless-stopped` to outlive this script. A binary has no such + # supervisor, so a detached binary would just run in the foreground here (or, + # if backgrounded, die when the script exits). Fail fast instead. + if [ "$detachNodes" == "true" ] && [ "$node_setup" == "binary" ]; then + echo "❌ --detach is only supported for docker nodes; '$item' is configured for binary mode." + exit 1 + fi + # spin nodes if [ "$node_setup" == "binary" ] then @@ -927,7 +936,14 @@ for item in "${spin_nodes[@]}"; do else docker pull "$docker_image" || true fi - execCmd="docker run --rm --pull=never" + if [ "$detachNodes" == "true" ]; then + # Detached: run in the background with a restart policy so the devnet + # keeps running after spin-node.sh exits. No --rm, so the container is + # kept for `docker logs` inspection. + execCmd="docker run -d --restart unless-stopped --pull=never" + else + execCmd="docker run --rm --pull=never" + fi if [ -n "$dockerWithSudo" ] then execCmd="sudo $execCmd" @@ -961,6 +977,13 @@ for item in "${spin_nodes[@]}"; do if [ "$dryRun" == "true" ]; then echo "[DRY RUN] Would execute: $execCmd" pid=0 + elif [ "$detachNodes" == "true" ]; then + # Detached `docker run -d` returns immediately after printing the + # container id; logs are captured by the docker daemon (docker logs ). + # There is no foreground process to track, so record a placeholder pid. + echo "$execCmd" + eval "$execCmd" + pid=0 else sed_remove_ansi='s/\x1b\[[0-9;]*[mJHG]//g' echo "$execCmd" @@ -1066,17 +1089,37 @@ cleanup() { _print_deployment_summary -trap "echo exit signal received;cleanup" SIGINT SIGTERM -echo -e "\n\nwaiting for nodes to exit" -printf '%*s' $(tput cols) | tr ' ' '-' -echo "press Ctrl+C to exit and cleanup..." -# Wait for background processes - use a compatible approach for all shells -if [ ${#spinned_pids[@]} -gt 0 ]; then - for pid in "${spinned_pids[@]}"; do - wait $pid 2>/dev/null || true - done +if [ "$detachNodes" == "true" ]; then + # Detached mode: leave the devnet running once spin-node.sh exits. Skip the + # trap/wait/cleanup entirely so the containers (started with + # --restart unless-stopped) survive independently of this script. + echo -e "\n\ndevnet started in detached mode; nodes keep running after this script exits" + printf '%*s' $(tput cols) | tr ' ' '-' + echo + # Mirror the sudo preference in the hints so copy-pasted commands work on + # hosts where the docker socket needs root (--dockerWithSudo). + _hint_docker="docker" + _hint_stop_flags="" + if [ -n "$dockerWithSudo" ]; then + _hint_docker="sudo docker" + _hint_stop_flags=" --dockerWithSudo" + fi + echo " view logs: $_hint_docker logs -f (e.g. $_hint_docker logs -f ${spin_nodes[0]})" + echo " stop all: NETWORK_DIR=$NETWORK_DIR $0 --node all --stop$_hint_stop_flags" + echo " (or raw: $_hint_docker rm -f $container_names)" else - # Fallback: wait for any background job - wait + trap "echo exit signal received;cleanup" SIGINT SIGTERM + echo -e "\n\nwaiting for nodes to exit" + printf '%*s' $(tput cols) | tr ' ' '-' + echo "press Ctrl+C to exit and cleanup..." + # Wait for background processes - use a compatible approach for all shells + if [ ${#spinned_pids[@]} -gt 0 ]; then + for pid in "${spinned_pids[@]}"; do + wait $pid 2>/dev/null || true + done + else + # Fallback: wait for any background job + wait + fi + cleanup fi -cleanup