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