1use indexmap::IndexMap;
2use serde_yaml::Value;
3
4#[derive(Debug, Clone)]
5pub enum ArgType {
6 Array,
7 Ulimits,
8 Switch,
9 Value,
10 IntValue,
11 FloatValue,
12 DeviceBlockIOConfigRate,
13 DeviceBlockIOConfigWeight,
14 Networks,
15 MapArray,
16 Map,
17 Envs,
18 Gpus,
19}
20
21#[derive(Debug, Clone)]
22pub struct Mapping {
23 pub arg_type: ArgType,
24 pub path: String,
25}
26
27impl Mapping {
28 pub fn new(arg_type: ArgType, path: &str) -> Self {
29 Self {
30 arg_type,
31 path: path.to_string(),
32 }
33 }
34}
35
36pub fn get_mappings() -> IndexMap<String, Mapping> {
37 let mut mappings = IndexMap::new();
38
39 mappings.insert("add-host".to_string(), Mapping::new(ArgType::Array, "extra_hosts"));
41 mappings.insert("blkio-weight".to_string(), Mapping::new(ArgType::IntValue, "blkio_config/weight"));
42 mappings.insert("blkio-weight-device".to_string(), Mapping::new(ArgType::DeviceBlockIOConfigWeight, "blkio_config/weight_device"));
43 mappings.insert("cap-add".to_string(), Mapping::new(ArgType::Array, "cap_add"));
44 mappings.insert("cap-drop".to_string(), Mapping::new(ArgType::Array, "cap_drop"));
45 mappings.insert("cgroup-parent".to_string(), Mapping::new(ArgType::Value, "cgroup_parent"));
46 mappings.insert("cgroupns".to_string(), Mapping::new(ArgType::Value, "cgroup"));
47 mappings.insert("cpu-period".to_string(), Mapping::new(ArgType::Value, "cpu_period"));
48 mappings.insert("cpu-quota".to_string(), Mapping::new(ArgType::Value, "cpu_quota"));
49 mappings.insert("cpu-rt-period".to_string(), Mapping::new(ArgType::Value, "cpu_rt_period"));
50 mappings.insert("cpu-rt-runtime".to_string(), Mapping::new(ArgType::Value, "cpu_rt_runtime"));
51 mappings.insert("cpu-shares".to_string(), Mapping::new(ArgType::IntValue, "cpu_shares"));
52 mappings.insert("cpus".to_string(), Mapping::new(ArgType::FloatValue, "deploy/resources/limits/cpus"));
53 mappings.insert("detached".to_string(), Mapping::new(ArgType::Switch, ""));
54 mappings.insert("device-cgroup-rule".to_string(), Mapping::new(ArgType::Array, "device_cgroup_rules"));
55 mappings.insert("device-read-bps".to_string(), Mapping::new(ArgType::DeviceBlockIOConfigRate, "blkio_config/device_read_bps"));
56 mappings.insert("device-read-iops".to_string(), Mapping::new(ArgType::DeviceBlockIOConfigRate, "blkio_config/device_read_iops"));
57 mappings.insert("device-write-bps".to_string(), Mapping::new(ArgType::DeviceBlockIOConfigRate, "blkio_config/device_write_bps"));
58 mappings.insert("device-write-iops".to_string(), Mapping::new(ArgType::DeviceBlockIOConfigRate, "blkio_config/device_write_iops"));
59 mappings.insert("device".to_string(), Mapping::new(ArgType::Array, "devices"));
60 mappings.insert("dns-opt".to_string(), Mapping::new(ArgType::Array, "dns_opt"));
61 mappings.insert("dns-search".to_string(), Mapping::new(ArgType::Array, "dns_search"));
62 mappings.insert("dns".to_string(), Mapping::new(ArgType::Array, "dns"));
63 mappings.insert("domainname".to_string(), Mapping::new(ArgType::Value, "domainname"));
64 mappings.insert("entrypoint".to_string(), Mapping::new(ArgType::Array, "entrypoint"));
65 mappings.insert("env-file".to_string(), Mapping::new(ArgType::Array, "env_file"));
66 mappings.insert("env".to_string(), Mapping::new(ArgType::Envs, "environment"));
67 mappings.insert("expose".to_string(), Mapping::new(ArgType::Array, "expose"));
68 mappings.insert("gpus".to_string(), Mapping::new(ArgType::Gpus, "deploy"));
69 mappings.insert("group-add".to_string(), Mapping::new(ArgType::Array, "group_add"));
70 mappings.insert("health-cmd".to_string(), Mapping::new(ArgType::Value, "healthcheck/test"));
71 mappings.insert("health-interval".to_string(), Mapping::new(ArgType::Value, "healthcheck/interval"));
72 mappings.insert("health-retries".to_string(), Mapping::new(ArgType::IntValue, "healthcheck/retries"));
73 mappings.insert("health-start-period".to_string(), Mapping::new(ArgType::Value, "healthcheck/start_period"));
74 mappings.insert("health-timeout".to_string(), Mapping::new(ArgType::Value, "healthcheck/timeout"));
75 mappings.insert("hostname".to_string(), Mapping::new(ArgType::Value, "hostname"));
76 mappings.insert("init".to_string(), Mapping::new(ArgType::Switch, "init"));
77 mappings.insert("interactive".to_string(), Mapping::new(ArgType::Switch, "stdin_open"));
78 mappings.insert("ip6".to_string(), Mapping::new(ArgType::Value, "networks/¤network¤/ipv6_address"));
79 mappings.insert("ip".to_string(), Mapping::new(ArgType::Value, "networks/¤network¤/ipv4_address"));
80 mappings.insert("ipc".to_string(), Mapping::new(ArgType::Value, "ipc"));
81 mappings.insert("isolation".to_string(), Mapping::new(ArgType::Value, "isolation"));
82 mappings.insert("label".to_string(), Mapping::new(ArgType::Array, "labels"));
83 mappings.insert("link-local-ip".to_string(), Mapping::new(ArgType::Array, "networks/¤network¤/link_local_ips"));
84 mappings.insert("link".to_string(), Mapping::new(ArgType::Array, "links"));
85 mappings.insert("log-driver".to_string(), Mapping::new(ArgType::Value, "logging/driver"));
86 mappings.insert("log-opt".to_string(), Mapping::new(ArgType::Map, "logging/options"));
87 mappings.insert("mac-address".to_string(), Mapping::new(ArgType::Value, "mac_address"));
88 mappings.insert("memory-reservation".to_string(), Mapping::new(ArgType::Value, "deploy/resources/reservations/memory"));
89 mappings.insert("memory-swap".to_string(), Mapping::new(ArgType::Value, "memswap_limit"));
90 mappings.insert("memory-swappiness".to_string(), Mapping::new(ArgType::Value, "mem_swappiness"));
91 mappings.insert("memory".to_string(), Mapping::new(ArgType::Value, "deploy/resources/limits/memory"));
92 mappings.insert("mount".to_string(), Mapping::new(ArgType::MapArray, "volumes"));
93 mappings.insert("name".to_string(), Mapping::new(ArgType::Value, "container_name"));
94 mappings.insert("net".to_string(), Mapping::new(ArgType::Networks, "network_mode"));
95 mappings.insert("network-alias".to_string(), Mapping::new(ArgType::Array, "networks/¤network¤/aliases"));
96 mappings.insert("network".to_string(), Mapping::new(ArgType::Networks, "network_mode"));
97 mappings.insert("no-healthcheck".to_string(), Mapping::new(ArgType::Switch, "healthcheck/disable"));
98 mappings.insert("oom-kill-disable".to_string(), Mapping::new(ArgType::Switch, "oom_kill_disable"));
99 mappings.insert("oom-score-adj".to_string(), Mapping::new(ArgType::Value, "oom_score_adj"));
100 mappings.insert("pid".to_string(), Mapping::new(ArgType::Value, "pid"));
101 mappings.insert("pids-limit".to_string(), Mapping::new(ArgType::IntValue, "deploy/resources/limits/pids"));
102 mappings.insert("platform".to_string(), Mapping::new(ArgType::Value, "platform"));
103 mappings.insert("privileged".to_string(), Mapping::new(ArgType::Switch, "privileged"));
104 mappings.insert("publish".to_string(), Mapping::new(ArgType::Array, "ports"));
105 mappings.insert("pull".to_string(), Mapping::new(ArgType::Value, "pull_policy"));
106 mappings.insert("read-only".to_string(), Mapping::new(ArgType::Switch, "read_only"));
107 mappings.insert("restart".to_string(), Mapping::new(ArgType::Value, "restart"));
108 mappings.insert("rm".to_string(), Mapping::new(ArgType::Switch, ""));
109 mappings.insert("runtime".to_string(), Mapping::new(ArgType::Value, "runtime"));
110 mappings.insert("security-opt".to_string(), Mapping::new(ArgType::Array, "security_opt"));
111 mappings.insert("shm-size".to_string(), Mapping::new(ArgType::Value, "shm_size"));
112 mappings.insert("stop-signal".to_string(), Mapping::new(ArgType::Value, "stop_signal"));
113 mappings.insert("stop-timeout".to_string(), Mapping::new(ArgType::Value, "stop_grace_period"));
114 mappings.insert("storage-opt".to_string(), Mapping::new(ArgType::Map, "storage_opt"));
115 mappings.insert("sysctl".to_string(), Mapping::new(ArgType::Array, "sysctls"));
116 mappings.insert("tmpfs".to_string(), Mapping::new(ArgType::Array, "tmpfs"));
117 mappings.insert("tty".to_string(), Mapping::new(ArgType::Switch, "tty"));
118 mappings.insert("ulimit".to_string(), Mapping::new(ArgType::Ulimits, "ulimits"));
119 mappings.insert("user".to_string(), Mapping::new(ArgType::Value, "user"));
120 mappings.insert("userns".to_string(), Mapping::new(ArgType::Value, "userns_mode"));
121 mappings.insert("uts".to_string(), Mapping::new(ArgType::Value, "uts"));
122 mappings.insert("volume".to_string(), Mapping::new(ArgType::Array, "volumes"));
123 mappings.insert("volumes-from".to_string(), Mapping::new(ArgType::Array, "volumes_from"));
124 mappings.insert("workdir".to_string(), Mapping::new(ArgType::Value, "working_dir"));
125
126 mappings.insert("v".to_string(), mappings.get("volume").unwrap().clone());
128 mappings.insert("p".to_string(), mappings.get("publish").unwrap().clone());
129 mappings.insert("e".to_string(), mappings.get("env").unwrap().clone());
130 mappings.insert("l".to_string(), mappings.get("label").unwrap().clone());
131 mappings.insert("h".to_string(), mappings.get("hostname").unwrap().clone());
132 mappings.insert("u".to_string(), mappings.get("user").unwrap().clone());
133 mappings.insert("w".to_string(), mappings.get("workdir").unwrap().clone());
134 mappings.insert("c".to_string(), mappings.get("cpu-shares").unwrap().clone());
135 mappings.insert("t".to_string(), mappings.get("tty").unwrap().clone());
136 mappings.insert("i".to_string(), mappings.get("interactive").unwrap().clone());
137 mappings.insert("m".to_string(), mappings.get("memory").unwrap().clone());
138 mappings.insert("d".to_string(), mappings.get("detached").unwrap().clone());
139
140 mappings
141}
142
143pub fn strip_quotes(val: &str) -> String {
144 let trimmed = val.trim();
145 if (trimmed.starts_with('"') && trimmed.ends_with('"'))
146 || (trimmed.starts_with('\'') && trimmed.ends_with('\''))
147 {
148 trimmed[1..trimmed.len() - 1].to_string()
149 } else {
150 trimmed.to_string()
151 }
152}
153
154pub fn parse_key_value_list(input: &str, list_sep: char, entry_sep: char) -> IndexMap<String, Value> {
155 let mut result = IndexMap::new();
156
157 for item in input.split(list_sep) {
158 let parts: Vec<&str> = item.splitn(2, entry_sep).collect();
159 if parts.len() == 2 {
160 let key = parts[0].trim().to_string();
161 let value = parts[1].trim();
162
163 if let Ok(num) = value.parse::<i64>() {
164 result.insert(key, Value::Number(num.into()));
165 } else {
166 result.insert(key, Value::String(value.to_string()));
167 }
168 }
169 }
170
171 result
172}
173
174pub fn is_boolean_flag(flag: &str) -> bool {
175 let mappings = get_mappings();
176 if let Some(mapping) = mappings.get(flag) {
177 matches!(mapping.arg_type, ArgType::Switch)
178 } else {
179 false
180 }
181}