fix #7173: config: drop empty tag list when writing
When the last tag of a container gets removed, for example in the web UI, the API gets an empty 'tags' value, which then ends up as an empty 'tags:' line in the config and in the output of 'pct config'. As the config parser reads that line back as a single space, it also gets written out again on every following config change. Skip a tag list without any tag when writing the config, which also cleans up existing configs with such a line on their next change. Keep it in the pending section, where it is still needed for removing all tags with a pending change. Add a basic test for parsing and writing container configs, similar to the one in qemu-server, to cover this. Signed-off-by: Michal Fox <me@dualfroz.com>
This commit is contained in:
1 parent
8275178ff1
commit
96e2453797
6 files changed
+83
-3
No files matched your search
@@ -1243,7 +1243,7 @@ sub write_pct_config {
|
||||
}
|
||||
|
||||
my $generate_raw_config = sub {
|
||||
my ($conf) = @_;
|
||||
my ($conf, $pending) = @_;
|
||||
|
||||
my $raw = '';
|
||||
|
||||
@@ -1265,6 +1265,8 @@ sub write_pct_config {
|
||||
my $value = $conf->{$key};
|
||||
die "detected invalid newline or carriage return inside property '$key'\n"
|
||||
if $value =~ m/[\r\n]/;
|
||||
# an empty tag list is only needed as pending change for removing all tags
|
||||
next if $key eq 'tags' && !$pending && $value =~ m/^\s*$/;
|
||||
$raw .= "$key: $value\n";
|
||||
}
|
||||
|
||||
@@ -1293,7 +1295,7 @@ sub write_pct_config {
|
||||
|
||||
if (scalar(keys %{ $conf->{pending} })) {
|
||||
$raw .= "\n[pve:pending]\n";
|
||||
$raw .= &$generate_raw_config($conf->{pending});
|
||||
$raw .= &$generate_raw_config($conf->{pending}, 1);
|
||||
}
|
||||
|
||||
foreach my $snapname (sort keys %{ $conf->{snapshots} }) {
|
||||
|
||||
+4
-1
@@ -2,7 +2,7 @@ RUN_USERNS := lxc-usernsexec -m "u:0:`id -u`:1" -m "g:0:`id -g`:1" --
|
||||
|
||||
all: test
|
||||
|
||||
test: test_setup test_snapshot test_bindmount test_idmap
|
||||
test: test_setup test_snapshot test_bindmount test_idmap test_parse_config
|
||||
|
||||
test_setup: run_setup_tests.pl
|
||||
if test -e /run/lock/sbuild; then \
|
||||
@@ -24,5 +24,8 @@ test_bindmount: bindmount_test.pl
|
||||
test_idmap: run_idmap_tests.pl
|
||||
./run_idmap_tests.pl
|
||||
|
||||
test_parse_config: run_parse_config_tests.pl
|
||||
./run_parse_config_tests.pl
|
||||
|
||||
clean:
|
||||
rm -rf tmprootfs
|
||||
@@ -0,0 +1,8 @@
|
||||
# empty tag list
|
||||
arch: amd64
|
||||
cores: 1
|
||||
hostname: notags
|
||||
memory: 512
|
||||
ostype: debian
|
||||
rootfs: local-lvm:vm-8006-disk-0,size=8G
|
||||
unprivileged: 1
|
||||
@@ -0,0 +1,9 @@
|
||||
# empty tag list
|
||||
arch: amd64
|
||||
cores: 1
|
||||
hostname: notags
|
||||
memory: 512
|
||||
ostype: debian
|
||||
rootfs: local-lvm:vm-8006-disk-0,size=8G
|
||||
tags:
|
||||
unprivileged: 1
|
||||
@@ -0,0 +1,11 @@
|
||||
# plain container
|
||||
arch: amd64
|
||||
cores: 1
|
||||
hostname: plain
|
||||
memory: 512
|
||||
net0: name=eth0,bridge=vmbr0,hwaddr=BC:24:11:2C:69:EC,ip=dhcp,type=veth
|
||||
ostype: debian
|
||||
rootfs: local-lvm:vm-8006-disk-0,size=8G
|
||||
swap: 512
|
||||
tags: bar;foo
|
||||
unprivileged: 1
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Tests parsing and writing container configuration files.
|
||||
#
|
||||
# If no expected file exists, the input is assumed to be equal to the expected output.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use lib qw(..);
|
||||
|
||||
use Test::More;
|
||||
|
||||
use PVE::LXC::Config;
|
||||
use PVE::Tools;
|
||||
|
||||
my $INPUT_DIR = './parse-config-input';
|
||||
my $EXPECTED_DIR = './parse-config-expected';
|
||||
|
||||
PVE::Tools::dir_glob_foreach(
|
||||
$INPUT_DIR,
|
||||
'.*\.conf',
|
||||
sub {
|
||||
my ($file) = @_;
|
||||
|
||||
my $fake_config_fn = "$file/lxc/8006.conf";
|
||||
my $input = PVE::Tools::file_get_contents("${INPUT_DIR}/${file}");
|
||||
|
||||
my $output = eval {
|
||||
my $conf = PVE::LXC::Config::parse_pct_config($fake_config_fn, $input, 1);
|
||||
PVE::LXC::Config::write_pct_config($fake_config_fn, $conf);
|
||||
};
|
||||
if (my $err = $@) {
|
||||
note("got unexpected error '$err'");
|
||||
fail($file);
|
||||
return;
|
||||
}
|
||||
|
||||
my $expected_file = "${EXPECTED_DIR}/${file}";
|
||||
my $expected =
|
||||
-f $expected_file ? PVE::Tools::file_get_contents($expected_file) : $input;
|
||||
|
||||
is($output, $expected, $file);
|
||||
},
|
||||
);
|
||||
|
||||
done_testing();
|
||||
Reference in new issue
Block a user