summaryrefslogtreecommitdiff
path: root/azurelinuxagent/common
diff options
context:
space:
mode:
Diffstat (limited to 'azurelinuxagent/common')
-rw-r--r--azurelinuxagent/common/conf.py5
-rw-r--r--azurelinuxagent/common/errorstate.py31
-rw-r--r--azurelinuxagent/common/event.py74
-rw-r--r--azurelinuxagent/common/exception.py12
-rw-r--r--azurelinuxagent/common/logger.py34
-rw-r--r--azurelinuxagent/common/osutil/default.py48
-rw-r--r--azurelinuxagent/common/osutil/factory.py9
-rw-r--r--azurelinuxagent/common/osutil/ubuntu.py37
-rw-r--r--azurelinuxagent/common/protocol/metadata.py2
-rw-r--r--azurelinuxagent/common/protocol/restapi.py6
-rw-r--r--azurelinuxagent/common/protocol/wire.py50
-rw-r--r--azurelinuxagent/common/utils/fileutil.py1
-rw-r--r--azurelinuxagent/common/version.py5
13 files changed, 60 insertions, 254 deletions
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()