|
30 | 30 | roles, networks = provider.init() |
31 | 31 | roles = en.sync_info(roles, networks) |
32 | 32 |
|
| 33 | +print(">>> Installing and configuring Chrony on all nodes...") |
| 34 | +with en.actions(roles=roles) as a: |
| 35 | + a.apt(name=["chrony"], state="present", update_cache=True) |
| 36 | + a.service(name="chrony", state="started", enabled=True) |
| 37 | + a.shell("chronyc makestep") |
| 38 | + |
33 | 39 | # Initial Docker engine deployment |
34 | 40 | registry_opts = dict(type="external", ip="docker-cache.grid5000.fr", port=80) |
35 | 41 | d = en.Docker( |
36 | 42 | agent=roles["arbitrator"] + roles["worker"], |
37 | 43 | bind_var_docker="/tmp/docker", |
38 | | - registry_opts=registry_opts |
| 44 | + registry_opts=registry_opts, |
39 | 45 | ) |
40 | 46 | d.deploy() |
41 | 47 |
|
|
62 | 68 | # Network emulation |
63 | 69 | netem = en.NetemHTB() |
64 | 70 | netem.add_constraints( |
65 | | - src=roles["worker"], |
66 | | - dest=roles["arbitrator"], |
| 71 | + src=roles["worker"] + roles["arbitrator"], |
| 72 | + dest=roles["worker"] + roles["arbitrator"], |
67 | 73 | delay="10ms", |
68 | 74 | rate="1gbit", |
69 | 75 | symmetric=True, |
|
79 | 85 | a.file(path="/tmp/metrics", state="absent") |
80 | 86 | a.file(path="/tmp/metrics", state="directory", mode="0777") |
81 | 87 | a.file(path=COMPONENTS_PATH, state="directory") |
82 | | - a.copy(src="config/redis/components-grid5000/", |
83 | | - dest=COMPONENTS_PATH + "/") |
| 88 | + a.copy(src="config/redis/components-grid5000/", dest=COMPONENTS_PATH + "/") |
84 | 89 |
|
85 | | - # Deploy Containers on Arbitrator |
| 90 | + # Deploy containers |
86 | 91 | with en.actions(roles=roles["arbitrator"]) as a: |
87 | 92 | a.docker_container( |
88 | | - name="redis", image=REDIS_IMAGE, |
89 | | - network_mode="host", state="started" |
| 93 | + name="redis", image=REDIS_IMAGE, network_mode="host", state="started" |
90 | 94 | ) |
91 | 95 | a.docker_container( |
92 | | - name="placement", image=PLACEMENT_IMAGE, |
93 | | - network_mode="host", state="started", |
94 | | - command=["./placement", "--port", "50006"] |
| 96 | + name="placement", |
| 97 | + image=PLACEMENT_IMAGE, |
| 98 | + network_mode="host", |
| 99 | + state="started", |
| 100 | + command=["./placement", "--port", "50006"], |
95 | 101 | ) |
96 | 102 | a.docker_container( |
97 | | - name="arbitrator-sidecar", image=SIDECAR_IMAGE, |
98 | | - network_mode="host", state="started", |
| 103 | + name="arbitrator-sidecar", |
| 104 | + image=SIDECAR_IMAGE, |
| 105 | + network_mode="host", |
| 106 | + state="started", |
99 | 107 | command=[ |
100 | 108 | "./daprd", |
101 | | - "--app-id", "arbitrator-sidecar", |
102 | | - "--app-port", "3000", |
103 | | - "--resources-path", "/components", |
104 | | - "--placement-host-address", "localhost:50006", |
105 | | - "--metrics-port", "9091", |
| 109 | + "--app-id", |
| 110 | + "arbitrator-sidecar", |
| 111 | + "--app-port", |
| 112 | + "3000", |
| 113 | + "--resources-path", |
| 114 | + "/components", |
| 115 | + "--placement-host-address", |
| 116 | + "localhost:50006", |
| 117 | + "--metrics-port", |
| 118 | + "9091", |
106 | 119 | ], |
107 | 120 | volumes=[f"{COMPONENTS_PATH}:/components"], |
108 | 121 | ) |
109 | 122 | time.sleep(10) |
110 | 123 | a.docker_container( |
111 | | - name="arbitrator", image=ACTOR_IMAGE, |
112 | | - network_mode="host", state="started", |
| 124 | + name="arbitrator", |
| 125 | + image=ACTOR_IMAGE, |
| 126 | + network_mode="host", |
| 127 | + state="started", |
113 | 128 | volumes=["/tmp/metrics:/metrics:rw"], |
114 | 129 | env={ |
115 | 130 | "ROLE": "arbitrator", |
|
120 | 135 | }, |
121 | 136 | ) |
122 | 137 |
|
123 | | - # Deploy Containers on Workers |
124 | 138 | for i, host in enumerate(roles["worker"]): |
125 | 139 | with en.actions(pattern_hosts=host.address, roles=roles) as a: |
126 | 140 | a.docker_container( |
127 | | - name="redis", image=REDIS_IMAGE, |
128 | | - network_mode="host", state="started" |
| 141 | + name="redis", image=REDIS_IMAGE, network_mode="host", state="started" |
129 | 142 | ) |
130 | 143 | a.docker_container( |
131 | | - name="placement", image=PLACEMENT_IMAGE, |
132 | | - network_mode="host", state="started", |
133 | | - command=["./placement", "--port", "50006"] |
| 144 | + name="placement", |
| 145 | + image=PLACEMENT_IMAGE, |
| 146 | + network_mode="host", |
| 147 | + state="started", |
| 148 | + command=["./placement", "--port", "50006"], |
134 | 149 | ) |
135 | 150 | a.docker_container( |
136 | | - name=f"w{i}-sidecar", image=SIDECAR_IMAGE, |
137 | | - network_mode="host", state="started", |
| 151 | + name=f"w{i}-sidecar", |
| 152 | + image=SIDECAR_IMAGE, |
| 153 | + network_mode="host", |
| 154 | + state="started", |
138 | 155 | command=[ |
139 | 156 | "./daprd", |
140 | | - "--app-id", f"w{i}-sidecar", |
141 | | - "--app-port", "3000", |
142 | | - "--resources-path", "/components", |
143 | | - "--placement-host-address", "localhost:50006", |
144 | | - "--metrics-port", "9091", |
| 157 | + "--app-id", |
| 158 | + f"w{i}-sidecar", |
| 159 | + "--app-port", |
| 160 | + "3000", |
| 161 | + "--resources-path", |
| 162 | + "/components", |
| 163 | + "--placement-host-address", |
| 164 | + "localhost:50006", |
| 165 | + "--metrics-port", |
| 166 | + "9091", |
145 | 167 | ], |
146 | 168 | volumes=[f"{COMPONENTS_PATH}:/components"], |
147 | 169 | ) |
148 | 170 | time.sleep(10) |
149 | 171 | a.docker_container( |
150 | | - name=f"w{i}", image=ACTOR_IMAGE, |
151 | | - network_mode="host", state="started", |
| 172 | + name=f"w{i}", |
| 173 | + image=ACTOR_IMAGE, |
| 174 | + network_mode="host", |
| 175 | + state="started", |
152 | 176 | volumes=["/tmp/metrics:/metrics:rw"], |
153 | 177 | env={ |
154 | 178 | "PHILOSOPHER_ID": str(i), |
|
160 | 184 |
|
161 | 185 | # Wait for data collection |
162 | 186 | print(f"--- {run_label}: Collecting data for {TIME_BEFORE_FETCH}s ---") |
163 | | - for _ in tqdm(range(TIME_BEFORE_FETCH), desc=run_label, unit="s", |
164 | | - mininterval=60): |
| 187 | + for _ in tqdm(range(TIME_BEFORE_FETCH), desc=run_label, unit="s", mininterval=60): |
165 | 188 | time.sleep(1) |
166 | 189 |
|
167 | | - # Capture NTP timing data on all nodes |
| 190 | + # Capture Chrony tracking data |
168 | 191 | with en.actions(roles=roles) as a: |
169 | | - a.shell("ntpq -p > /tmp/metrics/ntp_stats.txt") |
| 192 | + a.shell("chronyc tracking > /tmp/metrics/chrony_tracking.txt") |
| 193 | + a.shell("chronyc sources -v > /tmp/metrics/chrony_sources.txt") |
170 | 194 |
|
171 | | - # Fetch and Organize Results locally |
| 195 | + # Fetch and organize results |
172 | 196 | run_dest = LOCAL_ROOT / run_label |
173 | 197 | run_dest.mkdir(parents=True, exist_ok=True) |
174 | 198 |
|
175 | 199 | with en.actions(roles=roles) as a: |
176 | 200 | a.archive(path="/tmp/metrics", dest="/tmp/metrics.tar.gz", format="gz") |
177 | 201 | a.fetch(src="/tmp/metrics.tar.gz", dest=str(run_dest), flat=False) |
178 | 202 |
|
179 | | - # Local extraction |
180 | | - print(f"--- {run_label}: Extracting results ---") |
| 203 | + print(f"--- {run_label}: Cleaning up and extracting ---") |
| 204 | + |
| 205 | + with en.actions(roles=roles) as a: |
| 206 | + a.shell("docker rm -f $(docker ps -aq) || true") |
| 207 | + |
| 208 | + # Local file flattening |
181 | 209 | for host in en.get_hosts(roles): |
182 | 210 | host_dir = run_dest / host.address |
183 | 211 | tar_path = host_dir / "tmp" / "metrics.tar.gz" |
|
192 | 220 | except OSError: |
193 | 221 | pass |
194 | 222 |
|
195 | | - # Clean up all containers for next run |
196 | | - with en.actions(roles=roles) as a: |
197 | | - a.shell("docker rm -f $(docker ps -aq) || true") |
198 | | - |
199 | 223 | print(f"\n--- SUCCESS: All {NUM_RUNS} runs finished. Data in {LOCAL_ROOT} ---") |
200 | 224 | provider.destroy() |
0 commit comments