1
1
import subprocess
2
2
import sys
3
3
import tempfile
4
+ from multiprocessing import Process
4
5
from pathlib import Path
5
6
from typing import Optional
6
7
15
16
FORK_OBSERVER_CHART ,
16
17
HELM_COMMAND ,
17
18
INGRESS_HELM_COMMANDS ,
19
+ LOGGING_CRD_COMMANDS ,
18
20
LOGGING_HELM_COMMANDS ,
19
21
LOGGING_NAMESPACE ,
20
22
NAMESPACES_CHART_LOCATION ,
@@ -75,17 +77,47 @@ def _deploy(directory, debug, namespace, to_all_users):
75
77
76
78
if to_all_users :
77
79
namespaces = get_namespaces_by_type (WARGAMES_NAMESPACE_PREFIX )
80
+ processes = []
78
81
for namespace in namespaces :
79
- deploy (directory , debug , namespace .metadata .name , False )
82
+ p = Process (target = deploy , args = (directory , debug , namespace .metadata .name , False ))
83
+ p .start ()
84
+ processes .append (p )
85
+ for p in processes :
86
+ p .join ()
80
87
return
81
88
82
89
if (directory / NETWORK_FILE ).exists ():
83
- dl = deploy_logging_stack (directory , debug )
84
- deploy_network (directory , debug , namespace = namespace )
85
- df = deploy_fork_observer (directory , debug )
86
- if dl | df :
87
- deploy_ingress (debug )
88
- deploy_caddy (directory , debug )
90
+ processes = []
91
+ # Deploy logging CRD first to avoid synchronisation issues
92
+ deploy_logging_crd (directory , debug )
93
+
94
+ logging_process = Process (target = deploy_logging_stack , args = (directory , debug ))
95
+ logging_process .start ()
96
+ processes .append (logging_process )
97
+
98
+ network_process = Process (target = deploy_network , args = (directory , debug , namespace ))
99
+ network_process .start ()
100
+
101
+ ingress_process = Process (target = deploy_ingress , args = (directory , debug ))
102
+ ingress_process .start ()
103
+ processes .append (ingress_process )
104
+
105
+ caddy_process = Process (target = deploy_caddy , args = (directory , debug ))
106
+ caddy_process .start ()
107
+ processes .append (caddy_process )
108
+
109
+ # Wait for the network process to complete
110
+ network_process .join ()
111
+
112
+ # Start the fork observer process immediately after network process completes
113
+ fork_observer_process = Process (target = deploy_fork_observer , args = (directory , debug ))
114
+ fork_observer_process .start ()
115
+ processes .append (fork_observer_process )
116
+
117
+ # Wait for all other processes to complete
118
+ for p in processes :
119
+ p .join ()
120
+
89
121
elif (directory / NAMESPACES_FILE ).exists ():
90
122
deploy_namespaces (directory )
91
123
else :
@@ -118,11 +150,30 @@ def check_logging_required(directory: Path):
118
150
return False
119
151
120
152
153
+ def deploy_logging_crd (directory : Path , debug : bool ) -> bool :
154
+ """
155
+ This function exists so we can parallelise the rest of the loggin stack
156
+ installation
157
+ """
158
+ if not check_logging_required (directory ):
159
+ return False
160
+
161
+ click .echo (
162
+ "Found collectLogs or metricsExport in network definition, Deploying logging stack CRD"
163
+ )
164
+
165
+ for command in LOGGING_CRD_COMMANDS :
166
+ if not stream_command (command ):
167
+ print (f"Failed to run Helm command: { command } " )
168
+ return False
169
+ return True
170
+
171
+
121
172
def deploy_logging_stack (directory : Path , debug : bool ) -> bool :
122
173
if not check_logging_required (directory ):
123
174
return False
124
175
125
- click .echo ("Found collectLogs or metricsExport in network definition, Deploying logging stack" )
176
+ click .echo ("Deploying logging stack" )
126
177
127
178
for command in LOGGING_HELM_COMMANDS :
128
179
if not stream_command (command ):
@@ -144,7 +195,7 @@ def deploy_caddy(directory: Path, debug: bool):
144
195
if not network_file .get (name , {}).get ("enabled" , False ):
145
196
return
146
197
147
- cmd = f"{ HELM_COMMAND } { name } { CADDY_CHART } --namespace { namespace } "
198
+ cmd = f"{ HELM_COMMAND } { name } { CADDY_CHART } --namespace { namespace } --create-namespace "
148
199
if debug :
149
200
cmd += " --debug"
150
201
@@ -156,7 +207,15 @@ def deploy_caddy(directory: Path, debug: bool):
156
207
click .echo ("\n To access the warnet dashboard run:\n warnet dashboard" )
157
208
158
209
159
- def deploy_ingress (debug : bool ):
210
+ def deploy_ingress (directory : Path , debug : bool ):
211
+ # Deploy ingress if either logging or fork observer is enabled
212
+ network_file_path = directory / NETWORK_FILE
213
+ with network_file_path .open () as f :
214
+ network_file = yaml .safe_load (f )
215
+ fo_enabled = network_file .get ("fork_observer" , {}).get ("enabled" , False )
216
+ logging_enabled = check_logging_required (directory )
217
+ if not (fo_enabled or logging_enabled ):
218
+ return
160
219
click .echo ("Deploying ingress controller" )
161
220
162
221
for command in INGRESS_HELM_COMMANDS :
@@ -231,41 +290,49 @@ def deploy_fork_observer(directory: Path, debug: bool) -> bool:
231
290
232
291
def deploy_network (directory : Path , debug : bool = False , namespace : Optional [str ] = None ):
233
292
network_file_path = directory / NETWORK_FILE
234
- defaults_file_path = directory / DEFAULTS_FILE
235
-
236
293
namespace = get_default_namespace_or (namespace )
237
294
238
295
with network_file_path .open () as f :
239
296
network_file = yaml .safe_load (f )
240
297
298
+ processes = []
241
299
for node in network_file ["nodes" ]:
242
- click .echo (f"Deploying node: { node .get ('name' )} " )
243
- try :
244
- temp_override_file_path = ""
245
- node_name = node .get ("name" )
246
- node_config_override = {k : v for k , v in node .items () if k != "name" }
247
-
248
- cmd = f"{ HELM_COMMAND } { node_name } { BITCOIN_CHART_LOCATION } --namespace { namespace } -f { defaults_file_path } "
249
- if debug :
250
- cmd += " --debug"
251
-
252
- if node_config_override :
253
- with tempfile .NamedTemporaryFile (
254
- mode = "w" , suffix = ".yaml" , delete = False
255
- ) as temp_file :
256
- yaml .dump (node_config_override , temp_file )
257
- temp_override_file_path = Path (temp_file .name )
258
- cmd = f"{ cmd } -f { temp_override_file_path } "
259
-
260
- if not stream_command (cmd ):
261
- click .echo (f"Failed to run Helm command: { cmd } " )
262
- return
263
- except Exception as e :
264
- click .echo (f"Error: { e } " )
300
+ p = Process (target = deploy_single_node , args = (node , directory , debug , namespace ))
301
+ p .start ()
302
+ processes .append (p )
303
+
304
+ for p in processes :
305
+ p .join ()
306
+
307
+
308
+ def deploy_single_node (node , directory : Path , debug : bool , namespace : str ):
309
+ defaults_file_path = directory / DEFAULTS_FILE
310
+ click .echo (f"Deploying node: { node .get ('name' )} " )
311
+ temp_override_file_path = ""
312
+ try :
313
+ node_name = node .get ("name" )
314
+ node_config_override = {k : v for k , v in node .items () if k != "name" }
315
+
316
+ defaults_file_path = directory / DEFAULTS_FILE
317
+ cmd = f"{ HELM_COMMAND } { node_name } { BITCOIN_CHART_LOCATION } --namespace { namespace } -f { defaults_file_path } "
318
+ if debug :
319
+ cmd += " --debug"
320
+
321
+ if node_config_override :
322
+ with tempfile .NamedTemporaryFile (mode = "w" , suffix = ".yaml" , delete = False ) as temp_file :
323
+ yaml .dump (node_config_override , temp_file )
324
+ temp_override_file_path = Path (temp_file .name )
325
+ cmd = f"{ cmd } -f { temp_override_file_path } "
326
+
327
+ if not stream_command (cmd ):
328
+ click .echo (f"Failed to run Helm command: { cmd } " )
265
329
return
266
- finally :
267
- if temp_override_file_path :
268
- Path (temp_override_file_path ).unlink ()
330
+ except Exception as e :
331
+ click .echo (f"Error: { e } " )
332
+ return
333
+ finally :
334
+ if temp_override_file_path :
335
+ Path (temp_override_file_path ).unlink ()
269
336
270
337
271
338
def deploy_namespaces (directory : Path ):
@@ -284,32 +351,40 @@ def deploy_namespaces(directory: Path):
284
351
)
285
352
return
286
353
354
+ processes = []
287
355
for namespace in namespaces_file ["namespaces" ]:
288
- click .echo (f"Deploying namespace: { namespace .get ('name' )} " )
289
- try :
290
- temp_override_file_path = ""
291
- namespace_name = namespace .get ("name" )
292
- namespace_config_override = {k : v for k , v in namespace .items () if k != "name" }
293
-
294
- cmd = f"{ HELM_COMMAND } { namespace_name } { NAMESPACES_CHART_LOCATION } -f { defaults_file_path } "
295
-
296
- if namespace_config_override :
297
- with tempfile .NamedTemporaryFile (
298
- mode = "w" , suffix = ".yaml" , delete = False
299
- ) as temp_file :
300
- yaml .dump (namespace_config_override , temp_file )
301
- temp_override_file_path = Path (temp_file .name )
302
- cmd = f"{ cmd } -f { temp_override_file_path } "
303
-
304
- if not stream_command (cmd ):
305
- click .echo (f"Failed to run Helm command: { cmd } " )
306
- return
307
- except Exception as e :
308
- click .echo (f"Error: { e } " )
356
+ p = Process (target = deploy_single_namespace , args = (namespace , defaults_file_path ))
357
+ p .start ()
358
+ processes .append (p )
359
+
360
+ for p in processes :
361
+ p .join ()
362
+
363
+
364
+ def deploy_single_namespace (namespace , defaults_file_path : Path ):
365
+ click .echo (f"Deploying namespace: { namespace .get ('name' )} " )
366
+ temp_override_file_path = ""
367
+ try :
368
+ namespace_name = namespace .get ("name" )
369
+ namespace_config_override = {k : v for k , v in namespace .items () if k != "name" }
370
+
371
+ cmd = f"{ HELM_COMMAND } { namespace_name } { NAMESPACES_CHART_LOCATION } -f { defaults_file_path } "
372
+
373
+ if namespace_config_override :
374
+ with tempfile .NamedTemporaryFile (mode = "w" , suffix = ".yaml" , delete = False ) as temp_file :
375
+ yaml .dump (namespace_config_override , temp_file )
376
+ temp_override_file_path = Path (temp_file .name )
377
+ cmd = f"{ cmd } -f { temp_override_file_path } "
378
+
379
+ if not stream_command (cmd ):
380
+ click .echo (f"Failed to run Helm command: { cmd } " )
309
381
return
310
- finally :
311
- if temp_override_file_path :
312
- temp_override_file_path .unlink ()
382
+ except Exception as e :
383
+ click .echo (f"Error: { e } " )
384
+ return
385
+ finally :
386
+ if temp_override_file_path :
387
+ Path (temp_override_file_path ).unlink ()
313
388
314
389
315
390
def is_windows ():
0 commit comments