* [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support
@ 2023-11-16 14:09 Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH cluster v3 1/1] add profiles.cfg to cluster fs Dominik Csapak
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 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 to follow, depends on [0] for the oneOf schema support.
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] 10+ messages in thread
* [pve-devel] [PATCH cluster v3 1/1] add profiles.cfg to cluster fs
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
@ 2023-11-16 14:09 ` Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH guest-common v3 1/1] add profiles section config plugin Dominik Csapak
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 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] 10+ messages in thread
* [pve-devel] [PATCH guest-common v3 1/1] add profiles section config plugin
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH cluster v3 1/1] add profiles.cfg to cluster fs Dominik Csapak
@ 2023-11-16 14:09 ` Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH qemu-server v3 1/3] add the VM profiles plugin Dominik Csapak
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 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(1)' of the SectionConfig so we cannot forget that
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes from v2:
* rename get_guest_ready_config to load_profile
* rename some variables
* fix whitespace + indent
* omit now unncessary global options
* overwrite init of SectionConfig to always call init(1) and inject the
profile-description
* fix description
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..857642e
--- /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(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] 10+ messages in thread
* [pve-devel] [PATCH qemu-server v3 1/3] add the VM profiles plugin
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH cluster v3 1/1] add profiles.cfg to cluster fs Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH guest-common v3 1/1] add profiles section config plugin Dominik Csapak
@ 2023-11-16 14:09 ` Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH qemu-server v3 2/3] api: add profile option to create vm api call Dominik Csapak
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 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] 10+ messages in thread
* [pve-devel] [PATCH qemu-server v3 2/3] api: add profile option to create vm api call
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
` (2 preceding siblings ...)
2023-11-16 14:09 ` [pve-devel] [PATCH qemu-server v3 1/3] add the VM profiles plugin Dominik Csapak
@ 2023-11-16 14:09 ` Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH qemu-server v3 3/3] qm: register and init the profiles plugins Dominik Csapak
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 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>
---
changes from v2:
* adapt to load_profile name change
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] 10+ messages in thread
* [pve-devel] [PATCH qemu-server v3 3/3] qm: register and init the profiles plugins
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
` (3 preceding siblings ...)
2023-11-16 14:09 ` [pve-devel] [PATCH qemu-server v3 2/3] api: add profile option to create vm api call Dominik Csapak
@ 2023-11-16 14:09 ` Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH container v3 1/3] add the CT profiles plugin Dominik Csapak
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 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>
---
changes from v2:
* call init() instead of init(1) since the plugin does that already for us
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] 10+ messages in thread
* [pve-devel] [PATCH container v3 1/3] add the CT profiles plugin
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
` (4 preceding siblings ...)
2023-11-16 14:09 ` [pve-devel] [PATCH qemu-server v3 3/3] qm: register and init the profiles plugins Dominik Csapak
@ 2023-11-16 14:09 ` Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH container v3 2/3] api: add profile option to create ct api call Dominik Csapak
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 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] 10+ messages in thread
* [pve-devel] [PATCH container v3 2/3] api: add profile option to create ct api call
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
` (5 preceding siblings ...)
2023-11-16 14:09 ` [pve-devel] [PATCH container v3 1/3] add the CT profiles plugin Dominik Csapak
@ 2023-11-16 14:09 ` Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH container v3 3/3] pct: register and init the profiles plugins Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH manager v3 1/1] api: add guest profile api endpoint Dominik Csapak
8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 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>
---
changes from v2:
* adapt to load_profile name change
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] 10+ messages in thread
* [pve-devel] [PATCH container v3 3/3] pct: register and init the profiles plugins
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
` (6 preceding siblings ...)
2023-11-16 14:09 ` [pve-devel] [PATCH container v3 2/3] api: add profile option to create ct api call Dominik Csapak
@ 2023-11-16 14:09 ` Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH manager v3 1/1] api: add guest profile api endpoint Dominik Csapak
8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 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>
---
changes from v2:
* call init() instead of init(1) since the plugin already does that for us
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] 10+ messages in thread
* [pve-devel] [PATCH manager v3 1/1] api: add guest profile api endpoint
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
` (7 preceding siblings ...)
2023-11-16 14:09 ` [pve-devel] [PATCH container v3 3/3] pct: register and init the profiles plugins Dominik Csapak
@ 2023-11-16 14:09 ` Dominik Csapak
8 siblings, 0 replies; 10+ messages in thread
From: Dominik Csapak @ 2023-11-16 14:09 UTC (permalink / raw)
To: pve-devel
basic CRUD for the profile section config
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes from v2:
* add type parameter so we can filter the list
(useful for the ui)
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] 10+ messages in thread
end of thread, other threads:[~2023-11-16 14:09 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-16 14:09 [pve-devel] [PATCH cluster/guest-common/qemu-server/container/manager v2] add backend profile support Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH cluster v3 1/1] add profiles.cfg to cluster fs Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH guest-common v3 1/1] add profiles section config plugin Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH qemu-server v3 1/3] add the VM profiles plugin Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH qemu-server v3 2/3] api: add profile option to create vm api call Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH qemu-server v3 3/3] qm: register and init the profiles plugins Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH container v3 1/3] add the CT profiles plugin Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH container v3 2/3] api: add profile option to create ct api call Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH container v3 3/3] pct: register and init the profiles plugins Dominik Csapak
2023-11-16 14:09 ` [pve-devel] [PATCH manager v3 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