|
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