Commit 16145cba authored by Thomas Lamprecht's avatar Thomas Lamprecht Committed by Dietmar Maurer

Use JSONSchema to parse vzdump config

Instead of a lot of hardcoded if's use JSONSchema::parse_config to
parse and validate vzdump.conf. To do that $confdesc was extended
to match a valid schema.
Signed-off-by: 's avatarThomas Lamprecht <t.lamprecht@proxmox.com>
parent 42cda896
...@@ -27,6 +27,147 @@ my $logdir = '/var/log/vzdump'; ...@@ -27,6 +27,147 @@ my $logdir = '/var/log/vzdump';
my @plugins = qw(); my @plugins = qw();
my $confdesc = {
vmid => {
type => 'string', format => 'pve-vmid-list',
description => "The ID of the VM you want to backup.",
optional => 1,
},
node => get_standard_option('pve-node', {
description => "Only run if executed on this node.",
optional => 1,
}),
all => {
type => 'boolean',
description => "Backup all known VMs on this host.",
optional => 1,
default => 0,
},
stdexcludes => {
type => 'boolean',
description => "Exclude temorary files and logs.",
optional => 1,
default => 1,
},
compress => {
type => 'string',
description => "Compress dump file.",
optional => 1,
enum => ['0', '1', 'gzip', 'lzo'],
default => 'lzo',
},
pigz=> {
type => "integer",
description => "Uses pigz instead of gzip when N>0.".
" N=1 uses half of cores, N>1 uses N as thread count.",
optional => 1,
default => 0,
},
quiet => {
type => 'boolean',
description => "Be quiet.",
optional => 1,
default => 0,
},
mode => {
type => 'string',
description => "Backup mode.",
optional => 1,
default => 'stop',
enum => [ 'snapshot', 'suspend', 'stop' ],
},
exclude => {
type => 'string', format => 'pve-vmid-list',
description => "exclude specified VMs (assumes --all)",
optional => 1,
},
'exclude-path' => {
type => 'string', format => 'string-alist',
description => "exclude certain files/directories (regex).",
optional => 1,
},
mailto => {
type => 'string', format => 'string-list',
description => "",
optional => 1,
},
mailnotification => {
type => 'string',
description => "Specify when to send an email",
optional => 1,
enum => [ 'always', 'failure' ],
default => 'always',
},
tmpdir => {
type => 'string',
description => "Store temporary files to specified directory.",
optional => 1,
},
dumpdir => {
type => 'string',
description => "Store resulting files to specified directory.",
optional => 1,
},
script => {
type => 'string',
description => "Use specified hook script.",
optional => 1,
},
storage => get_standard_option('pve-storage-id', {
description => "Store resulting file to this storage.",
optional => 1,
}),
stop => {
type => 'boolean',
description => "Stop runnig backup jobs on this host.",
optional => 1,
default => 0,
},
size => {
type => 'integer',
description => "LVM snapshot size in MB.",
optional => 1,
minimum => 500,
},
bwlimit => {
type => 'integer',
description => "Limit I/O bandwidth (KBytes per second).",
optional => 1,
minimum => 0,
},
ionice => {
type => 'integer',
description => "Set CFQ ionice priority.",
optional => 1,
minimum => 0,
maximum => 8,
},
lockwait => {
type => 'integer',
description => "Maximal time to wait for the global lock (minutes).",
optional => 1,
minimum => 0,
},
stopwait => {
type => 'integer',
description => "Maximal time to wait until a VM is stopped (minutes).",
optional => 1,
minimum => 0,
},
maxfiles => {
type => 'integer',
description => "Maximal number of backup files per VM.",
optional => 1,
minimum => 1,
},
remove => {
type => 'boolean',
description => "Remove old backup files if there are more than 'maxfiles' backup files.",
optional => 1,
default => 1,
},
};
# Load available plugins # Load available plugins
my @pve_vzdump_classes = qw(PVE::VZDump::QemuServer PVE::VZDump::LXC); my @pve_vzdump_classes = qw(PVE::VZDump::QemuServer PVE::VZDump::LXC);
foreach my $plug (@pve_vzdump_classes) { foreach my $plug (@pve_vzdump_classes) {
...@@ -181,7 +322,7 @@ sub read_vzdump_defaults { ...@@ -181,7 +322,7 @@ sub read_vzdump_defaults {
my $fn = "/etc/vzdump.conf"; my $fn = "/etc/vzdump.conf";
my $res = { my $defaults = {
bwlimit => 0, bwlimit => 0,
ionice => 7, ionice => 7,
size => 1024, size => 1024,
...@@ -192,48 +333,16 @@ sub read_vzdump_defaults { ...@@ -192,48 +333,16 @@ sub read_vzdump_defaults {
pigz => 0, pigz => 0,
}; };
my $fh = IO::File->new ("<$fn"); my $raw;
return $res if !$fh; eval { $raw = PVE::Tools::file_get_contents($fn); };
return $defaults if $@;
my $line;
while (defined ($line = <$fh>)) { my $conf_schema = { type => 'object', properties => $confdesc, };
next if $line =~ m/^\s*$/; my $res = PVE::JSONSchema::parse_config($conf_schema, $fn, $raw);
next if $line =~ m/^\#/;
if ($line =~ m/tmpdir:\s*(.*\S)\s*$/) {
$res->{tmpdir} = $1;
} elsif ($line =~ m/dumpdir:\s*(.*\S)\s*$/) {
$res->{dumpdir} = $1;
} elsif ($line =~ m/storage:\s*(\S+)\s*$/) {
$res->{storage} = $1;
} elsif ($line =~ m/script:\s*(.*\S)\s*$/) {
$res->{script} = $1;
} elsif ($line =~ m/bwlimit:\s*(\d+)\s*$/) {
$res->{bwlimit} = int($1);
} elsif ($line =~ m/ionice:\s*([0-8])\s*$/) {
$res->{ionice} = int($1);
} elsif ($line =~ m/lockwait:\s*(\d+)\s*$/) {
$res->{lockwait} = int($1);
} elsif ($line =~ m/stopwait:\s*(\d+)\s*$/) {
$res->{stopwait} = int($1);
} elsif ($line =~ m/stop:\s*(\d+)\s*$/) {
$res->{stop} = int($1);
} elsif ($line =~ m/size:\s*(\d+)\s*$/) {
$res->{size} = int($1);
} elsif ($line =~ m/maxfiles:\s*(\d+)\s*$/) {
$res->{maxfiles} = int($1);
} elsif ($line =~ m/exclude-path:\s*(.*)\s*$/) {
$res->{'exclude-path'} = PVE::Tools::split_args($1);
} elsif ($line =~ m/mode:\s*(stop|snapshot|suspend)\s*$/) {
$res->{mode} = $1;
} elsif($line =~ m/pigz:\s*(\d+)\s*/) {
$res->{pigz} = $1;
} else {
debugmsg ('warn', "unable to parse configuration file '$fn' - error at line " . $., undef, 1);
}
foreach my $key (keys %$defaults) {
$res->{$key} = $defaults->{$key} if !$res->{$key};
} }
close ($fh);
return $res; return $res;
} }
...@@ -1105,146 +1214,6 @@ sub exec_backup { ...@@ -1105,146 +1214,6 @@ sub exec_backup {
unlink $pidfile; unlink $pidfile;
} }
my $confdesc = {
vmid => {
type => 'string', format => 'pve-vmid-list',
description => "The ID of the VM you want to backup.",
optional => 1,
},
node => get_standard_option('pve-node', {
description => "Only run if executed on this node.",
optional => 1,
}),
all => {
type => 'boolean',
description => "Backup all known VMs on this host.",
optional => 1,
default => 0,
},
stdexcludes => {
type => 'boolean',
description => "Exclude temorary files and logs.",
optional => 1,
default => 1,
},
compress => {
type => 'string',
description => "Compress dump file.",
optional => 1,
enum => ['0', '1', 'gzip', 'lzo'],
default => 'lzo',
},
pigz=> {
type => "integer",
description => "Uses pigz instead of gzip when N>0.".
" N=1 uses half of cores, N>1 uses N as thread count.",
optional => 1,
default => 0,
},
quiet => {
type => 'boolean',
description => "Be quiet.",
optional => 1,
default => 0,
},
mode => {
type => 'string',
description => "Backup mode.",
optional => 1,
default => 'stop',
enum => [ 'snapshot', 'suspend', 'stop' ],
},
exclude => {
type => 'string', format => 'pve-vmid-list',
description => "exclude specified VMs (assumes --all)",
optional => 1,
},
'exclude-path' => {
type => 'string', format => 'string-alist',
description => "exclude certain files/directories (regex).",
optional => 1,
},
mailto => {
type => 'string', format => 'string-list',
description => "",
optional => 1,
},
mailnotification => {
type => 'string',
description => "Specify when to send an email",
optional => 1,
enum => [ 'always', 'failure' ],
default => 'always',
},
tmpdir => {
type => 'string',
description => "Store temporary files to specified directory.",
optional => 1,
},
dumpdir => {
type => 'string',
description => "Store resulting files to specified directory.",
optional => 1,
},
script => {
type => 'string',
description => "Use specified hook script.",
optional => 1,
},
storage => get_standard_option('pve-storage-id', {
description => "Store resulting file to this storage.",
optional => 1,
}),
stop => {
type => 'boolean',
description => "Stop runnig backup jobs on this host.",
optional => 1,
default => 0,
},
size => {
type => 'integer',
description => "LVM snapshot size in MB.",
optional => 1,
minimum => 500,
},
bwlimit => {
type => 'integer',
description => "Limit I/O bandwidth (KBytes per second).",
optional => 1,
minimum => 0,
},
ionice => {
type => 'integer',
description => "Set CFQ ionice priority.",
optional => 1,
minimum => 0,
maximum => 8,
},
lockwait => {
type => 'integer',
description => "Maximal time to wait for the global lock (minutes).",
optional => 1,
minimum => 0,
},
stopwait => {
type => 'integer',
description => "Maximal time to wait until a VM is stopped (minutes).",
optional => 1,
minimum => 0,
},
maxfiles => {
type => 'integer',
description => "Maximal number of backup files per VM.",
optional => 1,
minimum => 1,
},
remove => {
type => 'boolean',
description => "Remove old backup files if there are more than 'maxfiles' backup files.",
optional => 1,
default => 1,
},
};
sub option_exists { sub option_exists {
my $key = shift; my $key = shift;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment