Skip to content

Commit c23da0a

Browse files
devin-ai-integration[bot]ana@graphops.xyz
andauthored
feat(erigon): add lz4 snapshot support (#489)
--------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: ana@graphops.xyz <ana@graphops.xyz>
1 parent 9e447be commit c23da0a

File tree

4 files changed

+64
-26
lines changed

4 files changed

+64
-26
lines changed

.helmdocsignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
charts/**/tests/**
2-
charts/**/_unittests/**
1+
charts/*/tests/*
2+
charts/*/_unittests/*

charts/erigon/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ We do not recommend that you upgrade the application by overriding `image.tag`.
147147
| rpcdaemon.extraLabels | Extra labels to attach to the Pod for matching against | object | `{}` |
148148
| rpcdaemon.nodeSelector | | object | `{}` |
149149
| rpcdaemon.podAnnotations | Annotations for the `Pod` | object | `{}` |
150-
| rpcdaemon.podSecurityContext | Pod-wide security context | object | `{"fsGroup":101337,"runAsGroup":101337,"runAsNonRoot":true,"runAsUser":101337}` |
150+
| rpcdaemon.podSecurityContext | Pod-wide security context | object | `{"fsGroup":1000,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000}` |
151151
| rpcdaemon.replicaCount | Number of replicas to run | int | `2` |
152152
| rpcdaemon.resources.limits | | object | `{}` |
153153
| rpcdaemon.resources.requests | Requests must be specified if you are using autoscaling | object | `{"cpu":"500m","memory":"4Gi"}` |
@@ -160,6 +160,7 @@ We do not recommend that you upgrade the application by overriding `image.tag`.
160160
| serviceAccount.name | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | string | `""` |
161161
| statefulNode.affinity | | object | `{}` |
162162
| statefulNode.affinityPresets.antiAffinityByHostname | Configure anti-affinity rules to prevent multiple Erigon instances on the same host | bool | `true` |
163+
| statefulNode.datadir | The path to the Erigon data directory | string | `"/storage"` |
163164
| statefulNode.extraArgs | Additional CLI arguments to pass to `erigon` | list | `[]` |
164165
| statefulNode.extraContainers | Additional containers to inject to this graph node group - an array of Container objects | list | `[]` |
165166
| statefulNode.extraInitContainers | Additional init containers to inject to this graph node group - an array of Container objects | list | `[]` |
@@ -177,7 +178,7 @@ We do not recommend that you upgrade the application by overriding `image.tag`.
177178
| statefulNode.p2pNodePort.initContainer.image.tag | Container tag | string | `"v1.25.4"` |
178179
| statefulNode.p2pNodePort.port | NodePort to be used. Must be unique. | int | `31000` |
179180
| statefulNode.podAnnotations | Annotations for the `Pod` | object | `{}` |
180-
| statefulNode.podSecurityContext | Pod-wide security context | object | `{"fsGroup":101337,"runAsGroup":101337,"runAsNonRoot":true,"runAsUser":101337}` |
181+
| statefulNode.podSecurityContext | Pod-wide security context | object | `{"fsGroup":1000,"runAsGroup":1000,"runAsNonRoot":true,"runAsUser":1000}` |
181182
| statefulNode.readinessProbe | Sets a readinessProbe configuration for the container | object | `{}` |
182183
| statefulNode.resources | | object | `{}` |
183184
| statefulNode.restoreSnapshot.enabled | Enable initialising Erigon state from a remote snapshot | bool | `false` |

charts/erigon/templates/stateful-node/statefulset.yaml

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -73,46 +73,80 @@ spec:
7373
emptyDir: {}
7474
{{- end }}
7575
initContainers:
76+
- name: set-permissions
77+
image: docker.io/busybox:1.37.0
78+
imagePullPolicy: IfNotPresent
79+
securityContext:
80+
runAsNonRoot: false
81+
runAsUser: 0
82+
command:
83+
- sh
84+
- -ac
85+
- |
86+
set -ex;
87+
if [ ! -f /storage/permissions_set ]; then
88+
chown -R 1000:1000 /storage;
89+
chmod -R 750 /storage;
90+
touch /storage/permissions_set
91+
else
92+
echo "Permissions already set, skipping"
93+
fi
94+
volumeMounts:
95+
- name: storage
96+
mountPath: "/storage"
7697
{{- if $values.restoreSnapshot.enabled }}
7798
- name: init-snapshot
78-
image: busybox:stable
99+
image: ghcr.io/graphops/docker-builds/init-stream-download:main
79100
imagePullPolicy: IfNotPresent
101+
securityContext:
102+
runAsNonRoot: true
103+
runAsUser: 1000
80104
command:
81105
- sh
82106
- -c
83107
- |
84-
set -x
108+
set -ex
85109
STORAGE_PATH="/storage"
86-
if [ "${SNAPSHOT_RESTORE_PATH}" == "" ]; then
87-
SNAPSHOT_RESTORE_PATH="$STORAGE_PATH/chaindata"
88-
else
89-
SNAPSHOT_RESTORE_PATH="${SNAPSHOT_RESTORE_PATH}"
90-
fi
110+
CHAINDATA_PATH="$STORAGE_PATH/chaindata"
91111
# If enabled and snapshot URL has been provided, restore snapshot
92112
if [ "${RESTORE_SNAPSHOT}" = "true" ] && [ "${SNAPSHOT_URL}" != "" ]; then
93113
echo "Snapshot restoration enabled"
94114
if [ ! -f "$STORAGE_PATH/from_snapshot" ] || [ "$(cat $STORAGE_PATH/from_snapshot)" != "${SNAPSHOT_URL}" ]; then
95115
echo "Clearing existing chaindata..."
96-
rm -rf "$SNAPSHOT_RESTORE_PATH"
116+
# Only remove chaindata directory, preserving from_snapshot file
117+
rm -rf "$CHAINDATA_PATH"
97118
echo "Downloading and extracting $SNAPSHOT_URL..."
98-
mkdir -p "$SNAPSHOT_RESTORE_PATH"
99-
wget -c "${SNAPSHOT_URL}" -O - | tar -xz -C "$SNAPSHOT_RESTORE_PATH"
100-
[ "$?" != "0" ] && echo "Streaming download failed" && exit 1
119+
mkdir -p "$CHAINDATA_PATH"
120+
121+
# Check if the snapshot is lz4 compressed
122+
if [[ "${SNAPSHOT_URL}" == *.tar.lz4 ]]; then
123+
cd "$STORAGE_PATH"
124+
wget -c "${SNAPSHOT_URL}" -O snapshot.tar.lz4 || { echo "Download failed. Exiting."; exit 1; }
125+
lz4 -d snapshot.tar.lz4 snapshot.tar || { echo "Decompression failed. Exiting."; exit 1; }
126+
tar -xvf snapshot.tar -C "$CHAINDATA_PATH" || { echo "Extraction failed. Exiting."; exit 1; }
127+
rm snapshot.tar snapshot.tar.lz4
128+
else
129+
# Original tar extraction logic
130+
wget -c "${SNAPSHOT_URL}" -O - | tar -xz -C "$CHAINDATA_PATH"
131+
[ "$?" != "0" ] && echo "Streaming download failed" && exit 1
132+
fi
133+
101134
echo "${SNAPSHOT_URL}" > ${STORAGE_PATH}/from_snapshot
102135
else
103136
echo "Snapshot configuration already restored, continuing..."
104137
fi
105138
else
106139
echo "Snapshot restoration not enabled, skipping..."
107140
fi
141+
# Ensure directories are writable
142+
chmod -R 777 "$STORAGE_PATH" "$CHAINDATA_PATH"
108143
volumeMounts:
109144
- name: storage
110-
mountPath: /storage
145+
mountPath: {{ $values.datadir }}
111146
env:
112147
- name: RESTORE_SNAPSHOT
113148
value: "true"
114-
- name: SNAPSHOT_RESTORE_PATH
115-
value: {{ $values.restoreSnapshot.snapshotRestorePath | default "" }}
149+
116150
- name: SNAPSHOT_URL
117151
value: {{ $values.restoreSnapshot.snapshotUrl }}
118152
{{- with $values.env }}
@@ -192,7 +226,7 @@ spec:
192226
{{- end }}
193227
set -ex;
194228
exec erigon \
195-
--datadir=/storage \
229+
--datadir={{ $values.datadir }} \
196230
{{- if $values.p2pNodePort.enabled }}
197231
--nat=extip:${EXTERNAL_IP} \
198232
--port=${EXTERNAL_PORT} \
@@ -252,7 +286,7 @@ spec:
252286
mountPath: /jwt
253287
{{- end }}
254288
- name: storage
255-
mountPath: /storage
289+
mountPath: {{ $values.datadir }}
256290
- name: tmp
257291
mountPath: /tmp
258292
{{- if $values.readinessProbe }}

charts/erigon/values.yaml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ statefulNode:
8585
# -- Extra labels to attach to the Pod for matching against
8686
extraLabels: {}
8787

88+
# -- The path to the Erigon data directory
89+
datadir: /storage
90+
8891
# -- [PersistentVolumeClaimSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#persistentvolumeclaimspec-v1-core) for Erigon storage
8992
volumeClaimSpec:
9093
accessModes: ["ReadWriteOnce"]
@@ -132,9 +135,9 @@ statefulNode:
132135
# -- Pod-wide security context
133136
podSecurityContext:
134137
runAsNonRoot: true
135-
runAsUser: 101337
136-
runAsGroup: 101337
137-
fsGroup: 101337
138+
runAsUser: 1000
139+
runAsGroup: 1000
140+
fsGroup: 1000
138141

139142
service:
140143
topologyAwareRouting:
@@ -220,9 +223,9 @@ rpcdaemon:
220223
# -- Pod-wide security context
221224
podSecurityContext:
222225
runAsNonRoot: true
223-
runAsUser: 101337
224-
runAsGroup: 101337
225-
fsGroup: 101337
226+
runAsUser: 1000
227+
runAsGroup: 1000
228+
fsGroup: 1000
226229

227230
service:
228231
type: ClusterIP

0 commit comments

Comments
 (0)