summaryrefslogtreecommitdiff
path: root/azurelinuxagent/ga
diff options
context:
space:
mode:
Diffstat (limited to 'azurelinuxagent/ga')
-rw-r--r--azurelinuxagent/ga/exthandlers.py77
-rw-r--r--azurelinuxagent/ga/update.py69
2 files changed, 85 insertions, 61 deletions
diff --git a/azurelinuxagent/ga/exthandlers.py b/azurelinuxagent/ga/exthandlers.py
index 9b99d04..e0125aa 100644
--- a/azurelinuxagent/ga/exthandlers.py
+++ b/azurelinuxagent/ga/exthandlers.py
@@ -149,14 +149,17 @@ def migrate_handler_state():
logger.warn("Exception occurred removing {0}: {1}", handler_state_path, str(e))
return
+
class ExtHandlerState(object):
NotInstalled = "NotInstalled"
Installed = "Installed"
Enabled = "Enabled"
+
def get_exthandlers_handler():
return ExtHandlersHandler()
+
class ExtHandlersHandler(object):
def __init__(self):
self.protocol_util = get_protocol_util()
@@ -222,8 +225,8 @@ class ExtHandlersHandler(object):
self.log_etag = True
state = ext_handler.properties.state
- ext_handler_i.logger.info("Expected handler state: {0}", state)
- if state == "enabled":
+ ext_handler_i.logger.info("Target handler state: {0}", state)
+ if state == u"enabled":
self.handle_enable(ext_handler_i)
elif state == u"disabled":
self.handle_disable(ext_handler_i)
@@ -237,21 +240,17 @@ class ExtHandlersHandler(object):
ext_handler_i.report_event(message=ustr(e), is_success=False)
def handle_enable(self, ext_handler_i):
-
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):
raise ExtensionError(u"Downgrade not allowed")
-
handler_state = ext_handler_i.get_handler_state()
- ext_handler_i.logger.info("Current handler state is: {0}", handler_state)
+ ext_handler_i.logger.info("[Enable] current handler state is: {0}",
+ handler_state.lower())
if handler_state == ExtHandlerState.NotInstalled:
ext_handler_i.set_handler_state(ExtHandlerState.NotInstalled)
-
ext_handler_i.download()
-
ext_handler_i.update_settings()
-
if old_ext_handler_i is None:
ext_handler_i.install()
elif ext_handler_i.version_gt(old_ext_handler_i):
@@ -268,13 +267,15 @@ class ExtHandlersHandler(object):
def handle_disable(self, ext_handler_i):
handler_state = ext_handler_i.get_handler_state()
- ext_handler_i.logger.info("Current handler state is: {0}", handler_state)
+ ext_handler_i.logger.info("[Disable] current handler state is: {0}",
+ handler_state.lower())
if handler_state == ExtHandlerState.Enabled:
ext_handler_i.disable()
def handle_uninstall(self, ext_handler_i):
handler_state = ext_handler_i.get_handler_state()
- ext_handler_i.logger.info("Current handler state is: {0}", handler_state)
+ ext_handler_i.logger.info("[Uninstall] current handler state is: {0}",
+ handler_state.lower())
if handler_state != ExtHandlerState.NotInstalled:
if handler_state == ExtHandlerState.Enabled:
ext_handler_i.disable()
@@ -299,7 +300,7 @@ class ExtHandlersHandler(object):
try:
self.protocol.report_vm_status(vm_status)
if self.log_report:
- logger.verbose("Successfully reported vm agent status")
+ logger.verbose("Completed vm agent status report")
except ProtocolError as e:
message = "Failed to report vm agent status: {0}".format(e)
add_event(AGENT_NAME, version=CURRENT_VERSION, is_success=False, message=message)
@@ -510,7 +511,7 @@ class ExtHandlerInstance(object):
op=self.operation, is_success=is_success)
def download(self):
- self.logger.info("Download extension package")
+ self.logger.verbose("Download extension package")
self.set_operation(WALAEventOperation.Download)
if self.pkg is None:
raise ExtensionError("No package uri found")
@@ -527,7 +528,7 @@ class ExtHandlerInstance(object):
if package is None:
raise ExtensionError("Failed to download extension")
- self.logger.info("Unpack extension package")
+ self.logger.verbose("Unpack extension package")
pkg_file = os.path.join(conf.get_lib_dir(),
os.path.basename(uri.uri) + ".zip")
try:
@@ -569,38 +570,38 @@ class ExtHandlerInstance(object):
self.create_handler_env()
def enable(self):
- self.logger.info("Enable extension.")
self.set_operation(WALAEventOperation.Enable)
-
man = self.load_manifest()
- self.launch_command(man.get_enable_command(), timeout=300)
+ enable_cmd = man.get_enable_command()
+ self.logger.info("Enable extension [{0}]".format(enable_cmd))
+ self.launch_command(enable_cmd, timeout=300)
self.set_handler_state(ExtHandlerState.Enabled)
self.set_handler_status(status="Ready", message="Plugin enabled")
def disable(self):
- self.logger.info("Disable extension.")
self.set_operation(WALAEventOperation.Disable)
-
man = self.load_manifest()
- self.launch_command(man.get_disable_command(), timeout=900)
+ disable_cmd = man.get_disable_command()
+ self.logger.info("Disable extension [{0}]".format(disable_cmd))
+ self.launch_command(disable_cmd, timeout=900)
self.set_handler_state(ExtHandlerState.Installed)
self.set_handler_status(status="NotReady", message="Plugin disabled")
def install(self):
- self.logger.info("Install extension.")
- self.set_operation(WALAEventOperation.Install)
-
man = self.load_manifest()
- self.launch_command(man.get_install_command(), timeout=900)
+ install_cmd = man.get_install_command()
+ self.logger.info("Install extension [{0}]".format(install_cmd))
+ self.set_operation(WALAEventOperation.Install)
+ self.launch_command(install_cmd, timeout=900)
self.set_handler_state(ExtHandlerState.Installed)
def uninstall(self):
- self.logger.info("Uninstall extension.")
- self.set_operation(WALAEventOperation.UnInstall)
-
try:
+ self.set_operation(WALAEventOperation.UnInstall)
man = self.load_manifest()
- self.launch_command(man.get_uninstall_command())
+ uninstall_cmd = man.get_uninstall_command()
+ self.logger.info("Uninstall extension [{0}]".format(uninstall_cmd))
+ self.launch_command(uninstall_cmd)
except ExtensionError as e:
self.report_event(message=ustr(e), is_success=False)
@@ -608,18 +609,19 @@ class ExtHandlerInstance(object):
try:
base_dir = self.get_base_dir()
if os.path.isdir(base_dir):
- self.logger.info("Remove ext handler dir: {0}", base_dir)
+ self.logger.info("Remove extension handler directory: {0}",
+ base_dir)
shutil.rmtree(base_dir)
except IOError as e:
- message = "Failed to rm ext handler dir: {0}".format(e)
+ message = "Failed to remove extension handler directory: {0}".format(e)
self.report_event(message=message, is_success=False)
def update(self):
- self.logger.info("Update extension.")
self.set_operation(WALAEventOperation.Update)
-
man = self.load_manifest()
- self.launch_command(man.get_update_command(), timeout=900)
+ update_cmd = man.get_update_command()
+ self.logger.info("Update extension [{0}]".format(update_cmd))
+ self.launch_command(update_cmd, timeout=900)
def update_with_install(self):
man = self.load_manifest()
@@ -709,23 +711,24 @@ class ExtHandlerInstance(object):
heartbeat = json.loads(heartbeat_json)[0]['heartbeat']
except IOError as e:
raise ExtensionError("Failed to get heartbeat file:{0}".format(e))
- except ValueError as e:
+ except (ValueError, KeyError) as e:
raise ExtensionError("Malformed heartbeat file: {0}".format(e))
return heartbeat
def is_responsive(self, heartbeat_file):
- last_update=int(time.time() - os.stat(heartbeat_file).st_mtime)
- return last_update <= 600 # updated within the last 10 min
+ last_update = int(time.time() - os.stat(heartbeat_file).st_mtime)
+ return last_update <= 600 # updated within the last 10 min
def launch_command(self, cmd, timeout=300):
- self.logger.info("Launch command:{0}", cmd)
+ self.logger.verbose("Launch command: [{0}]", cmd)
base_dir = self.get_base_dir()
try:
devnull = open(os.devnull, 'w')
child = subprocess.Popen(base_dir + "/" + cmd,
shell=True,
cwd=base_dir,
- stdout=devnull)
+ stdout=devnull,
+ env=os.environ)
except Exception as e:
#TODO do not catch all exception
raise ExtensionError("Failed to launch: {0}, {1}".format(cmd, e))
diff --git a/azurelinuxagent/ga/update.py b/azurelinuxagent/ga/update.py
index 59bc70c..203bb41 100644
--- a/azurelinuxagent/ga/update.py
+++ b/azurelinuxagent/ga/update.py
@@ -27,6 +27,7 @@ import signal
import subprocess
import sys
import time
+import traceback
import zipfile
import azurelinuxagent.common.conf as conf
@@ -40,6 +41,7 @@ from azurelinuxagent.common.exception import UpdateError, ProtocolError
from azurelinuxagent.common.future import ustr
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.protocol import get_protocol_util
+from azurelinuxagent.common.protocol.hostplugin import HostPluginProtocol
from azurelinuxagent.common.utils.flexible_version import FlexibleVersion
from azurelinuxagent.common.version import AGENT_NAME, AGENT_VERSION, AGENT_LONG_VERSION, \
AGENT_DIR_GLOB, AGENT_PKG_GLOB, \
@@ -49,7 +51,6 @@ from azurelinuxagent.common.version import AGENT_NAME, AGENT_VERSION, AGENT_LONG
from azurelinuxagent.ga.exthandlers import HandlerManifest
-
AGENT_ERROR_FILE = "error.json" # File name for agent error record
AGENT_MANIFEST_FILE = "HandlerManifest.json"
@@ -140,14 +141,24 @@ class UpdateHandler(object):
cmds,
cwd=agent_dir,
stdout=sys.stdout,
- stderr=sys.stderr)
+ stderr=sys.stderr,
+ env=os.environ)
+
+ logger.verbose(u"Agent {0} launched with command '{1}'", agent_name, agent_cmd)
- logger.info(u"Agent {0} launched with command '{1}'", agent_name, agent_cmd)
+ # If the most current agent is the installed agent and update is enabled,
+ # assume updates are likely available and poll every second.
+ # This reduces the start-up impact of finding / launching agent updates on
+ # fresh VMs.
+ if latest_agent is None and conf.get_autoupdate_enabled():
+ poll_interval = 1
+ else:
+ poll_interval = CHILD_POLL_INTERVAL
ret = None
start_time = time.time()
while (time.time() - start_time) < CHILD_HEALTH_INTERVAL:
- time.sleep(CHILD_POLL_INTERVAL)
+ time.sleep(poll_interval)
ret = self.child_process.poll()
if ret is not None:
break
@@ -249,6 +260,7 @@ class UpdateHandler(object):
except Exception as e:
logger.warn(u"Agent {0} failed with exception: {1}", CURRENT_AGENT, ustr(e))
+ logger.warn(traceback.format_exc())
sys.exit(1)
return
@@ -328,7 +340,7 @@ class UpdateHandler(object):
return False
family = conf.get_autoupdate_gafamily()
- logger.info("Checking for agent family {0} updates", family)
+ logger.verbose("Checking for agent family {0} updates", family)
self.last_attempt_time = now
try:
@@ -348,7 +360,7 @@ class UpdateHandler(object):
manifests = [m for m in manifest_list.vmAgentManifests \
if m.family == family and len(m.versionsManifestUris) > 0]
if len(manifests) == 0:
- logger.info(u"Incarnation {0} has no agent family {1} updates", etag, family)
+ logger.verbose(u"Incarnation {0} has no agent family {1} updates", etag, family)
return False
try:
@@ -595,7 +607,7 @@ class GuestAgent(object):
self.version = FlexibleVersion(version)
location = u"disk" if path is not None else u"package"
- logger.info(u"Instantiating Agent {0} from {1}", self.name, location)
+ logger.verbose(u"Instantiating Agent {0} from {1}", self.name, location)
self.error = None
self._load_error()
@@ -651,14 +663,14 @@ class GuestAgent(object):
def _ensure_downloaded(self):
try:
- logger.info(u"Ensuring Agent {0} is downloaded", self.name)
+ logger.verbose(u"Ensuring Agent {0} is downloaded", self.name)
if self.is_blacklisted:
- logger.info(u"Agent {0} is blacklisted - skipping download", self.name)
+ logger.warn(u"Agent {0} is blacklisted - skipping download", self.name)
return
if self.is_downloaded:
- logger.info(u"Agent {0} was previously downloaded - skipping download", self.name)
+ logger.verbose(u"Agent {0} was previously downloaded - skipping download", self.name)
self._load_manifest()
return
@@ -672,7 +684,7 @@ class GuestAgent(object):
self._load_error()
msg = u"Agent {0} downloaded successfully".format(self.name)
- logger.info(msg)
+ logger.verbose(msg)
add_event(
AGENT_NAME,
version=self.version,
@@ -698,18 +710,24 @@ class GuestAgent(object):
def _download(self):
for uri in self.pkg.uris:
- if self._fetch(uri.uri):
+ if not HostPluginProtocol.is_default_channel() and self._fetch(uri.uri):
break
- else:
- if self.host is not None and self.host.ensure_initialized():
+ elif self.host is not None and self.host.ensure_initialized():
+ if not HostPluginProtocol.is_default_channel():
logger.warn("Download unsuccessful, falling back to host plugin")
- uri, headers = self.host.get_artifact_request(uri.uri, self.host.manifest_uri)
- if uri is not None \
- and headers is not None \
- and self._fetch(uri, headers=headers):
- break
else:
- logger.warn("Download unsuccessful, host plugin not available")
+ logger.verbose("Using host plugin as default channel")
+
+ uri, headers = self.host.get_artifact_request(uri.uri, self.host.manifest_uri)
+ if self._fetch(uri, headers=headers):
+ if not HostPluginProtocol.is_default_channel():
+ logger.verbose("Setting host plugin as default channel")
+ HostPluginProtocol.set_default_channel(True)
+ break
+ else:
+ logger.warn("Host plugin download unsuccessful")
+ else:
+ logger.error("No download channels available")
if not os.path.isfile(self.get_agent_pkg_path()):
msg = u"Unable to download Agent {0} from any URI".format(self.name)
@@ -731,7 +749,10 @@ class GuestAgent(object):
fileutil.write_file(self.get_agent_pkg_path(),
bytearray(package),
asbin=True)
- logger.info(u"Agent {0} downloaded from {1}", self.name, uri)
+ logger.verbose(u"Agent {0} downloaded from {1}", self.name, uri)
+ else:
+ logger.verbose("Fetch was unsuccessful [{0}]",
+ HostPluginProtocol.read_response_error(resp))
except restutil.HttpError as http_error:
logger.verbose(u"Agent {0} download from {1} failed [{2}]",
self.name,
@@ -744,7 +765,7 @@ class GuestAgent(object):
if self.error is None:
self.error = GuestAgentError(self.get_agent_error_file())
self.error.load()
- logger.info(u"Agent {0} error state: {1}", self.name, ustr(self.error))
+ logger.verbose(u"Agent {0} error state: {1}", self.name, ustr(self.error))
except Exception as e:
logger.warn(u"Agent {0} failed loading error state: {1}", self.name, ustr(e))
return
@@ -780,7 +801,7 @@ class GuestAgent(object):
ustr(e))
raise UpdateError(msg)
- logger.info(
+ logger.verbose(
u"Agent {0} loaded manifest from {1}",
self.name,
self.get_agent_manifest_path())
@@ -810,7 +831,7 @@ class GuestAgent(object):
self.get_agent_dir())
raise UpdateError(msg)
- logger.info(
+ logger.verbose(
u"Agent {0} unpacked successfully to {1}",
self.name,
self.get_agent_dir())