9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 | def update_docker_swarm(config, yaml_path="docker-swarm.yml", prod=False):
"""_summary_
Args:
config (_type_): _description_
yaml_path (str, optional): _description_. Defaults to "docker-swarm.yml".
prod (bool, optional): _description_. Defaults to False.
Returns:
_type_: _description_
"""
with open(yaml_path, "r") as file:
# save backup version
shutil.copyfile(yaml_path, f"{yaml_path}.bak")
docker_compose = yaml.safe_load(file)
base_ip = [172, 27, 1, 11]
base_port = 49160
defined_services = set()
defined_services.add("panther-webapp")
implem_build_commands = dict(config.items("implem_build_commands"))
# Get docker limits from config
normal_cpu = config['docker_limits']['normal_cpu']
normal_mem = config['docker_limits']['normal_mem']
shadow_cpu = config['docker_limits']['shadow_cpu']
shadow_mem = config['docker_limits']['shadow_mem']
shadow_support = config['shadow_support']
for implem, should_build in config["implems"].items():
if should_build.lower() == "true":
tag, path, dockerfile = eval(implem_build_commands[implem])
service_name = tag.replace("_", "-") + "-panther"
defined_services.add(service_name)
base_ip[-1] += 1
base_port += 1
ipv4_address = ".".join(map(str, base_ip))
port = base_port
if prod:
volumes = [
"/tmp/.X11-unix:/tmp/.X11-unix"
]
else:
volumes = [
"/tmp/.X11-unix:/tmp/.X11-unix",
"${PWD}/panther_worker/app/:/app/",
"/app/panther-ivy/",
"/app/implementations/",
"${PWD}/panther_worker/app/panther-ivy/protocol-testing/:/app/panther-ivy/protocol-testing/",
"${PWD}/panther_worker/app/panther-ivy/ivy/include/:/app/panther-ivy/ivy/include/",
"${PWD}/outputs/tls-keys:/app/tls-keys",
"${PWD}/outputs/tickets:/app/tickets",
"${PWD}/outputs/qlogs:/app/qlogs",
]
is_shadow = shadow_support.getboolean(implem)
cpus = shadow_cpu if is_shadow else normal_cpu
memory = shadow_mem if is_shadow else normal_mem
docker_compose["services"][service_name] = {
"hostname": service_name,
"container_name": service_name,
"image": f"{service_name}:latest",
"command": 'bash -c "stty cols 100 rows 100 && python3 panther_client.py"',
"ports": [f"{port}:80"],
"volumes": volumes,
"networks": {"net": {"ipv4_address": ipv4_address}},
"privileged": True,
"tty": True,
"stdin_open": True,
# Spectre/Meltdown mitigation ~30% performance hit
"security_opt": ["seccomp:unconfined"],
"environment": [
"DISPLAY=${DISPLAY}",
"XAUTHORITY=~/.Xauthority",
"ROOT_PATH=${PWD}",
'MPLBACKEND="Agg"',
"COLUMNS=100",
"LINES=100",
],
"restart": "always",
"deploy": {
"resources": {
"limits": {
"cpus": cpus,
"memory": memory,
},
"reservations": {
"cpus": str(float(cpus)/2),
"memory": str(int(memory.replace("M",""))/2)+"M",
},
},
},
"depends_on": ["panther-webapp"],
}
if not prod:
# Spectre/Meltdown mitigation ~30% performance hit
docker_compose["services"][service_name]["security_opt"] = ["seccomp:unconfined"]
# Remove services not defined in config
services_to_remove = set(docker_compose["services"].keys()) - defined_services
for service in services_to_remove:
del docker_compose["services"][service]
with open(yaml_path, "w") as file:
yaml.safe_dump(docker_compose, file)
logging.info("Docker Swarm configuration updated successfully.")
return yaml_path, defined_services
|