1
2
3
4
5
6
7
8
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
|
From 1d42d850b71e3a0e269f268411999c265a1a8f5b Mon Sep 17 00:00:00 2001
From: zhongtao <zhongtao17@huawei.com>
Date: Mon, 10 Feb 2025 10:44:01 +0800
Subject: [PATCH 190/198] modified the procedure of start pod and set up
network in cri v1
Signed-off-by: zhongtao <zhongtao17@huawei.com>
---
.../v1/v1_cri_pod_sandbox_manager_service.cc | 276 +++++++++++++-----
.../v1/v1_cri_pod_sandbox_manager_service.h | 3 +
2 files changed, 206 insertions(+), 73 deletions(-)
diff --git a/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc b/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc
index 43705853..62464acd 100644
--- a/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc
+++ b/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.cc
@@ -19,6 +19,7 @@
#include <isula_libutils/host_config.h>
#include <isula_libutils/container_config.h>
#include <isula_libutils/auto_cleanup.h>
+#include <isula_libutils/container_network_settings.h>
#include <algorithm>
#include "checkpoint_handler.h"
@@ -273,12 +274,6 @@ void PodSandboxManagerService::SetupSandboxNetwork(const std::shared_ptr<sandbox
std::map<std::string, std::string> networkOptions;
networkOptions["UID"] = config.metadata().uid();
- if (prepare_network_namespace(sandboxKey.c_str(), false, 0) != 0) {
- error.Errorf("Failed to prepare network namespace: %s", sandboxKey.c_str());
- ERROR("Failed to prepare network namespace: %s", sandboxKey.c_str());
- return;
- }
-
// Setup networking for the sandbox.
m_pluginManager->SetUpPod(config.metadata().namespace_(), config.metadata().name(),
Network::DEFAULT_NETWORK_INTERFACE_NAME, sandbox->GetId(), stdAnnos, networkOptions,
@@ -295,85 +290,137 @@ void PodSandboxManagerService::SetupSandboxNetwork(const std::shared_ptr<sandbox
DEBUG("set %s ready", sandbox->GetId().c_str());
}
-auto PodSandboxManagerService::RunPodSandbox(const runtime::v1::PodSandboxConfig &config,
- const std::string &runtimeHandler, Errors &error) -> std::string
+void PodSandboxManagerService::GenerateNetworkSetting(std::string &sandboxKey, std::string &network_setting_json, Errors &error)
+{
+ container_network_settings *settings = NULL;
+ __isula_auto_free char *jerr = NULL;
+ __isula_auto_free char *setting_json { nullptr };
+
+ settings = (container_network_settings *)util_common_calloc_s(sizeof(container_network_settings));
+ if (settings == NULL) {
+ ERROR("Out of memory");
+ error.Errorf("Out of memory");
+ return;
+ }
+
+ auto settingsWarpper = std::unique_ptr<CStructWrapper<container_network_settings>>(new CStructWrapper<container_network_settings>(settings, free_container_network_settings));
+
+ settings->sandbox_key = util_strdup_s(sandboxKey.c_str());
+ if (settings->sandbox_key == NULL) {
+ ERROR("Failed to set sandbox key for network setting");
+ error.Errorf("Failed to set sandbox key for network setting");
+ return;
+ }
+
+ setting_json = container_network_settings_generate_json(settings, nullptr, &jerr);
+ if (setting_json == nullptr) {
+ error.Errorf("Get network settings json err:%s", jerr);
+ }
+
+ network_setting_json = std::string(setting_json);
+}
+
+void PodSandboxManagerService::StartPodSandboxAndSetupNetowrk(std::shared_ptr<sandbox::Sandbox> sandbox, std::string &sandboxKey, std::string &sandboxName, std::string &networkMode, Errors &error)
{
- std::string response_id;
- std::string sandboxName;
- sandbox::RuntimeInfo runtimeInfo;
- std::string networkMode;
- std::string sandboxKey;
- std::string jsonCheckpoint;
- std::string network_setting_json;
- runtime::v1::PodSandboxConfig copyConfig = config;
cri_container_message_t msg = { 0 };
-#ifdef ENABLE_NRI
- Errors nriErr;
-#endif
+ std::string network_setting_json;
- // Step 1: Parepare sandbox name, runtime and networkMode
- PrepareSandboxData(config, runtimeHandler, sandboxName, runtimeInfo, networkMode, error);
+ // Step 7.2.1: Call sandbox create.
+ sandbox->Create(error);
if (error.NotEmpty()) {
- return response_id;
+ ERROR("Failed to create sandbox: %s", sandboxName.c_str());
+ return;
}
- // Step 2: Pull the image for the sandbox.
- // Maybe we should pull image in shim controller ?
- // But pull image interface is only in CRI image service, and it can't be called in shim controller,
- // so we pull image in CRI pod service.
- const std::string &image = m_podSandboxImage;
- if (!EnsureSandboxImageExists(image, runtimeInfo.sandboxer, error)) {
- ERROR("Failed to pull sandbox image %s: %s", image.c_str(), error.NotEmpty() ? error.GetCMessage() : "");
- error.Errorf("Failed to pull sandbox image %s: %s", image.c_str(), error.NotEmpty() ? error.GetCMessage() : "");
- return response_id;
+ msg.container_id = sandbox->GetId().c_str();
+ msg.sandbox_id = sandbox->GetId().c_str();
+ msg.type = CRI_CONTAINER_MESSAGE_TYPE_CREATED;
+ mailbox_publish(MAILBOX_TOPIC_CRI_CONTAINER, &msg);
+
+ // Step 7.2.2: Save network settings json to disk
+ // Update network settings before start sandbox since sandbox container will use the sandbox key
+ if (namespace_is_cni(networkMode.c_str())) {
+ GenerateNetworkSetting(sandboxKey, network_setting_json, error);
+ // If saving network settings failed, ignore error
+ if (error.NotEmpty()) {
+ ERROR("Failed to generate networksetting :%s", error.GetCMessage());
+ return;
+ }
+
+ sandbox->UpdateNetworkSettings(network_setting_json, error);
+ // If saving network settings failed, ignore error
+ if (error.NotEmpty()) {
+ ERROR("%s", error.GetCMessage());
+ return;
+ }
}
- // Step 3: Prepare sandbox checkpoint
- PrepareSandboxCheckpoint(config, jsonCheckpoint, error);
+ // Step 7.2.3: Call sandbox start.
+ sandbox->Start(error);
if (error.NotEmpty()) {
- return response_id;
+ ERROR("Failed to start sandbox: %s", sandboxName.c_str());
+ return;
}
- // Step 4: Update sandbox instance config
- UpdateSandboxConfig(copyConfig, jsonCheckpoint, error);
+ // Step 7.2.4:Setup networking for the sandbox.
+ SetupSandboxNetwork(sandbox, network_setting_json, error);
if (error.NotEmpty()) {
- return response_id;
+ goto stop_sandbox;
}
- // Step 5: Prepare sandboxKey
+ // Step 7.2.5:update Network settings after setup network to update ip info.
if (namespace_is_cni(networkMode.c_str())) {
- // cleanup sandboxKey file in DeleteSandbox
- PrepareSandboxKey(sandboxKey, error);
- if (error.NotEmpty()) {
- return response_id;
+ Errors tmpErr;
+ sandbox->UpdateNetworkSettings(network_setting_json, tmpErr);
+ // If saving network settings failed, ignore error
+ if (tmpErr.NotEmpty()) {
+ WARN("%s", tmpErr.GetCMessage());
}
}
- // Step 6: Create sandbox instance
- auto sandbox = sandbox::SandboxManager::GetInstance()->CreateSandbox(sandboxName, runtimeInfo, sandboxKey,
- networkMode, copyConfig, image, error);
+ // Step 7.2.6: Save sandbox to disk
+ sandbox->Save(error);
if (error.NotEmpty()) {
- if (namespace_is_cni(networkMode.c_str())) {
- (void)remove_network_namespace_file(sandboxKey.c_str());
+ ERROR("Failed to save sandbox, %s", sandboxName.c_str());
+ goto cleanup_network;
+ }
+ return;
+
+cleanup_network:
+ if (namespace_is_cni(sandbox->GetNetMode().c_str())) {
+ Errors clearErr;
+ ClearCniNetwork(sandbox, clearErr);
+ if (clearErr.NotEmpty()) {
+ ERROR("Failed to clean cni network: %s", clearErr.GetCMessage());
}
- return response_id;
}
- // Step 7: Setup networking for the sandbox.
+stop_sandbox:
+ Errors stopError;
+ CRIHelpers::StopContainerHelper(m_cb, sandbox->GetId(), 0, stopError);
+ WARN("Error stop container: %s: %s", sandbox->GetId().c_str(), stopError.GetCMessage());
+}
+
+void PodSandboxManagerService::SetupNetowrkAndStartPodSandbox(std::shared_ptr<sandbox::Sandbox> sandbox, std::string &sandboxName, std::string &networkMode, Errors &error)
+{
+ cri_container_message_t msg = { 0 };
+ std::string network_setting_json;
+
+ // Step 7.1.1: Setup networking for the sandbox.
// Setup sandbox network before create sandbox since the remote create might fail for sandbox
SetupSandboxNetwork(sandbox, network_setting_json, error);
if (error.NotEmpty()) {
- goto cleanup_sandbox;
+ return;
}
- // Step 8: Save sandbox to disk
+ // Step 7.1.2: Save sandbox to disk
sandbox->Save(error);
if (error.NotEmpty()) {
ERROR("Failed to save sandbox, %s", sandboxName.c_str());
goto cleanup_network;
}
- // Step 9: Call sandbox create.
+ // Step 7.1.3: Call sandbox create.
sandbox->Create(error);
if (error.NotEmpty()) {
ERROR("Failed to create sandbox: %s", sandboxName.c_str());
@@ -385,7 +432,7 @@ auto PodSandboxManagerService::RunPodSandbox(const runtime::v1::PodSandboxConfig
msg.type = CRI_CONTAINER_MESSAGE_TYPE_CREATED;
mailbox_publish(MAILBOX_TOPIC_CRI_CONTAINER, &msg);
- // Step 10: Save network settings json to disk
+ // Step 7.1.4: Save network settings json to disk
// Update network settings before start sandbox since sandbox container will use the sandbox key
if (namespace_is_cni(networkMode.c_str())) {
Errors tmpErr;
@@ -396,26 +443,15 @@ auto PodSandboxManagerService::RunPodSandbox(const runtime::v1::PodSandboxConfig
}
}
- // Step 11: Call sandbox start.
+ // Step 7.1.5: Call sandbox start.
sandbox->Start(error);
if (error.NotEmpty()) {
ERROR("Failed to start sandbox: %s", sandboxName.c_str());
- // If start failed, sandbox should be NotReady, we cleanup network and delete sandbox in remove
- return response_id;
- }
-
- msg.type = CRI_CONTAINER_MESSAGE_TYPE_STARTED;
- mailbox_publish(MAILBOX_TOPIC_CRI_CONTAINER, &msg);
-
-#ifdef ENABLE_NRI
- if (!NRIAdaptation::GetInstance()->RunPodSandbox(sandbox, nriErr)) {
- ERROR("NRI RunPodSandbox failed: %s", nriErr.GetCMessage());
- error.Errorf("NRI RunPodSandbox failed: %s", nriErr.GetCMessage());
- return response_id;
+ // If start failed, sandbox should be NotReady, we cleanup network, but delete sandbox in remove
+ goto cleanup_network;
}
-#endif
- return sandbox->GetId();
+ return;
cleanup_network:
if (namespace_is_cni(sandbox->GetNetMode().c_str())) {
@@ -423,21 +459,115 @@ cleanup_network:
ClearCniNetwork(sandbox, clearErr);
if (clearErr.NotEmpty()) {
ERROR("Failed to clean cni network: %s", clearErr.GetCMessage());
+ return;
+ }
+ }
+}
+
+auto PodSandboxManagerService::RunPodSandbox(const runtime::v1::PodSandboxConfig &config,
+ const std::string &runtimeHandler, Errors &error) -> std::string
+{
+ std::string response_id;
+ std::string sandboxName;
+ sandbox::RuntimeInfo runtimeInfo;
+ std::string networkMode;
+ std::string sandboxKey;
+ std::string jsonCheckpoint;
+ runtime::v1::PodSandboxConfig copyConfig = config;
+ std::map<std::string, std::string> stdAnnos;
+ cri_container_message_t msg = { 0 };
+ std::shared_ptr<sandbox::Sandbox> sandbox;
+#ifdef ENABLE_NRI
+ Errors nriErr;
+#endif
+
+ // Step 1: Parepare sandbox name, runtime and networkMode
+ PrepareSandboxData(config, runtimeHandler, sandboxName, runtimeInfo, networkMode, error);
+ if (error.NotEmpty()) {
+ return response_id;
+ }
+
+ // Step 2: Pull the image for the sandbox.
+ // Maybe we should pull image in shim controller ?
+ // But pull image interface is only in CRI image service, and it can't be called in shim controller,
+ // so we pull image in CRI pod service.
+ const std::string &image = m_podSandboxImage;
+ if (!EnsureSandboxImageExists(image, runtimeInfo.sandboxer, error)) {
+ ERROR("Failed to pull sandbox image %s: %s", image.c_str(), error.NotEmpty() ? error.GetCMessage() : "");
+ error.Errorf("Failed to pull sandbox image %s: %s", image.c_str(), error.NotEmpty() ? error.GetCMessage() : "");
+ return response_id;
+ }
+
+ // Step 3: Prepare sandbox checkpoint
+ PrepareSandboxCheckpoint(config, jsonCheckpoint, error);
+ if (error.NotEmpty()) {
+ return response_id;
+ }
+
+ // Step 4: Update sandbox instance config
+ UpdateSandboxConfig(copyConfig, jsonCheckpoint, error);
+ if (error.NotEmpty()) {
+ return response_id;
+ }
+
+ // Step 5: Prepare sandboxKey and mount ns namespace
+ if (namespace_is_cni(networkMode.c_str())) {
+ // cleanup sandboxKey file in DeleteSandbox
+ PrepareSandboxKey(sandboxKey, error);
+ if (error.NotEmpty()) {
return response_id;
}
+ if (prepare_network_namespace(sandboxKey.c_str(), false, 0) != 0) {
+ error.Errorf("Failed to prepare network namespace: %s", sandboxKey.c_str());
+ ERROR("Failed to prepare network namespace: %s", sandboxKey.c_str());
+ goto clean_ns;
+ }
}
-cleanup_sandbox:
- sandbox::SandboxManager::GetInstance()->DeleteSandbox(sandbox->GetId(), error);
+ // Step 6: Create sandbox instance
+ sandbox = sandbox::SandboxManager::GetInstance()->CreateSandbox(sandboxName, runtimeInfo, sandboxKey,
+ networkMode, copyConfig, image, error);
+ if (error.NotEmpty()) {
+ goto clean_ns;
+ }
+
+ CRIHelpers::ProtobufAnnoMapToStd(sandbox->GetSandboxConfig().annotations(), stdAnnos);
+ // Step 7: According to the annotation and network namespace mode,
+ // determine the order of start sandbox and setup network.
+ // tips: clean sandbox and network in sub function.
+ if (CRIHelpers::SetupNetworkFirst(stdAnnos)) {
+ // Step 7.1: Setup networking for the sandbox, and then start the sandbox container.
+ SetupNetowrkAndStartPodSandbox(sandbox, sandboxName, networkMode, error);
+ } else {
+ // Step 7.2: (Default)Start the sandbox container, and then setup networking for the sandbox.
+ // why: Some kata multi-network plane plugins (such as configuring vfio device pass-through)
+ // need to be called after the pod is already running.
+ StartPodSandboxAndSetupNetowrk(sandbox, sandboxKey, sandboxName, networkMode, error);
+ }
if (error.NotEmpty()) {
- ERROR("Failed to delete sandbox: %s", sandbox->GetId().c_str());
+ goto clean_ns;
}
+
+ msg.type = CRI_CONTAINER_MESSAGE_TYPE_STARTED;
+ mailbox_publish(MAILBOX_TOPIC_CRI_CONTAINER, &msg);
+
#ifdef ENABLE_NRI
- if (!NRIAdaptation::GetInstance()->RemovePodSandbox(sandbox, nriErr)) {
- DEBUG("NRI RemovePodSandbox failed: %s", nriErr.GetCMessage());
+ if (!NRIAdaptation::GetInstance()->RunPodSandbox(sandbox, nriErr)) {
+ ERROR("NRI RunPodSandbox failed: %s", nriErr.GetCMessage());
+ error.Errorf("NRI RunPodSandbox failed: %s", nriErr.GetCMessage());
+ return response_id;
}
#endif
+ return sandbox->GetId();
+clean_ns:
+ if (namespace_is_cni(networkMode.c_str())) {
+ // umount netns when prepare runp failed
+ if (remove_network_namespace(sandboxKey.c_str()) != 0) {
+ SYSERROR("Failed to umount directory %s", sandboxKey.c_str());
+ }
+ (void)remove_network_namespace_file(sandboxKey.c_str());
+ }
return response_id;
}
diff --git a/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.h b/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.h
index b02216c0..01d06624 100644
--- a/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.h
+++ b/src/daemon/entry/cri/v1/v1_cri_pod_sandbox_manager_service.h
@@ -86,6 +86,9 @@ private:
void UpdateSandboxConfig(runtime::v1::PodSandboxConfig &config, std::string &jsonCheckpoint, Errors &error);
void SetupSandboxFiles(const std::string &resolvPath, const runtime::v1::PodSandboxConfig &config,
Errors &error);
+ void GenerateNetworkSetting(std::string &sandboxKey, std::string &network_setting_json, Errors &error);
+ void StartPodSandboxAndSetupNetowrk(std::shared_ptr<sandbox::Sandbox> sandbox, std::string &sandboxKey, std::string &sandboxName, std::string &networkMode, Errors &error);
+ void SetupNetowrkAndStartPodSandbox(std::shared_ptr<sandbox::Sandbox> sandbox, std::string &sandboxName, std::string &networkMode, Errors &error);
void SetupSandboxNetwork(const std::shared_ptr<sandbox::Sandbox> sandbox, std::string &network_settings_json,
Errors &error);
void ClearCniNetwork(const std::shared_ptr<sandbox::Sandbox> sandbox, Errors &error);
--
2.34.1
|