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