]> git.proxmox.com Git - pve-common.git/blob - src/PVE/Job/Registry.pm
bump version to 8.2.1
[pve-common.git] / src / PVE / Job / Registry.pm
1 package PVE::Job::Registry;
2
3 use strict;
4 use warnings;
5
6 # The job (config) base class, normally you would use this in one of two variants:
7 #
8 # 1) base of directly in manager and handle everything there; great for stuff that isn't residing
9 # outside of the manager, so that there is no cyclic dependency (forbidden!) required
10 #
11 # 2) use two (or even more) classes, one in the library (e.g., guest-common, access-control, ...)
12 # basing off this module, providing the basic config implementation. Then one in pve-manager
13 # (where every dependency is available) basing off the intermediate config one, that then holds
14 # the implementation of the 'run` method and is used in the job manager
15
16 use base qw(PVE::SectionConfig);
17
18 my $defaultData = {
19 propertyList => {
20 type => { description => "Section type." },
21 # FIXME: remove below? this is the section ID, schema would only be checked if a plugin
22 # declares this as explicit option, which isn't really required as its available anyway..
23 id => {
24 description => "The ID of the job.",
25 type => 'string',
26 format => 'pve-configid',
27 maxLength => 64,
28 },
29 enabled => {
30 description => "Determines if the job is enabled.",
31 type => 'boolean',
32 default => 1,
33 optional => 1,
34 },
35 schedule => {
36 description => "Backup schedule. The format is a subset of `systemd` calendar events.",
37 type => 'string', format => 'pve-calendar-event',
38 maxLength => 128,
39 },
40 comment => {
41 optional => 1,
42 type => 'string',
43 description => "Description for the Job.",
44 maxLength => 512,
45 },
46 'repeat-missed' => {
47 optional => 1,
48 type => 'boolean',
49 description => "If true, the job will be run as soon as possible if it was missed".
50 " while the scheduler was not running.",
51 default => 0,
52 },
53 },
54 };
55
56 sub private {
57 return $defaultData;
58 }
59
60 sub parse_config {
61 my ($class, $filename, $raw, $allow_unknown) = @_;
62
63 my $cfg = $class->SUPER::parse_config($filename, $raw, $allow_unknown);
64
65 for my $id (keys %{$cfg->{ids}}) {
66 my $data = $cfg->{ids}->{$id};
67 my $type = $data->{type};
68
69 # FIXME: below id injection is gross, guard to avoid breaking plugins that don't declare id
70 # as option; *iff* we want this it should be handled by section config directly.
71 if ($defaultData->{options}->{$type} && exists $defaultData->{options}->{$type}->{id}) {
72 $data->{id} = $id;
73 }
74 $data->{enabled} //= 1;
75
76 $data->{comment} = PVE::Tools::decode_text($data->{comment}) if defined($data->{comment});
77 }
78
79 return $cfg;
80 }
81
82 # call the plugin specific decode/encode code
83 sub decode_value {
84 my ($class, $type, $key, $value) = @_;
85
86 my $plugin = __PACKAGE__->lookup($type);
87 return $plugin->decode_value($type, $key, $value);
88 }
89
90 sub encode_value {
91 my ($class, $type, $key, $value) = @_;
92
93 my $plugin = __PACKAGE__->lookup($type);
94 return $plugin->encode_value($type, $key, $value);
95 }
96
97 sub write_config {
98 my ($class, $filename, $cfg, $allow_unknown) = @_;
99
100 for my $job (values $cfg->{ids}->%*) {
101 $job->{comment} = PVE::Tools::encode_text($job->{comment}) if defined($job->{comment});
102 }
103
104 $class->SUPER::write_config($filename, $cfg, $allow_unknown);
105 }
106
107 sub run {
108 my ($class, $cfg) = @_;
109
110 die "not implemented"; # implement in subclass
111 }
112
113 1;