]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/rbd/action/Namespace.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / tools / rbd / action / Namespace.cc
CommitLineData
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
16namespace rbd {
17namespace action {
18namespace ns {
19
20namespace at = argument_types;
21namespace po = boost::program_options;
22
23void get_create_arguments(po::options_description *positional,
24 po::options_description *options) {
25 at::add_pool_options(positional, options, true);
26}
27
28int 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
62void get_remove_arguments(po::options_description *positional,
63 po::options_description *options) {
64 at::add_pool_options(positional, options, true);
65}
66
67int 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
108void 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
114int 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
175Shell::Action action_create(
176 {"namespace", "create"}, {},
177 "Create an RBD image namespace.", "",
178 &get_create_arguments, &execute_create);
179
180Shell::Action action_remove(
181 {"namespace", "remove"}, {"namespace", "rm"},
182 "Remove an RBD image namespace.", "",
183 &get_remove_arguments, &execute_remove);
184
185Shell::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