]> git.proxmox.com Git - pve-storage.git/blob - PVE/API2/Disks.pm
add API for LVMThin management
[pve-storage.git] / PVE / API2 / Disks.pm
1 package PVE::API2::Disks;
2
3 use strict;
4 use warnings;
5
6 use PVE::SafeSyslog;
7 use PVE::Diskmanage;
8 use HTTP::Status qw(:constants);
9 use PVE::JSONSchema qw(get_standard_option);
10
11 use PVE::API2::Disks::LVM;
12 use PVE::API2::Disks::LVMThin;
13
14 use PVE::RESTHandler;
15
16 use base qw(PVE::RESTHandler);
17
18 __PACKAGE__->register_method ({
19 subclass => "PVE::API2::Disks::LVM",
20 path => 'lvm',
21 });
22
23 __PACKAGE__->register_method ({
24 subclass => "PVE::API2::Disks::LVMThin",
25 path => 'lvmthin',
26 });
27
28 __PACKAGE__->register_method ({
29 name => 'index',
30 path => '',
31 method => 'GET',
32 proxyto => 'node',
33 permissions => { user => 'all' },
34 description => "Node index.",
35 parameters => {
36 additionalProperties => 0,
37 properties => {
38 node => get_standard_option('pve-node'),
39 },
40 },
41 returns => {
42 type => 'array',
43 items => {
44 type => "object",
45 properties => {},
46 },
47 links => [ { rel => 'child', href => "{name}" } ],
48 },
49 code => sub {
50 my ($param) = @_;
51
52 my $result = [
53 { name => 'list' },
54 { name => 'initgpt' },
55 { name => 'smart' },
56 { name => 'lvm' },
57 { name => 'lvmthin' },
58 ];
59
60 return $result;
61 }});
62
63 __PACKAGE__->register_method ({
64 name => 'list',
65 path => 'list',
66 method => 'GET',
67 description => "List local disks.",
68 protected => 1,
69 proxyto => 'node',
70 permissions => {
71 check => ['perm', '/', ['Sys.Audit', 'Datastore.Audit'], any => 1],
72 },
73 parameters => {
74 additionalProperties => 0,
75 properties => {
76 node => get_standard_option('pve-node'),
77 skipsmart => {
78 description => "Skip smart checks.",
79 type => 'boolean',
80 optional => 1,
81 default => 0,
82 },
83 type => {
84 description => "Only list specific types of disks.",
85 type => 'string',
86 enum => ['unused', 'journal_disks'],
87 optional => 1,
88 },
89 },
90 },
91 returns => {
92 type => 'array',
93 items => {
94 type => 'object',
95 properties => {
96 devpath => {
97 type => 'string',
98 description => 'The device path',
99 },
100 used => { type => 'string', optional => 1 },
101 gpt => { type => 'boolean' },
102 size => { type => 'integer'},
103 osdid => { type => 'integer'},
104 vendor => { type => 'string', optional => 1 },
105 model => { type => 'string', optional => 1 },
106 serial => { type => 'string', optional => 1 },
107 wwn => { type => 'string', optional => 1},
108 health => { type => 'string', optional => 1},
109 },
110 },
111 },
112 code => sub {
113 my ($param) = @_;
114
115 my $skipsmart = $param->{skipsmart} // 0;
116
117 my $disks = PVE::Diskmanage::get_disks(undef, $skipsmart);
118
119 my $type = $param->{type} // '';
120 my $result = [];
121
122 foreach my $disk (sort keys %$disks) {
123 my $entry = $disks->{$disk};
124 if ($type eq 'journal_disks') {
125 next if $entry->{osdid} >= 0;
126 next if !$entry->{gpt};
127 } elsif ($type eq 'unused') {
128 next if $entry->{used};
129 } elsif ($type ne '') {
130 die "internal error"; # should not happen
131 }
132 push @$result, $entry;
133 }
134 return $result;
135 }});
136
137 __PACKAGE__->register_method ({
138 name => 'smart',
139 path => 'smart',
140 method => 'GET',
141 description => "Get SMART Health of a disk.",
142 protected => 1,
143 proxyto => "node",
144 permissions => {
145 check => ['perm', '/', ['Sys.Audit', 'Datastore.Audit'], any => 1],
146 },
147 parameters => {
148 additionalProperties => 0,
149 properties => {
150 node => get_standard_option('pve-node'),
151 disk => {
152 type => 'string',
153 pattern => '^/dev/[a-zA-Z0-9\/]+$',
154 description => "Block device name",
155 },
156 healthonly => {
157 type => 'boolean',
158 description => "If true returns only the health status",
159 optional => 1,
160 },
161 },
162 },
163 returns => {
164 type => 'object',
165 properties => {
166 health => { type => 'string' },
167 type => { type => 'string', optional => 1 },
168 attributes => { type => 'array', optional => 1},
169 text => { type => 'string', optional => 1 },
170 },
171 },
172 code => sub {
173 my ($param) = @_;
174
175 my $disk = PVE::Diskmanage::verify_blockdev_path($param->{disk});
176
177 my $result = PVE::Diskmanage::get_smart_data($disk, $param->{healthonly});
178
179 $result->{health} = 'UNKNOWN' if !defined $result->{health};
180 $result = { health => $result->{health} } if $param->{healthonly};
181
182 return $result;
183 }});
184
185 __PACKAGE__->register_method ({
186 name => 'initgpt',
187 path => 'initgpt',
188 method => 'POST',
189 description => "Initialize Disk with GPT",
190 protected => 1,
191 proxyto => "node",
192 permissions => {
193 check => ['perm', '/', ['Sys.Modify']],
194 },
195 parameters => {
196 additionalProperties => 0,
197 properties => {
198 node => get_standard_option('pve-node'),
199 disk => {
200 type => 'string',
201 description => "Block device name",
202 pattern => '^/dev/[a-zA-Z0-9\/]+$',
203 },
204 uuid => {
205 type => 'string',
206 description => 'UUID for the GPT table',
207 pattern => '[a-fA-F0-9\-]+',
208 maxLength => 36,
209 optional => 1,
210 },
211 },
212 },
213 returns => { type => 'string' },
214 code => sub {
215 my ($param) = @_;
216
217 my $disk = PVE::Diskmanage::verify_blockdev_path($param->{disk});
218
219 my $rpcenv = PVE::RPCEnvironment::get();
220
221 my $authuser = $rpcenv->get_user();
222
223 die "disk $disk already in use\n" if PVE::Diskmanage::disk_is_used($disk);
224 my $worker = sub {
225 PVE::Diskmanage::init_disk($disk, $param->{uuid});
226 };
227
228 my $diskid = $disk;
229 $diskid =~ s|^.*/||; # remove all up to the last slash
230 return $rpcenv->fork_worker('diskinit', $diskid, $authuser, $worker);
231 }});
232
233 1;