]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | |
2 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | |
3 | // vim: ts=8 sw=2 smarttab | |
4 | ||
5 | #include "tools/rbd/ArgumentTypes.h" | |
6 | #include "tools/rbd/Shell.h" | |
7 | #include "tools/rbd/Utils.h" | |
8 | #include "common/errno.h" | |
9 | #include "include/stringify.h" | |
10 | #include "common/Formatter.h" | |
11 | #include "common/TextTable.h" | |
12 | #include <algorithm> | |
13 | #include <iostream> | |
14 | #include <boost/program_options.hpp> | |
15 | ||
16 | namespace rbd { | |
17 | namespace action { | |
18 | namespace ns { | |
19 | ||
20 | namespace at = argument_types; | |
21 | namespace po = boost::program_options; | |
22 | ||
23 | void get_create_arguments(po::options_description *positional, | |
24 | po::options_description *options) { | |
25 | at::add_pool_options(positional, options, true); | |
26 | } | |
27 | ||
28 | int execute_create(const po::variables_map &vm, | |
29 | const std::vector<std::string> &ceph_global_init_args) { | |
30 | std::string pool_name; | |
31 | std::string namespace_name; | |
32 | size_t arg_index = 0; | |
2a845540 | 33 | int r = utils::get_pool_and_namespace_names(vm, true, &pool_name, |
11fdf7f2 TL |
34 | &namespace_name, &arg_index); |
35 | if (r < 0) { | |
36 | return r; | |
37 | } | |
38 | ||
39 | if (namespace_name.empty()) { | |
40 | std::cerr << "rbd: namespace name was not specified" << std::endl; | |
41 | return -EINVAL; | |
42 | } | |
43 | ||
44 | librados::Rados rados; | |
45 | librados::IoCtx io_ctx; | |
46 | r = utils::init(pool_name, "", &rados, &io_ctx); | |
47 | if (r < 0) { | |
48 | return r; | |
49 | } | |
50 | ||
51 | librbd::RBD rbd; | |
52 | r = rbd.namespace_create(io_ctx, namespace_name.c_str()); | |
53 | if (r < 0) { | |
54 | std::cerr << "rbd: failed to created namespace: " << cpp_strerror(r) | |
55 | << std::endl; | |
56 | return r; | |
57 | } | |
58 | ||
59 | return 0; | |
60 | } | |
61 | ||
62 | void get_remove_arguments(po::options_description *positional, | |
63 | po::options_description *options) { | |
64 | at::add_pool_options(positional, options, true); | |
65 | } | |
66 | ||
67 | int execute_remove(const po::variables_map &vm, | |
68 | const std::vector<std::string> &ceph_global_init_args) { | |
69 | std::string pool_name; | |
70 | std::string namespace_name; | |
71 | size_t arg_index = 0; | |
2a845540 | 72 | int r = utils::get_pool_and_namespace_names(vm, true, &pool_name, |
11fdf7f2 TL |
73 | &namespace_name, &arg_index); |
74 | if (r < 0) { | |
75 | return r; | |
76 | } | |
77 | ||
78 | if (namespace_name.empty()) { | |
79 | std::cerr << "rbd: namespace name was not specified" << std::endl; | |
80 | return -EINVAL; | |
81 | } | |
82 | ||
83 | librados::Rados rados; | |
84 | librados::IoCtx io_ctx; | |
85 | r = utils::init(pool_name, "", &rados, &io_ctx); | |
86 | if (r < 0) { | |
87 | return r; | |
88 | } | |
89 | ||
90 | librbd::RBD rbd; | |
91 | r = rbd.namespace_remove(io_ctx, namespace_name.c_str()); | |
92 | if (r == -EBUSY) { | |
93 | std::cerr << "rbd: namespace contains images which must be deleted first." | |
94 | << std::endl; | |
95 | return r; | |
96 | } else if (r == -ENOENT) { | |
97 | std::cerr << "rbd: namespace does not exist." << std::endl; | |
98 | return r; | |
99 | } else if (r < 0) { | |
100 | std::cerr << "rbd: failed to remove namespace: " << cpp_strerror(r) | |
101 | << std::endl; | |
102 | return r; | |
103 | } | |
104 | ||
105 | return 0; | |
106 | } | |
107 | ||
108 | void get_list_arguments(po::options_description *positional, | |
109 | po::options_description *options) { | |
110 | at::add_pool_options(positional, options, false); | |
111 | at::add_format_options(options); | |
112 | } | |
113 | ||
114 | int execute_list(const po::variables_map &vm, | |
115 | const std::vector<std::string> &ceph_global_init_args) { | |
116 | std::string pool_name; | |
117 | size_t arg_index = 0; | |
2a845540 | 118 | int r = utils::get_pool_and_namespace_names(vm, true, &pool_name, |
11fdf7f2 TL |
119 | nullptr, &arg_index); |
120 | if (r < 0) { | |
121 | return r; | |
122 | } | |
123 | ||
124 | at::Format::Formatter formatter; | |
125 | r = utils::get_formatter(vm, &formatter); | |
126 | if (r < 0) { | |
127 | return r; | |
128 | } | |
129 | ||
130 | librados::Rados rados; | |
131 | librados::IoCtx io_ctx; | |
132 | r = utils::init(pool_name, "", &rados, &io_ctx); | |
133 | if (r < 0) { | |
134 | return r; | |
135 | } | |
136 | ||
137 | librbd::RBD rbd; | |
138 | std::vector<std::string> names; | |
139 | r = rbd.namespace_list(io_ctx, &names); | |
140 | if (r < 0 && r != -ENOENT) { | |
141 | std::cerr << "rbd: failed to list namespaces: " << cpp_strerror(r) | |
142 | << std::endl; | |
143 | return r; | |
144 | } | |
145 | ||
146 | std::sort(names.begin(), names.end()); | |
147 | ||
148 | TextTable tbl; | |
149 | if (formatter) { | |
150 | formatter->open_array_section("namespaces"); | |
151 | } else { | |
152 | tbl.define_column("NAME", TextTable::LEFT, TextTable::LEFT); | |
153 | } | |
154 | ||
155 | for (auto& name : names) { | |
156 | if (formatter) { | |
157 | formatter->open_object_section("namespace"); | |
158 | formatter->dump_string("name", name); | |
159 | formatter->close_section(); | |
160 | } else { | |
161 | tbl << name << TextTable::endrow; | |
162 | } | |
163 | } | |
164 | ||
165 | if (formatter) { | |
166 | formatter->close_section(); | |
167 | formatter->flush(std::cout); | |
168 | } else if (!names.empty()) { | |
169 | std::cout << tbl; | |
170 | } | |
171 | ||
172 | return 0; | |
173 | } | |
174 | ||
175 | Shell::Action action_create( | |
176 | {"namespace", "create"}, {}, | |
177 | "Create an RBD image namespace.", "", | |
178 | &get_create_arguments, &execute_create); | |
179 | ||
180 | Shell::Action action_remove( | |
181 | {"namespace", "remove"}, {"namespace", "rm"}, | |
182 | "Remove an RBD image namespace.", "", | |
183 | &get_remove_arguments, &execute_remove); | |
184 | ||
185 | Shell::Action action_list( | |
186 | {"namespace", "list"}, {"namespace", "ls"}, "List RBD image namespaces.", "", | |
187 | &get_list_arguments, &execute_list); | |
188 | ||
189 | } // namespace ns | |
190 | } // namespace action | |
191 | } // namespace rbd |