Vinzenz Feenstra has uploaded a new change for review.

Change subject: Support for timezone reporting
......................................................................

Support for timezone reporting

Change-Id: I94c1429f40448a262d0d72fcc6dba2b4b59340c2
Bug-Url: https://bugzilla.redhat.com/869296
Guest-Agent-API-Version: 2
Signed-off-by: Vinzenz Feenstra <[email protected]>
---
M ovirt-guest-agent/OVirtAgentLogic.py
A ovirt-guest-agent/timezone.py
M tests/message_validator.py
3 files changed, 143 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-guest-agent 
refs/changes/13/28013/1

diff --git a/ovirt-guest-agent/OVirtAgentLogic.py 
b/ovirt-guest-agent/OVirtAgentLogic.py
index 35d4265..2055432 100644
--- a/ovirt-guest-agent/OVirtAgentLogic.py
+++ b/ovirt-guest-agent/OVirtAgentLogic.py
@@ -35,7 +35,7 @@
 from threading import Event
 from VirtIoChannel import VirtIoChannel
 
-_MAX_SUPPORTED_API_VERSION = 1
+_MAX_SUPPORTED_API_VERSION = 2
 _DISABLED_API_VALUE = 0
 
 _MESSAGE_MIN_API_VERSION = {
@@ -55,7 +55,8 @@
     'session-logon': 0,
     'session-shutdown': 0,
     'session-startup': 0,
-    'session-unlock': 0}
+    'session-unlock': 0,
+    'timezone': 2}
 
 
 # Return a safe (password masked) repr of the credentials block.
@@ -152,6 +153,10 @@
         except NotImplementedError:
             return -1
 
+    def getTimezone(self):
+        import timezone
+        return timezone.get_name()
+
 
 class AgentLogicBase:
 
@@ -202,6 +207,7 @@
         self.sendUserInfo()
         self.sendAppList()
         self.sendFQDN()
+        self.sendTimezone()
         counter = 0
         hbsecs = self.heartBitRate
         appsecs = self.appRefreshRate
@@ -309,6 +315,7 @@
             self.sendInfo()
             self.sendDisksUsages()
             self.sendFQDN()
+            self.sendTimezone()
         elif command == 'echo':
             logging.debug("Echo: %s", args)
             self._send('echo', args)
@@ -335,6 +342,9 @@
             self._send('active-user', {'name': cur_user})
             self.activeUser = cur_user
 
+    def sendTimezone(self):
+        self._send('timezone', {'zone': self.dr.getTimezone()})
+
     def sendInfo(self):
         self._send('host-name', {'name': self.dr.getMachineName()})
         self._send('os-version', {'version': self.dr.getOsVersion()})
diff --git a/ovirt-guest-agent/timezone.py b/ovirt-guest-agent/timezone.py
new file mode 100644
index 0000000..dc6d4c3
--- /dev/null
+++ b/ovirt-guest-agent/timezone.py
@@ -0,0 +1,122 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# vim:fenc=utf-8
+# Copyright 2014 Vinzenz Feenstra, Red Hat, Inc. and/or its affiliates.
+#
+# Licensed 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.
+#
+# Refer to the README and COPYING files for full details of the license.
+#
+
+import os
+import os.path
+import platform
+
+
+_IS_WINDOWS = platform.system() in ['Windows', 'Microsoft']
+
+
+def get_name_windows():
+    try:
+        import win32com.client
+        from pywintypes import com_error
+        wmi = win32com.client.Dispatch("WbemScripting.SWbemLocator")
+        server = wmi.ConnectServer(".", "root\cimv2")
+        for tz in server.ExecQuery("Select * from Win32_TimeZone"):
+            return tz.StandardName
+    except (ImportError, AttributeError, com_error):
+        pass
+    return ""
+
+
+def _read_etc_timezone():
+    f = open('/etc/timezone', 'r')
+    result = f.read().strip()
+    f.close()
+    return result
+
+
+def _parse_etc_sysconfig_clock():
+    f = open('/etc/sysconfig/clock', 'r')
+    data = f.read().split('\n')
+    f.close()
+    for line in data:
+        kv = line.split('=')
+        if len(kv) == 2 and kv[0] == 'ZONE':
+            return kv[1].replace('"', '')
+    return None
+
+
+def _zoneinfo_to_tz(path):
+    return '/'.join(path.split('/')[-2:])
+
+
+def _split_etc_localtime_symlink():
+    return _zoneinfo_to_tz(os.readlink('/etc/localtime'))
+
+
+def _hash_file(path):
+    from hashlib import md5
+    f = open(path, 'r')
+    result = md5(f.read()).hexdigest()
+    f.close()
+    return result
+
+
+def _find_etc_localtime_by_hash():
+    current = _hash_file('/etc/localtime')
+    location = '/usr/share/zoneinfo/'
+    if not os.path.isdir(location) and os.path.isdir('/usr/lib/zoneinfo/'):
+        location = '/usr/lib/zoneinfo/'
+    for root, dirs, names in os.walk(location):
+        for name in names:
+            fullname = os.path.join(root, name)
+            if current == _hash_file(fullname):
+                return _zoneinfo_to_tz(fullname)
+    return None
+
+
+def get_name():
+    if _IS_WINDOWS:
+        return get_name_windows()
+    return get_name_linux()
+
+
+def get_name_linux():
+    result = None
+    # is /etc/localtime a symlink?
+    if os.path.islink('/etc/localtime'):
+        result = _split_etc_localtime_symlink()
+    # Debianoid
+    if not result and os.path.exists('/etc/timezone'):
+        result = _read_etc_timezone()
+    # Pre-systemd RHEL/Fedora/CentOS
+    if not result and os.path.exists('/etc/sysconfig/clock'):
+        result = _parse_etc_sysconfig_clock()
+    # if /etc/localtime exists try to use file hashes to find a matching file
+    # in /usr/{lib,share}/zoneinfo/*
+    if not result and os.path.exists('/etc/localtime'):
+        result = _find_etc_localtime_by_hash()
+    return result or ''
+
+
+if __name__ == '__main__':
+    if os.path.islink('/etc/localtime'):
+        print '_split_etc_localtime_symlink =', _split_etc_localtime_symlink()
+    if os.path.exists('/etc/localtime'):
+        print '_find_etc_localtime_by_hash =', _find_etc_localtime_by_hash()
+    if os.path.exists('/etc/sysconfig/clock'):
+        print '_parse_etc_sysconfig_clock =', _parse_etc_sysconfig_clock()
+    if os.path.exists('/etc/timezone'):
+        print '_read_etc_timezone =', _read_etc_timezone()
+    print 'get_name_linux =', get_name_linux()
diff --git a/tests/message_validator.py b/tests/message_validator.py
index 67d5e71..2d9f97c 100644
--- a/tests/message_validator.py
+++ b/tests/message_validator.py
@@ -165,6 +165,7 @@
     'session-shutdown': _name_only('session-shutdown'),
     'session-startup': _name_only('session-startup'),
     'session-unlock': _name_only('session-unlock'),
+    'timezone': _name_and_one_str_param('timezone', 'zone'),
     'api-version': _name_and_one_integral_param('api-version', 'apiVersion')
 }
 
@@ -288,3 +289,11 @@
         assert(agent.dr.getAPIVersion() == 1)
         agent.parseCommand('refresh', {})
         assert(agent.dr.getAPIVersion() == 0)
+
+    @_ensure_messages('applications', 'host-name', 'os-version', 'active-user',
+                      'network-interfaces', 'disks-usage', 'fqdn', 'timezone')
+    def verifyRefreshReply3(self, agent):
+        agent.dr.setAPIVersion(2)
+        assert(agent.dr.getAPIVersion() == 2)
+        agent.parseCommand('refresh', {})
+        assert(agent.dr.getAPIVersion() == 0)


-- 
To view, visit http://gerrit.ovirt.org/28013
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I94c1429f40448a262d0d72fcc6dba2b4b59340c2
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-guest-agent
Gerrit-Branch: master
Gerrit-Owner: Vinzenz Feenstra <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to