Skip to content

Commit 927deb7

Browse files
fix: Support multiple sequencers: Add op-conductor-ops launcher [26/N] (#320)
**Description** `op-conductor-ops` is required when launching conductor instances. This PR introduces a disconnected launcher that runs a `bootstrap-cluster` command followed by a `status` command just for visibility purposes
1 parent d5fb08c commit 927deb7

3 files changed

Lines changed: 139 additions & 0 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[networks]
2+
3+
[networks.{{ .network_name }}]
4+
sequencers = [
5+
{{- range $name, $config := .sequencers }}
6+
"{{ $name }}",
7+
{{- end }}
8+
]
9+
10+
[sequencers]
11+
12+
{{- range $name, $sequencer := .sequencers }}
13+
[sequencers.{{ $name }}]
14+
raft_addr = "{{ $sequencer.conductor_raft_address }}"
15+
conductor_rpc_url = "{{ $sequencer.conductor_rpc_url }}"
16+
node_rpc_url = "{{ $sequencer.cl_rpc_url }}"
17+
voting = true
18+
{{- end }}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
_selectors = import_module("/src/l2/selectors.star")
2+
_net = import_module("/src/util/net.star")
3+
_registry = import_module("/src/package_io/registry.star")
4+
5+
_CONFIG_DIRPATH_ON_SERVICE = "/etc/op-conductor-ops"
6+
_CONFIG_TEMPLATE_FILENAME = "config.toml.tmpl"
7+
_CONFIG_FILENAME = "config.toml"
8+
9+
10+
def launch(
11+
plan,
12+
l2_params,
13+
registry,
14+
):
15+
participants_params = _get_participants_params_with_conductors(l2_params)
16+
if not participants_params:
17+
plan.print(
18+
"No conductors found for network {}, skipping op-conductor-ops launch".format(
19+
l2_params.network_params.name
20+
)
21+
)
22+
23+
return None
24+
25+
config_artifact = _create_op_conductor_ops_config_artifact(
26+
plan=plan,
27+
network_params=l2_params.network_params,
28+
participants_params=participants_params,
29+
)
30+
31+
_run_op_conductor_ops_command(
32+
plan=plan,
33+
cmd="bootstrap-cluster {}".format(l2_params.network_params.name),
34+
config_artifact=config_artifact,
35+
description="Bootstrap conductors for network {} using op-conductor-ops".format(
36+
l2_params.network_params.name
37+
),
38+
registry=registry,
39+
)
40+
41+
_run_op_conductor_ops_command(
42+
plan=plan,
43+
cmd="status {}".format(l2_params.network_params.name),
44+
config_artifact=config_artifact,
45+
description="Get status of conductors for network {} using op-conductor-ops".format(
46+
l2_params.network_params.name
47+
),
48+
registry=registry,
49+
)
50+
51+
52+
def _run_op_conductor_ops_command(
53+
plan,
54+
cmd,
55+
config_artifact,
56+
description,
57+
registry,
58+
):
59+
plan.run_sh(
60+
description=description,
61+
image=registry.get(_registry.OP_CONDUCTOR_OPS),
62+
files={
63+
_CONFIG_DIRPATH_ON_SERVICE: config_artifact,
64+
},
65+
run="./op-conductor-ops {}".format(
66+
cmd,
67+
),
68+
env_vars={
69+
"CONDUCTOR_CONFIG": "{}/{}".format(
70+
_CONFIG_DIRPATH_ON_SERVICE, _CONFIG_FILENAME
71+
),
72+
},
73+
wait=None,
74+
)
75+
76+
77+
def _get_participants_params_with_conductors(l2_params):
78+
return [
79+
participant_params
80+
for participant_params in l2_params.participants
81+
if participant_params.conductor_params
82+
and _selectors.is_sequencer(participant_params)
83+
]
84+
85+
86+
def _create_op_conductor_ops_config_artifact(plan, network_params, participants_params):
87+
config_template = read_file(_CONFIG_TEMPLATE_FILENAME)
88+
config_data = {
89+
"network_name": network_params.name,
90+
"sequencers": {
91+
participant_params.conductor_params.service_name: {
92+
"cl_rpc_url": _net.service_url(
93+
participant_params.cl.service_name,
94+
participant_params.cl.ports[_net.RPC_PORT_NAME],
95+
),
96+
"conductor_rpc_url": _net.service_url(
97+
participant_params.conductor_params.service_name,
98+
participant_params.conductor_params.ports[_net.RPC_PORT_NAME],
99+
),
100+
"conductor_raft_address": "{0}:{1}".format(
101+
participant_params.conductor_params.service_name,
102+
participant_params.conductor_params.ports[
103+
_net.CONSENSUS_PORT_NAME
104+
].number,
105+
),
106+
}
107+
for participant_params in participants_params
108+
},
109+
}
110+
111+
return plan.render_templates(
112+
{
113+
_CONFIG_FILENAME: struct(
114+
template=config_template,
115+
data=config_data,
116+
),
117+
},
118+
name="op-conductor-ops-config-{0}".format(network_params.network_id),
119+
)

src/package_io/registry.star

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ OP_PROPOSER = "op-proposer"
2121
OP_CONDUCTOR = "op-conductor"
2222
OP_DEPLOYER = "op-deployer"
2323
OP_FAUCET = "op-faucet"
24+
OP_CONDUCTOR_OPS = "op-conductor-ops"
2425

2526
PROXYD = "proxyd"
2627

@@ -66,6 +67,7 @@ _DEFAULT_IMAGES = {
6667
# TODO: update to use a versioned image when available
6768
# For now, we'll need users to pass the image explicitly
6869
OP_FAUCET: "",
70+
OP_CONDUCTOR_OPS: "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-conductor-ops:v0.0.2",
6971
# Proxyd
7072
PROXYD: "us-docker.pkg.dev/oplabs-tools-artifacts/images/proxyd:v4.14.5",
7173
# Sidecar

0 commit comments

Comments
 (0)