]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "tools/rbd/ArgumentTypes.h" | |
5 | #include "tools/rbd/Shell.h" | |
6 | #include "tools/rbd/Utils.h" | |
7 | #include "include/rbd/features.h" | |
11fdf7f2 | 8 | #include "common/config_proxy.h" |
7c673cae FG |
9 | #include "common/strtol.h" |
10 | #include "common/Formatter.h" | |
11 | #include "global/global_context.h" | |
12 | #include <iostream> | |
13 | #include <boost/tokenizer.hpp> | |
14 | ||
15 | namespace rbd { | |
16 | namespace argument_types { | |
17 | ||
18 | namespace po = boost::program_options; | |
19 | ||
20 | const std::map<uint64_t, std::string> ImageFeatures::FEATURE_MAPPING = { | |
21 | {RBD_FEATURE_LAYERING, RBD_FEATURE_NAME_LAYERING}, | |
22 | {RBD_FEATURE_STRIPINGV2, RBD_FEATURE_NAME_STRIPINGV2}, | |
23 | {RBD_FEATURE_EXCLUSIVE_LOCK, RBD_FEATURE_NAME_EXCLUSIVE_LOCK}, | |
24 | {RBD_FEATURE_OBJECT_MAP, RBD_FEATURE_NAME_OBJECT_MAP}, | |
25 | {RBD_FEATURE_FAST_DIFF, RBD_FEATURE_NAME_FAST_DIFF}, | |
26 | {RBD_FEATURE_DEEP_FLATTEN, RBD_FEATURE_NAME_DEEP_FLATTEN}, | |
27 | {RBD_FEATURE_JOURNALING, RBD_FEATURE_NAME_JOURNALING}, | |
28 | {RBD_FEATURE_DATA_POOL, RBD_FEATURE_NAME_DATA_POOL}, | |
11fdf7f2 TL |
29 | {RBD_FEATURE_OPERATIONS, RBD_FEATURE_NAME_OPERATIONS}, |
30 | {RBD_FEATURE_MIGRATING, RBD_FEATURE_NAME_MIGRATING}, | |
9f95a23c | 31 | {RBD_FEATURE_NON_PRIMARY, RBD_FEATURE_NAME_NON_PRIMARY}, |
7c673cae FG |
32 | }; |
33 | ||
34 | Format::Formatter Format::create_formatter(bool pretty) const { | |
35 | if (value == "json") { | |
36 | return Formatter(new JSONFormatter(pretty)); | |
37 | } else if (value == "xml") { | |
38 | return Formatter(new XMLFormatter(pretty)); | |
39 | } | |
40 | return Formatter(); | |
41 | } | |
42 | ||
43 | std::string get_name_prefix(ArgumentModifier modifier) { | |
44 | switch (modifier) { | |
45 | case ARGUMENT_MODIFIER_SOURCE: | |
46 | return SOURCE_PREFIX; | |
47 | case ARGUMENT_MODIFIER_DEST: | |
48 | return DEST_PREFIX; | |
49 | default: | |
50 | return ""; | |
51 | } | |
52 | } | |
53 | ||
54 | std::string get_description_prefix(ArgumentModifier modifier) { | |
55 | switch (modifier) { | |
56 | case ARGUMENT_MODIFIER_SOURCE: | |
57 | return "source "; | |
58 | case ARGUMENT_MODIFIER_DEST: | |
59 | return "destination "; | |
60 | default: | |
61 | return ""; | |
62 | } | |
63 | } | |
64 | ||
7c673cae FG |
65 | void add_pool_option(po::options_description *opt, |
66 | ArgumentModifier modifier, | |
67 | const std::string &desc_suffix) { | |
68 | std::string name = POOL_NAME + ",p"; | |
69 | std::string description = "pool name"; | |
70 | switch (modifier) { | |
71 | case ARGUMENT_MODIFIER_NONE: | |
72 | break; | |
73 | case ARGUMENT_MODIFIER_SOURCE: | |
74 | description = "source " + description; | |
75 | break; | |
76 | case ARGUMENT_MODIFIER_DEST: | |
77 | name = DEST_POOL_NAME; | |
78 | description = "destination " + description; | |
79 | break; | |
80 | } | |
81 | description += desc_suffix; | |
82 | ||
83 | // TODO add validator | |
84 | opt->add_options() | |
85 | (name.c_str(), po::value<std::string>(), description.c_str()); | |
86 | } | |
87 | ||
11fdf7f2 TL |
88 | void add_namespace_option(boost::program_options::options_description *opt, |
89 | ArgumentModifier modifier) { | |
90 | std::string name = NAMESPACE_NAME; | |
91 | std::string description = "namespace name"; | |
92 | switch (modifier) { | |
93 | case ARGUMENT_MODIFIER_NONE: | |
94 | break; | |
95 | case ARGUMENT_MODIFIER_SOURCE: | |
96 | description = "source " + description; | |
97 | break; | |
98 | case ARGUMENT_MODIFIER_DEST: | |
99 | name = DEST_NAMESPACE_NAME; | |
100 | description = "destination " + description; | |
101 | break; | |
102 | } | |
103 | ||
104 | // TODO add validator | |
105 | opt->add_options() | |
106 | (name.c_str(), po::value<std::string>(), description.c_str()); | |
107 | } | |
108 | ||
7c673cae FG |
109 | void add_image_option(po::options_description *opt, |
110 | ArgumentModifier modifier, | |
111 | const std::string &desc_suffix) { | |
112 | std::string name = IMAGE_NAME; | |
113 | std::string description = "image name"; | |
114 | switch (modifier) { | |
115 | case ARGUMENT_MODIFIER_NONE: | |
116 | break; | |
117 | case ARGUMENT_MODIFIER_SOURCE: | |
118 | description = "source " + description; | |
119 | break; | |
120 | case ARGUMENT_MODIFIER_DEST: | |
121 | name = DEST_IMAGE_NAME; | |
122 | description = "destination " + description; | |
123 | break; | |
124 | } | |
125 | description += desc_suffix; | |
126 | ||
127 | // TODO add validator | |
128 | opt->add_options() | |
129 | (name.c_str(), po::value<std::string>(), description.c_str()); | |
130 | } | |
131 | ||
132 | void add_image_id_option(po::options_description *opt, | |
133 | const std::string &desc_suffix) { | |
134 | std::string name = IMAGE_ID; | |
135 | std::string description = "image id"; | |
136 | description += desc_suffix; | |
137 | ||
138 | // TODO add validator | |
139 | opt->add_options() | |
140 | (name.c_str(), po::value<std::string>(), description.c_str()); | |
141 | } | |
142 | ||
7c673cae FG |
143 | void add_snap_option(po::options_description *opt, |
144 | ArgumentModifier modifier) { | |
145 | ||
146 | std::string name = SNAPSHOT_NAME; | |
147 | std::string description = "snapshot name"; | |
148 | switch (modifier) { | |
149 | case ARGUMENT_MODIFIER_NONE: | |
150 | break; | |
151 | case ARGUMENT_MODIFIER_DEST: | |
152 | name = DEST_SNAPSHOT_NAME; | |
153 | description = "destination " + description; | |
154 | break; | |
155 | case ARGUMENT_MODIFIER_SOURCE: | |
156 | description = "source " + description; | |
157 | break; | |
158 | } | |
159 | ||
160 | // TODO add validator | |
161 | opt->add_options() | |
162 | (name.c_str(), po::value<std::string>(), description.c_str()); | |
163 | } | |
164 | ||
11fdf7f2 | 165 | void add_snap_id_option(po::options_description *opt) { |
7c673cae | 166 | opt->add_options() |
11fdf7f2 | 167 | (SNAPSHOT_ID.c_str(), po::value<uint64_t>(), "snapshot id"); |
7c673cae FG |
168 | } |
169 | ||
170 | void add_pool_options(boost::program_options::options_description *pos, | |
11fdf7f2 TL |
171 | boost::program_options::options_description *opt, |
172 | bool namespaces_supported) { | |
7c673cae FG |
173 | opt->add_options() |
174 | ((POOL_NAME + ",p").c_str(), po::value<std::string>(), "pool name"); | |
11fdf7f2 TL |
175 | if (namespaces_supported) { |
176 | add_namespace_option(opt, ARGUMENT_MODIFIER_NONE); | |
177 | pos->add_options() | |
178 | ("pool-spec", "pool specification\n" | |
179 | "(example: <pool-name>[/<namespace>]"); | |
180 | } else { | |
181 | pos->add_options() | |
182 | ("pool-name", "pool name"); | |
183 | } | |
7c673cae FG |
184 | } |
185 | ||
186 | void add_image_spec_options(po::options_description *pos, | |
187 | po::options_description *opt, | |
188 | ArgumentModifier modifier) { | |
189 | pos->add_options() | |
190 | ((get_name_prefix(modifier) + IMAGE_SPEC).c_str(), | |
191 | (get_description_prefix(modifier) + "image specification\n" + | |
11fdf7f2 | 192 | "(example: [<pool-name>/[<namespace>/]]<image-name>)").c_str()); |
7c673cae | 193 | add_pool_option(opt, modifier); |
11fdf7f2 | 194 | add_namespace_option(opt, modifier); |
7c673cae FG |
195 | add_image_option(opt, modifier); |
196 | } | |
197 | ||
7c673cae FG |
198 | void add_snap_spec_options(po::options_description *pos, |
199 | po::options_description *opt, | |
200 | ArgumentModifier modifier) { | |
201 | pos->add_options() | |
202 | ((get_name_prefix(modifier) + SNAPSHOT_SPEC).c_str(), | |
203 | (get_description_prefix(modifier) + "snapshot specification\n" + | |
f67539c2 | 204 | "(example: [<pool-name>/[<namespace>/]]<image-name>@<snap-name>)").c_str()); |
7c673cae | 205 | add_pool_option(opt, modifier); |
11fdf7f2 | 206 | add_namespace_option(opt, modifier); |
7c673cae FG |
207 | add_image_option(opt, modifier); |
208 | add_snap_option(opt, modifier); | |
209 | } | |
210 | ||
211 | void add_image_or_snap_spec_options(po::options_description *pos, | |
212 | po::options_description *opt, | |
213 | ArgumentModifier modifier) { | |
214 | pos->add_options() | |
215 | ((get_name_prefix(modifier) + IMAGE_OR_SNAPSHOT_SPEC).c_str(), | |
216 | (get_description_prefix(modifier) + "image or snapshot specification\n" + | |
11fdf7f2 | 217 | "(example: [<pool-name>/[<namespace>/]]<image-name>[@<snap-name>])").c_str()); |
7c673cae | 218 | add_pool_option(opt, modifier); |
11fdf7f2 | 219 | add_namespace_option(opt, modifier); |
7c673cae FG |
220 | add_image_option(opt, modifier); |
221 | add_snap_option(opt, modifier); | |
222 | } | |
223 | ||
7c673cae FG |
224 | void add_create_image_options(po::options_description *opt, |
225 | bool include_format) { | |
226 | // TODO get default image format from conf | |
227 | if (include_format) { | |
228 | opt->add_options() | |
229 | (IMAGE_FORMAT.c_str(), po::value<ImageFormat>(), | |
f67539c2 | 230 | "image format [default: 2]") |
7c673cae FG |
231 | (IMAGE_NEW_FORMAT.c_str(), |
232 | po::value<ImageNewFormat>()->zero_tokens(), | |
f67539c2 | 233 | "deprecated[:image-format 2]"); |
7c673cae FG |
234 | } |
235 | ||
236 | opt->add_options() | |
237 | (IMAGE_ORDER.c_str(), po::value<ImageOrder>(), | |
f67539c2 | 238 | "deprecated[:object-size]") |
7c673cae FG |
239 | (IMAGE_OBJECT_SIZE.c_str(), po::value<ImageObjectSize>(), |
240 | "object size in B/K/M [4K <= object size <= 32M]") | |
241 | (IMAGE_FEATURES.c_str(), po::value<ImageFeatures>()->composing(), | |
242 | ("image features\n" + get_short_features_help(true)).c_str()) | |
243 | (IMAGE_SHARED.c_str(), po::bool_switch(), "shared image") | |
244 | (IMAGE_STRIPE_UNIT.c_str(), po::value<ImageObjectSize>(), "stripe unit in B/K/M") | |
245 | (IMAGE_STRIPE_COUNT.c_str(), po::value<uint64_t>(), "stripe count") | |
1911f103 TL |
246 | (IMAGE_DATA_POOL.c_str(), po::value<std::string>(), "data pool") |
247 | (IMAGE_MIRROR_IMAGE_MODE.c_str(), po::value<MirrorImageMode>(), | |
248 | "mirror image mode [journal or snapshot]"); | |
7c673cae FG |
249 | |
250 | add_create_journal_options(opt); | |
251 | } | |
252 | ||
253 | void add_create_journal_options(po::options_description *opt) { | |
254 | opt->add_options() | |
255 | (JOURNAL_SPLAY_WIDTH.c_str(), po::value<uint64_t>(), | |
256 | "number of active journal objects") | |
257 | (JOURNAL_OBJECT_SIZE.c_str(), po::value<JournalObjectSize>(), | |
a8e16298 | 258 | "size of journal objects [4K <= size <= 64M]") |
7c673cae FG |
259 | (JOURNAL_POOL.c_str(), po::value<std::string>(), |
260 | "pool for journal objects"); | |
261 | } | |
262 | ||
263 | void add_size_option(boost::program_options::options_description *opt) { | |
264 | opt->add_options() | |
265 | ((IMAGE_SIZE + ",s").c_str(), po::value<ImageSize>()->required(), | |
31f18b77 | 266 | "image size (in M/G/T) [default: M]"); |
7c673cae FG |
267 | } |
268 | ||
269 | void add_sparse_size_option(boost::program_options::options_description *opt) { | |
270 | opt->add_options() | |
271 | (IMAGE_SPARSE_SIZE.c_str(), po::value<ImageObjectSize>(), | |
272 | "sparse size in B/K/M [default: 4K]"); | |
273 | } | |
274 | ||
275 | void add_path_options(boost::program_options::options_description *pos, | |
276 | boost::program_options::options_description *opt, | |
277 | const std::string &description) { | |
278 | pos->add_options() | |
279 | (PATH_NAME.c_str(), po::value<std::string>(), description.c_str()); | |
280 | opt->add_options() | |
281 | (PATH.c_str(), po::value<std::string>(), description.c_str()); | |
282 | } | |
283 | ||
284 | void add_limit_option(po::options_description *opt) { | |
285 | std::string description = "maximum allowed snapshot count"; | |
286 | ||
287 | opt->add_options() | |
288 | (LIMIT.c_str(), po::value<uint64_t>(), description.c_str()); | |
289 | } | |
290 | ||
291 | void add_no_progress_option(boost::program_options::options_description *opt) { | |
292 | opt->add_options() | |
293 | (NO_PROGRESS.c_str(), po::bool_switch(), "disable progress output"); | |
294 | } | |
295 | ||
296 | void add_format_options(boost::program_options::options_description *opt) { | |
297 | opt->add_options() | |
181888fb | 298 | (FORMAT.c_str(), po::value<Format>(), "output format (plain, json, or xml) [default: plain]") |
7c673cae FG |
299 | (PRETTY_FORMAT.c_str(), po::bool_switch(), |
300 | "pretty formatting (json and xml)"); | |
301 | } | |
302 | ||
303 | void add_verbose_option(boost::program_options::options_description *opt) { | |
304 | opt->add_options() | |
305 | (VERBOSE.c_str(), po::bool_switch(), "be verbose"); | |
306 | } | |
307 | ||
308 | void add_no_error_option(boost::program_options::options_description *opt) { | |
309 | opt->add_options() | |
f67539c2 | 310 | (NO_ERR.c_str(), po::bool_switch(), "continue after error"); |
7c673cae FG |
311 | } |
312 | ||
313 | void add_export_format_option(boost::program_options::options_description *opt) { | |
314 | opt->add_options() | |
315 | ("export-format", po::value<ExportFormat>(), "format of image file"); | |
316 | } | |
317 | ||
11fdf7f2 TL |
318 | void add_flatten_option(boost::program_options::options_description *opt) { |
319 | opt->add_options() | |
320 | (IMAGE_FLATTEN.c_str(), po::bool_switch(), | |
321 | "fill clone with parent data (make it independent)"); | |
322 | } | |
323 | ||
f67539c2 TL |
324 | void add_snap_create_options(po::options_description *opt) { |
325 | opt->add_options() | |
326 | (SKIP_QUIESCE.c_str(), po::bool_switch(), "do not run quiesce hooks") | |
327 | (IGNORE_QUIESCE_ERROR.c_str(), po::bool_switch(), | |
328 | "ignore quiesce hook error"); | |
329 | } | |
330 | ||
7c673cae FG |
331 | std::string get_short_features_help(bool append_suffix) { |
332 | std::ostringstream oss; | |
333 | bool first_feature = true; | |
334 | oss << "["; | |
335 | for (auto &pair : ImageFeatures::FEATURE_MAPPING) { | |
11fdf7f2 TL |
336 | if ((pair.first & RBD_FEATURES_IMPLICIT_ENABLE) != 0ULL) { |
337 | // hide implicitly enabled features from list | |
338 | continue; | |
339 | } else if (!append_suffix && (pair.first & RBD_FEATURES_MUTABLE) == 0ULL) { | |
340 | // hide non-mutable features for the 'rbd feature XYZ' command | |
341 | continue; | |
342 | } | |
343 | ||
7c673cae FG |
344 | if (!first_feature) { |
345 | oss << ", "; | |
346 | } | |
347 | first_feature = false; | |
348 | ||
349 | std::string suffix; | |
350 | if (append_suffix) { | |
351 | if ((pair.first & rbd::utils::get_rbd_default_features(g_ceph_context)) != 0) { | |
352 | suffix += "+"; | |
353 | } | |
354 | if ((pair.first & RBD_FEATURES_MUTABLE) != 0) { | |
355 | suffix += "*"; | |
356 | } else if ((pair.first & RBD_FEATURES_DISABLE_ONLY) != 0) { | |
357 | suffix += "-"; | |
358 | } | |
359 | if (!suffix.empty()) { | |
360 | suffix = "(" + suffix + ")"; | |
361 | } | |
362 | } | |
363 | oss << pair.second << suffix; | |
364 | } | |
365 | oss << "]"; | |
366 | return oss.str(); | |
367 | } | |
368 | ||
369 | std::string get_long_features_help() { | |
370 | std::ostringstream oss; | |
371 | oss << "Image Features:" << std::endl | |
372 | << " (*) supports enabling/disabling on existing images" << std::endl | |
373 | << " (-) supports disabling-only on existing images" << std::endl | |
374 | << " (+) enabled by default for new images if features not specified" | |
375 | << std::endl; | |
376 | return oss.str(); | |
377 | } | |
378 | ||
379 | void validate(boost::any& v, const std::vector<std::string>& values, | |
380 | ImageSize *target_type, int) { | |
381 | po::validators::check_first_occurrence(v); | |
382 | const std::string &s = po::validators::get_single_string(values); | |
383 | ||
384 | std::string parse_error; | |
1adf2230 | 385 | uint64_t size = strict_iecstrtoll(s.c_str(), &parse_error); |
7c673cae FG |
386 | if (!parse_error.empty()) { |
387 | throw po::validation_error(po::validation_error::invalid_option_value); | |
388 | } | |
389 | ||
390 | //NOTE: We can remove below given three lines of code once all applications, | |
391 | //which use this CLI will adopt B/K/M/G/T/P/E with size value | |
392 | if (isdigit(*s.rbegin())) { | |
393 | size = size << 20; // Default MB to Bytes | |
394 | } | |
395 | v = boost::any(size); | |
396 | } | |
397 | ||
398 | void validate(boost::any& v, const std::vector<std::string>& values, | |
399 | ImageOrder *target_type, int dummy) { | |
400 | po::validators::check_first_occurrence(v); | |
401 | const std::string &s = po::validators::get_single_string(values); | |
402 | try { | |
403 | uint64_t order = boost::lexical_cast<uint64_t>(s); | |
404 | if (order >= 12 && order <= 25) { | |
405 | v = boost::any(order); | |
406 | return; | |
407 | } | |
408 | } catch (const boost::bad_lexical_cast &) { | |
409 | } | |
410 | throw po::validation_error(po::validation_error::invalid_option_value); | |
411 | } | |
412 | ||
413 | void validate(boost::any& v, const std::vector<std::string>& values, | |
414 | ImageObjectSize *target_type, int dummy) { | |
415 | po::validators::check_first_occurrence(v); | |
416 | const std::string &s = po::validators::get_single_string(values); | |
11fdf7f2 | 417 | |
7c673cae | 418 | std::string parse_error; |
1adf2230 | 419 | uint64_t objectsize = strict_iecstrtoll(s.c_str(), &parse_error); |
7c673cae FG |
420 | if (!parse_error.empty()) { |
421 | throw po::validation_error(po::validation_error::invalid_option_value); | |
422 | } | |
423 | v = boost::any(objectsize); | |
424 | } | |
425 | ||
426 | void validate(boost::any& v, const std::vector<std::string>& values, | |
427 | ImageFormat *target_type, int dummy) { | |
428 | po::validators::check_first_occurrence(v); | |
429 | const std::string &s = po::validators::get_single_string(values); | |
430 | try { | |
431 | uint32_t format = boost::lexical_cast<uint32_t>(s); | |
432 | if (format == 1 || format == 2) { | |
433 | v = boost::any(format); | |
434 | return; | |
435 | } | |
436 | } catch (const boost::bad_lexical_cast &) { | |
437 | } | |
438 | throw po::validation_error(po::validation_error::invalid_option_value); | |
439 | } | |
440 | ||
441 | void validate(boost::any& v, const std::vector<std::string>& values, | |
442 | ImageNewFormat *target_type, int dummy) { | |
7c673cae FG |
443 | v = boost::any(true); |
444 | } | |
445 | ||
446 | void validate(boost::any& v, const std::vector<std::string>& values, | |
447 | ImageFeatures *target_type, int) { | |
448 | if (v.empty()) { | |
449 | v = boost::any(static_cast<uint64_t>(0)); | |
450 | } | |
451 | ||
452 | uint64_t &features = boost::any_cast<uint64_t &>(v); | |
453 | for (auto &value : values) { | |
454 | boost::char_separator<char> sep(","); | |
455 | boost::tokenizer<boost::char_separator<char> > tok(value, sep); | |
456 | for (auto &token : tok) { | |
457 | bool matched = false; | |
458 | for (auto &it : ImageFeatures::FEATURE_MAPPING) { | |
459 | if (token == it.second) { | |
460 | features |= it.first; | |
461 | matched = true; | |
462 | break; | |
463 | } | |
464 | } | |
465 | ||
466 | if (!matched) { | |
467 | throw po::validation_error(po::validation_error::invalid_option_value); | |
468 | } | |
469 | } | |
470 | } | |
471 | } | |
472 | ||
1911f103 TL |
473 | void validate(boost::any& v, const std::vector<std::string>& values, |
474 | MirrorImageMode* mirror_image_mode, int) { | |
475 | po::validators::check_first_occurrence(v); | |
476 | const std::string &s = po::validators::get_single_string(values); | |
477 | if (s == "journal") { | |
478 | v = boost::any(RBD_MIRROR_IMAGE_MODE_JOURNAL); | |
479 | } else if (s == "snapshot") { | |
480 | v = boost::any(RBD_MIRROR_IMAGE_MODE_SNAPSHOT); | |
481 | } else { | |
482 | throw po::validation_error(po::validation_error::invalid_option_value); | |
483 | } | |
484 | } | |
485 | ||
7c673cae FG |
486 | void validate(boost::any& v, const std::vector<std::string>& values, |
487 | Format *target_type, int) { | |
488 | po::validators::check_first_occurrence(v); | |
489 | const std::string &s = po::validators::get_single_string(values); | |
490 | if (s == "plain" || s == "json" || s == "xml") { | |
491 | v = boost::any(Format(s)); | |
492 | } else { | |
493 | throw po::validation_error(po::validation_error::invalid_option_value); | |
494 | } | |
495 | } | |
496 | ||
497 | void validate(boost::any& v, const std::vector<std::string>& values, | |
498 | JournalObjectSize *target_type, int) { | |
499 | po::validators::check_first_occurrence(v); | |
500 | const std::string &s = po::validators::get_single_string(values); | |
501 | ||
502 | std::string parse_error; | |
1adf2230 | 503 | uint64_t size = strict_iecstrtoll(s.c_str(), &parse_error); |
a8e16298 | 504 | if (parse_error.empty() && (size >= (1 << 12)) && (size <= (1 << 26))) { |
7c673cae FG |
505 | v = boost::any(size); |
506 | return; | |
507 | } | |
508 | throw po::validation_error(po::validation_error::invalid_option_value); | |
509 | } | |
510 | ||
f67539c2 TL |
511 | void validate(boost::any& v, const std::vector<std::string>& values, |
512 | EncryptionAlgorithm *target_type, int) { | |
513 | po::validators::check_first_occurrence(v); | |
514 | const std::string &s = po::validators::get_single_string(values); | |
515 | if (s == "aes-128") { | |
516 | v = boost::any(RBD_ENCRYPTION_ALGORITHM_AES128); | |
517 | } else if (s == "aes-256") { | |
518 | v = boost::any(RBD_ENCRYPTION_ALGORITHM_AES256); | |
519 | } else { | |
520 | throw po::validation_error(po::validation_error::invalid_option_value); | |
521 | } | |
522 | } | |
523 | ||
7c673cae FG |
524 | void validate(boost::any& v, const std::vector<std::string>& values, |
525 | ExportFormat *target_type, int) { | |
526 | po::validators::check_first_occurrence(v); | |
527 | const std::string &s = po::validators::get_single_string(values); | |
528 | ||
529 | std::string parse_error; | |
1adf2230 | 530 | uint64_t format = strict_iecstrtoll(s.c_str(), &parse_error); |
7c673cae FG |
531 | if (!parse_error.empty() || (format != 1 && format != 2)) { |
532 | throw po::validation_error(po::validation_error::invalid_option_value); | |
533 | } | |
534 | ||
535 | v = boost::any(format); | |
536 | } | |
537 | ||
538 | void validate(boost::any& v, const std::vector<std::string>& values, | |
539 | Secret *target_type, int) { | |
7c673cae FG |
540 | |
541 | po::validators::check_first_occurrence(v); | |
542 | const std::string &s = po::validators::get_single_string(values); | |
11fdf7f2 | 543 | g_conf().set_val_or_die("keyfile", s.c_str()); |
7c673cae FG |
544 | v = boost::any(s); |
545 | } | |
546 | ||
547 | } // namespace argument_types | |
548 | } // namespace rbd |