diff options
author | Łukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com> | 2018-02-15 14:28:59 +0100 |
---|---|---|
committer | usd-importer <ubuntu-server@lists.ubuntu.com> | 2018-02-15 19:08:29 +0000 |
commit | 3afbcfff2f6e3faf50c0dffee55e7c48b50755b5 (patch) | |
tree | 44d4a5d80868fe6a8defe57f6cc9c21feae59a03 | |
parent | 6c9cd7e1ac55aae259d8e2f06569375e27a12f20 (diff) | |
parent | 7e7d885433a2bac56ce2361126bf7ec3d565fd66 (diff) | |
download | vyos-walinuxagent-3afbcfff2f6e3faf50c0dffee55e7c48b50755b5.tar.gz vyos-walinuxagent-3afbcfff2f6e3faf50c0dffee55e7c48b50755b5.zip |
Import patches-applied version 2.2.21+really2.2.20-0ubuntu1~16.04.1 to applied/ubuntu/xenial-proposed
Imported using git-ubuntu import.
Changelog parent: 6c9cd7e1ac55aae259d8e2f06569375e27a12f20
Unapplied parent: 7e7d885433a2bac56ce2361126bf7ec3d565fd66
New changelog entries:
* Backport bionic version to xenial.
* Revert to an older upstream release: 2.2.20 (LP: #1749589).
- Rename upstream tarball to 2.2.21+really2.2.20 to end up with a
temporarily higher version number than what's in the archive.
* debian/patches/disable_import_test.patch: refreshed patch.
48 files changed, 196 insertions, 791 deletions
diff --git a/azurelinuxagent/agent.py b/azurelinuxagent/agent.py index 4ab7aa0..e99f7be 100644 --- a/azurelinuxagent/agent.py +++ b/azurelinuxagent/agent.py @@ -63,9 +63,6 @@ class Agent(object): path="/var/log/waagent.log") logger.add_logger_appender(logger.AppenderType.CONSOLE, level, path="/dev/console") - logger.add_logger_appender(logger.AppenderType.TELEMETRY, - logger.LogLevel.WARNING, - path=event.add_log_event) ext_log_dir = conf.get_ext_log_dir() try: @@ -147,7 +144,7 @@ def main(args=[]): if command == "version": version() elif command == "help": - print(usage()) + usage() elif command == "start": start(conf_file_path=conf_file_path) else: @@ -231,16 +228,15 @@ def version(): def usage(): """ - Return agent usage message + Show agent usage """ - s = "\n" - s += ("usage: {0} [-verbose] [-force] [-help] " + print("") + print((("usage: {0} [-verbose] [-force] [-help] " "-configuration-path:<path to configuration file>" "-deprovision[+user]|-register-service|-version|-daemon|-start|" - "-run-exthandlers|-show-configuration]" - "").format(sys.argv[0]) - s += "\n" - return s + "-run-exthandlers]" + "").format(sys.argv[0]))) + print("") def start(conf_file_path=None): """ diff --git a/azurelinuxagent/common/conf.py b/azurelinuxagent/common/conf.py index 33f953a..045352d 100644 --- a/azurelinuxagent/common/conf.py +++ b/azurelinuxagent/common/conf.py @@ -40,11 +40,11 @@ class ConfigurationProvider(object): raise AgentConfigError("Can't not parse empty configuration") for line in content.split('\n'): if not line.startswith("#") and "=" in line: - parts = line.split('=', 1) + parts = line.split('=') if len(parts) < 2: continue key = parts[0].strip() - value = parts[1].split('#')[0].strip("\" ").strip() + value = parts[1].split('#')[0].strip("\" ") self.values[key] = value if value != "None" else None def get(self, key, default_val): @@ -138,7 +138,6 @@ __INTEGER_OPTIONS__ = { "Autoupdate.Frequency" : 3600 } - def get_configuration(conf=__conf__): options = {} for option in __SWITCH_OPTIONS__: diff --git a/azurelinuxagent/common/errorstate.py b/azurelinuxagent/common/errorstate.py deleted file mode 100644 index 750aa77..0000000 --- a/azurelinuxagent/common/errorstate.py +++ /dev/null @@ -1,31 +0,0 @@ -from datetime import datetime, timedelta - -ERROR_STATE_DELTA = timedelta(minutes=15) - - -class ErrorState(object): - def __init__(self, min_timedelta = ERROR_STATE_DELTA): - self.min_timedelta = min_timedelta - - self.count = 0 - self.timestamp = None - - def incr(self): - if self.count == 0: - self.timestamp = datetime.utcnow() - - self.count += 1 - - def reset(self): - self.count = 0 - self.timestamp = None - - def is_triggered(self): - if self.timestamp is None: - return False - - delta = datetime.utcnow() - self.timestamp - if delta >= self.min_timedelta: - return True - - return False diff --git a/azurelinuxagent/common/event.py b/azurelinuxagent/common/event.py index 84a439f..108cf00 100644 --- a/azurelinuxagent/common/event.py +++ b/azurelinuxagent/common/event.py @@ -15,29 +15,33 @@ # Requires Python 2.4+ and Openssl 1.0+ # -import atexit -import datetime -import json import os import sys -import time import traceback +import atexit +import json +import time +import datetime +import threading +import platform -from datetime import datetime +from datetime import datetime, timedelta import azurelinuxagent.common.conf as conf import azurelinuxagent.common.logger as logger -from azurelinuxagent.common.exception import EventError +from azurelinuxagent.common.exception import EventError, ProtocolError from azurelinuxagent.common.future import ustr from azurelinuxagent.common.protocol.restapi import TelemetryEventParam, \ + TelemetryEventList, \ TelemetryEvent, \ - get_properties -from azurelinuxagent.common.version import CURRENT_VERSION + set_properties, get_properties +from azurelinuxagent.common.version import DISTRO_NAME, DISTRO_VERSION, \ + DISTRO_CODE_NAME, AGENT_VERSION, \ + CURRENT_AGENT, CURRENT_VERSION _EVENT_MSG = "Event: name={0}, op={1}, message={2}, duration={3}" - class WALAEventOperation: ActivateResourceDisk = "ActivateResourceDisk" AgentBlacklisted = "AgentBlacklisted" @@ -56,14 +60,11 @@ class WALAEventOperation: HttpErrors = "HttpErrors" Install = "Install" InitializeHostPlugin = "InitializeHostPlugin" - Log = "Log" Partition = "Partition" ProcessGoalState = "ProcessGoalState" Provision = "Provision" - GuestState = "GuestState" ReportStatus = "ReportStatus" Restart = "Restart" - SkipUpdate = "SkipUpdate" UnhandledError = "UnhandledError" UnInstall = "UnInstall" Unknown = "Unknown" @@ -74,7 +75,7 @@ class WALAEventOperation: class EventStatus(object): EVENT_STATUS_FILE = "event_status.json" - def __init__(self): + def __init__(self, status_dir=conf.get_lib_dir()): self._path = None self._status = {} @@ -89,7 +90,7 @@ class EventStatus(object): event = self._event_name(name, version, op) if event not in self._status: return True - return self._status[event] is True + return self._status[event] == True def initialize(self, status_dir=conf.get_lib_dir()): self._path = os.path.join(status_dir, EventStatus.EVENT_STATUS_FILE) @@ -97,7 +98,7 @@ class EventStatus(object): def mark_event_status(self, name, version, op, status): event = self._event_name(name, version, op) - self._status[event] = (status is True) + self._status[event] = (status == True) self._save() def _event_name(self, name, version, op): @@ -120,7 +121,6 @@ class EventStatus(object): except Exception as e: logger.warn("Exception occurred saving event status: {0}".format(e)) - __event_status__ = EventStatus() __event_status_operations__ = [ WALAEventOperation.AutoUpdate, @@ -223,32 +223,6 @@ class EventLogger(object): except EventError as e: logger.error("{0}", e) - def add_log_event(self, level, message): - # By the time the message has gotten to this point it is formatted as - # - # YYYY/MM/DD HH:mm:ss.fffffff LEVEL <text>. - # - # The timestamp and the level are redundant, and should be stripped. - # The logging library does not schematize this data, so I am forced - # to parse the message. The format is regular, so the burden is low. - - parts = message.split(' ', 3) - msg = parts[3] if len(parts) == 4 \ - else message - - event = TelemetryEvent(7, "FFF0196F-EE4C-4EAF-9AA5-776F622DEB4F") - event.parameters.append(TelemetryEventParam('EventName', WALAEventOperation.Log)) - event.parameters.append(TelemetryEventParam('CapabilityUsed', logger.LogLevel.STRINGS[level])) - event.parameters.append(TelemetryEventParam('Context1', msg)) - event.parameters.append(TelemetryEventParam('Context2', '')) - event.parameters.append(TelemetryEventParam('Context3', '')) - - data = get_properties(event) - try: - self.save_event(json.dumps(data)) - except EventError: - pass - __event_logger__ = EventLogger() @@ -258,7 +232,6 @@ def elapsed_milliseconds(utc_start): return int(((d.days * 24 * 60 * 60 + d.seconds) * 1000) + \ (d.microseconds / 1000.0)) - def report_event(op, is_success=True, message=''): from azurelinuxagent.common.version import AGENT_NAME, CURRENT_VERSION add_event(AGENT_NAME, @@ -267,7 +240,6 @@ def report_event(op, is_success=True, message=''): message=message, op=op) - def report_periodic(delta, op, is_success=True, message=''): from azurelinuxagent.common.version import AGENT_NAME, CURRENT_VERSION add_periodic(delta, AGENT_NAME, @@ -276,7 +248,6 @@ def report_periodic(delta, op, is_success=True, message=''): message=message, op=op) - def add_event(name, op=WALAEventOperation.Unknown, is_success=True, duration=0, version=CURRENT_VERSION, message="", evt_type="", is_internal=False, log_event=True, @@ -293,14 +264,6 @@ def add_event(name, op=WALAEventOperation.Unknown, is_success=True, duration=0, version=str(version), message=message, evt_type=evt_type, is_internal=is_internal, log_event=log_event) - -def add_log_event(level, message, reporter=__event_logger__): - if reporter.event_dir is None: - return - - reporter.add_log_event(level, message) - - def add_periodic( delta, name, op=WALAEventOperation.Unknown, is_success=True, duration=0, version=CURRENT_VERSION, @@ -316,12 +279,10 @@ def add_periodic( version=str(version), message=message, evt_type=evt_type, is_internal=is_internal, log_event=log_event, force=force) - def mark_event_status(name, version, op, status): if op in __event_status_operations__: __event_status__.mark_event_status(name, version, op, status) - def should_emit_event(name, version, op, status): return \ op not in __event_status_operations__ or \ @@ -329,15 +290,12 @@ def should_emit_event(name, version, op, status): not __event_status__.event_marked(name, version, op) or \ __event_status__.event_succeeded(name, version, op) != status - def init_event_logger(event_dir): __event_logger__.event_dir = event_dir - def init_event_status(status_dir): __event_status__.initialize(status_dir) - def dump_unhandled_err(name): if hasattr(sys, 'last_type') and hasattr(sys, 'last_value') and \ hasattr(sys, 'last_traceback'): diff --git a/azurelinuxagent/common/exception.py b/azurelinuxagent/common/exception.py index bb8ab10..2e5a78a 100644 --- a/azurelinuxagent/common/exception.py +++ b/azurelinuxagent/common/exception.py @@ -44,7 +44,7 @@ class AgentConfigError(AgentError): class AgentNetworkError(AgentError): """ - When network is not available\. + When network is not avaiable. """ def __init__(self, msg=None, inner=None): @@ -86,7 +86,6 @@ class DhcpError(AgentError): def __init__(self, msg=None, inner=None): super(DhcpError, self).__init__(msg, inner) - class OSUtilError(AgentError): """ Failed to perform operation to OS configuration @@ -114,15 +113,6 @@ class ProtocolNotFoundError(ProtocolError): super(ProtocolNotFoundError, self).__init__(msg, inner) -class RestartError(ProtocolError): - """ - Variant of ProtocolError used to restart processing if the GoalState - becomes stale. - """ - - pass - - class HttpError(AgentError): """ Http request failure diff --git a/azurelinuxagent/common/logger.py b/azurelinuxagent/common/logger.py index 0a90718..bfdc73a 100644 --- a/azurelinuxagent/common/logger.py +++ b/azurelinuxagent/common/logger.py @@ -17,8 +17,8 @@ """ Log utils """ +import os import sys - from azurelinuxagent.common.future import ustr from datetime import datetime, timedelta @@ -28,7 +28,6 @@ EVERY_HOUR = timedelta(hours=1) EVERY_HALF_HOUR = timedelta(minutes=30) EVERY_FIFTEEN_MINUTES = timedelta(minutes=15) - class Logger(object): """ Logger class @@ -93,7 +92,6 @@ class Logger(object): appender = _create_logger_appender(appender_type, level, path) self.appenders.append(appender) - class ConsoleAppender(object): def __init__(self, level, path): self.level = level @@ -107,7 +105,6 @@ class ConsoleAppender(object): except IOError: pass - class FileAppender(object): def __init__(self, level, path): self.level = level @@ -121,7 +118,6 @@ class FileAppender(object): except IOError: pass - class StdoutAppender(object): def __init__(self, level): self.level = level @@ -133,24 +129,9 @@ class StdoutAppender(object): except IOError: pass - -class TelemetryAppender(object): - def __init__(self, level, event_func): - self.level = level - self.event_func = event_func - - def write(self, level, msg): - if self.level <= level: - try: - self.event_func(level, msg) - except IOError: - pass - - #Initialize logger instance DEFAULT_LOGGER = Logger() - class LogLevel(object): VERBOSE = 0 INFO = 1 @@ -163,46 +144,35 @@ class LogLevel(object): "ERROR" ] - class AppenderType(object): FILE = 0 CONSOLE = 1 STDOUT = 2 - TELEMETRY = 3 - def add_logger_appender(appender_type, level=LogLevel.INFO, path=None): DEFAULT_LOGGER.add_appender(appender_type, level, path) - def reset_periodic(): DEFAULT_LOGGER.reset_periodic() - def periodic(delta, msg_format, *args): DEFAULT_LOGGER.periodic(delta, msg_format, *args) - def verbose(msg_format, *args): DEFAULT_LOGGER.verbose(msg_format, *args) - def info(msg_format, *args): DEFAULT_LOGGER.info(msg_format, *args) - def warn(msg_format, *args): DEFAULT_LOGGER.warn(msg_format, *args) - def error(msg_format, *args): DEFAULT_LOGGER.error(msg_format, *args) - def log(level, msg_format, *args): DEFAULT_LOGGER.log(level, msg_format, args) - def _create_logger_appender(appender_type, level=LogLevel.INFO, path=None): if appender_type == AppenderType.CONSOLE: return ConsoleAppender(level, path) @@ -210,8 +180,6 @@ def _create_logger_appender(appender_type, level=LogLevel.INFO, path=None): return FileAppender(level, path) elif appender_type == AppenderType.STDOUT: return StdoutAppender(level) - elif appender_type == AppenderType.TELEMETRY: - return TelemetryAppender(level, path) else: raise ValueError("Unknown appender type") diff --git a/azurelinuxagent/common/osutil/default.py b/azurelinuxagent/common/osutil/default.py index 16b7444..ecade8d 100644 --- a/azurelinuxagent/common/osutil/default.py +++ b/azurelinuxagent/common/osutil/default.py @@ -66,10 +66,6 @@ FIREWALL_LIST = "iptables {0} -t security -L -nxv" FIREWALL_PACKETS = "iptables {0} -t security -L OUTPUT --zero OUTPUT -nxv" FIREWALL_FLUSH = "iptables {0} -t security --flush" -# Precisely delete the rules created by the agent. -FIREWALL_DELETE_CONNTRACK = "iptables {0} -t security -D OUTPUT -d {1} -p tcp -m conntrack --ctstate INVALID,NEW -j ACCEPT" -FIREWALL_DELETE_OWNER = "iptables {0} -t security -D OUTPUT -d {1} -p tcp -m owner --uid-owner {2} -j ACCEPT" - PACKET_PATTERN = "^\s*(\d+)\s+(\d+)\s+DROP\s+.*{0}[^\d]*$" _enable_firewall = True @@ -80,8 +76,8 @@ UUID_PATTERN = re.compile( r'^\s*[A-F0-9]{8}(?:\-[A-F0-9]{4}){3}\-[A-F0-9]{12}\s*$', re.IGNORECASE) - class DefaultOSUtil(object): + def __init__(self): self.agent_conf_file_path = '/etc/waagent.conf' self.selinux = None @@ -97,11 +93,6 @@ class DefaultOSUtil(object): wait = self.get_firewall_will_wait() rc, output = shellutil.run_get_output(FIREWALL_PACKETS.format(wait)) - if rc == 3: - # Transient error that we ignore. This code fires every loop - # of the daemon (60m), so we will get the value eventually. - return 0 - if rc != 0: return -1 @@ -138,40 +129,24 @@ class DefaultOSUtil(object): else "" return wait - def _delete_rule(self, rule): - """ - Continually execute the delete operation until the return - code is non-zero or the limit has been reached. - """ - for i in range(1, 100): - rc = shellutil.run(rule, chk_err=False) - if rc == 1: - return - elif rc == 2: - raise Exception("invalid firewall deletion rule '{0}'".format(rule)) - - def remove_firewall(self, dst_ip=None, uid=None): + def remove_firewall(self): # If a previous attempt failed, do not retry global _enable_firewall if not _enable_firewall: return False try: - if dst_ip is None or uid is None: - msg = "Missing arguments to enable_firewall" - logger.warn(msg) - raise Exception(msg) - wait = self.get_firewall_will_wait() - self._delete_rule(FIREWALL_DELETE_CONNTRACK.format(wait, dst_ip)) - self._delete_rule(FIREWALL_DELETE_OWNER.format(wait, dst_ip, uid)) + flush_rule = FIREWALL_FLUSH.format(wait) + if shellutil.run(flush_rule, chk_err=True) != 0: + raise Exception("non-zero return code") return True except Exception as e: _enable_firewall = False - logger.info("Unable to remove firewall -- " + logger.info("Unable to flush firewall -- " "no further attempts will be made: " "{0}".format(ustr(e))) return False @@ -192,15 +167,10 @@ class DefaultOSUtil(object): # If the DROP rule exists, make no changes drop_rule = FIREWALL_DROP.format(wait, "C", dst_ip) - rc = shellutil.run(drop_rule, chk_err=False) - if rc == 0: + + if shellutil.run(drop_rule, chk_err=False) == 0: logger.verbose("Firewall appears established") return True - elif rc == 2: - self.remove_firewall(dst_ip, uid) - msg = "please upgrade iptables to a version that supports the -C option" - logger.warn(msg) - raise Exception(msg) # Otherwise, append both rules accept_rule = FIREWALL_ACCEPT.format(wait, "A", dst_ip, uid) @@ -1028,7 +998,7 @@ class DefaultOSUtil(object): if not os.path.exists(hostname_record): # this file is created at provisioning time with agents >= 2.2.3 hostname = socket.gethostname() - logger.info('Hostname record does not exist, ' + logger.warn('Hostname record does not exist, ' 'creating [{0}] with hostname [{1}]', hostname_record, hostname) diff --git a/azurelinuxagent/common/osutil/factory.py b/azurelinuxagent/common/osutil/factory.py index 1b4e2cb..43aa6a7 100644 --- a/azurelinuxagent/common/osutil/factory.py +++ b/azurelinuxagent/common/osutil/factory.py @@ -27,8 +27,7 @@ from .freebsd import FreeBSDOSUtil from .openbsd import OpenBSDOSUtil from .redhat import RedhatOSUtil, Redhat6xOSUtil from .suse import SUSEOSUtil, SUSE11OSUtil -from .ubuntu import UbuntuOSUtil, Ubuntu12OSUtil, Ubuntu14OSUtil, \ - UbuntuSnappyOSUtil, Ubuntu16OSUtil +from .ubuntu import UbuntuOSUtil, Ubuntu12OSUtil, Ubuntu14OSUtil, UbuntuSnappyOSUtil from .alpine import AlpineOSUtil from .bigip import BigIpOSUtil from .gaia import GaiaOSUtil @@ -47,12 +46,10 @@ def get_osutil(distro_name=DISTRO_NAME, return ClearLinuxUtil() if distro_name == "ubuntu": - if Version(distro_version) in [Version("12.04"), Version("12.10")]: + if Version(distro_version) == Version("12.04") or Version(distro_version) == Version("12.10"): return Ubuntu12OSUtil() - elif Version(distro_version) in [Version("14.04"), Version("14.10")]: + elif Version(distro_version) == Version("14.04") or Version(distro_version) == Version("14.10"): return Ubuntu14OSUtil() - elif Version(distro_version) in [Version('16.04'), Version('16.10'), Version('17.04')]: - return Ubuntu16OSUtil() elif distro_full_name == "Snappy Ubuntu Core": return UbuntuSnappyOSUtil() else: diff --git a/azurelinuxagent/common/osutil/ubuntu.py b/azurelinuxagent/common/osutil/ubuntu.py index 8dacc75..3c353cf 100644 --- a/azurelinuxagent/common/osutil/ubuntu.py +++ b/azurelinuxagent/common/osutil/ubuntu.py @@ -16,14 +16,9 @@ # Requires Python 2.4+ and Openssl 1.0+ # -import time - -import azurelinuxagent.common.logger as logger import azurelinuxagent.common.utils.shellutil as shellutil - from azurelinuxagent.common.osutil.default import DefaultOSUtil - class Ubuntu14OSUtil(DefaultOSUtil): def __init__(self): super(Ubuntu14OSUtil, self).__init__() @@ -46,7 +41,6 @@ class Ubuntu14OSUtil(DefaultOSUtil): def get_dhcp_lease_endpoint(self): return self.get_endpoint_from_leases_path('/var/lib/dhcp/dhclient.*.leases') - class Ubuntu12OSUtil(Ubuntu14OSUtil): def __init__(self): super(Ubuntu12OSUtil, self).__init__() @@ -56,13 +50,9 @@ class Ubuntu12OSUtil(Ubuntu14OSUtil): ret = shellutil.run_get_output("pidof dhclient3", chk_err=False) return ret[1] if ret[0] == 0 else None - -class Ubuntu16OSUtil(Ubuntu14OSUtil): - """ - Ubuntu 16.04, 16.10, and 17.04. - """ +class UbuntuOSUtil(Ubuntu14OSUtil): def __init__(self): - super(Ubuntu16OSUtil, self).__init__() + super(UbuntuOSUtil, self).__init__() def register_agent_service(self): return shellutil.run("systemctl unmask walinuxagent", chk_err=False) @@ -70,29 +60,6 @@ class Ubuntu16OSUtil(Ubuntu14OSUtil): def unregister_agent_service(self): return shellutil.run("systemctl mask walinuxagent", chk_err=False) - -class UbuntuOSUtil(Ubuntu16OSUtil): - def __init__(self): - super(UbuntuOSUtil, self).__init__() - - def restart_if(self, ifname, retries=3, wait=5): - """ - Restart an interface by bouncing the link. systemd-networkd observes - this event, and forces a renew of DHCP. - """ - retry_limit=retries+1 - for attempt in range(1, retry_limit): - return_code=shellutil.run("ip link set {0} down && ip link set {0} up".format(ifname)) - if return_code == 0: - return - logger.warn("failed to restart {0}: return code {1}".format(ifname, return_code)) - if attempt < retry_limit: - logger.info("retrying in {0} seconds".format(wait)) - time.sleep(wait) - else: - logger.warn("exceeded restart retries") - - class UbuntuSnappyOSUtil(Ubuntu14OSUtil): def __init__(self): super(UbuntuSnappyOSUtil, self).__init__() diff --git a/azurelinuxagent/common/protocol/metadata.py b/azurelinuxagent/common/protocol/metadata.py index 0cfa5ed..ed4fff9 100644 --- a/azurelinuxagent/common/protocol/metadata.py +++ b/azurelinuxagent/common/protocol/metadata.py @@ -240,7 +240,7 @@ class MetadataProtocol(Protocol): set_properties("extensionHandlers", ext_list.extHandlers, data) return ext_list, etag - def get_ext_handler_pkgs(self, ext_handler, etag): + def get_ext_handler_pkgs(self, ext_handler): logger.verbose("Get extension handler packages") pkg_list = ExtHandlerPackageList() diff --git a/azurelinuxagent/common/protocol/restapi.py b/azurelinuxagent/common/protocol/restapi.py index 5a678d7..275cedb 100644 --- a/azurelinuxagent/common/protocol/restapi.py +++ b/azurelinuxagent/common/protocol/restapi.py @@ -315,15 +315,15 @@ class Protocol(DataContract): def get_ext_handlers(self): raise NotImplementedError() - def get_ext_handler_pkgs(self, extension, etag): + def get_ext_handler_pkgs(self, extension): raise NotImplementedError() def get_artifacts_profile(self): raise NotImplementedError() - def download_ext_handler_pkg(self, uri, headers=None, use_proxy=True): + def download_ext_handler_pkg(self, uri, headers=None): try: - resp = restutil.http_get(uri, headers=headers, use_proxy=use_proxy) + resp = restutil.http_get(uri, use_proxy=True, headers=headers) if restutil.request_succeeded(resp): return resp.read() except Exception as e: diff --git a/azurelinuxagent/common/protocol/wire.py b/azurelinuxagent/common/protocol/wire.py index 963d33c..af6f943 100644 --- a/azurelinuxagent/common/protocol/wire.py +++ b/azurelinuxagent/common/protocol/wire.py @@ -18,7 +18,6 @@ import json import os -import random import re import time import xml.sax.saxutils as saxutils @@ -28,7 +27,7 @@ import azurelinuxagent.common.utils.fileutil as fileutil import azurelinuxagent.common.utils.textutil as textutil from azurelinuxagent.common.exception import ProtocolNotFoundError, \ - ResourceGoneError, RestartError + ResourceGoneError from azurelinuxagent.common.future import httpclient, bytebuffer from azurelinuxagent.common.protocol.hostplugin import HostPluginProtocol from azurelinuxagent.common.protocol.restapi import * @@ -145,9 +144,10 @@ class WireProtocol(Protocol): # In wire protocol, incarnation is equivalent to ETag return ext_conf.ext_handlers, goal_state.incarnation - def get_ext_handler_pkgs(self, ext_handler, etag): + def get_ext_handler_pkgs(self, ext_handler): logger.verbose("Get extension handler package") - man = self.client.get_ext_manifest(ext_handler, etag) + goal_state = self.client.get_goal_state() + man = self.client.get_ext_manifest(ext_handler, goal_state) return man.pkg_list def get_artifacts_profile(self): @@ -160,10 +160,10 @@ class WireProtocol(Protocol): if package is not None: return package else: - logger.verbose("Download did not succeed, falling back to host plugin") + logger.warn("Download did not succeed, falling back to host plugin") host = self.client.get_host_plugin() uri, headers = host.get_artifact_request(uri, host.manifest_uri) - package = super(WireProtocol, self).download_ext_handler_pkg(uri, headers=headers, use_proxy=False) + package = super(WireProtocol, self).download_ext_handler_pkg(uri, headers=headers) return package def report_provision_status(self, provision_status): @@ -591,10 +591,7 @@ class WireClient(object): def fetch_manifest(self, version_uris): logger.verbose("Fetch manifest") - version_uris_shuffled = version_uris - random.shuffle(version_uris_shuffled) - - for version in version_uris_shuffled: + for version in version_uris: response = None if not HostPluginProtocol.is_default_channel(): response = self.fetch(version.uri) @@ -698,10 +695,13 @@ class WireClient(object): INCARNATION_FILE_NAME) uri = GOAL_STATE_URI.format(self.endpoint) - goal_state = None + # Start updating goalstate, retry on 410 + fetch_goal_state = True for retry in range(0, max_retry): try: - if goal_state is None: + if fetch_goal_state: + fetch_goal_state = False + xml_text = self.fetch_config(uri, self.get_header()) goal_state = GoalState(xml_text) @@ -734,7 +734,7 @@ class WireClient(object): except ResourceGoneError: logger.info("GoalState is stale -- re-fetching") - goal_state = None + fetch_goal_state = True except Exception as e: log_method = logger.info \ @@ -799,35 +799,25 @@ class WireClient(object): self.ext_conf = ExtensionsConfig(xml_text) return self.ext_conf - def get_ext_manifest(self, ext_handler, incarnation): - + def get_ext_manifest(self, ext_handler, goal_state): for update_goal_state in [False, True]: try: if update_goal_state: self.update_goal_state(forced=True) - incarnation = self.get_goal_state().incarnation + goal_state = self.get_goal_state() local_file = MANIFEST_FILE_NAME.format( ext_handler.name, - incarnation) + goal_state.incarnation) local_file = os.path.join(conf.get_lib_dir(), local_file) - - xml_text = None - if not update_goal_state: - try: - xml_text = self.fetch_cache(local_file) - except ProtocolError: - pass - - if xml_text is None: - xml_text = self.fetch_manifest(ext_handler.versionUris) - self.save_cache(local_file, xml_text) + xml_text = self.fetch_manifest(ext_handler.versionUris) + self.save_cache(local_file, xml_text) return ExtensionManifest(xml_text) except ResourceGoneError: continue - raise RestartError("Failed to retrieve extension manifest") + raise ProtocolError("Failed to retrieve extension manifest") def filter_package_list(self, family, ga_manifest, goal_state): complete_list = ga_manifest.pkg_list @@ -895,7 +885,7 @@ class WireClient(object): logger.info("Wire protocol version:{0}", PROTOCOL_VERSION) elif PROTOCOL_VERSION in version_info.get_supported(): logger.info("Wire protocol version:{0}", PROTOCOL_VERSION) - logger.info("Server preferred version:{0}", preferred) + logger.warn("Server preferred version:{0}", preferred) else: error = ("Agent supported wire protocol version: {0} was not " "advised by Fabric.").format(PROTOCOL_VERSION) diff --git a/azurelinuxagent/common/utils/fileutil.py b/azurelinuxagent/common/utils/fileutil.py index 1f0c7ac..7846506 100644 --- a/azurelinuxagent/common/utils/fileutil.py +++ b/azurelinuxagent/common/utils/fileutil.py @@ -27,6 +27,7 @@ import os import pwd import re import shutil +import string import azurelinuxagent.common.logger as logger import azurelinuxagent.common.utils.textutil as textutil diff --git a/azurelinuxagent/common/version.py b/azurelinuxagent/common/version.py index f743f11..eeef1f3 100644 --- a/azurelinuxagent/common/version.py +++ b/azurelinuxagent/common/version.py @@ -113,7 +113,7 @@ def get_distro(): AGENT_NAME = "WALinuxAgent" AGENT_LONG_NAME = "Azure Linux Agent" -AGENT_VERSION = '2.2.21' +AGENT_VERSION = '2.2.20' AGENT_LONG_VERSION = "{0}-{1}".format(AGENT_NAME, AGENT_VERSION) AGENT_DESCRIPTION = """ The Azure Linux Agent supports the provisioning and running of Linux @@ -161,17 +161,14 @@ def set_current_agent(): version = AGENT_VERSION return agent, FlexibleVersion(version) - def is_agent_package(path): path = os.path.basename(path) return not re.match(AGENT_PKG_PATTERN, path) is None - def is_agent_path(path): path = os.path.basename(path) return not re.match(AGENT_NAME_PATTERN, path) is None - CURRENT_AGENT, CURRENT_VERSION = set_current_agent() diff --git a/azurelinuxagent/ga/env.py b/azurelinuxagent/ga/env.py index d9b7d82..8eecd3e 100644 --- a/azurelinuxagent/ga/env.py +++ b/azurelinuxagent/ga/env.py @@ -107,7 +107,7 @@ class EnvHandler(object): version=CURRENT_VERSION, op=WALAEventOperation.Firewall, is_success=success, - log_event=False) + log_event=True) timeout = conf.get_root_device_scsi_timeout() if timeout is not None: diff --git a/azurelinuxagent/ga/exthandlers.py b/azurelinuxagent/ga/exthandlers.py index cc1796b..fa51279 100644 --- a/azurelinuxagent/ga/exthandlers.py +++ b/azurelinuxagent/ga/exthandlers.py @@ -22,7 +22,6 @@ import glob import json import os import os.path -import random import re import shutil import stat @@ -33,22 +32,25 @@ import zipfile import azurelinuxagent.common.conf as conf import azurelinuxagent.common.logger as logger import azurelinuxagent.common.utils.fileutil as fileutil +import azurelinuxagent.common.utils.restutil as restutil +import azurelinuxagent.common.utils.shellutil as shellutil import azurelinuxagent.common.version as version -from azurelinuxagent.common.errorstate import ErrorState, ERROR_STATE_DELTA -from azurelinuxagent.common.event import add_event, WALAEventOperation, elapsed_milliseconds -from azurelinuxagent.common.exception import ExtensionError, ProtocolError, RestartError +from azurelinuxagent.common.event import add_event, WALAEventOperation +from azurelinuxagent.common.exception import ExtensionError, ProtocolError, HttpError from azurelinuxagent.common.future import ustr +from azurelinuxagent.common.version import AGENT_VERSION from azurelinuxagent.common.protocol.restapi import ExtHandlerStatus, \ ExtensionStatus, \ ExtensionSubStatus, \ + Extension, \ VMStatus, ExtHandler, \ get_properties, \ set_properties from azurelinuxagent.common.utils.flexible_version import FlexibleVersion +from azurelinuxagent.common.utils.textutil import Version from azurelinuxagent.common.protocol import get_protocol_util -from azurelinuxagent.common.version import AGENT_NAME, CURRENT_VERSION - +from azurelinuxagent.common.version import AGENT_NAME, CURRENT_AGENT, CURRENT_VERSION #HandlerEnvironment.json schema version HANDLER_ENVIRONMENT_VERSION = 1.0 @@ -174,12 +176,9 @@ class ExtHandlersHandler(object): self.protocol = None self.ext_handlers = None self.last_etag = None - self.last_upgrade_guids = {} + self.last_guids = {} self.log_report = False self.log_etag = True - self.log_process = False - - self.report_status_error_state = ErrorState() def run(self): self.ext_handlers, etag = None, None @@ -207,8 +206,6 @@ class ExtHandlersHandler(object): self.report_ext_handlers_status() self.cleanup_outdated_handlers() - except RestartError: - raise except Exception as e: msg = u"Exception processing extension handlers: {0}".format( ustr(e)) @@ -224,19 +221,11 @@ class ExtHandlersHandler(object): self.report_ext_handlers_status() return - def get_upgrade_guid(self, name): - return self.last_upgrade_guids.get(name, (None, False))[0] - - def get_log_upgrade_guid(self, ext_handler): - return self.last_upgrade_guids.get(ext_handler.name, (None, False))[1] - - def set_log_upgrade_guid(self, ext_handler, log_val): - guid = self.get_upgrade_guid(ext_handler.name) - if guid is not None: - self.last_upgrade_guids[ext_handler.name] = (guid, log_val) + def get_guid(self, name): + return self.last_guids.get(name, None) def is_new_guid(self, ext_handler): - last_guid = self.get_upgrade_guid(ext_handler.name) + last_guid = self.get_guid(ext_handler.name) if last_guid is None: return True return last_guid != ext_handler.properties.upgradeGuid @@ -330,23 +319,10 @@ class ExtHandlersHandler(object): if state == u"enabled" and \ ext_handler.properties.upgradeGuid is not None and \ not self.is_new_guid(ext_handler): - ext_handler_i.ext_handler.properties.version = ext_handler_i.get_installed_version() - ext_handler_i.set_logger() - if self.last_etag != etag: - self.set_log_upgrade_guid(ext_handler, True) - - msg = "New GUID is the same as the old GUID. Exiting without upgrading." - if self.get_log_upgrade_guid(ext_handler): - ext_handler_i.logger.info(msg) - self.set_log_upgrade_guid(ext_handler, False) - ext_handler_i.set_handler_state(ExtHandlerState.Enabled) - ext_handler_i.set_handler_status(status="Ready", message="No change") - ext_handler_i.set_operation(WALAEventOperation.SkipUpdate) - ext_handler_i.report_event(message=ustr(msg), is_success=True) + logger.info("New GUID is the same as the old GUID. Exiting without upgrading.") return - self.set_log_upgrade_guid(ext_handler, True) - ext_handler_i.decide_version(etag=etag, target_state=state) + ext_handler_i.decide_version(target_state=state) if not ext_handler_i.is_upgrade and self.last_etag == etag: if self.log_etag: ext_handler_i.logger.verbose("Version {0} is current for etag {1}", @@ -362,29 +338,23 @@ class ExtHandlersHandler(object): self.handle_enable(ext_handler_i) if ext_handler.properties.upgradeGuid is not None: ext_handler_i.logger.info("New Upgrade GUID: {0}", ext_handler.properties.upgradeGuid) - self.last_upgrade_guids[ext_handler.name] = (ext_handler.properties.upgradeGuid, True) + self.last_guids[ext_handler.name] = ext_handler.properties.upgradeGuid elif state == u"disabled": self.handle_disable(ext_handler_i) # Remove the GUID from the dictionary so that it is upgraded upon re-enable - self.last_upgrade_guids.pop(ext_handler.name, None) + self.last_guids.pop(ext_handler.name, None) elif state == u"uninstall": self.handle_uninstall(ext_handler_i) # Remove the GUID from the dictionary so that it is upgraded upon re-install - self.last_upgrade_guids.pop(ext_handler.name, None) + self.last_guids.pop(ext_handler.name, None) else: message = u"Unknown ext handler state:{0}".format(state) raise ExtensionError(message) - except RestartError: - ext_handler_i.logger.info("GoalState became stale during " - "processing. Restarting with new " - "GoalState") - raise except Exception as e: ext_handler_i.set_handler_status(message=ustr(e), code=-1) ext_handler_i.report_event(message=ustr(e), is_success=False) def handle_enable(self, ext_handler_i): - self.log_process = True old_ext_handler_i = ext_handler_i.get_installed_ext_handler() if old_ext_handler_i is not None and \ old_ext_handler_i.version_gt(ext_handler_i): @@ -411,7 +381,6 @@ class ExtHandlersHandler(object): ext_handler_i.enable() def handle_disable(self, ext_handler_i): - self.log_process = True handler_state = ext_handler_i.get_handler_state() ext_handler_i.logger.info("[Disable] current handler state is: {0}", handler_state.lower()) @@ -419,7 +388,6 @@ class ExtHandlersHandler(object): ext_handler_i.disable() def handle_uninstall(self, ext_handler_i): - self.log_process = True handler_state = ext_handler_i.get_handler_state() ext_handler_i.logger.info("[Uninstall] current handler state is: {0}", handler_state.lower()) @@ -428,7 +396,7 @@ class ExtHandlersHandler(object): ext_handler_i.disable() ext_handler_i.uninstall() ext_handler_i.rm_ext_handler_dir() - + def report_ext_handlers_status(self): """Go through handler_state dir, collect and report status""" vm_status = VMStatus(status="Ready", message="Guest Agent is running") @@ -449,9 +417,7 @@ class ExtHandlersHandler(object): self.protocol.report_vm_status(vm_status) if self.log_report: logger.verbose("Completed vm agent status report") - self.report_status_error_state.reset() except ProtocolError as e: - self.report_status_error_state.incr() message = "Failed to report vm agent status: {0}".format(e) add_event(AGENT_NAME, version=CURRENT_VERSION, @@ -459,25 +425,13 @@ class ExtHandlersHandler(object): is_success=False, message=message) - if self.report_status_error_state.is_triggered(): - message = "Failed to report vm agent status for more than {0}"\ - .format(ERROR_STATE_DELTA) - - add_event(AGENT_NAME, - version=CURRENT_VERSION, - op=WALAEventOperation.ExtensionProcessing, - is_success=False, - message=message) - - self.report_status_error_state.reset() - def report_ext_handler_status(self, vm_status, ext_handler): ext_handler_i = ExtHandlerInstance(ext_handler, self.protocol) handler_status = ext_handler_i.get_handler_status() if handler_status is None: return - guid = self.get_upgrade_guid(ext_handler.name) + guid = self.get_guid(ext_handler.name) if guid is not None: handler_status.upgradeGuid = guid @@ -507,7 +461,9 @@ class ExtHandlerInstance(object): self.pkg = None self.pkg_file = None self.is_upgrade = False - self.set_logger() + + prefix = "[{0}]".format(self.get_full_name()) + self.logger = logger.Logger(logger.DEFAULT_LOGGER, prefix) try: fileutil.mkdir(self.get_log_dir(), mode=0o755) @@ -518,9 +474,12 @@ class ExtHandlerInstance(object): self.logger.add_appender(logger.AppenderType.FILE, logger.LogLevel.INFO, log_file) - def decide_version(self, etag, target_state=None): + def decide_version(self, target_state=None): self.logger.verbose("Decide which version to use") - pkg_list = self.protocol.get_ext_handler_pkgs(self.ext_handler, etag) + try: + pkg_list = self.protocol.get_ext_handler_pkgs(self.ext_handler) + except ProtocolError as e: + raise ExtensionError("Failed to get ext handler pkgs", e) # Determine the desired and installed versions requested_version = FlexibleVersion( @@ -627,13 +586,8 @@ class ExtHandlerInstance(object): raise ExtensionError("Failed to find any valid extension package") self.logger.verbose("Use version: {0}", self.pkg.version) - self.set_logger() return - def set_logger(self): - prefix = "[{0}]".format(self.get_full_name()) - self.logger = logger.Logger(logger.DEFAULT_LOGGER, prefix) - def version_gt(self, other): self_version = self.ext_handler.properties.version other_version = other.ext_handler.properties.version @@ -693,22 +647,19 @@ class ExtHandlerInstance(object): def set_operation(self, op): self.operation = op - def report_event(self, message="", is_success=True, duration=0): + def report_event(self, message="", is_success=True): version = self.ext_handler.properties.version add_event(name=self.ext_handler.name, version=version, message=message, - op=self.operation, is_success=is_success, duration=duration) + op=self.operation, is_success=is_success) def download(self): - begin_utc = datetime.datetime.utcnow() self.logger.verbose("Download extension package") self.set_operation(WALAEventOperation.Download) if self.pkg is None: raise ExtensionError("No package uri found") package = None - uris_shuffled = self.pkg.uris - random.shuffle(uris_shuffled) - for uri in uris_shuffled: + for uri in self.pkg.uris: try: package = self.protocol.download_ext_handler_pkg(uri.uri) if package is not None: @@ -734,8 +685,7 @@ class ExtHandlerInstance(object): for file in fileutil.get_all_files(self.get_base_dir()): fileutil.chmod(file, os.stat(file).st_mode | stat.S_IXUSR) - duration = elapsed_milliseconds(begin_utc) - self.report_event(message="Download succeeded", duration=duration) + self.report_event(message="Download succeeded") self.logger.info("Initialize extension directory") #Save HandlerManifest.json @@ -942,7 +892,6 @@ class ExtHandlerInstance(object): return last_update <= 600 # updated within the last 10 min def launch_command(self, cmd, timeout=300): - begin_utc = datetime.datetime.utcnow() self.logger.verbose("Launch command: [{0}]", cmd) base_dir = self.get_base_dir() try: @@ -968,8 +917,7 @@ class ExtHandlerInstance(object): if ret == None or ret != 0: raise ExtensionError("Non-zero exit code: {0}, {1}".format(ret, cmd)) - duration = elapsed_milliseconds(begin_utc) - self.report_event(message="Launch command succeeded: {0}".format(cmd), duration=duration) + self.report_event(message="Launch command succeeded: {0}".format(cmd)) def load_manifest(self): man_file = self.get_manifest_file() diff --git a/azurelinuxagent/ga/monitor.py b/azurelinuxagent/ga/monitor.py index 71ac9b0..e3ef292 100644 --- a/azurelinuxagent/ga/monitor.py +++ b/azurelinuxagent/ga/monitor.py @@ -203,31 +203,26 @@ class MonitorHandler(object): version=CURRENT_VERSION, op=WALAEventOperation.HeartBeat, is_success=True, - message=msg, - log_event=False) + message=msg) counter += 1 - io_errors = IOErrorCounter.get_and_reset() - hostplugin_errors = io_errors.get("hostplugin") - protocol_errors = io_errors.get("protocol") - other_errors = io_errors.get("other") + ioerrors = IOErrorCounter.get_and_reset() + hostplugin_errors = ioerrors.get("hostplugin") + protocol_errors = ioerrors.get("protocol") + other_errors = ioerrors.get("other") - if hostplugin_errors > 0 \ - or protocol_errors > 0 \ - or other_errors > 0: - - msg = "hostplugin:{0};protocol:{1};other:{2}"\ - .format(hostplugin_errors, - protocol_errors, - other_errors) + if hostplugin_errors > 0 or \ + protocol_errors > 0 or \ + other_errors > 0: + msg = "hostplugin:{0};protocol:{1};other:{2}".format( + hostplugin_errors, protocol_errors, other_errors) add_event( name=AGENT_NAME, version=CURRENT_VERSION, op=WALAEventOperation.HttpErrors, - is_success=True, - message=msg, - log_event=False) + is_success=False, + msg=msg) try: self.collect_and_send_events() diff --git a/azurelinuxagent/ga/update.py b/azurelinuxagent/ga/update.py index 2e43031..03d94c3 100644 --- a/azurelinuxagent/ga/update.py +++ b/azurelinuxagent/ga/update.py @@ -21,7 +21,6 @@ import glob import json import os import platform -import random import re import shutil import signal @@ -45,7 +44,6 @@ from azurelinuxagent.common.event import add_event, add_periodic, \ WALAEventOperation from azurelinuxagent.common.exception import ProtocolError, \ ResourceGoneError, \ - RestartError, \ UpdateError from azurelinuxagent.common.future import ustr from azurelinuxagent.common.osutil import get_osutil @@ -662,7 +660,7 @@ class UpdateHandler(object): continue msg = u"Exception retrieving agent manifests: {0}".format( - ustr(traceback.format_exc())) + ustr(e)) logger.warn(msg) add_event( AGENT_NAME, @@ -729,13 +727,6 @@ class GuestAgent(object): if isinstance(e, ResourceGoneError): raise - # The agent was improperly blacklisting versions due to a timeout - # encountered while downloading a later version. Errors of type - # socket.error are IOError, so this should provide sufficient - # protection against a large class of I/O operation failures. - if isinstance(e, IOError): - raise - # Note the failure, blacklist the agent if the package downloaded # - An exception with a downloaded package indicates the package # is corrupt (e.g., missing the HandlerManifest.json file) @@ -826,9 +817,7 @@ class GuestAgent(object): self._load_error() def _download(self): - uris_shuffled = self.pkg.uris - random.shuffle(uris_shuffled) - for uri in uris_shuffled: + for uri in self.pkg.uris: if not HostPluginProtocol.is_default_channel() and self._fetch(uri.uri): break diff --git a/azurelinuxagent/pa/provision/cloudinit.py b/azurelinuxagent/pa/provision/cloudinit.py index fa47799..c674526 100644 --- a/azurelinuxagent/pa/provision/cloudinit.py +++ b/azurelinuxagent/pa/provision/cloudinit.py @@ -26,9 +26,9 @@ from datetime import datetime import azurelinuxagent.common.conf as conf import azurelinuxagent.common.logger as logger import azurelinuxagent.common.utils.fileutil as fileutil +import azurelinuxagent.common.utils.shellutil as shellutil -from azurelinuxagent.common.event import elapsed_milliseconds, \ - WALAEventOperation +from azurelinuxagent.common.event import elapsed_milliseconds from azurelinuxagent.common.exception import ProvisionError, ProtocolError from azurelinuxagent.common.future import ustr from azurelinuxagent.common.protocol import OVF_FILE_NAME @@ -64,12 +64,9 @@ class CloudInitProvisionHandler(ProvisionHandler): logger.info("Finished provisioning") self.report_ready(thumbprint) - self.report_event("Provisioning with cloud-init succeeded", + self.report_event("Provision succeed", is_success=True, duration=elapsed_milliseconds(utc_start)) - self.report_event(self.create_guest_state_telemetry_messsage(), - is_success=True, - operation=WALAEventOperation.GuestState) except ProvisionError as e: logger.error("Provisioning failed: {0}", ustr(e)) diff --git a/azurelinuxagent/pa/provision/default.py b/azurelinuxagent/pa/provision/default.py index 44e171b..d278975 100644 --- a/azurelinuxagent/pa/provision/default.py +++ b/azurelinuxagent/pa/provision/default.py @@ -22,7 +22,6 @@ Provision handler import os import os.path import re -import socket import time from datetime import datetime @@ -89,14 +88,10 @@ class ProvisionHandler(object): self.write_provisioned() - self.report_event("Provisioning succeeded", + self.report_event("Provision succeed", is_success=True, duration=elapsed_milliseconds(utc_start)) - self.report_event(self.create_guest_state_telemetry_messsage(), - is_success=True, - operation=WALAEventOperation.GuestState) - self.report_ready(thumbprint) logger.info("Provisioning complete") @@ -269,53 +264,12 @@ class ProvisionHandler(object): logger.info("Deploy ssh key pairs.") self.osutil.deploy_ssh_keypair(ovfenv.username, keypair) - def report_event(self, message, is_success=False, duration=0, - operation=WALAEventOperation.Provision): + def report_event(self, message, is_success=False, duration=0): add_event(name=AGENT_NAME, message=message, duration=duration, is_success=is_success, - op=operation) - - def get_cpu_count(self): - try: - count = len([x for x in open('/proc/cpuinfo').readlines() - if x.startswith("processor")]) - return count - except Exception as e: - logger.verbose(u"Failed to determine the CPU count: {0}.", ustr(e)) - pass - return -1 - - def get_mem_size_mb(self): - try: - for line in open('/proc/meminfo').readlines(): - m = re.match('^MemTotal:\s*(\d+) kB$', line) - if m is not None: - return int(int(m.group(1)) / 1024) - except Exception as e: - logger.verbose(u"Failed to determine the memory size: {0}..", ustr(e)) - pass - return -1 - - def create_guest_state_telemetry_messsage(self): - """ - Create a GuestState JSON message that contains the current CPU, Memory - (MB), and hostname of the guest. - - e.g. - - { - "cpu": 1, - "mem": 1024, - "hostname": "server1234" - } - """ - cpu = self.get_cpu_count() - mem = self.get_mem_size_mb() - - return """{{"cpu": {0}, "mem": {1}, "hostname": "{2}"}}"""\ - .format(cpu, mem, socket.gethostname()) + op=WALAEventOperation.Provision) def report_not_ready(self, sub_status, description): status = ProvisionStatus(status="NotReady", subStatus=sub_status, diff --git a/azurelinuxagent/pa/provision/factory.py b/azurelinuxagent/pa/provision/factory.py index 9e88618..d87765f 100644 --- a/azurelinuxagent/pa/provision/factory.py +++ b/azurelinuxagent/pa/provision/factory.py @@ -16,7 +16,9 @@ # import azurelinuxagent.common.conf as conf +import azurelinuxagent.common.logger as logger +from azurelinuxagent.common.utils.textutil import Version from azurelinuxagent.common.version import DISTRO_NAME, DISTRO_VERSION, \ DISTRO_FULL_NAME diff --git a/azurelinuxagent/pa/rdma/suse.py b/azurelinuxagent/pa/rdma/suse.py index 2b6ae29..729c842 100644 --- a/azurelinuxagent/pa/rdma/suse.py +++ b/azurelinuxagent/pa/rdma/suse.py @@ -91,7 +91,7 @@ class SUSERDMAHandler(RDMAHandler): logger.info("Package '%s' is not a match." % entry) else: logger.info("Package '%s' is a match. Installing." % entry) - complete_name = '%s-%s' % (package_name, entry) + complete_name = '%s-%s' % (package_name, version) cmd = zypper_install % complete_name result = shellutil.run(cmd) if result: diff --git a/config/alpine/waagent.conf b/config/alpine/waagent.conf index 883c81b..99495d5 100644 --- a/config/alpine/waagent.conf +++ b/config/alpine/waagent.conf @@ -14,8 +14,7 @@ Provisioning.DeleteRootPassword=y # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=y -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=rsa # Monitor host name changes and publish changes via DHCP requests. @@ -89,5 +88,5 @@ OS.SshDir=/etc/ssh # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/arch/waagent.conf b/config/arch/waagent.conf index cf14e0a..200a458 100644 --- a/config/arch/waagent.conf +++ b/config/arch/waagent.conf @@ -14,8 +14,7 @@ Provisioning.DeleteRootPassword=n # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=y -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=rsa # Monitor host name changes and publish changes via DHCP requests. @@ -115,5 +114,5 @@ OS.SshDir=/etc/ssh # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/bigip/waagent.conf b/config/bigip/waagent.conf index 1e59a6a..9ff6ee1 100644 --- a/config/bigip/waagent.conf +++ b/config/bigip/waagent.conf @@ -25,8 +25,7 @@ Provisioning.DeleteRootPassword=y # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=y -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=rsa # Monitor host name changes and publish changes via DHCP requests. @@ -93,5 +92,5 @@ AutoUpdate.Enabled=y # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/clearlinux/waagent.conf b/config/clearlinux/waagent.conf index c63f92b..8109425 100644 --- a/config/clearlinux/waagent.conf +++ b/config/clearlinux/waagent.conf @@ -25,8 +25,7 @@ Provisioning.DeleteRootPassword=y # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=y -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=rsa # Monitor host name changes and publish changes via DHCP requests. @@ -87,5 +86,5 @@ AutoUpdate.GAFamily=Prod # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/coreos/waagent.conf b/config/coreos/waagent.conf index ee4ebf2..cbb327f 100644 --- a/config/coreos/waagent.conf +++ b/config/coreos/waagent.conf @@ -14,8 +14,7 @@ Provisioning.DeleteRootPassword=n # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=n -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=ed25519 # Monitor host name changes and publish changes via DHCP requests. @@ -115,5 +114,5 @@ OS.AllowHTTP=y # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/freebsd/waagent.conf b/config/freebsd/waagent.conf index 74ad843..6406c75 100644 --- a/config/freebsd/waagent.conf +++ b/config/freebsd/waagent.conf @@ -14,8 +14,7 @@ Provisioning.DeleteRootPassword=y # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=y -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=rsa # Monitor host name changes and publish changes via DHCP requests. @@ -113,5 +112,5 @@ OS.SudoersDir=/usr/local/etc/sudoers.d # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/gaia/waagent.conf b/config/gaia/waagent.conf index 0fd78a8..9c28ba3 100644 --- a/config/gaia/waagent.conf +++ b/config/gaia/waagent.conf @@ -14,8 +14,7 @@ Provisioning.DeleteRootPassword=n # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=n -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=rsa # Monitor host name changes and publish changes via DHCP requests. @@ -112,5 +111,5 @@ AutoUpdate.Enabled=n # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/openbsd/waagent.conf b/config/openbsd/waagent.conf index 580b4a3..a39a9a5 100644 --- a/config/openbsd/waagent.conf +++ b/config/openbsd/waagent.conf @@ -15,7 +15,6 @@ Provisioning.DeleteRootPassword=y Provisioning.RegenerateSshHostKeyPair=y # Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. Provisioning.SshHostKeyPairType=auto # Monitor host name changes and publish changes via DHCP requests. @@ -111,5 +110,5 @@ OS.PasswordPath=/etc/master.passwd # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/suse/waagent.conf b/config/suse/waagent.conf index e83caf3..ba50be6 100644 --- a/config/suse/waagent.conf +++ b/config/suse/waagent.conf @@ -14,8 +14,7 @@ Provisioning.DeleteRootPassword=y # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=y -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=rsa # Monitor host name changes and publish changes via DHCP requests. @@ -115,5 +114,5 @@ OS.SshDir=/etc/ssh # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/ubuntu/waagent.conf b/config/ubuntu/waagent.conf index 4fa2d12..71f2c04 100644 --- a/config/ubuntu/waagent.conf +++ b/config/ubuntu/waagent.conf @@ -14,8 +14,7 @@ Provisioning.DeleteRootPassword=y # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=n -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=rsa # Monitor host name changes and publish changes via DHCP requests. @@ -103,5 +102,5 @@ OS.SshDir=/etc/ssh # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/config/waagent.conf b/config/waagent.conf index 5772645..589ca99 100644 --- a/config/waagent.conf +++ b/config/waagent.conf @@ -15,7 +15,6 @@ Provisioning.DeleteRootPassword=n Provisioning.RegenerateSshHostKeyPair=n # Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. Provisioning.SshHostKeyPairType=rsa # Monitor host name changes and publish changes via DHCP requests. @@ -115,5 +114,5 @@ OS.SshDir=/etc/ssh # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs +# - The default is false to protect the state of exising VMs OS.EnableFirewall=y diff --git a/debian/changelog b/debian/changelog index c9c0460..fa45d18 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +walinuxagent (2.2.21+really2.2.20-0ubuntu1~16.04.1) xenial; urgency=medium + + * Backport bionic version to xenial. + * Revert to an older upstream release: 2.2.20 (LP: #1749589). + - Rename upstream tarball to 2.2.21+really2.2.20 to end up with a + temporarily higher version number than what's in the archive. + * debian/patches/disable_import_test.patch: refreshed patch. + + -- Łukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com> Thu, 15 Feb 2018 14:28:59 +0100 + walinuxagent (2.2.21-0ubuntu1) bionic; urgency=medium * New upstream release (LP: #1746628). diff --git a/debian/patches/disable_import_test.patch b/debian/patches/disable_import_test.patch index e6b4bdb..d8e0e6b 100644 --- a/debian/patches/disable_import_test.patch +++ b/debian/patches/disable_import_test.patch @@ -1,7 +1,7 @@ -Index: walinuxagent-2.2.21/config/waagent.conf +Index: walinuxagent-2.2.21+really2.2.20/config/waagent.conf =================================================================== ---- walinuxagent-2.2.21.orig/config/waagent.conf -+++ walinuxagent-2.2.21/config/waagent.conf +--- walinuxagent-2.2.21+really2.2.20.orig/config/waagent.conf ++++ walinuxagent-2.2.21+really2.2.20/config/waagent.conf @@ -3,16 +3,16 @@ # @@ -21,8 +21,8 @@ Index: walinuxagent-2.2.21/config/waagent.conf +Provisioning.RegenerateSshHostKeyPair=n # Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". - # The "auto" option is supported on OpenSSH 5.9 (2011) and later. -@@ -37,14 +37,14 @@ Provisioning.ExecuteCustomData=n + Provisioning.SshHostKeyPairType=rsa +@@ -36,14 +36,14 @@ Provisioning.ExecuteCustomData=n Provisioning.AllowResetSysUser=n # Format if unformatted. If 'n', resource disk will not be mounted. diff --git a/tests/common/osutil/test_default.py b/tests/common/osutil/test_default.py index c9fa1de..a73f4b4 100644 --- a/tests/common/osutil/test_default.py +++ b/tests/common/osutil/test_default.py @@ -516,16 +516,6 @@ Match host 192.168.1.2\n\ self.assertEqual(-1, util.get_firewall_dropped_packets("not used")) @patch('azurelinuxagent.common.utils.shellutil.run_get_output') - def test_get_firewall_dropped_packets_transient_error_ignored(self, mock_output): - osutil._enable_firewall = True - util = osutil.DefaultOSUtil() - - mock_output.side_effect = [ - (0, "iptables v{0}".format(osutil.IPTABLES_LOCKING_VERSION)), - (3, "can't initialize iptables table `security': iptables who? (do you need to insmod?)")] - self.assertEqual(0, util.get_firewall_dropped_packets("not used")) - - @patch('azurelinuxagent.common.utils.shellutil.run_get_output') def test_get_firewall_dropped_packets(self, mock_output): osutil._enable_firewall = True util = osutil.DefaultOSUtil() @@ -648,34 +638,6 @@ Chain OUTPUT (policy ACCEPT 104 packets, 43628 bytes) ]) self.assertFalse(osutil._enable_firewall) - @patch('azurelinuxagent.common.utils.shellutil.run_get_output') - @patch('azurelinuxagent.common.utils.shellutil.run') - def test_enable_firewall_checks_for_invalid_iptables_options(self, mock_run, mock_output): - osutil._enable_firewall = True - util = osutil.DefaultOSUtil() - - dst = '1.2.3.4' - version = "iptables v{0}".format(osutil.IPTABLES_LOCKING_VERSION) - wait = "-w" - - # iptables uses the following exit codes - # 0 - correct function - # 1 - other errors - # 2 - errors which appear to be caused by invalid or abused command - # line parameters - mock_run.side_effect = [2] - mock_output.return_value = (0, version) - - self.assertFalse(util.enable_firewall(dst_ip='1.2.3.4', uid=42)) - self.assertFalse(osutil._enable_firewall) - - mock_run.assert_has_calls([ - call(osutil.FIREWALL_DROP.format(wait, "C", dst), chk_err=False), - ]) - mock_output.assert_has_calls([ - call(osutil.IPTABLES_VERSION) - ]) - @patch('os.getuid', return_value=42) @patch('azurelinuxagent.common.utils.shellutil.run_get_output') @patch('azurelinuxagent.common.utils.shellutil.run') @@ -708,15 +670,12 @@ Chain OUTPUT (policy ACCEPT 104 packets, 43628 bytes) version = "iptables v{0}".format(osutil.IPTABLES_LOCKING_VERSION) wait = "-w" - mock_run.side_effect = [0, 1, 0, 1] + mock_run.side_effect = [0, 0] mock_output.side_effect = [(0, version), (0, "Output")] - self.assertTrue(util.remove_firewall(dst, uid)) + self.assertTrue(util.remove_firewall()) mock_run.assert_has_calls([ - call(osutil.FIREWALL_DELETE_CONNTRACK.format(wait, dst), chk_err=False), - call(osutil.FIREWALL_DELETE_CONNTRACK.format(wait, dst), chk_err=False), - call(osutil.FIREWALL_DELETE_OWNER.format(wait, dst, uid), chk_err=False), - call(osutil.FIREWALL_DELETE_OWNER.format(wait, dst, uid), chk_err=False), + call(osutil.FIREWALL_FLUSH.format(wait), chk_err=True) ]) mock_output.assert_has_calls([ call(osutil.IPTABLES_VERSION) @@ -730,17 +689,15 @@ Chain OUTPUT (policy ACCEPT 104 packets, 43628 bytes) osutil._enable_firewall = True util = osutil.DefaultOSUtil() - dst_ip='1.2.3.4' - uid=42 version = "iptables v{0}".format(osutil.IPTABLES_LOCKING_VERSION) wait = "-w" - mock_run.side_effect = [2] + mock_run.side_effect = [1, 0] mock_output.side_effect = [(0, version), (1, "Output")] - self.assertFalse(util.remove_firewall(dst_ip, uid)) + self.assertFalse(util.remove_firewall()) mock_run.assert_has_calls([ - call(osutil.FIREWALL_DELETE_CONNTRACK.format(wait, dst_ip), chk_err=False), + call(osutil.FIREWALL_FLUSH.format(wait), chk_err=True) ]) mock_output.assert_has_calls([ call(osutil.IPTABLES_VERSION) diff --git a/tests/common/test_conf.py b/tests/common/test_conf.py index 057c83b..a2c6573 100644 --- a/tests/common/test_conf.py +++ b/tests/common/test_conf.py @@ -65,7 +65,7 @@ class TestConf(AgentTestCase): "AutoUpdate.GAFamily" : "Prod", "EnableOverProvisioning" : False, "OS.AllowHTTP" : False, - "OS.EnableFirewall" : False + "OS.EnableFirewall" : True } def setUp(self): @@ -78,7 +78,6 @@ class TestConf(AgentTestCase): def test_key_value_handling(self): self.assertEqual("Value1", self.conf.get("FauxKey1", "Bad")) self.assertEqual("Value2 Value2", self.conf.get("FauxKey2", "Bad")) - self.assertEqual("delalloc,rw,noatime,nobarrier,users,mode=777", self.conf.get("FauxKey3", "Bad")) def test_get_ssh_dir(self): self.assertTrue(get_ssh_dir(self.conf).startswith("/notareal/path")) @@ -111,5 +110,4 @@ class TestConf(AgentTestCase): for k in TestConf.EXPECTED_CONFIGURATION.keys(): self.assertEqual( TestConf.EXPECTED_CONFIGURATION[k], - configuration[k], - k) + configuration[k]) diff --git a/tests/common/test_errorstate.py b/tests/common/test_errorstate.py deleted file mode 100644 index 7513fe5..0000000 --- a/tests/common/test_errorstate.py +++ /dev/null @@ -1,69 +0,0 @@ -from datetime import timedelta - -from azurelinuxagent.common.errorstate import * -from tests.tools import * - - -class TestErrorState(unittest.TestCase): - def test_errorstate00(self): - """ - If ErrorState is never incremented, it will never trigger. - """ - test_subject = ErrorState(timedelta(seconds=10000)) - self.assertFalse(test_subject.is_triggered()) - self.assertEqual(0, test_subject.count) - - def test_errorstate01(self): - """ - If ErrorState is never incremented, and the timedelta is zero it will - not trigger. - """ - test_subject = ErrorState(timedelta(seconds=0)) - self.assertFalse(test_subject.is_triggered()) - self.assertEqual(0, test_subject.count) - - def test_errorstate02(self): - """ - If ErrorState is triggered, and the current time is within timedelta - of now it will trigger. - """ - test_subject = ErrorState(timedelta(seconds=0)) - test_subject.incr() - - - self.assertTrue(test_subject.is_triggered()) - self.assertEqual(1, test_subject.count) - - @patch('azurelinuxagent.common.errorstate.datetime') - def test_errorstate03(self, mock_time): - """ - ErrorState will not trigger until - 1. ErrorState has been incr() at least once. - 2. The timedelta from the first incr() has elapsed. - """ - test_subject = ErrorState(timedelta(minutes=15)) - - for x in range(1, 10): - mock_time.utcnow = Mock(return_value=datetime.utcnow() + timedelta(minutes=x)) - - test_subject.incr() - self.assertFalse(test_subject.is_triggered()) - - mock_time.utcnow = Mock(return_value=datetime.utcnow() + timedelta(minutes=30)) - test_subject.incr() - self.assertTrue(test_subject.is_triggered()) - - def test_errorstate04(self): - """ - If ErrorState is reset the timestamp of the last incr() is reset to - None. - """ - - test_subject = ErrorState(timedelta(minutes=15)) - self.assertTrue(test_subject.timestamp is None) - - test_subject.incr() - self.assertTrue(test_subject.timestamp is not None) - - test_subject.reset() - self.assertTrue(test_subject.timestamp is None) diff --git a/tests/common/test_event.py b/tests/common/test_event.py index 01bcd7b..d52d3e6 100644 --- a/tests/common/test_event.py +++ b/tests/common/test_event.py @@ -49,7 +49,8 @@ class TestEvent(AgentTestCase): self.assertTrue(es.event_succeeded("Foo", "1.2", "FauxOperation")) def test_event_status_records_status(self): - es = event.EventStatus() + d = tempfile.mkdtemp() + es = event.EventStatus(tempfile.mkdtemp()) es.mark_event_status("Foo", "1.2", "FauxOperation", True) self.assertTrue(es.event_succeeded("Foo", "1.2", "FauxOperation")) @@ -69,7 +70,7 @@ class TestEvent(AgentTestCase): self.assertFalse(es.event_succeeded("Foo", "1.2", "FauxOperation")) def test_should_emit_event_ignores_unknown_operations(self): - event.__event_status__ = event.EventStatus() + event.__event_status__ = event.EventStatus(tempfile.mkdtemp()) self.assertTrue(event.should_emit_event("Foo", "1.2", "FauxOperation", True)) self.assertTrue(event.should_emit_event("Foo", "1.2", "FauxOperation", False)) @@ -82,7 +83,7 @@ class TestEvent(AgentTestCase): def test_should_emit_event_handles_known_operations(self): - event.__event_status__ = event.EventStatus() + event.__event_status__ = event.EventStatus(tempfile.mkdtemp()) # Known operations always initially "fire" for op in event.__event_status_operations__: diff --git a/tests/common/test_logger.py b/tests/common/test_logger.py index 005c429..9e298b3 100644 --- a/tests/common/test_logger.py +++ b/tests/common/test_logger.py @@ -15,20 +15,17 @@ # Requires Python 2.4+ and Openssl 1.0+ # -import json from datetime import datetime import azurelinuxagent.common.logger as logger -from azurelinuxagent.common.event import add_log_event -from azurelinuxagent.common.version import CURRENT_AGENT, CURRENT_VERSION from tests.tools import * _MSG = "This is our test logging message {0} {1}" _DATA = ["arg1", "arg2"] - class TestLogger(AgentTestCase): + @patch('azurelinuxagent.common.logger.Logger.info') def test_periodic_emits_if_not_previously_sent(self, mock_info): logger.reset_periodic() @@ -67,38 +64,3 @@ class TestLogger(AgentTestCase): logger.periodic(logger.EVERY_DAY, _MSG, *_DATA) mock_info.assert_called_once_with(_MSG, *_DATA) - - def test_telemetry_logger(self): - mock = MagicMock() - appender = logger.TelemetryAppender(logger.LogLevel.WARNING, mock) - appender.write(logger.LogLevel.WARNING, "--unit-test--") - - mock.assert_called_once_with(logger.LogLevel.WARNING, "--unit-test--") - - @patch('azurelinuxagent.common.event.EventLogger.save_event') - def test_telemetry_logger1(self, mock_save): - appender = logger.TelemetryAppender(logger.LogLevel.WARNING, add_log_event) - appender.write(logger.LogLevel.WARNING, "--unit-test--") - - self.assertEqual(1, mock_save.call_count) - telemetry_json = json.loads(mock_save.call_args[0][0]) - - self.assertEqual('FFF0196F-EE4C-4EAF-9AA5-776F622DEB4F', telemetry_json['providerId']) - self.assertEqual(7, telemetry_json['eventId']) - - self.assertEqual(5, len(telemetry_json['parameters'])) - for x in telemetry_json['parameters']: - if x['name'] == 'EventName': - self.assertEqual(x['value'], 'Log') - - elif x['name'] == 'CapabilityUsed': - self.assertEqual(x['value'], 'WARNING') - - elif x['name'] == 'Context1': - self.assertEqual(x['value'], '--unit-test--') - - elif x['name'] == 'Context2': - self.assertEqual(x['value'], '') - - elif x['name'] == 'Context3': - self.assertEqual(x['value'], '') diff --git a/tests/data/test_waagent.conf b/tests/data/test_waagent.conf index be0596a..24d05f8 100644 --- a/tests/data/test_waagent.conf +++ b/tests/data/test_waagent.conf @@ -6,7 +6,6 @@ =Value0 FauxKey1= Value1 FauxKey2=Value2 Value2 -FauxKey3=delalloc,rw,noatime,nobarrier,users,mode=777 # Enable instance creation Provisioning.Enabled=y @@ -20,8 +19,7 @@ Provisioning.DeleteRootPassword=y # Generate fresh host key pair. Provisioning.RegenerateSshHostKeyPair=y -# Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". -# The "auto" option is supported on OpenSSH 5.9 (2011) and later. +# Supported values are "rsa", "dsa" and "ecdsa". Provisioning.SshHostKeyPairType=rsa # An EOL comment that should be ignored # Monitor host name changes and publish changes via DHCP requests. @@ -124,5 +122,5 @@ OS.SshDir=/notareal/path # Add firewall rules to protect access to Azure host node services # Note: -# - The default is false to protect the state of existing VMs -OS.EnableFirewall=n +# - The default is false to protect the state of exising VMs +OS.EnableFirewall=y diff --git a/tests/ga/test_extension.py b/tests/ga/test_extension.py index 9a72989..9111cde 100644 --- a/tests/ga/test_extension.py +++ b/tests/ga/test_extension.py @@ -414,8 +414,7 @@ class TestExtension(AgentTestCase): "<Incarnation>4<") test_data.ext_conf = test_data.ext_conf.replace("1.0.0", "1.1.0") exthandlers_handler.run() - self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.0.0") - self._assert_ext_status(protocol.report_ext_status, "success", 0) + self._assert_no_handler_status(protocol.report_vm_status) #Test GUID change with hotfix test_data.goal_state = test_data.goal_state.replace("<Incarnation>4<", @@ -459,8 +458,7 @@ class TestExtension(AgentTestCase): "<Incarnation>10<") test_data.ext_conf = test_data.ext_conf.replace("1.1.0", "1.2.0") exthandlers_handler.run() - self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.1.1") - self._assert_ext_status(protocol.report_ext_status, "success", 0) + self._assert_no_handler_status(protocol.report_vm_status) #Test GUID change with upgrade available test_data.goal_state = test_data.goal_state.replace("<Incarnation>10<", @@ -579,12 +577,12 @@ class TestExtension(AgentTestCase): decision_version = '1.0.0' _, protocol = self._create_mock(WireProtocolData(datafile), *args) - ext_handlers, etag = protocol.get_ext_handlers() + ext_handlers, _ = protocol.get_ext_handlers() self.assertEqual(1, len(ext_handlers.extHandlers)) ext_handler = ext_handlers.extHandlers[0] self.assertEqual('OSTCExtensions.ExampleHandlerLinux', ext_handler.name) self.assertEqual(config_version, ext_handler.properties.version, "config version.") - ExtHandlerInstance(ext_handler, protocol).decide_version(etag) + ExtHandlerInstance(ext_handler, protocol).decide_version() self.assertEqual(decision_version, ext_handler.properties.version, "decision version.") def test_ext_handler_version_decide_between_minor_versions(self, *args): @@ -611,7 +609,6 @@ class TestExtension(AgentTestCase): _, protocol = self._create_mock(WireProtocolData(DATA_FILE), *args) version_uri = Mock() version_uri.uri = 'http://some/Microsoft.OSTCExtensions_ExampleHandlerLinux_asiaeast_manifest.xml' - incarnation = 1 for (installed_version, config_version, expected_version, autoupgrade_expected_version) in cases: ext_handler = Mock() @@ -623,9 +620,8 @@ class TestExtension(AgentTestCase): ext_handler_instance = ExtHandlerInstance(ext_handler, protocol) ext_handler_instance.get_installed_version = Mock(return_value=installed_version) - ext_handler_instance.decide_version(incarnation) + ext_handler_instance.decide_version() self.assertEqual(expected_version, ext_handler.properties.version) - incarnation += 1 ext_handler.properties.version = config_version ext_handler.properties.upgradePolicy = 'auto' @@ -633,9 +629,8 @@ class TestExtension(AgentTestCase): ext_handler_instance = ExtHandlerInstance(ext_handler, protocol) ext_handler_instance.get_installed_version = Mock(return_value=installed_version) - ext_handler_instance.decide_version(incarnation) + ext_handler_instance.decide_version() self.assertEqual(autoupgrade_expected_version, ext_handler.properties.version) - incarnation += 1 if __name__ == '__main__': diff --git a/tests/ga/test_update.py b/tests/ga/test_update.py index 21c81e9..88535f5 100644 --- a/tests/ga/test_update.py +++ b/tests/ga/test_update.py @@ -17,12 +17,17 @@ from __future__ import print_function +from datetime import datetime + +import json +import shutil +import stat + from azurelinuxagent.common.event import * from azurelinuxagent.common.protocol.hostplugin import * from azurelinuxagent.common.protocol.metadata import * from azurelinuxagent.common.protocol.wire import * from azurelinuxagent.common.utils.fileutil import * -from azurelinuxagent.common.version import AGENT_PKG_GLOB, AGENT_DIR_GLOB from azurelinuxagent.ga.update import * from tests.tools import * @@ -384,30 +389,6 @@ class TestGuestAgent(UpdateTestCase): @patch("azurelinuxagent.ga.update.GuestAgent._ensure_downloaded") @patch("azurelinuxagent.ga.update.GuestAgent._ensure_loaded") - def test_resource_gone_error_not_blacklisted(self, mock_loaded, mock_downloaded): - try: - mock_downloaded.side_effect = ResourceGoneError() - agent = GuestAgent(path=self.agent_path) - self.assertFalse(agent.is_blacklisted) - except ResourceGoneError: - pass - except: - self.fail("Exception was not expected!") - - @patch("azurelinuxagent.ga.update.GuestAgent._ensure_downloaded") - @patch("azurelinuxagent.ga.update.GuestAgent._ensure_loaded") - def test_ioerror_not_blacklisted(self, mock_loaded, mock_downloaded): - try: - mock_downloaded.side_effect = IOError() - agent = GuestAgent(path=self.agent_path) - self.assertFalse(agent.is_blacklisted) - except IOError: - pass - except: - self.fail("Exception was not expected!") - - @patch("azurelinuxagent.ga.update.GuestAgent._ensure_downloaded") - @patch("azurelinuxagent.ga.update.GuestAgent._ensure_loaded") def test_is_downloaded(self, mock_loaded, mock_downloaded): agent = GuestAgent(path=self.agent_path) self.assertFalse(agent.is_downloaded) @@ -1018,8 +999,8 @@ class TestUpdate(UpdateTestCase): self.assertTrue(2 < len(self.update_handler.agents)) # Purge every other agent - purged_agents = self.update_handler.agents[1::2] - kept_agents = self.update_handler.agents[::2] + kept_agents = self.update_handler.agents[1::2] + purged_agents = self.update_handler.agents[::2] # Reload and assert only the kept agents remain on disk self.update_handler.agents = kept_agents @@ -1569,7 +1550,6 @@ class ProtocolMock(object): self.call_counts["update_goal_state"] += 1 self.goal_state_forced = self.goal_state_forced or forced - class ResponseMock(Mock): def __init__(self, status=restutil.httpclient.OK, response=None, reason=None): Mock.__init__(self) @@ -1599,6 +1579,5 @@ class TimeMock(Mock): self.next_time += self.time_increment return current_time - if __name__ == '__main__': unittest.main() diff --git a/tests/pa/test_provision.py b/tests/pa/test_provision.py index 2c2d2c9..7045fcc 100644 --- a/tests/pa/test_provision.py +++ b/tests/pa/test_provision.py @@ -15,13 +15,9 @@ # Requires Python 2.4+ and Openssl 1.0+ # -import json -import socket - import azurelinuxagent.common.utils.fileutil as fileutil -from azurelinuxagent.common.event import WALAEventOperation -from azurelinuxagent.common.exception import ProvisionError +from azurelinuxagent.common.exception import ProtocolError from azurelinuxagent.common.osutil.default import DefaultOSUtil from azurelinuxagent.common.protocol import OVF_FILE_NAME from azurelinuxagent.pa.provision import get_provision_handler @@ -119,85 +115,6 @@ class TestProvision(AgentTestCase): ph.osutil.is_current_instance_id.assert_called_once() deprovision_handler.run_changed_unique_id.assert_called_once() - @distros() - @patch('azurelinuxagent.common.osutil.default.DefaultOSUtil.get_instance_id', - return_value='B9F3C233-9913-9F42-8EB3-BA656DF32502') - def test_provision_telemetry_success(self, mock_util, distro_name, distro_version, - distro_full_name): - """ - Assert that the agent issues two telemetry messages as part of a - successful provisioning. - - 1. Provision - 2. GuestState - """ - ph = get_provision_handler(distro_name, distro_version, - distro_full_name) - ph.report_event = MagicMock() - ph.reg_ssh_host_key = MagicMock(return_value='--thumprint--') - - mock_osutil = MagicMock() - mock_osutil.decode_customdata = Mock(return_value="") - - ph.osutil = mock_osutil - ph.protocol_util.osutil = mock_osutil - ph.protocol_util.get_protocol_by_file = MagicMock() - ph.protocol_util.get_protocol = MagicMock() - - conf.get_dvd_mount_point = Mock(return_value=self.tmp_dir) - ovfenv_file = os.path.join(self.tmp_dir, OVF_FILE_NAME) - ovfenv_data = load_data("ovf-env.xml") - fileutil.write_file(ovfenv_file, ovfenv_data) - - ph.run() - - call1 = call("Provisioning succeeded", duration=ANY, is_success=True) - call2 = call(ANY, is_success=True, operation=WALAEventOperation.GuestState) - ph.report_event.assert_has_calls([call1, call2]) - - args, kwargs = ph.report_event.call_args_list[1] - guest_state_json = json.loads(args[0]) - self.assertTrue(1 <= guest_state_json['cpu']) - self.assertTrue(1 <= guest_state_json['mem']) - self.assertEqual(socket.gethostname(), guest_state_json['hostname']) - - @distros() - @patch( - 'azurelinuxagent.common.osutil.default.DefaultOSUtil.get_instance_id', - return_value='B9F3C233-9913-9F42-8EB3-BA656DF32502') - def test_provision_telemetry_fail(self, mock_util, distro_name, - distro_version, - distro_full_name): - """ - Assert that the agent issues one telemetry message as part of a - failed provisioning. - - 1. Provision - """ - ph = get_provision_handler(distro_name, distro_version, - distro_full_name) - ph.report_event = MagicMock() - ph.reg_ssh_host_key = MagicMock(side_effect=ProvisionError( - "--unit-test--")) - - mock_osutil = MagicMock() - mock_osutil.decode_customdata = Mock(return_value="") - - ph.osutil = mock_osutil - ph.protocol_util.osutil = mock_osutil - ph.protocol_util.get_protocol_by_file = MagicMock() - ph.protocol_util.get_protocol = MagicMock() - - conf.get_dvd_mount_point = Mock(return_value=self.tmp_dir) - ovfenv_file = os.path.join(self.tmp_dir, OVF_FILE_NAME) - ovfenv_data = load_data("ovf-env.xml") - fileutil.write_file(ovfenv_file, ovfenv_data) - - ph.run() - ph.report_event.assert_called_once_with( - "[ProvisionError] --unit-test--") - - if __name__ == '__main__': unittest.main() diff --git a/tests/protocol/test_metadata.py b/tests/protocol/test_metadata.py index 5f90f12..5047b86 100644 --- a/tests/protocol/test_metadata.py +++ b/tests/protocol/test_metadata.py @@ -39,7 +39,7 @@ class TestMetadataProtocolGetters(AgentTestCase): protocol.get_certs() ext_handlers, etag = protocol.get_ext_handlers() for ext_handler in ext_handlers.extHandlers: - protocol.get_ext_handler_pkgs(ext_handler, etag) + protocol.get_ext_handler_pkgs(ext_handler) def test_getters(self, *args): test_data = MetadataProtocolData(DATA_FILE) diff --git a/tests/protocol/test_wire.py b/tests/protocol/test_wire.py index 9e475ec..77a0882 100644 --- a/tests/protocol/test_wire.py +++ b/tests/protocol/test_wire.py @@ -43,9 +43,8 @@ class TestWireProtocol(AgentTestCase): protocol.get_vminfo() protocol.get_certs() ext_handlers, etag = protocol.get_ext_handlers() - self.assertEqual("1", etag) for ext_handler in ext_handlers.extHandlers: - protocol.get_ext_handler_pkgs(ext_handler, etag) + protocol.get_ext_handler_pkgs(ext_handler) crt1 = os.path.join(self.tmp_dir, '33B0ABCE4673538650971C10F7D7397E71561F35.crt') @@ -94,7 +93,6 @@ class TestWireProtocol(AgentTestCase): # HostingEnvironmentConfig, will be retrieved the expected number self.assertEqual(2, test_data.call_counts["hostingenvuri"]) - def test_call_storage_kwargs(self, mock_cryptutil, mock_sleep): diff --git a/tests/test_agent.py b/tests/test_agent.py index 2095db0..51b157d 100644 --- a/tests/test_agent.py +++ b/tests/test_agent.py @@ -15,7 +15,9 @@ # Requires Python 2.4+ and Openssl 1.0+ # +import mock import os.path +import sys from azurelinuxagent.agent import * from azurelinuxagent.common.conf import * @@ -37,7 +39,7 @@ Logs.Verbose = False OS.AllowHTTP = False OS.CheckRdmaDriver = False OS.EnableFIPS = True -OS.EnableFirewall = False +OS.EnableFirewall = True OS.EnableRDMA = False OS.HomeDir = /home OS.OpensslPath = /usr/bin/openssl @@ -166,22 +168,3 @@ class TestAgent(AgentTestCase): for k in sorted(configuration.keys()): actual_configuration.append("{0} = {1}".format(k, configuration[k])) self.assertEqual(EXPECTED_CONFIGURATION, actual_configuration) - - def test_agent_usage_message(self): - message = usage() - - # Python 2.6 does not have assertIn() - self.assertTrue("-verbose" in message) - self.assertTrue("-force" in message) - self.assertTrue("-help" in message) - self.assertTrue("-configuration-path" in message) - self.assertTrue("-deprovision" in message) - self.assertTrue("-register-service" in message) - self.assertTrue("-version" in message) - self.assertTrue("-daemon" in message) - self.assertTrue("-start" in message) - self.assertTrue("-run-exthandlers" in message) - self.assertTrue("-show-configuration" in message) - - # sanity check - self.assertFalse("-not-a-valid-option" in message) diff --git a/tests/tools.py b/tests/tools.py index 5c65847..73a64b6 100644 --- a/tests/tools.py +++ b/tests/tools.py @@ -37,9 +37,9 @@ from azurelinuxagent.common.version import PY_VERSION_MAJOR # Import mock module for Python2 and Python3 try: - from unittest.mock import Mock, patch, MagicMock, DEFAULT, ANY, call + from unittest.mock import Mock, patch, MagicMock, DEFAULT, call except ImportError: - from mock import Mock, patch, MagicMock, DEFAULT, ANY, call + from mock import Mock, patch, MagicMock, DEFAULT, call test_dir = os.path.dirname(os.path.abspath(__file__)) data_dir = os.path.join(test_dir, "data") |