* [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters
2025-02-10 12:07 [pve-devel] [PATCH 0/8 container/manager/docs] fix #4686: Cloudinit support for LXC Daniel Herzig
@ 2025-02-10 12:07 ` Daniel Herzig
2025-02-13 10:10 ` Fiona Ebner
` (2 more replies)
2025-02-10 12:07 ` [pve-devel] [PATCH 2/8 container] cloudinit: basic implementation Daniel Herzig
` (6 subsequent siblings)
7 siblings, 3 replies; 23+ messages in thread
From: Daniel Herzig @ 2025-02-10 12:07 UTC (permalink / raw)
To: pve-devel; +Cc: Leo Nunner
From: Leo Nunner <l.nunner@proxmox.com>
Introduce configuration parameters for cloud-init. Like with VMs, it's
possible to specify:
- user
- password
- ssh keys
- enable/disable updates on first boot
It's also possible to pass through custom config files for the user and
vendor settings. We don't allow configuring the network through
cloud-init, since it will clash with whatever configuration we already
did for the container.
Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
---
src/PVE/API2/LXC.pm | 3 ++
src/PVE/API2/LXC/Config.pm | 7 ++++-
src/PVE/LXC/Config.pm | 61 ++++++++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index 7cb5122..d6e647d 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -2515,6 +2515,9 @@ __PACKAGE__->register_method({
my $pending_delete_hash = PVE::LXC::Config->parse_pending_delete($conf->{pending}->{delete});
+ $conf->{cipassword} = '**********' if defined($conf->{cipassword});
+ $conf->{pending}->{cipassword} = '********** ' if defined($conf->{pending}->{cipassword});
+
return PVE::GuestHelpers::config_with_pending_array($conf, $pending_delete_hash);
}});
diff --git a/src/PVE/API2/LXC/Config.pm b/src/PVE/API2/LXC/Config.pm
index 5cbc014..55e9730 100644
--- a/src/PVE/API2/LXC/Config.pm
+++ b/src/PVE/API2/LXC/Config.pm
@@ -79,7 +79,7 @@ __PACKAGE__->register_method({
} else {
$conf = PVE::LXC::Config->load_current_config($param->{vmid}, $param->{current});
}
-
+ $conf->{cipassword} = '**********' if $conf->{cipassword};
return $conf;
}});
@@ -148,6 +148,11 @@ __PACKAGE__->register_method({
$param->{cpuunits} = PVE::CGroup::clamp_cpu_shares($param->{cpuunits})
if defined($param->{cpuunits}); # clamp value depending on cgroup version
+ if (defined(my $cipassword = $param->{cipassword})) {
+ $param->{cipassword} = PVE::Tools::encrypt_pw($cipassword)
+ if $cipassword !~ /^\$(?:[156]|2[ay])(\$.+){2}/;
+ }
+
my $code = sub {
my $conf = PVE::LXC::Config->load_config($vmid);
diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
index 5cc37f7..e3ed93b 100644
--- a/src/PVE/LXC/Config.pm
+++ b/src/PVE/LXC/Config.pm
@@ -450,6 +450,63 @@ my $features_desc = {
},
};
+my $cicustom_fmt = {
+ user => {
+ type => 'string',
+ optional => 1,
+ description => 'To pass a custom file containing all user data to the container via cloud-init.',
+ format => 'pve-volume-id',
+ format_description => 'volume',
+ },
+ vendor => {
+ type => 'string',
+ optional => 1,
+ description => 'To pass a custom file containing all vendor data to the container via cloud-init.',
+ format => 'pve-volume-id',
+ format_description => 'volume',
+ },
+};
+PVE::JSONSchema::register_format('pve-pct-cicustom', $cicustom_fmt);
+
+my $confdesc_cloudinit = {
+ cienable => {
+ optional => 1,
+ type => 'boolean',
+ description => "cloud-init: provide cloud-init configuration to container.",
+ },
+ ciuser => {
+ optional => 1,
+ type => 'string',
+ description => "cloud-init: User name to change ssh keys and password for instead of the"
+ ." image's configured default user.",
+ },
+ cipassword => {
+ optional => 1,
+ type => 'string',
+ description => 'cloud-init: Password to assign the user. Using this is generally not'
+ .' recommended. Use ssh keys instead. Also note that older cloud-init versions do not'
+ .' support hashed passwords.',
+ },
+ ciupgrade => {
+ optional => 1,
+ type => 'boolean',
+ description => 'cloud-init: do an automatic package update on boot.'
+ },
+ cicustom => {
+ optional => 1,
+ type => 'string',
+ description => 'cloud-init: Specify custom files to replace the automatically generated'
+ .' ones at start.',
+ format => 'pve-pct-cicustom',
+ },
+ sshkeys => {
+ optional => 1,
+ type => 'string',
+ format => 'urlencoded',
+ description => "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).",
+ },
+};
+
my $confdesc = {
lock => {
optional => 1,
@@ -622,6 +679,10 @@ my $confdesc = {
},
};
+foreach my $key (keys %$confdesc_cloudinit) {
+ $confdesc->{$key} = $confdesc_cloudinit->{$key};
+}
+
my $valid_lxc_conf_keys = {
'lxc.apparmor.profile' => 1,
'lxc.apparmor.allow_incomplete' => 1,
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters
2025-02-10 12:07 ` [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters Daniel Herzig
@ 2025-02-13 10:10 ` Fiona Ebner
2025-02-13 10:18 ` Mira Limbeck
2025-02-13 10:23 ` Fiona Ebner
2025-02-13 12:15 ` Fiona Ebner
2 siblings, 1 reply; 23+ messages in thread
From: Fiona Ebner @ 2025-02-13 10:10 UTC (permalink / raw)
To: Proxmox VE development discussion, Daniel Herzig
Am 10.02.25 um 13:07 schrieb Daniel Herzig:
> From: Leo Nunner <l.nunner@proxmox.com>
>
> Introduce configuration parameters for cloud-init. Like with VMs, it's
> possible to specify:
> - user
> - password
> - ssh keys
> - enable/disable updates on first boot
>
> It's also possible to pass through custom config files for the user and
> vendor settings. We don't allow configuring the network through
> cloud-init, since it will clash with whatever configuration we already
> did for the container.
Unfortunately, Leo didn't write why configuring 'meta' for cicustom is
not allowed...
> diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
> index 5cc37f7..e3ed93b 100644
> --- a/src/PVE/LXC/Config.pm
> +++ b/src/PVE/LXC/Config.pm
> @@ -450,6 +450,63 @@ my $features_desc = {
> },
> };
>
> +my $cicustom_fmt = {
> + user => {
> + type => 'string',
> + optional => 1,
> + description => 'To pass a custom file containing all user data to the container via cloud-init.',
> + format => 'pve-volume-id',
> + format_description => 'volume',
> + },
> + vendor => {
> + type => 'string',
> + optional => 1,
> + description => 'To pass a custom file containing all vendor data to the container via cloud-init.',
> + format => 'pve-volume-id',
> + format_description => 'volume',
> + },
...i.e. it's missing here. This might be an oversight, because the doc
patch mentions it in an example command: 'pct set 9000 --cicustom
"user=<volume>,meta=<volume>"'
> +};
> +PVE::JSONSchema::register_format('pve-pct-cicustom', $cicustom_fmt);
> +
> +my $confdesc_cloudinit = {
> + cienable => {
> + optional => 1,
> + type => 'boolean',
> + description => "cloud-init: provide cloud-init configuration to container.",
Missing the default.
> + },
> + ciuser => {
> + optional => 1,
> + type => 'string',
> + description => "cloud-init: User name to change ssh keys and password for instead of the"
> + ." image's configured default user.",
> + },
> + cipassword => {
> + optional => 1,
> + type => 'string',
> + description => 'cloud-init: Password to assign the user. Using this is generally not'
> + .' recommended. Use ssh keys instead. Also note that older cloud-init versions do not'
> + .' support hashed passwords.',
> + },
> + ciupgrade => {
> + optional => 1,
> + type => 'boolean',
> + description => 'cloud-init: do an automatic package update on boot.'
Missing the default.
> + },
> + cicustom => {
> + optional => 1,
> + type => 'string',
> + description => 'cloud-init: Specify custom files to replace the automatically generated'
> + .' ones at start.',
> + format => 'pve-pct-cicustom',
> + },
> + sshkeys => {
> + optional => 1,
> + type => 'string',
> + format => 'urlencoded',
> + description => "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).",
> + },
> +};
> +
> my $confdesc = {
> lock => {
> optional => 1,
> @@ -622,6 +679,10 @@ my $confdesc = {
> },
> };
>
> +foreach my $key (keys %$confdesc_cloudinit) {
Style nit: use "for"
> + $confdesc->{$key} = $confdesc_cloudinit->{$key};
> +}
> +
> my $valid_lxc_conf_keys = {
> 'lxc.apparmor.profile' => 1,
> 'lxc.apparmor.allow_incomplete' => 1,
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters
2025-02-13 10:10 ` Fiona Ebner
@ 2025-02-13 10:18 ` Mira Limbeck
2025-02-13 10:22 ` Fiona Ebner
0 siblings, 1 reply; 23+ messages in thread
From: Mira Limbeck @ 2025-02-13 10:18 UTC (permalink / raw)
To: pve-devel
On 2/13/25 11:10, Fiona Ebner wrote:
> Am 10.02.25 um 13:07 schrieb Daniel Herzig:
>> From: Leo Nunner <l.nunner@proxmox.com>
>>
>> Introduce configuration parameters for cloud-init. Like with VMs, it's
>> possible to specify:
>> - user
>> - password
>> - ssh keys
>> - enable/disable updates on first boot
>>
>> It's also possible to pass through custom config files for the user and
>> vendor settings. We don't allow configuring the network through
>> cloud-init, since it will clash with whatever configuration we already
>> did for the container.
>
> Unfortunately, Leo didn't write why configuring 'meta' for cicustom is
> not allowed...
Maybe because you can configure network interfaces via metadata as well?
https://cloudinit.readthedocs.io/en/latest/reference/datasources/nocloud.html#example-meta-data
We don't do that in any of our code, but custom configs circumvent that.
>
>> diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
>> index 5cc37f7..e3ed93b 100644
>> --- a/src/PVE/LXC/Config.pm
>> +++ b/src/PVE/LXC/Config.pm
>> @@ -450,6 +450,63 @@ my $features_desc = {
>> },
>> };
>>
>> +my $cicustom_fmt = {
>> + user => {
>> + type => 'string',
>> + optional => 1,
>> + description => 'To pass a custom file containing all user data to the container via cloud-init.',
>> + format => 'pve-volume-id',
>> + format_description => 'volume',
>> + },
>> + vendor => {
>> + type => 'string',
>> + optional => 1,
>> + description => 'To pass a custom file containing all vendor data to the container via cloud-init.',
>> + format => 'pve-volume-id',
>> + format_description => 'volume',
>> + },
>
> ...i.e. it's missing here. This might be an oversight, because the doc
> patch mentions it in an example command: 'pct set 9000 --cicustom
> "user=<volume>,meta=<volume>"'
>
>> +};
>> +PVE::JSONSchema::register_format('pve-pct-cicustom', $cicustom_fmt);
>> +
>> +my $confdesc_cloudinit = {
>> + cienable => {
>> + optional => 1,
>> + type => 'boolean',
>> + description => "cloud-init: provide cloud-init configuration to container.",
>
> Missing the default.
>
>> + },
>> + ciuser => {
>> + optional => 1,
>> + type => 'string',
>> + description => "cloud-init: User name to change ssh keys and password for instead of the"
>> + ." image's configured default user.",
>> + },
>> + cipassword => {
>> + optional => 1,
>> + type => 'string',
>> + description => 'cloud-init: Password to assign the user. Using this is generally not'
>> + .' recommended. Use ssh keys instead. Also note that older cloud-init versions do not'
>> + .' support hashed passwords.',
>> + },
>> + ciupgrade => {
>> + optional => 1,
>> + type => 'boolean',
>> + description => 'cloud-init: do an automatic package update on boot.'
>
> Missing the default.
>
>> + },
>> + cicustom => {
>> + optional => 1,
>> + type => 'string',
>> + description => 'cloud-init: Specify custom files to replace the automatically generated'
>> + .' ones at start.',
>> + format => 'pve-pct-cicustom',
>> + },
>> + sshkeys => {
>> + optional => 1,
>> + type => 'string',
>> + format => 'urlencoded',
>> + description => "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).",
>> + },
>> +};
>> +
>> my $confdesc = {
>> lock => {
>> optional => 1,
>> @@ -622,6 +679,10 @@ my $confdesc = {
>> },
>> };
>>
>> +foreach my $key (keys %$confdesc_cloudinit) {
>
> Style nit: use "for"
>
>> + $confdesc->{$key} = $confdesc_cloudinit->{$key};
>> +}
>> +
>> my $valid_lxc_conf_keys = {
>> 'lxc.apparmor.profile' => 1,
>> 'lxc.apparmor.allow_incomplete' => 1,
>
>
>
> _______________________________________________
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
>
>
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters
2025-02-13 10:18 ` Mira Limbeck
@ 2025-02-13 10:22 ` Fiona Ebner
0 siblings, 0 replies; 23+ messages in thread
From: Fiona Ebner @ 2025-02-13 10:22 UTC (permalink / raw)
To: Proxmox VE development discussion, Mira Limbeck
Am 13.02.25 um 11:18 schrieb Mira Limbeck:
> On 2/13/25 11:10, Fiona Ebner wrote:
>> Am 10.02.25 um 13:07 schrieb Daniel Herzig:
>>> From: Leo Nunner <l.nunner@proxmox.com>
>>>
>>> Introduce configuration parameters for cloud-init. Like with VMs, it's
>>> possible to specify:
>>> - user
>>> - password
>>> - ssh keys
>>> - enable/disable updates on first boot
>>>
>>> It's also possible to pass through custom config files for the user and
>>> vendor settings. We don't allow configuring the network through
>>> cloud-init, since it will clash with whatever configuration we already
>>> did for the container.
>>
>> Unfortunately, Leo didn't write why configuring 'meta' for cicustom is
>> not allowed...
> Maybe because you can configure network interfaces via metadata as well?
> https://cloudinit.readthedocs.io/en/latest/reference/datasources/nocloud.html#example-meta-data
>
> We don't do that in any of our code, but custom configs circumvent that.
Good to know. We can also leave it out for now, mention this in the
commit message and fix the docs example. Can still be added/evaluated
later if users request it.
>>
>>> diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
>>> index 5cc37f7..e3ed93b 100644
>>> --- a/src/PVE/LXC/Config.pm
>>> +++ b/src/PVE/LXC/Config.pm
>>> @@ -450,6 +450,63 @@ my $features_desc = {
>>> },
>>> };
>>>
>>> +my $cicustom_fmt = {
>>> + user => {
>>> + type => 'string',
>>> + optional => 1,
>>> + description => 'To pass a custom file containing all user data to the container via cloud-init.',
>>> + format => 'pve-volume-id',
>>> + format_description => 'volume',
>>> + },
>>> + vendor => {
>>> + type => 'string',
>>> + optional => 1,
>>> + description => 'To pass a custom file containing all vendor data to the container via cloud-init.',
>>> + format => 'pve-volume-id',
>>> + format_description => 'volume',
>>> + },
>>
>> ...i.e. it's missing here. This might be an oversight, because the doc
>> patch mentions it in an example command: 'pct set 9000 --cicustom
>> "user=<volume>,meta=<volume>"'
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters
2025-02-10 12:07 ` [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters Daniel Herzig
2025-02-13 10:10 ` Fiona Ebner
@ 2025-02-13 10:23 ` Fiona Ebner
2025-02-13 15:05 ` Daniel Herzig
2025-02-13 12:15 ` Fiona Ebner
2 siblings, 1 reply; 23+ messages in thread
From: Fiona Ebner @ 2025-02-13 10:23 UTC (permalink / raw)
To: Proxmox VE development discussion, Daniel Herzig
Am 10.02.25 um 13:07 schrieb Daniel Herzig:
> From: Leo Nunner <l.nunner@proxmox.com>
>
> Introduce configuration parameters for cloud-init. Like with VMs, it's
> possible to specify:
> - user
> - password
> - ssh keys
> - enable/disable updates on first boot
>
> It's also possible to pass through custom config files for the user and
> vendor settings. We don't allow configuring the network through
> cloud-init, since it will clash with whatever configuration we already
> did for the container.
Since I didn't mention it yet, when you do changes, you should keep a
brief changelog of what changed between Leo's version and your version
in the git trailers, e.g.:
Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
[DH: add foo
refactor bar
fix regex for baz]
Signed-off-by: Daniel Herzig <d.herzig@proxmox.com>
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters
2025-02-13 10:23 ` Fiona Ebner
@ 2025-02-13 15:05 ` Daniel Herzig
0 siblings, 0 replies; 23+ messages in thread
From: Daniel Herzig @ 2025-02-13 15:05 UTC (permalink / raw)
To: Fiona Ebner; +Cc: Proxmox VE development discussion
Fiona Ebner <f.ebner@proxmox.com> writes:
> Am 10.02.25 um 13:07 schrieb Daniel Herzig:
>> From: Leo Nunner <l.nunner@proxmox.com>
>>
>> Introduce configuration parameters for cloud-init. Like with VMs, it's
>> possible to specify:
>> - user
>> - password
>> - ssh keys
>> - enable/disable updates on first boot
>>
>> It's also possible to pass through custom config files for the user and
>> vendor settings. We don't allow configuring the network through
>> cloud-init, since it will clash with whatever configuration we already
>> did for the container.
>
> Since I didn't mention it yet, when you do changes, you should keep a
> brief changelog of what changed between Leo's version and your version
> in the git trailers, e.g.:
>
> Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
> [DH: add foo
> refactor bar
> fix regex for baz]
> Signed-off-by: Daniel Herzig <d.herzig@proxmox.com>
Thanks for the review and the input Fiona, I'll add this once I
actually start changing stuff apart from the initial rebase!
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters
2025-02-10 12:07 ` [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters Daniel Herzig
2025-02-13 10:10 ` Fiona Ebner
2025-02-13 10:23 ` Fiona Ebner
@ 2025-02-13 12:15 ` Fiona Ebner
2 siblings, 0 replies; 23+ messages in thread
From: Fiona Ebner @ 2025-02-13 12:15 UTC (permalink / raw)
To: Proxmox VE development discussion, Daniel Herzig
Am 10.02.25 um 13:07 schrieb Daniel Herzig:
> diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
> index 5cc37f7..e3ed93b 100644
> --- a/src/PVE/LXC/Config.pm
> +++ b/src/PVE/LXC/Config.pm
> @@ -450,6 +450,63 @@ my $features_desc = {
> },
> };
>
> +my $cicustom_fmt = {
> + user => {
> + type => 'string',
> + optional => 1,
> + description => 'To pass a custom file containing all user data to the container via cloud-init.',
> + format => 'pve-volume-id',
> + format_description => 'volume',
> + },
> + vendor => {
> + type => 'string',
> + optional => 1,
> + description => 'To pass a custom file containing all vendor data to the container via cloud-init.',
> + format => 'pve-volume-id',
> + format_description => 'volume',
> + },
> +};
> +PVE::JSONSchema::register_format('pve-pct-cicustom', $cicustom_fmt);
> +
> +my $confdesc_cloudinit = {
Hmm, maybe we should rather move these into the Cloudinit module to
avoid bloating up the config module here. Then everything is collected
there.
> },
> };
>
> +foreach my $key (keys %$confdesc_cloudinit) {
> + $confdesc->{$key} = $confdesc_cloudinit->{$key};
And just access it here e.g. by declaring it as shared in the other module:
our $confdesc_cloudinit
> +}
> +
> my $valid_lxc_conf_keys = {
> 'lxc.apparmor.profile' => 1,
> 'lxc.apparmor.allow_incomplete' => 1,
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [pve-devel] [PATCH 2/8 container] cloudinit: basic implementation
2025-02-10 12:07 [pve-devel] [PATCH 0/8 container/manager/docs] fix #4686: Cloudinit support for LXC Daniel Herzig
2025-02-10 12:07 ` [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters Daniel Herzig
@ 2025-02-10 12:07 ` Daniel Herzig
2025-02-13 11:01 ` Fiona Ebner
2025-02-10 12:07 ` [pve-devel] [PATCH 3/8 container] cloudinit: add dump command to pct Daniel Herzig
` (5 subsequent siblings)
7 siblings, 1 reply; 23+ messages in thread
From: Daniel Herzig @ 2025-02-10 12:07 UTC (permalink / raw)
To: pve-devel; +Cc: Leo Nunner
From: Leo Nunner <l.nunner@proxmox.com>
The code to generate the actual configuration works pretty much the same
as with the VM system. We generate an instance ID by hashing the user
configuration, causing cloud-init to run every time said configuration
changes.
Instead of creating a config drive, we write files directly into the
volume of the container. We create a folder at
'/var/lib/cloud/seed/nocloud-net' and write the files 'user-data',
'vendor-data' and 'meta-data'. Cloud-init looks at the instance ID
inside 'meta-data' to decide whether it should run (again) or not.
Custom scripts need to be located inside the snippets directory, and
overwrite the default generated configuration file.
Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
---
src/PVE/LXC.pm | 1 +
src/PVE/LXC/Cloudinit.pm | 114 ++++++++++++++++++++++++++++++++++++++
src/PVE/LXC/Makefile | 1 +
src/lxc-pve-prestart-hook | 5 ++
4 files changed, 121 insertions(+)
create mode 100644 src/PVE/LXC/Cloudinit.pm
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index 4d20645..35bb6b5 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -40,6 +40,7 @@ use PVE::Tools qw(
use PVE::Syscall qw(:fsmount);
use PVE::LXC::CGroup;
+use PVE::LXC::Cloudinit;
use PVE::LXC::Config;
use PVE::LXC::Monitor;
use PVE::LXC::Tools;
diff --git a/src/PVE/LXC/Cloudinit.pm b/src/PVE/LXC/Cloudinit.pm
new file mode 100644
index 0000000..3e8617b
--- /dev/null
+++ b/src/PVE/LXC/Cloudinit.pm
@@ -0,0 +1,114 @@
+package PVE::LXC::Cloudinit;
+
+use strict;
+use warnings;
+
+use Digest::SHA;
+use File::Path;
+
+use PVE::LXC;
+
+sub gen_cloudinit_metadata {
+ my ($user) = @_;
+
+ my $uuid_str = Digest::SHA::sha1_hex($user);
+ return cloudinit_metadata($uuid_str);
+}
+
+sub cloudinit_metadata {
+ my ($uuid) = @_;
+ my $raw = "";
+
+ $raw .= "instance-id: $uuid\n";
+
+ return $raw;
+}
+
+sub cloudinit_userdata {
+ my ($conf) = @_;
+
+ my $content = "#cloud-config\n";
+
+ my $username = $conf->{ciuser};
+ my $password = $conf->{cipassword};
+
+ $content .= "user: $username\n" if defined($username);
+ $content .= "password: $password\n" if defined($password);
+
+ if (defined(my $keys = $conf->{sshkeys})) {
+ $keys = URI::Escape::uri_unescape($keys);
+ $keys = [map { my $key = $_; chomp $key; $key } split(/\n/, $keys)];
+ $keys = [grep { /\S/ } @$keys];
+ $content .= "ssh_authorized_keys:\n";
+ foreach my $k (@$keys) {
+ $content .= " - $k\n";
+ }
+ }
+ $content .= "chpasswd:\n";
+ $content .= " expire: False\n";
+
+ if (!defined($username) || $username ne 'root') {
+ $content .= "users:\n";
+ $content .= " - default\n";
+ }
+
+ $content .= "package_upgrade: true\n" if $conf->{ciupgrade};
+
+ return $content;
+}
+
+sub read_cloudinit_snippets_file {
+ my ($storage_conf, $volid) = @_;
+
+ my ($full_path, undef, $type) = PVE::Storage::path($storage_conf, $volid);
+ die "$volid is not in the snippets directory\n" if $type ne 'snippets';
+ return PVE::Tools::file_get_contents($full_path, 1 * 1024 * 1024);
+}
+
+sub read_custom_cloudinit_files {
+ my ($conf) = @_;
+
+ my $cloudinit_conf = $conf->{cicustom};
+ my $files = $cloudinit_conf ? PVE::JSONSchema::parse_property_string('pve-pct-cicustom', $cloudinit_conf) : {};
+
+ my $user_volid = $files->{user};
+ my $vendor_volid = $files->{vendor};
+
+ my $storage_conf = PVE::Storage::config();
+
+ my $user_data;
+ if ($user_volid) {
+ $user_data = read_cloudinit_snippets_file($storage_conf, $user_volid);
+ }
+
+ my $vendor_data;
+ if ($vendor_volid) {
+ $user_data = read_cloudinit_snippets_file($storage_conf, $vendor_volid);
+ }
+
+ return ($user_data, $vendor_data);
+}
+
+sub create_cloudinit_files {
+ my ($conf, $setup) = @_;
+
+ my $cloudinit_dir = "/var/lib/cloud/seed/nocloud-net";
+
+ my ($user_data, $vendor_data) = read_custom_cloudinit_files($conf);
+ $user_data = cloudinit_userdata($conf) if !defined($user_data);
+ $vendor_data = '' if !defined($vendor_data);
+
+ my $meta_data = gen_cloudinit_metadata($user_data);
+
+ $setup->protected_call(sub {
+ my $plugin = $setup->{plugin};
+
+ $plugin->ct_make_path($cloudinit_dir);
+
+ $plugin->ct_file_set_contents("$cloudinit_dir/user-data", $user_data);
+ $plugin->ct_file_set_contents("$cloudinit_dir/vendor-data", $vendor_data);
+ $plugin->ct_file_set_contents("$cloudinit_dir/meta-data", $meta_data);
+ });
+}
+
+1;
diff --git a/src/PVE/LXC/Makefile b/src/PVE/LXC/Makefile
index a190260..5d595ba 100644
--- a/src/PVE/LXC/Makefile
+++ b/src/PVE/LXC/Makefile
@@ -1,5 +1,6 @@
SOURCES= \
CGroup.pm \
+ Cloudinit.pm \
Command.pm \
Config.pm \
Create.pm \
diff --git a/src/lxc-pve-prestart-hook b/src/lxc-pve-prestart-hook
index fdaead2..c9f8ff0 100755
--- a/src/lxc-pve-prestart-hook
+++ b/src/lxc-pve-prestart-hook
@@ -13,6 +13,7 @@ use POSIX;
use PVE::CGroup;
use PVE::Cluster;
use PVE::LXC::Config;
+use PVE::LXC::Cloudinit;
use PVE::LXC::Setup;
use PVE::LXC::Tools;
use PVE::LXC;
@@ -173,6 +174,10 @@ PVE::LXC::Tools::lxc_hook('pre-start', 'lxc', sub {
my $lxc_setup = PVE::LXC::Setup->new($conf, $rootdir);
$lxc_setup->pre_start_hook();
+ if ($conf->{cienable}) {
+ PVE::LXC::Cloudinit::create_cloudinit_files($conf, $lxc_setup)
+ }
+
if (PVE::CGroup::cgroup_mode() == 2) {
if (!$lxc_setup->unified_cgroupv2_support()) {
log_warn($vmid, "old systemd (< v232) detected, container won't run in a pure cgroupv2"
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 2/8 container] cloudinit: basic implementation
2025-02-10 12:07 ` [pve-devel] [PATCH 2/8 container] cloudinit: basic implementation Daniel Herzig
@ 2025-02-13 11:01 ` Fiona Ebner
2025-02-13 11:29 ` Mira Limbeck
2025-02-13 12:06 ` Fiona Ebner
0 siblings, 2 replies; 23+ messages in thread
From: Fiona Ebner @ 2025-02-13 11:01 UTC (permalink / raw)
To: Proxmox VE development discussion, Daniel Herzig
Am 10.02.25 um 13:07 schrieb Daniel Herzig:
> From: Leo Nunner <l.nunner@proxmox.com>
>
> The code to generate the actual configuration works pretty much the same
> as with the VM system. We generate an instance ID by hashing the user
> configuration, causing cloud-init to run every time said configuration
> changes.
>
> Instead of creating a config drive, we write files directly into the
> volume of the container. We create a folder at
> '/var/lib/cloud/seed/nocloud-net' and write the files 'user-data',
> 'vendor-data' and 'meta-data'. Cloud-init looks at the instance ID
> inside 'meta-data' to decide whether it should run (again) or not.
>
> Custom scripts need to be located inside the snippets directory, and
> overwrite the default generated configuration file.
>
> Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
> ---
> src/PVE/LXC.pm | 1 +
> src/PVE/LXC/Cloudinit.pm | 114 ++++++++++++++++++++++++++++++++++++++
> src/PVE/LXC/Makefile | 1 +
> src/lxc-pve-prestart-hook | 5 ++
> 4 files changed, 121 insertions(+)
> create mode 100644 src/PVE/LXC/Cloudinit.pm
>
> diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
> index 4d20645..35bb6b5 100644
> --- a/src/PVE/LXC.pm
> +++ b/src/PVE/LXC.pm
> @@ -40,6 +40,7 @@ use PVE::Tools qw(
> use PVE::Syscall qw(:fsmount);
>
> use PVE::LXC::CGroup;
> +use PVE::LXC::Cloudinit;
> use PVE::LXC::Config;
> use PVE::LXC::Monitor;
> use PVE::LXC::Tools;
Hmm, seems like this import is unused. Can you double check?
> diff --git a/src/PVE/LXC/Cloudinit.pm b/src/PVE/LXC/Cloudinit.pm
> new file mode 100644
> index 0000000..3e8617b
> --- /dev/null
> +++ b/src/PVE/LXC/Cloudinit.pm
> @@ -0,0 +1,114 @@
> +package PVE::LXC::Cloudinit;
> +
> +use strict;
> +use warnings;
> +
> +use Digest::SHA;
> +use File::Path;
Missing includes:
use URI::Escape;
And we also need a dependency on liburi-perl in debian/control ;)
use PVE::JSONSchema;
> +use PVE::LXC;
use PVE::Storage;
use PVE::Tools;
> +
> +sub gen_cloudinit_metadata {
> + my ($user) = @_;
> +
> + my $uuid_str = Digest::SHA::sha1_hex($user);
Hmm, shouldn't this also depend on the vendor data? Otherwise, if only
the vendor data changes, then it will still have the same instance ID.
Seems like for VMs, we only use user and network data here.
@Mira do you know more by chance?
> + return cloudinit_metadata($uuid_str);
> +}
> +
> +sub cloudinit_metadata {
> + my ($uuid) = @_;
> + my $raw = "";
> +
> + $raw .= "instance-id: $uuid\n";
> +
> + return $raw;
> +}
> +
> +sub cloudinit_userdata {
> + my ($conf) = @_;
> +
> + my $content = "#cloud-config\n";
> +
> + my $username = $conf->{ciuser};
> + my $password = $conf->{cipassword};
> +
> + $content .= "user: $username\n" if defined($username);
> + $content .= "password: $password\n" if defined($password);
> +
> + if (defined(my $keys = $conf->{sshkeys})) {
> + $keys = URI::Escape::uri_unescape($keys);
> + $keys = [map { my $key = $_; chomp $key; $key } split(/\n/, $keys)];
> + $keys = [grep { /\S/ } @$keys];
> + $content .= "ssh_authorized_keys:\n";
> + foreach my $k (@$keys) {
> + $content .= " - $k\n";
> + }
> + }
> + $content .= "chpasswd:\n";
> + $content .= " expire: False\n";
> +
> + if (!defined($username) || $username ne 'root') {
> + $content .= "users:\n";
> + $content .= " - default\n";
> + }
> +
> + $content .= "package_upgrade: true\n" if $conf->{ciupgrade};
For VMs, we default to true here. I'd like to keep it consistent.
> +
> + return $content;
> +}
> +
> +sub read_cloudinit_snippets_file {
> + my ($storage_conf, $volid) = @_;
> +
> + my ($full_path, undef, $type) = PVE::Storage::path($storage_conf, $volid);
The qemu-server implementation does things a bit differently here using
parse_volname() and abs_filesystem_path(). The latter makes sure to
activate the storage/volume, which is desirable. I'd either add a call
to activate the volume here too, or align the helpers.
> + die "$volid is not in the snippets directory\n" if $type ne 'snippets';
> + return PVE::Tools::file_get_contents($full_path, 1 * 1024 * 1024);
> +}
> +
---snip 8<---
> diff --git a/src/lxc-pve-prestart-hook b/src/lxc-pve-prestart-hook
> index fdaead2..c9f8ff0 100755
> --- a/src/lxc-pve-prestart-hook
> +++ b/src/lxc-pve-prestart-hook
> @@ -13,6 +13,7 @@ use POSIX;
> use PVE::CGroup;
> use PVE::Cluster;
> use PVE::LXC::Config;
> +use PVE::LXC::Cloudinit;
Nit: not ordered alphabetically
> use PVE::LXC::Setup;
> use PVE::LXC::Tools;
> use PVE::LXC;
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 2/8 container] cloudinit: basic implementation
2025-02-13 11:01 ` Fiona Ebner
@ 2025-02-13 11:29 ` Mira Limbeck
2025-02-13 12:02 ` Fiona Ebner
2025-02-13 15:09 ` Daniel Herzig
2025-02-13 12:06 ` Fiona Ebner
1 sibling, 2 replies; 23+ messages in thread
From: Mira Limbeck @ 2025-02-13 11:29 UTC (permalink / raw)
To: Fiona Ebner, Proxmox VE development discussion, Daniel Herzig
On 2/13/25 12:01, Fiona Ebner wrote:
> Am 10.02.25 um 13:07 schrieb Daniel Herzig:
>> From: Leo Nunner <l.nunner@proxmox.com>
>>
>> The code to generate the actual configuration works pretty much the same
>> as with the VM system. We generate an instance ID by hashing the user
>> configuration, causing cloud-init to run every time said configuration
>> changes.
>>
>> Instead of creating a config drive, we write files directly into the
>> volume of the container. We create a folder at
>> '/var/lib/cloud/seed/nocloud-net' and write the files 'user-data',
>> 'vendor-data' and 'meta-data'. Cloud-init looks at the instance ID
>> inside 'meta-data' to decide whether it should run (again) or not.
>>
>> Custom scripts need to be located inside the snippets directory, and
>> overwrite the default generated configuration file.
>>
>> Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
>> ---
>> src/PVE/LXC.pm | 1 +
>> src/PVE/LXC/Cloudinit.pm | 114 ++++++++++++++++++++++++++++++++++++++
>> src/PVE/LXC/Makefile | 1 +
>> src/lxc-pve-prestart-hook | 5 ++
>> 4 files changed, 121 insertions(+)
>> create mode 100644 src/PVE/LXC/Cloudinit.pm
>>
>> diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
>> index 4d20645..35bb6b5 100644
>> --- a/src/PVE/LXC.pm
>> +++ b/src/PVE/LXC.pm
>> @@ -40,6 +40,7 @@ use PVE::Tools qw(
>> use PVE::Syscall qw(:fsmount);
>>
>> use PVE::LXC::CGroup;
>> +use PVE::LXC::Cloudinit;
>> use PVE::LXC::Config;
>> use PVE::LXC::Monitor;
>> use PVE::LXC::Tools;
>
> Hmm, seems like this import is unused. Can you double check?
>
>> diff --git a/src/PVE/LXC/Cloudinit.pm b/src/PVE/LXC/Cloudinit.pm
>> new file mode 100644
>> index 0000000..3e8617b
>> --- /dev/null
>> +++ b/src/PVE/LXC/Cloudinit.pm
>> @@ -0,0 +1,114 @@
>> +package PVE::LXC::Cloudinit;
>> +
>> +use strict;
>> +use warnings;
>> +
>> +use Digest::SHA;
>> +use File::Path;
>
> Missing includes:
>
> use URI::Escape;
>
> And we also need a dependency on liburi-perl in debian/control ;)
>
> use PVE::JSONSchema;
>
>> +use PVE::LXC;
>
> use PVE::Storage;
> use PVE::Tools;
>
>> +
>> +sub gen_cloudinit_metadata {
>> + my ($user) = @_;
>> +
>> + my $uuid_str = Digest::SHA::sha1_hex($user);
>
> Hmm, shouldn't this also depend on the vendor data? Otherwise, if only
> the vendor data changes, then it will still have the same instance ID.
>
> Seems like for VMs, we only use user and network data here.
>
> @Mira do you know more by chance?
I don't think vendor-data should be part of the instance-id. It's used
to create a first configuration that a user can override via the user
config.
The vendor-data won't be used again once it's already configured.
I'm not a 100% sure, but changing the instance-id leads to rerunning
lots of modules (e.g. User, Network and others), but the vendor-data
parts do not.
Only a complete `cloud-init clean` should trigger the modules using
vendor-data to run again.
https://cloudinit.readthedocs.io/en/latest/explanation/vendordata.html#vendor-data
>> + return cloudinit_metadata($uuid_str);
>> +}
>> +
>> +sub cloudinit_metadata {
>> + my ($uuid) = @_;
>> + my $raw = "";
>> +
>> + $raw .= "instance-id: $uuid\n";
>> +
>> + return $raw;
>> +}
>> +
>> +sub cloudinit_userdata {
>> + my ($conf) = @_;
>> +
>> + my $content = "#cloud-config\n";
>> +
>> + my $username = $conf->{ciuser};
>> + my $password = $conf->{cipassword};
>> +
>> + $content .= "user: $username\n" if defined($username);
>> + $content .= "password: $password\n" if defined($password);
>> +
>> + if (defined(my $keys = $conf->{sshkeys})) {
>> + $keys = URI::Escape::uri_unescape($keys);
>> + $keys = [map { my $key = $_; chomp $key; $key } split(/\n/, $keys)];
>> + $keys = [grep { /\S/ } @$keys];
>> + $content .= "ssh_authorized_keys:\n";
>> + foreach my $k (@$keys) {
>> + $content .= " - $k\n";
>> + }
>> + }
>> + $content .= "chpasswd:\n";
>> + $content .= " expire: False\n";
>> +
>> + if (!defined($username) || $username ne 'root') {
>> + $content .= "users:\n";
>> + $content .= " - default\n";
>> + }
>> +
>> + $content .= "package_upgrade: true\n" if $conf->{ciupgrade};
>
> For VMs, we default to true here. I'd like to keep it consistent.
>
>> +
>> + return $content;
>> +}
>> +
>> +sub read_cloudinit_snippets_file {
>> + my ($storage_conf, $volid) = @_;
>> +
>> + my ($full_path, undef, $type) = PVE::Storage::path($storage_conf, $volid);
>
> The qemu-server implementation does things a bit differently here using
> parse_volname() and abs_filesystem_path(). The latter makes sure to
> activate the storage/volume, which is desirable. I'd either add a call
> to activate the volume here too, or align the helpers.
>
>> + die "$volid is not in the snippets directory\n" if $type ne 'snippets';
>> + return PVE::Tools::file_get_contents($full_path, 1 * 1024 * 1024);
>> +}
>> +
>
> ---snip 8<---
>
>> diff --git a/src/lxc-pve-prestart-hook b/src/lxc-pve-prestart-hook
>> index fdaead2..c9f8ff0 100755
>> --- a/src/lxc-pve-prestart-hook
>> +++ b/src/lxc-pve-prestart-hook
>> @@ -13,6 +13,7 @@ use POSIX;
>> use PVE::CGroup;
>> use PVE::Cluster;
>> use PVE::LXC::Config;
>> +use PVE::LXC::Cloudinit;
>
> Nit: not ordered alphabetically
>
>> use PVE::LXC::Setup;
>> use PVE::LXC::Tools;
>> use PVE::LXC;
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 2/8 container] cloudinit: basic implementation
2025-02-13 11:29 ` Mira Limbeck
@ 2025-02-13 12:02 ` Fiona Ebner
2025-02-13 15:09 ` Daniel Herzig
1 sibling, 0 replies; 23+ messages in thread
From: Fiona Ebner @ 2025-02-13 12:02 UTC (permalink / raw)
To: Mira Limbeck, Proxmox VE development discussion, Daniel Herzig
Am 13.02.25 um 12:29 schrieb Mira Limbeck:
> On 2/13/25 12:01, Fiona Ebner wrote:
>> Am 10.02.25 um 13:07 schrieb Daniel Herzig:
>>> +sub gen_cloudinit_metadata {
>>> + my ($user) = @_;
>>> +
>>> + my $uuid_str = Digest::SHA::sha1_hex($user);
>>
>> Hmm, shouldn't this also depend on the vendor data? Otherwise, if only
>> the vendor data changes, then it will still have the same instance ID.
>>
>> Seems like for VMs, we only use user and network data here.
>>
>> @Mira do you know more by chance?
> I don't think vendor-data should be part of the instance-id. It's used
> to create a first configuration that a user can override via the user
> config.
> The vendor-data won't be used again once it's already configured.
> I'm not a 100% sure, but changing the instance-id leads to rerunning
> lots of modules (e.g. User, Network and others), but the vendor-data
> parts do not.
>
> Only a complete `cloud-init clean` should trigger the modules using
> vendor-data to run again.
>
>
> https://cloudinit.readthedocs.io/en/latest/explanation/vendordata.html#vendor-data
Oh, thank you for the explanation!
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 2/8 container] cloudinit: basic implementation
2025-02-13 11:29 ` Mira Limbeck
2025-02-13 12:02 ` Fiona Ebner
@ 2025-02-13 15:09 ` Daniel Herzig
1 sibling, 0 replies; 23+ messages in thread
From: Daniel Herzig @ 2025-02-13 15:09 UTC (permalink / raw)
To: Mira Limbeck; +Cc: Proxmox VE development discussion
Mira Limbeck <m.limbeck@proxmox.com> writes:
> On 2/13/25 12:01, Fiona Ebner wrote:
>> Am 10.02.25 um 13:07 schrieb Daniel Herzig:
>>> From: Leo Nunner <l.nunner@proxmox.com>
>>>
>>
>> @Mira do you know more by chance?
> I don't think vendor-data should be part of the instance-id. It's used
> to create a first configuration that a user can override via the user
> config.
> The vendor-data won't be used again once it's already configured.
> I'm not a 100% sure, but changing the instance-id leads to rerunning
> lots of modules (e.g. User, Network and others), but the vendor-data
> parts do not.
>
> Only a complete `cloud-init clean` should trigger the modules using
> vendor-data to run again.
>
>
> https://cloudinit.readthedocs.io/en/latest/explanation/vendordata.html#vendor-data
>
Thanks for the input Mira!
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 2/8 container] cloudinit: basic implementation
2025-02-13 11:01 ` Fiona Ebner
2025-02-13 11:29 ` Mira Limbeck
@ 2025-02-13 12:06 ` Fiona Ebner
1 sibling, 0 replies; 23+ messages in thread
From: Fiona Ebner @ 2025-02-13 12:06 UTC (permalink / raw)
To: Proxmox VE development discussion, Daniel Herzig
Am 13.02.25 um 12:01 schrieb Fiona Ebner:
> Am 10.02.25 um 13:07 schrieb Daniel Herzig:
>> diff --git a/src/PVE/LXC/Cloudinit.pm b/src/PVE/LXC/Cloudinit.pm
>> new file mode 100644
>> index 0000000..3e8617b
>> --- /dev/null
>> +++ b/src/PVE/LXC/Cloudinit.pm
>> @@ -0,0 +1,114 @@
>> +package PVE::LXC::Cloudinit;
>> +
>> +use strict;
>> +use warnings;
>> +
>> +use Digest::SHA;
>> +use File::Path;
>
> Missing includes:
>
> use URI::Escape;
>
> And we also need a dependency on liburi-perl in debian/control ;)
>
> use PVE::JSONSchema;
>
>> +use PVE::LXC;
And actually, this one is not used (it just transitively imported all
the other needed ones, but that's confusing)
>
> use PVE::Storage;
> use PVE::Tools;
>
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [pve-devel] [PATCH 3/8 container] cloudinit: add dump command to pct
2025-02-10 12:07 [pve-devel] [PATCH 0/8 container/manager/docs] fix #4686: Cloudinit support for LXC Daniel Herzig
2025-02-10 12:07 ` [pve-devel] [PATCH 1/8 container] cloudinit: introduce config parameters Daniel Herzig
2025-02-10 12:07 ` [pve-devel] [PATCH 2/8 container] cloudinit: basic implementation Daniel Herzig
@ 2025-02-10 12:07 ` Daniel Herzig
2025-02-13 12:00 ` Fiona Ebner
2025-02-10 12:07 ` [pve-devel] [PATCH 4/8 container] cloudinit: add function dumping options for docs Daniel Herzig
` (4 subsequent siblings)
7 siblings, 1 reply; 23+ messages in thread
From: Daniel Herzig @ 2025-02-10 12:07 UTC (permalink / raw)
To: pve-devel; +Cc: Leo Nunner
From: Leo Nunner <l.nunner@proxmox.com>
Introduce a 'pct cloudinit dump <vmid> <section>' command to dump the
generated cloudinit configuration for a section.
Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
---
src/PVE/API2/LXC.pm | 33 +++++++++++++++++++++++++++++++++
src/PVE/CLI/pct.pm | 4 ++++
src/PVE/LXC/Cloudinit.pm | 11 +++++++++++
3 files changed, 48 insertions(+)
diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index d6e647d..e883c43 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -3041,4 +3041,37 @@ __PACKAGE__->register_method({
return { socket => $socket };
}});
+
+__PACKAGE__->register_method({
+ name => 'cloudinit_generated_config_dump',
+ path => '{vmid}/cloudinit/dump',
+ method => 'GET',
+ proxyto => 'node',
+ description => "Get automatically generated cloudinit config.",
+ permissions => {
+ check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
+ },
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid }),
+ type => {
+ description => 'Config type.',
+ type => 'string',
+ enum => ['user', 'meta'],
+ },
+ },
+ },
+ returns => {
+ type => 'string',
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $conf = PVE::LXC::Config->load_config($param->{vmid});
+
+ return PVE::LXC::Cloudinit::dump_cloudinit_config($conf, $param->{type});
+ }});
+
1;
diff --git a/src/PVE/CLI/pct.pm b/src/PVE/CLI/pct.pm
index b0a1ec2..60c2ccd 100755
--- a/src/PVE/CLI/pct.pm
+++ b/src/PVE/CLI/pct.pm
@@ -1046,6 +1046,10 @@ our $cmddef = {
rescan => [ __PACKAGE__, 'rescan', []],
cpusets => [ __PACKAGE__, 'cpusets', []],
fstrim => [ __PACKAGE__, 'fstrim', ['vmid']],
+
+ cloudinit => {
+ dump => [ "PVE::API2::LXC", 'cloudinit_generated_config_dump', ['vmid', 'type'], { node => $nodename }, sub { print "$_[0]\n"; }],
+ },
};
1;
diff --git a/src/PVE/LXC/Cloudinit.pm b/src/PVE/LXC/Cloudinit.pm
index 3e8617b..b6fec2c 100644
--- a/src/PVE/LXC/Cloudinit.pm
+++ b/src/PVE/LXC/Cloudinit.pm
@@ -111,4 +111,15 @@ sub create_cloudinit_files {
});
}
+sub dump_cloudinit_config {
+ my ($conf, $type) = @_;
+
+ if ($type eq 'user') {
+ return cloudinit_userdata($conf);
+ } else { # metadata config
+ my $user = cloudinit_userdata($conf);
+ return gen_cloudinit_metadata($user);
+ }
+}
+
1;
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [pve-devel] [PATCH 4/8 container] cloudinit: add function dumping options for docs
2025-02-10 12:07 [pve-devel] [PATCH 0/8 container/manager/docs] fix #4686: Cloudinit support for LXC Daniel Herzig
` (2 preceding siblings ...)
2025-02-10 12:07 ` [pve-devel] [PATCH 3/8 container] cloudinit: add dump command to pct Daniel Herzig
@ 2025-02-10 12:07 ` Daniel Herzig
2025-02-10 12:07 ` [pve-devel] [PATCH 5/8 manager] cloudinit: rename qemu cloudinit panel Daniel Herzig
` (3 subsequent siblings)
7 siblings, 0 replies; 23+ messages in thread
From: Daniel Herzig @ 2025-02-10 12:07 UTC (permalink / raw)
To: pve-devel; +Cc: Leo Nunner
From: Leo Nunner <l.nunner@proxmox.com>
Adds a cloudinit_config_properties function which dumps the config
parameters from the cloudinit config description. This is called
automatically when generating the docs.
Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
---
src/PVE/LXC/Config.pm | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
index e3ed93b..7e184ee 100644
--- a/src/PVE/LXC/Config.pm
+++ b/src/PVE/LXC/Config.pm
@@ -1322,6 +1322,9 @@ sub check_type {
}
}
+sub cloudinit_config_properties {
+ return Storable::dclone($confdesc_cloudinit);
+}
# add JSON properties for create and set function
sub json_config_properties {
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [pve-devel] [PATCH 5/8 manager] cloudinit: rename qemu cloudinit panel
2025-02-10 12:07 [pve-devel] [PATCH 0/8 container/manager/docs] fix #4686: Cloudinit support for LXC Daniel Herzig
` (3 preceding siblings ...)
2025-02-10 12:07 ` [pve-devel] [PATCH 4/8 container] cloudinit: add function dumping options for docs Daniel Herzig
@ 2025-02-10 12:07 ` Daniel Herzig
2025-02-10 12:07 ` [pve-devel] [PATCH 6/8 manager] cloudinit: introduce panel for LXCs Daniel Herzig
` (2 subsequent siblings)
7 siblings, 0 replies; 23+ messages in thread
From: Daniel Herzig @ 2025-02-10 12:07 UTC (permalink / raw)
To: pve-devel; +Cc: Leo Nunner
From: Leo Nunner <l.nunner@proxmox.com>
Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
---
www/manager6/qemu/CloudInit.js | 4 ++--
www/manager6/qemu/Config.js | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/www/manager6/qemu/CloudInit.js b/www/manager6/qemu/CloudInit.js
index 0449d810..5c8c3859 100644
--- a/www/manager6/qemu/CloudInit.js
+++ b/www/manager6/qemu/CloudInit.js
@@ -1,6 +1,6 @@
Ext.define('PVE.qemu.CloudInit', {
extend: 'Proxmox.grid.PendingObjectGrid',
- xtype: 'pveCiPanel',
+ xtype: 'pveQemuCiPanel',
onlineHelp: 'qm_cloud_init',
@@ -64,7 +64,7 @@ Ext.define('PVE.qemu.CloudInit', {
xtype: 'proxmoxButton',
disabled: true,
enableFn: function(rec) {
- let view = this.up('pveCiPanel');
+ let view = this.up('pveQemuCiPanel');
return !!view.rows[rec.data.key].editor;
},
handler: function() {
diff --git a/www/manager6/qemu/Config.js b/www/manager6/qemu/Config.js
index 48eb753e..41dd0415 100644
--- a/www/manager6/qemu/Config.js
+++ b/www/manager6/qemu/Config.js
@@ -286,7 +286,7 @@ Ext.define('PVE.qemu.Config', {
title: 'Cloud-Init',
itemId: 'cloudinit',
iconCls: 'fa fa-cloud',
- xtype: 'pveCiPanel',
+ xtype: 'pveQemuCiPanel',
},
{
title: gettext('Options'),
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [pve-devel] [PATCH 6/8 manager] cloudinit: introduce panel for LXCs
2025-02-10 12:07 [pve-devel] [PATCH 0/8 container/manager/docs] fix #4686: Cloudinit support for LXC Daniel Herzig
` (4 preceding siblings ...)
2025-02-10 12:07 ` [pve-devel] [PATCH 5/8 manager] cloudinit: rename qemu cloudinit panel Daniel Herzig
@ 2025-02-10 12:07 ` Daniel Herzig
2025-02-10 12:07 ` [pve-devel] [PATCH 7/8 docs] pct: add script to generate cloudinit options Daniel Herzig
2025-02-10 12:07 ` [pve-devel] [PATCH 8/8 docs] pct: document cloudinit for LXC Daniel Herzig
7 siblings, 0 replies; 23+ messages in thread
From: Daniel Herzig @ 2025-02-10 12:07 UTC (permalink / raw)
To: pve-devel; +Cc: Leo Nunner
From: Leo Nunner <l.nunner@proxmox.com>
based on the already existing panel for VMs. Some things have been
changed, there is no network configuration, and a separate "enable"
options toggles cloud-init (simillar to adding/removing a cloud-init
drive for VMs).
Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
---
www/manager6/Makefile | 1 +
www/manager6/lxc/CloudInit.js | 237 ++++++++++++++++++++++++++++++++++
www/manager6/lxc/Config.js | 6 +
3 files changed, 244 insertions(+)
create mode 100644 www/manager6/lxc/CloudInit.js
diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index c94a5cdf..a0e7a2e6 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -189,6 +189,7 @@ JSSRC= \
dc/PCIMapView.js \
dc/USBMapView.js \
lxc/CmdMenu.js \
+ lxc/CloudInit.js \
lxc/Config.js \
lxc/CreateWizard.js \
lxc/DeviceEdit.js \
diff --git a/www/manager6/lxc/CloudInit.js b/www/manager6/lxc/CloudInit.js
new file mode 100644
index 00000000..11d5448d
--- /dev/null
+++ b/www/manager6/lxc/CloudInit.js
@@ -0,0 +1,237 @@
+Ext.define('PVE.lxc.CloudInit', {
+ extend: 'Proxmox.grid.PendingObjectGrid',
+ xtype: 'pveLxcCiPanel',
+
+ tbar: [
+ {
+ xtype: 'proxmoxButton',
+ disabled: true,
+ dangerous: true,
+ confirmMsg: function(rec) {
+ let view = this.up('grid');
+ var warn = gettext('Are you sure you want to remove entry {0}');
+
+ var entry = rec.data.key;
+ var msg = Ext.String.format(warn, "'"
+ + view.renderKey(entry, {}, rec) + "'");
+
+ return msg;
+ },
+ enableFn: function(record) {
+ let view = this.up('grid');
+ var caps = Ext.state.Manager.get('GuiCap');
+ if (view.rows[record.data.key].never_delete ||
+ !caps.vms['VM.Config.Network']) {
+ return false;
+ }
+
+ if (record.data.key === 'cipassword' && !record.data.value) {
+ return false;
+ }
+ return true;
+ },
+ handler: function() {
+ let view = this.up('grid');
+ let records = view.getSelection();
+ if (!records || !records.length) {
+ return;
+ }
+
+ var id = records[0].data.key;
+
+ var params = {};
+ params.delete = id;
+ Proxmox.Utils.API2Request({
+ url: view.baseurl + '/config',
+ waitMsgTarget: view,
+ method: 'PUT',
+ params: params,
+ failure: function(response, opts) {
+ Ext.Msg.alert('Error', response.htmlStatus);
+ },
+ callback: function() {
+ view.reload();
+ },
+ });
+ },
+ text: gettext('Remove'),
+ },
+ {
+ xtype: 'proxmoxButton',
+ disabled: true,
+ enableFn: function(rec) {
+ let view = this.up('pveLxcCiPanel');
+ return !!view.rows[rec.data.key].editor;
+ },
+ handler: function() {
+ let view = this.up('grid');
+ view.run_editor();
+ },
+ text: gettext('Edit'),
+ },
+ ],
+
+ border: false,
+
+ renderKey: function(key, metaData, rec, rowIndex, colIndex, store) {
+ var me = this;
+ var rows = me.rows;
+ var rowdef = rows[key] || {};
+
+ var icon = "";
+ if (rowdef.iconCls) {
+ icon = '<i class="' + rowdef.iconCls + '"></i> ';
+ }
+ return icon + (rowdef.header || key);
+ },
+
+ listeners: {
+ activate: function() {
+ var me = this;
+ me.rstore.startUpdate();
+ },
+ itemdblclick: function() {
+ var me = this;
+ me.run_editor();
+ },
+ },
+
+ initComponent: function() {
+ var me = this;
+
+ var nodename = me.pveSelNode.data.node;
+ if (!nodename) {
+ throw "no node name specified";
+ }
+
+ var vmid = me.pveSelNode.data.vmid;
+ if (!vmid) {
+ throw "no VM ID specified";
+ }
+ var caps = Ext.state.Manager.get('GuiCap');
+ me.baseurl = '/api2/extjs/nodes/' + nodename + '/lxc/' + vmid;
+ me.url = me.baseurl + '/pending';
+ me.editorConfig.url = me.baseurl + '/config';
+ me.editorConfig.pveSelNode = me.pveSelNode;
+
+ let caps_ci = caps.vms['VM.Config.Cloudinit'] || caps.vms['VM.Config.Network'];
+ /* editor is string and object */
+ me.rows = {
+ cienable: {
+ header: gettext('Enable'),
+ iconCls: 'fa fa-cloud',
+ never_delete: true,
+ defaultValue: false,
+ editor: caps_ci ? {
+ xtype: 'proxmoxWindowEdit',
+ subject: gettext('Enable Cloud-Init'),
+ items: [
+ {
+ xtype: 'proxmoxcheckbox',
+ deleteEmpty: true,
+ fieldLabel: gettext('Enable'),
+ name: 'cienable',
+ },
+ ],
+ } : undefined,
+ renderer: Proxmox.Utils.format_boolean,
+ },
+ ciuser: {
+ header: gettext('User'),
+ iconCls: 'fa fa-user',
+ never_delete: true,
+ defaultValue: '',
+ editor: caps_ci ? {
+ xtype: 'proxmoxWindowEdit',
+ subject: gettext('User'),
+ items: [
+ {
+ xtype: 'proxmoxtextfield',
+ deleteEmpty: true,
+ emptyText: Proxmox.Utils.defaultText,
+ fieldLabel: gettext('User'),
+ name: 'ciuser',
+ },
+ ],
+ } : undefined,
+ renderer: function(value) {
+ return value || Proxmox.Utils.defaultText;
+ },
+ },
+ cipassword: {
+ header: gettext('Password'),
+ iconCls: 'fa fa-unlock',
+ defaultValue: '',
+ editor: caps_ci ? {
+ xtype: 'proxmoxWindowEdit',
+ subject: gettext('Password'),
+ items: [
+ {
+ xtype: 'proxmoxtextfield',
+ inputType: 'password',
+ deleteEmpty: true,
+ emptyText: Proxmox.Utils.noneText,
+ fieldLabel: gettext('Password'),
+ name: 'cipassword',
+ },
+ ],
+ } : undefined,
+ renderer: function(value) {
+ return value || Proxmox.Utils.noneText;
+ },
+ },
+ sshkeys: {
+ header: gettext('SSH public key'),
+ iconCls: 'fa fa-key',
+ editor: caps_ci ? 'PVE.qemu.SSHKeyEdit' : undefined,
+ never_delete: true,
+ renderer: function(value) {
+ value = decodeURIComponent(value);
+ var keys = value.split('\n');
+ var text = [];
+ keys.forEach(function(key) {
+ if (key.length) {
+ let res = PVE.Parser.parseSSHKey(key);
+ if (res) {
+ key = Ext.String.htmlEncode(res.comment);
+ if (res.options) {
+ key += ' <span style="color:gray">(' + gettext('with options') + ')</span>';
+ }
+ text.push(key);
+ return;
+ }
+ // Most likely invalid at this point, so just stick to
+ // the old value.
+ text.push(Ext.String.htmlEncode(key));
+ }
+ });
+ if (text.length) {
+ return text.join('<br>');
+ } else {
+ return Proxmox.Utils.noneText;
+ }
+ },
+ defaultValue: '',
+ },
+ ciupgrade: {
+ header: gettext('Upgrade packages'),
+ iconCls: 'fa fa-archive',
+ renderer: Proxmox.Utils.format_boolean,
+ defaultValue: '',
+ editor: {
+ xtype: 'proxmoxWindowEdit',
+ subject: gettext('Upgrade packages on boot'),
+ items: {
+ xtype: 'proxmoxcheckbox',
+ name: 'ciupgrade',
+ uncheckedValue: 0,
+ defaultValue: 0,
+ fieldLabel: gettext('Upgrade packages'),
+ labelWidth: 140,
+ },
+ },
+ },
+ };
+ me.callParent();
+ },
+});
diff --git a/www/manager6/lxc/Config.js b/www/manager6/lxc/Config.js
index a7191fa2..6e53de72 100644
--- a/www/manager6/lxc/Config.js
+++ b/www/manager6/lxc/Config.js
@@ -262,6 +262,12 @@ Ext.define('PVE.lxc.Config', {
itemId: 'dns',
xtype: 'pveLxcDNS',
},
+ {
+ title: 'Cloud-Init',
+ itemId: 'cloudinit',
+ iconCls: 'fa fa-cloud',
+ xtype: 'pveLxcCiPanel',
+ },
{
title: gettext('Options'),
itemId: 'options',
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [pve-devel] [PATCH 7/8 docs] pct: add script to generate cloudinit options
2025-02-10 12:07 [pve-devel] [PATCH 0/8 container/manager/docs] fix #4686: Cloudinit support for LXC Daniel Herzig
` (5 preceding siblings ...)
2025-02-10 12:07 ` [pve-devel] [PATCH 6/8 manager] cloudinit: introduce panel for LXCs Daniel Herzig
@ 2025-02-10 12:07 ` Daniel Herzig
2025-02-13 9:52 ` Fiona Ebner
2025-02-10 12:07 ` [pve-devel] [PATCH 8/8 docs] pct: document cloudinit for LXC Daniel Herzig
7 siblings, 1 reply; 23+ messages in thread
From: Daniel Herzig @ 2025-02-10 12:07 UTC (permalink / raw)
To: pve-devel; +Cc: Leo Nunner
From: Leo Nunner <l.nunner@proxmox.com>
…the same way as it's already being done for VMs.
Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
---
gen-pct-cloud-init-opts.pl | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100755 gen-pct-cloud-init-opts.pl
diff --git a/gen-pct-cloud-init-opts.pl b/gen-pct-cloud-init-opts.pl
new file mode 100755
index 0000000..c22c4d1
--- /dev/null
+++ b/gen-pct-cloud-init-opts.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+use lib '.';
+use strict;
+use warnings;
+use PVE::JSONSchema;
+use PVE::RESTHandler;
+use PVE::LXC::Config;
+
+my $prop = PVE::LXC::Config::cloudinit_config_properties();
+
+my $data = PVE::RESTHandler::dump_properties($prop, 'asciidoc', 'config');
+
+$data =~ s/cloud-init: //g;
+
+print $data;
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 7/8 docs] pct: add script to generate cloudinit options
2025-02-10 12:07 ` [pve-devel] [PATCH 7/8 docs] pct: add script to generate cloudinit options Daniel Herzig
@ 2025-02-13 9:52 ` Fiona Ebner
0 siblings, 0 replies; 23+ messages in thread
From: Fiona Ebner @ 2025-02-13 9:52 UTC (permalink / raw)
To: Proxmox VE development discussion, Daniel Herzig
Am 10.02.25 um 13:07 schrieb Daniel Herzig:
> From: Leo Nunner <l.nunner@proxmox.com>
>
> …the same way as it's already being done for VMs.
Nit: can we avoid the unicode ellipsis here ;)
>
> Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
> ---
> gen-pct-cloud-init-opts.pl | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
> create mode 100755 gen-pct-cloud-init-opts.pl
>
> diff --git a/gen-pct-cloud-init-opts.pl b/gen-pct-cloud-init-opts.pl
> new file mode 100755
> index 0000000..c22c4d1
> --- /dev/null
> +++ b/gen-pct-cloud-init-opts.pl
> @@ -0,0 +1,16 @@
> +#!/usr/bin/perl
> +
> +use lib '.';
Style nit: add a blank line here...
> +use strict;
> +use warnings;
...and here...
> +use PVE::JSONSchema;
> +use PVE::RESTHandler;
> +use PVE::LXC::Config;
...and sort alphabetically.
> +
> +my $prop = PVE::LXC::Config::cloudinit_config_properties();
> +
> +my $data = PVE::RESTHandler::dump_properties($prop, 'asciidoc', 'config');
> +
> +$data =~ s/cloud-init: //g;
> +
> +print $data;
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [pve-devel] [PATCH 8/8 docs] pct: document cloudinit for LXC
2025-02-10 12:07 [pve-devel] [PATCH 0/8 container/manager/docs] fix #4686: Cloudinit support for LXC Daniel Herzig
` (6 preceding siblings ...)
2025-02-10 12:07 ` [pve-devel] [PATCH 7/8 docs] pct: add script to generate cloudinit options Daniel Herzig
@ 2025-02-10 12:07 ` Daniel Herzig
2025-02-12 15:46 ` Fiona Ebner
7 siblings, 1 reply; 23+ messages in thread
From: Daniel Herzig @ 2025-02-10 12:07 UTC (permalink / raw)
To: pve-devel; +Cc: Leo Nunner
From: Leo Nunner <l.nunner@proxmox.com>
adds documentation for Cloud-Init for containers. Most of it has been
taken from the VM documentation, since the configuration mostly works
the same. Added a script to extract the cloudinit parameters the same
way it's already done for VMs.
Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
---
Makefile | 1 +
pct-cloud-init.adoc | 114 ++++++++++++++++++++++++++++++++++++++++++++
pct.adoc | 4 ++
3 files changed, 119 insertions(+)
create mode 100644 pct-cloud-init.adoc
diff --git a/Makefile b/Makefile
index f30d77a..24836b8 100644
--- a/Makefile
+++ b/Makefile
@@ -53,6 +53,7 @@ GEN_SCRIPTS= \
gen-pct.conf.5-opts.pl \
gen-pct-network-opts.pl \
gen-pct-mountpoint-opts.pl \
+ gen-pct-cloud-init-opts.pl \
gen-qm.conf.5-opts.pl \
gen-cpu-models.conf.5-opts.pl \
gen-qm-cloud-init-opts.pl \
diff --git a/pct-cloud-init.adoc b/pct-cloud-init.adoc
new file mode 100644
index 0000000..1398e7b
--- /dev/null
+++ b/pct-cloud-init.adoc
@@ -0,0 +1,114 @@
+[[pct_cloud_init]]
+Cloud-Init Support
+------------------
+ifdef::wiki[]
+:pve-toplevel:
+endif::wiki[]
+
+{pve} supports the Cloud-init 'nocloud' format for LXC.
+
+{pve} writes the Cloud-init configuration directly into the container.
+When the 'cienable' option is set to true, the configuration is updated
+directly before before every boot. Each configuration is identified by
+an 'instance id', which Cloud-Init uses to decide whether it should run
+again or not.
+
+Preparing Cloud-Init Templates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The first step is to prepare your container. Any template will suffice.
+Simply install the Cloud-Init packages inside the CT that you want to
+prepare. On Debian/Ubuntu based systems this is as simple as:
+
+----
+apt install cloud-init
+----
+
+WARNING: This command is *not* intended to be executed on the {pve} host, but
+only inside the container.
+
+A simple preparation for a cloud-init capable container could look like this:
+
+----
+# download an image
+pveam download local ubuntu-22.10-standard_22.10-1_amd64.tar.zst
+
+# create a new container
+pct create 9000 local:vztmpl/ubuntu-22.10-standard_22.10-1_amd64.tar.zst \
+ --storage local-lvm --memory 512 \
+ --net0 name=eth0,bridge=vmbr0,ip=dhcp,type=veth
+----
+
+Now, the package can be installed inside the container:
+
+----
+# install the needed packages
+pct start 9000
+pct exec 9000 apt update
+pct exec 9000 apt install cloud-init
+pct stop 9000
+----
+
+Finally, it can be helpful to turn the container into a template, to be able
+to quickly create clones whenever needed.
+
+----
+pct template 9000
+----
+
+Deploying Cloud-Init Templates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A template can easily be deployed by cloning:
+
+----
+pct clone 9000 3000 --hostname ubuntu
+----
+
+Cloud-Init can now be enabled, and will run automatically on the next boot.
+
+----
+pct set 3000 --cienable=1
+----
+
+Custom Cloud-Init Configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Cloud-Init integration also allows custom config files to be used instead
+of the automatically generated configs. This is done via the `cicustom`
+option on the command line:
+
+----
+pct set 9000 --cicustom "user=<volume>,meta=<volume>"
+----
+
+The custom config files have to be on a storage that supports snippets and have
+to be available on all nodes the container is going to be migrated to. Otherwise the
+container won't be able to start.
+For example:
+
+----
+qm set 9000 --cicustom "user=local:snippets/userconfig.yaml"
+----
+
+In contrast to the options for VMs, containers only support custom 'user'
+and 'vendor' scripts, but not 'network'. Network configuration is done through
+the already existing facilities integrated into {pve}. They can all be specified
+together or mixed and matched however needed.
+The automatically generated config will be used for any section that doesn't have a
+custom config file specified.
+
+The generated config can be dumped to serve as a base for custom configs:
+
+----
+pct cloudinit dump 9000 user
+----
+
+The same command exists for `meta`.
+
+
+Cloud-Init specific Options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+include::pct-cloud-init-opts.adoc[]
+
diff --git a/pct.adoc b/pct.adoc
index 529b72f..de80347 100644
--- a/pct.adoc
+++ b/pct.adoc
@@ -622,6 +622,10 @@ It will be called during various phases of the guests lifetime. For an example
and documentation see the example script under
`/usr/share/pve-docs/examples/guest-example-hookscript.pl`.
+ifndef::wiki[]
+include::pct-cloud-init.adoc[]
+endif::wiki[]
+
Security Considerations
-----------------------
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [pve-devel] [PATCH 8/8 docs] pct: document cloudinit for LXC
2025-02-10 12:07 ` [pve-devel] [PATCH 8/8 docs] pct: document cloudinit for LXC Daniel Herzig
@ 2025-02-12 15:46 ` Fiona Ebner
0 siblings, 0 replies; 23+ messages in thread
From: Fiona Ebner @ 2025-02-12 15:46 UTC (permalink / raw)
To: Proxmox VE development discussion, Daniel Herzig
Planning to look at the code patches tomorrow, for now I started here :)
Am 10.02.25 um 13:07 schrieb Daniel Herzig:
> From: Leo Nunner <l.nunner@proxmox.com>
>
> adds documentation for Cloud-Init for containers. Most of it has been
> taken from the VM documentation, since the configuration mostly works
> the same. Added a script to extract the cloudinit parameters the same
> way it's already done for VMs.
>
> Signed-off-by: Leo Nunner <l.nunner@proxmox.com>
> ---
> Makefile | 1 +
> pct-cloud-init.adoc | 114 ++++++++++++++++++++++++++++++++++++++++++++
> pct.adoc | 4 ++
> 3 files changed, 119 insertions(+)
> create mode 100644 pct-cloud-init.adoc
>
> diff --git a/Makefile b/Makefile
> index f30d77a..24836b8 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -53,6 +53,7 @@ GEN_SCRIPTS= \
> gen-pct.conf.5-opts.pl \
> gen-pct-network-opts.pl \
> gen-pct-mountpoint-opts.pl \
> + gen-pct-cloud-init-opts.pl \
> gen-qm.conf.5-opts.pl \
> gen-cpu-models.conf.5-opts.pl \
> gen-qm-cloud-init-opts.pl \
> diff --git a/pct-cloud-init.adoc b/pct-cloud-init.adoc
> new file mode 100644
> index 0000000..1398e7b
> --- /dev/null
> +++ b/pct-cloud-init.adoc
> @@ -0,0 +1,114 @@
> +[[pct_cloud_init]]
> +Cloud-Init Support
> +------------------
> +ifdef::wiki[]
> +:pve-toplevel:
> +endif::wiki[]
> +
> +{pve} supports the Cloud-init 'nocloud' format for LXC.
s/Cloud-init/Cloud-Init/
Although the official name seems to be "cloud-init", the documentation
for VMs uses "Cloud-Init" as the capitalization, so I think we should
stick to it (or change it to "cloud-init" consistently everywhere).
> +
> +{pve} writes the Cloud-init configuration directly into the container.
s/Cloud-init/Cloud-Init/
> +When the 'cienable' option is set to true, the configuration is updated
> +directly before before every boot. Each configuration is identified by
> +an 'instance id', which Cloud-Init uses to decide whether it should run
> +again or not.
Maybe add a quick sentence what happens if "cienable" is not set, just
for clarity? Hmm, seems strange actually:
* previously added SSH keys will stay added
* previously added users will stay added
* package upgrades seems to revert to default 'No'
If this really is intentional, this should be documented of course.
Seems like it behaves the same for VMs, should be documented there too.
> +
> +Preparing Cloud-Init Templates
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The first step is to prepare your container. Any template will suffice.
> +Simply install the Cloud-Init packages inside the CT that you want to
s/CT/countainer/
> +prepare. On Debian/Ubuntu based systems this is as simple as:
> +
> +----
> +apt install cloud-init
> +----
> +
> +WARNING: This command is *not* intended to be executed on the {pve} host, but
> +only inside the container.
> +
> +A simple preparation for a cloud-init capable container could look like this:
s/cloud-init/Cloud-Init/
> +
> +----
> +# download an image
> +pveam download local ubuntu-22.10-standard_22.10-1_amd64.tar.zst
This one doesn't exists (on PVE 8.3), would be nice to have a working
example.
> +
> +# create a new container
> +pct create 9000 local:vztmpl/ubuntu-22.10-standard_22.10-1_amd64.tar.zst \
> + --storage local-lvm --memory 512 \
Maybe specify an explicit rootfs with size rather than the '--storage'
option. The automatic default of 4 GiB is a bit magic-y and like this,
users won't see how to adapt the size for their use case straight away.
I'd also add --unprivileged 1 --features nesting=1 since that is usually
desired and are the UI defaults too. As well as setting the 'cores'.
> + --net0 name=eth0,bridge=vmbr0,ip=dhcp,type=veth
> +----
> +
> +Now, the package can be installed inside the container:
> +
> +----
> +# install the needed packages
> +pct start 9000
NOTE: you will need to wait until the network is ready ;)
> +pct exec 9000 apt update
> +pct exec 9000 apt install cloud-init
> +pct stop 9000
> +----
> +
> +Finally, it can be helpful to turn the container into a template, to be able
> +to quickly create clones whenever needed.
> +
> +----
> +pct template 9000
> +----
> +
I think there should be a section about describing how to actually
configure the settings (also referring to the UI). Currently, there only
is the description with the custom configuration, but the basic
configuration is not mentioned at all.
> +Deploying Cloud-Init Templates
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +A template can easily be deployed by cloning:
> +
> +----
> +pct clone 9000 3000 --hostname ubuntu
> +----
> +
> +Cloud-Init can now be enabled, and will run automatically on the next boot.
> +
> +----
> +pct set 3000 --cienable=1
> +----
> +
> +Custom Cloud-Init Configuration
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The Cloud-Init integration also allows custom config files to be used instead
> +of the automatically generated configs. This is done via the `cicustom`
> +option on the command line:
> +
> +----
> +pct set 9000 --cicustom "user=<volume>,meta=<volume>"
> +----
> +
> +The custom config files have to be on a storage that supports snippets and have
> +to be available on all nodes the container is going to be migrated to. Otherwise the
> +container won't be able to start.
> +For example:
> +
> +----
> +qm set 9000 --cicustom "user=local:snippets/userconfig.yaml"
Uses qm instead of pct
> +----
> +
> +In contrast to the options for VMs, containers only support custom 'user'
> +and 'vendor' scripts, but not 'network'. Network configuration is done through
> +the already existing facilities integrated into {pve}. They can all be specified
> +together or mixed and matched however needed.
> +The automatically generated config will be used for any section that doesn't have a
> +custom config file specified.
> +
> +The generated config can be dumped to serve as a base for custom configs:
> +
> +----
> +pct cloudinit dump 9000 user
> +----
> +
> +The same command exists for `meta`.
> +
> +
> +Cloud-Init specific Options
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~
Doesn't use title case
> +
> +include::pct-cloud-init-opts.adoc[]
> +
> diff --git a/pct.adoc b/pct.adoc
> index 529b72f..de80347 100644
> --- a/pct.adoc
> +++ b/pct.adoc
> @@ -622,6 +622,10 @@ It will be called during various phases of the guests lifetime. For an example
> and documentation see the example script under
> `/usr/share/pve-docs/examples/guest-example-hookscript.pl`.
>
> +ifndef::wiki[]
> +include::pct-cloud-init.adoc[]
> +endif::wiki[]
> +
> Security Considerations
> -----------------------
>
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 23+ messages in thread