use PVE::Tools qw(run_command);
use PVE::JSONSchema qw(get_standard_option);
use PVE::Ceph::Tools;
+use PVE::Ceph::Services;
use PVE::API2::Ceph;
use PVE::API2::Ceph::FS;
use PVE::API2::Ceph::MDS;
parameters => {
additionalProperties => 0,
properties => {
+ logs => {
+ description => 'Additionally purge Ceph logs, /var/log/ceph.',
+ type => 'boolean',
+ optional => 1,
+ },
+ crash => {
+ description => 'Additionally purge Ceph crash logs, /var/lib/ceph/crash.',
+ type => 'boolean',
+ optional => 1,
+ },
},
},
returns => { type => 'null' },
code => sub {
my ($param) = @_;
- my $monstat;
+ my $message;
+ my $pools = [];
+ my $monstat = {};
+ my $mdsstat = {};
+ my $osdstat = [];
eval {
my $rados = PVE::RADOS->new();
- my $monstat = $rados->mon_command({ prefix => 'mon_status' });
+ $pools = PVE::Ceph::Tools::ls_pools(undef, $rados);
+ $monstat = PVE::Ceph::Services::get_services_info('mon', undef, $rados);
+ $mdsstat = PVE::Ceph::Services::get_services_info('mds', undef, $rados);
+ $osdstat = $rados->mon_command({ prefix => 'osd metadata' });
};
- my $err = $@;
+ warn "Error gathering ceph info, already purged? Message: $@" if $@;
+
+ my $osd = grep { $_->{hostname} eq $nodename } @$osdstat;
+ my $mds = grep { $mdsstat->{$_}->{host} eq $nodename } keys %$mdsstat;
+ my $mon = grep { $monstat->{$_}->{host} eq $nodename } keys %$monstat;
+
+ # no pools = no data
+ $message .= "- remove pools, this will !!DESTROY DATA!!\n" if @$pools;
+ $message .= "- remove active OSD on $nodename\n" if $osd;
+ $message .= "- remove active MDS on $nodename\n" if $mds;
+ $message .= "- remove other MONs, $nodename is not the last MON\n"
+ if scalar(keys %$monstat) > 1 && $mon;
+
+ # display all steps at once
+ die "Unable to purge Ceph!\n\nTo continue:\n$message" if $message;
- die "detected running ceph services- unable to purge data\n"
- if !$err;
+ my $services = PVE::Ceph::Services::get_local_services();
+ $services->{mon} = $monstat if $mon;
+ $services->{crash}->{$nodename} = { direxists => 1 } if $param->{crash};
+ $services->{logs}->{$nodename} = { direxists => 1 } if $param->{logs};
- # fixme: this is dangerous - should we really support this function?
- PVE::Ceph::Tools::purge_all_ceph_files();
+ PVE::Ceph::Tools::purge_all_ceph_services($services);
+ PVE::Ceph::Tools::purge_all_ceph_files($services);
return undef;
}});
properties => {
version => {
type => 'string',
- #enum => ['hammer', 'jewel'], # for jessie
- enum => ['luminous',], # for stretch
+ # for buster, luminous kept for testing/upgrade purposes only! - FIXME: remove with 6.2?
+ enum => ['luminous', 'nautilus', 'octopus'],
+ default => 'nautilus',
+ description => "Ceph version to install.",
optional => 1,
- }
+ },
+ 'allow-experimental' => {
+ type => 'boolean',
+ default => 0,
+ optional => 1,
+ description => "Allow experimental versions. Use with care!",
+ },
},
},
returns => { type => 'null' },
code => sub {
my ($param) = @_;
- my $cephver = $param->{version} || 'luminous';
-
- if ($cephver eq 'luminous') {
- PVE::Tools::file_set_contents("/etc/apt/sources.list.d/ceph.list",
- "deb http://download.proxmox.com/debian/ceph-luminous stretch main\n");
+ my $default_vers = 'nautilus';
+ my $cephver = $param->{version} || $default_vers;
+
+ my $repolist;
+ if ($cephver eq 'nautilus') {
+ $repolist = "deb http://download.proxmox.com/debian/ceph-nautilus buster main\n";
+ } elsif ($cephver eq 'luminous') {
+ die "Not allowed to select version '$cephver'\n" if !$param->{'allow-experimental'};
+ $repolist = "deb http://download.proxmox.com/debian/ceph-luminous buster main\n";
+ } elsif ($cephver eq 'octopus') {
+ $repolist = "deb http://download.proxmox.com/debian/ceph-octopus buster main\n";
} else {
die "not implemented ceph version: $cephver";
}
+ PVE::Tools::file_set_contents("/etc/apt/sources.list.d/ceph.list", $repolist);
+
+ warn "WARNING: installing non-default ceph release '$cephver'!\n\n" if $cephver ne $default_vers;
local $ENV{DEBIAN_FRONTEND} = 'noninteractive';
print "update available package list\n";
print "\ninstalled ceph $cephver successfully\n";
- if (! -e '/etc/systemd/system/ceph.service') {
- print "\nreplacing ceph init script with own ceph.service\n";
- eval {
- run_command('cp -v /usr/share/doc/pve-manager/examples/ceph.service /etc/systemd/system/ceph.service');
- run_command('systemctl daemon-reload');
- run_command('systemctl enable ceph.service');
- };
- if (my $err = $@) {
- warn "WARNING: could not install ceph.service: $@\n";
- } else {
- print "installed ceph.service successfully\n";
- }
- }
+ return undef;
+ }});
+__PACKAGE__->register_method ({
+ name => 'status',
+ path => 'status',
+ method => 'GET',
+ description => "Get Ceph Status.",
+ parameters => {
+ additionalProperties => 0,
+ },
+ returns => { type => 'null' },
+ code => sub {
+ PVE::Ceph::Tools::check_ceph_inited();
+
+ run_command(
+ ['ceph', '-s'],
+ outfunc => sub { print "$_[0]\n" },
+ errfunc => sub { print STDERR "$_[0]\n" }
+ );
return undef;
}});
init => [ 'PVE::API2::Ceph', 'init', [], { node => $nodename } ],
pool => {
ls => [ 'PVE::API2::Ceph', 'lspools', [], { node => $nodename }, sub {
- my $res = shift;
-
- printf("%-20s %10s %10s %10s %10s %20s\n", "Name", "size", "min_size",
- "pg_num", "%-used", "used");
- foreach my $p (sort {$a->{pool_name} cmp $b->{pool_name}} @$res) {
- printf("%-20s %10d %10d %10d %10.2f %20d\n", $p->{pool_name},
- $p->{size}, $p->{min_size}, $p->{pg_num},
- $p->{percent_used}, $p->{bytes_used});
- }
- }],
+ my ($data, $schema, $options) = @_;
+ PVE::CLIFormatter::print_api_result($data, $schema,
+ [
+ 'pool_name',
+ 'size',
+ 'min_size',
+ 'pg_num',
+ 'pg_autoscale_mode',
+ 'crush_rule_name',
+ 'percent_used',
+ 'bytes_used',
+ ],
+ $options);
+ }, $PVE::RESTHandler::standard_output_options],
create => [ 'PVE::API2::Ceph', 'createpool', ['name'], { node => $nodename }],
destroy => [ 'PVE::API2::Ceph', 'destroypool', ['name'], { node => $nodename } ],
+ set => [ 'PVE::API2::Ceph', 'setpool', ['name'], { node => $nodename } ],
},
lspools => { alias => 'pool ls' },
createpool => { alias => 'pool create' },
create => [ 'PVE::API2::Ceph::MDS', 'createmds', [], { node => $nodename }, $upid_exit],
destroy => [ 'PVE::API2::Ceph::MDS', 'destroymds', ['name'], { node => $nodename }, $upid_exit],
},
- start => [ 'PVE::API2::Ceph', 'start', ['service'], { node => $nodename }, $upid_exit],
- stop => [ 'PVE::API2::Ceph', 'stop', ['service'], { node => $nodename }, $upid_exit],
+ start => [ 'PVE::API2::Ceph', 'start', [], { node => $nodename }, $upid_exit],
+ stop => [ 'PVE::API2::Ceph', 'stop', [], { node => $nodename }, $upid_exit],
install => [ __PACKAGE__, 'install', [] ],
purge => [ __PACKAGE__, 'purge', [] ],
- status => [ 'PVE::API2::Ceph', 'status', [], { node => $nodename }, sub {
- my $res = shift;
- my $json = JSON->new->allow_nonref;
- print $json->pretty->encode($res) . "\n";
- }],
+ status => [ __PACKAGE__, 'status', []],
};
1;