]> git.proxmox.com Git - qemu-server.git/commitdiff
config: define machine schema as property-string
authorMarkus Frank <m.frank@proxmox.com>
Wed, 24 Jan 2024 09:49:15 +0000 (10:49 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Thu, 11 Apr 2024 08:18:27 +0000 (10:18 +0200)
Convert the machine parameter to a property-string and use the machine
type as the default key for backward compatibility.

Signed-off-by: Markus Frank <m.frank@proxmox.com>
PVE/API2/Qemu.pm
PVE/QemuConfig.pm
PVE/QemuServer.pm
PVE/QemuServer/Machine.pm

index dc44dee18dec8b84ee80c39388065c093bca3fae..f3ce83d6f9d4126967a5034e36621d2fae12948c 100644 (file)
@@ -1127,11 +1127,13 @@ __PACKAGE__->register_method({
                        $conf->{vmgenid} = PVE::QemuServer::generate_uuid();
                    }
 
-                   my $machine = $conf->{machine};
+                   my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+                   my $machine = $machine_conf->{type};
                    if (!$machine || $machine =~ m/^(?:pc|q35|virt)$/) {
                        # always pin Windows' machine version on create, they get to easily confused
                        if (PVE::QemuServer::Helpers::windows_version($conf->{ostype})) {
-                           $conf->{machine} = PVE::QemuServer::windows_get_pinned_machine_version($machine);
+                           $machine_conf->{type} = PVE::QemuServer::windows_get_pinned_machine_version($machine);
+                           $conf->{machine} = PVE::QemuServer::Machine::print_machine($machine_conf);
                        }
                    }
 
@@ -1996,6 +1998,9 @@ my $update_vm_api  = sub {
                        );
                    }
                    $conf->{pending}->{$opt} = $param->{$opt};
+               } elsif ($opt eq 'machine') {
+                   my $machine_conf = PVE::QemuServer::Machine::parse_machine($param->{$opt});
+                   $conf->{pending}->{$opt} = $param->{$opt};
                } else {
                    $conf->{pending}->{$opt} = $param->{$opt};
 
index ca30eda0f3333ad606ff35d26b3e852c722ad288..8e8a7828e10e7f0ce2f57318e25d506755f46b89 100644 (file)
@@ -432,7 +432,8 @@ sub __snapshot_rollback_hook {
        } else {
            # Note: old code did not store 'machine', so we try to be smart
            # and guess the snapshot was generated with kvm 1.4 (pc-i440fx-1.4).
-           $data->{forcemachine} = $conf->{machine} || 'pc-i440fx-1.4';
+           my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+           $data->{forcemachine} = $machine_conf->{type} || 'pc-i440fx-1.4';
 
            # we remove the 'machine' configuration if not explicitly specified
            # in the original config.
index 4728811bccd1222fdbee3030f16ed387e4246700..abe175a438e806043a84f3e90b0fdfa614680f75 100644 (file)
@@ -124,14 +124,6 @@ PVE::JSONSchema::register_standard_option('pve-qm-stateuri', {
     optional => 1,
 });
 
-PVE::JSONSchema::register_standard_option('pve-qemu-machine', {
-       description => "Specifies the QEMU machine type.",
-       type => 'string',
-       pattern => '(pc|pc(-i440fx)?-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|q35|pc-q35-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|virt(?:-\d+(\.\d+)+)?(\+pve\d+)?)',
-       maxLength => 40,
-       optional => 1,
-});
-
 # FIXME: remove in favor of just using the INotify one, it's cached there exactly the same way
 my $nodename_cache;
 sub nodename {
@@ -2102,8 +2094,9 @@ sub qemu_created_version_fixups {
     # check if we need to apply some handling for VMs that always use the latest machine version but
     # had a machine version transition happen that affected HW such that, e.g., an OS config change
     # would be required (we do not want to pin machine version for non-windows OS type)
+    my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
     if (
-       (!defined($conf->{machine}) || $conf->{machine} =~ m/^(?:pc|q35|virt)$/) # non-versioned machine
+       (!defined($machine_conf->{type}) || $machine_conf->{type} =~ m/^(?:pc|q35|virt)$/) # non-versioned machine
        && (!defined($meta->{'creation-qemu'}) || !min_version($meta->{'creation-qemu'}, 6, 1)) # created before 6.1
        && (!$forced_vers || min_version($forced_vers, 6, 1)) # handle snapshot-rollback/migrations
        && min_version($kvmver, 6, 1) # only need to apply the change since 6.1
@@ -3259,7 +3252,8 @@ sub windows_get_pinned_machine_version {
 sub get_vm_machine {
     my ($conf, $forcemachine, $arch, $add_pve_version, $kvmversion) = @_;
 
-    my $machine = $forcemachine || $conf->{machine};
+    my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+    my $machine = $forcemachine || $machine_conf->{type};
 
     if (!$machine || $machine =~ m/^(?:pc|q35|virt)$/) {
        $kvmversion //= kvm_user_version();
@@ -3508,6 +3502,8 @@ sub config_to_command {
     my $kvm = $conf->{kvm};
     my $nodename = nodename();
 
+    my $machine_conf = PVE::QemuServer::Machine::parse_machine($conf->{machine});
+
     my $arch = get_vm_arch($conf);
     my $kvm_binary = get_command_for_arch($arch);
     my $kvmver = kvm_user_version($kvm_binary);
index 13721ae8a51779c96a4ad86e995f1c1b059baa76..5e3a75c5967b81a5ebdffa1ce8e4d19dbb6b5aec 100644 (file)
@@ -5,6 +5,7 @@ use warnings;
 
 use PVE::QemuServer::Helpers;
 use PVE::QemuServer::Monitor;
+use PVE::JSONSchema qw(get_standard_option parse_property_string);
 
 # Bump this for VM HW layout changes during a release (where the QEMU machine
 # version stays the same)
@@ -12,10 +13,46 @@ our $PVE_MACHINE_VERSION = {
     '4.1' => 2,
 };
 
+my $machine_fmt = {
+    type => {
+       default_key => 1,
+       description => "Specifies the QEMU machine type.",
+       type => 'string',
+       pattern => '(pc|pc(-i440fx)?-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|q35|pc-q35-\d+(\.\d+)+(\+pve\d+)?(\.pxe)?|virt(?:-\d+(\.\d+)+)?(\+pve\d+)?)',
+       maxLength => 40,
+       format_description => 'machine type',
+       optional => 1,
+    },
+};
+
+PVE::JSONSchema::register_format('pve-qemu-machine-fmt', $machine_fmt);
+
+PVE::JSONSchema::register_standard_option('pve-qemu-machine', {
+    description => "Specify the QEMU machine type.",
+    type => 'string',
+    optional => 1,
+    format => PVE::JSONSchema::get_format('pve-qemu-machine-fmt'),
+});
+
+sub parse_machine {
+    my ($value) = @_;
+
+    return if !$value;
+
+    my $res = parse_property_string($machine_fmt, $value);
+    return $res;
+}
+
+sub print_machine {
+    my ($machine_conf) = @_;
+    return print_property_string($machine_conf, $machine_fmt);
+}
+
 sub machine_type_is_q35 {
     my ($conf) = @_;
 
-    return $conf->{machine} && ($conf->{machine} =~ m/q35/) ? 1 : 0;
+    my $machine_conf = parse_machine($conf->{machine});
+    return $machine_conf->{type} && ($machine_conf->{type} =~ m/q35/) ? 1 : 0;
 }
 
 # In list context, also returns whether the current machine is deprecated or not.
@@ -126,7 +163,8 @@ sub qemu_machine_pxe {
 
     my $machine =  get_current_qemu_machine($vmid);
 
-    if ($conf->{machine} && $conf->{machine} =~ m/\.pxe$/) {
+    my $machine_conf = parse_machine($conf->{machine});
+    if ($machine_conf->{type} && $machine_conf->{type} =~ m/\.pxe$/) {
        $machine .= '.pxe';
     }