1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "tools/rbd/ArgumentTypes.h"
5 #include "tools/rbd/Shell.h"
6 #include "tools/rbd/Utils.h"
7 #include "common/errno.h"
8 #include "common/Formatter.h"
9 #include "common/TextTable.h"
11 #include <boost/program_options.hpp>
15 namespace image_meta {
17 namespace at = argument_types;
18 namespace po = boost::program_options;
22 void add_key_option(po::options_description *positional) {
23 positional->add_options()
24 ("key", "image meta key");
27 int get_key(const po::variables_map &vm, std::string *key) {
28 *key = utils::get_positional_argument(vm, 1);
30 std::cerr << "rbd: metadata key was not specified" << std::endl;
36 const uint32_t MAX_KEYS = 64;
38 } // anonymous namespace
40 static int do_metadata_list(librbd::Image& image, Formatter *f)
47 bool more_results = true;
48 while (more_results) {
49 std::map<std::string, bufferlist> pairs;
50 r = image.metadata_list(last_key, MAX_KEYS, &pairs);
52 std::cerr << "failed to list metadata of image : " << cpp_strerror(r)
57 more_results = (pairs.size() == MAX_KEYS);
61 f->open_object_section("metadatas");
63 tbl.define_column("Key", TextTable::LEFT, TextTable::LEFT);
64 tbl.define_column("Value", TextTable::LEFT, TextTable::LEFT);
68 last_key = pairs.rbegin()->first;
69 count += pairs.size();
71 for (auto kv : pairs) {
72 std::string val(kv.second.c_str(), kv.second.length());
74 f->dump_string(kv.first.c_str(), val.c_str());
76 tbl << kv.first << val << TextTable::endrow;
83 bool single = (count == 1);
84 std::cout << "There " << (single ? "is" : "are") << " " << count << " "
85 << (single ? "metadatum" : "metadata") << " on this image"
86 << (count == 0 ? "." : ":") << std::endl;
94 std::cout << std::endl << tbl;
100 static int do_metadata_set(librbd::Image& image, const char *key,
103 int r = image.metadata_set(key, value);
105 std::cerr << "failed to set metadata " << key << " of image : "
106 << cpp_strerror(r) << std::endl;
111 static int do_metadata_remove(librbd::Image& image, const char *key)
113 int r = image.metadata_remove(key);
115 std::cerr << "rbd: no existing metadata key " << key << " of image : "
116 << cpp_strerror(r) << std::endl;
118 std::cerr << "failed to remove metadata " << key << " of image : "
119 << cpp_strerror(r) << std::endl;
124 static int do_metadata_get(librbd::Image& image, const char *key)
127 int r = image.metadata_get(key, &s);
129 std::cerr << "failed to get metadata " << key << " of image : "
130 << cpp_strerror(r) << std::endl;
133 std::cout << s << std::endl;
137 void get_list_arguments(po::options_description *positional,
138 po::options_description *options) {
139 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
140 at::add_format_options(options);
143 int execute_list(const po::variables_map &vm) {
144 size_t arg_index = 0;
145 std::string pool_name;
146 std::string image_name;
147 std::string snap_name;
148 int r = utils::get_pool_image_snapshot_names(
149 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
150 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
155 at::Format::Formatter formatter;
156 r = utils::get_formatter(vm, &formatter);
161 librados::Rados rados;
162 librados::IoCtx io_ctx;
164 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
165 &rados, &io_ctx, &image);
170 r = do_metadata_list(image, formatter.get());
172 std::cerr << "rbd: listing metadata failed: " << cpp_strerror(r)
179 void get_get_arguments(po::options_description *positional,
180 po::options_description *options) {
181 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
182 add_key_option(positional);
185 int execute_get(const po::variables_map &vm) {
186 size_t arg_index = 0;
187 std::string pool_name;
188 std::string image_name;
189 std::string snap_name;
190 int r = utils::get_pool_image_snapshot_names(
191 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
192 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
198 r = get_key(vm, &key);
203 librados::Rados rados;
204 librados::IoCtx io_ctx;
206 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
207 &rados, &io_ctx, &image);
212 r = do_metadata_get(image, key.c_str());
214 std::cerr << "rbd: getting metadata failed: " << cpp_strerror(r)
221 void get_set_arguments(po::options_description *positional,
222 po::options_description *options) {
223 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
224 add_key_option(positional);
225 positional->add_options()
226 ("value", "image meta value");
229 int execute_set(const po::variables_map &vm) {
230 size_t arg_index = 0;
231 std::string pool_name;
232 std::string image_name;
233 std::string snap_name;
234 int r = utils::get_pool_image_snapshot_names(
235 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
236 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
242 r = get_key(vm, &key);
247 std::string value = utils::get_positional_argument(vm, 2);
249 std::cerr << "rbd: metadata value was not specified" << std::endl;
253 librados::Rados rados;
254 librados::IoCtx io_ctx;
256 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
257 &rados, &io_ctx, &image);
262 r = do_metadata_set(image, key.c_str(), value.c_str());
264 std::cerr << "rbd: setting metadata failed: " << cpp_strerror(r)
271 void get_remove_arguments(po::options_description *positional,
272 po::options_description *options) {
273 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
274 add_key_option(positional);
277 int execute_remove(const po::variables_map &vm) {
278 size_t arg_index = 0;
279 std::string pool_name;
280 std::string image_name;
281 std::string snap_name;
282 int r = utils::get_pool_image_snapshot_names(
283 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
284 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
290 r = get_key(vm, &key);
295 librados::Rados rados;
296 librados::IoCtx io_ctx;
298 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
299 &rados, &io_ctx, &image);
304 r = do_metadata_remove(image, key.c_str());
306 std::cerr << "rbd: removing metadata failed: " << cpp_strerror(r)
313 Shell::Action action_list(
314 {"image-meta", "list"}, {}, "Image metadata list keys with values.", "",
315 &get_list_arguments, &execute_list);
316 Shell::Action action_get(
317 {"image-meta", "get"}, {},
318 "Image metadata get the value associated with the key.", "",
319 &get_get_arguments, &execute_get);
320 Shell::Action action_set(
321 {"image-meta", "set"}, {}, "Image metadata set key with value.", "",
322 &get_set_arguments, &execute_set);
323 Shell::Action action_remove(
324 {"image-meta", "remove"}, {},
325 "Image metadata remove the key and value associated.", "",
326 &get_remove_arguments, &execute_remove);
328 } // namespace image_meta
329 } // namespace action