]> git.proxmox.com Git - pve-storage.git/blob - PVE/API2/Storage/FileRestore.pm
file-restore: return perl-y booleans
[pve-storage.git] / PVE / API2 / Storage / FileRestore.pm
1 package PVE::API2::Storage::FileRestore;
2
3 use strict;
4 use warnings;
5
6 use MIME::Base64;
7 use PVE::JSONSchema qw(get_standard_option);
8 use PVE::PBSClient;
9 use PVE::Storage;
10 use PVE::Tools qw(extract_param);
11
12 use PVE::RESTHandler;
13 use base qw(PVE::RESTHandler);
14
15 __PACKAGE__->register_method ({
16 name => 'list',
17 path => 'list',
18 method => 'GET',
19 proxyto => 'node',
20 permissions => {
21 description => "You need read access for the volume.",
22 user => 'all',
23 },
24 description => "List files and directories for single file restore under the given path.",
25 parameters => {
26 additionalProperties => 0,
27 properties => {
28 node => get_standard_option('pve-node'),
29 storage => get_standard_option('pve-storage-id'),
30 snapshot => {
31 description => "Backup snapshot identifier.",
32 type => 'string',
33 },
34 filepath => {
35 description => 'base64-path to the directory or file being listed, or "/".',
36 type => 'string',
37 },
38 },
39 },
40 returns => {
41 type => 'array',
42 items => {
43 type => "object",
44 properties => {
45 filepath => {
46 description => "base64 path of the current entry",
47 type => 'string',
48 },
49 type => {
50 description => "Entry type.",
51 type => 'string',
52 },
53 text => {
54 description => "Entry display text.",
55 type => 'string',
56 },
57 leaf => {
58 description => "If this entry is a leaf in the directory graph.",
59 type => 'boolean',
60 },
61 size => {
62 description => "Entry file size.",
63 type => 'integer',
64 optional => 1,
65 },
66 mtime => {
67 description => "Entry last-modified time (unix timestamp).",
68 type => 'integer',
69 optional => 1,
70 },
71 },
72 },
73 },
74 protected => 1,
75 code => sub {
76 my ($param) = @_;
77
78 my $rpcenv = PVE::RPCEnvironment::get();
79 my $user = $rpcenv->get_user();
80
81 my $path = extract_param($param, 'filepath') || "/";
82 my $base64 = $path ne "/";
83 my $snap = extract_param($param, 'snapshot');
84 my $storeid = extract_param($param, 'storage');
85 my $cfg = PVE::Storage::config();
86 my $scfg = PVE::Storage::storage_config($cfg, $storeid);
87
88 my $volid = "$storeid:backup/$snap";
89 PVE::Storage::check_volume_access($rpcenv, $user, $cfg, undef, $volid);
90
91 my $client = PVE::PBSClient->new($scfg, $storeid);
92 my $ret = $client->file_restore_list($snap, $path, $base64);
93
94
95 # 'leaf' is a proper JSON boolean, map to perl-y bool
96 # TODO: make PBSClient decode all bools always as 1/0?
97 foreach my $item (@$ret) {
98 $item->{leaf} = $item->{leaf} ? 1 : 0;
99 }
100
101 return $ret;
102 }});
103
104 __PACKAGE__->register_method ({
105 name => 'download',
106 path => 'download',
107 method => 'GET',
108 proxyto => 'node',
109 permissions => {
110 description => "You need read access for the volume.",
111 user => 'all',
112 },
113 description => "Extract a file or directory (as zip archive) from a PBS backup.",
114 parameters => {
115 additionalProperties => 0,
116 properties => {
117 node => get_standard_option('pve-node'),
118 storage => get_standard_option('pve-storage-id'),
119 snapshot => {
120 description => "Backup snapshot identifier.",
121 type => 'string',
122 },
123 filepath => {
124 description => 'base64-path to the directory or file to download.',
125 type => 'string',
126 },
127 },
128 },
129 returns => {
130 type => 'any', # download
131 },
132 protected => 1,
133 code => sub {
134 my ($param) = @_;
135
136 my $rpcenv = PVE::RPCEnvironment::get();
137 my $user = $rpcenv->get_user();
138
139 my $path = extract_param($param, 'filepath');
140 my $snap = extract_param($param, 'snapshot');
141 my $storeid = extract_param($param, 'storage');
142 my $cfg = PVE::Storage::config();
143 my $scfg = PVE::Storage::storage_config($cfg, $storeid);
144
145 my $volid = "$storeid:backup/$snap";
146 PVE::Storage::check_volume_access($rpcenv, $user, $cfg, undef, $volid);
147
148 my $client = PVE::PBSClient->new($scfg, $storeid);
149 my $fifo = $client->file_restore_extract_prepare();
150
151 $rpcenv->fork_worker('pbs-download', undef, $user, sub {
152 my $name = decode_base64($path);
153 print "Starting download of file: $name\n";
154 $client->file_restore_extract($fifo, $snap, $path, 1);
155 });
156
157 my $ret = {
158 download => {
159 path => $fifo,
160 stream => 1,
161 'content-type' => 'application/octet-stream',
162 },
163 };
164 return $ret;
165 }});
166
167 1;