]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
esx: Add VNC support
authorMatthias Bolte <matthias.bolte@googlemail.com>
Sat, 16 Jan 2010 12:52:34 +0000 (13:52 +0100)
committerMatthias Bolte <matthias.bolte@googlemail.com>
Mon, 18 Jan 2010 00:44:20 +0000 (01:44 +0100)
* src/conf/domain_conf.c: add defaults for the video device
* src/esx/esx_vmx.[ch]: add VNC support to the VMX handling
* tests/vmx2xmltest.c, tests/xml2vmxtest.c: add tests for the VNC support

src/conf/domain_conf.c
src/esx/esx_vmx.c
src/esx/esx_vmx.h
tests/vmx2xmldata/vmx2xml-graphics-vnc.vmx [new file with mode: 0644]
tests/vmx2xmldata/vmx2xml-graphics-vnc.xml [new file with mode: 0644]
tests/vmx2xmltest.c
tests/xml2vmxdata/xml2vmx-graphics-vnc.vmx [new file with mode: 0644]
tests/xml2vmxdata/xml2vmx-graphics-vnc.xml [new file with mode: 0644]
tests/xml2vmxtest.c

index 126e7e186f8c65ae0dc4a5e167f7c17cd1d35c3a..5c427fbcbbe770634b15206e21ab02673b3c44e3 100644 (file)
@@ -2490,6 +2490,8 @@ virDomainVideoDefaultRAM(virDomainDefPtr def,
     case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
         if (def->virtType == VIR_DOMAIN_VIRT_VBOX)
             return 8 * 1024;
+        else if (def->virtType == VIR_DOMAIN_VIRT_VMWARE)
+            return 4 * 1024;
         else
             return 9 * 1024;
         break;
@@ -2523,6 +2525,9 @@ virDomainVideoDefaultType(virDomainDefPtr def)
     case VIR_DOMAIN_VIRT_VBOX:
         return VIR_DOMAIN_VIDEO_TYPE_VBOX;
 
+    case VIR_DOMAIN_VIRT_VMWARE:
+        return VIR_DOMAIN_VIDEO_TYPE_VMVGA;
+
     default:
         return -1;
     }
index 4b334b6cad7c44e8f886b8c428c9552e1619600c..52041428fa19b6a3161e0e974b9ad90e1092bb9a 100644 (file)
@@ -736,7 +736,7 @@ esxVMX_ParseConfig(virConnectPtr conn, esxVI_Context *ctx, const char *vmx,
     char *guestOS = NULL;
     int controller;
     int port;
-    int present;
+    int present; // boolean
     char *scsi_virtualDev = NULL;
     int id;
 
@@ -974,7 +974,20 @@ esxVMX_ParseConfig(virConnectPtr conn, esxVI_Context *ctx, const char *vmx,
     def->localtime*/
 
     /* def:graphics */
-    /* FIXME */
+    if (VIR_ALLOC_N(def->graphics, 1) < 0) {
+        virReportOOMError(conn);
+        goto failure;
+    }
+
+    def->ngraphics = 0;
+
+    if (esxVMX_ParseVNC(conn, conf, &def->graphics[def->ngraphics]) < 0) {
+        goto failure;
+    }
+
+    if (def->graphics[def->ngraphics] != NULL) {
+        ++def->ngraphics;
+    }
 
     /* def:disks: 4 * 15 scsi + 2 * 2 ide + 2 floppy = 66 */
     if (VIR_ALLOC_N(def->disks, 66) < 0) {
@@ -1161,6 +1174,70 @@ esxVMX_ParseConfig(virConnectPtr conn, esxVI_Context *ctx, const char *vmx,
 
 
 
+int
+esxVMX_ParseVNC(virConnectPtr conn, virConfPtr conf, virDomainGraphicsDefPtr *def)
+{
+    int enabled = 0; // boolean
+    long long port = 0;
+
+    if (def == NULL || *def != NULL) {
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
+        return -1;
+    }
+
+    if (esxUtil_GetConfigBoolean(conn, conf, "RemoteDisplay.vnc.enabled",
+                                 &enabled, 0, 1) < 0) {
+        return -1;
+    }
+
+    if (! enabled) {
+        return 0;
+    }
+
+    if (VIR_ALLOC(*def) < 0) {
+        virReportOOMError(conn);
+        goto failure;
+    }
+
+    (*def)->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
+
+    if (esxUtil_GetConfigLong(conn, conf, "RemoteDisplay.vnc.port",
+                              &port, -1, 1) < 0 ||
+        esxUtil_GetConfigString(conn, conf, "RemoteDisplay.vnc.ip",
+                                &(*def)->data.vnc.listenAddr, 1) < 0 ||
+        esxUtil_GetConfigString(conn, conf, "RemoteDisplay.vnc.keymap",
+                                &(*def)->data.vnc.keymap, 1) < 0 ||
+        esxUtil_GetConfigString(conn, conf, "RemoteDisplay.vnc.password",
+                                &(*def)->data.vnc.passwd, 1) < 0) {
+        goto failure;
+    }
+
+    if (port < 0) {
+        VIR_WARN0("VNC is enabled but VMX entry 'RemoteDisplay.vnc.port' "
+                  "is missing, the VNC port is unknown");
+
+        (*def)->data.vnc.port = 0;
+        (*def)->data.vnc.autoport = 1;
+    } else {
+        if (port < 5900 || port > 5964) {
+            VIR_WARN("VNC port %lld it out of [5900..5964] range", port);
+        }
+
+        (*def)->data.vnc.port = port;
+        (*def)->data.vnc.autoport = 0;
+    }
+
+    return 0;
+
+  failure:
+    virDomainGraphicsDefFree(*def);
+    *def = NULL;
+
+    return -1;
+}
+
+
+
 int
 esxVMX_ParseSCSIController(virConnectPtr conn, virConfPtr conf, int controller,
                            int *present, char **virtualDev)
@@ -2215,7 +2292,7 @@ esxVMX_FormatConfig(virConnectPtr conn, esxVI_Context *ctx,
                           (int)(def->memory / 1024));
     }
 
-    /* vmx:numvcpus -> def:vcpus */
+    /* def:vcpus -> vmx:numvcpus */
     if (def->vcpus <= 0 || (def->vcpus % 2 != 0 && def->vcpus != 1)) {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
                   "Expecting domain XML entry 'vcpu' to be an unsigned "
@@ -2261,6 +2338,24 @@ esxVMX_FormatConfig(virConnectPtr conn, esxVI_Context *ctx,
         virBufferAddLit(&buffer, "\"\n");
     }
 
+    /* def:graphics */
+    for (i = 0; i < def->ngraphics; ++i) {
+        switch (def->graphics[i]->type) {
+          case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
+            if (esxVMX_FormatVNC(conn, def->graphics[i], &buffer) < 0) {
+                goto failure;
+            }
+
+            break;
+
+          default:
+            ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                      "Unsupported graphics type '%s'",
+                      virDomainGraphicsTypeToString(def->graphics[i]->type));
+            goto failure;
+        }
+    }
+
     /* def:disks */
     int scsi_present[4] = { 0, 0, 0, 0 };
     char *scsi_virtualDev[4] = { NULL, NULL, NULL, NULL };
@@ -2306,7 +2401,7 @@ esxVMX_FormatConfig(virConnectPtr conn, esxVI_Context *ctx,
 
           default:
             ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
-                      "Unsuppotred disk device type '%s'",
+                      "Unsupported disk device type '%s'",
                       virDomainDiskDeviceTypeToString(def->disks[i]->device));
             goto failure;
         }
@@ -2361,6 +2456,49 @@ esxVMX_FormatConfig(virConnectPtr conn, esxVI_Context *ctx,
 
 
 
+int
+esxVMX_FormatVNC(virConnectPtr conn, virDomainGraphicsDefPtr def, virBufferPtr buffer)
+{
+    if (def->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
+        return -1;
+    }
+
+    virBufferVSprintf(buffer, "RemoteDisplay.vnc.enabled = \"true\"\n");
+
+    if (def->data.vnc.autoport) {
+        VIR_WARN0("VNC autoport is enabled, but the automatically assigned "
+                  "VNC port cannot be read back");
+    } else {
+        if (def->data.vnc.port < 5900 || def->data.vnc.port > 5964) {
+            VIR_WARN("VNC port %d it out of [5900..5964] range",
+                     def->data.vnc.port);
+        }
+
+        virBufferVSprintf(buffer, "RemoteDisplay.vnc.port = \"%d\"\n",
+                          def->data.vnc.port);
+    }
+
+    if (def->data.vnc.listenAddr != NULL) {
+        virBufferVSprintf(buffer, "RemoteDisplay.vnc.ip = \"%s\"\n",
+                          def->data.vnc.listenAddr);
+    }
+
+    if (def->data.vnc.keymap != NULL) {
+        virBufferVSprintf(buffer, "RemoteDisplay.vnc.keymap = \"%s\"\n",
+                          def->data.vnc.keymap);
+    }
+
+    if (def->data.vnc.passwd != NULL) {
+        virBufferVSprintf(buffer, "RemoteDisplay.vnc.password = \"%s\"\n",
+                          def->data.vnc.passwd);
+    }
+
+    return 0;
+}
+
+
+
 int
 esxVMX_FormatHardDisk(virConnectPtr conn, esxVI_Context *ctx,
                       virDomainDiskDefPtr def, virBufferPtr buffer)
index 9a66e49f8bb56c2ab78ef3d76fe3ef5d10342f2e..0c06fefbba88b3f51f08890461b3b5a453bc8cac 100644 (file)
@@ -65,6 +65,9 @@ esxVMX_ParseConfig(virConnectPtr conn, esxVI_Context *ctx, const char *vmx,
                    const char *datastoreName, const char *directoryName,
                    esxVI_APIVersion apiVersion);
 
+int
+esxVMX_ParseVNC(virConnectPtr conn, virConfPtr conf, virDomainGraphicsDefPtr *def);
+
 int
 esxVMX_ParseSCSIController(virConnectPtr conn, virConfPtr conf,
                            int controller, int *present, char **virtualDev);
@@ -101,6 +104,9 @@ char *
 esxVMX_FormatConfig(virConnectPtr conn, esxVI_Context *ctx,
                     virDomainDefPtr def, esxVI_APIVersion apiVersion);
 
+int
+esxVMX_FormatVNC(virConnectPtr conn, virDomainGraphicsDefPtr def, virBufferPtr buffer);
+
 int
 esxVMX_FormatHardDisk(virConnectPtr conn, esxVI_Context *ctx,
                       virDomainDiskDefPtr def, virBufferPtr buffer);
diff --git a/tests/vmx2xmldata/vmx2xml-graphics-vnc.vmx b/tests/vmx2xmldata/vmx2xml-graphics-vnc.vmx
new file mode 100644 (file)
index 0000000..bd3e55f
--- /dev/null
@@ -0,0 +1,6 @@
+config.version = "8"
+virtualHW.version = "4"
+RemoteDisplay.vnc.enabled = "true"
+RemoteDisplay.vnc.port = "5903"
+RemoteDisplay.vnc.keymap = "de"
+RemoteDisplay.vnc.password = "password"
diff --git a/tests/vmx2xmldata/vmx2xml-graphics-vnc.xml b/tests/vmx2xmldata/vmx2xml-graphics-vnc.xml
new file mode 100644 (file)
index 0000000..159324d
--- /dev/null
@@ -0,0 +1,17 @@
+<domain type='vmware'>
+  <uuid>00000000-0000-0000-0000-000000000000</uuid>
+  <memory>32768</memory>
+  <currentMemory>32768</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686'>hvm</type>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <input type='mouse' bus='ps2'/>
+    <graphics type='vnc' port='5903' autoport='no' keymap='de' passwd='password'/>
+  </devices>
+</domain>
index 0cb387b2c6b1af04db71a4a23fc3316bc68ab176..2e4547e88ed693db62c03792f9b87dcc56d8d8d8 100644 (file)
@@ -42,7 +42,7 @@ testCompareFiles(const char *vmx, const char *xml, esxVI_APIVersion apiVersion)
         goto failure;
     }
 
-    formatted = virDomainDefFormat(NULL, def, 0);
+    formatted = virDomainDefFormat(NULL, def, VIR_DOMAIN_XML_SECURE);
 
     if (formatted == NULL) {
         goto failure;
@@ -120,6 +120,8 @@ mymain(int argc, char **argv)
     DO_TEST("minimal", "minimal", esxVI_APIVersion_25);
     DO_TEST("minimal-64bit", "minimal-64bit", esxVI_APIVersion_25);
 
+    DO_TEST("graphics-vnc", "graphics-vnc", esxVI_APIVersion_25);
+
     DO_TEST("scsi-buslogic", "scsi-buslogic", esxVI_APIVersion_25);
     DO_TEST("scsi-writethrough", "scsi-writethrough", esxVI_APIVersion_25);
 
diff --git a/tests/xml2vmxdata/xml2vmx-graphics-vnc.vmx b/tests/xml2vmxdata/xml2vmx-graphics-vnc.vmx
new file mode 100644 (file)
index 0000000..b4966b5
--- /dev/null
@@ -0,0 +1,11 @@
+config.version = "8"
+virtualHW.version = "4"
+guestOS = "other"
+uuid.bios = "56 4d 9b ef ac d9 b4 e0-c8 f0 ae a8 b9 10 35 15"
+displayName = "minimal"
+memsize = "4"
+numvcpus = "1"
+RemoteDisplay.vnc.enabled = "true"
+RemoteDisplay.vnc.port = "5903"
+RemoteDisplay.vnc.keymap = "de"
+RemoteDisplay.vnc.password = "password"
diff --git a/tests/xml2vmxdata/xml2vmx-graphics-vnc.xml b/tests/xml2vmxdata/xml2vmx-graphics-vnc.xml
new file mode 100644 (file)
index 0000000..400dcdd
--- /dev/null
@@ -0,0 +1,11 @@
+<domain type='vmware'>
+  <name>minimal</name>
+  <uuid>564d9bef-acd9-b4e0-c8f0-aea8b9103515</uuid>
+  <memory>4096</memory>
+  <os>
+    <type>hvm</type>
+  </os>
+  <devices>
+    <graphics type='vnc' port='5903' autoport='no' keymap='de' passwd='password'/>
+  </devices>
+</domain>
index b5b7cc8143a8d48e866a9f411473f519f48226e4..1a621a2da5bfc8fda67b865740182f474f322684 100644 (file)
@@ -173,6 +173,8 @@ mymain(int argc, char **argv)
     DO_TEST("minimal", "minimal", esxVI_APIVersion_25);
     DO_TEST("minimal-64bit", "minimal-64bit", esxVI_APIVersion_25);
 
+    DO_TEST("graphics-vnc", "graphics-vnc", esxVI_APIVersion_25);
+
     DO_TEST("scsi-buslogic", "scsi-buslogic", esxVI_APIVersion_25);
     DO_TEST("scsi-writethrough", "scsi-writethrough", esxVI_APIVersion_25);