]> git.proxmox.com Git - pve-manager.git/blame - PVE/API2/Ceph/Pools.pm
api: ceph pools: add type to returned properties
[pve-manager.git] / PVE / API2 / Ceph / Pools.pm
CommitLineData
56d02a86
AA
1package PVE::API2::Ceph::Pools;
2
3use strict;
4use warnings;
5
6use PVE::Ceph::Tools;
7use PVE::Ceph::Services;
f35e7fcd 8use PVE::JSONSchema qw(get_standard_option parse_property_string);
56d02a86
AA
9use PVE::RADOS;
10use PVE::RESTHandler;
11use PVE::RPCEnvironment;
12use PVE::Storage;
13use PVE::Tools qw(extract_param);
14
15use PVE::API2::Storage::Config;
16
17use base qw(PVE::RESTHandler);
18
5a3d7942
AA
19my $get_autoscale_status = sub {
20 my ($rados) = shift;
21
22 $rados = PVE::RADOS->new() if !defined($rados);
23
24 my $autoscale = $rados->mon_command({
25 prefix => 'osd pool autoscale-status'});
26
27 my $data;
28 foreach my $p (@$autoscale) {
5a3d7942
AA
29 $data->{$p->{pool_name}} = $p;
30 }
31
32 return $data;
33};
34
35
56d02a86
AA
36__PACKAGE__->register_method ({
37 name => 'lspools',
38 path => '',
39 method => 'GET',
40 description => "List all pools.",
41 proxyto => 'node',
42 protected => 1,
43 permissions => {
44 check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1],
45 },
46 parameters => {
47 additionalProperties => 0,
48 properties => {
49 node => get_standard_option('pve-node'),
50 },
51 },
52 returns => {
53 type => 'array',
54 items => {
55 type => "object",
56 properties => {
84b08e8a
TL
57 pool => {
58 type => 'integer',
59 title => 'ID',
60 },
61 pool_name => {
62 type => 'string',
63 title => 'Name',
64 },
65 size => {
66 type => 'integer',
67 title => 'Size',
68 },
fca1900c
AL
69 type => {
70 type => 'string',
71 title => 'Type',
72 enum => ['replicated', 'erasure', 'unknown'],
73 },
84b08e8a
TL
74 min_size => {
75 type => 'integer',
76 title => 'Min Size',
77 },
78 pg_num => {
79 type => 'integer',
80 title => 'PG Num',
81 },
82 pg_num_min => {
83 type => 'integer',
84 title => 'min. PG Num',
85 optional => 1,
86 },
87 pg_num_final => {
88 type => 'integer',
89 title => 'Optimal PG Num',
90 optional => 1,
91 },
92 pg_autoscale_mode => {
93 type => 'string',
94 title => 'PG Autoscale Mode',
95 optional => 1,
96 },
97 crush_rule => {
98 type => 'integer',
99 title => 'Crush Rule',
100 },
101 crush_rule_name => {
102 type => 'string',
103 title => 'Crush Rule Name',
104 },
105 percent_used => {
106 type => 'number',
107 title => '%-Used',
108 },
109 bytes_used => {
110 type => 'integer',
111 title => 'Used',
112 },
113 target_size => {
114 type => 'integer',
115 title => 'PG Autoscale Target Size',
116 optional => 1,
117 },
118 target_size_ratio => {
119 type => 'number',
120 title => 'PG Autoscale Target Ratio',
121 optional => 1,
122 },
123 autoscale_status => {
124 type => 'object',
125 title => 'Autoscale Status',
126 optional => 1,
127 },
56d02a86
AA
128 },
129 },
130 links => [ { rel => 'child', href => "{pool_name}" } ],
131 },
132 code => sub {
133 my ($param) = @_;
134
135 PVE::Ceph::Tools::check_ceph_inited();
136
137 my $rados = PVE::RADOS->new();
138
139 my $stats = {};
140 my $res = $rados->mon_command({ prefix => 'df' });
141
142 foreach my $d (@{$res->{pools}}) {
143 next if !$d->{stats};
144 next if !defined($d->{id});
145 $stats->{$d->{id}} = $d->{stats};
146 }
147
148 $res = $rados->mon_command({ prefix => 'osd dump' });
149 my $rulestmp = $rados->mon_command({ prefix => 'osd crush rule dump'});
150
151 my $rules = {};
152 for my $rule (@$rulestmp) {
153 $rules->{$rule->{rule_id}} = $rule->{rule_name};
154 }
155
156 my $data = [];
157 my $attr_list = [
158 'pool',
159 'pool_name',
160 'size',
161 'min_size',
162 'pg_num',
163 'crush_rule',
164 'pg_autoscale_mode',
165 ];
166
5a3d7942
AA
167 # pg_autoscaler module is not enabled in Nautilus
168 my $autoscale = eval { $get_autoscale_status->($rados) };
169
56d02a86
AA
170 foreach my $e (@{$res->{pools}}) {
171 my $d = {};
172 foreach my $attr (@$attr_list) {
173 $d->{$attr} = $e->{$attr} if defined($e->{$attr});
174 }
175
5a3d7942
AA
176 if ($autoscale) {
177 $d->{autoscale_status} = $autoscale->{$d->{pool_name}};
178 $d->{pg_num_final} = $d->{autoscale_status}->{pg_num_final};
179 # some info is nested under options instead
180 $d->{pg_num_min} = $e->{options}->{pg_num_min};
181 $d->{target_size} = $e->{options}->{target_size_bytes};
182 $d->{target_size_ratio} = $e->{options}->{target_size_ratio};
183 }
184
56d02a86
AA
185 if (defined($d->{crush_rule}) && defined($rules->{$d->{crush_rule}})) {
186 $d->{crush_rule_name} = $rules->{$d->{crush_rule}};
187 }
188
189 if (my $s = $stats->{$d->{pool}}) {
190 $d->{bytes_used} = $s->{bytes_used};
191 $d->{percent_used} = $s->{percent_used};
192 }
fca1900c
AL
193
194 # Cephs numerical pool types are barely documented. Found the following in the Ceph
195 # codebase: https://github.com/ceph/ceph/blob/ff144995a849407c258bcb763daa3e03cfce5059/src/osd/osd_types.h#L1221-L1233
196 if ($e->{type} == 1) {
197 $d->{type} = 'replicated';
198 } elsif ($e->{type} == 3) {
199 $d->{type} = 'erasure';
200 } else {
201 # we should never get here, but better be safe
202 $d->{type} = 'unknown';
203 }
56d02a86
AA
204 push @$data, $d;
205 }
206
207
208 return $data;
209 }});
210
211
212my $ceph_pool_common_options = sub {
213 my ($nodefault) = shift;
214 my $options = {
215 name => {
461e2141 216 title => 'Name',
56d02a86
AA
217 description => "The name of the pool. It must be unique.",
218 type => 'string',
219 },
220 size => {
461e2141 221 title => 'Size',
56d02a86
AA
222 description => 'Number of replicas per object',
223 type => 'integer',
224 default => 3,
225 optional => 1,
226 minimum => 1,
227 maximum => 7,
228 },
229 min_size => {
461e2141 230 title => 'Min Size',
56d02a86
AA
231 description => 'Minimum number of replicas per object',
232 type => 'integer',
233 default => 2,
234 optional => 1,
235 minimum => 1,
236 maximum => 7,
237 },
238 pg_num => {
461e2141 239 title => 'PG Num',
56d02a86
AA
240 description => "Number of placement groups.",
241 type => 'integer',
242 default => 128,
243 optional => 1,
6b36f368 244 minimum => 1,
56d02a86
AA
245 maximum => 32768,
246 },
5a3d7942
AA
247 pg_num_min => {
248 title => 'min. PG Num',
249 description => "Minimal number of placement groups.",
250 type => 'integer',
251 optional => 1,
252 maximum => 32768,
253 },
56d02a86 254 crush_rule => {
461e2141 255 title => 'Crush Rule Name',
56d02a86
AA
256 description => "The rule to use for mapping object placement in the cluster.",
257 type => 'string',
258 optional => 1,
259 },
260 application => {
461e2141 261 title => 'Application',
56d02a86
AA
262 description => "The application of the pool.",
263 default => 'rbd',
264 type => 'string',
265 enum => ['rbd', 'cephfs', 'rgw'],
266 optional => 1,
267 },
268 pg_autoscale_mode => {
461e2141 269 title => 'PG Autoscale Mode',
56d02a86
AA
270 description => "The automatic PG scaling mode of the pool.",
271 type => 'string',
272 enum => ['on', 'off', 'warn'],
273 default => 'warn',
274 optional => 1,
275 },
5a3d7942
AA
276 target_size => {
277 description => "The estimated target size of the pool for the PG autoscaler.",
278 title => 'PG Autoscale Target Size',
279 type => 'string',
280 pattern => '^(\d+(\.\d+)?)([KMGT])?$',
281 optional => 1,
282 },
283 target_size_ratio => {
284 description => "The estimated target ratio of the pool for the PG autoscaler.",
285 title => 'PG Autoscale Target Ratio',
286 type => 'number',
287 optional => 1,
288 },
56d02a86
AA
289 };
290
291 if ($nodefault) {
292 delete $options->{$_}->{default} for keys %$options;
293 }
294 return $options;
295};
296
297
298my $add_storage = sub {
f35e7fcd 299 my ($pool, $storeid, $ec_data_pool) = @_;
56d02a86
AA
300
301 my $storage_params = {
302 type => 'rbd',
303 pool => $pool,
304 storage => $storeid,
305 krbd => 0,
306 content => 'rootdir,images',
307 };
308
f35e7fcd 309 $storage_params->{'data-pool'} = $ec_data_pool if $ec_data_pool;
3bd128d7 310
56d02a86
AA
311 PVE::API2::Storage::Config->create($storage_params);
312};
313
314my $get_storages = sub {
315 my ($pool) = @_;
316
317 my $cfg = PVE::Storage::config();
318
319 my $storages = $cfg->{ids};
320 my $res = {};
321 foreach my $storeid (keys %$storages) {
322 my $curr = $storages->{$storeid};
29fe1eea
AL
323 next if $curr->{type} ne 'rbd';
324 if (
325 $pool eq $curr->{pool} ||
326 (defined $curr->{'data-pool'} && $pool eq $curr->{'data-pool'})
327 ) {
328 $res->{$storeid} = $storages->{$storeid};
329 }
56d02a86
AA
330 }
331
332 return $res;
333};
334
f35e7fcd
TL
335my $ec_format = {
336 k => {
337 type => 'integer',
338 description => "Number of data chunks. Will create an erasure coded pool plus a"
339 ." replicated pool for metadata.",
136f761b 340 minimum => 2,
f35e7fcd
TL
341 },
342 m => {
343 type => 'integer',
344 description => "Number of coding chunks. Will create an erasure coded pool plus a"
345 ." replicated pool for metadata.",
346 minimum => 1,
347 },
348 'failure-domain' => {
349 type => 'string',
350 description => "CRUSH failure domain. Default is 'host'. Will create an erasure"
351 ." coded pool plus a replicated pool for metadata.",
352 format_description => 'domain',
353 optional => 1,
136f761b 354 default => 'host',
f35e7fcd
TL
355 },
356 'device-class' => {
357 type => 'string',
358 description => "CRUSH device class. Will create an erasure coded pool plus a"
359 ." replicated pool for metadata.",
360 format_description => 'class',
361 optional => 1,
362 },
363 profile => {
364 description => "Override the erasure code (EC) profile to use. Will create an"
365 ." erasure coded pool plus a replicated pool for metadata.",
366 type => 'string',
367 format_description => 'profile',
368 optional => 1,
369 },
370};
371
372sub ec_parse_and_check {
373 my ($property, $rados) = @_;
374 return if !$property;
375
376 my $ec = parse_property_string($ec_format, $property);
377
378 die "Erasure code profile '$ec->{profile}' does not exist.\n"
379 if $ec->{profile} && !PVE::Ceph::Tools::ecprofile_exists($ec->{profile}, $rados);
380
381 return $ec;
382}
383
56d02a86
AA
384
385__PACKAGE__->register_method ({
386 name => 'createpool',
387 path => '',
388 method => 'POST',
f35e7fcd 389 description => "Create Ceph pool",
56d02a86
AA
390 proxyto => 'node',
391 protected => 1,
392 permissions => {
393 check => ['perm', '/', [ 'Sys.Modify' ]],
394 },
395 parameters => {
396 additionalProperties => 0,
397 properties => {
398 node => get_standard_option('pve-node'),
399 add_storages => {
4605d6fd 400 description => "Configure VM and CT storage using the new pool.",
56d02a86
AA
401 type => 'boolean',
402 optional => 1,
4605d6fd 403 default => "0; for erasure coded pools: 1",
56d02a86 404 },
f35e7fcd 405 'erasure-coding' => {
ec63b237
TL
406 description => "Create an erasure coded pool for RBD with an"
407 ." accompaning replicated pool for metadata storage.",
3bd128d7 408 type => 'string',
f35e7fcd 409 format => $ec_format,
3bd128d7
AL
410 optional => 1,
411 },
56d02a86
AA
412 %{ $ceph_pool_common_options->() },
413 },
414 },
415 returns => { type => 'string' },
416 code => sub {
417 my ($param) = @_;
418
419 PVE::Cluster::check_cfs_quorum();
420 PVE::Ceph::Tools::check_ceph_configured();
421
3bd128d7 422 my $pool = my $name = extract_param($param, 'name');
56d02a86
AA
423 my $node = extract_param($param, 'node');
424 my $add_storages = extract_param($param, 'add_storages');
425
426 my $rpcenv = PVE::RPCEnvironment::get();
427 my $user = $rpcenv->get_user();
5a3d7942
AA
428 # Ceph uses target_size_bytes
429 if (defined($param->{'target_size'})) {
430 my $target_sizestr = extract_param($param, 'target_size');
431 $param->{target_size_bytes} = PVE::JSONSchema::parse_size($target_sizestr);
432 }
433
07316e6d
TL
434 my $rados = PVE::RADOS->new();
435 my $ec = ec_parse_and_check(extract_param($param, 'erasure-coding'), $rados);
436 $add_storages = 1 if $ec && !defined($add_storages);
437
56d02a86
AA
438 if ($add_storages) {
439 $rpcenv->check($user, '/storage', ['Datastore.Allocate']);
440 die "pool name contains characters which are illegal for storage naming\n"
441 if !PVE::JSONSchema::parse_storage_id($pool);
442 }
443
444 # pool defaults
445 $param->{pg_num} //= 128;
446 $param->{size} //= 3;
447 $param->{min_size} //= 2;
448 $param->{application} //= 'rbd';
449 $param->{pg_autoscale_mode} //= 'warn';
450
f35e7fcd
TL
451 my $worker = sub {
452 # reopen with longer timeout
453 $rados = PVE::RADOS->new(timeout => PVE::Ceph::Tools::get_config('long_rados_timeout'));
454
455 if ($ec) {
456 if (!$ec->{profile}) {
457 $ec->{profile} = PVE::Ceph::Tools::get_ecprofile_name($pool, $rados);
458 eval {
459 PVE::Ceph::Tools::create_ecprofile(
460 $ec->@{'profile', 'k', 'm', 'failure-domain', 'device-class'},
461 $rados,
462 );
463 };
464 die "could not create erasure code profile '$ec->{profile}': $@\n" if $@;
465 print "created new erasure code profile '$ec->{profile}'\n";
466 }
3bd128d7 467
f35e7fcd
TL
468 my $ec_data_param = {};
469 # copy all params, should be a flat hash
470 $ec_data_param = { map { $_ => $param->{$_} } keys %$param };
3bd128d7 471
f35e7fcd
TL
472 $ec_data_param->{pool_type} = 'erasure';
473 $ec_data_param->{allow_ec_overwrites} = 'true';
474 $ec_data_param->{erasure_code_profile} = $ec->{profile};
475 delete $ec_data_param->{size};
476 delete $ec_data_param->{min_size};
3bd128d7 477
f35e7fcd
TL
478 # metadata pool should be ok with 32 PGs
479 $param->{pg_num} = 32;
480
481 $pool = "${name}-metadata";
482 $ec->{data_pool} = "${name}-data";
483
484 PVE::Ceph::Tools::create_pool($ec->{data_pool}, $ec_data_param, $rados);
485 }
56d02a86 486
f35e7fcd 487 PVE::Ceph::Tools::create_pool($pool, $param, $rados);
3bd128d7 488
56d02a86 489 if ($add_storages) {
f35e7fcd 490 eval { $add_storage->($pool, "${name}", $ec->{data_pool}) };
3bd128d7 491 die "adding PVE storage for ceph pool '$name' failed: $@\n" if $@;
56d02a86
AA
492 }
493 };
494
495 return $rpcenv->fork_worker('cephcreatepool', $pool, $user, $worker);
496 }});
497
498
499__PACKAGE__->register_method ({
500 name => 'destroypool',
501 path => '{name}',
502 method => 'DELETE',
503 description => "Destroy pool",
504 proxyto => 'node',
505 protected => 1,
506 permissions => {
507 check => ['perm', '/', [ 'Sys.Modify' ]],
508 },
509 parameters => {
510 additionalProperties => 0,
511 properties => {
512 node => get_standard_option('pve-node'),
513 name => {
514 description => "The name of the pool. It must be unique.",
515 type => 'string',
516 },
517 force => {
518 description => "If true, destroys pool even if in use",
519 type => 'boolean',
520 optional => 1,
521 default => 0,
522 },
523 remove_storages => {
524 description => "Remove all pveceph-managed storages configured for this pool",
525 type => 'boolean',
526 optional => 1,
527 default => 0,
528 },
3bd128d7 529 remove_ecprofile => {
f35e7fcd 530 description => "Remove the erasure code profile. Defaults to true, if applicable.",
3bd128d7
AL
531 type => 'boolean',
532 optional => 1,
533 default => 1,
534 },
56d02a86
AA
535 },
536 },
537 returns => { type => 'string' },
538 code => sub {
539 my ($param) = @_;
540
541 PVE::Ceph::Tools::check_ceph_inited();
542
543 my $rpcenv = PVE::RPCEnvironment::get();
544 my $user = $rpcenv->get_user();
545 $rpcenv->check($user, '/storage', ['Datastore.Allocate'])
546 if $param->{remove_storages};
547
548 my $pool = $param->{name};
549
550 my $worker = sub {
551 my $storages = $get_storages->($pool);
552
553 # if not forced, destroy ceph pool only when no
554 # vm disks are on it anymore
555 if (!$param->{force}) {
556 my $storagecfg = PVE::Storage::config();
557 foreach my $storeid (keys %$storages) {
558 my $storage = $storages->{$storeid};
559
560 # check if any vm disks are on the pool
561 print "checking storage '$storeid' for RBD images..\n";
562 my $res = PVE::Storage::vdisk_list($storagecfg, $storeid);
563 die "ceph pool '$pool' still in use by storage '$storeid'\n"
564 if @{$res->{$storeid}} != 0;
565 }
566 }
f35e7fcd 567 my $rados = PVE::RADOS->new();
56d02a86 568
f35e7fcd 569 my $pool_properties = PVE::Ceph::Tools::get_pool_properties($pool, $rados);
3bd128d7 570
f35e7fcd 571 PVE::Ceph::Tools::destroy_pool($pool, $rados);
56d02a86 572
3bd128d7 573 if (my $ecprofile = $pool_properties->{erasure_code_profile}) {
f35e7fcd 574 print "found erasure coded profile '$ecprofile', destroying its CRUSH rule\n";
3bd128d7 575 my $crush_rule = $pool_properties->{crush_rule};
f35e7fcd 576 eval { PVE::Ceph::Tools::destroy_crush_rule($crush_rule, $rados); };
3bd128d7
AL
577 warn "removing crush rule '${crush_rule}' failed: $@\n" if $@;
578
f35e7fcd
TL
579 if ($param->{remove_ecprofile} // 1) {
580 print "destroying erasure coded profile '$ecprofile'\n";
581 eval { PVE::Ceph::Tools::destroy_ecprofile($ecprofile, $rados) };
3bd128d7
AL
582 warn "removing EC profile '${ecprofile}' failed: $@\n" if $@;
583 }
584 }
585
56d02a86
AA
586 if ($param->{remove_storages}) {
587 my $err;
588 foreach my $storeid (keys %$storages) {
589 # skip external clusters, not managed by pveceph
590 next if $storages->{$storeid}->{monhost};
591 eval { PVE::API2::Storage::Config->delete({storage => $storeid}) };
592 if ($@) {
593 warn "failed to remove storage '$storeid': $@\n";
594 $err = 1;
595 }
596 }
597 die "failed to remove (some) storages - check log and remove manually!\n"
598 if $err;
599 }
600 };
601 return $rpcenv->fork_worker('cephdestroypool', $pool, $user, $worker);
602 }});
603
604
605__PACKAGE__->register_method ({
606 name => 'setpool',
607 path => '{name}',
608 method => 'PUT',
609 description => "Change POOL settings",
610 proxyto => 'node',
611 protected => 1,
612 permissions => {
613 check => ['perm', '/', [ 'Sys.Modify' ]],
614 },
615 parameters => {
616 additionalProperties => 0,
617 properties => {
618 node => get_standard_option('pve-node'),
619 %{ $ceph_pool_common_options->('nodefault') },
620 },
621 },
622 returns => { type => 'string' },
623 code => sub {
624 my ($param) = @_;
625
626 PVE::Ceph::Tools::check_ceph_configured();
627
628 my $rpcenv = PVE::RPCEnvironment::get();
629 my $authuser = $rpcenv->get_user();
630
51d6db58
AA
631 my $pool = extract_param($param, 'name');
632 my $node = extract_param($param, 'node');
56d02a86 633
5a3d7942
AA
634 # Ceph uses target_size_bytes
635 if (defined($param->{'target_size'})) {
636 my $target_sizestr = extract_param($param, 'target_size');
637 $param->{target_size_bytes} = PVE::JSONSchema::parse_size($target_sizestr);
638 }
639
56d02a86 640 my $worker = sub {
51d6db58 641 PVE::Ceph::Tools::set_pool($pool, $param);
56d02a86
AA
642 };
643
644 return $rpcenv->fork_worker('cephsetpool', $pool, $authuser, $worker);
645 }});
646
647
54ba7dd9
AA
648__PACKAGE__->register_method ({
649 name => 'getpool',
650 path => '{name}',
651 method => 'GET',
652 description => "List pool settings.",
653 proxyto => 'node',
654 protected => 1,
655 permissions => {
656 check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1],
657 },
658 parameters => {
659 additionalProperties => 0,
660 properties => {
661 node => get_standard_option('pve-node'),
662 name => {
663 description => "The name of the pool. It must be unique.",
664 type => 'string',
665 },
666 verbose => {
667 type => 'boolean',
668 default => 0,
669 optional => 1,
670 description => "If enabled, will display additional data".
671 "(eg. statistics).",
672 },
673 },
674 },
675 returns => {
676 type => "object",
677 properties => {
678 id => { type => 'integer', title => 'ID' },
679 pgp_num => { type => 'integer', title => 'PGP num' },
680 noscrub => { type => 'boolean', title => 'noscrub' },
681 'nodeep-scrub' => { type => 'boolean', title => 'nodeep-scrub' },
682 nodelete => { type => 'boolean', title => 'nodelete' },
683 nopgchange => { type => 'boolean', title => 'nopgchange' },
684 nosizechange => { type => 'boolean', title => 'nosizechange' },
685 write_fadvise_dontneed => { type => 'boolean', title => 'write_fadvise_dontneed' },
686 hashpspool => { type => 'boolean', title => 'hashpspool' },
687 use_gmt_hitset => { type => 'boolean', title => 'use_gmt_hitset' },
688 fast_read => { type => 'boolean', title => 'Fast Read' },
689 application_list => { type => 'array', title => 'Application', optional => 1 },
690 statistics => { type => 'object', title => 'Statistics', optional => 1 },
5a3d7942 691 autoscale_status => { type => 'object', title => 'Autoscale Status', optional => 1 },
54ba7dd9
AA
692 %{ $ceph_pool_common_options->() },
693 },
694 },
695 code => sub {
696 my ($param) = @_;
697
698 PVE::Ceph::Tools::check_ceph_inited();
699
700 my $verbose = $param->{verbose};
701 my $pool = $param->{name};
702
703 my $rados = PVE::RADOS->new();
704 my $res = $rados->mon_command({
705 prefix => 'osd pool get',
706 pool => "$pool",
707 var => 'all',
708 });
709
710 my $data = {
711 id => $res->{pool_id},
712 name => $pool,
713 size => $res->{size},
714 min_size => $res->{min_size},
715 pg_num => $res->{pg_num},
5a3d7942 716 pg_num_min => $res->{pg_num_min},
54ba7dd9
AA
717 pgp_num => $res->{pgp_num},
718 crush_rule => $res->{crush_rule},
719 pg_autoscale_mode => $res->{pg_autoscale_mode},
720 noscrub => "$res->{noscrub}",
721 'nodeep-scrub' => "$res->{'nodeep-scrub'}",
722 nodelete => "$res->{nodelete}",
723 nopgchange => "$res->{nopgchange}",
724 nosizechange => "$res->{nosizechange}",
725 write_fadvise_dontneed => "$res->{write_fadvise_dontneed}",
726 hashpspool => "$res->{hashpspool}",
727 use_gmt_hitset => "$res->{use_gmt_hitset}",
728 fast_read => "$res->{fast_read}",
5a3d7942
AA
729 target_size => $res->{target_size_bytes},
730 target_size_ratio => $res->{target_size_ratio},
54ba7dd9
AA
731 };
732
733 if ($verbose) {
734 my $stats;
735 my $res = $rados->mon_command({ prefix => 'df' });
736
5a3d7942
AA
737 # pg_autoscaler module is not enabled in Nautilus
738 # avoid partial read further down, use new rados instance
739 my $autoscale_status = eval { $get_autoscale_status->() };
740 $data->{autoscale_status} = $autoscale_status->{$pool};
741
54ba7dd9
AA
742 foreach my $d (@{$res->{pools}}) {
743 next if !$d->{stats};
744 next if !defined($d->{name}) && !$d->{name} ne "$pool";
745 $data->{statistics} = $d->{stats};
746 }
747
748 my $apps = $rados->mon_command({ prefix => "osd pool application get", pool => "$pool", });
749 $data->{application_list} = [ keys %$apps ];
750 }
751
752 return $data;
753 }});
754
755
56d02a86 7561;