]>
git.proxmox.com Git - pmg-api.git/blob - src/PMG/API2/PBS/Job.pm
23874225b04a615391ed4b4e21b57e7a1cb61fa3
1 package PMG
::API2
::PBS
::Job
;
6 use POSIX
qw(strftime);
7 use File
::Path
qw(rmtree);
9 use PVE
::JSONSchema
qw(get_standard_option);
12 use PVE
::Tools
qw(extract_param);
15 use PMG
::RESTEnvironment
;
20 use base
qw(PVE::RESTHandler);
22 __PACKAGE__-
>register_method ({
26 description
=> "List all configured Proxmox Backup Server jobs.",
27 permissions
=> { check
=> [ 'admin', 'audit' ] },
31 additionalProperties
=> 0,
33 node
=> get_standard_option
('pve-node'),
38 items
=> PMG
::PBSConfig-
>createSchema(1),
39 links
=> [ { rel
=> 'child', href
=> "{remote}" } ],
46 my $conf = PMG
::PBSConfig-
>new();
47 return $res if !defined($conf);
49 foreach my $remote (keys %{$conf->{ids
}}) {
50 my $d = $conf->{ids
}->{$remote};
53 server
=> $d->{server
},
54 datastore
=> $d->{datastore
},
61 __PACKAGE__-
>register_method ({
62 name
=> 'remote_index',
65 description
=> "Backup Job index.",
67 additionalProperties
=> 0,
69 node
=> get_standard_option
('pve-node'),
71 description
=> "Proxmox Backup Server ID.",
72 type
=> 'string', format
=> 'pve-configid',
80 properties
=> { section
=> { type
=> 'string'} },
82 links
=> [ { rel
=> 'child', href
=> "{section}" } ],
88 { section
=> 'snapshot' },
89 { section
=> 'timer' },
95 my sub get_snapshots
{
96 my ($remote, $group) = @_;
98 my $conf = PMG
::PBSConfig-
>new();
100 my $remote_config = $conf->{ids
}->{$remote};
101 die "PBS remote '$remote' does not exist\n" if !$remote_config;
104 return $res if $remote_config->{disable
};
106 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
108 my $snapshots = $pbs->get_snapshots($group);
109 foreach my $item (@$snapshots) {
110 my ($type, $id, $time) = $item->@{qw(backup-type backup-id backup-time)};
111 next if $type ne 'host';
113 my @pxar = grep { $_->{filename
} eq 'pmgbackup.pxar.didx' } @{$item->{files
}};
114 next if (scalar(@pxar) != 1);
116 my $time_rfc3339 = strftime
("%FT%TZ", gmtime($time));
120 'backup-time' => $time_rfc3339,
122 size
=> $item->{size
} // 1,
128 __PACKAGE__-
>register_method ({
129 name
=> 'get_snapshots',
130 path
=> '{remote}/snapshot',
132 description
=> "Get snapshots stored on remote.",
135 permissions
=> { check
=> [ 'admin', 'audit' ] },
137 additionalProperties
=> 0,
139 node
=> get_standard_option
('pve-node'),
141 description
=> "Proxmox Backup Server ID.",
142 type
=> 'string', format
=> 'pve-configid',
151 'backup-time' => { type
=> 'string'},
152 'backup-id' => { type
=> 'string'},
153 ctime
=> { type
=> 'string'},
154 size
=> { type
=> 'integer'},
157 links
=> [ { rel
=> 'child', href
=> "{backup-id}" } ],
162 return get_snapshots
($param->{remote
});
165 __PACKAGE__-
>register_method ({
166 name
=> 'get_group_snapshots',
167 path
=> '{remote}/snapshot/{backup-id}',
169 description
=> "Get snapshots from a specific ID stored on remote.",
172 permissions
=> { check
=> [ 'admin', 'audit' ] },
174 additionalProperties
=> 0,
176 node
=> get_standard_option
('pve-node'),
178 description
=> "Proxmox Backup Server ID.",
179 type
=> 'string', format
=> 'pve-configid',
182 description
=> "ID (hostname) of backup snapshot",
192 'backup-time' => { type
=> 'string'},
193 'backup-id' => { type
=> 'string'},
194 ctime
=> { type
=> 'string'},
195 size
=> { type
=> 'integer'},
198 links
=> [ { rel
=> 'child', href
=> "{backup-time}" } ],
203 return get_snapshots
($param->{remote
}, "host/$param->{node}");
206 __PACKAGE__-
>register_method ({
207 name
=> 'forget_snapshot',
208 path
=> '{remote}/snapshot/{backup-id}/{backup-time}',
210 description
=> "Forget a snapshot",
213 permissions
=> { check
=> [ 'admin', 'audit' ] },
215 additionalProperties
=> 0,
217 node
=> get_standard_option
('pve-node'),
219 description
=> "Proxmox Backup Server ID.",
220 type
=> 'string', format
=> 'pve-configid',
223 description
=> "ID (hostname) of backup snapshot",
227 description
=> "Backup time in RFC 3339 format",
232 returns
=> {type
=> 'null' },
236 my $remote = $param->{remote
};
237 my $id = $param->{'backup-id'};
238 my $time = $param->{'backup-time'};
240 my $conf = PMG
::PBSConfig-
>new();
241 my $remote_config = $conf->{ids
}->{$remote};
242 die "PBS remote '$remote' does not exist\n" if !$remote_config;
243 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
245 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
247 eval { $pbs->forget_snapshot("host/$id/$time") };
248 die "Forgetting backup failed: $@" if $@;
254 __PACKAGE__-
>register_method ({
255 name
=> 'run_backup',
256 path
=> '{remote}/snapshot',
258 description
=> "Create a new backup and prune the backup group afterwards, if configured.",
261 permissions
=> { check
=> [ 'admin', 'audit' ] },
263 additionalProperties
=> 0,
265 node
=> get_standard_option
('pve-node'),
267 description
=> "Proxmox Backup Server ID.",
268 type
=> 'string', format
=> 'pve-configid',
271 description
=> "Backup statistic databases.",
278 returns
=> { type
=> "string" },
282 my $rpcenv = PMG
::RESTEnvironment-
>get();
283 my $authuser = $rpcenv->get_user();
285 my $remote = $param->{remote
};
286 my $node = $param->{node
};
288 my $conf = PMG
::PBSConfig-
>new();
290 my $remote_config = $conf->{ids
}->{$remote};
291 die "PBS remote '$remote' does not exist\n" if !$remote_config;
292 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
294 $param->{statistic
} //= $remote_config->{'include-statistics'} // 1;
296 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
297 my $backup_dir = "/var/lib/pmg/backup/current";
302 print "starting update of current backup state\n";
304 -d
$backup_dir || mkdir $backup_dir;
305 PMG
::Backup
::pmg_backup
($backup_dir, $param->{statistic
});
307 $pbs->backup_fs_tree($backup_dir, $node, 'pmgbackup');
311 print "backup finished\n";
313 my $group = "host/$node";
314 if (defined(my $prune_opts = $conf->prune_options($remote))) {
315 print "starting prune of $group\n";
316 my $res = $pbs->prune_group(undef, $prune_opts, $group);
318 foreach my $pruned (@$res){
319 my $time = strftime
("%FT%TZ", gmtime($pruned->{'backup-time'}));
320 my $snap = $pruned->{'backup-type'} . '/' . $pruned->{'backup-id'} . '/' . $time;
321 print "pruned snapshot: $snap\n";
323 print "prune finished\n";
329 return $rpcenv->fork_worker('pbs_backup', undef, $authuser, $worker);
333 __PACKAGE__-
>register_method ({
335 path
=> '{remote}/snapshot/{backup-id}/{backup-time}',
337 description
=> "Restore the system configuration.",
338 permissions
=> { check
=> [ 'admin' ] },
342 additionalProperties
=> 0,
344 PMG
::Backup
::get_restore_options
(),
346 description
=> "Proxmox Backup Server ID.",
347 type
=> 'string', format
=> 'pve-configid',
350 description
=> "backup-time to restore",
354 description
=> "backup-id (hostname) of backup snapshot",
359 returns
=> { type
=> "string" },
363 my $rpcenv = PMG
::RESTEnvironment-
>get();
364 my $authuser = $rpcenv->get_user();
366 my $remote = $param->{remote
};
367 my $id = $param->{'backup-id'};
368 my $time = $param->{'backup-time'};
369 my $snapshot = "host/$id/$time";
371 my $conf = PMG
::PBSConfig-
>new();
373 my $remote_config = $conf->{ids
}->{$remote};
374 die "PBS remote '$remote' does not exist\n" if !$remote_config;
375 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
377 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
380 my $dirname = "/tmp/proxrestore_$$.$now";
382 $param->{database
} //= 1;
384 die "nothing selected - please select what you want to restore (config or database?)\n"
385 if !($param->{database
} || $param->{config
});
388 print "starting restore of $snapshot from $remote\n";
390 $pbs->restore_pxar($snapshot, 'pmgbackup', $dirname);
391 print "starting restore of PMG config\n";
392 PMG
::Backup
::pmg_restore
(
398 print "restore finished\n";
401 return $rpcenv->fork_worker('pbs_restore', undef, $authuser, $worker);
404 __PACKAGE__-
>register_method ({
405 name
=> 'create_timer',
406 path
=> '{remote}/timer',
408 description
=> "Create backup schedule",
411 permissions
=> { check
=> [ 'admin', 'audit' ] },
413 additionalProperties
=> 0,
415 node
=> get_standard_option
('pve-node'),
417 description
=> "Proxmox Backup Server ID.",
418 type
=> 'string', format
=> 'pve-configid',
421 description
=> "Schedule for the backup (OnCalendar setting of the systemd.timer)",
422 type
=> 'string', pattern
=> '[0-9a-zA-Z*.:,\-/ ]+',
423 default => 'daily', optional
=> 1,
426 description
=> "Randomized delay to add to the starttime (RandomizedDelaySec setting of the systemd.timer)",
427 type
=> 'string', pattern
=> '[0-9a-zA-Z. ]+',
428 default => '5min', optional
=> 1,
432 returns
=> { type
=> 'null' },
436 my $remote = $param->{remote
};
437 my $schedule = $param->{schedule
} // 'daily';
438 my $delay = $param->{delay
} // '5min';
440 my $conf = PMG
::PBSConfig-
>new();
442 my $remote_config = $conf->{ids
}->{$remote};
443 die "PBS remote '$remote' does not exist\n" if !$remote_config;
444 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
446 PMG
::PBSSchedule
::create_schedule
($remote, $schedule, $delay);
450 __PACKAGE__-
>register_method ({
451 name
=> 'delete_timer',
452 path
=> '{remote}/timer',
454 description
=> "Delete backup schedule",
457 permissions
=> { check
=> [ 'admin', 'audit' ] },
459 additionalProperties
=> 0,
461 node
=> get_standard_option
('pve-node'),
463 description
=> "Proxmox Backup Server ID.",
464 type
=> 'string', format
=> 'pve-configid',
468 returns
=> { type
=> 'null' },
472 my $remote = $param->{remote
};
474 PMG
::PBSSchedule
::delete_schedule
($remote);
478 __PACKAGE__-
>register_method ({
479 name
=> 'list_timer',
480 path
=> '{remote}/timer',
482 description
=> "Get timer specification",
485 permissions
=> { check
=> [ 'admin', 'audit' ] },
487 additionalProperties
=> 0,
489 node
=> get_standard_option
('pve-node'),
491 description
=> "Proxmox Backup Server ID.",
492 type
=> 'string', format
=> 'pve-configid',
500 description
=> "Proxmox Backup Server remote ID.",
501 type
=> 'string', format
=> 'pve-configid',
505 description
=> "Schedule for the backup (OnCalendar setting of the systemd.timer)",
506 type
=> 'string', pattern
=> '[0-9a-zA-Z*.:,\-/ ]+',
507 default => 'daily', optional
=> 1,
510 description
=> "Randomized delay to add to the starttime (RandomizedDelaySec setting of the systemd.timer)",
511 type
=> 'string', pattern
=> '[0-9a-zA-Z. ]+',
512 default => '5min', optional
=> 1,
515 description
=> "The date time of the next run, in server locale.",
520 description
=> "unit file for the systemd.timer unit",
521 type
=> 'string', optional
=> 1,
528 my $remote = $param->{remote
};
530 my $schedules = PMG
::PBSSchedule
::get_schedules
($remote);
533 if (scalar(@$schedules) >= 1) {
534 $res = $schedules->[0];