]>
git.proxmox.com Git - pve-manager.git/blob - PVE/API2/Ceph/Pools.pm
fac21301e69647052f7020c3f7e39483d757854c
1 package PVE
::API2
::Ceph
::Pools
;
7 use PVE
::Ceph
::Services
;
8 use PVE
::JSONSchema
qw(get_standard_option);
11 use PVE
::RPCEnvironment
;
13 use PVE
::Tools
qw(extract_param);
15 use PVE
::API2
::Storage
::Config
;
17 use base
qw(PVE::RESTHandler);
19 __PACKAGE__-
>register_method ({
23 description
=> "List all pools.",
27 check
=> ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any
=> 1],
30 additionalProperties
=> 0,
32 node
=> get_standard_option
('pve-node'),
40 pool
=> { type
=> 'integer', title
=> 'ID' },
41 pool_name
=> { type
=> 'string', title
=> 'Name' },
42 size
=> { type
=> 'integer', title
=> 'Size' },
43 min_size
=> { type
=> 'integer', title
=> 'Min Size' },
44 pg_num
=> { type
=> 'integer', title
=> 'PG Num' },
45 pg_autoscale_mode
=> { type
=> 'string', optional
=> 1, title
=> 'PG Autoscale Mode' },
46 crush_rule
=> { type
=> 'integer', title
=> 'Crush Rule' },
47 crush_rule_name
=> { type
=> 'string', title
=> 'Crush Rule Name' },
48 percent_used
=> { type
=> 'number', title
=> '%-Used' },
49 bytes_used
=> { type
=> 'integer', title
=> 'Used' },
52 links
=> [ { rel
=> 'child', href
=> "{pool_name}" } ],
57 PVE
::Ceph
::Tools
::check_ceph_inited
();
59 my $rados = PVE
::RADOS-
>new();
62 my $res = $rados->mon_command({ prefix
=> 'df' });
64 foreach my $d (@{$res->{pools
}}) {
66 next if !defined($d->{id
});
67 $stats->{$d->{id
}} = $d->{stats
};
70 $res = $rados->mon_command({ prefix
=> 'osd dump' });
71 my $rulestmp = $rados->mon_command({ prefix
=> 'osd crush rule dump'});
74 for my $rule (@$rulestmp) {
75 $rules->{$rule->{rule_id
}} = $rule->{rule_name
};
89 foreach my $e (@{$res->{pools
}}) {
91 foreach my $attr (@$attr_list) {
92 $d->{$attr} = $e->{$attr} if defined($e->{$attr});
95 if (defined($d->{crush_rule
}) && defined($rules->{$d->{crush_rule
}})) {
96 $d->{crush_rule_name
} = $rules->{$d->{crush_rule
}};
99 if (my $s = $stats->{$d->{pool
}}) {
100 $d->{bytes_used
} = $s->{bytes_used
};
101 $d->{percent_used
} = $s->{percent_used
};
111 my $ceph_pool_common_options = sub {
112 my ($nodefault) = shift;
115 description
=> "The name of the pool. It must be unique.",
119 description
=> 'Number of replicas per object',
127 description
=> 'Minimum number of replicas per object',
135 description
=> "Number of placement groups.",
143 description
=> "The rule to use for mapping object placement in the cluster.",
148 description
=> "The application of the pool.",
151 enum
=> ['rbd', 'cephfs', 'rgw'],
154 pg_autoscale_mode
=> {
155 description
=> "The automatic PG scaling mode of the pool.",
157 enum
=> ['on', 'off', 'warn'],
164 delete $options->{$_}->{default} for keys %$options;
170 my $add_storage = sub {
171 my ($pool, $storeid) = @_;
173 my $storage_params = {
178 content
=> 'rootdir,images',
181 PVE
::API2
::Storage
::Config-
>create($storage_params);
184 my $get_storages = sub {
187 my $cfg = PVE
::Storage
::config
();
189 my $storages = $cfg->{ids
};
191 foreach my $storeid (keys %$storages) {
192 my $curr = $storages->{$storeid};
193 $res->{$storeid} = $storages->{$storeid}
194 if $curr->{type
} eq 'rbd' && $pool eq $curr->{pool
};
201 __PACKAGE__-
>register_method ({
202 name
=> 'createpool',
205 description
=> "Create POOL",
209 check
=> ['perm', '/', [ 'Sys.Modify' ]],
212 additionalProperties
=> 0,
214 node
=> get_standard_option
('pve-node'),
216 description
=> "Configure VM and CT storage using the new pool.",
220 %{ $ceph_pool_common_options->() },
223 returns
=> { type
=> 'string' },
227 PVE
::Cluster
::check_cfs_quorum
();
228 PVE
::Ceph
::Tools
::check_ceph_configured
();
230 my $pool = extract_param
($param, 'name');
231 my $node = extract_param
($param, 'node');
232 my $add_storages = extract_param
($param, 'add_storages');
234 my $rpcenv = PVE
::RPCEnvironment
::get
();
235 my $user = $rpcenv->get_user();
238 $rpcenv->check($user, '/storage', ['Datastore.Allocate']);
239 die "pool name contains characters which are illegal for storage naming\n"
240 if !PVE
::JSONSchema
::parse_storage_id
($pool);
244 $param->{pg_num
} //= 128;
245 $param->{size
} //= 3;
246 $param->{min_size
} //= 2;
247 $param->{application
} //= 'rbd';
248 $param->{pg_autoscale_mode
} //= 'warn';
252 PVE
::Ceph
::Tools
::create_pool
($pool, $param);
256 eval { $add_storage->($pool, "${pool}"); };
258 warn "failed to add storage: $@";
261 die "adding storage for pool '$pool' failed, check log and add manually!\n"
266 return $rpcenv->fork_worker('cephcreatepool', $pool, $user, $worker);
270 __PACKAGE__-
>register_method ({
271 name
=> 'destroypool',
274 description
=> "Destroy pool",
278 check
=> ['perm', '/', [ 'Sys.Modify' ]],
281 additionalProperties
=> 0,
283 node
=> get_standard_option
('pve-node'),
285 description
=> "The name of the pool. It must be unique.",
289 description
=> "If true, destroys pool even if in use",
295 description
=> "Remove all pveceph-managed storages configured for this pool",
302 returns
=> { type
=> 'string' },
306 PVE
::Ceph
::Tools
::check_ceph_inited
();
308 my $rpcenv = PVE
::RPCEnvironment
::get
();
309 my $user = $rpcenv->get_user();
310 $rpcenv->check($user, '/storage', ['Datastore.Allocate'])
311 if $param->{remove_storages
};
313 my $pool = $param->{name
};
316 my $storages = $get_storages->($pool);
318 # if not forced, destroy ceph pool only when no
319 # vm disks are on it anymore
320 if (!$param->{force
}) {
321 my $storagecfg = PVE
::Storage
::config
();
322 foreach my $storeid (keys %$storages) {
323 my $storage = $storages->{$storeid};
325 # check if any vm disks are on the pool
326 print "checking storage '$storeid' for RBD images..\n";
327 my $res = PVE
::Storage
::vdisk_list
($storagecfg, $storeid);
328 die "ceph pool '$pool' still in use by storage '$storeid'\n"
329 if @{$res->{$storeid}} != 0;
333 PVE
::Ceph
::Tools
::destroy_pool
($pool);
335 if ($param->{remove_storages
}) {
337 foreach my $storeid (keys %$storages) {
338 # skip external clusters, not managed by pveceph
339 next if $storages->{$storeid}->{monhost
};
340 eval { PVE
::API2
::Storage
::Config-
>delete({storage
=> $storeid}) };
342 warn "failed to remove storage '$storeid': $@\n";
346 die "failed to remove (some) storages - check log and remove manually!\n"
350 return $rpcenv->fork_worker('cephdestroypool', $pool, $user, $worker);
354 __PACKAGE__-
>register_method ({
358 description
=> "Change POOL settings",
362 check
=> ['perm', '/', [ 'Sys.Modify' ]],
365 additionalProperties
=> 0,
367 node
=> get_standard_option
('pve-node'),
368 %{ $ceph_pool_common_options->('nodefault') },
371 returns
=> { type
=> 'string' },
375 PVE
::Ceph
::Tools
::check_ceph_configured
();
377 my $rpcenv = PVE
::RPCEnvironment
::get
();
378 my $authuser = $rpcenv->get_user();
380 my $pool = $param->{name
};
381 my $ceph_param = \
%$param;
382 for my $item ('name', 'node') {
383 # not ceph parameters
384 delete $ceph_param->{$item};
388 PVE
::Ceph
::Tools
::set_pool
($pool, $ceph_param);
391 return $rpcenv->fork_worker('cephsetpool', $pool, $authuser, $worker);