From 1fefeef92fd1881b21e124b83f2adefd3e014087 Mon Sep 17 00:00:00 2001
From: xiaofengw-vmware <42736879+xiaofengw-vmware@users.noreply.github.com>
Date: Fri, 27 Mar 2020 00:31:04 +0800
Subject: VMWware: support to update guest info gc status if enabled (#261)

---
 cloudinit/sources/DataSourceOVF.py                 | 27 +++++++++++++++-------
 cloudinit/sources/helpers/vmware/imc/config.py     | 11 +++++++++
 .../sources/helpers/vmware/imc/guestcust_util.py   |  9 ++++++++
 3 files changed, 39 insertions(+), 8 deletions(-)

(limited to 'cloudinit')

diff --git a/cloudinit/sources/DataSourceOVF.py b/cloudinit/sources/DataSourceOVF.py
index 9f6e6b6c..7bba283f 100644
--- a/cloudinit/sources/DataSourceOVF.py
+++ b/cloudinit/sources/DataSourceOVF.py
@@ -37,7 +37,8 @@ from cloudinit.sources.helpers.vmware.imc.guestcust_util import (
     enable_nics,
     get_nics_to_enable,
     set_customization_status,
-    get_tools_config
+    get_tools_config,
+    set_gc_status
 )
 
 LOG = logging.getLogger(__name__)
@@ -140,6 +141,8 @@ class DataSourceOVF(sources.DataSource):
             try:
                 cf = ConfigFile(vmwareImcConfigFilePath)
                 self._vmware_cust_conf = Config(cf)
+                set_gc_status(self._vmware_cust_conf, "Started")
+
                 (md, ud, cfg) = read_vmware_imc(self._vmware_cust_conf)
                 self._vmware_nics_to_enable = get_nics_to_enable(nicspath)
                 imcdirpath = os.path.dirname(vmwareImcConfigFilePath)
@@ -171,7 +174,8 @@ class DataSourceOVF(sources.DataSource):
                     "Error parsing the customization Config File",
                     e,
                     GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED,
-                    vmwareImcConfigFilePath)
+                    vmwareImcConfigFilePath,
+                    self._vmware_cust_conf)
 
             if special_customization:
                 if customscript:
@@ -183,7 +187,8 @@ class DataSourceOVF(sources.DataSource):
                             "Error executing pre-customization script",
                             e,
                             GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED,
-                            vmwareImcConfigFilePath)
+                            vmwareImcConfigFilePath,
+                            self._vmware_cust_conf)
 
             try:
                 LOG.debug("Preparing the Network configuration")
@@ -197,7 +202,8 @@ class DataSourceOVF(sources.DataSource):
                     "Error preparing Network Configuration",
                     e,
                     GuestCustEvent.GUESTCUST_EVENT_NETWORK_SETUP_FAILED,
-                    vmwareImcConfigFilePath)
+                    vmwareImcConfigFilePath,
+                    self._vmware_cust_conf)
 
             if special_customization:
                 LOG.debug("Applying password customization")
@@ -215,7 +221,8 @@ class DataSourceOVF(sources.DataSource):
                         "Error applying Password Configuration",
                         e,
                         GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED,
-                        vmwareImcConfigFilePath)
+                        vmwareImcConfigFilePath,
+                        self._vmware_cust_conf)
 
                 if customscript:
                     try:
@@ -228,7 +235,8 @@ class DataSourceOVF(sources.DataSource):
                             "Error executing post-customization script",
                             e,
                             GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED,
-                            vmwareImcConfigFilePath)
+                            vmwareImcConfigFilePath,
+                            self._vmware_cust_conf)
 
             if product_marker:
                 try:
@@ -240,7 +248,8 @@ class DataSourceOVF(sources.DataSource):
                         "Error creating marker files",
                         e,
                         GuestCustEvent.GUESTCUST_EVENT_CUSTOMIZE_FAILED,
-                        vmwareImcConfigFilePath)
+                        vmwareImcConfigFilePath,
+                        self._vmware_cust_conf)
 
             self._vmware_cust_found = True
             found.append('vmware-tools')
@@ -252,6 +261,7 @@ class DataSourceOVF(sources.DataSource):
             set_customization_status(
                 GuestCustStateEnum.GUESTCUST_STATE_DONE,
                 GuestCustErrorEnum.GUESTCUST_ERROR_SUCCESS)
+            set_gc_status(self._vmware_cust_conf, "Successful")
 
         else:
             np = [('com.vmware.guestInfo', transport_vmware_guestinfo),
@@ -646,7 +656,7 @@ def setup_marker_files(markerid, marker_dir):
     open(markerfile, 'w').close()
 
 
-def _raise_error_status(prefix, error, event, config_file):
+def _raise_error_status(prefix, error, event, config_file, conf):
     """
     Raise error and send customization status to the underlying VMware
     Virtualization Platform. Also, cleanup the imc directory.
@@ -655,6 +665,7 @@ def _raise_error_status(prefix, error, event, config_file):
     set_customization_status(
         GuestCustStateEnum.GUESTCUST_STATE_RUNNING,
         event)
+    set_gc_status(conf, prefix)
     util.del_dir(os.path.dirname(config_file))
     raise error
 
diff --git a/cloudinit/sources/helpers/vmware/imc/config.py b/cloudinit/sources/helpers/vmware/imc/config.py
index 2eaeff34..f2a81416 100644
--- a/cloudinit/sources/helpers/vmware/imc/config.py
+++ b/cloudinit/sources/helpers/vmware/imc/config.py
@@ -25,6 +25,7 @@ class Config(object):
     SUFFIX = 'DNS|SUFFIX|'
     TIMEZONE = 'DATETIME|TIMEZONE'
     UTC = 'DATETIME|UTC'
+    POST_GC_STATUS = 'MISC|POST-GC-STATUS'
 
     def __init__(self, configFile):
         self._configFile = configFile
@@ -104,4 +105,14 @@ class Config(object):
     def custom_script_name(self):
         """Return the name of custom (pre/post) script."""
         return self._configFile.get(Config.CUSTOM_SCRIPT, None)
+
+    @property
+    def post_gc_status(self):
+        """Return whether to post guestinfo.gc.status VMX property."""
+        postGcStatus = self._configFile.get(Config.POST_GC_STATUS, 'no')
+        postGcStatus = postGcStatus.lower()
+        if postGcStatus not in ('yes', 'no'):
+            raise ValueError('PostGcStatus value should be yes/no')
+        return postGcStatus == 'yes'
+
 # vi: ts=4 expandtab
diff --git a/cloudinit/sources/helpers/vmware/imc/guestcust_util.py b/cloudinit/sources/helpers/vmware/imc/guestcust_util.py
index 3d369d04..c60a38d7 100644
--- a/cloudinit/sources/helpers/vmware/imc/guestcust_util.py
+++ b/cloudinit/sources/helpers/vmware/imc/guestcust_util.py
@@ -154,4 +154,13 @@ def get_tools_config(section, key, defaultVal):
     return retValue
 
 
+# Sets message to the VMX guestinfo.gc.status property to the
+# underlying VMware Virtualization Platform.
+def set_gc_status(config, gcMsg):
+    if config and config.post_gc_status:
+        rpc = "info-set guestinfo.gc.status %s" % gcMsg
+        return send_rpc(rpc)
+    return None
+
+
 # vi: ts=4 expandtab
-- 
cgit v1.2.3