]> git.proxmox.com Git - pve-storage.git/blob - PVE/API2/Storage/FileRestore.pm
68f81ebe1e31acc125be6d99afe4f268aeabcb74
[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 => 'any', # JSON::PP::Boolean gets passed through
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 return $ret;
95 }});
96
97 __PACKAGE__->register_method ({
98 name => 'download',
99 path => 'download',
100 method => 'GET',
101 proxyto => 'node',
102 permissions => {
103 description => "You need read access for the volume.",
104 user => 'all',
105 },
106 description => "Extract a file or directory (as zip archive) from a PBS backup.",
107 parameters => {
108 additionalProperties => 0,
109 properties => {
110 node => get_standard_option('pve-node'),
111 storage => get_standard_option('pve-storage-id'),
112 snapshot => {
113 description => "Backup snapshot identifier.",
114 type => 'string',
115 },
116 filepath => {
117 description => 'base64-path to the directory or file to download.',
118 type => 'string',
119 },
120 },
121 },
122 returns => {
123 type => 'any', # download
124 },
125 protected => 1,
126 code => sub {
127 my ($param) = @_;
128
129 my $rpcenv = PVE::RPCEnvironment::get();
130 my $user = $rpcenv->get_user();
131
132 my $path = extract_param($param, 'filepath');
133 my $snap = extract_param($param, 'snapshot');
134 my $storeid = extract_param($param, 'storage');
135 my $cfg = PVE::Storage::config();
136 my $scfg = PVE::Storage::storage_config($cfg, $storeid);
137
138 my $volid = "$storeid:backup/$snap";
139 PVE::Storage::check_volume_access($rpcenv, $user, $cfg, undef, $volid);
140
141 my $client = PVE::PBSClient->new($scfg, $storeid);
142 my $fifo = $client->file_restore_extract_prepare();
143
144 $rpcenv->fork_worker('pbs-download', undef, $user, sub {
145 my $name = decode_base64($path);
146 print "Starting download of file: $name\n";
147 $client->file_restore_extract($fifo, $snap, $path, 1);
148 });
149
150 my $ret = {
151 download => {
152 path => $fifo,
153 stream => 1,
154 'content-type' => 'application/octet-stream',
155 },
156 };
157 return $ret;
158 }});
159
160 1;