]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd/action/ImageMeta.cc
d3147ab0e9ca95b7a622798f11a7133cc73d5363
[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 < 0) {
101 std::cerr << "failed to remove metadata " << key << " of image : "
102 << cpp_strerror(r) << std::endl;
103 }
104 return r;
105 }
106
107 static int do_metadata_get(librbd::Image& image, const char *key)
108 {
109 std::string s;
110 int r = image.metadata_get(key, &s);
111 if (r < 0) {
112 std::cerr << "failed to get metadata " << key << " of image : "
113 << cpp_strerror(r) << std::endl;
114 return r;
115 }
116 std::cout << s << std::endl;
117 return r;
118 }
119
120 void get_list_arguments(po::options_description *positional,
121 po::options_description *options) {
122 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
123 at::add_format_options(options);
124 }
125
126 int execute_list(const po::variables_map &vm) {
127 size_t arg_index = 0;
128 std::string pool_name;
129 std::string image_name;
130 std::string snap_name;
131 int r = utils::get_pool_image_snapshot_names(
132 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
133 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
134 if (r < 0) {
135 return r;
136 }
137
138 at::Format::Formatter formatter;
139 r = utils::get_formatter(vm, &formatter);
140 if (r < 0) {
141 return r;
142 }
143
144 librados::Rados rados;
145 librados::IoCtx io_ctx;
146 librbd::Image image;
147 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
148 &rados, &io_ctx, &image);
149 if (r < 0) {
150 return r;
151 }
152
153 r = do_metadata_list(image, formatter.get());
154 if (r < 0) {
155 std::cerr << "rbd: listing metadata failed: " << cpp_strerror(r)
156 << std::endl;
157 return r;
158 }
159 return 0;
160 }
161
162 void get_get_arguments(po::options_description *positional,
163 po::options_description *options) {
164 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
165 add_key_option(positional);
166 }
167
168 int execute_get(const po::variables_map &vm) {
169 size_t arg_index = 0;
170 std::string pool_name;
171 std::string image_name;
172 std::string snap_name;
173 int r = utils::get_pool_image_snapshot_names(
174 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
175 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
176 if (r < 0) {
177 return r;
178 }
179
180 std::string key;
181 r = get_key(vm, &key);
182 if (r < 0) {
183 return r;
184 }
185
186 librados::Rados rados;
187 librados::IoCtx io_ctx;
188 librbd::Image image;
189 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
190 &rados, &io_ctx, &image);
191 if (r < 0) {
192 return r;
193 }
194
195 r = do_metadata_get(image, key.c_str());
196 if (r < 0) {
197 std::cerr << "rbd: getting metadata failed: " << cpp_strerror(r)
198 << std::endl;
199 return r;
200 }
201 return 0;
202 }
203
204 void get_set_arguments(po::options_description *positional,
205 po::options_description *options) {
206 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
207 add_key_option(positional);
208 positional->add_options()
209 ("value", "image meta value");
210 }
211
212 int execute_set(const po::variables_map &vm) {
213 size_t arg_index = 0;
214 std::string pool_name;
215 std::string image_name;
216 std::string snap_name;
217 int r = utils::get_pool_image_snapshot_names(
218 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
219 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
220 if (r < 0) {
221 return r;
222 }
223
224 std::string key;
225 r = get_key(vm, &key);
226 if (r < 0) {
227 return r;
228 }
229
230 std::string value = utils::get_positional_argument(vm, 2);
231 if (value.empty()) {
232 std::cerr << "rbd: metadata value was not specified" << std::endl;
233 return -EINVAL;
234 }
235
236 librados::Rados rados;
237 librados::IoCtx io_ctx;
238 librbd::Image image;
239 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
240 &rados, &io_ctx, &image);
241 if (r < 0) {
242 return r;
243 }
244
245 r = do_metadata_set(image, key.c_str(), value.c_str());
246 if (r < 0) {
247 std::cerr << "rbd: setting metadata failed: " << cpp_strerror(r)
248 << std::endl;
249 return r;
250 }
251 return 0;
252 }
253
254 void get_remove_arguments(po::options_description *positional,
255 po::options_description *options) {
256 at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
257 add_key_option(positional);
258 }
259
260 int execute_remove(const po::variables_map &vm) {
261 size_t arg_index = 0;
262 std::string pool_name;
263 std::string image_name;
264 std::string snap_name;
265 int r = utils::get_pool_image_snapshot_names(
266 vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
267 &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE);
268 if (r < 0) {
269 return r;
270 }
271
272 std::string key;
273 r = get_key(vm, &key);
274 if (r < 0) {
275 return r;
276 }
277
278 librados::Rados rados;
279 librados::IoCtx io_ctx;
280 librbd::Image image;
281 r = utils::init_and_open_image(pool_name, image_name, "", "", false,
282 &rados, &io_ctx, &image);
283 if (r < 0) {
284 return r;
285 }
286
287 r = do_metadata_remove(image, key.c_str());
288 if (r < 0) {
289 std::cerr << "rbd: removing metadata failed: " << cpp_strerror(r)
290 << std::endl;
291 return r;
292 }
293 return 0;
294 }
295
296 Shell::Action action_list(
297 {"image-meta", "list"}, {}, "Image metadata list keys with values.", "",
298 &get_list_arguments, &execute_list);
299 Shell::Action action_get(
300 {"image-meta", "get"}, {},
301 "Image metadata get the value associated with the key.", "",
302 &get_get_arguments, &execute_get);
303 Shell::Action action_set(
304 {"image-meta", "set"}, {}, "Image metadata set key with value.", "",
305 &get_set_arguments, &execute_set);
306 Shell::Action action_remove(
307 {"image-meta", "remove"}, {},
308 "Image metadata remove the key and value associated.", "",
309 &get_remove_arguments, &execute_remove);
310
311 } // namespace image_meta
312 } // namespace action
313 } // namespace rbd