]> git.proxmox.com Git - pve-manager.git/blobdiff - PVE/CLI/pveceph.pm
pveceph: change status from long JSON to ceph -s
[pve-manager.git] / PVE / CLI / pveceph.pm
index 56b6ba667b463bba8ee4726c6adce5f84757d6cc..de046dd045b3f2fe42743690b88f63e1eae46ddc 100755 (executable)
@@ -18,6 +18,7 @@ use PVE::Storage;
 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;
@@ -49,25 +50,58 @@ __PACKAGE__->register_method ({
     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;
     }});
@@ -82,24 +116,41 @@ __PACKAGE__->register_method ({
        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";
@@ -121,20 +172,26 @@ __PACKAGE__->register_method ({
 
        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;
     }});
 
@@ -142,18 +199,23 @@ our $cmddef = {
     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' },
@@ -183,15 +245,11 @@ our $cmddef = {
        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;