in azurelinuxagent/ga/agent_update_handler.py [0:0]
def run(self, goal_state, ext_gs_updated):
try:
# If auto update is disabled, we don't proceed with update
if not conf.get_auto_update_to_latest_version():
return
# Update the state only on new goal state
if ext_gs_updated:
# Reset the last reported update state on new goal state before we attempt update otherwise we keep reporting the last update error if any
self._last_attempted_update_error_msg = ""
self._gs_id = goal_state.extensions_goal_state.id
self._updater.sync_new_gs_id(self._gs_id)
agent_family = self._get_agent_family_manifest(goal_state)
# Always agent uses self-update for initial update regardless vm enrolled into RSM or not
# So ignoring the check for updater switch for the initial goal state/update
if not GuestAgentUpdateUtil.is_initial_update():
# Updater will return True or False if we need to switch the updater
# If self-updater receives RSM update enabled, it will switch to RSM updater
# If RSM updater receives RSM update disabled, it will switch to self-update
# No change in updater if GS not updated
is_rsm_update_enabled = self._updater.is_rsm_update_enabled(agent_family, ext_gs_updated)
if not is_rsm_update_enabled and isinstance(self._updater, RSMVersionUpdater):
msg = "VM not enabled for RSM updates, switching to self-update mode"
logger.info(msg)
add_event(op=WALAEventOperation.AgentUpgrade, message=msg, log_event=False)
self._updater = SelfUpdateVersionUpdater(self._gs_id)
GuestAgentUpdateUtil.remove_rsm_update_state_file()
if is_rsm_update_enabled and isinstance(self._updater, SelfUpdateVersionUpdater):
msg = "VM enabled for RSM updates, switching to RSM update mode"
logger.info(msg)
add_event(op=WALAEventOperation.AgentUpgrade, message=msg, log_event=False)
self._updater = RSMVersionUpdater(self._gs_id, self._daemon_version)
GuestAgentUpdateUtil.save_rsm_update_state_file()
# If updater is changed in previous step, we allow update as it consider as first attempt. If not, it checks below condition
# RSM checks new goal state; self-update checks manifest download interval
if not self._updater.is_update_allowed_this_time(ext_gs_updated):
return
self._updater.retrieve_agent_version(agent_family, goal_state)
if not self._updater.is_retrieved_version_allowed_to_update(agent_family):
return
self._updater.log_new_agent_update_message()
agent = self._updater.download_and_get_new_agent(self._protocol, agent_family, goal_state)
# Below condition is to break the update loop if new agent is in bad state in previous attempts
# If the bad agent update already attempted 3 times, we don't want to continue with update anymore.
# Otherewise we allow the update by increment the update attempt count and clear the bad state to make good agent
# [Note: As a result, it is breaking contract between RSM and agent, we may NOT honor the RSM retries for that version]
if agent.get_update_attempt_count() >= 3:
msg = "Attempted enough update retries for version: {0} but still agent not recovered from bad state. So, we stop updating to this version".format(str(agent.version))
raise AgentUpdateError(msg)
else:
agent.clear_error()
agent.inc_update_attempt_count()
msg = "Agent update attempt count: {0} for version: {1}".format(agent.get_update_attempt_count(), str(agent.version))
logger.info(msg)
add_event(op=WALAEventOperation.AgentUpgrade, message=msg, log_event=False)
self._updater.purge_extra_agents_from_disk()
self._updater.proceed_with_update()
except Exception as err:
log_error = True
if isinstance(err, AgentUpgradeExitException):
raise err
elif isinstance(err, AgentUpdateError):
error_msg = ustr(err)
elif isinstance(err, AgentFamilyMissingError):
error_msg = ustr(err)
# Agent family missing error is permanent in the given goal state, so we don't want to log it on every iteration of main loop if there is no new goal state
log_error = ext_gs_updated
else:
error_msg = "Unable to update Agent: {0}".format(textutil.format_exception(err))
if log_error:
logger.warn(error_msg)
add_event(op=WALAEventOperation.AgentUpgrade, is_success=False, message=error_msg, log_event=False)
self._last_attempted_update_error_msg = error_msg
# save initial update state when agent is doing first update
finally:
if GuestAgentUpdateUtil.is_initial_update():
GuestAgentUpdateUtil.save_initial_update_state_file()