[pve-devel] applied-series: [PATCH stable-7 container 0/2] setup: cherry-pick ubuntu 24.04 support
Am 04/06/2024 um 10:34 schrieb Christoph Heiss: > This backports the series to support Ubuntu 24.04 "Noble" CTs [0]. > > They could be cherry-picked cleanly. Tested on a up-to-date PVE 7.4 > system (running on `pvetest`), template for Ubuntu 24.04 > (`ubuntu-24.04-standard_24.04-2_amd64.tar.zst`) was copied from a 8.2 > host for testing. > > Tested creating new CT from that template, using either a static IP or > DHCP. Then working around with the system a bit, everything seems to > work just fine. > > [0] https://lists.proxmox.com/pipermail/pve-devel/2024-April/063766.html > > Fiona Ebner (2): > setup: support Ubuntu 24.04 Noble > setup: unlink default netplan configuration even with Ubuntu >= 23.04 > > src/PVE/LXC/Setup/Ubuntu.pm | 3 +++ > 1 file changed, 3 insertions(+) > applied, thanks! ___ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH v1 pve-common 1/3] section config: document package and its methods with POD
Apart from the obvious benefits that documentation has, this also allows LSPs to provide docstrings e.g. via 'textDocument/hover' [0]. Tested with Perl Navigator [1]. [0]: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_hover [1]: https://github.com/bscan/PerlNavigator Signed-off-by: Max Carrara --- src/PVE/SectionConfig.pm | 737 +++ 1 file changed, 672 insertions(+), 65 deletions(-) diff --git a/src/PVE/SectionConfig.pm b/src/PVE/SectionConfig.pm index a18e9d8..99ee348 100644 --- a/src/PVE/SectionConfig.pm +++ b/src/PVE/SectionConfig.pm @@ -10,65 +10,102 @@ use PVE::Exception qw(raise_param_exc); use PVE::JSONSchema qw(get_standard_option); use PVE::Tools; -# This package provides a way to have multiple (often similar) types of entries -# in the same config file, each in its own section, thus "Section Config". -# -# The intended structure is to have a single 'base' plugin that inherits from -# this class and provides meaningful defaults in its '$defaultData', e.g. a -# default list of the core properties in its propertyList (most often only 'id' -# and 'type') -# -# Each 'real' plugin then has it's own package that should inherit from the -# 'base' plugin and returns it's specific properties in the 'properties' method, -# its type in the 'type' method and all the known options, from both parent and -# itself, in the 'options' method. -# The options method can also be used to define if a property is 'optional' or -# 'fixed' (only settable on config entity-creation), for example: -# -# -# sub options { -# return { -# 'some-optional-property' => { optional => 1 }, -# 'a-fixed-property' => { fixed => 1 }, -# 'a-required-but-not-fixed-property' => {}, -# }; -# } -# ``` -# -# 'fixed' options can be set on create, but not changed afterwards. -# -# To actually use it, you have to first register all the plugins and then init -# the 'base' plugin, like so: -# -# ``` -# use PVE::Dummy::Plugin1; -# use PVE::Dummy::Plugin2; -# use PVE::Dummy::BasePlugin; -# -# PVE::Dummy::Plugin1->register(); -# PVE::Dummy::Plugin2->register(); -# PVE::Dummy::BasePlugin->init(); -# ``` -# -# There are two modes for how properties are exposed, the default 'unified' -# mode and the 'isolated' mode. -# In the default unified mode, there is only a global list of properties -# which the plugins can use, so you cannot define the same property name twice -# in different plugins. The reason for this is to force the use of identical -# properties for multiple plugins. -# -# The second way is to use the 'isolated' mode, which can be achieved by -# calling init with `1` as its parameter like this: -# -# ``` -# PVE::Dummy::BasePlugin->init(property_isolation => 1); -# ``` -# -# With this, each plugin get's their own isolated list of properties which it -# can use. Note that in this mode, you only have to specify the property in the -# options method when it is either 'fixed' or comes from the global list of -# properties. All locally defined ones get automatically added to the schema -# for that plugin. +=pod + +=head1 NAME + +SectionConfig + +=head1 DESCRIPTION + +This package provides a way to have multiple (often similar) types of entries +in the same config file, each in its own section, thus I. + +Under the hood, this package automatically creates and manages a matching +I for one's plugin architecture that is used to represent data +that is read from and written to the config file. + +Where this config file is located, as well as its permissions and other related +things, is up to the plugin author and is not handled by C +at all. + +=head1 USAGE + +The intended structure is to have a single I that inherits from +this class and provides meaningful defaults in its C<$defaultData>, such as a +default list of core C I. The I is +thus very similar to an I. + +Each I is then defined in its own package that should inherit +from the I and defines which I it itself provides and +uses, as well as which I it uses from the I. + +The methods that need to be implemented are annotated in the L section +below. + + ┌─┐ + │ SectionConfig │ + └┬┘ + │ + │ + │ + ┌▼┐ + │BasePlugin │ + └┬┘ + │ + ┌─┴─┐ + │ │ +┌▼┐ ┌▼┐ +│ConcretePluginFoo│ │ConcretePluginBar│ +└─┘ └─┘ + +=head2 REGISTERING PLUGINS + +In order to actually be able to use plugins, they must first be I +and then I via the "base" plugin: + +u
[pve-devel] [PATCH v1 pve-common 3/3] section config: clean up parser logic
In order to make the parser somewhat more maintainable in the future, this commit cleans up its logic and makes its control flow easier to follow. Signed-off-by: Max Carrara --- src/PVE/SectionConfig.pm | 189 --- 1 file changed, 98 insertions(+), 91 deletions(-) diff --git a/src/PVE/SectionConfig.pm b/src/PVE/SectionConfig.pm index a6b0183..30faaa4 100644 --- a/src/PVE/SectionConfig.pm +++ b/src/PVE/SectionConfig.pm @@ -1014,25 +1014,26 @@ The error. sub parse_config { my ($class, $filename, $raw, $allow_unknown) = @_; -my $pdata = $class->private(); +if (!defined($raw)) { + return { + ids => {}, + order => {}, + digest => Digest::SHA::sha1_hex(''), + }; +} + +my $re_begins_with_comment = qr/^\s*#/; +my $re_kv_pair = qr/^\s+ (\S+) (\s+ (.*\S) )? \s*$/x; my $ids = {}; my $order = {}; - -$raw = '' if !defined($raw); - my $digest = Digest::SHA::sha1_hex($raw); -my $pri = 1; +my $current_order = 1; +my $line_no = 0; -my $lineno = 0; my @lines = split(/\n/, $raw); -my $nextline = sub { - while (defined(my $line = shift @lines)) { - $lineno++; - return $line if ($line !~ /^\s*#/); - } -}; +my @errors; my $is_array = sub { my ($type, $key) = @_; @@ -1043,106 +1044,112 @@ sub parse_config { return $schema->{type} eq 'array'; }; -my $errors = []; -while (@lines) { - my $line = $nextline->(); +my $get_next_line = sub { + while (scalar(@lines)) { + my $line = shift(@lines); + $line_no++; + + next if ($line =~ m/$re_begins_with_comment/); + + return $line; + } + + return undef; +}; + +my $skip_to_next_empty_line = sub { + while ($get_next_line->() ne '') {} +}; + +while (defined(my $line = $get_next_line->())) { next if !$line; - my $errprefix = "file $filename line $lineno"; + my $errprefix = "file $filename line $line_no"; - my ($type, $sectionId, $errmsg, $config) = $class->parse_section_header($line); - if ($config) { - my $skip = 0; - my $unknown = 0; + my ($type, $section_id, $errmsg, $config) = $class->parse_section_header($line); - my $plugin; + if (!defined($config)) { + warn "$errprefix - ignore config line: $line\n"; + next; + } - if ($errmsg) { - $skip = 1; - chomp $errmsg; - warn "$errprefix (skip section '$sectionId'): $errmsg\n"; - } elsif (!$type) { - $skip = 1; - warn "$errprefix (skip section '$sectionId'): missing type - internal error\n"; - } else { - if (!($plugin = $pdata->{plugins}->{$type})) { - if ($allow_unknown) { - $unknown = 1; - } else { - $skip = 1; - warn "$errprefix (skip section '$sectionId'): unsupported type '$type'\n"; - } - } - } + if ($errmsg) { + chomp $errmsg; + warn "$errprefix (skip section '$section_id'): $errmsg\n"; + $skip_to_next_empty_line->(); + next; + } + + if (!$type) { + warn "$errprefix (skip section '$section_id'): missing type - internal error\n"; + $skip_to_next_empty_line->(); + next; + } + + my $plugin = eval { $class->lookup($type) }; + my $is_unknown_type = defined($@) && $@ ne ''; + + if ($is_unknown_type && !$allow_unknown) { + warn "$errprefix (skip section '$section_id'): unsupported type '$type'\n"; + $skip_to_next_empty_line->(); + next; + } + + # Parse kv-pairs of section - will go on until empty line is encountered + while (my $section_line = $get_next_line->()) { + if ($section_line =~ m/$re_kv_pair/) { + my ($key, $value) = ($1, $3); - while ($line = $nextline->()) { - next if $skip; - - $errprefix = "file $filename line $lineno"; - - if ($line =~ m/^\s+(\S+)(\s+(.*\S))?\s*$/) { - my ($k, $v) = ($1, $3); - - eval { - if ($unknown) { - if (!defined($config->{$k})) { - $config->{$k} = $v; - } else { - if (!ref($config->{$k})) { - $config->{$k} = [$config->{$k}]; - } - push $config->{$k}->@*, $v; - } - } elsif ($is_array->($type, $k)) { - $v = $plugin->check_value($type, $k, $v, $sectionId); -
[pve-devel] [PATCH v1 pve-common 0/3] Section Config: Documentation & Code Cleanup
Section Config: Documentation & Code Cleanup The main focus of this series is the comprehensive documentation which is added in patch 01. While not every single quirk and implementation detail may be covered, it should be decent enough to help developers quickly get started with writing their own Section Config plugin architecture. The docs are written in POD - not necessarily because it is a convenient format to write documentation in, but rather because the entire Perl ecosystem uses it. No need to reinvent the wheel. Furthermore, POD is supported by LSPs (at least Perl Navigator), which means that the "docstrings" for Section Config methods will actually show up as inlay hints. Patch 02 updates the module's code style to be more in line with our Perl Style Guide [0]. Patch 03 cleans up the Section Config parser's internal logic and makes its control flow easier to follow. Note that this patch does *not* mean to change the parsing behaviour in any way, as that would risk accidentally breaking existing Section Config plugin architectures or config APIs. Testing --- Even though the existing unit tests pass, it would be nice if someone could give this series a spin and tried to change or add various config settings, e.g. storage settings and SDN settings, to make sure that the updated parser logic really does behave the same as before. Generating Docs --- If you prefer to read the added docs in a different format, you may use `perldoc` to render e.g. a webpage of the module's docs instead: $ perldoc -ohtml src/PVE/SectionConfig.pm > docs.html $ firefox docs.html Summary of Changes -- Max Carrara (3): section config: document package and its methods with POD section config: update code style section config: clean up parser logic src/PVE/SectionConfig.pm | 982 +++ 1 file changed, 798 insertions(+), 184 deletions(-) -- 2.39.2 ___ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH v1 pve-common 2/3] section config: update code style
Replace `foreach` with `for` and use postfix deref instead of block (circumfix) dereference (`$foo->%*` instead of `%$foo`). Furthermore, make `format_config_line` a private sub instead of unnecessarily declaring it as an anonymous subroutine, which avoids the `&$sub_ref(...)` syntax altogether. Signed-off-by: Max Carrara --- src/PVE/SectionConfig.pm | 62 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/PVE/SectionConfig.pm b/src/PVE/SectionConfig.pm index 99ee348..a6b0183 100644 --- a/src/PVE/SectionConfig.pm +++ b/src/PVE/SectionConfig.pm @@ -422,7 +422,7 @@ sub createSchema { my $props = $base || {}; if (!$class->has_isolated_properties()) { - foreach my $p (keys %$propertyList) { + for my $p (keys $propertyList->%*) { next if $skip_type && $p eq 'type'; if (!$propertyList->{$p}->{optional}) { @@ -435,7 +435,7 @@ sub createSchema { my $copts = $class->options(); $required = 0 if defined($copts->{$p}) && $copts->{$p}->{optional}; - foreach my $t (keys %$plugins) { + for my $t (keys $plugins->%*) { my $opts = $pdata->{options}->{$t} || {}; $required = 0 if !defined($opts->{$p}) || $opts->{$p}->{optional}; } @@ -450,7 +450,7 @@ sub createSchema { } } } else { - for my $type (sort keys %$plugins) { + for my $type (sort keys $plugins->%*) { my $opts = $pdata->{options}->{$type} || {}; for my $key (sort keys $opts->%*) { my $schema = $class->get_property_schema($type, $key); @@ -510,7 +510,7 @@ sub updateSchema { my $filter_type = $single_class ? $class->type() : undef; if (!$class->has_isolated_properties()) { - foreach my $p (keys %$propertyList) { + for my $p (keys $propertyList->%*) { next if $p eq 'type'; my $copts = $class->options(); @@ -526,7 +526,7 @@ sub updateSchema { $modifyable = 1 if defined($copts->{$p}) && !$copts->{$p}->{fixed}; - foreach my $t (keys %$plugins) { + for my $t (keys $plugins->%*) { my $opts = $pdata->{options}->{$t} || {}; next if !defined($opts->{$p}); $modifyable = 1 if !$opts->{$p}->{fixed}; @@ -536,7 +536,7 @@ sub updateSchema { $props->{$p} = $propertyList->{$p}; } } else { - for my $type (sort keys %$plugins) { + for my $type (sort keys $plugins->%*) { my $opts = $pdata->{options}->{$type} || {}; for my $key (sort keys $opts->%*) { next if $opts->{$key}->{fixed}; @@ -605,7 +605,7 @@ sub init { my $pdata = $class->private(); -foreach my $k (qw(options plugins plugindata propertyList isolatedPropertyList)) { +for my $k (qw(options plugins plugindata propertyList isolatedPropertyList)) { $pdata->{$k} = {} if !$pdata->{$k}; } @@ -613,9 +613,9 @@ sub init { my $propertyList = $pdata->{propertyList}; my $isolatedPropertyList = $pdata->{isolatedPropertyList}; -foreach my $type (keys %$plugins) { +for my $type (keys $plugins->%*) { my $props = $plugins->{$type}->properties(); - foreach my $p (keys %$props) { + for my $p (keys $props->%*) { my $res; if ($property_isolation) { $res = $isolatedPropertyList->{$type}->{$p} = {}; @@ -624,16 +624,16 @@ sub init { $res = $propertyList->{$p} = {}; } my $data = $props->{$p}; - for my $a (keys %$data) { + for my $a (keys $data->%*) { $res->{$a} = $data->{$a}; } $res->{optional} = 1; } } -foreach my $type (keys %$plugins) { +for my $type (keys $plugins->%*) { my $opts = $plugins->{$type}->options(); - foreach my $p (keys %$opts) { + for my $p (keys $opts->%*) { my $prop; if ($property_isolation) { $prop = $isolatedPropertyList->{$type}->{$p}; @@ -644,7 +644,7 @@ sub init { # automatically the properties to options (if not specified explicitly) if ($property_isolation) { - foreach my $p (keys $isolatedPropertyList->{$type}->%*) { + for my $p (keys $isolatedPropertyList->{$type}->%*) { next if $opts->{$p}; $opts->{$p} = {}; $opts->{$p}->{optional} = 1 if $isolatedPropertyList->{$type}->{$p}->{optional}; @@ -655,7 +655,7 @@ sub init { } $propertyList->{type}->{type} = 'string'; -$propertyList->{type}->{enum} = [sort keys %$plugins]; +$propertyList->{type}->{enum} = [sort keys $plugins->%*]; } =pod @@ -796,7 +796,7 @@ sub check_value { } PVE::JSONSchema::check_prop($value, $checkschema, '', $errors); - if (scalar(keys %$errors)) { +
[pve-devel] applied-series: [PATCH many v3 0/8] notifications: move template strings to template files
applied series & bumped packages, thanks ___ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH stable-7 container 2/2] setup: unlink default netplan configuration even with Ubuntu >= 23.04
From: Fiona Ebner It seems like commit 02d9462 ("setup: enable systemd-networkd via preset for ubuntu 23.04+") also resulted in the default netplan configuration no longer being unlinked. That should still happen, even if systemd-networkd is now enabled via preset. Otherwise, the network configuration created by Proxmox VE is not ordered before the one generated by netplan and thus not applied by systemd-networkd. Reported in the community forum: https://forum.proxmox.com/threads/145848/post-658058 Fixes: 02d9462 ("setup: enable systemd-networkd via preset for ubuntu 23.04+") Signed-off-by: Fiona Ebner (cherry picked from commit dfcbad017361d4e3ded20af573fbaeacc05231eb) Signed-off-by: Christoph Heiss --- src/PVE/LXC/Setup/Ubuntu.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/PVE/LXC/Setup/Ubuntu.pm b/src/PVE/LXC/Setup/Ubuntu.pm index cea8ef5..897eab9 100644 --- a/src/PVE/LXC/Setup/Ubuntu.pm +++ b/src/PVE/LXC/Setup/Ubuntu.pm @@ -73,7 +73,9 @@ sub template_fixup { '/etc/systemd/system/multi-user.target.wants/systemd-networkd.service'); $self->ct_symlink('/lib/systemd/system/systemd-networkd.socket', '/etc/systemd/system/socket.target.wants/systemd-networkd.socket'); +} +if ($version >= '17.10') { # unlink default netplan lxc config $self->ct_unlink('/etc/netplan/10-lxc.yaml'); } -- 2.44.1 ___ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH stable-7 container 0/2] setup: cherry-pick ubuntu 24.04 support
This backports the series to support Ubuntu 24.04 "Noble" CTs [0]. They could be cherry-picked cleanly. Tested on a up-to-date PVE 7.4 system (running on `pvetest`), template for Ubuntu 24.04 (`ubuntu-24.04-standard_24.04-2_amd64.tar.zst`) was copied from a 8.2 host for testing. Tested creating new CT from that template, using either a static IP or DHCP. Then working around with the system a bit, everything seems to work just fine. [0] https://lists.proxmox.com/pipermail/pve-devel/2024-April/063766.html Fiona Ebner (2): setup: support Ubuntu 24.04 Noble setup: unlink default netplan configuration even with Ubuntu >= 23.04 src/PVE/LXC/Setup/Ubuntu.pm | 3 +++ 1 file changed, 3 insertions(+) -- 2.44.1 ___ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH stable-7 container 1/2] setup: support Ubuntu 24.04 Noble
From: Fiona Ebner Minimally tested, that an upgrade from an existing 23.04 container works, there still is network and no obviously bad messages in the container's journal. Reported in the community forum: https://forum.proxmox.com/threads/145848/ Signed-off-by: Fiona Ebner (cherry picked from commit 3d800f832c25e4bf2435d88ab190fd8e681a67b1) Signed-off-by: Christoph Heiss --- src/PVE/LXC/Setup/Ubuntu.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PVE/LXC/Setup/Ubuntu.pm b/src/PVE/LXC/Setup/Ubuntu.pm index 905cacb..cea8ef5 100644 --- a/src/PVE/LXC/Setup/Ubuntu.pm +++ b/src/PVE/LXC/Setup/Ubuntu.pm @@ -12,6 +12,7 @@ use PVE::LXC::Setup::Debian; use base qw(PVE::LXC::Setup::Debian); my $known_versions = { +'24.04' => 1, # noble '23.10' => 1, # mantic '23.04' => 1, # lunar '22.10' => 1, # kinetic -- 2.44.1 ___ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel