|
1 | 1 | import argparse
|
2 | 2 | import base64
|
| 3 | +import io |
3 | 4 | import json
|
4 | 5 | import logging
|
5 | 6 | import logging.config
|
|
10 | 11 | import signal
|
11 | 12 | import subprocess
|
12 | 13 | import sys
|
| 14 | +import tarfile |
13 | 15 | import tempfile
|
14 | 16 | import threading
|
15 | 17 | import time
|
@@ -268,20 +270,47 @@ def tank_messages(self, network: str, node_a: int, node_b: int) -> str:
|
268 | 270 | self.logger.error(msg)
|
269 | 271 | raise ServerError(message=msg) from e
|
270 | 272 |
|
271 |
| - def network_export(self, network: str) -> str: |
| 273 | + def network_export(self, network: str, activity: str | None) -> bool: |
272 | 274 | """
|
273 |
| - Export all data for sim-ln to subdirectory |
| 275 | + Export all data for a simln container running on the network |
274 | 276 | """
|
275 |
| - try: |
276 |
| - wn = self.get_warnet(network) |
277 |
| - subdir = os.path.join(wn.config_dir, "simln") |
278 |
| - os.makedirs(subdir, exist_ok=True) |
279 |
| - wn.export(subdir) |
280 |
| - return subdir |
281 |
| - except Exception as e: |
282 |
| - msg = f"Error exporting network: {e}" |
283 |
| - self.logger.error(msg) |
284 |
| - raise ServerError(message=msg) from e |
| 277 | + wn = self.get_warnet(network) |
| 278 | + if "simln" not in wn.services: |
| 279 | + raise Exception("No simln service in network") |
| 280 | + |
| 281 | + # JSON object that will eventually be written to simln config file |
| 282 | + config = {"nodes": []} |
| 283 | + if activity: |
| 284 | + config["activity"] = json.loads(activity) |
| 285 | + # In-memory file to build tar archive |
| 286 | + tar_buffer = io.BytesIO() |
| 287 | + with tarfile.open(fileobj=tar_buffer, mode="w") as tar_file: |
| 288 | + # tank LN nodes add their credentials to tar archive |
| 289 | + wn.export(config, tar_file) |
| 290 | + # write config file |
| 291 | + config_bytes = json.dumps(config).encode('utf-8') |
| 292 | + config_stream = io.BytesIO(config_bytes) |
| 293 | + tarinfo = tarfile.TarInfo(name="sim.json") |
| 294 | + tarinfo.size = len(config_bytes) |
| 295 | + tar_file.addfile(tarinfo=tarinfo, fileobj=config_stream) |
| 296 | + |
| 297 | + # Write the archive to the RPC server's config directory |
| 298 | + source_file = wn.config_dir / "simln.tar" |
| 299 | + with open(source_file, "wb") as output: |
| 300 | + tar_buffer.seek(0) |
| 301 | + output.write(tar_buffer.read()) |
| 302 | + |
| 303 | + if self.backend == "compose": |
| 304 | + # Extract the archive into a subdirectory that is already |
| 305 | + # shared with the simln container as a volume |
| 306 | + subprocess.run(["tar", "-xf", source_file, "-C", wn.config_dir / 'simln']) |
| 307 | + # Force quick restart of the container instead of waiting |
| 308 | + # for the exponential backoff to come around |
| 309 | + wn.container_interface.restart_service_container("simln") |
| 310 | + if self.backend == "k8s": |
| 311 | + # Copy the archive to the "emptydir" volume in the simln pod |
| 312 | + wn.container_interface.write_service_config(source_file, "simln", "/simln/") |
| 313 | + return True |
285 | 314 |
|
286 | 315 | def scenarios_available(self) -> list[tuple]:
|
287 | 316 | """
|
|
0 commit comments