]>
git.proxmox.com Git - pmg-api.git/blob - src/PMG/API2/PBS/Job.pm
9b289387a7213434c07566900de9fd664e886e5c
1 package PMG
::API2
::PBS
::Job
;
6 use POSIX
qw(strftime);
8 use PVE
::JSONSchema
qw(get_standard_option);
11 use PVE
::Tools
qw(extract_param);
14 use PMG
::RESTEnvironment
;
19 use base
qw(PVE::RESTHandler);
21 __PACKAGE__-
>register_method ({
25 description
=> "List all configured Proxmox Backup Server jobs.",
26 permissions
=> { check
=> [ 'admin', 'audit' ] },
30 additionalProperties
=> 0,
32 node
=> get_standard_option
('pve-node'),
37 items
=> PMG
::PBSConfig-
>createSchema(1),
38 links
=> [ { rel
=> 'child', href
=> "{remote}" } ],
45 my $conf = PMG
::PBSConfig-
>new();
46 return $res if !defined($conf);
48 foreach my $remote (keys %{$conf->{ids
}}) {
49 my $d = $conf->{ids
}->{$remote};
52 server
=> $d->{server
},
53 datastore
=> $d->{datastore
},
60 __PACKAGE__-
>register_method ({
61 name
=> 'remote_index',
64 description
=> "Backup Job index.",
66 additionalProperties
=> 0,
68 node
=> get_standard_option
('pve-node'),
70 description
=> "Proxmox Backup Server ID.",
71 type
=> 'string', format
=> 'pve-configid',
79 properties
=> { section
=> { type
=> 'string'} },
81 links
=> [ { rel
=> 'child', href
=> "{section}" } ],
87 { section
=> 'snapshots' },
88 { section
=> 'backup' },
89 { section
=> 'restore' },
90 { section
=> 'timer' },
95 __PACKAGE__-
>register_method ({
96 name
=> 'get_snapshots',
97 path
=> '{remote}/snapshots',
99 description
=> "Get snapshots stored on remote.",
102 permissions
=> { check
=> [ 'admin', 'audit' ] },
104 additionalProperties
=> 0,
106 node
=> get_standard_option
('pve-node'),
108 description
=> "Proxmox Backup Server ID.",
109 type
=> 'string', format
=> 'pve-configid',
118 time => { type
=> 'string'},
119 ctime
=> { type
=> 'string'},
120 size
=> { type
=> 'integer'},
123 links
=> [ { rel
=> 'child', href
=> "{time}" } ],
128 my $remote = $param->{remote
};
129 my $node = $param->{node
};
131 my $conf = PMG
::PBSConfig-
>new();
133 my $remote_config = $conf->{ids
}->{$remote};
134 die "PBS remote '$remote' does not exist\n" if !$remote_config;
136 return [] if $remote_config->{disable
};
139 group
=> "host/$node",
142 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
143 my $snapshots = $pbs->get_snapshots($snap_param);
145 foreach my $item (@$snapshots) {
146 my $btype = $item->{"backup-type"};
147 my $bid = $item->{"backup-id"};
148 my $epoch = $item->{"backup-time"};
149 my $size = $item->{size
} // 1;
151 my @pxar = grep { $_->{filename
} eq 'pmgbackup.pxar.didx' } @{$item->{files
}};
152 die "unexpected number of pmgbackup archives in snapshot\n" if (scalar(@pxar) != 1);
155 next if !($btype eq 'host');
156 next if !($bid eq $node);
158 my $time = strftime
("%FT%TZ", gmtime($epoch));
172 __PACKAGE__-
>register_method ({
173 name
=> 'forget_snapshot',
174 path
=> '{remote}/snapshots/{time}',
176 description
=> "Forget a snapshot",
179 permissions
=> { check
=> [ 'admin', 'audit' ] },
181 additionalProperties
=> 0,
183 node
=> get_standard_option
('pve-node'),
185 description
=> "Proxmox Backup Server ID.",
186 type
=> 'string', format
=> 'pve-configid',
189 description
=> "Backup time in RFC 3399 format",
194 returns
=> {type
=> 'null' },
198 my $remote = $param->{remote
};
199 my $node = $param->{node
};
200 my $time = $param->{time};
202 my $snapshot = "host/$node/$time";
204 my $conf = PMG
::PBSConfig-
>new();
206 my $remote_config = $conf->{ids
}->{$remote};
207 die "PBS remote '$remote' does not exist\n" if !$remote_config;
208 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
210 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
212 eval { $pbs->forget_snapshot($snapshot) };
213 die "Forgetting backup failed: $@" if $@;
219 __PACKAGE__-
>register_method ({
220 name
=> 'run_backup',
221 path
=> '{remote}/backup',
223 description
=> "run backup and prune the backupgroup afterwards.",
226 permissions
=> { check
=> [ 'admin', 'audit' ] },
228 additionalProperties
=> 0,
230 node
=> get_standard_option
('pve-node'),
232 description
=> "Proxmox Backup Server ID.",
233 type
=> 'string', format
=> 'pve-configid',
237 returns
=> { type
=> "string" },
241 my $rpcenv = PMG
::RESTEnvironment-
>get();
242 my $authuser = $rpcenv->get_user();
244 my $remote = $param->{remote
};
245 my $node = $param->{node
};
247 my $conf = PMG
::PBSConfig-
>new();
249 my $remote_config = $conf->{ids
}->{$remote};
250 die "PBS remote '$remote' does not exist\n" if !$remote_config;
251 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
253 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
254 my $backup_dir = "/var/lib/pmg/backup/current";
259 print "starting update of current backup state\n";
261 -d
$backup_dir || mkdir $backup_dir;
262 PMG
::Backup
::pmg_backup
($backup_dir, $param->{statistic
});
266 pxarname
=> 'pmgbackup',
270 $pbs->backup_tree($pbs_opts);
272 print "backup finished\n";
274 my $group = "host/$node";
275 if (defined(my $prune_opts = $conf->prune_options($remote))) {
276 print "starting prune of $group\n";
277 my $res = $pbs->prune_group(undef, $prune_opts, $group);
279 foreach my $pruned (@$res){
280 my $time = strftime
("%FT%TZ", gmtime($pruned->{'backup-time'}));
281 my $snap = $pruned->{'backup-type'} . '/' . $pruned->{'backup-id'} . '/' . $time;
282 print "pruned snapshot: $snap\n";
284 print "prune finished\n";
290 return $rpcenv->fork_worker('pbs_backup', undef, $authuser, $worker);
294 __PACKAGE__-
>register_method ({
296 path
=> '{remote}/restore',
298 description
=> "Restore the system configuration.",
299 permissions
=> { check
=> [ 'admin' ] },
303 additionalProperties
=> 0,
305 PMG
::Backup
::get_restore_options
(),
307 description
=> "Proxmox Backup Server ID.",
308 type
=> 'string', format
=> 'pve-configid',
310 'backup-time' => {description
=> "backup-time to restore",
311 optional
=> 1, type
=> 'string'
313 'backup-id' => {description
=> "backup-id (hostname) of backup snapshot",
314 optional
=> 1, type
=> 'string'
318 returns
=> { type
=> "string" },
322 my $rpcenv = PMG
::RESTEnvironment-
>get();
323 my $authuser = $rpcenv->get_user();
325 my $remote = $param->{remote
};
326 my $backup_id = $param->{'backup-id'} // $param->{node
};
327 my $snapshot = "host/$backup_id";
328 $snapshot .= "/$param->{'backup-time'}" if defined($param->{'backup-time'});
330 my $conf = PMG
::PBSConfig-
>new();
332 my $remote_config = $conf->{ids
}->{$remote};
333 die "PBS remote '$remote' does not exist\n" if !$remote_config;
334 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
336 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
339 my $dirname = "/tmp/proxrestore_$$.$time";
341 $param->{database
} //= 1;
343 die "nothing selected - please select what you want to restore (config or database?)\n"
344 if !($param->{database
} || $param->{config
});
347 pxarname
=> 'pmgbackup',
349 snapshot
=> $snapshot,
355 print "starting restore of $snapshot from $remote\n";
357 $pbs->restore_pxar($pbs_opts);
358 print "starting restore of PMG config\n";
359 PMG
::Backup
::pmg_restore
($dirname, $param->{database
},
360 $param->{config
}, $param->{statistic
});
361 print "restore finished\n";
366 return $rpcenv->fork_worker('pbs_restore', undef, $authuser, $worker);
369 __PACKAGE__-
>register_method ({
370 name
=> 'create_timer',
371 path
=> '{remote}/timer',
373 description
=> "Create backup schedule",
376 permissions
=> { check
=> [ 'admin', 'audit' ] },
378 additionalProperties
=> 0,
380 node
=> get_standard_option
('pve-node'),
382 description
=> "Proxmox Backup Server ID.",
383 type
=> 'string', format
=> 'pve-configid',
386 description
=> "Schedule for the backup (OnCalendar setting of the systemd.timer)",
387 type
=> 'string', pattern
=> '[0-9a-zA-Z*.:,\-/ ]+',
388 default => 'daily', optional
=> 1,
391 description
=> "Randomized delay to add to the starttime (RandomizedDelaySec setting of the systemd.timer)",
392 type
=> 'string', pattern
=> '[0-9a-zA-Z. ]+',
393 default => 'daily', optional
=> 1,
397 returns
=> { type
=> 'null' },
401 my $remote = $param->{remote
};
402 my $schedule = $param->{schedule
} // 'daily';
403 my $delay = $param->{delay
} // '5min';
405 my $conf = PMG
::PBSConfig-
>new();
407 my $remote_config = $conf->{ids
}->{$remote};
408 die "PBS remote '$remote' does not exist\n" if !$remote_config;
409 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
411 PMG
::PBSSchedule
::create_schedule
($remote, $schedule, $delay);
415 __PACKAGE__-
>register_method ({
416 name
=> 'delete_timer',
417 path
=> '{remote}/timer',
419 description
=> "Delete backup schedule",
422 permissions
=> { check
=> [ 'admin', 'audit' ] },
424 additionalProperties
=> 0,
426 node
=> get_standard_option
('pve-node'),
428 description
=> "Proxmox Backup Server ID.",
429 type
=> 'string', format
=> 'pve-configid',
433 returns
=> { type
=> 'null' },
437 my $remote = $param->{remote
};
439 PMG
::PBSSchedule
::delete_schedule
($remote);
443 __PACKAGE__-
>register_method ({
444 name
=> 'list_timer',
445 path
=> '{remote}/timer',
447 description
=> "Get timer specification",
450 permissions
=> { check
=> [ 'admin', 'audit' ] },
452 additionalProperties
=> 0,
454 node
=> get_standard_option
('pve-node'),
456 description
=> "Proxmox Backup Server ID.",
457 type
=> 'string', format
=> 'pve-configid',
461 returns
=> { type
=> 'object', properties
=> {
463 description
=> "Proxmox Backup Server ID.",
464 type
=> 'string', format
=> 'pve-configid',
468 description
=> "Schedule for the backup (OnCalendar setting of the systemd.timer)",
469 type
=> 'string', pattern
=> '[0-9a-zA-Z*.:,\-/ ]+',
470 default => 'daily', optional
=> 1,
473 description
=> "Randomized delay to add to the starttime (RandomizedDelaySec setting of the systemd.timer)",
474 type
=> 'string', pattern
=> '[0-9a-zA-Z. ]+',
475 default => 'daily', optional
=> 1,
478 description
=> "unit file for the systemd.timer unit",
479 type
=> 'string', optional
=> 1,
485 my $remote = $param->{remote
};
487 my $schedules = PMG
::PBSSchedule
::get_schedules
();
488 my @data = grep {$_->{remote
} eq $remote} @$schedules;
491 if (scalar(@data) == 1) {