]> git.proxmox.com Git - pve-guest-common.git/blob - PVE/VZDump/Plugin.pm
fix #1291: implement remove_vmid_from_backup_jobs
[pve-guest-common.git] / PVE / VZDump / Plugin.pm
1 package PVE::VZDump::Plugin;
2
3 use strict;
4 use warnings;
5
6 use POSIX qw(strftime);
7
8 use PVE::Tools;
9 use PVE::SafeSyslog;
10 use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
11 use PVE::VZDump::Common; # register parser/writer for vzdump.cron
12
13 my $log_level = {
14 err => 'ERROR:',
15 info => 'INFO:',
16 warn => 'WARN:',
17 };
18
19 sub debugmsg {
20 my ($mtype, $msg, $logfd, $syslog) = @_;
21
22 chomp $msg;
23
24 return if !$msg;
25
26 my $level = $log_level->{$mtype} ? $mtype : 'err';
27 my $pre = $log_level->{$level};
28
29 my $timestr = strftime ("%F %H:%M:%S", CORE::localtime);
30
31 syslog ($level, "$pre $msg") if $syslog;
32
33 foreach my $line (split (/\n/, $msg)) {
34 print STDERR "$pre $line\n";
35 print $logfd "$timestr $pre $line\n" if $logfd;
36 }
37 }
38
39 sub set_logfd {
40 my ($self, $logfd) = @_;
41
42 $self->{logfd} = $logfd;
43 }
44
45 sub cmd {
46 my ($self, $cmdstr, %param) = @_;
47
48 my $logfunc = sub {
49 my $line = shift;
50 debugmsg ('info', $line, $self->{logfd});
51 };
52
53 PVE::Tools::run_command($cmdstr, %param, logfunc => $logfunc);
54 }
55
56 sub cmd_noerr {
57 my ($self, $cmdstr, %param) = @_;
58
59 my $res;
60 eval { $res = $self->cmd($cmdstr, %param); };
61 $self->logerr ($@) if $@;
62 return $res;
63 }
64
65 sub log {
66 my ($self, $level, $msg, $to_syslog) = @_;
67
68 debugmsg($level, $msg, $self->{logfd}, $to_syslog);
69 }
70
71 sub loginfo {
72 my ($self, $msg) = @_;
73
74 debugmsg('info', $msg, $self->{logfd}, 0);
75 }
76
77 sub logerr {
78 my ($self, $msg) = @_;
79
80 debugmsg('err', $msg, $self->{logfd}, 0);
81 }
82
83 sub type {
84 return 'unknown';
85 };
86
87 sub vmlist {
88 my ($self) = @_;
89
90 return [ keys %{$self->{vmlist}} ] if $self->{vmlist};
91
92 return [];
93 }
94
95 sub vm_status {
96 my ($self, $vmid) = @_;
97
98 die "internal error"; # implement in subclass
99 }
100
101 sub prepare {
102 my ($self, $task, $vmid, $mode) = @_;
103
104 die "internal error"; # implement in subclass
105 }
106
107 sub lock_vm {
108 my ($self, $vmid) = @_;
109
110 die "internal error"; # implement in subclass
111 }
112
113 sub unlock_vm {
114 my ($self, $vmid) = @_;
115
116 die "internal error"; # implement in subclass
117 }
118
119 sub stop_vm {
120 my ($self, $task, $vmid) = @_;
121
122 die "internal error"; # implement in subclass
123 }
124
125 sub start_vm {
126 my ($self, $task, $vmid) = @_;
127
128 die "internal error"; # implement in subclass
129 }
130
131 sub suspend_vm {
132 my ($self, $task, $vmid) = @_;
133
134 die "internal error"; # implement in subclass
135 }
136
137 sub resume_vm {
138 my ($self, $task, $vmid) = @_;
139
140 die "internal error"; # implement in subclass
141 }
142
143 sub snapshot {
144 my ($self, $task, $vmid) = @_;
145
146 die "internal error"; # implement in subclass
147 }
148
149 sub copy_data_phase2 {
150 my ($self, $task, $vmid) = @_;
151
152 die "internal error"; # implement in subclass
153 }
154
155 sub assemble {
156 my ($self, $task, $vmid) = @_;
157
158 die "internal error"; # implement in subclass
159 }
160
161 sub archive {
162 my ($self, $task, $vmid, $filename, $comp) = @_;
163
164 die "internal error"; # implement in subclass
165 }
166
167 sub cleanup {
168 my ($self, $task, $vmid) = @_;
169
170 die "internal error"; # implement in subclass
171 }
172
173 sub remove_vmid_from_list {
174 my ($list, $rm_vmid) = @_;
175 # this removes the given vmid from the list, if present
176 return join(',', grep { $_ ne $rm_vmid } PVE::Tools::split_list($list));
177 }
178
179 sub remove_vmid_from_jobs {
180 my ($jobs, $exclude_vmid) = @_;
181
182 my $updated_jobs = [];
183 foreach my $job (@$jobs) {
184 if (defined $job->{vmid}) {
185 my $list = remove_vmid_from_list($job->{vmid}, $exclude_vmid);
186 if ($list) {
187 $job->{vmid} = $list;
188 push @$updated_jobs, $job;
189 }
190 } elsif (defined $job->{exclude}) {
191 my $list = remove_vmid_from_list($job->{exclude}, $exclude_vmid);
192 if ($list) {
193 $job->{exclude} = $list;
194 } else {
195 delete $job->{exclude};
196 }
197 push @$updated_jobs, $job;
198 } else {
199 push @$updated_jobs, $job;
200 }
201 }
202 return $updated_jobs;
203 }
204
205 sub remove_vmid_from_backup_jobs {
206 my ($vmid) = @_;
207
208 cfs_lock_file('vzdump.cron', undef, sub {
209 my $vzdump_jobs = cfs_read_file('vzdump.cron');
210 my $jobs = $vzdump_jobs->{jobs} || [];
211 $vzdump_jobs->{jobs} = remove_vmid_from_jobs($jobs, $vmid);
212 cfs_write_file('vzdump.cron', $vzdump_jobs);
213 });
214 die "$@" if ($@);
215 }
216
217 1;