]> git.proxmox.com Git - pve-storage.git/blob - PVE/API2/Storage/Scan.pm
implement zfsscan to list local zfs pools
[pve-storage.git] / PVE / API2 / Storage / Scan.pm
1 package PVE::API2::Storage::Scan;
2
3 use strict;
4 use warnings;
5
6 use PVE::SafeSyslog;
7 use PVE::Storage;
8 use PVE::Storage::LVMPlugin;
9 use HTTP::Status qw(:constants);
10 use PVE::JSONSchema qw(get_standard_option);
11
12 use PVE::RESTHandler;
13
14 use base qw(PVE::RESTHandler);
15
16 __PACKAGE__->register_method ({
17 name => 'index',
18 path => '',
19 method => 'GET',
20 description => "Index of available scan methods",
21 permissions => {
22 user => 'all',
23 },
24 parameters => {
25 additionalProperties => 0,
26 properties => {
27 node => get_standard_option('pve-node'),
28 },
29 },
30 returns => {
31 type => 'array',
32 items => {
33 type => "object",
34 properties => { method => { type => 'string'} },
35 },
36 links => [ { rel => 'child', href => "{method}" } ],
37 },
38 code => sub {
39 my ($param) = @_;
40
41 my $res = [
42 { method => 'lvm' },
43 { method => 'iscsi' },
44 { method => 'nfs' },
45 { method => 'glusterfs' },
46 { method => 'usb' },
47 { method => 'zfs' },
48 ];
49
50 return $res;
51 }});
52
53 __PACKAGE__->register_method ({
54 name => 'zfsscan',
55 path => 'zfs',
56 method => 'GET',
57 description => "Scan zfs pool list on local node.",
58 protected => 1,
59 proxyto => "node",
60 permissions => {
61 check => ['perm', '/storage', ['Datastore.Allocate']],
62 },
63 parameters => {
64 additionalProperties => 0,
65 properties => {
66 node => get_standard_option('pve-node'),
67 },
68 },
69 returns => {
70 type => 'array',
71 items => {
72 type => "object",
73 properties => {
74 pool => { type => 'string'},
75 },
76 },
77 },
78 code => sub {
79 my ($param) = @_;
80
81 return PVE::Storage::scan_zfs();
82 }});
83
84 __PACKAGE__->register_method ({
85 name => 'nfsscan',
86 path => 'nfs',
87 method => 'GET',
88 description => "Scan remote NFS server.",
89 protected => 1,
90 proxyto => "node",
91 permissions => {
92 check => ['perm', '/storage', ['Datastore.Allocate']],
93 },
94 parameters => {
95 additionalProperties => 0,
96 properties => {
97 node => get_standard_option('pve-node'),
98 server => { type => 'string', format => 'pve-storage-server' },
99 },
100 },
101 returns => {
102 type => 'array',
103 items => {
104 type => "object",
105 properties => {
106 path => { type => 'string'},
107 options => { type => 'string'},
108 },
109 },
110 },
111 code => sub {
112 my ($param) = @_;
113
114 my $server = $param->{server};
115 my $res = PVE::Storage::scan_nfs($server);
116
117 my $data = [];
118 foreach my $k (keys %$res) {
119 push @$data, { path => $k, options => $res->{$k} };
120 }
121 return $data;
122 }});
123
124 # Note: GlusterFS currently does not have an equivalent of showmount.
125 # As workaround, we simply use nfs showmount.
126 # see http://www.gluster.org/category/volumes/
127
128 __PACKAGE__->register_method ({
129 name => 'glusterfsscan',
130 path => 'glusterfs',
131 method => 'GET',
132 description => "Scan remote GlusterFS server.",
133 protected => 1,
134 proxyto => "node",
135 permissions => {
136 check => ['perm', '/storage', ['Datastore.Allocate']],
137 },
138 parameters => {
139 additionalProperties => 0,
140 properties => {
141 node => get_standard_option('pve-node'),
142 server => { type => 'string', format => 'pve-storage-server' },
143 },
144 },
145 returns => {
146 type => 'array',
147 items => {
148 type => "object",
149 properties => {
150 volname => { type => 'string'},
151 },
152 },
153 },
154 code => sub {
155 my ($param) = @_;
156
157 my $server = $param->{server};
158 my $res = PVE::Storage::scan_nfs($server);
159
160 my $data = [];
161 foreach my $path (keys %$res) {
162 if ($path =~ m!^/([^\s/]+)$!) {
163 push @$data, { volname => $1 };
164 }
165 }
166 return $data;
167 }});
168
169 __PACKAGE__->register_method ({
170 name => 'iscsiscan',
171 path => 'iscsi',
172 method => 'GET',
173 description => "Scan remote iSCSI server.",
174 protected => 1,
175 proxyto => "node",
176 permissions => {
177 check => ['perm', '/storage', ['Datastore.Allocate']],
178 },
179 parameters => {
180 additionalProperties => 0,
181 properties => {
182 node => get_standard_option('pve-node'),
183 portal => { type => 'string', format => 'pve-storage-portal-dns' },
184 },
185 },
186 returns => {
187 type => 'array',
188 items => {
189 type => "object",
190 properties => {
191 target => { type => 'string'},
192 portal => { type => 'string'},
193 },
194 },
195 },
196 code => sub {
197 my ($param) = @_;
198
199 my $res = PVE::Storage::scan_iscsi($param->{portal});
200
201 my $data = [];
202 foreach my $k (keys %$res) {
203 push @$data, { target => $k, portal => join(',', @{$res->{$k}}) };
204 }
205
206 return $data;
207 }});
208
209 __PACKAGE__->register_method ({
210 name => 'lvmscan',
211 path => 'lvm',
212 method => 'GET',
213 description => "List local LVM volume groups.",
214 protected => 1,
215 proxyto => "node",
216 permissions => {
217 check => ['perm', '/storage', ['Datastore.Allocate']],
218 },
219 parameters => {
220 additionalProperties => 0,
221 properties => {
222 node => get_standard_option('pve-node'),
223 },
224 },
225 returns => {
226 type => 'array',
227 items => {
228 type => "object",
229 properties => {
230 vg => { type => 'string'},
231 },
232 },
233 },
234 code => sub {
235 my ($param) = @_;
236
237 my $res = PVE::Storage::LVMPlugin::lvm_vgs();
238 return PVE::RESTHandler::hash_to_array($res, 'vg');
239 }});
240
241 __PACKAGE__->register_method ({
242 name => 'usbscan',
243 path => 'usb',
244 method => 'GET',
245 description => "List local USB devices.",
246 protected => 1,
247 proxyto => "node",
248 permissions => {
249 check => ['perm', '/', ['Sys.Modify']],
250 },
251 parameters => {
252 additionalProperties => 0,
253 properties => {
254 node => get_standard_option('pve-node'),
255 },
256 },
257 returns => {
258 type => 'array',
259 items => {
260 type => "object",
261 properties => {
262 busnum => { type => 'integer'},
263 devnum => { type => 'integer'},
264 port => { type => 'integer'},
265 usbpath => { type => 'string', optional => 1},
266 level => { type => 'integer'},
267 class => { type => 'integer'},
268 vendid => { type => 'string'},
269 prodid => { type => 'string'},
270 speed => { type => 'string'},
271
272 product => { type => 'string', optional => 1 },
273 serial => { type => 'string', optional => 1 },
274 manufacturer => { type => 'string', optional => 1 },
275 },
276 },
277 },
278 code => sub {
279 my ($param) = @_;
280
281 return PVE::Storage::scan_usb();
282 }});
283
284 1;