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
