]>
git.proxmox.com Git - pmg-api.git/blob - src/PMG/API2/PBS/Job.pm
91e0f818a2b206e06d8c0dbe2135e830241374c1
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
=> 'snapshot' },
88 { section
=> 'timer' },
94 my sub get_snapshots
{
95 my ($remote, $group) = @_;
97 my $conf = PMG
::PBSConfig-
>new();
99 my $remote_config = $conf->{ids
}->{$remote};
100 die "PBS remote '$remote' does not exist\n" if !$remote_config;
103 return $res if $remote_config->{disable
};
105 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
107 my $snapshots = $pbs->get_snapshots($group);
108 foreach my $item (@$snapshots) {
109 my ($type, $id, $time) = $item->@{qw(backup-type backup-id backup-time)};
110 next if $type ne 'host';
112 my @pxar = grep { $_->{filename
} eq 'pmgbackup.pxar.didx' } @{$item->{files
}};
113 next if (scalar(@pxar) != 1);
115 my $time_rfc3339 = strftime
("%FT%TZ", gmtime($time));
119 'backup-time' => $time_rfc3339,
121 size
=> $item->{size
} // 1,
127 __PACKAGE__-
>register_method ({
128 name
=> 'get_snapshots',
129 path
=> '{remote}/snapshot',
131 description
=> "Get snapshots stored on remote.",
134 permissions
=> { check
=> [ 'admin', 'audit' ] },
136 additionalProperties
=> 0,
138 node
=> get_standard_option
('pve-node'),
140 description
=> "Proxmox Backup Server ID.",
141 type
=> 'string', format
=> 'pve-configid',
150 'backup-time' => { type
=> 'string'},
151 'backup-id' => { type
=> 'string'},
152 ctime
=> { type
=> 'string'},
153 size
=> { type
=> 'integer'},
156 links
=> [ { rel
=> 'child', href
=> "{backup-id}" } ],
161 return get_snapshots
($param->{remote
});
164 __PACKAGE__-
>register_method ({
165 name
=> 'get_group_snapshots',
166 path
=> '{remote}/snapshot/{backup-id}',
168 description
=> "Get snapshots from a specific ID stored on remote.",
171 permissions
=> { check
=> [ 'admin', 'audit' ] },
173 additionalProperties
=> 0,
175 node
=> get_standard_option
('pve-node'),
177 description
=> "Proxmox Backup Server ID.",
178 type
=> 'string', format
=> 'pve-configid',
181 description
=> "ID (hostname) of backup snapshot",
191 'backup-time' => { type
=> 'string'},
192 'backup-id' => { type
=> 'string'},
193 ctime
=> { type
=> 'string'},
194 size
=> { type
=> 'integer'},
197 links
=> [ { rel
=> 'child', href
=> "{backup-time}" } ],
202 return get_snapshots
($param->{remote
}, "host/$param->{node}");
205 __PACKAGE__-
>register_method ({
206 name
=> 'forget_snapshot',
207 path
=> '{remote}/snapshot/{backup-id}/{backup-time}',
209 description
=> "Forget a snapshot",
212 permissions
=> { check
=> [ 'admin', 'audit' ] },
214 additionalProperties
=> 0,
216 node
=> get_standard_option
('pve-node'),
218 description
=> "Proxmox Backup Server ID.",
219 type
=> 'string', format
=> 'pve-configid',
222 description
=> "ID (hostname) of backup snapshot",
226 description
=> "Backup time in RFC 3339 format",
231 returns
=> {type
=> 'null' },
235 my $remote = $param->{remote
};
236 my $id = $param->{'backup-id'};
237 my $time = $param->{'backup-time'};
239 my $conf = PMG
::PBSConfig-
>new();
240 my $remote_config = $conf->{ids
}->{$remote};
241 die "PBS remote '$remote' does not exist\n" if !$remote_config;
242 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
244 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
246 eval { $pbs->forget_snapshot("host/$id/$time") };
247 die "Forgetting backup failed: $@" if $@;
253 __PACKAGE__-
>register_method ({
254 name
=> 'run_backup',
255 path
=> '{remote}/snapshot',
257 description
=> "Create a new backup and prune the backup group afterwards, if configured.",
260 permissions
=> { check
=> [ 'admin', 'audit' ] },
262 additionalProperties
=> 0,
264 node
=> get_standard_option
('pve-node'),
266 description
=> "Proxmox Backup Server ID.",
267 type
=> 'string', format
=> 'pve-configid',
271 returns
=> { type
=> "string" },
275 my $rpcenv = PMG
::RESTEnvironment-
>get();
276 my $authuser = $rpcenv->get_user();
278 my $remote = $param->{remote
};
279 my $node = $param->{node
};
281 my $conf = PMG
::PBSConfig-
>new();
283 my $remote_config = $conf->{ids
}->{$remote};
284 die "PBS remote '$remote' does not exist\n" if !$remote_config;
285 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
287 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
288 my $backup_dir = "/var/lib/pmg/backup/current";
293 print "starting update of current backup state\n";
295 -d
$backup_dir || mkdir $backup_dir;
296 PMG
::Backup
::pmg_backup
($backup_dir, $param->{statistic
});
298 $pbs->backup_fs_tree($backup_dir, $node, 'pmgbackup');
300 print "backup finished\n";
302 my $group = "host/$node";
303 if (defined(my $prune_opts = $conf->prune_options($remote))) {
304 print "starting prune of $group\n";
305 my $res = $pbs->prune_group(undef, $prune_opts, $group);
307 foreach my $pruned (@$res){
308 my $time = strftime
("%FT%TZ", gmtime($pruned->{'backup-time'}));
309 my $snap = $pruned->{'backup-type'} . '/' . $pruned->{'backup-id'} . '/' . $time;
310 print "pruned snapshot: $snap\n";
312 print "prune finished\n";
318 return $rpcenv->fork_worker('pbs_backup', undef, $authuser, $worker);
322 __PACKAGE__-
>register_method ({
324 path
=> '{remote}/snapshot/{backup-id}/{backup-time}',
326 description
=> "Restore the system configuration.",
327 permissions
=> { check
=> [ 'admin' ] },
331 additionalProperties
=> 0,
333 PMG
::Backup
::get_restore_options
(),
335 description
=> "Proxmox Backup Server ID.",
336 type
=> 'string', format
=> 'pve-configid',
339 description
=> "backup-time to restore",
343 description
=> "backup-id (hostname) of backup snapshot",
348 returns
=> { type
=> "string" },
352 my $rpcenv = PMG
::RESTEnvironment-
>get();
353 my $authuser = $rpcenv->get_user();
355 my $remote = $param->{remote
};
356 my $id = $param->{'backup-id'};
357 my $time = $param->{'backup-time'};
358 my $snapshot = "host/$id/$time";
360 my $conf = PMG
::PBSConfig-
>new();
362 my $remote_config = $conf->{ids
}->{$remote};
363 die "PBS remote '$remote' does not exist\n" if !$remote_config;
364 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
366 my $pbs = PVE
::PBSClient-
>new($remote_config, $remote, $conf->{secret_dir
});
369 my $dirname = "/tmp/proxrestore_$$.$now";
371 $param->{database
} //= 1;
373 die "nothing selected - please select what you want to restore (config or database?)\n"
374 if !($param->{database
} || $param->{config
});
377 print "starting restore of $snapshot from $remote\n";
379 $pbs->restore_pxar($snapshot, 'pmgbackup', $dirname);
380 print "starting restore of PMG config\n";
381 PMG
::Backup
::pmg_restore
(
387 print "restore finished\n";
390 return $rpcenv->fork_worker('pbs_restore', undef, $authuser, $worker);
393 __PACKAGE__-
>register_method ({
394 name
=> 'create_timer',
395 path
=> '{remote}/timer',
397 description
=> "Create backup schedule",
400 permissions
=> { check
=> [ 'admin', 'audit' ] },
402 additionalProperties
=> 0,
404 node
=> get_standard_option
('pve-node'),
406 description
=> "Proxmox Backup Server ID.",
407 type
=> 'string', format
=> 'pve-configid',
410 description
=> "Schedule for the backup (OnCalendar setting of the systemd.timer)",
411 type
=> 'string', pattern
=> '[0-9a-zA-Z*.:,\-/ ]+',
412 default => 'daily', optional
=> 1,
415 description
=> "Randomized delay to add to the starttime (RandomizedDelaySec setting of the systemd.timer)",
416 type
=> 'string', pattern
=> '[0-9a-zA-Z. ]+',
417 default => '5min', optional
=> 1,
421 returns
=> { type
=> 'null' },
425 my $remote = $param->{remote
};
426 my $schedule = $param->{schedule
} // 'daily';
427 my $delay = $param->{delay
} // '5min';
429 my $conf = PMG
::PBSConfig-
>new();
431 my $remote_config = $conf->{ids
}->{$remote};
432 die "PBS remote '$remote' does not exist\n" if !$remote_config;
433 die "PBS remote '$remote' is disabled\n" if $remote_config->{disable
};
435 PMG
::PBSSchedule
::create_schedule
($remote, $schedule, $delay);
439 __PACKAGE__-
>register_method ({
440 name
=> 'delete_timer',
441 path
=> '{remote}/timer',
443 description
=> "Delete backup schedule",
446 permissions
=> { check
=> [ 'admin', 'audit' ] },
448 additionalProperties
=> 0,
450 node
=> get_standard_option
('pve-node'),
452 description
=> "Proxmox Backup Server ID.",
453 type
=> 'string', format
=> 'pve-configid',
457 returns
=> { type
=> 'null' },
461 my $remote = $param->{remote
};
463 PMG
::PBSSchedule
::delete_schedule
($remote);
467 __PACKAGE__-
>register_method ({
468 name
=> 'list_timer',
469 path
=> '{remote}/timer',
471 description
=> "Get timer specification",
474 permissions
=> { check
=> [ 'admin', 'audit' ] },
476 additionalProperties
=> 0,
478 node
=> get_standard_option
('pve-node'),
480 description
=> "Proxmox Backup Server ID.",
481 type
=> 'string', format
=> 'pve-configid',
489 description
=> "Proxmox Backup Server remote ID.",
490 type
=> 'string', format
=> 'pve-configid',
494 description
=> "Schedule for the backup (OnCalendar setting of the systemd.timer)",
495 type
=> 'string', pattern
=> '[0-9a-zA-Z*.:,\-/ ]+',
496 default => 'daily', optional
=> 1,
499 description
=> "Randomized delay to add to the starttime (RandomizedDelaySec setting of the systemd.timer)",
500 type
=> 'string', pattern
=> '[0-9a-zA-Z. ]+',
501 default => '5min', optional
=> 1,
504 description
=> "unit file for the systemd.timer unit",
505 type
=> 'string', optional
=> 1,
512 my $remote = $param->{remote
};
514 my $schedules = PMG
::PBSSchedule
::get_schedules
($remote);
517 if (scalar(@$schedules) >= 1) {
518 $res = $schedules->[0];