]> git.proxmox.com Git - pve-manager.git/blob - PVE/CLI/pveceph.pm
pveceph install: output warnings from apt update, they're relevant
[pve-manager.git] / PVE / CLI / pveceph.pm
1 package PVE::CLI::pveceph;
2
3 use strict;
4 use warnings;
5
6 use Fcntl ':flock';
7 use File::Path;
8 use IO::File;
9 use JSON;
10 use Data::Dumper;
11 use LWP::UserAgent;
12
13 use PVE::SafeSyslog;
14 use PVE::Cluster;
15 use PVE::INotify;
16 use PVE::RPCEnvironment;
17 use PVE::Storage;
18 use PVE::Tools qw(run_command);
19 use PVE::JSONSchema qw(get_standard_option);
20 use PVE::Ceph::Tools;
21 use PVE::API2::Ceph;
22 use PVE::API2::Ceph::FS;
23 use PVE::API2::Ceph::MDS;
24 use PVE::API2::Ceph::MGR;
25 use PVE::API2::Ceph::MON;
26 use PVE::API2::Ceph::OSD;
27
28 use PVE::CLIHandler;
29
30 use base qw(PVE::CLIHandler);
31
32 my $nodename = PVE::INotify::nodename();
33
34 my $upid_exit = sub {
35 my $upid = shift;
36 my $status = PVE::Tools::upid_read_status($upid);
37 exit($status eq 'OK' ? 0 : -1);
38 };
39
40 sub setup_environment {
41 PVE::RPCEnvironment->setup_default_cli_env();
42 }
43
44 __PACKAGE__->register_method ({
45 name => 'purge',
46 path => 'purge',
47 method => 'POST',
48 description => "Destroy ceph related data and configuration files.",
49 parameters => {
50 additionalProperties => 0,
51 properties => {
52 },
53 },
54 returns => { type => 'null' },
55 code => sub {
56 my ($param) = @_;
57
58 my $monstat;
59
60 eval {
61 my $rados = PVE::RADOS->new();
62 my $monstat = $rados->mon_command({ prefix => 'mon_status' });
63 };
64 my $err = $@;
65
66 die "detected running ceph services- unable to purge data\n"
67 if !$err;
68
69 # fixme: this is dangerous - should we really support this function?
70 PVE::Ceph::Tools::purge_all_ceph_files();
71
72 return undef;
73 }});
74
75 __PACKAGE__->register_method ({
76 name => 'install',
77 path => 'install',
78 method => 'POST',
79 description => "Install ceph related packages.",
80 parameters => {
81 additionalProperties => 0,
82 properties => {
83 version => {
84 type => 'string',
85 #enum => ['hammer', 'jewel'], # for jessie
86 enum => ['luminous',], # for stretch
87 optional => 1,
88 }
89 },
90 },
91 returns => { type => 'null' },
92 code => sub {
93 my ($param) = @_;
94
95 my $cephver = $param->{version} || 'luminous';
96
97 if ($cephver eq 'luminous') {
98 PVE::Tools::file_set_contents("/etc/apt/sources.list.d/ceph.list",
99 "deb http://download.proxmox.com/debian/ceph-luminous stretch main\n");
100 } else {
101 die "not implemented ceph version: $cephver";
102 }
103
104 local $ENV{DEBIAN_FRONTEND} = 'noninteractive';
105 print "update available package list\n";
106 eval { run_command(['apt-get', '-q', 'update'], outfunc => sub {}, errfunc => sub { print STDERR "$_[0]\n" }) };
107
108 my @apt_install = qw(apt-get --no-install-recommends -o Dpkg::Options::=--force-confnew install --);
109 my @ceph_packages = qw(
110 ceph
111 ceph-common
112 ceph-mds
113 ceph-fuse
114 gdisk
115 );
116
117 print "start installation\n";
118 if (system(@apt_install, @ceph_packages) != 0) {
119 die "apt failed during ceph installation ($?)\n";
120 }
121
122 print "\ninstalled ceph $cephver successfully\n";
123
124 if (! -e '/etc/systemd/system/ceph.service') {
125 print "\nreplacing ceph init script with own ceph.service\n";
126 eval {
127 run_command('cp -v /usr/share/doc/pve-manager/examples/ceph.service /etc/systemd/system/ceph.service');
128 run_command('systemctl daemon-reload');
129 run_command('systemctl enable ceph.service');
130 };
131 if (my $err = $@) {
132 warn "WARNING: could not install ceph.service: $@\n";
133 } else {
134 print "installed ceph.service successfully\n";
135 }
136 }
137
138 return undef;
139 }});
140
141 our $cmddef = {
142 init => [ 'PVE::API2::Ceph', 'init', [], { node => $nodename } ],
143 pool => {
144 ls => [ 'PVE::API2::Ceph', 'lspools', [], { node => $nodename }, sub {
145 my $res = shift;
146
147 printf("%-20s %10s %10s %10s %10s %20s\n", "Name", "size", "min_size",
148 "pg_num", "%-used", "used");
149 foreach my $p (sort {$a->{pool_name} cmp $b->{pool_name}} @$res) {
150 printf("%-20s %10d %10d %10d %10.2f %20d\n", $p->{pool_name},
151 $p->{size}, $p->{min_size}, $p->{pg_num},
152 $p->{percent_used}, $p->{bytes_used});
153 }
154 }],
155 create => [ 'PVE::API2::Ceph', 'createpool', ['name'], { node => $nodename }],
156 destroy => [ 'PVE::API2::Ceph', 'destroypool', ['name'], { node => $nodename } ],
157 },
158 lspools => { alias => 'pool ls' },
159 createpool => { alias => 'pool create' },
160 destroypool => { alias => 'pool destroy' },
161 fs => {
162 create => [ 'PVE::API2::Ceph::FS', 'createfs', [], { node => $nodename }],
163 },
164 osd => {
165 create => [ 'PVE::API2::Ceph::OSD', 'createosd', ['dev'], { node => $nodename }, $upid_exit],
166 destroy => [ 'PVE::API2::Ceph::OSD', 'destroyosd', ['osdid'], { node => $nodename }, $upid_exit],
167 },
168 createosd => { alias => 'osd create' },
169 destroyosd => { alias => 'osd destroy' },
170 mon => {
171 create => [ 'PVE::API2::Ceph::MON', 'createmon', [], { node => $nodename }, $upid_exit],
172 destroy => [ 'PVE::API2::Ceph::MON', 'destroymon', ['monid'], { node => $nodename }, $upid_exit],
173 },
174 createmon => { alias => 'mon create' },
175 destroymon => { alias => 'mon destroy' },
176 mgr => {
177 create => [ 'PVE::API2::Ceph::MGR', 'createmgr', [], { node => $nodename }, $upid_exit],
178 destroy => [ 'PVE::API2::Ceph::MGR', 'destroymgr', ['id'], { node => $nodename }, $upid_exit],
179 },
180 createmgr => { alias => 'mgr create' },
181 destroymgr => { alias => 'mgr destroy' },
182 mds => {
183 create => [ 'PVE::API2::Ceph::MDS', 'createmds', [], { node => $nodename }, $upid_exit],
184 destroy => [ 'PVE::API2::Ceph::MDS', 'destroymds', ['name'], { node => $nodename }, $upid_exit],
185 },
186 start => [ 'PVE::API2::Ceph', 'start', ['service'], { node => $nodename }, $upid_exit],
187 stop => [ 'PVE::API2::Ceph', 'stop', ['service'], { node => $nodename }, $upid_exit],
188 install => [ __PACKAGE__, 'install', [] ],
189 purge => [ __PACKAGE__, 'purge', [] ],
190 status => [ 'PVE::API2::Ceph', 'status', [], { node => $nodename }, sub {
191 my $res = shift;
192 my $json = JSON->new->allow_nonref;
193 print $json->pretty->encode($res) . "\n";
194 }],
195 };
196
197 1;