]>
git.proxmox.com Git - pve-storage.git/blob - src/PVE/API2/Disks.pm
1 package PVE
::API2
::Disks
;
7 use HTTP
::Status
qw(:constants);
10 use PVE
::JSONSchema
qw(get_standard_option);
12 use PVE
::Tools
qw(run_command);
14 use PVE
::API2
::Disks
::Directory
;
15 use PVE
::API2
::Disks
::LVM
;
16 use PVE
::API2
::Disks
::LVMThin
;
17 use PVE
::API2
::Disks
::ZFS
;
20 use base
qw(PVE::RESTHandler);
22 __PACKAGE__-
>register_method ({
23 subclass
=> "PVE::API2::Disks::LVM",
27 __PACKAGE__-
>register_method ({
28 subclass
=> "PVE::API2::Disks::LVMThin",
32 __PACKAGE__-
>register_method ({
33 subclass
=> "PVE::API2::Disks::Directory",
37 __PACKAGE__-
>register_method ({
38 subclass
=> "PVE::API2::Disks::ZFS",
42 __PACKAGE__-
>register_method ({
47 permissions
=> { user
=> 'all' },
48 description
=> "Node index.",
50 additionalProperties
=> 0,
52 node
=> get_standard_option
('pve-node'),
61 links
=> [ { rel
=> 'child', href
=> "{name}" } ],
68 { name
=> 'initgpt' },
71 { name
=> 'lvmthin' },
72 { name
=> 'directory' },
73 { name
=> 'wipedisk' },
80 __PACKAGE__-
>register_method ({
84 description
=> "List local disks.",
88 check
=> ['or', ['perm', '/', ['Sys.Audit']], ['perm', '/nodes/{node}', ['Sys.Audit']]],
91 additionalProperties
=> 0,
93 node
=> get_standard_option
('pve-node'),
94 'include-partitions' => {
95 description
=> "Also include partitions.",
101 description
=> "Skip smart checks.",
107 description
=> "Only list specific types of disks.",
109 enum
=> ['unused', 'journal_disks'],
121 description
=> 'The device path',
123 used
=> { type
=> 'string', optional
=> 1 },
124 gpt
=> { type
=> 'boolean' },
125 mounted
=> { type
=> 'boolean' },
126 size
=> { type
=> 'integer'},
127 osdid
=> { type
=> 'integer'}, # TODO: deprecate / remove in PVE 9?
130 items
=> { type
=> 'integer' },
132 vendor
=> { type
=> 'string', optional
=> 1 },
133 model
=> { type
=> 'string', optional
=> 1 },
134 serial
=> { type
=> 'string', optional
=> 1 },
135 wwn
=> { type
=> 'string', optional
=> 1},
136 health
=> { type
=> 'string', optional
=> 1},
139 description
=> 'For partitions only. The device path of ' .
140 'the disk the partition resides on.',
149 my $skipsmart = $param->{skipsmart
} // 0;
150 my $include_partitions = $param->{'include-partitions'} // 0;
152 my $disks = PVE
::Diskmanage
::get_disks
(
158 my $type = $param->{type
} // '';
161 foreach my $disk (sort keys %$disks) {
162 my $entry = $disks->{$disk};
163 if ($type eq 'journal_disks') {
164 next if $entry->{osdid
} >= 0;
165 if (my $usage = $entry->{used
}) {
166 next if !($usage eq 'partitions' && $entry->{gpt
}
169 } elsif ($type eq 'unused') {
170 next if $entry->{used
};
171 } elsif ($type ne '') {
172 die "internal error"; # should not happen
174 push @$result, $entry;
179 __PACKAGE__-
>register_method ({
183 description
=> "Get SMART Health of a disk.",
187 check
=> ['perm', '/', ['Sys.Audit']],
190 additionalProperties
=> 0,
192 node
=> get_standard_option
('pve-node'),
195 pattern
=> '^/dev/[a-zA-Z0-9\/]+$',
196 description
=> "Block device name",
200 description
=> "If true returns only the health status",
208 health
=> { type
=> 'string' },
209 type
=> { type
=> 'string', optional
=> 1 },
210 attributes
=> { type
=> 'array', optional
=> 1},
211 text
=> { type
=> 'string', optional
=> 1 },
217 my $disk = PVE
::Diskmanage
::verify_blockdev_path
($param->{disk
});
219 my $result = PVE
::Diskmanage
::get_smart_data
($disk, $param->{healthonly
});
221 $result->{health
} = 'UNKNOWN' if !defined $result->{health
};
222 $result = { health
=> $result->{health
} } if $param->{healthonly
};
227 __PACKAGE__-
>register_method ({
231 description
=> "Initialize Disk with GPT",
235 check
=> ['perm', '/', ['Sys.Modify']],
238 additionalProperties
=> 0,
240 node
=> get_standard_option
('pve-node'),
243 description
=> "Block device name",
244 pattern
=> '^/dev/[a-zA-Z0-9\/]+$',
248 description
=> 'UUID for the GPT table',
249 pattern
=> '[a-fA-F0-9\-]+',
255 returns
=> { type
=> 'string' },
259 my $disk = PVE
::Diskmanage
::verify_blockdev_path
($param->{disk
});
261 my $rpcenv = PVE
::RPCEnvironment
::get
();
263 my $authuser = $rpcenv->get_user();
265 die "$disk is a partition\n" if PVE
::Diskmanage
::is_partition
($disk);
266 die "disk $disk already in use\n" if PVE
::Diskmanage
::disk_is_used
($disk);
268 PVE
::Diskmanage
::init_disk
($disk, $param->{uuid
});
272 $diskid =~ s
|^.*/||; # remove all up to the last slash
273 return $rpcenv->fork_worker('diskinit', $diskid, $authuser, $worker);
276 __PACKAGE__-
>register_method ({
280 description
=> "Wipe a disk or partition.",
284 additionalProperties
=> 0,
286 node
=> get_standard_option
('pve-node'),
289 description
=> "Block device name",
290 pattern
=> '^/dev/[a-zA-Z0-9\/]+$',
294 returns
=> { type
=> 'string' },
298 my $disk = PVE
::Diskmanage
::verify_blockdev_path
($param->{disk
});
300 my $mounted = PVE
::Diskmanage
::is_mounted
($disk);
301 die "disk/partition '${mounted}' is mounted\n" if $mounted;
303 my $held = PVE
::Diskmanage
::has_holder
($disk);
304 die "disk/partition '${held}' has a holder\n" if $held;
306 my $rpcenv = PVE
::RPCEnvironment
::get
();
307 my $authuser = $rpcenv->get_user();
310 PVE
::Diskmanage
::wipe_blockdev
($disk);
311 PVE
::Diskmanage
::udevadm_trigger
($disk);
314 my $basename = basename
($disk); # avoid '/' in the ID
316 return $rpcenv->fork_worker('wipedisk', $basename, $authuser, $worker);