Inherits from SectionConfig to provide base parsing infrastructure.

Use with helper functions:
* config_from_file gives bless'd config
* get_model_by_name returns a "formatted" hash for a single CPU model
* config_to_file writes changes back

File reads are cached in a local hash.

Signed-off-by: Stefan Reiter <s.rei...@proxmox.com>
---

This will definitely require some sort of versioning mechanism, otherwise CPU
definitions could be changed after starting a VM, thus breaking live-migration
by starting the migration-target with different parameters.

Hints, ideas, recommendations?


 PVE/QemuServer/CustomCPUConfig.pm | 129 ++++++++++++++++++++++++++++++
 PVE/QemuServer/Makefile           |   1 +
 2 files changed, 130 insertions(+)
 create mode 100644 PVE/QemuServer/CustomCPUConfig.pm

diff --git a/PVE/QemuServer/CustomCPUConfig.pm 
b/PVE/QemuServer/CustomCPUConfig.pm
new file mode 100644
index 0000000..87ba9e6
--- /dev/null
+++ b/PVE/QemuServer/CustomCPUConfig.pm
@@ -0,0 +1,129 @@
+package PVE::QemuServer::CustomCPUConfig;
+
+use strict;
+use warnings;
+use PVE::Tools qw(file_get_contents file_set_contents);
+
+use base qw(PVE::SectionConfig);
+
+my $defaultData = {
+    propertyList => {
+       basemodel => {
+           description => "Emulated CPU type to inherit defaults from.",
+           type => 'string',
+           format_description => 'string',
+           default => 'kvm64',
+       },
+       flags => {
+           description => "List of additional CPU flags separated by ';'."
+                        . " Use '+FLAG' to enable, '-FLAG' to disable a flag."
+                        . " Supports all flags supported by QEMU/KVM.",
+           format_description => '+FLAG[;-FLAG...]',
+           type => 'string',
+           pattern => qr/[+-][a-zA-Z0-9\-_\.]+(;[+-][a-zA-Z0-9\-_\.]+)*/,
+           optional => 1,
+       },
+       'phys-bits' => {
+           type => 'integer',
+           minimum => 1,
+           maximum => 64,
+           optional => 1,
+           description => "The physical memory bits that are reported to the 
guest OS. Must be smaller or equal to the host.",
+       },
+       'host-phys-bits' => {
+           type => 'boolean',
+           default => 0,
+           description => "Whether to report the host's physical memory bits. 
Overrides 'phys-bits' when set.",
+       },
+       vendor => {
+           type => 'string',
+           enum => [qw(default AuthenticAMD GenuineIntel)],
+           default => 'default',
+           description => "The CPU vendor to report. 'default' uses the 
host's.",
+       },
+    }
+};
+
+sub private {
+    return $defaultData;
+}
+
+sub options {
+    return {
+       basemodel => { optional => 1 },
+       flags => { optional => 1 },
+       'phys-bits' => { optional => 1 },
+       'host-phys-bits' => { optional => 1 },
+       vendor => { optional => 1 }
+    };
+}
+
+sub type {
+    return 'cpu-model';
+}
+
+# helpers for reading/parsing and writing/formatting of config files
+
+my $default_filename = "/etc/pve/cpu-models.conf";
+my $cfg_cache = {};
+
+sub config_from_file {
+    my ($filename) = @_;
+
+    $filename //= $default_filename;
+
+    if (my $cached = $cfg_cache->{$filename}) {
+       return $cached;
+    }
+
+    return undef if ! -e $filename;
+
+    my $raw = file_get_contents($filename);
+    my $cfg = __PACKAGE__->parse_config($filename, $raw);
+
+    bless $cfg, qw(PVE::QemuServer::CustomCPUConfig);
+    $cfg_cache->{$filename} = $cfg;
+
+    return $cfg;
+}
+
+sub config_to_file {
+    my ($class, $filename) = @_;
+
+    $filename //= $default_filename;
+
+    $cfg_cache->{$filename} = $class;
+
+    my $raw = $class->write_config($filename);
+    file_set_contents($filename, $raw);
+}
+
+# Use this to get a single model in the format described by $defaultData above
+# Includes the name as an additional property and sets default values for 
undefs
+# Returns undef for unknown $name
+sub get_model_by_name {
+    my ($class, $name) = @_;
+
+    return undef if !defined($class->{ids}->{$name});
+
+    my $model = {
+       name => $name
+    };
+
+    for my $property (keys %{$defaultData->{propertyList}}) {
+       next if $property eq 'type';
+
+       if (my $value = $class->{ids}->{$name}->{$property}) {
+           $model->{$property} = $value;
+       } elsif (my $default = 
$defaultData->{propertyList}->{$property}->{default}) {
+           $model->{$property} = $default;
+       }
+    }
+
+    return $model;
+}
+
+__PACKAGE__->register();
+__PACKAGE__->init();
+
+1;
diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile
index afc39a3..41b4cb6 100644
--- a/PVE/QemuServer/Makefile
+++ b/PVE/QemuServer/Makefile
@@ -5,6 +5,7 @@ SOURCES=PCI.pm          \
        OVF.pm          \
        Cloudinit.pm    \
        Agent.pm        \
+       CustomCPUConfig.pm \
 
 .PHONY: install
 install: ${SOURCES}
-- 
2.20.1


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to