]>
Commit | Line | Data |
---|---|---|
b6cf0a66 DM |
1 | package PVE::API2::Storage::Scan; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
6 | use PVE::SafeSyslog; | |
7 | use PVE::Storage; | |
6d64e9e0 | 8 | use PVE::Storage::LVMPlugin; |
b6cf0a66 DM |
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", | |
5f642f73 DM |
21 | permissions => { |
22 | user => 'all', | |
23 | }, | |
b6cf0a66 DM |
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' }, | |
3cf5e19e | 45 | { method => 'glusterfs' }, |
b6cf0a66 DM |
46 | { method => 'usb' }, |
47 | ]; | |
48 | ||
49 | return $res; | |
50 | }}); | |
51 | ||
52 | __PACKAGE__->register_method ({ | |
53 | name => 'nfsscan', | |
54 | path => 'nfs', | |
55 | method => 'GET', | |
56 | description => "Scan remote NFS server.", | |
57 | protected => 1, | |
58 | proxyto => "node", | |
5f642f73 DM |
59 | permissions => { |
60 | check => ['perm', '/storage', ['Datastore.Allocate']], | |
61 | }, | |
b6cf0a66 DM |
62 | parameters => { |
63 | additionalProperties => 0, | |
64 | properties => { | |
65 | node => get_standard_option('pve-node'), | |
66 | server => { type => 'string', format => 'pve-storage-server' }, | |
67 | }, | |
68 | }, | |
69 | returns => { | |
70 | type => 'array', | |
71 | items => { | |
72 | type => "object", | |
73 | properties => { | |
74 | path => { type => 'string'}, | |
75 | options => { type => 'string'}, | |
76 | }, | |
77 | }, | |
78 | }, | |
79 | code => sub { | |
80 | my ($param) = @_; | |
81 | ||
82 | my $server = $param->{server}; | |
83 | my $res = PVE::Storage::scan_nfs($server); | |
84 | ||
85 | my $data = []; | |
86 | foreach my $k (keys %$res) { | |
87 | push @$data, { path => $k, options => $res->{$k} }; | |
88 | } | |
89 | return $data; | |
90 | }}); | |
91 | ||
3cf5e19e DM |
92 | # Note: GlusterFS currently does not have an equivalent of showmount. |
93 | # As workaround, we simply use nfs showmount. | |
94 | # see http://www.gluster.org/category/volumes/ | |
95 | ||
96 | __PACKAGE__->register_method ({ | |
97 | name => 'glusterfsscan', | |
98 | path => 'glusterfs', | |
99 | method => 'GET', | |
100 | description => "Scan remote GlusterFS server.", | |
101 | protected => 1, | |
102 | proxyto => "node", | |
103 | permissions => { | |
104 | check => ['perm', '/storage', ['Datastore.Allocate']], | |
105 | }, | |
106 | parameters => { | |
107 | additionalProperties => 0, | |
108 | properties => { | |
109 | node => get_standard_option('pve-node'), | |
110 | server => { type => 'string', format => 'pve-storage-server' }, | |
111 | }, | |
112 | }, | |
113 | returns => { | |
114 | type => 'array', | |
115 | items => { | |
116 | type => "object", | |
117 | properties => { | |
118 | volname => { type => 'string'}, | |
119 | }, | |
120 | }, | |
121 | }, | |
122 | code => sub { | |
123 | my ($param) = @_; | |
124 | ||
125 | my $server = $param->{server}; | |
126 | my $res = PVE::Storage::scan_nfs($server); | |
127 | ||
128 | my $data = []; | |
129 | foreach my $path (keys %$res) { | |
130 | if ($path =~ m!^/([^\s/]+)$!) { | |
131 | push @$data, { volname => $1 }; | |
132 | } | |
133 | } | |
134 | return $data; | |
135 | }}); | |
136 | ||
b6cf0a66 DM |
137 | __PACKAGE__->register_method ({ |
138 | name => 'iscsiscan', | |
139 | path => 'iscsi', | |
140 | method => 'GET', | |
141 | description => "Scan remote iSCSI server.", | |
142 | protected => 1, | |
143 | proxyto => "node", | |
5f642f73 DM |
144 | permissions => { |
145 | check => ['perm', '/storage', ['Datastore.Allocate']], | |
146 | }, | |
b6cf0a66 DM |
147 | parameters => { |
148 | additionalProperties => 0, | |
149 | properties => { | |
150 | node => get_standard_option('pve-node'), | |
151 | portal => { type => 'string', format => 'pve-storage-portal-dns' }, | |
152 | }, | |
153 | }, | |
154 | returns => { | |
155 | type => 'array', | |
156 | items => { | |
157 | type => "object", | |
158 | properties => { | |
159 | target => { type => 'string'}, | |
160 | portal => { type => 'string'}, | |
161 | }, | |
162 | }, | |
163 | }, | |
164 | code => sub { | |
165 | my ($param) = @_; | |
166 | ||
167 | my $res = PVE::Storage::scan_iscsi($param->{portal}); | |
168 | ||
169 | my $data = []; | |
170 | foreach my $k (keys %$res) { | |
171 | push @$data, { target => $k, portal => join(',', @{$res->{$k}}) }; | |
172 | } | |
173 | ||
174 | return $data; | |
175 | }}); | |
176 | ||
177 | __PACKAGE__->register_method ({ | |
178 | name => 'lvmscan', | |
179 | path => 'lvm', | |
180 | method => 'GET', | |
181 | description => "List local LVM volume groups.", | |
182 | protected => 1, | |
183 | proxyto => "node", | |
5f642f73 DM |
184 | permissions => { |
185 | check => ['perm', '/storage', ['Datastore.Allocate']], | |
186 | }, | |
b6cf0a66 DM |
187 | parameters => { |
188 | additionalProperties => 0, | |
189 | properties => { | |
190 | node => get_standard_option('pve-node'), | |
191 | }, | |
192 | }, | |
193 | returns => { | |
194 | type => 'array', | |
195 | items => { | |
196 | type => "object", | |
197 | properties => { | |
198 | vg => { type => 'string'}, | |
199 | }, | |
200 | }, | |
201 | }, | |
202 | code => sub { | |
203 | my ($param) = @_; | |
204 | ||
6d64e9e0 | 205 | my $res = PVE::Storage::LVMPlugin::lvm_vgs(); |
b6cf0a66 DM |
206 | return PVE::RESTHandler::hash_to_array($res, 'vg'); |
207 | }}); | |
208 | ||
209 | __PACKAGE__->register_method ({ | |
210 | name => 'usbscan', | |
211 | path => 'usb', | |
212 | method => 'GET', | |
213 | description => "List local USB devices.", | |
214 | protected => 1, | |
215 | proxyto => "node", | |
5f642f73 DM |
216 | permissions => { |
217 | check => ['perm', '/', ['Sys.Modify']], | |
218 | }, | |
b6cf0a66 DM |
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 | busnum => { type => 'integer'}, | |
231 | devnum => { type => 'integer'}, | |
232 | port => { type => 'integer'}, | |
233 | usbpath => { type => 'string', optional => 1}, | |
234 | level => { type => 'integer'}, | |
235 | class => { type => 'integer'}, | |
236 | vendid => { type => 'string'}, | |
237 | prodid => { type => 'string'}, | |
238 | speed => { type => 'string'}, | |
239 | ||
240 | product => { type => 'string', optional => 1 }, | |
241 | serial => { type => 'string', optional => 1 }, | |
242 | manufacturer => { type => 'string', optional => 1 }, | |
243 | }, | |
244 | }, | |
245 | }, | |
246 | code => sub { | |
247 | my ($param) = @_; | |
248 | ||
249 | return PVE::Storage::scan_usb(); | |
250 | }}); | |
251 | ||
252 | 1; |