adding sui wallet script

This commit is contained in:
Brad Stein 2025-08-14 20:37:30 -05:00
parent b891ed7f72
commit 968532cc55
6 changed files with 298 additions and 36 deletions

View File

@ -5,43 +5,33 @@ ARG P2POOL_VERSION=v4.9
FROM ${DEBIAN_IMAGE} AS fetch FROM ${DEBIAN_IMAGE} AS fetch
ARG TARGETARCH ARG TARGETARCH
ARG P2POOL_VERSION ARG P2POOL_VERSION
RUN set -eux; \ RUN set -eux; \
apt-get update; \ apt-get update; \
apt-get install -y --no-install-recommends ca-certificates curl jq xz-utils tar unzip; \ apt-get install -y --no-install-recommends ca-certificates curl jq xz-utils tar; \
update-ca-certificates; \ update-ca-certificates; rm -rf /var/lib/apt/lists/*
rm -rf /var/lib/apt/lists/*
# Pick the correct asset URL for our arch from the release metadata
RUN set -eux; \ RUN set -eux; \
case "${TARGETARCH:-arm64}" in \ case "${TARGETARCH:-arm64}" in \
amd64) ARCH_RE='(x86_64|amd64)';; \ amd64) ARCH_RE='(x86_64|amd64)';; \
arm64) ARCH_RE='(arm64|aarch64|armv8)';; \ arm64) ARCH_RE='(arm64|aarch64|armv8)';; \
arm) ARCH_RE='(arm|armv7|armhf)';; \ arm) ARCH_RE='(arm|armv7|armhf)';; \
*) echo "Unsupported TARGETARCH=${TARGETARCH}"; exit 1;; \ *) echo "Unsupported TARGETARCH=${TARGETARCH}"; exit 1;; \
esac; \ esac; \
API="https://api.github.com/repos/SChernykh/p2pool/releases/tags/${P2POOL_VERSION}"; \ API="https://api.github.com/repos/SChernykh/p2pool/releases/tags/${P2POOL_VERSION}"; \
URL="$(curl -fsSL "$API" | jq -r --arg re "$ARCH_RE" \ URL="$(curl -fsSL "${API}" | jq -r --arg re "${ARCH_RE}" '.assets[].browser_download_url | select(test("linux") and test($re))' | head -n1)"; \
'.assets[] | select((.name|test("linux")) and (.name|test($re))) | .browser_download_url' | head -n1)"; \ test -n "${URL}"; echo "Downloading ${URL}"; \
test -n "$URL"; \ curl -fsSL "${URL}" -o /tmp/p2pool.tgz; \
echo "Downloading $URL"; \ mkdir -p /out; tar -xzf /tmp/p2pool.tgz -C /out; \
mkdir -p /tmp/p2pool; \ BIN="$(find /out -maxdepth 1 -type f -name 'p2pool*' | head -n1)"; \
curl -fsSL "$URL" -o /tmp/p2pool/p2pool.tar; \ test -n "${BIN}"; install -m0755 "${BIN}" /out/p2pool
# try both common formats
( tar -xOf /tmp/p2pool/p2pool.tar >/dev/null 2>&1 && tar -xf /tmp/p2pool/p2pool.tar -C /tmp/p2pool ) \
|| ( tar -xzf /tmp/p2pool/p2pool.tar -C /tmp/p2pool || tar -xJf /tmp/p2pool/p2pool.tar -C /tmp/p2pool ); \
# find the p2pool binary and install as a stable name
P="$(find /tmp/p2pool -maxdepth 2 -type f -name 'p2pool' | head -n1)"; \
test -n "$P"; \
install -m 0755 "$P" /usr/local/bin/p2pool
FROM ${DEBIAN_IMAGE} FROM ${DEBIAN_IMAGE}
RUN set -eux; \ RUN set -eux; \
apt-get update; \ apt-get update; \
apt-get install -y --no-install-recommends ca-certificates; \ apt-get install -y --no-install-recommends ca-certificates; \
update-ca-certificates; \ update-ca-certificates; rm -rf /var/lib/apt/lists/*
rm -rf /var/lib/apt/lists/* COPY --from=fetch /out/p2pool /usr/local/bin/p2pool
COPY --from=fetch /usr/local/bin/p2pool /usr/local/bin/p2pool
RUN /usr/local/bin/p2pool --version || true
EXPOSE 3333 EXPOSE 3333
ENTRYPOINT ["p2pool"] ENTRYPOINT ["/usr/local/bin/p2pool"]

View File

@ -20,17 +20,14 @@ RUN set -eux; \
*) echo "Unsupported TARGETARCH=${TARGETARCH}"; exit 1 ;; \ *) echo "Unsupported TARGETARCH=${TARGETARCH}"; exit 1 ;; \
esac; \ esac; \
URL="https://downloads.getmonero.org/cli/${F}-${MONERO_VERSION}.tar.bz2"; \ URL="https://downloads.getmonero.org/cli/${F}-${MONERO_VERSION}.tar.bz2"; \
echo "Downloading $URL"; \ echo "Fetching $URL"; \
mkdir -p /opt/monero; \ mkdir -p /opt/monero; \
curl -fsSL "$URL" -o /opt/monero/monero.tar.bz2; \ curl -fsSL "$URL" -o /opt/monero/monero.tar.bz2; \
tar -xjf /opt/monero/monero.tar.bz2 -C /opt/monero --strip-components=1; \ tar -xjf /opt/monero/monero.tar.bz2 -C /opt/monero --strip-components=1; \
rm -f /opt/monero/monero.tar.bz2; \ install -m 0755 /opt/monero/monero-wallet-rpc /usr/local/bin/monero-wallet-rpc; \
install -m 0755 /opt/monero/monero-* /usr/local/bin/ || true; \ rm -f /opt/monero/monero.tar.bz2
install -m 0755 /opt/monero/monerod /usr/local/bin/ || true; \
install -m 0755 /opt/monero/monero-wallet-rpc /usr/local/bin/
ENV PATH="/usr/local/bin:/usr/bin:/bin"
RUN /usr/local/bin/monero-wallet-rpc --version || true RUN /usr/local/bin/monero-wallet-rpc --version || true
EXPOSE 18083 EXPOSE 18083
ENTRYPOINT ["monero-wallet-rpc"]

View File

@ -518,7 +518,7 @@ function walletsvc_bootstrap --description "Interactive setup of monero-wallet-r
echo " - |" echo " - |"
echo " RPCU=\$(cat /run/monero-secrets/rpc-user);" echo " RPCU=\$(cat /run/monero-secrets/rpc-user);"
echo " RPCP=\$(cat /run/monero-secrets/rpc-pass);" echo " RPCP=\$(cat /run/monero-secrets/rpc-pass);"
echo " exec monero-wallet-rpc \\" echo " exec /usr/local/bin/monero-wallet-rpc \\"
echo " --wallet-dir /data \\" echo " --wallet-dir /data \\"
echo " --daemon-address $daemon_addr \\" echo " --daemon-address $daemon_addr \\"
echo " --rpc-bind-ip 0.0.0.0 --rpc-bind-port 18083 \\" echo " --rpc-bind-ip 0.0.0.0 --rpc-bind-port 18083 \\"

View File

@ -0,0 +1,275 @@
### --------- helpers ----------
function _need
for c in $argv
if not type -q $c
echo (set_color red)"Error:"(set_color normal)" missing command: $c" >&2
return 1
end
end
end
function _banner -a MSG
set_color cyan; echo; echo "==> $MSG"; set_color normal
end
function _k8s_name -a S
set s (string lower -- $S)
set s (string replace -ar -- '[^a-z0-9-]' '-' $s)
set s (string replace -r -- '^-+|(-)+$' '$1' $s)
echo $s
end
function _require -a WHAT VAL
if test -z "$VAL"
echo (set_color red)"Error:"(set_color normal)" $WHAT cannot be empty." >&2
return 1
end
end
function _sc_list
kubectl get storageclass -o json 2>/dev/null | jq -r '
.items[] | [
.metadata.name,
.provisioner,
(.reclaimPolicy // "Delete"),
( .metadata.annotations["storageclass.kubernetes.io/is-default-class"] == "true"
or .metadata.annotations["storageclass.beta.kubernetes.io/is-default-class"] == "true")
] | @tsv'
end
function _choose_sc
set lines (_sc_list)
if test (count $lines) -eq 0
echo (set_color red)"Error:"(set_color normal)" No StorageClasses found." >&2
return 1
end
echo "" >&2
echo "==> Available StorageClasses" >&2
echo " # | name | provisioner | reclaim | default" >&2
echo "----+----------------------+------------------------+---------+--------" >&2
set i 1
for l in $lines
set name (echo $l | awk -F'\t' '{print $1}')
set prov (echo $l | awk -F'\t' '{print $2}')
set rec (echo $l | awk -F'\t' '{print $3}')
set def (echo $l | awk -F'\t' '{print $4}')
printf " %2d | %-20s | %-22s | %-7s | %s\n" $i $name $prov $rec $def >&2
set i (math $i + 1)
end
set prefer (printf "%s\n" $lines | awk -F'\t' '$4=="true"{print $1}' | head -n1)
if test -z "$prefer"
set prefer (printf "%s\n" $lines | awk -F'\t' '{print $1}' | head -n1)
end
read -P "Pick StorageClass by number or name (blank = $prefer): " choice
if test -z "$choice"
echo $prefer
return 0
end
if string match -qr '^[0-9]+$' -- $choice
set idx (math $choice)
if test $idx -lt 1 -o $idx -gt (count $lines)
echo (set_color red)"Error:"(set_color normal)" Choice out of range." >&2
return 1
end
printf "%s\n" $lines[$idx] | awk -F'\t' '{print $1}'
else
printf "%s\n" $lines | awk -F'\t' -v want="$choice" '$1==want{print $1}'
end
end
### --------- main workflow ----------
function suiwallet_bootstrap --description "Create a Sui wallet (PVC+Deployment) and generate a new address"
_need kubectl jq awk; or return 1
_banner "Sui wallet bootstrap"
read -P "Namespace [crypto]: " ns
if test -z "$ns"; set ns crypto; end
set ns (_k8s_name $ns)
echo "Ensuring namespace '$ns' exists…"
if not kubectl get ns $ns >/dev/null 2>&1
kubectl create ns $ns; or return 1
end
kubectl get storageclass 2>/dev/null
echo "TIP: Prefer a Retain StorageClass so deleting the pod won't delete keys."
set sc (_choose_sc); or return 1
read -P "Wallet name (e.g. 'brad' → wallet-sui-brad): " wallet_raw
_require "Wallet name" $wallet_raw; or return 1
set base (_k8s_name $wallet_raw)
set app "wallet-sui-$base"
set pvc $app
read -P "Network [mainnet|testnet|devnet] [mainnet]: " net
if test -z "$net"; set net mainnet; end
switch $net
case mainnet
set rpc_url https://fullnode.mainnet.sui.io:443
case testnet
set rpc_url https://fullnode.testnet.sui.io:443
case devnet
set rpc_url https://fullnode.devnet.sui.io:443
case '*'
echo (set_color red)"Error:"(set_color normal)" network must be mainnet|testnet|devnet"; return 1
end
read -P "Container image [mysten/sui-tools:latest]: " image
if test -z "$image"; set image mysten/sui-tools:latest; end
read -P "Address alias to create [main]: " alias
if test -z "$alias"; set alias main; end
read -P "Mnemonic word length [24]: " wl
if test -z "$wl"; set wl 24; end
read -P "Store mnemonic as a Kubernetes Secret? (NOT recommended) (y/N): " store_mn
set store_mn (string lower -- $store_mn)
_banner "Summary"
echo " Namespace: $ns"
echo " App name: $app"
echo " StorageClass: $sc"
echo " PVC: $pvc"
echo " Image: $image"
echo " Network: $net"
echo " RPC URL: $rpc_url"
echo " New alias: $alias (word length: $wl)"
read -P "Proceed? [y/N]: " ok
if not string match -qi 'y*' -- $ok
echo "Aborted."; return 1
end
_banner "Applying PVC"
kubectl -n $ns get pvc $pvc >/dev/null 2>&1; or begin
printf "%s\n" \
"apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: $pvc
namespace: $ns
spec:
accessModes: [\"ReadWriteOnce\"]
storageClassName: $sc
resources:
requests:
storage: 1Gi" | kubectl apply -f -; or return 1
end
_banner "Applying Deployment"
printf "%s\n" \
"apiVersion: apps/v1
kind: Deployment
metadata:
name: $app
namespace: $ns
labels: { app: $app }
spec:
replicas: 1
selector: { matchLabels: { app: $app } }
template:
metadata:
labels: { app: $app }
spec:
containers:
- name: sui-tools
image: $image
imagePullPolicy: IfNotPresent
command: [\"bash\",\"-lc\",\"sleep infinity\"]
volumeMounts:
- name: data
mountPath: /root/.sui
resources:
requests: { cpu: 50m, memory: 128Mi }
limits: { cpu: 1, memory: 512Mi }
volumes:
- name: data
persistentVolumeClaim: { claimName: $pvc }" | kubectl apply -f -; or return 1
_banner "Waiting for rollout"
kubectl -n $ns rollout status deploy/$app --timeout=120s; or return 1
_banner "Initializing Sui client env ($net) and creating a new address"
# new-env: writes client.yaml; new-address: writes to sui.keystore and prints the phrase
set OUT (mktemp)
kubectl -n $ns exec deploy/$app -- bash -lc \
(printf 'mkdir -p /root/.sui/sui_config ;
sui client new-env --alias %s --rpc %s >/dev/null 2>&1 || true ;
sui client new-address ed25519 --word-length %s --alias %s' \
$net $rpc_url $wl $alias) | tee $OUT
set ADDR (kubectl -n $ns exec deploy/$app -- bash -lc \
(printf 'sui client addresses | awk "/%s/{print \$NF}" | tail -n1' $alias))
echo
echo (set_color yellow)"IMPORTANT — Secret Recovery Phrase (write down & store offline):"(set_color normal)
grep -E 'Secret Recovery Phrase|Mnemon' $OUT -A2 | sed -e 's/^\s\+//'
echo
echo "Address alias '$alias' appears to be: $ADDR"
rm -f $OUT
if test "$store_mn" = "y" -o "$store_mn" = "yes"
set MN (kubectl -n $ns exec deploy/$app -- bash -lc \
(printf 'sui client addresses >/dev/null 2>&1 ; sui client new-address ed25519 --word-length %s --alias %s --json 2>/dev/null | jq -r .secretRecoveryPhrase || true' $wl "${alias}-dup"))
if test -n "$MN" -a "$MN" != "null"
kubectl -n $ns create secret generic {$app}-mnemonic \
--from-literal=mnemonic="$MN" --dry-run=client -o yaml | kubectl -n $ns apply -f -
echo (set_color yellow)"Stored mnemonic in Secret $ns/{$app}-mnemonic. Treat your cluster as sensitive."(set_color normal)
# clean the duplicate alias we created to harvest JSON
kubectl -n $ns exec deploy/$app -- bash -lc "sui client remove-address --alias ${alias}-dup >/dev/null 2>&1 || true" >/dev/null 2>&1
else
echo (set_color red)"Warning:"(set_color normal)" could not capture mnemonic via --json, not storing."
end
end
echo
echo "Done. Files inside the pod:"
kubectl -n $ns exec deploy/$app -- bash -lc 'ls -l /root/.sui/sui_config || true'
echo
echo "Useful commands:"
echo " suiwallet_addresses $ns $app"
echo " suiwallet_export_keystore $ns $app ./sui.keystore.$base"
echo " kubectl -n $ns exec -it deploy/$app -- bash # interactive CLI"
end
### --------- utilities ----------
function suiwallet_addresses -a NS APP
if test -z "$NS"; set NS crypto; end
if test -z "$APP"; set APP wallet-sui-main; end
kubectl -n $NS exec deploy/$APP -- bash -lc 'sui client addresses || true'
end
function suiwallet_export_keystore -a NS APP DEST
if test -z "$NS"; set NS crypto; end
if test -z "$APP"; set APP wallet-sui-main; end
if test -z "$DEST"; set DEST ./sui.keystore; end
echo "Copying keystore to $DEST (keep it safe!)"
kubectl -n $NS cp deploy/$APP:/root/.sui/sui_config/sui.keystore $DEST
end
function suiwallet_status -a NS APP
if test -z "$NS"; set NS crypto; end
if test -z "$APP"; set APP wallet-sui-main; end
kubectl -n $NS get deploy,po,pvc -l app=$APP -o wide
end
function suiwallet_stop -a NS APP
if test -z "$NS"; set NS crypto; end
if test -z "$APP"; set APP wallet-sui-main; end
kubectl -n $NS delete deploy $APP --ignore-not-found
echo "Stopped $NS/$APP (PVC kept)."
end
function suiwallet_purge -a NS APP PVC
if test -z "$NS"; set NS crypto; end
if test -z "$APP"; set APP wallet-sui-main; end
if test -z "$PVC"; set PVC $APP; end
echo "Type to confirm: PURGE $NS $PVC"
read CONFIRM
if test "$CONFIRM" != "PURGE $NS $PVC"
echo "Aborted."; return 1
end
kubectl -n $NS delete deploy $APP --ignore-not-found
kubectl -n $NS delete pvc $PVC --ignore-not-found --wait=true
end

View File

@ -39,7 +39,7 @@ spec:
-o p2pool.crypto.svc.cluster.local:3333 \ -o p2pool.crypto.svc.cluster.local:3333 \
-u x \ -u x \
-k \ -k \
--donate-level 0 \ --donate-level N \
--cpu-priority 1 \ --cpu-priority 1 \
--threads "${THR}" ${EXTRA} --threads "${THR}" ${EXTRA}
volumeMounts: volumeMounts:

View File

@ -14,7 +14,7 @@ spec:
labels: { app: zot } labels: { app: zot }
spec: spec:
nodeSelector: nodeSelector:
kubernetes.io/arch: arm64 node-role.kubernetes.io/worker: "true"
containers: containers:
- name: zot - name: zot
image: ghcr.io/project-zot/zot-linux-arm64:latest image: ghcr.io/project-zot/zot-linux-arm64:latest