]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd/action/ImageMeta.cc
update sources to v12.1.3
[ceph.git] / ceph / src / tools / rbd / action / ImageMeta.cc
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 "common/errno.h"
8 #include "common/Formatter.h"
9 #include "common/TextTable.h"
10 #include <iostream>
11 #include <boost/program_options.hpp>
12
13 namespace rbd {
14 namespace action {
15 namespace image_meta {
16
17 namespace at = argument_types;
18 namespace po = boost::program_options;
19
20 namespace {
21
22 void add_key_option(po::options_description *positional) {
23 positional->add_options()
24 ("key", "image meta key");
25 }
26
27 int get_key(const po::variables_map &vm, std::string *key) {
28 *key = utils::get_positional_argument(vm, 1);
29 if (key->empty()) {
30 std::cerr << "rbd: metadata key was not specified" << std::endl;
31 return -EINVAL;
32 }
33 return 0;
34 }
35
36 } // anonymous namespace
37
38 static int do_metadata_list(librbd::Image& image, Formatter *f)
39 {
40 std::map<std::string, bufferlist> pairs;
41 int r;
42 TextTable tbl;
43
44 r = image.metadata_list("", 0, &pairs);
45 if (r < 0) {
46 std::cerr << "failed to list metadata of image : " << cpp_strerror(r)
47 << std::endl;
48 return r;
49 }
50
51 if (f) {
52 f->open_object_section("metadatas");
53 } else {
54 tbl.define_column("Key", TextTable::LEFT, TextTable::LEFT);
55 tbl.define_column("Value", TextTable::LEFT, TextTable::LEFT);
56 }
57
58 if (!pairs.empty()) {
59 bool one = (pairs.size() == 1);
60
61 if (!f) {
62 std::cout << "There " << (one ? "is " : "are ") << pairs.size()
63 << " metadata" << (one ? "" : "s") << " on this image.\n";
64 }
65
66 for (std::map<std::string, bufferlist>::iterator it = pairs.begin();
67 it != pairs.end(); ++it) {
68 std::string val(it->second.c_str(), it->second.length());
69 if (f) {
70 f->dump_string(it->first.c_str(), val.c_str());
71 } else {
72 tbl << it->first << val.c_str() << TextTable::endrow;
73 }
74 }
75 if (!f)
76 std::cout << tbl;
77 }
78
79 if (f) {
80 f->close_section();
81 f->flush(std::cout);
82 }
83 return 0;
84 }
85
86 static int do_metadata_set(librbd::Image& image, const char *key,
87 const char *value)
88 {
89 int r = image.metadata_set(key, value);
90 if (r < 0) {
91 std::cerr << "failed to set metadata " << key << " of image : "
92 << cpp_strerror(r) << std::endl;
93 }
94 return r;
95 }
96
97 static int do_metadata_remove(librbd::Image& image, const char *key)
98 {
99 int r = image.metadata_remove(key);
100 if (r == -ENOENT) {
101 std::cerr << "rbd: no existing metadata key " << key << " of image : "
102 << cpp_strerror(r) << std::endl;
103 } else if(r < 0) {
104 std::cerr << "failed to remove metadata " << key << " of image : "
105 << cpp_strerror(r) << std::endl;
106 }
107 return r;
108 }
109
110 static int do_metadata_get(librbd::Image& image, const char *key)
111 {
112 std::string s;
113 int r = image.metadata_get(key, &s);
114 if (r < 0) {
115 std::cerr << "failed to get metadata " << key << " of image : "
116 << cpp_strerror(r) << std::endl;
117 return r;
118 }
119 std::cout << s << std::endl;
120 return r;
121 }
122
123 void get_list_arguments(po::options_description *positional,
124 po::options_description *options) {
125 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
126 at::add_format_options(options);
127 }
128
129 int execute_list(const po::variables_map &vm) {
130 size_t arg_index = 0;
131 std::string pool_name;
132 std::string image_name;
133 std::string snap_name;
134 int r = utils::get_pool_image_snapshot_names(
135 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
136 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
137 if (r < 0) {
138 return r;
139 }
140
141 at::Format::Formatter formatter;
142 r = utils::get_formatter(vm, &formatter);
143 if (r < 0) {
144 return r;
145 }
146
147 librados::Rados rados;
148 librados::IoCtx io_ctx;
149 librbd::Image image;
150 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
151 &rados, &io_ctx, &image);
152 if (r < 0) {
153 return r;
154 }
155
156 r = do_metadata_list(image, formatter.get());
157 if (r < 0) {
158 std::cerr << "rbd: listing metadata failed: " << cpp_strerror(r)
159 << std::endl;
160 return r;
161 }
162 return 0;
163 }
164
165 void get_get_arguments(po::options_description *positional,
166 po::options_description *options) {
167 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
168 add_key_option(positional);
169 }
170
171 int execute_get(const po::variables_map &vm) {
172 size_t arg_index = 0;
173 std::string pool_name;
174 std::string image_name;
175 std::string snap_name;
176 int r = utils::get_pool_image_snapshot_names(
177 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
178 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
179 if (r < 0) {
180 return r;
181 }
182
183 std::string key;
184 r = get_key(vm, &key);
185 if (r < 0) {
186 return r;
187 }
188
189 librados::Rados rados;
190 librados::IoCtx io_ctx;
191 librbd::Image image;
192 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
193 &rados, &io_ctx, &image);
194 if (r < 0) {
195 return r;
196 }
197
198 r = do_metadata_get(image, key.c_str());
199 if (r < 0) {
200 std::cerr << "rbd: getting metadata failed: " << cpp_strerror(r)
201 << std::endl;
202 return r;
203 }
204 return 0;
205 }
206
207 void get_set_arguments(po::options_description *positional,
208 po::options_description *options) {
209 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
210 add_key_option(positional);
211 positional->add_options()
212 ("value", "image meta value");
213 }
214
215 int execute_set(const po::variables_map &vm) {
216 size_t arg_index = 0;
217 std::string pool_name;
218 std::string image_name;
219 std::string snap_name;
220 int r = utils::get_pool_image_snapshot_names(
221 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
222 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
223 if (r < 0) {
224 return r;
225 }
226
227 std::string key;
228 r = get_key(vm, &key);
229 if (r < 0) {
230 return r;
231 }
232
233 std::string value = utils::get_positional_argument(vm, 2);
234 if (value.empty()) {
235 std::cerr << "rbd: metadata value was not specified" << std::endl;
236 return -EINVAL;
237 }
238
239 librados::Rados rados;
240 librados::IoCtx io_ctx;
241 librbd::Image image;
242 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
243 &rados, &io_ctx, &image);
244 if (r < 0) {
245 return r;
246 }
247
248 r = do_metadata_set(image, key.c_str(), value.c_str());
249 if (r < 0) {
250 std::cerr << "rbd: setting metadata failed: " << cpp_strerror(r)
251 << std::endl;
252 return r;
253 }
254 return 0;
255 }
256
257 void get_remove_arguments(po::options_description *positional,
258 po::options_description *options) {
259 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
260 add_key_option(positional);
261 }
262
263 int execute_remove(const po::variables_map &vm) {
264 size_t arg_index = 0;
265 std::string pool_name;
266 std::string image_name;
267 std::string snap_name;
268 int r = utils::get_pool_image_snapshot_names(
269 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
270 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
271 if (r < 0) {
272 return r;
273 }
274
275 std::string key;
276 r = get_key(vm, &key);
277 if (r < 0) {
278 return r;
279 }
280
281 librados::Rados rados;
282 librados::IoCtx io_ctx;
283 librbd::Image image;
284 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
285 &rados, &io_ctx, &image);
286 if (r < 0) {
287 return r;
288 }
289
290 r = do_metadata_remove(image, key.c_str());
291 if (r < 0) {
292 std::cerr << "rbd: removing metadata failed: " << cpp_strerror(r)
293 << std::endl;
294 return r;
295 }
296 return 0;
297 }
298
299 Shell::Action action_list(
300 {"image-meta", "list"}, {}, "Image metadata list keys with values.", "",
301 &get_list_arguments, &execute_list);
302 Shell::Action action_get(
303 {"image-meta", "get"}, {},
304 "Image metadata get the value associated with the key.", "",
305 &get_get_arguments, &execute_get);
306 Shell::Action action_set(
307 {"image-meta", "set"}, {}, "Image metadata set key with value.", "",
308 &get_set_arguments, &execute_set);
309 Shell::Action action_remove(
310 {"image-meta", "remove"}, {},
311 "Image metadata remove the key and value associated.", "",
312 &get_remove_arguments, &execute_remove);
313
314 } // namespace image_meta
315 } // namespace action
316 } // namespace rbd