[pve-devel] [RFC qemu-server 3/9] api: add /cpu/model/* get endpoint

Stefan Reiter s.reiter at proxmox.com
Thu Oct 28 13:41:44 CEST 2021


For custom models, this returns the saved configuration, for default
models it returns the cputype, vendor and a list of flags that the guest
OS will see when running with this CPU type (using the -list-flags QEMU
parameter).

For custom models it also includes the digest of the whole config, in
case someone retrieved it to modify it with a PUT call afterwards.

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---
 PVE/API2/Qemu/CPU.pm        | 76 ++++++++++++++++++++++++++++++++++++-
 PVE/QemuServer/CPUConfig.pm |  7 ++++
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/PVE/API2/Qemu/CPU.pm b/PVE/API2/Qemu/CPU.pm
index 610ffb9..9cc1d77 100644
--- a/PVE/API2/Qemu/CPU.pm
+++ b/PVE/API2/Qemu/CPU.pm
@@ -5,8 +5,10 @@ use warnings;
 
 use PVE::RESTHandler;
 use PVE::JSONSchema qw(get_standard_option);
+use PVE::INotify;
 use PVE::QemuServer;
 use PVE::QemuServer::CPUConfig;
+use PVE::Tools qw(run_command get_host_arch);
 
 use base qw(PVE::RESTHandler);
 
@@ -49,7 +51,7 @@ __PACKAGE__->register_method({
 		},
 	    },
 	},
-	links => [ { rel => 'child', href => '{name}' } ],
+	links => [ { rel => 'child', href => 'model/{name}' } ],
     },
     code => sub {
 	my $rpcenv = PVE::RPCEnvironment::get();
@@ -144,4 +146,76 @@ __PACKAGE__->register_method({
 	return $retval;
     }});
 
+__PACKAGE__->register_method({
+    name => 'info',
+    path => 'model/{cputype}',
+    method => 'GET',
+    description => 'Retrieve details about a specific CPU model.',
+    permissions => {
+	check => [ 'perm', '/nodes', ['Sys.Audit'] ],
+    },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    node => get_standard_option('pve-node'),
+	    cputype => {
+		type => 'string',
+		description => "Name of the CPU model to query. Prefix with"
+			     . " '-custom' for custom models.",
+	    },
+	},
+    },
+    returns => {
+	type => 'object',
+	properties => PVE::QemuServer::CPUConfig::add_cpu_json_properties({
+	    vendor => {
+		type => 'string',
+		description => 'The CPU vendor reported to the guest OS. Only'
+			    . ' relevant for default models.',
+		optional => 1,
+	    },
+	    digest => get_standard_option('pve-config-digest'),
+	}),
+    },
+    code => sub {
+	my ($param) = @_;
+	my $cputype = $param->{cputype};
+
+	if ($cputype =~ m/^custom-/) {
+	    my $conf = PVE::QemuServer::CPUConfig::load_custom_model_conf();
+	    my $digest = $conf->{digest};
+	    my $retval = PVE::QemuServer::CPUConfig::get_custom_model($cputype);
+	    $retval->{digest} = $digest;
+	    return $retval;
+	}
+
+	# this correctly errors in case $cputype is unknown
+	my $vendor = PVE::QemuServer::CPUConfig::get_cpu_vendor($cputype);
+
+	my $retval = {
+	    cputype => $cputype,
+	    vendor => $vendor,
+	};
+
+	# for built-in models return all flags that QEMU assigns to this model
+	# by default (note that these flags might still differ very slightly
+	# with certain machine versions, but since this output is only intended
+	# for assisting a user in a GUI environment this should be fine)
+	my @flags;
+	my $qemu_binary = PVE::QemuServer::get_command_for_arch(get_host_arch());
+	my $retcode = run_command([$qemu_binary, '-list-flags', '-cpu', $cputype],
+	    outfunc => sub { @flags = split(/\s/, shift); }, noerr => 1);
+
+	if ($retcode || !@flags) {
+	    my $nodename = PVE::INotify::nodename();
+	    warn "warning: could not retrieve QEMU flags for built-in cpu type"
+	       . " '$cputype'. Make sure node '$nodename' has the latest"
+	       . " pve-qemu-kvm.\n";
+	} else {
+	    $retval->{flags} = join(";", map {"+$_"} @flags);
+	}
+
+	return $retval;
+    }});
+
 1;
diff --git a/PVE/QemuServer/CPUConfig.pm b/PVE/QemuServer/CPUConfig.pm
index b9981c8..9be8022 100644
--- a/PVE/QemuServer/CPUConfig.pm
+++ b/PVE/QemuServer/CPUConfig.pm
@@ -320,6 +320,13 @@ sub is_custom_model {
     return $cputype =~ m/^custom-/;
 }
 
+sub get_cpu_vendor {
+    my ($cputype) = @_;
+    my $retval = $cpu_vendor_list->{$cputype} or
+	die "Built-in CPU type '$cputype' does not exist\n";
+    return $retval;
+}
+
 # Use this to get a single model in the format described by $cpu_fmt.
 # Allows names with and without custom- prefix.
 sub get_custom_model {
-- 
2.30.2





More information about the pve-devel mailing list