From 0d6defa41e0be337f6560e7b179ac21d73d0b8e9 Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Wed, 30 Oct 2024 15:43:46 +0100 Subject: [PATCH 01/11] OP node stopped flag depending on RID --- .../templates/service-rpc-individual.yaml | 1 + charts/op-node/templates/statefulset.yaml | 20 +++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/charts/op-node/templates/service-rpc-individual.yaml b/charts/op-node/templates/service-rpc-individual.yaml index 6f1c6cfd..386cbfee 100644 --- a/charts/op-node/templates/service-rpc-individual.yaml +++ b/charts/op-node/templates/service-rpc-individual.yaml @@ -2,6 +2,7 @@ {{ range $index, $e := until (int $replicas) }} {{- with $.Values.services.rpc }} {{- if and .individualServiceEnabled }} +--- apiVersion: v1 kind: Service metadata: diff --git a/charts/op-node/templates/statefulset.yaml b/charts/op-node/templates/statefulset.yaml index d75b15db..6333b038 100644 --- a/charts/op-node/templates/statefulset.yaml +++ b/charts/op-node/templates/statefulset.yaml @@ -116,12 +116,26 @@ spec: {{- end }} args: - | + RID=$(echo $HOSTNAME | sed 's/{{ .Release.Name }}-//') datadir="{{ .Values.persistence.mountPath | default .Values.config.rollup.config }}" advertiseIpFlag="" if [ -f $datadir/advertiseIP ]; then advertiseIpFlag="--p2p.advertise.ip=$(cat $datadir/advertiseIP)" fi + # Check if conductor is enabled and start extra copies stopped + sequencerFlag="" + {{- if .Values.config.sequencer.enabled }} + sequencerFlag="--sequencer.enabled" + {{- if not .Values.config.conductor.enabled }} + if [ "$RID" -gt 0 ]; then + stoppedFlag="--sequencer.stopped" + else + stoppedFlag="" + fi + {{- end }} + {{- end }} + exec op-node \ --l1=$L1_URL \ --l1.trustrpc={{ .Values.config.l1.trustrpc }} \ @@ -150,11 +164,9 @@ spec: {{- if .Values.config.safedbPath }} --safedb-path={{ .Values.config.safedbPath }} \ {{- end }} + $sequencerFlag \ + $stoppedFlag \ {{- if .Values.config.sequencer.enabled }} - --sequencer.enabled \ - {{- if .Values.config.sequencer.stopped }} - --sequencer.stopped \ - {{- end }} {{- if kindIs "int" .Values.config.sequencer.l1Confs }} --sequencer.l1-confs={{ int .Values.config.sequencer.l1Confs }} \ {{- end }} From 2763404c4b32efdc643ead21e23191aefc82f62e Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Wed, 30 Oct 2024 16:20:37 +0100 Subject: [PATCH 02/11] Chart version --- charts/op-node/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/op-node/Chart.yaml b/charts/op-node/Chart.yaml index f7feb7fa..a6e24ece 100644 --- a/charts/op-node/Chart.yaml +++ b/charts/op-node/Chart.yaml @@ -1,7 +1,7 @@ --- name: op-node apiVersion: v2 -version: 0.4.6 +version: 0.4.7 description: Celo implementation for op-node consensus engine (Optimism Rollup) home: https://clabs.co sources: From 36ee137a74c29fbe13fccc33dfb5c6482406d8f0 Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Wed, 30 Oct 2024 15:23:21 +0000 Subject: [PATCH 03/11] [Automatic] - Update chart README.md --- charts/op-node/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/op-node/README.md b/charts/op-node/README.md index 8666917a..e763d1ca 100644 --- a/charts/op-node/README.md +++ b/charts/op-node/README.md @@ -1,6 +1,6 @@ # op-node -![Version: 0.4.6](https://img.shields.io/badge/Version-0.4.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.0.0](https://img.shields.io/badge/AppVersion-v1.0.0-informational?style=flat-square) +![Version: 0.4.7](https://img.shields.io/badge/Version-0.4.7-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.0.0](https://img.shields.io/badge/AppVersion-v1.0.0-informational?style=flat-square) Celo implementation for op-node consensus engine (Optimism Rollup) Initially based on [dysnix/charts/op-node](https://github.com/dysnix/charts/tree/main/dysnix/op-node). From 18e5c17533048a0066c7e394831c1e402a5f4613 Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Wed, 30 Oct 2024 22:47:17 +0100 Subject: [PATCH 04/11] Fixes and conductor RID --- charts/op-conductor/Chart.yaml | 2 +- .../templates/configmap-scripts.yaml | 11 ++++ .../templates/scripts/_download-rollup.tpl | 11 ++++ .../scripts/_split-config-parameters.tpl | 45 ++++++++++++++ .../op-conductor/templates/statefulset.yaml | 62 +++++-------------- charts/op-conductor/values.yaml | 15 ++--- .../scripts/_split-config-parameters.tpl | 11 ++++ charts/op-node/templates/statefulset.yaml | 6 +- charts/op-node/values.yaml | 6 +- 9 files changed, 111 insertions(+), 58 deletions(-) create mode 100644 charts/op-conductor/templates/configmap-scripts.yaml create mode 100644 charts/op-conductor/templates/scripts/_download-rollup.tpl create mode 100644 charts/op-conductor/templates/scripts/_split-config-parameters.tpl diff --git a/charts/op-conductor/Chart.yaml b/charts/op-conductor/Chart.yaml index 92e8fde8..9bdb3c9b 100644 --- a/charts/op-conductor/Chart.yaml +++ b/charts/op-conductor/Chart.yaml @@ -1,7 +1,7 @@ --- name: op-conductor apiVersion: v2 -version: 0.0.5 +version: 0.0.6 description: Helm chart deploying OP Conductor, a HA controller for op-node home: https://clabs.co sources: diff --git a/charts/op-conductor/templates/configmap-scripts.yaml b/charts/op-conductor/templates/configmap-scripts.yaml new file mode 100644 index 00000000..308588c0 --- /dev/null +++ b/charts/op-conductor/templates/configmap-scripts.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "op-conductor.fullname" . }}-scripts + labels: + {{- include "op-conductor.labels" . | nindent 4 }} +data: + download-rollup.sh: |- + {{- include (print $.Template.BasePath "/scripts/_download-rollup.tpl") . | nindent 4 }} + split-config-parameters.sh: |- + {{- include (print $.Template.BasePath "/scripts/_split-config-parameters.tpl") . | nindent 4 }} diff --git a/charts/op-conductor/templates/scripts/_download-rollup.tpl b/charts/op-conductor/templates/scripts/_download-rollup.tpl new file mode 100644 index 00000000..38dcd5d7 --- /dev/null +++ b/charts/op-conductor/templates/scripts/_download-rollup.tpl @@ -0,0 +1,11 @@ +#!/usr/bin/env sh +set -e + +datadir="{{ .Values.persistence.mountPath }}" +if [ ! -f $datadir/.initialized ]; then + wget -qO $datadir/rollup.json "{{ .Values.init.rollup.url }}" + touch $datadir/.initialized + echo "Successfully downloaded rollup files" +else + echo "Already downloaded, skipping." +fi diff --git a/charts/op-conductor/templates/scripts/_split-config-parameters.tpl b/charts/op-conductor/templates/scripts/_split-config-parameters.tpl new file mode 100644 index 00000000..fb3c4759 --- /dev/null +++ b/charts/op-conductor/templates/scripts/_split-config-parameters.tpl @@ -0,0 +1,45 @@ +#!/usr/bin/env sh + +# Get Replica ID from hostname +RID=$(echo $HOSTNAME | sed 's/{{ .Release.Name }}-//') +datadir="{{ .Values.persistence.mountPath }}" + +# Split the advertised addresses based on the comma and get the $RID-th key +loadBalancerIps="{{ join "," .Values.services.consensus.loadBalancerIPs }}" +clusterIps="{{ join "," .Values.services.consensus.clusterIPs }}" +# If the loadBalancerIPs are defined, use them +if [ -n "$loadBalancerIps" ]; then + advertiseIp=$(echo "$loadBalancerIps" | tr ',' '\n' | sed -n "$((RID + 1))p") +# If the clusterIPs are defined now, use them +elif [ -n "$clusterIps" ]; then + advertiseIp=$(echo "$clusterIps" | tr ',' '\n' | sed -n "$((RID + 1))p") +# If none of the above are defined, use pod's ip +else + advertiseIp="$(hostname -i)" +fi +if [ -z "$advertiseIp" ]; then + echo "Could not determine advertise address" + exit 1 +fi +echo "Setting advertise address to $advertiseIp" +echo "$advertiseIp" > "$datadir/advertiseIP" + +# Get the execution url +executionUrl="" +if [ -n "{{ .Values.config.execution.url }}" ]; then + executionUrl="{{ .Values.config.execution.url }}" +else + executionUrl="{{ .Values.config.execution.protocol }}://{{ .Values.config.execution.namePattern }}-$RID:{{ .Values.config.execution.port }}" +fi +echo "Setting execution url to $executionUrl" +echo "$executionUrl" > "$datadir/executionUrl" + +# Get the node url +nodeUrl="" +if [ -n "{{ .Values.config.node.url }}" ]; then + nodeUrl="{{ .Values.config.node.url }}" +else + nodeUrl="{{ .Values.config.node.protocol }}://{{ .Values.config.node.namePattern }}-$RID:{{ .Values.config.node.port }}" +fi +echo "Setting execution url to $nodeUrl" +echo "$nodeUrl" > "$datadir/nodeUrl" diff --git a/charts/op-conductor/templates/statefulset.yaml b/charts/op-conductor/templates/statefulset.yaml index 9cdd2e42..a8f550a6 100644 --- a/charts/op-conductor/templates/statefulset.yaml +++ b/charts/op-conductor/templates/statefulset.yaml @@ -36,20 +36,10 @@ spec: securityContext: {{- toYaml . | nindent 10 }} {{- end }} - command: - - /bin/sh - - -c - args: - - | - datadir="{{ .Values.persistence.mountPath }}" - if [ ! -f $datadir/.initialized ]; then - wget -qO $datadir/rollup.json "{{ .Values.init.rollup.url }}" - touch $datadir/.initialized - echo "Successfully downloaded rollup files" - else - echo "Already downloaded, skipping." - fi + command: ["sh", "/scripts/download-rollup.sh"] volumeMounts: + - name: scripts + mountPath: /scripts - name: data mountPath: {{ .Values.persistence.mountPath }} - name: split-config-parameters @@ -59,31 +49,10 @@ spec: securityContext: {{- toYaml . | nindent 10 }} {{- end }} - command: - - /bin/sh - - -c - args: - - | - # Get Replica ID from hostname - RID=$(echo $HOSTNAME | sed 's/{{ .Release.Name }}-//') - datadir="{{ .Values.persistence.mountPath }}" - - # Get the IP used for consensus. First try to get the service IP, then the pod IP - if [ -z "{{ .Values.config.consensus.addr }}" ]; then - SERVICE_NAME="{{ include "op-conductor.fullname" . | replace "-" "_" | upper }}_CONSENSUS_$RID" - SERVICE_IP=$(eval echo \$$SERVICE_NAME) - if [ -n "$SERVICE_IP" ]; then - echo "Using service IP for consensus" - echo $SERVICE_IP > "$datadir/consensus.addr" - else - echo "Using pod IP for consensus" - echo $(hostname -i) > "$datadir/consensus.addr" - fi - else - echo "{{ .Values.config.consensus.addr }}" > "$datadir/consensus.addr" - fi - echo "Using consensus address: $(cat $datadir/consensus.addr)" + command: ["sh", "/scripts/split-config-parameters.sh"] volumeMounts: + - name: scripts + mountPath: /scripts - name: data mountPath: {{ .Values.persistence.mountPath }} containers: @@ -93,21 +62,20 @@ spec: - -c args: - | + RID=$(echo $HOSTNAME | sed 's/{{ .Release.Name }}-//') datadir="{{ .Values.persistence.mountPath }}" bootstrap_flag="--raft.bootstrap=false" # Check if we need to bootstrap the raft cluster - {{- if .Values.config.raft.bootstrap }} - if [ ! -d $datadir/{{ .Values.config.raft.server.id }} ]; then + if [ ! -d $datadir/$RID ] && [ "$RID" -eq 2 ]; then bootstrap_flag="--raft.bootstrap=true" fi - {{- end }} exec /usr/local/bin/op-conductor \ - --consensus.addr=$(cat $datadir/consensus.addr) \ + --consensus.addr=$(cat $datadir/advertiseIP) \ --consensus.port={{ .Values.config.consensus.port }} \ - --execution.rpc={{ .Values.config.execution.rpc }} \ - --node.rpc={{ .Values.config.node.rpc }} \ - --rollup.config={{ .Values.persistence.mountPath }}/rollup.json \ + --execution.rpc=$(cat $datadir/executionUrl) \ + --node.rpc=$(cat $datadir/nodeUrl) \ + --rollup.config=$datadir/rollup.json \ --rpc.addr={{ .Values.config.rpc.addr }} \ --rpc.port={{ .Values.config.rpc.port }} \ {{- if .Values.config.rpc.enableAdmin }} @@ -117,7 +85,7 @@ spec: --rpc.enable-proxy \ {{- end }} $bootstrap_flag \ - --raft.server.id={{ .Values.config.raft.server.id }} \ + --raft.server.id=$RID \ --raft.storage.dir={{ .Values.persistence.mountPath }} \ --healthcheck.interval={{ .Values.config.healthcheck.interval }} \ --healthcheck.min-peer-count={{ .Values.config.healthcheck.minPeerCount }} \ @@ -159,6 +127,10 @@ spec: volumeMounts: - mountPath: /raft name: data + volumes: + - name: scripts + configMap: + name: {{ template "op-conductor.fullname" . }}-scripts updateStrategy: rollingUpdate: partition: 0 diff --git a/charts/op-conductor/values.yaml b/charts/op-conductor/values.yaml index b94fda9a..cf1c27f7 100644 --- a/charts/op-conductor/values.yaml +++ b/charts/op-conductor/values.yaml @@ -21,19 +21,16 @@ config: execution: # execution engine (op-geth) rpc endpoint rpc: http://op-geth:8545 + protocol: "" # Used for multiReplica. Leave url empty if using multiReplica + namePattern: "" # Used for multiReplica. Set to the op-geth sts name pattern. Example: "op-geth-validator-authrpc" + port: "" # Used for multiReplica. Port of op-geth L2 node with multiReplica node: rpc: http://op-node:8547 + protocol: "" # Used for multiReplica. Leave url empty if using multiReplica + namePattern: "" # Used for multiReplica. Set to the op-node sts name pattern. Example: "op-geth-validator-authrpc" + port: "" # Used for multiReplica. Port of op-node L2 node with multiReplica consensus: - # Address to listen for consensus connections. It cannot be 0. If empty, it will try to use - # the service ip or the pod ip. - addr: "" port: 50050 - raft: - bootstrap: false - server: - id: 1 - storage: - dir: /raft rpc: enableAdmin: false enableProxy: true diff --git a/charts/op-node/templates/scripts/_split-config-parameters.tpl b/charts/op-node/templates/scripts/_split-config-parameters.tpl index 88e7e066..54567577 100644 --- a/charts/op-node/templates/scripts/_split-config-parameters.tpl +++ b/charts/op-node/templates/scripts/_split-config-parameters.tpl @@ -53,3 +53,14 @@ else fi echo "Setting L2 url to $l2Url" echo "$l2Url" > "$datadir/l2Url" + + +# Get the conductor url +conductorRpcUrl="" +if [ -n "{{ .Values.config.conductor.rpc.url }}" ]; then + conductorRpcUrl="{{ .Values.config.conductor.rpc.url }}" +else + conductorRpcUrl="{{ .Values.config.conductor.rpc.protocol }}://{{ .Values.config.conductor.rpc.namePattern }}-$RID:{{ .Values.config.conductor.rpc.port }}" +fi +echo "Setting conductor url to $conductorRpcUrl" +echo "$conductorRpcUrl" > "$datadir/conductorRpcUrl" diff --git a/charts/op-node/templates/statefulset.yaml b/charts/op-node/templates/statefulset.yaml index 6333b038..af335ceb 100644 --- a/charts/op-node/templates/statefulset.yaml +++ b/charts/op-node/templates/statefulset.yaml @@ -127,7 +127,9 @@ spec: sequencerFlag="" {{- if .Values.config.sequencer.enabled }} sequencerFlag="--sequencer.enabled" - {{- if not .Values.config.conductor.enabled }} + {{- if .Values.config.conductor.enabled }} + stoppedFlag="" + {{- else }} if [ "$RID" -gt 0 ]; then stoppedFlag="--sequencer.stopped" else @@ -178,7 +180,7 @@ spec: {{- end }} {{- if .Values.config.conductor.enabled }} --conductor.enabled \ - --conductor.rpc={{ .Values.config.conductor.rpc }} \ + --conductor.rpc=$(cat $datadir/conductorRpcUrl) \ --conductor.rpc-timeout={{ .Values.config.conductor.rpcTimeout }} \ {{- end }} {{- end }} diff --git a/charts/op-node/values.yaml b/charts/op-node/values.yaml index 21a78fd7..9b13074b 100644 --- a/charts/op-node/values.yaml +++ b/charts/op-node/values.yaml @@ -248,8 +248,12 @@ config: l1Confs: 0 # number of L1 blocks to keep distance from the L1 head before deriving L2 data from conductor: enabled: false # Enable the conductor service - rpc: http://127.0.0.1:8547 # Conductor service rpc endpoint rpcTimeout: 1s # Conductor service rpc timeout + rpc: + url: http://127.0.0.1:8547 # Conductor service rpc endpoint + protocol: "" # Used for multiReplica. Leave url empty if using multiReplica + namePattern: "" # Used for multiReplica. Set to the op-conductor sts name pattern. Example: "op-conductor-rpc" + port: "" # Used for multiReplica. Port of op-conductor with multiReplica altda: enabled: false # enable altda daServer: "" # altda data availability server From 6ace09136ae091daa9dc56053d3f36d32bb7fafb Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Wed, 30 Oct 2024 21:49:54 +0000 Subject: [PATCH 05/11] [Automatic] - Update chart README.md --- charts/op-conductor/README.md | 12 +++++++----- charts/op-node/README.md | 5 ++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/charts/op-conductor/README.md b/charts/op-conductor/README.md index 08c288d6..d4f7dbd6 100644 --- a/charts/op-conductor/README.md +++ b/charts/op-conductor/README.md @@ -1,6 +1,6 @@ # op-conductor -![Version: 0.0.5](https://img.shields.io/badge/Version-0.0.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.8.0](https://img.shields.io/badge/AppVersion-v1.8.0-informational?style=flat-square) +![Version: 0.0.6](https://img.shields.io/badge/Version-0.0.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.8.0](https://img.shields.io/badge/AppVersion-v1.8.0-informational?style=flat-square) Helm chart deploying OP Conductor, a HA controller for op-node @@ -24,8 +24,10 @@ Helm chart deploying OP Conductor, a HA controller for op-node | Key | Type | Default | Description | |-----|------|---------|-------------| -| config.consensus.addr | string | `""` | | | config.consensus.port | int | `50050` | | +| config.execution.namePattern | string | `""` | | +| config.execution.port | string | `""` | | +| config.execution.protocol | string | `""` | | | config.execution.rpc | string | `"http://op-geth:8545"` | | | config.healthcheck.interval | int | `10` | | | config.healthcheck.minPeerCount | int | `1` | | @@ -38,11 +40,11 @@ Helm chart deploying OP Conductor, a HA controller for op-node | config.metrics.enabled | bool | `true` | | | config.metrics.port | int | `7300` | | | config.network | string | `""` | | +| config.node.namePattern | string | `""` | | +| config.node.port | string | `""` | | +| config.node.protocol | string | `""` | | | config.node.rpc | string | `"http://op-node:8547"` | | | config.paused | bool | `false` | | -| config.raft.bootstrap | bool | `false` | | -| config.raft.server.id | int | `1` | | -| config.raft.storage.dir | string | `"/raft"` | | | config.rpc.addr | string | `"0.0.0.0"` | | | config.rpc.enableAdmin | bool | `false` | | | config.rpc.enableProxy | bool | `true` | | diff --git a/charts/op-node/README.md b/charts/op-node/README.md index e763d1ca..05163d60 100644 --- a/charts/op-node/README.md +++ b/charts/op-node/README.md @@ -32,7 +32,10 @@ Initially based on [dysnix/charts/op-node](https://github.com/dysnix/charts/tree | config.altda.enabled | bool | `false` | | | config.altda.verifyOnRead | bool | `false` | | | config.conductor.enabled | bool | `false` | | -| config.conductor.rpc | string | `"http://127.0.0.1:8547"` | | +| config.conductor.rpc.namePattern | string | `""` | | +| config.conductor.rpc.port | string | `""` | | +| config.conductor.rpc.protocol | string | `""` | | +| config.conductor.rpc.url | string | `"http://127.0.0.1:8547"` | | | config.conductor.rpcTimeout | string | `"1s"` | | | config.enableAdmin | bool | `false` | | | config.jwt | string | `""` | | From 67caefb64707a6aaa55ecd8ae71d495d9659ea2f Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Thu, 31 Oct 2024 15:08:51 +0100 Subject: [PATCH 06/11] WIP op-conductor-start-tool chart --- charts/op-conductor-start-tool/Chart.yaml | 27 ++++ .../templates/_helpers.tpl | 52 +++++++ .../templates/cronjob.yaml | 127 ++++++++++++++++++ charts/op-conductor-start-tool/values.yaml | 21 +++ 4 files changed, 227 insertions(+) create mode 100644 charts/op-conductor-start-tool/Chart.yaml create mode 100644 charts/op-conductor-start-tool/templates/_helpers.tpl create mode 100644 charts/op-conductor-start-tool/templates/cronjob.yaml create mode 100644 charts/op-conductor-start-tool/values.yaml diff --git a/charts/op-conductor-start-tool/Chart.yaml b/charts/op-conductor-start-tool/Chart.yaml new file mode 100644 index 00000000..0d0ff754 --- /dev/null +++ b/charts/op-conductor-start-tool/Chart.yaml @@ -0,0 +1,27 @@ +--- +name: op-conductor-start-tool +apiVersion: v2 +version: 0.0.1 +description: OP Conductor start tool Cel2 network +home: https://clabs.co +sources: + - https://celo.org + - https://docs.celo.org + - https://clabs.co + - https://github.com/celo-org +keywords: + - celo + - blockchain + - optimism + - rollup + - ethereum + - layer2 + - op-stack + - op-conductor +maintainers: + - name: cLabs + email: devops@clabs.co + url: https://clabs.co +type: application +icon: https://pbs.twimg.com/profile_images/1613170131491848195/InjXBNx9_400x400.jpg +appVersion: v1.0.0 diff --git a/charts/op-conductor-start-tool/templates/_helpers.tpl b/charts/op-conductor-start-tool/templates/_helpers.tpl new file mode 100644 index 00000000..c658941d --- /dev/null +++ b/charts/op-conductor-start-tool/templates/_helpers.tpl @@ -0,0 +1,52 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "op-conductor-start-tool.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "op-conductor-start-tool.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "op-conductor-start-tool.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "op-conductor-start-tool.labels" -}} +helm.sh/chart: {{ include "op-conductor-start-tool.chart" . }} +{{ include "op-conductor-start-tool.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "op-conductor-start-tool.selectorLabels" -}} +app.kubernetes.io/name: {{ include "op-conductor-start-tool.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/op-conductor-start-tool/templates/cronjob.yaml b/charts/op-conductor-start-tool/templates/cronjob.yaml new file mode 100644 index 00000000..3cd8da74 --- /dev/null +++ b/charts/op-conductor-start-tool/templates/cronjob.yaml @@ -0,0 +1,127 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ .Release.Name }} + labels: + {{- include "op-conductor-start-tool.labels" . | nindent 4 }} + component: op-conductor-start-tool +spec: + schedule: "{{ .Values.schedule }}" + suspend: {{ .Values.suspend }} + concurrencyPolicy: Forbid + jobTemplate: + spec: + backoffLimit: 0 + template: + metadata: + labels: + {{- include "op-conductor-start-tool.labels" . | nindent 12 }} + spec: + containers: + - name: switch-and-start + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /bin/sh + - -c + args: + - | + apk add curl + apk add jq + + first=0 + last=$(( {{ .Values.opNode.replicas }} - 1 )) + + echo "Check OP Node status" + i=0 + while [ $i -lt {{ .Values.opNode.replicas }} ] + do + echo "Checking OP Node $i" + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"admin_sequencerActive","params":[],"id":1}' \ + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$i:{{ .Values.opNode.port }} -s | jq .result > /tmp/RESULT_NODE_${i}_ACTIVE + echo "OP Node $i active? $(cat /tmp/RESULT_NODE_${i}_ACTIVE)" + i=$((i + 1)) + done + + echo "Check OP Conductor status" + i=0 + while [ $i -lt {{ .Values.opConductor.replicas }} ] + do + echo "Checking OP Conductor $i" + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_stopped","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$i:{{ .Values.opConductor.rpc.port }} -s | jq .result > /tmp/RESULT_COND_${i}_STOPPED + echo "OP Conductor $i stopped? $(cat /tmp/RESULT_COND_${i}_STOPPED)" + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_paused","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$i:{{ .Values.opConductor.rpc.port }} -s | jq .result > /tmp/RESULT_COND_${i}_PAUSED + echo "OP Conductor $i paused? $(cat /tmp/RESULT_COND_${i}_PAUSED)" + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_sequencerHealthy","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$i:{{ .Values.opConductor.rpc.port }} -s | jq .result > /tmp/RESULT_COND_${i}_SEQ_HEALTHY + echo "OP Conductor $i sequencer healthy? $(cat /tmp/RESULT_COND_${i}_SEQ_HEALTHY)" + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$i:{{ .Values.opConductor.rpc.port }} -s | jq .result > /tmp/RESULT_COND_${i}_LEADER + echo "OP Conductor $i leader? $(cat /tmp/RESULT_COND_${i}_LEADER)" + i=$((i + 1)) + done + + if [ $(cat /tmp/RESULT_NODE_0_ACTIVE) = "true" ] && [ $(cat /tmp/RESULT_NODE_2_ACTIVE) = "false" ] && \ + [ $(cat /tmp/RESULT_COND_2_STOPPED) = "false" ] && \ + [ $(cat /tmp/RESULT_COND_2_PAUSED) = "true" ] && \ + [ $(cat /tmp/RESULT_COND_2_SEQ_HEALTHY) = "true" ] && \ + [ $(cat /tmp/RESULT_COND_2_LEADER) = "true" ]; then + echo "Requirements for switch and start are met" + else + echo "Requirements for switch and start are NOT met. Exiting..." + exit 1 + fi + + echo "Stopping OP Node $first" + LAST_UNSAFE_HASH=$(curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' \ + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$first:{{ .Values.opNode.port }} -s | jq .result) + echo "Stopped OP Node $first with unsafe hash $LAST_UNSAFE_HASH. Starting OP Node $last..." + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"admin_startSequencer","params":["$LAST_UNSAFE_HASH"],"id":1}' \ + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s + if [ $? -eq 0 ]; then + echo "Started OP Node $last" + else + echo "Failed to start OP Node $last" + exit 1 + fi + + echo "Forming raft cluster..." + echo "Checking OP Conductor $last is leader" + CHECK_LEADER=$(curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq .result) + if [ ! $CHECK_LEADER = "true" ]; then + echo "OP Conductor $last is NOT the leader, exiting..." + exit 1 + fi + i=0 + while [ $i -lt $(( {{ .Values.opNode.replicas }} -1 )) ] + do + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_addServerAsVoter","params":["$i", "{{ .Values.opConductor.consensus.namePattern }}-$i:{{ .Values.opConductor.consensus.port }}", 0],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq .result) + i=$((i + 1)) + done + echo "Done forming raft cluster" + + echo "Unpausing OP Conductors..." + i=0 + while [ $i -lt {{ .Values.opConductor.replicas }} ] + do + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_resume","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$i:{{ .Values.opConductor.rpc.port }} -s + i=$((i + 1)) + done + echo "OP Conductors unpaused." + + restartPolicy: Never diff --git a/charts/op-conductor-start-tool/values.yaml b/charts/op-conductor-start-tool/values.yaml new file mode 100644 index 00000000..149e72f0 --- /dev/null +++ b/charts/op-conductor-start-tool/values.yaml @@ -0,0 +1,21 @@ +--- +schedule: "0 0 30 2 0" +suspend: true +image: + repository: alpine + tag: 3.19 + pullPolicy: IfNotPresent +opNode: + replicas: 3 + protocol: "http" + namePattern: "op-node-sequencer-rpc" + port: "9545" +opConductor: + replicas: 3 + protocol: "http" + rpc: + namePattern: "op-conductor-rpc" + port: "8545" + consensus: + namePattern: "op-conductor-consensus" + port: "50050" From a3be634e27ecfb2bb5cdd687c710690d0da05501 Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Thu, 31 Oct 2024 14:11:27 +0000 Subject: [PATCH 07/11] [Automatic] - Update chart README.md --- README.md | 1 + charts/op-conductor-start-tool/README.md | 43 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 charts/op-conductor-start-tool/README.md diff --git a/README.md b/README.md index ee3f35c6..4625e8ec 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ The charts are published to the OCI registry at `oci://us-west1-docker.pkg.dev/d - [op-bootnode](./charts/op-bootnode/README.md) - Celo implementation for op-bootnode (Optimism Rollup) - [op-conductor](./charts/op-conductor/README.md) - Helm chart deploying OP Conductor, a HA controller for op-node - [op-conductor-mon](./charts/op-conductor-mon/README.md) - A Helm chart for OP Conductor monitoring +- [op-conductor-start-tool](./charts/op-conductor-start-tool/README.md) - OP Conductor start tool Cel2 network - [op-geth](./charts/op-geth/README.md) - Celo implementation for op-geth execution engine (Optimism Rollup) - [op-geth-bootnode](./charts/op-geth-bootnode/README.md) - Celo implementation for op-geth-bootnode execution engine (Optimism Rollup) - [op-node](./charts/op-node/README.md) - Celo implementation for op-node consensus engine (Optimism Rollup) diff --git a/charts/op-conductor-start-tool/README.md b/charts/op-conductor-start-tool/README.md new file mode 100644 index 00000000..e5686615 --- /dev/null +++ b/charts/op-conductor-start-tool/README.md @@ -0,0 +1,43 @@ +# op-conductor-start-tool + +![Version: 0.0.1](https://img.shields.io/badge/Version-0.0.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.0.0](https://img.shields.io/badge/AppVersion-v1.0.0-informational?style=flat-square) + +OP Conductor start tool Cel2 network + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| cLabs | | | + +## Source Code + +* +* +* +* + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"alpine"` | | +| image.tag | float | `3.19` | | +| opConductor.consensus.namePattern | string | `"op-conductor-consensus"` | | +| opConductor.consensus.port | string | `"50050"` | | +| opConductor.protocol | string | `"http"` | | +| opConductor.replicas | int | `3` | | +| opConductor.rpc.namePattern | string | `"op-conductor-rpc"` | | +| opConductor.rpc.port | string | `"8545"` | | +| opNode.namePattern | string | `"op-node-sequencer-rpc"` | | +| opNode.port | string | `"9545"` | | +| opNode.protocol | string | `"http"` | | +| opNode.replicas | int | `3` | | +| schedule | string | `"0 0 30 2 0"` | | +| suspend | bool | `true` | | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) From 6f940be7e55fbacef9427767362ca66d54f23fde Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Thu, 31 Oct 2024 17:05:33 +0100 Subject: [PATCH 08/11] Script fixes --- .../templates/cronjob.yaml | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/charts/op-conductor-start-tool/templates/cronjob.yaml b/charts/op-conductor-start-tool/templates/cronjob.yaml index 3cd8da74..34c314b1 100644 --- a/charts/op-conductor-start-tool/templates/cronjob.yaml +++ b/charts/op-conductor-start-tool/templates/cronjob.yaml @@ -74,24 +74,28 @@ spec: [ $(cat /tmp/RESULT_COND_2_SEQ_HEALTHY) = "true" ] && \ [ $(cat /tmp/RESULT_COND_2_LEADER) = "true" ]; then echo "Requirements for switch and start are met" + SWITCH=true else echo "Requirements for switch and start are NOT met. Exiting..." - exit 1 + SWITCH=false fi - echo "Stopping OP Node $first" - LAST_UNSAFE_HASH=$(curl -X POST -H "Content-Type: application/json" --data \ - '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' \ - {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$first:{{ .Values.opNode.port }} -s | jq .result) - echo "Stopped OP Node $first with unsafe hash $LAST_UNSAFE_HASH. Starting OP Node $last..." - curl -X POST -H "Content-Type: application/json" --data \ - '{"jsonrpc":"2.0","method":"admin_startSequencer","params":["$LAST_UNSAFE_HASH"],"id":1}' \ - {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s - if [ $? -eq 0 ]; then - echo "Started OP Node $last" - else - echo "Failed to start OP Node $last" - exit 1 + if [ $SWITCH -eq "true"]; then + echo "Stopping OP Node $first" + LAST_UNSAFE_HASH=$(curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' \ + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$first:{{ .Values.opNode.port }} -s | jq .result) + echo "Stopped OP Node $first with unsafe hash $LAST_UNSAFE_HASH. Starting OP Node $last..." + START=$(curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"admin_startSequencer","params":[$LAST_UNSAFE_HASH],"id":1}' \ + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s) + if [ $? -eq 0 ] || [ $LAST -ne "null"]; then + echo "Started OP Node $last" + else + echo "Failed to start OP Node $last" + echo "$START" + exit 1 + fi fi echo "Forming raft cluster..." @@ -108,7 +112,7 @@ spec: do curl -X POST -H "Content-Type: application/json" --data \ '{"jsonrpc":"2.0","method":"conductor_addServerAsVoter","params":["$i", "{{ .Values.opConductor.consensus.namePattern }}-$i:{{ .Values.opConductor.consensus.port }}", 0],"id":1}' \ - {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq .result) + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq .result i=$((i + 1)) done echo "Done forming raft cluster" From 2ad5e111fb5ed6c664f6cee829cb74efee2a8ab0 Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Thu, 31 Oct 2024 20:34:17 +0100 Subject: [PATCH 09/11] Script fixes --- .../templates/cronjob.yaml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/charts/op-conductor-start-tool/templates/cronjob.yaml b/charts/op-conductor-start-tool/templates/cronjob.yaml index 34c314b1..47d3ed32 100644 --- a/charts/op-conductor-start-tool/templates/cronjob.yaml +++ b/charts/op-conductor-start-tool/templates/cronjob.yaml @@ -76,11 +76,11 @@ spec: echo "Requirements for switch and start are met" SWITCH=true else - echo "Requirements for switch and start are NOT met. Exiting..." + echo "Requirements for switch and start are NOT met. Skipping..." SWITCH=false fi - if [ $SWITCH -eq "true"]; then + if [ $SWITCH = true ]; then echo "Stopping OP Node $first" LAST_UNSAFE_HASH=$(curl -X POST -H "Content-Type: application/json" --data \ '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' \ @@ -88,8 +88,8 @@ spec: echo "Stopped OP Node $first with unsafe hash $LAST_UNSAFE_HASH. Starting OP Node $last..." START=$(curl -X POST -H "Content-Type: application/json" --data \ '{"jsonrpc":"2.0","method":"admin_startSequencer","params":[$LAST_UNSAFE_HASH],"id":1}' \ - {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s) - if [ $? -eq 0 ] || [ $LAST -ne "null"]; then + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s | jq .result) + if [ $? -eq 0 ] && [ $START -eq "null"]; then echo "Started OP Node $last" else echo "Failed to start OP Node $last" @@ -101,15 +101,17 @@ spec: echo "Forming raft cluster..." echo "Checking OP Conductor $last is leader" CHECK_LEADER=$(curl -X POST -H "Content-Type: application/json" --data \ - '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ + '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq .result) - if [ ! $CHECK_LEADER = "true" ]; then + if [ "$CHECK_LEADER" = false ]; then echo "OP Conductor $last is NOT the leader, exiting..." exit 1 fi i=0 - while [ $i -lt $(( {{ .Values.opNode.replicas }} -1 )) ] + echo "Sending addServerAsVoter to OP Conductor $last" + while [ $i -lt $(( {{ .Values.opNode.replicas }} - 1 )) ] do + echo "Sending addServerAsVoter to OP Conductor $last for member $i" curl -X POST -H "Content-Type: application/json" --data \ '{"jsonrpc":"2.0","method":"conductor_addServerAsVoter","params":["$i", "{{ .Values.opConductor.consensus.namePattern }}-$i:{{ .Values.opConductor.consensus.port }}", 0],"id":1}' \ {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq .result @@ -121,6 +123,7 @@ spec: i=0 while [ $i -lt {{ .Values.opConductor.replicas }} ] do + echo "Sending conductor_resume to OP Conductor $i" curl -X POST -H "Content-Type: application/json" --data \ '{"jsonrpc":"2.0","method":"conductor_resume","params":[],"id":1}' \ {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$i:{{ .Values.opConductor.rpc.port }} -s From 92477532814e5f1879c0beeec715ef92c2d444ac Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Fri, 1 Nov 2024 10:30:49 +0100 Subject: [PATCH 10/11] Script var fixes --- .../op-conductor-start-tool/templates/cronjob.yaml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/charts/op-conductor-start-tool/templates/cronjob.yaml b/charts/op-conductor-start-tool/templates/cronjob.yaml index 47d3ed32..2380adc3 100644 --- a/charts/op-conductor-start-tool/templates/cronjob.yaml +++ b/charts/op-conductor-start-tool/templates/cronjob.yaml @@ -84,16 +84,21 @@ spec: echo "Stopping OP Node $first" LAST_UNSAFE_HASH=$(curl -X POST -H "Content-Type: application/json" --data \ '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' \ - {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$first:{{ .Values.opNode.port }} -s | jq .result) + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$first:{{ .Values.opNode.port }} -s | jq -r .result) echo "Stopped OP Node $first with unsafe hash $LAST_UNSAFE_HASH. Starting OP Node $last..." START=$(curl -X POST -H "Content-Type: application/json" --data \ - '{"jsonrpc":"2.0","method":"admin_startSequencer","params":[$LAST_UNSAFE_HASH],"id":1}' \ + '{"jsonrpc":"2.0","method":"admin_startSequencer","params":["'${LAST_UNSAFE_HASH}'"],"id":1}' \ {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s | jq .result) - if [ $? -eq 0 ] && [ $START -eq "null"]; then + echo "Checking OP Node $last status" + STARTED=$(curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"admin_sequencerActive","params":[],"id":1}' \ + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s | jq .result) + if [ "$STARTED" = true ]; then echo "Started OP Node $last" else echo "Failed to start OP Node $last" - echo "$START" + echo "admin_startSequencer result: $START" + echo "admin_sequencerActive result: $STARTED" exit 1 fi fi From 1a73e1e9a73ce47fddb371239d65086b84793818 Mon Sep 17 00:00:00 2001 From: alvarof2 Date: Fri, 1 Nov 2024 11:15:49 +0100 Subject: [PATCH 11/11] Fix creating raft cluster --- .../templates/cronjob.yaml | 105 ++++++++++++------ 1 file changed, 70 insertions(+), 35 deletions(-) diff --git a/charts/op-conductor-start-tool/templates/cronjob.yaml b/charts/op-conductor-start-tool/templates/cronjob.yaml index 2380adc3..0d74c1e4 100644 --- a/charts/op-conductor-start-tool/templates/cronjob.yaml +++ b/charts/op-conductor-start-tool/templates/cronjob.yaml @@ -86,54 +86,89 @@ spec: '{"jsonrpc":"2.0","method":"admin_stopSequencer","params":[],"id":1}' \ {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$first:{{ .Values.opNode.port }} -s | jq -r .result) echo "Stopped OP Node $first with unsafe hash $LAST_UNSAFE_HASH. Starting OP Node $last..." - START=$(curl -X POST -H "Content-Type: application/json" --data \ + curl -X POST -H "Content-Type: application/json" --data \ '{"jsonrpc":"2.0","method":"admin_startSequencer","params":["'${LAST_UNSAFE_HASH}'"],"id":1}' \ - {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s | jq .result) - echo "Checking OP Node $last status" + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s + echo "Started OP Node $last, checking OP Node $last status..." STARTED=$(curl -X POST -H "Content-Type: application/json" --data \ '{"jsonrpc":"2.0","method":"admin_sequencerActive","params":[],"id":1}' \ {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$last:{{ .Values.opNode.port }} -s | jq .result) if [ "$STARTED" = true ]; then - echo "Started OP Node $last" + echo "OP Node $last is active" else echo "Failed to start OP Node $last" - echo "admin_startSequencer result: $START" echo "admin_sequencerActive result: $STARTED" + echo "Falling back to activating OP Node $first" + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"admin_startSequencer","params":["'${LAST_UNSAFE_HASH}'"],"id":1}' \ + {{ .Values.opNode.protocol }}://{{ .Values.opNode.namePattern }}-$first:{{ .Values.opNode.port }} -s exit 1 fi fi - echo "Forming raft cluster..." - echo "Checking OP Conductor $last is leader" - CHECK_LEADER=$(curl -X POST -H "Content-Type: application/json" --data \ - '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ - {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq .result) - if [ "$CHECK_LEADER" = false ]; then - echo "OP Conductor $last is NOT the leader, exiting..." - exit 1 + echo "Checking raft cluster..." + CLUSTER_MEMBERS=$(curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_clusterMembership","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq '.result.servers | length') + echo "Current raft cluster members: $CLUSTER_MEMBERS" + if [ "$CLUSTER_MEMBERS" = 1 ]; then + echo "Forming raft cluster..." + echo "Checking OP Conductor $last is leader" + CHECK_LEADER=$(curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_leader","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq .result) + if [ "$CHECK_LEADER" = false ]; then + echo "OP Conductor $last is NOT the leader, exiting..." + exit 1 + fi + i=0 + echo "Sending addServerAsVoter to OP Conductor $last" + while [ $i -lt $(( {{ .Values.opNode.replicas }} - 1 )) ] + do + echo "Sending addServerAsVoter to OP Conductor $last for member $i" + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_addServerAsVoter","params":["'${i}'", "{{ .Values.opConductor.consensus.namePattern }}-'${i}':{{ .Values.opConductor.consensus.port }}", 0],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s + i=$((i + 1)) + done + CLUSTER_MEMBERS=$(curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_clusterMembership","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq '.result.servers | length') + if [ "$CLUSTER_MEMBERS" = {{ .Values.opNode.replicas }} ]; then + echo "Done forming raft cluster" + else + echo "Failed to form raft cluster. Exiting..." + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_clusterMembership","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s + exit 1 + fi + else + echo "Raft cluster already formed" fi - i=0 - echo "Sending addServerAsVoter to OP Conductor $last" - while [ $i -lt $(( {{ .Values.opNode.replicas }} - 1 )) ] - do - echo "Sending addServerAsVoter to OP Conductor $last for member $i" - curl -X POST -H "Content-Type: application/json" --data \ - '{"jsonrpc":"2.0","method":"conductor_addServerAsVoter","params":["$i", "{{ .Values.opConductor.consensus.namePattern }}-$i:{{ .Values.opConductor.consensus.port }}", 0],"id":1}' \ - {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$last:{{ .Values.opConductor.rpc.port }} -s | jq .result - i=$((i + 1)) - done - echo "Done forming raft cluster" - echo "Unpausing OP Conductors..." - i=0 - while [ $i -lt {{ .Values.opConductor.replicas }} ] - do - echo "Sending conductor_resume to OP Conductor $i" - curl -X POST -H "Content-Type: application/json" --data \ - '{"jsonrpc":"2.0","method":"conductor_resume","params":[],"id":1}' \ - {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$i:{{ .Values.opConductor.rpc.port }} -s - i=$((i + 1)) - done - echo "OP Conductors unpaused." + if [ $(cat /tmp/RESULT_COND_0_PAUSED) = "true" ] && \ + [ $(cat /tmp/RESULT_COND_1_PAUSED) = "true" ] && \ + [ $(cat /tmp/RESULT_COND_2_PAUSED) = "true" ]; then + echo "Conductors are paused" + UNPAUSE=true + else + echo "Conductors are NOT paused. Skipping..." + UNPAUSE=false + fi + + if [ $UNPAUSE = true ]; then + echo "Unpausing OP Conductors..." + i=0 + while [ $i -lt {{ .Values.opConductor.replicas }} ] + do + echo "Sending conductor_resume to OP Conductor $i" + curl -X POST -H "Content-Type: application/json" --data \ + '{"jsonrpc":"2.0","method":"conductor_resume","params":[],"id":1}' \ + {{ .Values.opConductor.protocol }}://{{ .Values.opConductor.rpc.namePattern }}-$i:{{ .Values.opConductor.rpc.port }} -s + i=$((i + 1)) + done + echo "OP Conductors unpaused." + fi restartPolicy: Never