diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 652f6431f0e..f5f38edbb2e 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -47,7 +47,6 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
-import com.cloud.resource.RequestWrapper;
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
import org.apache.cloudstack.storage.to.TemplateObjectTO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
@@ -146,6 +145,7 @@ import com.cloud.hypervisor.kvm.storage.KVMStorageProcessor;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.RouterPrivateIpStrategy;
import com.cloud.network.Networks.TrafficType;
+import com.cloud.resource.RequestWrapper;
import com.cloud.resource.ServerResource;
import com.cloud.resource.ServerResourceBase;
import com.cloud.storage.JavaStorageLayer;
@@ -199,7 +199,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
private String _modifyVlanPath;
private String _versionstringpath;
- private String _patchViaSocketPath;
+ private String _patchScriptPath;
private String _createvmPath;
private String _manageSnapshotPath;
private String _resizeVolumePath;
@@ -682,9 +682,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
throw new ConfigurationException("Unable to find versions.sh");
}
- _patchViaSocketPath = Script.findScript(kvmScriptsDir + "/patch/", "patchviasocket.py");
- if (_patchViaSocketPath == null) {
- throw new ConfigurationException("Unable to find patchviasocket.py");
+ _patchScriptPath = Script.findScript(kvmScriptsDir, "patch.sh");
+ if (_patchScriptPath == null) {
+ throw new ConfigurationException("Unable to find patch.sh");
}
_heartBeatPath = Script.findScript(kvmScriptsDir, "kvmheartbeat.sh");
@@ -1362,13 +1362,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
public boolean passCmdLine(final String vmName, final String cmdLine) throws InternalErrorException {
- final Script command = new Script(_patchViaSocketPath, 5 * 1000, s_logger);
+ final Script command = new Script(_patchScriptPath, 30 * 1000, s_logger);
String result;
command.add("-n", vmName);
- command.add("-p", cmdLine.replaceAll(" ", "%"));
+ command.add("-c", cmdLine);
result = command.execute();
if (result != null) {
- s_logger.error("passcmd failed:" + result);
+ s_logger.error("Passing cmdline failed:" + result);
return false;
}
return true;
@@ -2141,12 +2141,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
final SerialDef serial = new SerialDef("pty", null, (short)0);
devices.addDevice(serial);
- /* Add a VirtIO channel for SystemVMs for communication and provisioning */
- if (vmTO.getType() != VirtualMachine.Type.User) {
- devices.addDevice(new ChannelDef(vmTO.getName() + ".vport", ChannelDef.ChannelType.UNIX,
- new File(_qemuSocketsPath + "/" + vmTO.getName() + ".agent")));
- }
-
if (_rngEnable) {
final RngDef rngDevice = new RngDef(_rngPath, _rngBackendModel, _rngRateBytes, _rngRatePeriod);
devices.addDevice(rngDevice);
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
index 5a75f078f9e..18abb1c77b4 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
@@ -115,7 +115,6 @@ public final class LibvirtStartCommandWrapper extends CommandWrapper" +
"" +
"" +
- "" +
- "" +
- "" +
- "" +
- "" +
- "" +
"" +
"" +
"" +
@@ -215,14 +206,9 @@ public class LibvirtDomainXMLParserTest extends TestCase {
assertEquals(channelType, channels.get(i).getChannelType());
}
- /* SSVM provisioning port/channel */
- assertEquals(channelState, channels.get(0).getChannelState());
- assertEquals(new File(ssvmAgentPath), channels.get(0).getPath());
- assertEquals(ssvmAgentName, channels.get(0).getName());
-
/* Qemu Guest Agent port/channel */
- assertEquals(new File(guestAgentPath), channels.get(1).getPath());
- assertEquals(guestAgentName, channels.get(1).getName());
+ assertEquals(new File(guestAgentPath), channels.get(0).getPath());
+ assertEquals(guestAgentName, channels.get(0).getName());
List ifs = parser.getInterfaces();
for (int i = 0; i < ifs.size(); i++) {
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
index b391b94e740..6a06c11fca7 100644
--- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
+++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
@@ -21,13 +21,13 @@ package com.cloud.hypervisor.kvm.resource;
import java.io.File;
-import junit.framework.TestCase;
-
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
import com.cloud.utils.Pair;
+import junit.framework.TestCase;
+
public class LibvirtVMDefTest extends TestCase {
public void testInterfaceEtehrnet() {
@@ -180,7 +180,7 @@ public class LibvirtVMDefTest extends TestCase {
public void testChannelDef() {
ChannelDef.ChannelType type = ChannelDef.ChannelType.UNIX;
ChannelDef.ChannelState state = ChannelDef.ChannelState.CONNECTED;
- String name = "v-136-VM.vport";
+ String name = "v-136-VM.org.qemu.guest_agent.0";
File path = new File("/var/lib/libvirt/qemu/" + name);
ChannelDef channelDef = new ChannelDef(name, type, state, path);
diff --git a/scripts/installer/windows/client.wxs b/scripts/installer/windows/client.wxs
index ee09744fc7b..c54b76cc475 100644
--- a/scripts/installer/windows/client.wxs
+++ b/scripts/installer/windows/client.wxs
@@ -1046,7 +1046,7 @@
-
+
diff --git a/scripts/vm/hypervisor/kvm/patch.sh b/scripts/vm/hypervisor/kvm/patch.sh
new file mode 100755
index 00000000000..e7c79fd9a73
--- /dev/null
+++ b/scripts/vm/hypervisor/kvm/patch.sh
@@ -0,0 +1,80 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -e
+
+# Get the VM name and cmdline
+while getopts "n:c:h" opt; do
+ case ${opt} in
+ n )
+ name=$OPTARG
+ ;;
+ c )
+ cmdline=$(echo $OPTARG | base64 -w 0)
+ ;;
+ h )
+ echo "Usage: $0 -n [VM name] -c [command line]"
+ exit 0
+ ;;
+ esac
+done
+
+SSHKEY_FILE="/root/.ssh/id_rsa.pub.cloud"
+if [ ! -e $SSHKEY_FILE ]; then
+ echo "SSH public key file $SSHKEY_FILE not found!"
+ exit 1
+fi
+
+if ! which virsh > /dev/null; then
+ echo "Libvirt CLI 'virsh' not found"
+ exit 1
+fi
+
+# Read the SSH public key
+sshkey=$(cat $SSHKEY_FILE | base64 -w 0)
+
+# Method to send and write payload inside the VM
+send_file() {
+ local name=${1}
+ local path=${2}
+ local content=${@:3}
+ local fd=$(virsh qemu-agent-command $name "{\"execute\":\"guest-file-open\", \"arguments\":{\"path\":\"$path\",\"mode\":\"w+\"}}" | sed 's/[^:]*:\([^}]*\).*/\1/')
+ virsh qemu-agent-command $name "{\"execute\":\"guest-file-write\", \"arguments\":{\"handle\":$fd,\"buf-b64\":\"$content\"}}" > /dev/null
+ virsh qemu-agent-command $name "{\"execute\":\"guest-file-close\", \"arguments\":{\"handle\":$fd}}" > /dev/null
+}
+
+# Wait for the guest agent to come online
+while ! virsh qemu-agent-command $name '{"execute":"guest-ping"}' >/dev/null 2>&1
+do
+ sleep 0.1
+done
+
+# Test guest agent sanity
+while [ "$(virsh qemu-agent-command $name '{"execute":"guest-sync","arguments":{"id":1234567890}}' 2>/dev/null)" != '{"return":1234567890}' ]
+do
+ sleep 0.1
+done
+
+# Write ssh public key
+send_file $name "/root/.ssh/authorized_keys" $sshkey
+
+# Fix ssh public key permission
+virsh qemu-agent-command $name '{"execute":"guest-exec","arguments":{"path":"chmod","arg":["go-rwx","/root/.ssh/authorized_keys"]}}' > /dev/null
+
+# Write cmdline payload
+send_file $name "/var/cache/cloud/cmdline" $cmdline
diff --git a/scripts/vm/hypervisor/kvm/patchviasocket.py b/scripts/vm/hypervisor/kvm/patchviasocket.py
deleted file mode 100755
index c971d5dcc58..00000000000
--- a/scripts/vm/hypervisor/kvm/patchviasocket.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-#
-# This script connects to the system vm socket and writes the
-# authorized_keys and cmdline data to it. The system VM then
-# reads it from /dev/vport0p1 in cloud_early_config
-#
-
-import argparse
-import os
-import socket
-
-SOCK_FILE = "/var/lib/libvirt/qemu/{name}.agent"
-PUB_KEY_FILE = "/root/.ssh/id_rsa.pub.cloud"
-MESSAGE = "pubkey:{key}\ncmdline:{cmdline}\n"
-
-
-def send_to_socket(sock_file, key_file, cmdline):
- if not os.path.exists(key_file):
- print("ERROR: ssh public key not found on host at {0}".format(key_file))
- return 1
-
- try:
- with open(key_file, "r") as f:
- pub_key = f.read()
- except IOError as e:
- print("ERROR: unable to open {0} - {1}".format(key_file, e.strerror))
- return 1
-
- # Keep old substitution from perl code:
- cmdline = cmdline.replace("%", " ")
-
- msg = MESSAGE.format(key=pub_key, cmdline=cmdline)
-
- if not os.path.exists(sock_file):
- print("ERROR: {0} socket not found".format(sock_file))
- return 1
-
- try:
- s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- s.connect(sock_file)
- s.sendall(msg)
- s.close()
- except IOError as e:
- print("ERROR: unable to connect to {0} - {1}".format(sock_file, e.strerror))
- return 1
-
- return 0 # Success
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Send configuration to system VM socket")
- parser.add_argument("-n", "--name", required=True, help="Name of VM")
- parser.add_argument("-p", "--cmdline", required=True, help="Command line")
-
- arguments = parser.parse_args()
-
- socket_file = SOCK_FILE.format(name=arguments.name)
-
- exit(send_to_socket(socket_file, PUB_KEY_FILE, arguments.cmdline))
diff --git a/scripts/vm/hypervisor/kvm/test_patchviasocket.py b/scripts/vm/hypervisor/kvm/test_patchviasocket.py
deleted file mode 100755
index 6b411d32246..00000000000
--- a/scripts/vm/hypervisor/kvm/test_patchviasocket.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import patchviasocket
-
-import getpass
-import os
-import socket
-import tempfile
-import time
-import threading
-import unittest
-
-KEY_DATA = "I luv\nCloudStack\n"
-CMD_DATA = "/run/this-for-me --please=TRUE! very%quickly"
-NON_EXISTING_FILE = "must-not-exist"
-
-
-def write_key_file():
- _, tmpfile = tempfile.mkstemp(".sck")
- with open(tmpfile, "w") as f:
- f.write(KEY_DATA)
- return tmpfile
-
-
-class SocketThread(threading.Thread):
- def __init__(self):
- super(SocketThread, self).__init__()
- self._data = ""
- self._folder = tempfile.mkdtemp(".sck")
- self._file = os.path.join(self._folder, "socket")
- self._ready = False
-
- def data(self):
- return self._data
-
- def file(self):
- return self._file
-
- def wait_until_ready(self):
- while not self._ready:
- time.sleep(0.050)
-
- def run(self):
- TIMEOUT = 0.314 # Very short time for tests that don't write to socket.
- MAX_SIZE = 10 * 1024
-
- s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- try:
- s.bind(self._file)
- s.listen(1)
- s.settimeout(TIMEOUT)
- try:
- self._ready = True
- client, address = s.accept()
- self._data = client.recv(MAX_SIZE)
- client.close()
- except socket.timeout:
- pass
- finally:
- s.close()
- os.remove(self._file)
- os.rmdir(self._folder)
-
-
-class TestPatchViaSocket(unittest.TestCase):
- def setUp(self):
- self._key_file = write_key_file()
-
- self._unreadable = write_key_file()
- os.chmod(self._unreadable, 0)
-
- self.assertFalse(os.path.exists(NON_EXISTING_FILE))
- self.assertNotEqual("root", getpass.getuser(), "must be non-root user (to test access denied errors)")
-
- def tearDown(self):
- os.remove(self._key_file)
- os.remove(self._unreadable)
-
- def test_write_to_socket(self):
- reader = SocketThread()
- reader.start()
- reader.wait_until_ready()
- self.assertEquals(0, patchviasocket.send_to_socket(reader.file(), self._key_file, CMD_DATA))
- reader.join()
- data = reader.data()
- self.assertIn(KEY_DATA, data)
- self.assertIn(CMD_DATA.replace("%", " "), data)
- self.assertNotIn("LUV", data)
- self.assertNotIn("very%quickly", data) # Testing substitution
-
- def test_host_key_error(self):
- reader = SocketThread()
- reader.start()
- reader.wait_until_ready()
- self.assertEquals(1, patchviasocket.send_to_socket(reader.file(), NON_EXISTING_FILE, CMD_DATA))
- reader.join() # timeout
-
- def test_host_key_access_denied(self):
- reader = SocketThread()
- reader.start()
- reader.wait_until_ready()
- self.assertEquals(1, patchviasocket.send_to_socket(reader.file(), self._unreadable, CMD_DATA))
- reader.join() # timeout
-
- def test_nonexistant_socket_error(self):
- reader = SocketThread()
- reader.start()
- reader.wait_until_ready()
- self.assertEquals(1, patchviasocket.send_to_socket(NON_EXISTING_FILE, self._key_file, CMD_DATA))
- reader.join() # timeout
-
- def test_invalid_socket_error(self):
- reader = SocketThread()
- reader.start()
- reader.wait_until_ready()
- self.assertEquals(1, patchviasocket.send_to_socket(self._key_file, self._key_file, CMD_DATA))
- reader.join() # timeout
-
- def test_access_denied_socket_error(self):
- reader = SocketThread()
- reader.start()
- reader.wait_until_ready()
- self.assertEquals(1, patchviasocket.send_to_socket(self._unreadable, self._key_file, CMD_DATA))
- reader.join() # timeout
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/systemvm/debian/opt/cloud/bin/setup/cloud-early-config b/systemvm/debian/opt/cloud/bin/setup/cloud-early-config
index 8ba7701de8a..6aa0314040c 100755
--- a/systemvm/debian/opt/cloud/bin/setup/cloud-early-config
+++ b/systemvm/debian/opt/cloud/bin/setup/cloud-early-config
@@ -90,41 +90,29 @@ get_boot_params() {
sed -i "s/%/ /g" $CMDLINE
;;
kvm)
- VPORT=$(find /dev/virtio-ports -type l -name '*.vport' 2>/dev/null|head -1)
-
- if [ -z "$VPORT" ]; then
- log_it "No suitable VirtIO port was found in /dev/virtio-ports" && exit 2
+ # Use any old cmdline as backup only
+ if [ -s $CMDLINE ]; then
+ mv $CMDLINE $CMDLINE.old
+ log_it "Found a non-empty old cmdline file"
fi
-
- if [ ! -e "$VPORT" ]; then
- log_it "${VPORT} not loaded, perhaps guest kernel is too old." && exit 2
- fi
-
- local factor=2
- local progress=1
- for i in {1..5}
- do
- while read line; do
- if [[ $line == cmdline:* ]]; then
- cmd=${line//cmdline:/}
- echo $cmd > $CMDLINE
- elif [[ $line == pubkey:* ]]; then
- pubkey=${line//pubkey:/}
- echo $pubkey > /var/cache/cloud/authorized_keys
- echo $pubkey > /root/.ssh/authorized_keys
- fi
- done < $VPORT
- # In case of reboot we do not send the boot args again.
- # So, no need to wait for them, as the boot args are already set at startup
- if [ -s $CMDLINE ]
- then
- log_it "Found a non empty cmdline file. Will now exit the loop and proceed with configuration."
- break;
+ systemctl enable --now qemu-guest-agent
+ # Wait for $CMDLINE file to be written by the qemu-guest-agent
+ for i in {1..60}; do
+ if [ -s $CMDLINE ]; then
+ log_it "Received a new non-empty cmdline file from qemu-guest-agent"
+ break
fi
- sleep ${progress}s
- progress=$[ progress * factor ]
+ sleep 1
done
- chmod go-rwx /root/.ssh/authorized_keys
+ # Use any old cmdline only when new cmdline is not received
+ if [ -e $CMDLINE.old ]; then
+ if [ -s $CMDLINE ]; then
+ rm $CMDLINE.old
+ else
+ mv $CMDLINE.old $CMDLINE
+ log_it "Using old cmdline file, VM was perhaps rebooted."
+ fi
+ fi
;;
vmware)
vmtoolsd --cmd 'machine.id.get' > $CMDLINE
diff --git a/systemvm/debian/root/.ssh/authorized_keys b/systemvm/debian/root/.ssh/authorized_keys
deleted file mode 100644
index c09f6379a34..00000000000
--- a/systemvm/debian/root/.ssh/authorized_keys
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2RIE3hgSAD8zULuyE7KDW9EKh2oVbNGY7iSL/VI5xHLISKh4e8ksTshWjlGBtrUCnuzR7y2BUxZ65RI8XkB1fEDxcOU4/0lVPvJYDSsGveXoOgpLwOtKRoGLgjFUGzBQlj2s6YaYQxoNTqtBVkDIH6ekPNq0Q38hRrFcsVIk1sFo5ejuvFxt2wx6APcFIQtHSNezEDO0GVUScDU1N1YEMMv1PU3M/SrcezkXrGl/efF3kWtY9L5xm7sojHMCCqsI38r8ogof67F7JdWRXM6Nl3VzkdCBzWGcyAl+cYfjzgOiBGXyAyYBk8qqzJjKwUOtdjfRvCyowA/0xBwMW1T7PQ==
diff --git a/systemvm/pom.xml b/systemvm/pom.xml
index 55fc12b9d95..a72e3e9aac7 100644
--- a/systemvm/pom.xml
+++ b/systemvm/pom.xml
@@ -87,12 +87,6 @@
agent.zip
-
- debian/root/.ssh
-
- authorized_keys
-
-
@@ -167,7 +161,6 @@
systemvm.isoagent.zipcloud-scripts.tgz
- authorized_keys
diff --git a/tools/appliance/systemvmtemplate/scripts/configure_systemvm_services.sh b/tools/appliance/systemvmtemplate/scripts/configure_systemvm_services.sh
index 48695014bd9..78d868d8b0f 100644
--- a/tools/appliance/systemvmtemplate/scripts/configure_systemvm_services.sh
+++ b/tools/appliance/systemvmtemplate/scripts/configure_systemvm_services.sh
@@ -19,7 +19,7 @@
set -e
set -x
-CLOUDSTACK_RELEASE=4.11.2
+CLOUDSTACK_RELEASE=4.11.3
function configure_apache2() {
# Enable ssl, rewrite and auth
diff --git a/tools/appliance/systemvmtemplate/template.json b/tools/appliance/systemvmtemplate/template.json
index 1c62b1e0942..083a66c9cfa 100644
--- a/tools/appliance/systemvmtemplate/template.json
+++ b/tools/appliance/systemvmtemplate/template.json
@@ -38,8 +38,8 @@
"disk_interface": "virtio",
"net_device": "virtio-net",
- "iso_url": "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-9.6.0-amd64-netinst.iso",
- "iso_checksum": "fcd77acbd46f33e0a266faf284acc1179ab0a3719e4b8abebac555307aa978aa242d7052c8d41e1a5fc6d1b30bc6ca6d62269e71526b71c9d5199b13339f0e25",
+ "iso_url": "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-9.9.0-amd64-netinst.iso",
+ "iso_checksum": "42d9818abc4a08681dc0638f07e7aeb35d0c44646ab1e5b05a31a71d76c99da52b6192db9a3e852171ac78c2ba6b110b337c0b562c7be3d32e86a105023a6a0c",
"iso_checksum_type": "sha512",
"vm_name": "systemvmtemplate",