]> git.proxmox.com Git - pmg-api.git/blob - src/PMG/PBSConfig.pm
ee506f1feda743a35aca0683d4bc4a622ed982d6
[pmg-api.git] / src / PMG / PBSConfig.pm
1 package PMG::PBSConfig;
2
3 # section config implementation for PBS integration in PMG
4
5 use strict;
6 use warnings;
7
8 use PVE::Tools qw(extract_param);
9 use PVE::SectionConfig;
10 use PVE::JSONSchema qw(get_standard_option);
11 use PVE::PBSClient;
12
13 use base qw(PVE::SectionConfig);
14
15 my $inotify_file_id = 'pmg-pbs.conf';
16 my $secret_dir = '/etc/pmg/pbs';
17 my $config_filename = "${secret_dir}/pbs.conf";
18
19 my %prune_option = (
20 optional => 1,
21 type => 'integer', minimum => '0',
22 format_description => 'N',
23 );
24
25 my %prune_properties = (
26 'keep-last' => {
27 %prune_option,
28 description => 'Keep the last <N> backups.',
29 },
30 'keep-hourly' => {
31 %prune_option,
32 description => 'Keep backups for the last <N> different hours. If there is'
33 .' more than one backup for a single hour, only the latest one is kept.'
34 },
35 'keep-daily' => {
36 %prune_option,
37 description => 'Keep backups for the last <N> different days. If there is'
38 .' more than one backup for a single day, only the latest one is kept.'
39 },
40 'keep-weekly' => {
41 %prune_option,
42 description => 'Keep backups for the last <N> different weeks. If there is'
43 .'more than one backup for a single week, only the latest one is kept.'
44 },
45 'keep-monthly' => {
46 %prune_option,
47 description => 'Keep backups for the last <N> different months. If there is'
48 .' more than one backup for a single month, only the latest one is kept.'
49 },
50 'keep-yearly' => {
51 %prune_option,
52 description => 'Keep backups for the last <N> different years. If there is'
53 .' more than one backup for a single year, only the latest one is kept.'
54 },
55 );
56
57 my $defaultData = {
58 propertyList => {
59 type => { description => "Section type." },
60 remote => {
61 description => "Proxmox Backup Server ID.",
62 type => 'string', format => 'pve-configid',
63 },
64 },
65 };
66
67 my $SAFE_ID_RE = '(?:[A-Za-z0-9_][A-Za-z0-9._\-]*)';
68 my $NS_RE = "(?:${SAFE_ID_RE}/){0,7}(?:${SAFE_ID_RE})?";
69
70 sub properties {
71 return {
72 datastore => {
73 description => "Proxmox Backup Server datastore name.",
74 pattern => $SAFE_ID_RE,
75 type => 'string',
76 },
77 namespace => {
78 type => 'string',
79 description => "Proxmox Backup Server namespace in the datastore, defaults to the root NS.",
80 pattern => $NS_RE,
81 maxLength => 256,
82 },
83 server => {
84 description => "Proxmox Backup Server address.",
85 type => 'string', format => 'address',
86 maxLength => 256,
87 },
88 disable => {
89 description => "Flag to disable (deactivate) the entry.",
90 type => 'boolean',
91 optional => 1,
92 },
93 password => {
94 description => "Password or API token secret for the user on the"
95 ." Proxmox Backup Server.",
96 type => 'string',
97 optional => 1,
98 },
99 username => get_standard_option('pmg-email-address', {
100 description => "Username or API token ID on the Proxmox Backup Server"
101 }),
102 fingerprint => get_standard_option('fingerprint-sha256'),
103 notify => {
104 description => "Specify when to notify via e-mail",
105 type => 'string',
106 enum => [ 'always', 'error', 'never' ],
107 optional => 1,
108 },
109 'include-statistics' => {
110 description => "Include statistics in scheduled backups",
111 type => 'boolean',
112 optional => 1,
113 },
114 %prune_properties,
115 };
116 }
117
118 sub options {
119 return {
120 server => {},
121 datastore => {},
122 namespace => { optional => 1 },
123 disable => { optional => 1 },
124 username => { optional => 1 },
125 password => { optional => 1 },
126 fingerprint => { optional => 1 },
127 notify => { optional => 1 },
128 'include-statistics' => { optional => 1 },
129 'keep-last' => { optional => 1 },
130 'keep-hourly' => { optional => 1 },
131 'keep-daily' => { optional => 1 },
132 'keep-weekly' => { optional => 1 },
133 'keep-monthly' => { optional => 1 },
134 'keep-yearly' => { optional => 1 },
135 };
136 }
137
138 sub type {
139 return 'pbs';
140 }
141
142 sub private {
143 return $defaultData;
144 }
145
146 sub prune_options {
147 my ($self, $remote) = @_;
148
149 my $remote_cfg = $self->{ids}->{$remote};
150
151 my $res = {};
152 my $pruning_setup;
153 foreach my $keep_opt (keys %prune_properties) {
154 if (defined($remote_cfg->{$keep_opt})) {
155 $pruning_setup = 1;
156 $res->{$keep_opt} = $remote_cfg->{$keep_opt};
157 }
158 }
159 return $pruning_setup ? $res : undef;
160 }
161
162 sub new {
163 my ($type) = @_;
164
165 my $class = ref($type) || $type;
166
167 my $cfg = PVE::INotify::read_file($inotify_file_id);
168
169 $cfg->{secret_dir} = $secret_dir;
170
171 return bless $cfg, $class;
172 }
173
174 sub write {
175 my ($self) = @_;
176
177 PVE::INotify::write_file($inotify_file_id, $self);
178 }
179
180 sub lock_config {
181 my ($code, $errmsg) = @_;
182
183 my $lockfile = "/var/lock/pmgpbsconfig.lck";
184
185 my $p = PVE::Tools::lock_file($lockfile, undef, $code);
186 if (my $err = $@) {
187 $errmsg ? die "$errmsg: $err" : die $err;
188 }
189 }
190
191 __PACKAGE__->register();
192 __PACKAGE__->init();
193
194 sub read_pmg_pbs_conf {
195 my ($filename, $fh) = @_;
196
197 my $raw = defined($fh) ? do { local $/ = undef; <$fh> } : '';
198
199 return __PACKAGE__->parse_config($filename, $raw);
200 }
201
202 sub write_pmg_pbs_conf {
203 my ($filename, $fh, $cfg) = @_;
204
205 my $raw = __PACKAGE__->write_config($filename, $cfg);
206
207 PVE::Tools::safe_print($filename, $fh, $raw);
208 }
209
210 PVE::INotify::register_file(
211 $inotify_file_id,
212 $config_filename,
213 \&read_pmg_pbs_conf,
214 \&write_pmg_pbs_conf,
215 undef,
216 always_call_parser => 1
217 );
218
219 1;