public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support
@ 2023-11-17 11:45 Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH cluster v4 1/1] add profiles.cfg to cluster fs Dominik Csapak
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

This series aims to provide profile support when creating guests (ct/vm)
so that users can reuse options without having to specify them every
time.

UI is still not done, but sending the backend again.

changes from v3:
* adapt to the changes in section config regarding the 'init' ->
  now `init(property_isolation => 1)` instead of `init(1)`

  otherwise there where no changes since v3

changes from v2:
* rename get_guest_ready_config into load_profile
* rename some variables
* add type parameter to profile listing so we can filter
* whitespace fixes
* comment fixes

changes from rfc/v1:
* uses a section config with separated plugins, using the oneOf schema
* move the parsing with preparing into a helper into the Plugin class
* don't save the profile into the 'meta' option, but log it instead

0: https://lists.proxmox.com/pipermail/pve-devel/2023-November/060300.html

pve-cluster:

Dominik Csapak (1):
  add profiles.cfg to cluster fs

 src/PVE/Cluster.pm  | 1 +
 src/pmxcfs/status.c | 1 +
 2 files changed, 2 insertions(+)

pve-guest-common:

Dominik Csapak (1):
  add profiles section config plugin

 src/Makefile               |  2 +
 src/PVE/Profiles/Plugin.pm | 83 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 src/PVE/Profiles/Plugin.pm

qemu-server:

Dominik Csapak (3):
  add the VM profiles plugin
  api: add profile option to create vm api call
  qm: register and init the profiles plugins

 PVE/API2/Qemu.pm      | 23 +++++++++++++++++++++++
 PVE/CLI/qm.pm         |  6 ++++++
 PVE/Makefile          |  1 +
 PVE/Profiles/Makefile |  5 +++++
 PVE/Profiles/VM.pm    | 28 ++++++++++++++++++++++++++++
 PVE/QemuServer.pm     |  6 ++++++
 6 files changed, 69 insertions(+)
 create mode 100644 PVE/Profiles/Makefile
 create mode 100644 PVE/Profiles/VM.pm

pve-container:

Dominik Csapak (3):
  add the CT profiles plugin
  api: add profile option to create ct api call
  pct: register and init the profiles plugins

 src/PVE/API2/LXC.pm       | 23 +++++++++++++++++++++++
 src/PVE/CLI/pct.pm        |  6 ++++++
 src/PVE/Makefile          |  1 +
 src/PVE/Profiles/CT.pm    | 28 ++++++++++++++++++++++++++++
 src/PVE/Profiles/Makefile |  4 ++++
 5 files changed, 62 insertions(+)
 create mode 100644 src/PVE/Profiles/CT.pm
 create mode 100644 src/PVE/Profiles/Makefile

pve-manager:

Dominik Csapak (1):
  api: add guest profile api endpoint

 PVE/API2/Cluster.pm          |   7 +
 PVE/API2/Cluster/Makefile    |   1 +
 PVE/API2/Cluster/Profiles.pm | 239 +++++++++++++++++++++++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 PVE/API2/Cluster/Profiles.pm

-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] [PATCH cluster v4 1/1] add profiles.cfg to cluster fs
  2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
@ 2023-11-17 11:45 ` Dominik Csapak
  2023-11-17 13:54   ` [pve-devel] applied: " Thomas Lamprecht
  2023-11-17 11:45 ` [pve-devel] [PATCH guest-common v4 1/1] add profiles section config plugin Dominik Csapak
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/PVE/Cluster.pm  | 1 +
 src/pmxcfs/status.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/PVE/Cluster.pm b/src/PVE/Cluster.pm
index cfa2583..c01bf89 100644
--- a/src/PVE/Cluster.pm
+++ b/src/PVE/Cluster.pm
@@ -80,6 +80,7 @@ my $observed = {
     'sdn/dns.cfg' => 1,
     'sdn/.running-config' => 1,
     'virtual-guest/cpu-models.conf' => 1,
+    'virtual-guest/profiles.cfg' => 1,
     'mapping/pci.cfg' => 1,
     'mapping/usb.cfg' => 1,
 };
diff --git a/src/pmxcfs/status.c b/src/pmxcfs/status.c
index c8094ac..bcec079 100644
--- a/src/pmxcfs/status.c
+++ b/src/pmxcfs/status.c
@@ -109,6 +109,7 @@ static memdb_change_t memdb_change_array[] = {
 	{ .path = "sdn/dns.cfg" },
 	{ .path = "sdn/.running-config" },
 	{ .path = "virtual-guest/cpu-models.conf" },
+	{ .path = "virtual-guest/profiles.cfg" },
 	{ .path = "firewall/cluster.fw" },
 	{ .path = "mapping/pci.cfg" },
 	{ .path = "mapping/usb.cfg" },
-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] [PATCH guest-common v4 1/1] add profiles section config plugin
  2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH cluster v4 1/1] add profiles.cfg to cluster fs Dominik Csapak
@ 2023-11-17 11:45 ` Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH qemu-server v4 1/3] add the VM profiles plugin Dominik Csapak
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

this is intended to house custom profiles which can be used
on guest creation instead of manually needing to specify every option.

we do special things here:
* we always set 'allow_unknown' to 1, because when using the guest
  specific parts in the cli, we cannot depend on the other one, else
  we'd get a cyclic dependency, and without that we need to ignore
  unknown sections

* we add the 'profile-description' to the options of all registered
  plugins (so we don't have to do it manually)

* we always call 'init(property_isolation => 1)' of the SectionConfig so we cannot forget that

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/Makefile               |  2 +
 src/PVE/Profiles/Plugin.pm | 83 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 src/PVE/Profiles/Plugin.pm

diff --git a/src/Makefile b/src/Makefile
index cbc40c1..d99645c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -17,6 +17,8 @@ install: PVE
 	install -d ${PERL5DIR}/PVE/Mapping
 	install -m 0644 PVE/Mapping/PCI.pm ${PERL5DIR}/PVE/Mapping/
 	install -m 0644 PVE/Mapping/USB.pm ${PERL5DIR}/PVE/Mapping/
+	install -d ${PERL5DIR}/PVE/Profiles
+	install -m 0644 PVE/Profiles/Plugin.pm ${PERL5DIR}/PVE/Profiles/
 	install -d ${PERL5DIR}/PVE/VZDump
 	install -m 0644 PVE/VZDump/Plugin.pm ${PERL5DIR}/PVE/VZDump/
 	install -m 0644 PVE/VZDump/Common.pm ${PERL5DIR}/PVE/VZDump/
diff --git a/src/PVE/Profiles/Plugin.pm b/src/PVE/Profiles/Plugin.pm
new file mode 100644
index 0000000..717383b
--- /dev/null
+++ b/src/PVE/Profiles/Plugin.pm
@@ -0,0 +1,83 @@
+package PVE::Profiles::Plugin;
+
+use strict;
+use warnings;
+
+use PVE::Cluster qw(cfs_register_file);
+use PVE::SectionConfig;
+
+use base qw(PVE::SectionConfig);
+
+my $CFG_PATH = 'virtual-guest/profiles.cfg';
+
+cfs_register_file(
+    $CFG_PATH,
+    sub { __PACKAGE__->parse_config(@_); },
+    sub { __PACKAGE__->write_config(@_); }
+);
+
+my $defaultData = {
+    propertyList => {
+	type => { description => 'Profile type.' },
+	id => {
+	    type => 'string',
+	    description => "The ID of the profile.",
+	    format => 'pve-configid',
+	},
+	'profile-description' => {
+	    description => "Use this to add a short comment about a profile.",
+	    type => 'string',
+	    optional => 1,
+	    maxLength => 128,
+	},
+    },
+};
+
+sub private {
+    return $defaultData;
+}
+
+sub parse_config {
+    my ($class, $filename, $raw, $allow_unknown) = @_;
+
+    # always allow unknown section types, so that qemu-server/pct-container
+    # can parse the file without loading the other plugin type
+    return $class->SUPER::parse_config($filename, $raw, 1);
+}
+
+sub write_config {
+    my ($class, $filename, $cfg, $allow_unknown) = @_;
+
+    return $class->SUPER::write_config($filename, $cfg, 1);
+}
+
+# gets, checks and prepares the guest config
+# throws an error if it does not exist or the type is wrong
+sub load_profile {
+    my ($profile_id, $profile_type) = @_;
+
+    my $cfg = PVE::Cluster::cfs_read_file($CFG_PATH);
+
+    my $profile = $cfg->{ids}->{$profile_id};
+    die "no such profile '$profile_id'\n" if !defined $profile;
+    die "wrong type '$profile->{type}'\n" if $profile->{type} ne $profile_type;
+
+    delete $profile->{type};
+    delete $profile->{'profile-description'};
+
+    return $profile;
+}
+
+# override so we can add the profile description to all sub classes
+sub init {
+    my ($class) = @_;
+
+    $class->SUPER::init(property_isolation => 1);
+
+    my $pdata = $class->private();
+    for my $type (keys $pdata->{plugins}->%*) {
+	$pdata->{options}->{$type}->{'profile-description'} = { optional => 1 };
+    }
+}
+
+1;
-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] [PATCH qemu-server v4 1/3] add the VM profiles plugin
  2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH cluster v4 1/1] add profiles.cfg to cluster fs Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH guest-common v4 1/1] add profiles section config plugin Dominik Csapak
@ 2023-11-17 11:45 ` Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH qemu-server v4 2/3] api: add profile option to create vm api call Dominik Csapak
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

simply uses the json_config_properties for the vm config and maps them
to "vm_${opt}"

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 PVE/Makefile          |  1 +
 PVE/Profiles/Makefile |  5 +++++
 PVE/Profiles/VM.pm    | 28 ++++++++++++++++++++++++++++
 3 files changed, 34 insertions(+)
 create mode 100644 PVE/Profiles/Makefile
 create mode 100644 PVE/Profiles/VM.pm

diff --git a/PVE/Makefile b/PVE/Makefile
index dc173681..d09ca98d 100644
--- a/PVE/Makefile
+++ b/PVE/Makefile
@@ -12,3 +12,4 @@ install:
 	$(MAKE) -C API2 install
 	$(MAKE) -C CLI install
 	$(MAKE) -C QemuServer install
+	$(MAKE) -C Profiles install
diff --git a/PVE/Profiles/Makefile b/PVE/Profiles/Makefile
new file mode 100644
index 00000000..e5f56833
--- /dev/null
+++ b/PVE/Profiles/Makefile
@@ -0,0 +1,5 @@
+SOURCES=VM.pm
+
+.PHONY: install
+install: ${SOURCES}
+	for i in ${SOURCES}; do install -D -m 0644 $$i ${DESTDIR}${PERLDIR}/PVE/Profiles/$$i; done
diff --git a/PVE/Profiles/VM.pm b/PVE/Profiles/VM.pm
new file mode 100644
index 00000000..dc664ec5
--- /dev/null
+++ b/PVE/Profiles/VM.pm
@@ -0,0 +1,28 @@
+package PVE::Profiles::VM;
+
+use strict;
+use warnings;
+
+use PVE::Profiles::Plugin;
+use PVE::QemuServer;
+
+use base qw(PVE::Profiles::Plugin);
+
+sub type {
+    return "vm";
+}
+
+sub properties {
+    return PVE::QemuServer::json_config_properties();
+}
+
+sub options {
+    my $props = PVE::QemuServer::json_config_properties();
+    my $opts = {};
+    for my $opt (keys $props->%*) {
+	$opts->{$opt} = { optional => 1 };
+    }
+    return $opts;
+}
+
+1;
-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] [PATCH qemu-server v4 2/3] api: add profile option to create vm api call
  2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
                   ` (2 preceding siblings ...)
  2023-11-17 11:45 ` [pve-devel] [PATCH qemu-server v4 1/3] add the VM profiles plugin Dominik Csapak
@ 2023-11-17 11:45 ` Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH qemu-server v4 3/3] qm: register and init the profiles plugins Dominik Csapak
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

we use the the profile cfg as the 'param' hash, but overwrite the values
with the ones from the api call, so one can overwrite options from the
profile easily

also we add the used profile to the meta info in the config, since
it might be interesting which one was used

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 PVE/API2/Qemu.pm  | 23 +++++++++++++++++++++++
 PVE/QemuServer.pm |  6 ++++++
 2 files changed, 29 insertions(+)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 38bdaabd..cce36a8d 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -49,6 +49,9 @@ use PVE::SSHInfo;
 use PVE::Replication;
 use PVE::StorageTunnel;
 
+use PVE::Profiles::Plugin;
+use PVE::Profiles::VM;
+
 BEGIN {
     if (!$ENV{PVE_GENERATING_DOCS}) {
 	require PVE::HA::Env::PVE2;
@@ -837,6 +840,11 @@ __PACKAGE__->register_method({
 		    default => 0,
 		    description => "Start VM after it was created successfully.",
 		},
+		profile => {
+		    optional => 1,
+		    type => 'string',
+		    description => "The profile to use as base config.",
+		},
 	    },
 	    1, # with_disk_alloc
 	),
@@ -850,6 +858,19 @@ __PACKAGE__->register_method({
 	my $rpcenv = PVE::RPCEnvironment::get();
 	my $authuser = $rpcenv->get_user();
 
+	my $profile = extract_param($param, 'profile');
+	if (defined($profile)) {
+	    $rpcenv->check_full($authuser, "/mapping/guest-profile/${profile}", ['Mapping.Use']);
+	    my $profile_cfg = eval { PVE::Profiles::Plugin::load_profile($profile, 'vm') };
+	    raise_param_exc({ profile => "$@"}) if $@;
+
+	    for my $opt (keys $param->%*) {
+		$profile_cfg->{$opt} = $param->{$opt};
+	    }
+
+	    $param = $profile_cfg;
+	}
+
 	my $node = extract_param($param, 'node');
 	my $vmid = extract_param($param, 'vmid');
 
@@ -1013,6 +1034,8 @@ __PACKAGE__->register_method({
 		my $conf = $param;
 		my $arch = PVE::QemuServer::get_vm_arch($conf);
 
+		print "using profile '$profile'\n" if $profile;
+
 		$conf->{meta} = PVE::QemuServer::new_meta_info_string();
 
 		my $vollist = [];
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index c465fb6f..1c7e65ea 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -293,6 +293,12 @@ my $meta_info_fmt = {
 	pattern => '\d+(\.\d+)+',
 	optional => 1,
     },
+    'profile' => {
+	type => 'string',
+	description => 'The Profile used during creation.',
+	format => 'pve-configid',
+	optional => 1,
+    },
 };
 
 my $confdesc = {
-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] [PATCH qemu-server v4 3/3] qm: register and init the profiles plugins
  2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
                   ` (3 preceding siblings ...)
  2023-11-17 11:45 ` [pve-devel] [PATCH qemu-server v4 2/3] api: add profile option to create vm api call Dominik Csapak
@ 2023-11-17 11:45 ` Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH container v4 1/3] add the CT profiles plugin Dominik Csapak
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

we have to that here, so the properties/options are correctly configured
when using that feature on the cli

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 PVE/CLI/qm.pm | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/PVE/CLI/qm.pm b/PVE/CLI/qm.pm
index b17b4fe2..82240ba3 100755
--- a/PVE/CLI/qm.pm
+++ b/PVE/CLI/qm.pm
@@ -37,6 +37,12 @@ use PVE::QemuServer::Monitor qw(mon_cmd);
 use PVE::QemuServer::OVF;
 use PVE::QemuServer;
 
+use PVE::Profiles::Plugin;
+use PVE::Profiles::VM;
+
+PVE::Profiles::VM->register();
+PVE::Profiles::Plugin->init();
+
 use PVE::CLIHandler;
 use base qw(PVE::CLIHandler);
 
-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] [PATCH container v4 1/3] add the CT profiles plugin
  2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
                   ` (4 preceding siblings ...)
  2023-11-17 11:45 ` [pve-devel] [PATCH qemu-server v4 3/3] qm: register and init the profiles plugins Dominik Csapak
@ 2023-11-17 11:45 ` Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH container v4 2/3] api: add profile option to create ct api call Dominik Csapak
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

simply uses the json_config_properties for the ct config and maps them
to "ct_${opt}"

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/PVE/Makefile          |  1 +
 src/PVE/Profiles/CT.pm    | 28 ++++++++++++++++++++++++++++
 src/PVE/Profiles/Makefile |  4 ++++
 3 files changed, 33 insertions(+)
 create mode 100644 src/PVE/Profiles/CT.pm
 create mode 100644 src/PVE/Profiles/Makefile

diff --git a/src/PVE/Makefile b/src/PVE/Makefile
index 40742e4..e9ad9a3 100644
--- a/src/PVE/Makefile
+++ b/src/PVE/Makefile
@@ -8,5 +8,6 @@ install: ${SOURCES}
 	make -C LXC install
 	make -C VZDump install
 	make -C CLI install
+	make -C Profiles install
 
 
diff --git a/src/PVE/Profiles/CT.pm b/src/PVE/Profiles/CT.pm
new file mode 100644
index 0000000..513fad4
--- /dev/null
+++ b/src/PVE/Profiles/CT.pm
@@ -0,0 +1,28 @@
+package PVE::Profiles::CT;
+
+use strict;
+use warnings;
+
+use PVE::Profiles::Plugin;
+use PVE::LXC::Config;
+
+use base qw(PVE::Profiles::Plugin);
+
+sub type {
+    return "ct";
+}
+
+sub properties {
+    return PVE::LXC::Config::json_config_properties();
+}
+
+sub options {
+    my $props = PVE::LXC::Config::json_config_properties();
+    my $opts = {};
+    for my $opt (keys $props->%*) {
+	$opts->{$opt} = { optional => 1 };
+    }
+    return $opts;
+}
+
+1;
diff --git a/src/PVE/Profiles/Makefile b/src/PVE/Profiles/Makefile
new file mode 100644
index 0000000..e63a9f2
--- /dev/null
+++ b/src/PVE/Profiles/Makefile
@@ -0,0 +1,4 @@
+
+.PHONY: install
+install:
+	install -D -m 0644 CT.pm ${PERLDIR}/PVE/Profiles/CT.pm
-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] [PATCH container v4 2/3] api: add profile option to create ct api call
  2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
                   ` (5 preceding siblings ...)
  2023-11-17 11:45 ` [pve-devel] [PATCH container v4 1/3] add the CT profiles plugin Dominik Csapak
@ 2023-11-17 11:45 ` Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH container v4 3/3] pct: register and init the profiles plugins Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH manager v4 1/1] api: add guest profile api endpoint Dominik Csapak
  8 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

we use the profile cfg as the 'param' hash, but overwrite the values
with the ones from the api call, so one can overwrite options from
the profile easily

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/PVE/API2/LXC.pm | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index 8839105..12a1439 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -27,6 +27,10 @@ use PVE::API2::LXC::Config;
 use PVE::API2::LXC::Status;
 use PVE::API2::LXC::Snapshot;
 use PVE::JSONSchema qw(get_standard_option);
+
+use PVE::Profiles::Plugin;
+use PVE::Profiles::CT;
+
 use base qw(PVE::RESTHandler);
 
 BEGIN {
@@ -196,6 +200,11 @@ __PACKAGE__->register_method({
 		default => 0,
 		description => "Start the CT after its creation finished successfully.",
 	    },
+	    profile => {
+		optional => 1,
+		type => 'string',
+		description => "The profile to use as base config.",
+	    },
 	}),
     },
     returns => {
@@ -209,6 +218,19 @@ __PACKAGE__->register_method({
 	my $rpcenv = PVE::RPCEnvironment::get();
 	my $authuser = $rpcenv->get_user();
 
+	my $profile = extract_param($param, 'profile');
+	if (defined($profile)) {
+	    $rpcenv->check_full($authuser, "/mapping/guest-profile/${profile}", ['Mapping.Use']);
+	    my $profile_cfg = eval { PVE::Profiles::Plugin::load_profile($profile, 'ct') };
+	    raise_param_exc({ profile => "$@" }) if $@;
+
+	    for my $opt (keys $param->%*) {
+		$profile_cfg->{$opt} = $param->{$opt};
+	    }
+
+	    $param = $profile_cfg;
+	}
+
 	my $node = extract_param($param, 'node');
 	my $vmid = extract_param($param, 'vmid');
 	my $ignore_unpack_errors = extract_param($param, 'ignore-unpack-errors');
@@ -381,6 +403,7 @@ __PACKAGE__->register_method({
 	    my $vollist = [];
 	    eval {
 		my $orig_mp_param; # only used if $restore
+		print "using profile '$profile'\n" if $profile;
 		if ($restore) {
 		    die "can't overwrite running container\n" if PVE::LXC::check_running($vmid);
 		    if ($archive ne '-') {
-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] [PATCH container v4 3/3] pct: register and init the profiles plugins
  2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
                   ` (6 preceding siblings ...)
  2023-11-17 11:45 ` [pve-devel] [PATCH container v4 2/3] api: add profile option to create ct api call Dominik Csapak
@ 2023-11-17 11:45 ` Dominik Csapak
  2023-11-17 11:45 ` [pve-devel] [PATCH manager v4 1/1] api: add guest profile api endpoint Dominik Csapak
  8 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

we have to that here, so the properties/options are correctly configured
when using that feature on the cli

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/PVE/CLI/pct.pm | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/PVE/CLI/pct.pm b/src/PVE/CLI/pct.pm
index a0b9bce..e579b7a 100755
--- a/src/PVE/CLI/pct.pm
+++ b/src/PVE/CLI/pct.pm
@@ -24,6 +24,12 @@ use PVE::API2::LXC::Snapshot;
 use PVE::API2::LXC::Status;
 use PVE::API2::LXC;
 
+use PVE::Profiles::Plugin;
+use PVE::Profiles::CT;
+
+PVE::Profiles::CT->register();
+PVE::Profiles::Plugin->init();
+
 use base qw(PVE::CLIHandler);
 
 my $nodename = PVE::INotify::nodename();
-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] [PATCH manager v4 1/1] api: add guest profile api endpoint
  2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
                   ` (7 preceding siblings ...)
  2023-11-17 11:45 ` [pve-devel] [PATCH container v4 3/3] pct: register and init the profiles plugins Dominik Csapak
@ 2023-11-17 11:45 ` Dominik Csapak
  8 siblings, 0 replies; 11+ messages in thread
From: Dominik Csapak @ 2023-11-17 11:45 UTC (permalink / raw)
  To: pve-devel

basic CRUD for the profile section config

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 PVE/API2/Cluster.pm          |   7 +
 PVE/API2/Cluster/Makefile    |   1 +
 PVE/API2/Cluster/Profiles.pm | 239 +++++++++++++++++++++++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 PVE/API2/Cluster/Profiles.pm

diff --git a/PVE/API2/Cluster.pm b/PVE/API2/Cluster.pm
index 04387ab4..d628df85 100644
--- a/PVE/API2/Cluster.pm
+++ b/PVE/API2/Cluster.pm
@@ -30,6 +30,7 @@ use PVE::API2::Cluster::Mapping;
 use PVE::API2::Cluster::Jobs;
 use PVE::API2::Cluster::MetricServer;
 use PVE::API2::Cluster::Notifications;
+use PVE::API2::Cluster::Profiles;
 use PVE::API2::ClusterConfig;
 use PVE::API2::Firewall::Cluster;
 use PVE::API2::HAConfig;
@@ -103,6 +104,11 @@ __PACKAGE__->register_method ({
     path => 'mapping',
 });
 
+__PACKAGE__->register_method ({
+    subclass => "PVE::API2::Cluster::Profiles",
+    path => 'profiles',
+});
+
 if ($have_sdn) {
     __PACKAGE__->register_method ({
        subclass => "PVE::API2::Network::SDN",
@@ -158,6 +164,7 @@ __PACKAGE__->register_method ({
 	    { name => 'notifications' },
 	    { name => 'nextid' },
 	    { name => 'options' },
+	    { name => 'profiles' },
 	    { name => 'replication' },
 	    { name => 'resources' },
 	    { name => 'status' },
diff --git a/PVE/API2/Cluster/Makefile b/PVE/API2/Cluster/Makefile
index b109e5cb..35a3f871 100644
--- a/PVE/API2/Cluster/Makefile
+++ b/PVE/API2/Cluster/Makefile
@@ -9,6 +9,7 @@ PERLSOURCE= 			\
 	MetricServer.pm		\
 	Mapping.pm		\
 	Notifications.pm		\
+	Profiles.pm		\
 	Jobs.pm			\
 	Ceph.pm
 
diff --git a/PVE/API2/Cluster/Profiles.pm b/PVE/API2/Cluster/Profiles.pm
new file mode 100644
index 00000000..1631f4bd
--- /dev/null
+++ b/PVE/API2/Cluster/Profiles.pm
@@ -0,0 +1,239 @@
+package PVE::API2::Cluster::Profiles;
+
+use warnings;
+use strict;
+
+use PVE::Tools qw(extract_param extract_sensitive_params);
+use PVE::Exception qw(raise_perm_exc raise_param_exc);
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::RPCEnvironment;
+
+use PVE::Profiles::Plugin;
+use PVE::Profiles::VM;
+use PVE::Profiles::CT;
+
+PVE::Profiles::VM->register();
+PVE::Profiles::CT->register();
+PVE::Profiles::Plugin->init(1);
+
+use PVE::RESTHandler;
+
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method ({
+    name => 'profile_index',
+    path => '',
+    method => 'GET',
+    description => "List configured guest profiles.",
+    permissions => {
+	user => 'all',
+	description => "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or".
+	    " 'Mapping.Audit' permissions on 'mapping/guest-profile/<id>'.",
+    },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    type => {
+		type => 'string',
+		description => "If set, return only profiles of this type.",
+		optional => 1,
+		enum => ['vm', 'ct'],
+	    },
+	},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {
+		id => {
+		    description => "The ID of the entry.",
+		    type => 'string'
+		},
+		type => {
+		    description => "Plugin type.",
+		    type => 'string',
+		},
+	    },
+	},
+	links => [ { rel => 'child', href => "{id}" } ],
+    },
+    code => sub {
+	my ($param) = @_;
+
+	my $rpcenv = PVE::RPCEnvironment::get();
+	my $authuser = $rpcenv->get_user();
+
+	my $res = [];
+	my $cfg = PVE::Cluster::cfs_read_file('virtual-guest/profiles.cfg');
+	my $can_see_mapping_privs = ['Mapping.Modify', 'Mapping.Use', 'Mapping.Audit'];
+
+	for my $id (sort keys $cfg->{ids}->%*) {
+	    next if !$rpcenv->check_any($authuser, "/mapping/guest-profile/$id", $can_see_mapping_privs, 1);
+	    my $plugin_config = $cfg->{ids}->{$id};
+	    next if defined($param->{type}) && $plugin_config->{type} ne $param->{type};
+	    push @$res, {
+		id => $id,
+		type => $plugin_config->{type},
+		'profile-description' => $plugin_config->{'profile-description'},
+	    };
+	}
+
+	return $res;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'read',
+    path => '{id}',
+    method => 'GET',
+    description => "Read profile configuration.",
+    permissions => {
+	check =>['or',
+	    ['perm', '/mapping/guest-profile/{id}', ['Mapping.Use']],
+	    ['perm', '/mapping/guest-profile/{id}', ['Mapping.Modify']],
+	    ['perm', '/mapping/guest-profile/{id}', ['Mapping.Audit']],
+	],
+    },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    id => {
+		type => 'string',
+		format => 'pve-configid',
+	    },
+	},
+    },
+    returns => { type => 'object' },
+    code => sub {
+	my ($param) = @_;
+
+	my $cfg = PVE::Cluster::cfs_read_file('virtual-guest/profiles.cfg');
+	my $id = $param->{id};
+
+	raise_param_exc({id => "no such profile '$id'"}) if !defined($cfg->{ids}->{$id});
+
+	return $cfg->{ids}->{$id};
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'create',
+    path => '{id}',
+    protected => 1,
+    method => 'POST',
+    description => "Create a new profile.",
+    permissions => {
+	check => ['perm', '/mapping/guest-profile', ['Mapping.Modify']],
+    },
+    parameters => PVE::Profiles::Plugin->createSchema(),
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+
+	my $type = extract_param($param, 'type');
+	my $plugin = PVE::Profiles::Plugin->lookup($type);
+	my $id = extract_param($param, 'id');
+
+	PVE::Cluster::cfs_lock_file('virtual-guest/profiles.cfg', undef, sub {
+	    my $cfg = PVE::Cluster::cfs_read_file('virtual-guest/profiles.cfg');
+
+	    raise_param_exc({id => "Profile '$id' already exists"})
+		if $cfg->{ids}->{$id};
+
+	    my $opts = $plugin->check_config($id, $param, 1, 1);
+
+	    $cfg->{ids}->{$id} = $opts;
+
+	    PVE::Cluster::cfs_write_file('virtual-guest/profiles.cfg', $cfg);
+	});
+	die $@ if $@;
+
+	return;
+    }});
+
+
+__PACKAGE__->register_method ({
+    name => 'update',
+    protected => 1,
+    path => '{id}',
+    method => 'PUT',
+    description => "Update profile configuration.",
+    permissions => {
+	check => ['perm', '/mapping/guest-profile/{id}', ['Mapping.Modify']],
+    },
+    parameters => PVE::Profiles::Plugin->updateSchema(),
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+
+	my $id = extract_param($param, 'id');
+	my $type = extract_param($param, 'type');
+	my $digest = extract_param($param, 'digest');
+	my $delete = extract_param($param, 'delete');
+
+	if ($delete) {
+	    $delete = [PVE::Tools::split_list($delete)];
+	}
+
+	PVE::Cluster::cfs_lock_file('virtual-guest/profiles.cfg', undef, sub {
+	    my $cfg = PVE::Cluster::cfs_read_file('virtual-guest/profiles.cfg');
+
+	    PVE::SectionConfig::assert_if_modified($cfg, $digest);
+
+	    my $data = $cfg->{ids}->{$id};
+	    raise_param_exc({id => "no such profile '$id'"}) if !defined($data);
+	    raise_param_exc({type => "wrong type '$type"}) if $type ne $data->{type};
+
+	    my $plugin = PVE::Profiles::Plugin->lookup($data->{type});
+	    my $opts = $plugin->check_config($id, $param, 0, 1);
+
+	    my $options = $plugin->private()->{options}->{$data->{type}};
+	    PVE::SectionConfig::delete_from_config($data, $options, $opts, $delete);
+
+	    $data->{$_} = $opts->{$_} for keys $opts->%*;
+
+	    PVE::Cluster::cfs_write_file('virtual-guest/profiles.cfg', $cfg);
+	});
+	die $@ if $@;
+
+	return;
+    }});
+
+__PACKAGE__->register_method ({
+    name => 'delete',
+    protected => 1,
+    path => '{id}',
+    method => 'DELETE',
+    description => "Remove profile.",
+    permissions => {
+	check => [ 'perm', '/mapping/guest-profile', ['Mapping.Modify']],
+    },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    id => {
+		type => 'string',
+		format => 'pve-configid',
+	    },
+	}
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+
+	my $id = $param->{id};
+
+	PVE::Cluster::cfs_lock_file('virtual-guest/profiles.cfg', undef, sub {
+	    my $cfg = PVE::Cluster::cfs_read_file('virtual-guest/profiles.cfg');
+
+	    if ($cfg->{ids}->{$id}) {
+		delete $cfg->{ids}->{$id};
+	    }
+
+	    PVE::Cluster::cfs_write_file('virtual-guest/profiles.cfg', $cfg);
+	});
+	die $@ if $@;
+
+	return;
+    }});
+
+1;
-- 
2.30.2





^ permalink raw reply	[flat|nested] 11+ messages in thread

* [pve-devel] applied: [PATCH cluster v4 1/1] add profiles.cfg to cluster fs
  2023-11-17 11:45 ` [pve-devel] [PATCH cluster v4 1/1] add profiles.cfg to cluster fs Dominik Csapak
@ 2023-11-17 13:54   ` Thomas Lamprecht
  0 siblings, 0 replies; 11+ messages in thread
From: Thomas Lamprecht @ 2023-11-17 13:54 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

Am 17/11/2023 um 12:45 schrieb Dominik Csapak:
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  src/PVE/Cluster.pm  | 1 +
>  src/pmxcfs/status.c | 1 +
>  2 files changed, 2 insertions(+)
> 
>

I'm currently preparing a version bump, and it might be easier for all
if this is already included, even if we'd drop it again (unlikely), so:

applied this one for now, thanks!




^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-11-17 13:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-17 11:45 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v4] add backend profile support Dominik Csapak
2023-11-17 11:45 ` [pve-devel] [PATCH cluster v4 1/1] add profiles.cfg to cluster fs Dominik Csapak
2023-11-17 13:54   ` [pve-devel] applied: " Thomas Lamprecht
2023-11-17 11:45 ` [pve-devel] [PATCH guest-common v4 1/1] add profiles section config plugin Dominik Csapak
2023-11-17 11:45 ` [pve-devel] [PATCH qemu-server v4 1/3] add the VM profiles plugin Dominik Csapak
2023-11-17 11:45 ` [pve-devel] [PATCH qemu-server v4 2/3] api: add profile option to create vm api call Dominik Csapak
2023-11-17 11:45 ` [pve-devel] [PATCH qemu-server v4 3/3] qm: register and init the profiles plugins Dominik Csapak
2023-11-17 11:45 ` [pve-devel] [PATCH container v4 1/3] add the CT profiles plugin Dominik Csapak
2023-11-17 11:45 ` [pve-devel] [PATCH container v4 2/3] api: add profile option to create ct api call Dominik Csapak
2023-11-17 11:45 ` [pve-devel] [PATCH container v4 3/3] pct: register and init the profiles plugins Dominik Csapak
2023-11-17 11:45 ` [pve-devel] [PATCH manager v4 1/1] api: add guest profile api endpoint Dominik Csapak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal