]> git.proxmox.com Git - pve-manager.git/blame - PVE/API2/Ceph/MDS.pm
ceph: factor out the service info generation
[pve-manager.git] / PVE / API2 / Ceph / MDS.pm
CommitLineData
b82649cc
TL
1package PVE::API2::Ceph::MDS;
2
3use strict;
4use warnings;
5
6fb08cb9 6use PVE::Ceph::Tools;
27439be6 7use PVE::Ceph::Services;
c31f487e 8use PVE::Cluster qw(cfs_read_file cfs_write_file);
b82649cc
TL
9use PVE::INotify;
10use PVE::JSONSchema qw(get_standard_option);
11use PVE::RADOS;
12use PVE::RESTHandler;
13use PVE::RPCEnvironment;
14
15use base qw(PVE::RESTHandler);
16
17__PACKAGE__->register_method ({
18 name => 'index',
19 path => '',
20 method => 'GET',
21 description => "MDS directory index.",
22 permissions => {
23 check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1],
24 },
25 proxyto => 'node',
26 protected => 1,
27 parameters => {
28 additionalProperties => 0,
29 properties => {
30 node => get_standard_option('pve-node'),
31 },
32 },
33 returns => {
34 type => 'array',
35 items => {
36 type => "object",
37 properties => {
38 name => {
39 description => "The name (ID) for the MDS",
40 },
41 addr => {
42 type => 'string',
43 optional => 1,
44 },
45 host => {
46 type => 'string',
47 optional => 1,
48 },
49 state => {
50 type => 'string',
51 description => 'State of the MDS',
52 },
53 standby_replay => {
54 type => 'boolean',
55 optional => 1,
56 description => 'If true, the standby MDS is polling the active MDS for faster recovery (hot standby).',
57 },
58 rank => {
59 type => 'integer',
60 optional => 1,
61 },
62 },
63 },
64 links => [ { rel => 'child', href => "{name}" } ],
65 },
66 code => sub {
67 my ($param) = @_;
68
6fb08cb9 69 PVE::Ceph::Tools::check_ceph_inited();
1aa902ae 70
b82649cc
TL
71 my $res = [];
72
c31f487e 73 my $cfg = cfs_read_file('ceph.conf');
d5373b7d 74 my $rados = PVE::RADOS->new();
b82649cc 75
d5373b7d 76 my $mds_hash = PVE::Ceph::Services::get_services_info("mds", $cfg, $rados);
b82649cc 77
d5373b7d 78 my $mds_state = PVE::Ceph::Services::get_cluster_mds_state($rados);
b82649cc
TL
79 foreach my $name (keys %$mds_state) {
80 my $d = $mds_state->{$name};
81 # just overwrite, this always provides more info
82 $mds_hash->{$name}->{$_} = $d->{$_} for keys %$d;
83 }
84
85 return PVE::RESTHandler::hash_to_array($mds_hash, 'name');
86 }
87});
88
89__PACKAGE__->register_method ({
90 name => 'createmds',
91 path => '{name}',
92 method => 'POST',
93 description => "Create Ceph Metadata Server (MDS)",
94 proxyto => 'node',
95 protected => 1,
96 permissions => {
97 check => ['perm', '/', [ 'Sys.Modify' ]],
98 },
99 parameters => {
100 additionalProperties => 0,
101 properties => {
102 node => get_standard_option('pve-node'),
103 name => {
104 type => 'string',
105 optional => 1,
106 default => 'nodename',
107 pattern => '[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?',
108 description => "The ID for the mds, when omitted the same as the nodename",
109 },
110 hotstandby => {
111 type => 'boolean',
112 optional => 1,
113 default => '0',
114 description => "Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. ".
115 "Faster switch on MDS failure, but needs more idle resources.",
116 },
117 },
118 },
119 returns => { type => 'string' },
120 code => sub {
121 my ($param) = @_;
122
6fb08cb9 123 PVE::Ceph::Tools::check_ceph_installed('ceph_mds');
b82649cc 124
6fb08cb9 125 PVE::Ceph::Tools::check_ceph_inited();
b82649cc
TL
126
127 my $rpcenv = PVE::RPCEnvironment::get();
128 my $authuser = $rpcenv->get_user();
129
130 my $nodename = $param->{node};
131 $nodename = INotify::nodename() if $nodename eq 'localhost';
132
133 my $mds_id = $param->{name} // $nodename;
134
135 my $worker = sub {
6fb08cb9 136 my $timeout = PVE::Ceph::Tools::get_config('long_rados_timeout');
b82649cc
TL
137 my $rados = PVE::RADOS->new(timeout => $timeout);
138
c31f487e 139 my $cfg = cfs_read_file('ceph.conf');
b82649cc
TL
140
141 my $section = "mds.$mds_id";
142
143 if (defined($cfg->{$section})) {
144 die "MDS '$mds_id' already referenced in ceph config, abort!\n"
145 }
146
147 if (!defined($cfg->{mds}->{keyring})) {
148 # $id isn't a perl variable but a ceph metavariable
149 my $keyring = '/var/lib/ceph/mds/ceph-$id/keyring';
150
151 $cfg->{mds}->{keyring} = $keyring;
152 }
153
154 $cfg->{$section}->{host} = $nodename;
155 $cfg->{$section}->{"mds standby for name"} = 'pve';
156
157 if ($param->{hotstandby}) {
158 $cfg->{$section}->{"mds standby replay"} = 'true';
159 }
160
c31f487e 161 cfs_write_file('ceph.conf', $cfg);
b82649cc 162
27439be6 163 eval { PVE::Ceph::Services::create_mds($mds_id, $rados) };
b82649cc
TL
164 if (my $err = $@) {
165 # we abort early if the section is defined, so we know that we
166 # wrote it at this point. Do not auto remove the service, could
167 # do real harm for previously manual setup MDS
168 warn "Encountered error, remove '$section' from ceph.conf\n";
c31f487e 169 my $cfg = cfs_read_file('ceph.conf');
b82649cc 170 delete $cfg->{$section};
c31f487e 171 cfs_write_file('ceph.conf', $cfg);
b82649cc
TL
172
173 die "$err\n";
174 }
175 };
176
177 return $rpcenv->fork_worker('cephcreatemds', "mds.$mds_id", $authuser, $worker);
178 }
179});
180
181__PACKAGE__->register_method ({
182 name => 'destroymds',
183 path => '{name}',
184 method => 'DELETE',
185 description => "Destroy Ceph Metadata Server",
186 proxyto => 'node',
187 protected => 1,
188 permissions => {
189 check => ['perm', '/', [ 'Sys.Modify' ]],
190 },
191 parameters => {
192 additionalProperties => 0,
193 properties => {
194 node => get_standard_option('pve-node'),
195 name => {
196 description => 'The name (ID) of the mds',
197 type => 'string',
198 pattern => '[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?',
199 },
200 },
201 },
202 returns => { type => 'string' },
203 code => sub {
204 my ($param) = @_;
205
206 my $rpcenv = PVE::RPCEnvironment::get();
207
208 my $authuser = $rpcenv->get_user();
209
6fb08cb9 210 PVE::Ceph::Tools::check_ceph_inited();
b82649cc
TL
211
212 my $mds_id = $param->{name};
213
214 my $worker = sub {
6fb08cb9 215 my $timeout = PVE::Ceph::Tools::get_config('long_rados_timeout');
b82649cc
TL
216 my $rados = PVE::RADOS->new(timeout => $timeout);
217
c31f487e 218 my $cfg = cfs_read_file('ceph.conf');
b82649cc
TL
219
220 if (defined($cfg->{"mds.$mds_id"})) {
221 delete $cfg->{"mds.$mds_id"};
c31f487e 222 cfs_write_file('ceph.conf', $cfg);
b82649cc
TL
223 }
224
27439be6 225 PVE::Ceph::Services::destroy_mds($mds_id, $rados);
b82649cc
TL
226 };
227
228 return $rpcenv->fork_worker('cephdestroymds', "mds.$mds_id", $authuser, $worker);
229 }
230});
231
2321;