master
h 391 lines 10.7 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 wslc_schema.h
8
9 Abstract:
10
11 Contains the WSLC schema definitions for container operations.
12
13 --*/
14
15 #pragma once
16
17 #include "JsonUtils.h"
18
19 namespace wsl::windows::common::wslc_schema {
20
21 using wsl::shared::EmptyObject;
22
23 struct InspectPortBinding
24 {
25 std::string HostIp;
26 std::string HostPort;
27
28 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(InspectPortBinding, HostIp, HostPort);
29 };
30
31 struct InspectMount
32 {
33 std::string Type;
34 std::string Name;
35 std::string Source;
36 std::string Destination;
37 bool ReadWrite{};
38
39 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(InspectMount, Type, Name, Source, Destination, ReadWrite);
40 };
41
42 struct HealthcheckResult
43 {
44 std::string Start;
45 std::string End;
46 int ExitCode{};
47 std::string Output;
48
49 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(HealthcheckResult, Start, End, ExitCode, Output);
50 };
51
52 struct Health
53 {
54 std::string Status;
55 int FailingStreak{};
56 std::vector<HealthcheckResult> Log;
57
58 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Health, Status, FailingStreak, Log);
59 };
60
61 struct ContainerInspectState
62 {
63 std::string Status;
64 bool Running{};
65 int ExitCode{};
66 std::string StartedAt;
67 std::string FinishedAt;
68 std::optional<Health> Health;
69
70 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerInspectState, Status, Running, ExitCode, StartedAt, FinishedAt, Health);
71 };
72
73 struct Ulimit
74 {
75 std::string Name;
76 std::int64_t Soft{};
77 std::int64_t Hard{};
78
79 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Ulimit, Name, Soft, Hard);
80 };
81
82 struct InspectHostConfig
83 {
84 std::string NetworkMode;
85 std::int64_t Memory{};
86 std::int64_t NanoCpus{};
87 std::vector<Ulimit> Ulimits;
88
89 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(InspectHostConfig, NetworkMode, Memory, NanoCpus, Ulimits);
90 };
91
92 struct HealthConfig
93 {
94 std::optional<std::vector<std::string>> Test;
95 std::optional<std::int64_t> Interval;
96 std::optional<std::int64_t> Timeout;
97 std::optional<std::int64_t> StartPeriod;
98 std::optional<int> Retries;
99
100 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(HealthConfig, Test, Interval, Timeout, StartPeriod, Retries);
101 };
102
103 struct ContainerConfig
104 {
105 std::string Image;
106 std::optional<std::vector<std::string>> Env;
107 std::optional<std::vector<std::string>> Cmd;
108 std::optional<std::vector<std::string>> Entrypoint;
109 std::string User;
110 std::string WorkingDir;
111 std::optional<int> StopTimeout;
112 std::optional<HealthConfig> Healthcheck;
113 std::map<std::string, std::string> Labels;
114
115 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerConfig, Image, Env, Cmd, Entrypoint, User, WorkingDir, StopTimeout, Healthcheck, Labels);
116 };
117
118 struct InspectEndpointIPAMConfig
119 {
120 std::string IPv4Address;
121 std::vector<std::string> LinkLocalIPs;
122
123 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(InspectEndpointIPAMConfig, IPv4Address, LinkLocalIPs);
124 };
125
126 struct InspectEndpointSettings
127 {
128 std::string IPAddress;
129 std::string Gateway;
130 std::string MacAddress;
131 int IPPrefixLen{};
132 std::vector<std::string> Aliases;
133 std::vector<std::string> Links;
134 std::map<std::string, std::string> DriverOpts;
135 std::optional<InspectEndpointIPAMConfig> IPAMConfig;
136
137 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(InspectEndpointSettings, IPAddress, Gateway, MacAddress, IPPrefixLen, Aliases, Links, DriverOpts, IPAMConfig);
138 };
139
140 struct InspectNetworkSettings
141 {
142 std::map<std::string, InspectEndpointSettings> Networks;
143
144 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(InspectNetworkSettings, Networks);
145 };
146
147 struct InspectContainer
148 {
149 std::string Id;
150 std::string Name;
151 std::string Created;
152 std::string Image;
153 ContainerInspectState State;
154 InspectHostConfig HostConfig;
155 ContainerConfig Config;
156 std::map<std::string, std::vector<InspectPortBinding>> Ports;
157 std::vector<InspectMount> Mounts;
158 std::map<std::string, std::string> Labels;
159 InspectNetworkSettings NetworkSettings;
160 std::optional<std::int64_t> SizeRw;
161 std::optional<std::int64_t> SizeRootFs;
162
163 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
164 InspectContainer, Id, Name, Created, Image, State, HostConfig, Config, Ports, Mounts, Labels, NetworkSettings, SizeRw, SizeRootFs);
165 };
166
167 // Serializes a container inspect document. SizeRw and SizeRootFs are only populated when the
168 // daemon was asked to compute them, so the keys are omitted entirely when they have no value.
169 inline nlohmann::json ToInspectJson(const InspectContainer& container)
170 {
171 nlohmann::json document = container;
172
173 if (!container.SizeRw.has_value())
174 {
175 document.erase("SizeRw");
176 }
177
178 if (!container.SizeRootFs.has_value())
179 {
180 document.erase("SizeRootFs");
181 }
182
183 return document;
184 }
185
186 struct ImageConfig
187 {
188 std::optional<std::vector<std::string>> Cmd;
189 std::optional<std::vector<std::string>> Entrypoint;
190 std::optional<std::vector<std::string>> Env;
191 std::optional<std::map<std::string, EmptyObject>> ExposedPorts;
192 std::optional<std::map<std::string, std::string>> Labels;
193 std::string StopSignal;
194 std::string User;
195 std::optional<std::map<std::string, EmptyObject>> Volumes;
196 std::string WorkingDir;
197
198 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ImageConfig, Cmd, Entrypoint, Env, ExposedPorts, Labels, StopSignal, User, Volumes, WorkingDir);
199 };
200
201 struct ImageRootFS
202 {
203 std::string Type;
204 std::optional<std::vector<std::string>> Layers;
205
206 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ImageRootFS, Type, Layers);
207 };
208
209 struct InspectImage
210 {
211 std::string Id;
212 std::optional<std::vector<std::string>> RepoTags;
213 std::optional<std::vector<std::string>> RepoDigests;
214 std::string Parent;
215 std::string Comment;
216 std::string Created;
217 std::string Author;
218 std::string Architecture;
219 std::string Os;
220 int64_t Size{};
221 std::optional<std::map<std::string, std::string>> Metadata;
222 std::optional<ImageConfig> Config;
223 std::optional<ImageRootFS> RootFS;
224
225 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
226 InspectImage, Id, RepoTags, RepoDigests, Parent, Comment, Created, Author, Architecture, Os, Size, Metadata, Config, RootFS);
227 };
228
229 struct InspectVolume
230 {
231 std::string Name;
232 std::string Driver;
233 std::string CreatedAt;
234 std::string Mountpoint;
235 std::string Scope;
236 std::optional<std::map<std::string, std::string>> Options;
237 std::optional<std::map<std::string, std::string>> Labels;
238 std::optional<std::map<std::string, std::string>> Status;
239 };
240
241 // Labels and options are reported as null rather than as empty objects, and the driver-specific
242 // status is omitted entirely when the driver reports nothing.
243 inline void to_json(nlohmann::json& j, const InspectVolume& volume)
244 {
245 const auto mapOrNull = [](const std::optional<std::map<std::string, std::string>>& value) {
246 return value.has_value() && !value->empty() ? nlohmann::json(*value) : nlohmann::json(nullptr);
247 };
248
249 j = nlohmann::json::object();
250 j["CreatedAt"] = volume.CreatedAt;
251 j["Driver"] = volume.Driver;
252 j["Labels"] = mapOrNull(volume.Labels);
253 j["Mountpoint"] = volume.Mountpoint;
254 j["Name"] = volume.Name;
255 j["Options"] = mapOrNull(volume.Options);
256 j["Scope"] = volume.Scope;
257
258 if (volume.Status.has_value() && !volume.Status->empty())
259 {
260 j["Status"] = *volume.Status;
261 }
262 }
263
264 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_FROM_ONLY(InspectVolume, Name, Driver, CreatedAt, Mountpoint, Scope, Options, Labels, Status);
265
266 struct IPAMConfig
267 {
268 std::string Subnet;
269 std::string Gateway;
270 std::string IPRange;
271 };
272
273 // The gateway and ip range are omitted when unset rather than emitted as empty strings.
274 inline void to_json(nlohmann::json& j, const IPAMConfig& config)
275 {
276 j = nlohmann::json::object();
277 j["Subnet"] = config.Subnet;
278
279 if (!config.Gateway.empty())
280 {
281 j["Gateway"] = config.Gateway;
282 }
283
284 if (!config.IPRange.empty())
285 {
286 j["IPRange"] = config.IPRange;
287 }
288 }
289
290 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_FROM_ONLY(IPAMConfig, Subnet, Gateway, IPRange);
291
292 struct IPAM
293 {
294 std::string Driver;
295 std::optional<std::vector<IPAMConfig>> Config;
296 std::map<std::string, std::string> Options;
297
298 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(IPAM, Driver, Config, Options);
299 };
300
301 struct NetworkConfigFrom
302 {
303 std::string Network;
304
305 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(NetworkConfigFrom, Network);
306 };
307
308 struct NetworkContainer
309 {
310 std::string Name;
311 std::string EndpointID;
312 std::string MacAddress;
313 std::string IPv4Address;
314 std::string IPv6Address;
315
316 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(NetworkContainer, Name, EndpointID, MacAddress, IPv4Address, IPv6Address);
317 };
318
319 struct Network
320 {
321 std::string Id;
322 std::string Name;
323 std::string Created;
324 std::string Driver;
325 std::string Scope;
326 bool EnableIPv4{true};
327 bool EnableIPv6{};
328 bool Internal{};
329 bool Attachable{};
330 bool Ingress{};
331 bool ConfigOnly{};
332 NetworkConfigFrom ConfigFrom;
333 IPAM IPAM;
334 std::map<std::string, std::string> Options;
335 std::map<std::string, std::string> Labels;
336 std::map<std::string, NetworkContainer> Containers;
337 nlohmann::json Status = nlohmann::json::object();
338
339 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
340 Network, Id, Name, Created, Driver, Scope, EnableIPv4, EnableIPv6, Internal, Attachable, Ingress, ConfigOnly, ConfigFrom, IPAM, Options, Labels, Containers, Status);
341 };
342
343 // The network properties carried from the session to the CLI for "network list". Values keep their
344 // native types; the CLI renders the string output.
345 struct NetworkListEntry
346 {
347 std::string Id;
348 std::string Name;
349 std::string Driver;
350 std::string Scope;
351 std::string Created;
352 bool EnableIPv4{true};
353 bool EnableIPv6{};
354 bool Internal{};
355 std::map<std::string, std::string> Labels;
356
357 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(NetworkListEntry, Id, Name, Driver, Scope, Created, EnableIPv4, EnableIPv6, Internal, Labels);
358 };
359
360 // The volume properties carried from the session to the CLI for "volume list". Values keep their
361 // native types; the CLI renders the string output.
362 struct VolumeListEntry
363 {
364 std::string Name;
365 std::string Driver;
366 std::string Mountpoint;
367 std::string Scope;
368 std::map<std::string, std::string> Labels;
369
370 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(VolumeListEntry, Name, Driver, Mountpoint, Scope, Labels);
371 };
372
373 struct EventActor
374 {
375 std::string ID;
376 std::map<std::string, std::string> Attributes;
377
378 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(EventActor, ID, Attributes);
379 };
380
381 struct Event
382 {
383 std::string Type;
384 std::string Action;
385 EventActor Actor;
386 std::int64_t time{};
387
388 NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Event, Type, Action, Actor, time);
389 };
390
391 } // namespace wsl::windows::common::wslc_schema