iuna

iuna

iuna - experimental mainnet-candidate protocol
git clone https://getiuna.org/git/iuna.git
Log | Files | Refs | README | LICENSE

commit 732084452778941eb30509f65b1a420bce45e5c5
parent 2acd5ddbdd6349b081886280cd7d0b8280e03de7
Author: Joris Hartog <jorishartog@hotmail.com>
Date:   Tue, 25 Aug 2026 15:35:54 +0200

Support genesis deployments with fresh PVCs

Diffstat:
MREADME.md | 8++++++++
Mconfig/deployment.yml | 17+++++++++++++++--
Mdeployment.sh | 100++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
3 files changed, 112 insertions(+), 13 deletions(-)

diff --git a/README.md b/README.md @@ -68,6 +68,14 @@ Release and deploy with: ./deployment.sh 0.2.48 ``` +To start a new chain, deploy with `--genesis`. This asks for confirmation, +starts the node with `--genesis`, and switches it to a new version-specific PVC; +the existing PVC is retained: + +```sh +./deployment.sh --genesis 0.4.0 +``` + Deployment publishes two images to the `jhx-app` k3s cluster: - `https://getiuna.org/` routes to the static website image. diff --git a/config/deployment.yml b/config/deployment.yml @@ -6,7 +6,7 @@ metadata: apiVersion: v1 kind: PersistentVolumeClaim metadata: - name: local-path-db-pvc + name: ${IUNA_NODE_PVC} namespace: iuna spec: accessModes: @@ -153,6 +153,9 @@ metadata: namespace: iuna spec: replicas: 1 + strategy: + type: Recreate + rollingUpdate: null selector: matchLabels: app: iuna-node @@ -165,6 +168,16 @@ spec: - name: iuna-node image: ${IUNA_NODE_IMAGE} imagePullPolicy: IfNotPresent + args: +${IUNA_NODE_GENESIS_ARG} + - --data-dir + - /data + - --http + - 0.0.0.0:18661 + - --p2p + - 0.0.0.0:9444 + - --p2p-announce + - 142.132.164.59:9444 ports: - name: management containerPort: 18661 @@ -176,7 +189,7 @@ spec: volumes: - name: data persistentVolumeClaim: - claimName: local-path-db-pvc + claimName: ${IUNA_NODE_PVC} --- apiVersion: v1 kind: Service diff --git a/deployment.sh b/deployment.sh @@ -4,8 +4,9 @@ set -euo pipefail cd "$(dirname "${BASH_SOURCE[0]}")" usage() { - echo "Usage: $0 <version>" >&2 + echo "Usage: $0 [--genesis] <version>" >&2 echo "Example: $0 0.2.48" >&2 + echo " $0 --genesis 0.4.0" >&2 } die() { @@ -379,15 +380,19 @@ import_image_to_k3s() { render_manifest() { local www_image="$1" local node_image="$2" - local output="$3" + local node_pvc="$3" + local genesis="$4" + local output="$5" local local_allowlist_file="config/admin-ip-allowlist.local" local allowlist_entry local allowlist_entry_count=0 local escaped_www_image local escaped_node_image + local escaped_node_pvc escaped_www_image="$(escape_sed_replacement "$www_image")" escaped_node_image="$(escape_sed_replacement "$node_image")" + escaped_node_pvc="$(escape_sed_replacement "$node_pvc")" [ -f "$local_allowlist_file" ] || die "missing local admin allowlist: ${local_allowlist_file}" while IFS= read -r allowlist_entry || [ -n "$allowlist_entry" ]; do @@ -403,7 +408,14 @@ render_manifest() { sed \ -e "s|\${IUNA_WWW_IMAGE}|${escaped_www_image}|g" \ -e "s|\${IUNA_NODE_IMAGE}|${escaped_node_image}|g" \ - config/deployment.yml | awk -v local_allowlist_file="$local_allowlist_file" ' + -e "s|\${IUNA_NODE_PVC}|${escaped_node_pvc}|g" \ + config/deployment.yml | awk \ + -v local_allowlist_file="$local_allowlist_file" \ + -v genesis="$genesis" ' + $0 == "${IUNA_NODE_GENESIS_ARG}" { + if (genesis == "true") print " - --genesis" + next + } $0 == "${IUNA_ADMIN_IP_ALLOWLIST_LOCAL}" { while ((getline entry < local_allowlist_file) > 0) { sub(/#.*/, "", entry) @@ -417,21 +429,50 @@ render_manifest() { ' > "$output" } +genesis_pvc_name() { + local version="$1" + printf 'local-path-db-pvc-v%s' "${version//./-}" +} + +ensure_genesis_pvc_is_new() { + local version="$1" + local kubectl_context="${IUNA_KUBECTL_CONTEXT:-jhx-app}" + local node_pvc + local existing_pvc + + require_command kubectl + node_pvc="$(genesis_pvc_name "$version")" + existing_pvc="$(kubectl --context "$kubectl_context" -n iuna get pvc "$node_pvc" --ignore-not-found -o name)" || \ + die "could not check whether genesis PVC ${node_pvc} exists" + [ -z "$existing_pvc" ] || die "genesis PVC ${node_pvc} already exists; refusing to reuse it" +} + deploy_docker_image() { local version="$1" + local genesis="$2" local www_image="${IUNA_WWW_IMAGE:-iuna-www:v${version}}" local node_image="${IUNA_NODE_IMAGE:-iuna-node:v${version}}" + local node_pvc local kubectl_context="${IUNA_KUBECTL_CONTEXT:-jhx-app}" local tmp_folder require_command kubectl + node_pvc="$(kubectl --context "$kubectl_context" -n iuna get deployment node --ignore-not-found -o jsonpath='{.spec.template.spec.volumes[?(@.name=="data")].persistentVolumeClaim.claimName}')" || \ + die "could not determine the PVC used by the current node deployment" + node_pvc="${node_pvc:-local-path-db-pvc}" + tmp_folder="$(mktemp -d)" trap 'rm -rf "$tmp_folder"' RETURN + if [ "$genesis" = "true" ]; then + node_pvc="$(genesis_pvc_name "$version")" + ensure_genesis_pvc_is_new "$version" + fi + import_image_to_k3s "$www_image" "$tmp_folder" import_image_to_k3s "$node_image" "$tmp_folder" - render_manifest "$www_image" "$node_image" "${tmp_folder}/deployment.yml" + render_manifest "$www_image" "$node_image" "$node_pvc" "$genesis" "${tmp_folder}/deployment.yml" local current_www_selector current_www_selector="$(kubectl --context "$kubectl_context" -n iuna get deployment www -o jsonpath='{.spec.selector.matchLabels.app}' 2>/dev/null || true)" @@ -443,28 +484,63 @@ deploy_docker_image() { kubectl --context "$kubectl_context" -n iuna rollout restart deployment/www deployment/node kubectl --context "$kubectl_context" -n iuna rollout status deployment/www kubectl --context "$kubectl_context" -n iuna rollout status deployment/node + + if [ "$genesis" = "true" ]; then + echo "Genesis is gestart; --genesis wordt nu verwijderd voor volgende pod-starts" + render_manifest "$www_image" "$node_image" "$node_pvc" false "${tmp_folder}/deployment.yml" + kubectl --context "$kubectl_context" apply -f "${tmp_folder}/deployment.yml" + kubectl --context "$kubectl_context" -n iuna rollout status deployment/node + fi } main() { - [ "$#" -eq 1 ] || { usage; exit 2; } - - local version="${1#v}" + local genesis=false + local version="" + + while [ "$#" -gt 0 ]; do + case "$1" in + --genesis) + [ "$genesis" = "false" ] || die "--genesis may only be specified once" + genesis=true + ;; + -*) + die "unknown option: $1" + ;; + *) + [ -z "$version" ] || { usage; exit 2; } + version="${1#v}" + ;; + esac + shift + done + + [ -n "$version" ] || { usage; exit 2; } [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || die "version must look like 0.2.48" ensure_clean_worktree + if [ "$genesis" = "true" ]; then + echo "LET OP: dit start een nieuwe chain met --genesis en een nieuwe PVC." + echo "De bestaande chain en PVC blijven bewaard, maar de node schakelt over naar local-path-db-pvc-v${version//./-}." + if ! confirm "Weet je het zeker? (Y/N) "; then + echo "Deployment afgebroken" + exit 1 + fi + ensure_genesis_pvc_is_new "$version" + fi + # Check if the tag already exists; if it does, only deploy if git rev-parse --verify "v${version}" >/dev/null 2>&1; then ensure_head_matches_tag "v${version}" echo "Tag v${version} already exists; rebuilding Docker images and deploying" - if ! confirm "Are you sure you want to deploy v${version}? (y/N) "; then + if [ "$genesis" != "true" ] && ! confirm "Are you sure you want to deploy v${version}? (y/N) "; then echo "Aborting deployment" exit 1 fi run_release_tests build_linux_cli_archives "$version" build_docker_image "$version" - deploy_docker_image "$version" + deploy_docker_image "$version" "$genesis" exit 0 fi @@ -473,7 +549,9 @@ main() { build_versions "$version" commit_and_tag "$version" build_docker_image "$version" - deploy_docker_image "$version" + deploy_docker_image "$version" "$genesis" } -main "$@" +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + main "$@" +fi