Merge pull request #200 from brendandixon/2.1_selfupdate

Separate provision agent and guest agent
This commit is contained in:
brendandixon
2016-05-31 11:23:11 -07:00
92 changed files with 1461 additions and 1031 deletions
+82 -19
View File
@@ -25,41 +25,90 @@ import os
import sys
import re
import subprocess
from azurelinuxagent.metadata import AGENT_NAME, AGENT_LONG_VERSION, \
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.event as event
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.version import AGENT_NAME, AGENT_LONG_VERSION, \
DISTRO_NAME, DISTRO_VERSION, \
PY_VERSION_MAJOR, PY_VERSION_MINOR, \
PY_VERSION_MICRO
from azurelinuxagent.distro.loader import get_distro
from azurelinuxagent.common.osutil import get_osutil
class Agent(object):
def __init__(self, verbose):
"""
Initialize agent running environment.
"""
self.distro = get_distro();
self.distro.init_handler.run(verbose)
self.osutil = get_osutil()
#Init stdout log
level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
logger.add_logger_appender(logger.AppenderType.STDOUT, level)
#Init config
conf_file_path = self.osutil.get_agent_conf_file_path()
conf.load_conf_from_file(conf_file_path)
#Init log
verbose = verbose or conf.get_logs_verbose()
level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
logger.add_logger_appender(logger.AppenderType.FILE, level,
path="/var/log/waagent.log")
logger.add_logger_appender(logger.AppenderType.CONSOLE, level,
path="/dev/console")
#Init event reporter
event_dir = os.path.join(conf.get_lib_dir(), "events")
event.init_event_logger(event_dir)
event.enable_unhandled_err_dump("WALA")
def daemon(self):
"""
Run agent daemon
"""
self.distro.daemon_handler.run()
from azurelinuxagent.daemon import get_daemon_handler
daemon_handler = get_daemon_handler()
daemon_handler.run()
def provision(self):
"""
Run provision command
"""
from azurelinuxagent.pa.provision import get_provision_handler
provision_handler = get_provision_handler()
provision_handler.run()
def deprovision(self, force=False, deluser=False):
"""
Run deprovision command
"""
self.distro.deprovision_handler.run(force=force, deluser=deluser)
from azurelinuxagent.pa.deprovision import get_deprovision_handler
deprovision_handler = get_deprovision_handler()
deprovision_handler.run(force=force, deluser=deluser)
def register_service(self):
"""
Register agent as a service
"""
print("Register {0} service".format(AGENT_NAME))
self.distro.osutil.register_agent_service()
self.osutil.register_agent_service()
print("Start {0} service".format(AGENT_NAME))
self.distro.osutil.start_agent_service()
self.osutil.start_agent_service()
def update(self):
"""
Run extension handlers handler
"""
from azurelinuxagent.ga.update import get_update_handler
update_handler = get_update_handler()
update_handler.run()
def run_exthandlers(self):
"""
Run extension handlers handler
"""
from azurelinuxagent.ga.exthandlers import get_exthandlers_handler
exthandlers_handler = get_exthandlers_handler()
exthandlers_handler.run()
def main():
"""
@@ -74,15 +123,24 @@ def main():
elif command == "start":
start()
else:
agent = Agent(verbose)
if command == "deprovision+user":
agent.deprovision(force, deluser=True)
elif command == "deprovision":
agent.deprovision(force, deluser=False)
elif command == "register-service":
agent.register_service()
elif command == "daemon":
agent.daemon()
try:
agent = Agent(verbose)
if command == "deprovision+user":
agent.deprovision(force, deluser=True)
elif command == "provision":
agent.provision()
elif command == "deprovision":
agent.deprovision(force, deluser=False)
elif command == "register-service":
agent.register_service()
elif command == "daemon":
agent.daemon()
elif command == "update":
agent.update()
elif command == "run-exthandlers":
agent.run_exthandlers()
except Exception as e:
logger.error(u"Failed to run '{0}': {1}", command, e)
def parse_args(sys_args):
"""
@@ -102,6 +160,10 @@ def parse_args(sys_args):
cmd = "start"
elif re.match("^([-/]*)register-service", a):
cmd = "register-service"
elif re.match("^([-/]*)update", a):
cmd = "update"
elif re.match("^([-/]*)run-exthandlers", a):
cmd = "run-exthandlers"
elif re.match("^([-/]*)version", a):
cmd = "version"
elif re.match("^([-/]*)verbose", a):
@@ -129,7 +191,8 @@ def usage():
"""
print("")
print((("usage: {0} [-verbose] [-force] [-help]"
"-deprovision[+user]|-register-service|-version|-daemon|-start]"
"-deprovision[+user]|-register-service|-version|-daemon|-start|"
"-update|-run-exthandlers]"
"").format(sys.argv[0])))
print("")
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,8 +21,8 @@
Module conf loads and parses configuration file
"""
import os
import azurelinuxagent.utils.fileutil as fileutil
from azurelinuxagent.exception import AgentConfigError
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.common.exception import AgentConfigError
class ConfigurationProvider(object):
"""
@@ -167,3 +167,9 @@ def get_resourcedisk_filesystem(conf=__conf__):
def get_resourcedisk_swap_size_mb(conf=__conf__):
return conf.get_int("ResourceDisk.SwapSizeMB", 0)
def get_autoupdate_gafamily(conf=__conf__):
return conf.get("AutoUpdate.GAFamily", "Prod")
def get_autoupdate_enabled(conf=__conf__):
return conf.get_switch("AutoUpdate.Enabled", True)
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,29 +13,34 @@
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
import os
import socket
import array
import time
import threading
import azurelinuxagent.logger as logger
import azurelinuxagent.conf as conf
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
from azurelinuxagent.utils.textutil import hex_dump, hex_dump2, hex_dump3, \
compare_bytes, str_to_ord, \
unpack_big_endian, \
unpack_little_endian, \
int_to_ip4_addr
from azurelinuxagent.exception import DhcpError
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
from azurelinuxagent.common.utils.textutil import hex_dump, hex_dump2, \
hex_dump3, \
compare_bytes, str_to_ord, \
unpack_big_endian, \
unpack_little_endian, \
int_to_ip4_addr
from azurelinuxagent.common.exception import DhcpError
from azurelinuxagent.common.osutil import get_osutil
def get_dhcp_handler():
return DhcpHandler()
class DhcpHandler(object):
"""
Azure use DHCP option 245 to pass endpoint ip to VMs.
"""
def __init__(self, distro):
self.distro = distro
def __init__(self):
self.osutil = get_osutil()
self.endpoint = None
self.gateway = None
self.routes = None
@@ -56,13 +59,13 @@ class DhcpHandler(object):
"""
Wait for network stack to be initialized.
"""
ipv4 = self.distro.osutil.get_ip4_addr()
ipv4 = self.osutil.get_ip4_addr()
while ipv4 == '' or ipv4 == '0.0.0.0':
logger.info("Waiting for network.")
time.sleep(10)
logger.info("Try to start network interface.")
self.distro.osutil.start_network()
ipv4 = self.distro.osutil.get_ip4_addr()
self.osutil.start_network()
ipv4 = self.osutil.get_ip4_addr()
def conf_routes(self):
logger.info("Configure routes")
@@ -70,16 +73,16 @@ class DhcpHandler(object):
logger.info("Routes:{0}", self.routes)
#Add default gateway
if self.gateway is not None:
self.distro.osutil.route_add(0 , 0, self.gateway)
self.osutil.route_add(0 , 0, self.gateway)
if self.routes is not None:
for route in self.routes:
self.distro.osutil.route_add(route[0], route[1], route[2])
self.osutil.route_add(route[0], route[1], route[2])
def _send_dhcp_req(self, request):
__waiting_duration__ = [0, 10, 30, 60, 60]
for duration in __waiting_duration__:
try:
self.distro.osutil.allow_dhcp_broadcast()
self.osutil.allow_dhcp_broadcast()
response = socket_send(request)
validate_dhcp_resp(request, response)
return response
@@ -95,7 +98,8 @@ class DhcpHandler(object):
Stop dhcp service if necessary
"""
logger.info("Send dhcp request")
mac_addr = self.distro.osutil.get_mac_addr()
mac_addr = self.osutil.get_mac_addr()
req = build_dhcp_request(mac_addr)
# Do unicast first, then fallback to broadcast if fails.
req = build_dhcp_request(mac_addr, self._request_broadcast)
@@ -103,23 +107,23 @@ class DhcpHandler(object):
self._request_broadcast = True
# Temporary allow broadcast for dhcp. Remove the route when done.
missing_default_route = self.distro.osutil.is_missing_default_route()
ifname = self.distro.osutil.get_if_name()
missing_default_route = self.osutil.is_missing_default_route()
ifname = self.osutil.get_if_name()
if missing_default_route:
self.distro.osutil.set_route_for_dhcp_broadcast(ifname)
self.osutil.set_route_for_dhcp_broadcast(ifname)
# In some distros, dhcp service needs to be shutdown before agent probe
# endpoint through dhcp.
if self.distro.osutil.is_dhcp_enabled():
self.distro.osutil.stop_dhcp_service()
if self.osutil.is_dhcp_enabled():
self.osutil.stop_dhcp_service()
resp = self._send_dhcp_req(req)
if self.distro.osutil.is_dhcp_enabled():
self.distro.osutil.start_dhcp_service()
if self.osutil.is_dhcp_enabled():
self.osutil.start_dhcp_service()
if missing_default_route:
self.distro.osutil.remove_route_for_dhcp_broadcast(ifname)
self.osutil.remove_route_for_dhcp_broadcast(ifname)
if resp is None:
raise DhcpError("Failed to receive dhcp response.")
@@ -24,14 +24,14 @@ import time
import datetime
import threading
import platform
import azurelinuxagent.logger as logger
from azurelinuxagent.exception import EventError, ProtocolError
from azurelinuxagent.future import ustr
from azurelinuxagent.protocol.restapi import TelemetryEventParam, \
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.exception import EventError, ProtocolError
from azurelinuxagent.common.future import ustr
from azurelinuxagent.common.protocol.restapi import TelemetryEventParam, \
TelemetryEventList, \
TelemetryEvent, \
set_properties, get_properties
from azurelinuxagent.metadata import DISTRO_NAME, DISTRO_VERSION, \
from azurelinuxagent.common.version import DISTRO_NAME, DISTRO_VERSION, \
DISTRO_CODE_NAME, AGENT_VERSION
@@ -113,3 +113,11 @@ class CryptError(AgentError):
"""
def __init__(self, msg=None, inner=None):
super(CryptError, self).__init__('000011', msg, inner)
class UpdateError(AgentError):
"""
Update Guest Agent error
"""
def __init__(self, msg=None, inner=None):
super(UpdateError, self).__init__('000012', msg, inner)
@@ -14,15 +14,12 @@
#
# Requires Python 2.4+ and openssl_bin 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
"""
Log utils
"""
import os
import sys
from azurelinuxagent.future import ustr
from azurelinuxagent.common.future import ustr
from datetime import datetime
class Logger(object):
+18
View File
@@ -0,0 +1,18 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.common.osutil.factory import get_osutil
@@ -26,11 +26,11 @@ import struct
import fcntl
import time
import base64
import azurelinuxagent.logger as logger
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.textutil as textutil
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.textutil as textutil
from azurelinuxagent.common.osutil.default import DefaultOSUtil
class CoreOSUtil(DefaultOSUtil):
def __init__(self):
@@ -26,11 +26,11 @@ import struct
import fcntl
import time
import base64
import azurelinuxagent.logger as logger
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.textutil as textutil
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.textutil as textutil
from azurelinuxagent.common.osutil.default import DefaultOSUtil
class DebianOSUtil(DefaultOSUtil):
def __init__(self):
@@ -26,14 +26,14 @@ import time
import pwd
import fcntl
import base64
import azurelinuxagent.logger as logger
import azurelinuxagent.conf as conf
from azurelinuxagent.exception import OSUtilError
from azurelinuxagent.future import ustr
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.textutil as textutil
from azurelinuxagent.utils.cryptutil import CryptUtil
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.exception import OSUtilError
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.textutil as textutil
from azurelinuxagent.common.utils.cryptutil import CryptUtil
__RULES_FILES__ = [ "/lib/udev/rules.d/75-persistent-net-generator.rules",
"/etc/udev/rules.d/70-persistent-net.rules" ]
@@ -15,56 +15,55 @@
# Requires Python 2.4+ and Openssl 1.0+
#
import azurelinuxagent.logger as logger
from azurelinuxagent.utils.textutil import Version
from azurelinuxagent.metadata import DISTRO_NAME, DISTRO_VERSION, \
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
from azurelinuxagent.distro.default.distro import DefaultDistro
from azurelinuxagent.distro.ubuntu.distro import UbuntuDistro, \
Ubuntu14Distro, \
Ubuntu12Distro, \
UbuntuSnappyDistro
from azurelinuxagent.distro.redhat.distro import RedhatDistro, Redhat6xDistro
from azurelinuxagent.distro.coreos.distro import CoreOSDistro
from azurelinuxagent.distro.suse.distro import SUSE11Distro, SUSEDistro
from azurelinuxagent.distro.debian.distro import DebianDistro
from azurelinuxagent.distro.freebsd.distro import FreeBSDDistro
def get_distro(distro_name=DISTRO_NAME, distro_version=DISTRO_VERSION,
from .default import DefaultOSUtil
from .coreos import CoreOSUtil
from .debian import DebianOSUtil
from .freebsd import FreeBSDOSUtil
from .redhat import RedhatOSUtil, Redhat6xOSUtil
from .suse import SUSEOSUtil, SUSE11OSUtil
from .ubuntu import UbuntuOSUtil, Ubuntu12OSUtil, Ubuntu14OSUtil, \
UbuntuSnappyOSUtil
def get_osutil(distro_name=DISTRO_NAME, distro_version=DISTRO_VERSION,
distro_full_name=DISTRO_FULL_NAME):
if distro_name == "ubuntu":
if Version(distro_version) == Version("12.04") or \
Version(distro_version) == Version("12.10"):
return Ubuntu12Distro()
return Ubuntu12OSUtil()
elif Version(distro_version) == Version("14.04") or \
Version(distro_version) == Version("14.10"):
return Ubuntu14Distro()
return Ubuntu14OSUtil()
elif distro_full_name == "Snappy Ubuntu Core":
return UbuntuSnappyDistro()
return UbuntuSnappyOSUtil()
else:
return UbuntuDistro()
return UbuntuOSUtil()
if distro_name == "coreos":
return CoreOSDistro()
return CoreOSUtil()
if distro_name == "suse":
if distro_full_name=='SUSE Linux Enterprise Server' and \
Version(distro_version) < Version('12') or \
distro_full_name == 'openSUSE' and \
Version(distro_version) < Version('13.2'):
return SUSE11Distro()
return SUSE11OSUtil()
else:
return SUSEDistro()
return SUSEOSUtil()
elif distro_name == "debian":
return DebianDistro()
return DebianOSUtil()
elif distro_name == "redhat" or distro_name == "centos" or \
distro_name == "oracle":
if Version(distro_version) < Version("7"):
return Redhat6xDistro()
return Redhat6xOSUtil()
else:
return RedhatDistro()
return RedhatOSUtil()
elif distro_name == "freebsd":
return FreeBSDDistro()
return FreeBSDOSUtil()
else:
logger.warn("Unable to load distro implemetation for {0}.", distro_name)
logger.warn("Use default distro implemetation instead.")
return DefaultDistro()
return DefaultOSUtil()
@@ -16,11 +16,11 @@
#
# Requires Python 2.4+ and Openssl 1.0+
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.textutil as textutil
import azurelinuxagent.logger as logger
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
from azurelinuxagent.exception import OSUtilError
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.textutil as textutil
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.exception import OSUtilError
from azurelinuxagent.common.osutil.default import DefaultOSUtil
class FreeBSDOSUtil(DefaultOSUtil):
@@ -26,15 +26,15 @@ import struct
import fcntl
import time
import base64
import azurelinuxagent.conf as conf
import azurelinuxagent.logger as logger
from azurelinuxagent.future import ustr, bytebuffer
from azurelinuxagent.exception import OSUtilError, CryptError
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.textutil as textutil
from azurelinuxagent.utils.cryptutil import CryptUtil
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.future import ustr, bytebuffer
from azurelinuxagent.common.exception import OSUtilError, CryptError
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.textutil as textutil
from azurelinuxagent.common.utils.cryptutil import CryptUtil
from azurelinuxagent.common.osutil.default import DefaultOSUtil
class Redhat6xOSUtil(DefaultOSUtil):
def __init__(self):
@@ -25,12 +25,12 @@ import array
import struct
import fcntl
import time
import azurelinuxagent.logger as logger
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.textutil as textutil
from azurelinuxagent.metadata import DISTRO_NAME, DISTRO_VERSION, DISTRO_FULL_NAME
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.textutil as textutil
from azurelinuxagent.common.version import DISTRO_NAME, DISTRO_VERSION, DISTRO_FULL_NAME
from azurelinuxagent.common.osutil.default import DefaultOSUtil
class SUSE11OSUtil(DefaultOSUtil):
def __init__(self):
@@ -25,11 +25,11 @@ import array
import struct
import fcntl
import time
import azurelinuxagent.logger as logger
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.textutil as textutil
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.textutil as textutil
from azurelinuxagent.common.osutil.default import DefaultOSUtil
class Ubuntu14OSUtil(DefaultOSUtil):
def __init__(self):
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,8 +15,7 @@
# Requires Python 2.4+ and Openssl 1.0+
#
def get_osutil():
from azurelinuxagent.distro.debian.osutil import DebianOSUtil
return DebianOSUtil()
from azurelinuxagent.common.protocol.util import get_protocol_util, \
OVF_FILE_NAME, \
TAG_FILE_NAME
@@ -20,15 +20,15 @@ import json
import shutil
import os
import time
from azurelinuxagent.exception import ProtocolError, HttpError
from azurelinuxagent.future import httpclient, ustr
import azurelinuxagent.conf as conf
import azurelinuxagent.logger as logger
import azurelinuxagent.utils.restutil as restutil
import azurelinuxagent.utils.textutil as textutil
import azurelinuxagent.utils.fileutil as fileutil
from azurelinuxagent.utils.cryptutil import CryptUtil
from azurelinuxagent.protocol.restapi import *
from azurelinuxagent.common.exception import ProtocolError, HttpError
from azurelinuxagent.common.future import httpclient, ustr
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.restutil as restutil
import azurelinuxagent.common.utils.textutil as textutil
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.common.utils.cryptutil import CryptUtil
from azurelinuxagent.common.protocol.restapi import *
METADATA_ENDPOINT='169.254.169.254'
APIVERSION='2015-05-01-preview'
@@ -58,6 +58,8 @@ class MetadataProtocol(Protocol):
self.apiversion, "&$expand=*")
self.ext_uri = BASE_URI.format(self.endpoint, "extensionHandlers",
self.apiversion, "&$expand=*")
self.vmagent_uri = BASE_URI.format(self.endpoint, "vmAgentVersions",
self.apiversion, "&$expand=*")
self.provision_status_uri = BASE_URI.format(self.endpoint,
"provisioningStatus",
self.apiversion, "")
@@ -140,6 +142,29 @@ class MetadataProtocol(Protocol):
#TODO download and save certs
return CertList()
def get_vmagent_manifests(self):
manifests = VMAgentManifestList()
data = self._get_data(self.vmagent_uri)
set_properties("vmAgentManifests", manifests.vmAgentManifests, data)
return manifests
def get_vmagent_pkgs(self, vmagent_manifest):
#Agent package is the same with extension handler
vmagent_pkgs = ExtHandlerPackageList()
data = None
for manifest_uri in vmagent_manifest.versionsManifestUris:
try:
data = self._get_data(manifest_uri.uri)
break
except ProtocolError as e:
logger.warn("Failed to get vmagent versions: {0}", e)
logger.info("Retry getting vmagent versions")
if data is None:
raise ProtocolError(("Failed to get versions for vm agent: {0}"
"").format(vmagent_manifest.family))
set_properties("vmAgentVersions", vmagent_pkgs, data)
return vmagent_pkgs
def get_ext_handlers(self):
headers = {
"x-ms-vmagent-public-x509-cert": self._get_trans_cert()
@@ -23,11 +23,11 @@ import os
import re
import shutil
import xml.dom.minidom as minidom
import azurelinuxagent.logger as logger
from azurelinuxagent.exception import ProtocolError
from azurelinuxagent.future import ustr
import azurelinuxagent.utils.fileutil as fileutil
from azurelinuxagent.utils.textutil import parse_doc, findall, find, findtext
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.exception import ProtocolError
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.common.utils.textutil import parse_doc, findall, find, findtext
OVF_VERSION = "1.0"
OVF_NAME_SPACE = "http://schemas.dmtf.org/ovf/environment/1"
@@ -21,10 +21,10 @@ import copy
import re
import json
import xml.dom.minidom
import azurelinuxagent.logger as logger
from azurelinuxagent.exception import ProtocolError, HttpError
from azurelinuxagent.future import ustr
import azurelinuxagent.utils.restutil as restutil
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.exception import ProtocolError, HttpError
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.utils.restutil as restutil
def validata_param(name, val, expected_type):
if val is None:
@@ -102,6 +102,20 @@ class CertList(DataContract):
def __init__(self):
self.certificates = DataContractList(Cert)
#TODO: confirm vmagent manifest schema
class VMAgentManifestUri(DataContract):
def __init__(self, uri=None):
self.uri = uri
class VMAgentManifest(DataContract):
def __init__(self, family=None):
self.family = family
self.versionsManifestUris = DataContractList(VMAgentManifestUri)
class VMAgentManifestList(DataContract):
def __init__(self):
self.vmAgentManifests = DataContractList(VMAgentManifest)
class Extension(DataContract):
def __init__(self, name=None, sequenceNumber=None, publicSettings=None,
protectedSettings=None, certificateThumbprint=None):
@@ -224,6 +238,12 @@ class Protocol(DataContract):
def get_certs(self):
raise NotImplementedError()
def get_vmagent_manifests(self):
raise NotImplementedError()
def get_vmagent_pkgs(self):
raise NotImplementedError()
def get_ext_handlers(self):
raise NotImplementedError()
@@ -21,16 +21,19 @@ import re
import shutil
import time
import threading
import azurelinuxagent.conf as conf
import azurelinuxagent.logger as logger
from azurelinuxagent.exception import ProtocolError, OSUtilError, \
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.exception import ProtocolError, OSUtilError, \
ProtocolNotFoundError, DhcpError
from azurelinuxagent.future import ustr
import azurelinuxagent.utils.fileutil as fileutil
from azurelinuxagent.protocol.ovfenv import OvfEnv
from azurelinuxagent.protocol.wire import WireProtocol
from azurelinuxagent.protocol.metadata import MetadataProtocol, METADATA_ENDPOINT
import azurelinuxagent.utils.shellutil as shellutil
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.dhcp import get_dhcp_handler
from azurelinuxagent.common.protocol.ovfenv import OvfEnv
from azurelinuxagent.common.protocol.wire import WireProtocol
from azurelinuxagent.common.protocol.metadata import MetadataProtocol, \
METADATA_ENDPOINT
import azurelinuxagent.common.utils.shellutil as shellutil
OVF_FILE_NAME = "ovf-env.xml"
@@ -46,15 +49,19 @@ PROBE_INTERVAL = 10
ENDPOINT_FILE_NAME = "WireServerEndpoint"
def get_protocol_util():
return ProtocolUtil()
class ProtocolUtil(object):
"""
ProtocolUtil handles initialization for protocol instance. 2 protocol types
are invoked, wire protocol and metadata protocols.
"""
def __init__(self, distro):
self.distro = distro
self.protocol = None
def __init__(self):
self.lock = threading.Lock()
self.protocol = None
self.osutil = get_osutil()
self.dhcp_handler = get_dhcp_handler()
def copy_ovf_env(self):
"""
@@ -65,7 +72,7 @@ class ProtocolUtil(object):
ovf_file_path_on_dvd = os.path.join(dvd_mount_point, OVF_FILE_NAME)
tag_file_path_on_dvd = os.path.join(dvd_mount_point, TAG_FILE_NAME)
try:
self.distro.osutil.mount_dvd()
self.osutil.mount_dvd()
ovfxml = fileutil.read_file(ovf_file_path_on_dvd, remove_bom=True)
ovfenv = OvfEnv(ovfxml)
ovfxml = re.sub("<UserPassword>.*?<", "<UserPassword>*<", ovfxml)
@@ -81,8 +88,8 @@ class ProtocolUtil(object):
raise ProtocolError(ustr(e))
try:
self.distro.osutil.umount_dvd()
self.distro.osutil.eject_dvd()
self.osutil.umount_dvd()
self.osutil.eject_dvd()
except OSUtilError as e:
logger.warn(ustr(e))
@@ -114,23 +121,24 @@ class ProtocolUtil(object):
raise OSUtilError(ustr(e))
def _detect_wire_protocol(self):
endpoint = self.distro.dhcp_handler.endpoint
endpoint = self.dhcp_handler.endpoint
if endpoint is None:
logger.info("WireServer endpoint is not found. Rerun dhcp handler")
try:
self.distro.dhcp_handler.run()
self.dhcp_handler.run()
except DhcpError as e:
raise ProtocolError(ustr(e))
endpoint = self.distro.dhcp_handler.endpoint
endpoint = self.dhcp_handler.endpoint
try:
protocol = WireProtocol(endpoint)
protocol.detect()
self._set_wireserver_endpoint(endpoint)
self.save_protocol("WireProtocol")
return protocol
except ProtocolError as e:
logger.info("WireServer is not responding. Reset endpoint")
self.distro.dhcp_handler.endpoint = None
self.dhcp_handler.endpoint = None
raise e
def _detect_metadata_protocol(self):
@@ -138,7 +146,9 @@ class ProtocolUtil(object):
protocol.detect()
#Only allow root access METADATA_ENDPOINT
self.distro.osutil.set_admin_access_to_ip(METADATA_ENDPOINT)
self.osutil.set_admin_access_to_ip(METADATA_ENDPOINT)
self.save_protocol("MetadataProtocol")
return protocol
@@ -146,9 +156,8 @@ class ProtocolUtil(object):
"""
Probe protocol endpoints in turn.
"""
protocol_file_path = os.path.join(conf.get_lib_dir(), PROTOCOL_FILE_NAME)
if os.path.isfile(protocol_file_path):
os.remove(protocol_file_path)
self.clear_protocol()
for retry in range(0, MAX_RETRY):
for protocol in protocols:
try:
@@ -174,7 +183,7 @@ class ProtocolUtil(object):
protocol_file_path = os.path.join(conf.get_lib_dir(),
PROTOCOL_FILE_NAME)
if not os.path.isfile(protocol_file_path):
raise ProtocolError("No protocl found")
raise ProtocolNotFoundError("No protocol found")
protocol_name = fileutil.read_file(protocol_file_path)
if protocol_name == "WireProtocol":
@@ -186,23 +195,61 @@ class ProtocolUtil(object):
raise ProtocolNotFoundError(("Unknown protocol: {0}"
"").format(protocol_name))
def detect_protocol(self):
def save_protocol(self, protocol_name):
"""
Save protocol endpoint
"""
protocol_file_path = os.path.join(conf.get_lib_dir(), PROTOCOL_FILE_NAME)
try:
fileutil.write_file(protocol_file_path, protocol_name)
except IOError as e:
logger.error("Failed to save protocol endpoint: {0}", e)
def clear_protocol(self):
"""
Cleanup previous saved endpoint.
"""
logger.info("Clean protocol")
self.protocol = None
protocol_file_path = os.path.join(conf.get_lib_dir(), PROTOCOL_FILE_NAME)
if not os.path.isfile(protocol_file_path):
return
try:
os.remove(protocol_file_path)
except IOError as e:
logger.error("Failed to clear protocol endpoint: {0}", e)
def get_protocol(self):
"""
Detect protocol by endpoints
:returns: protocol instance
"""
logger.info("Detect protocol endpoints")
protocols = ["WireProtocol", "MetadataProtocol"]
self.lock.acquire()
try:
if self.protocol is None:
self.protocol = self._detect_protocol(protocols)
if self.protocol is not None:
return self.protocol
try:
self.protocol = self._get_protocol()
return self.protocol
except ProtocolNotFoundError:
pass
logger.info("Detect protocol endpoints")
protocols = ["WireProtocol", "MetadataProtocol"]
self.protocol = self._detect_protocol(protocols)
return self.protocol
finally:
self.lock.release()
def detect_protocol_by_file(self):
def get_protocol_by_file(self):
"""
Detect protocol by tag file.
@@ -211,33 +258,27 @@ class ProtocolUtil(object):
:returns: protocol instance
"""
logger.info("Detect protocol by file")
self.lock.acquire()
try:
if self.protocol is not None:
return self.protocol
try:
self.protocol = self._get_protocol()
return self.protocol
except ProtocolNotFoundError:
pass
logger.info("Detect protocol by file")
tag_file_path = os.path.join(conf.get_lib_dir(), TAG_FILE_NAME)
if self.protocol is None:
protocols = []
if os.path.isfile(tag_file_path):
protocols.append("MetadataProtocol")
else:
protocols.append("WireProtocol")
self.protocol = self._detect_protocol(protocols)
finally:
self.lock.release()
return self.protocol
def get_protocol(self):
"""
Get protocol instance based on previous detecting result.
:returns protocol instance
"""
self.lock.acquire()
try:
if self.protocol is None:
self.protocol = self._get_protocol()
protocols = []
if os.path.isfile(tag_file_path):
protocols.append("MetadataProtocol")
else:
protocols.append("WireProtocol")
self.protocol = self._detect_protocol(protocols)
return self.protocol
finally:
self.lock.release()
return self.protocol
@@ -22,19 +22,19 @@ import re
import time
import traceback
import xml.sax.saxutils as saxutils
import azurelinuxagent.conf as conf
import azurelinuxagent.logger as logger
from azurelinuxagent.exception import ProtocolError, HttpError, \
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.exception import ProtocolError, HttpError, \
ProtocolNotFoundError
from azurelinuxagent.future import ustr, httpclient, bytebuffer
import azurelinuxagent.utils.restutil as restutil
from azurelinuxagent.utils.textutil import parse_doc, findall, find, findtext, \
from azurelinuxagent.common.future import ustr, httpclient, bytebuffer
import azurelinuxagent.common.utils.restutil as restutil
from azurelinuxagent.common.utils.textutil import parse_doc, findall, find, findtext, \
getattrib, gettext, remove_bom, \
get_bytes_from_pem
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
from azurelinuxagent.utils.cryptutil import CryptUtil
from azurelinuxagent.protocol.restapi import *
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
from azurelinuxagent.common.utils.cryptutil import CryptUtil
from azurelinuxagent.common.protocol.restapi import *
VERSION_INFO_URI = "http://{0}/?comp=versions"
GOAL_STATE_URI = "http://{0}/machine/?comp=goalstate"
@@ -102,6 +102,18 @@ class WireProtocol(Protocol):
certificates = self.client.get_certs()
return certificates.cert_list
def get_vmagent_manifests(self):
#Update goal state to get latest extensions config
self.client.update_goal_state()
goal_state = self.client.get_goal_state()
ext_conf = self.client.get_ext_conf()
return ext_conf.vmagent_manifests, goal_state.incarnation
def get_vmagent_pkgs(self, vmagent_manifest):
goal_state = self.client.get_goal_state()
man = self.client.get_gafamily_manifest(vmagent_manifest, goal_state)
return man.pkg_list
def get_ext_handlers(self):
logger.verb("Get extension handler config")
#Update goal state to get latest extensions config
@@ -711,6 +723,14 @@ class WireClient(object):
self.save_cache(local_file, xml_text)
return ExtensionManifest(xml_text)
def get_gafamily_manifest(self, vmagent_manifest, goal_state):
local_file = MANIFEST_FILE_NAME.format(vmagent_manifest.family,
goal_state.incarnation)
local_file = os.path.join(conf.get_lib_dir(), local_file)
xml_text = self.fetch_manifest(vmagent_manifest.versionsManifestUris)
fileutil.write_file(local_file, xml_text)
return ExtensionManifest(xml_text)
def check_wire_protocol_version(self):
uri = VERSION_INFO_URI.format(self.endpoint)
version_info_xml = self.fetch_config(uri, None)
@@ -1052,6 +1072,7 @@ class ExtensionsConfig(object):
def __init__(self, xml_text):
logger.verb("Load ExtensionsConfig.xml")
self.ext_handlers = ExtHandlerList()
self.vmagent_manifests = VMAgentManifestList()
self.status_upload_blob = None
if xml_text is not None:
self.parse(xml_text)
@@ -1061,6 +1082,21 @@ class ExtensionsConfig(object):
Write configuration to file ExtensionsConfig.xml.
"""
xml_doc = parse_doc(xml_text)
ga_families_list = find(xml_doc, "GAFamilies")
ga_families = findall(ga_families_list, "GAFamily")
for ga_family in ga_families:
family = findtext(ga_family, "Name")
uris_list = find(ga_family, "Uris")
uris = findall(uris_list, "Uri")
manifest = VMAgentManifest()
manifest.family = family
for uri in uris:
manifestUri = VMAgentManifestUri(uri=gettext(uri))
manifest.versionsManifestUris.append(manifestUri)
self.vmagent_manifests.vmAgentManifests.append(manifest)
plugins_list = find(xml_doc, "Plugins")
plugins = findall(plugins_list, "Plugin")
plugin_settings_list = find(xml_doc, "PluginSettings")
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,9 +19,9 @@
import base64
import struct
from azurelinuxagent.future import ustr, bytebuffer
from azurelinuxagent.exception import CryptError
import azurelinuxagent.utils.shellutil as shellutil
from azurelinuxagent.common.future import ustr, bytebuffer
from azurelinuxagent.common.exception import CryptError
import azurelinuxagent.common.utils.shellutil as shellutil
class CryptUtil(object):
def __init__(self, openssl_cmd):
@@ -26,9 +26,9 @@ import re
import shutil
import pwd
import tempfile
import azurelinuxagent.logger as logger
from azurelinuxagent.future import ustr
import azurelinuxagent.utils.textutil as textutil
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.utils.textutil as textutil
def read_file(filepath, asbin=False, remove_bom=False, encoding='utf-8'):
"""
@@ -21,10 +21,10 @@ import time
import platform
import os
import subprocess
import azurelinuxagent.conf as conf
import azurelinuxagent.logger as logger
from azurelinuxagent.exception import HttpError
from azurelinuxagent.future import httpclient, urlparse
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.exception import HttpError
from azurelinuxagent.common.future import httpclient, urlparse
"""
REST api util functions
@@ -20,8 +20,8 @@
import platform
import os
import subprocess
from azurelinuxagent.future import ustr
import azurelinuxagent.logger as logger
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.logger as logger
if not hasattr(subprocess,'check_output'):
def check_output(*popenargs, **kwargs):
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,8 +19,8 @@ import os
import re
import platform
import sys
import azurelinuxagent.utils.fileutil as fileutil
from azurelinuxagent.future import ustr
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.common.future import ustr
def get_distro():
if 'FreeBSD' in platform.system():
+18
View File
@@ -0,0 +1,18 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.daemon.main import get_daemon_handler
@@ -21,8 +21,13 @@ import os
import socket
import threading
import time
import azurelinuxagent.logger as logger
import azurelinuxagent.conf as conf
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.dhcp import get_dhcp_handler
def get_env_handler():
return EnvHandler()
class EnvHandler(object):
"""
@@ -32,8 +37,9 @@ class EnvHandler(object):
Monitor scsi disk.
If new scsi disk found, set timeout
"""
def __init__(self, distro):
self.distro = distro
def __init__(self):
self.osutil = get_osutil()
self.dhcp_handler = get_dhcp_handler()
self.stopped = True
self.hostname = None
self.dhcpid = None
@@ -46,9 +52,9 @@ class EnvHandler(object):
self.stopped = False
logger.info("Start env monitor service.")
self.distro.dhcp_handler.conf_routes()
self.dhcp_handler.conf_routes()
self.hostname = socket.gethostname()
self.dhcpid = self.distro.osutil.get_dhcp_pid()
self.dhcpid = self.osutil.get_dhcp_pid()
self.server_thread = threading.Thread(target = self.monitor)
self.server_thread.setDaemon(True)
self.server_thread.start()
@@ -59,10 +65,10 @@ class EnvHandler(object):
If dhcp clinet process re-start has occurred, reset routes.
"""
while not self.stopped:
self.distro.osutil.remove_rules_files()
self.osutil.remove_rules_files()
timeout = conf.get_root_device_scsi_timeout()
if timeout is not None:
self.distro.osutil.set_scsi_disks_timeout(timeout)
self.osutil.set_scsi_disks_timeout(timeout)
if conf.get_monitor_hostname():
self.handle_hostname_update()
self.handle_dhclient_restart()
@@ -73,25 +79,25 @@ class EnvHandler(object):
if curr_hostname != self.hostname:
logger.info("EnvMonitor: Detected host name change: {0} -> {1}",
self.hostname, curr_hostname)
self.distro.osutil.set_hostname(curr_hostname)
self.distro.osutil.publish_hostname(curr_hostname)
self.osutil.set_hostname(curr_hostname)
self.osutil.publish_hostname(curr_hostname)
self.hostname = curr_hostname
def handle_dhclient_restart(self):
if self.dhcpid is None:
logger.warn("Dhcp client is not running. ")
self.dhcpid = self.distro.osutil.get_dhcp_pid()
self.dhcpid = self.osutil.get_dhcp_pid()
return
#The dhcp process hasn't changed since last check
if self.distro.osutil.check_pid_alive(self.dhcpid.strip()):
if self.osutil.check_pid_alive(self.dhcpid.strip()):
return
newpid = self.distro.osutil.get_dhcp_pid()
newpid = self.osutil.get_dhcp_pid()
if newpid is not None and newpid != self.dhcpid:
logger.info("EnvMonitor: Detected dhcp client restart. "
"Restoring routing table.")
self.distro.dhcp_handler.conf_routes()
self.dhcp_handler.conf_routes()
self.dhcpid = newpid
def stop(self):
@@ -21,24 +21,43 @@ import os
import time
import sys
import traceback
import azurelinuxagent.conf as conf
import azurelinuxagent.logger as logger
from azurelinuxagent.future import ustr
from azurelinuxagent.event import add_event, WALAEventOperation
from azurelinuxagent.exception import ProtocolError
from azurelinuxagent.metadata import AGENT_LONG_NAME, AGENT_VERSION, \
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.future import ustr
from azurelinuxagent.common.event import add_event, WALAEventOperation
from azurelinuxagent.common.exception import ProtocolError
from azurelinuxagent.common.version import AGENT_LONG_NAME, AGENT_VERSION, \
DISTRO_NAME, DISTRO_VERSION, \
DISTRO_FULL_NAME, PY_VERSION_MAJOR, \
PY_VERSION_MINOR, PY_VERSION_MICRO
import azurelinuxagent.event as event
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.common.event as event
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.protocol import get_protocol_util
from azurelinuxagent.daemon.scvmm import get_scvmm_handler
from azurelinuxagent.daemon.resourcedisk import get_resourcedisk_handler
from azurelinuxagent.daemon.monitor import get_monitor_handler
from azurelinuxagent.daemon.env import get_env_handler
from azurelinuxagent.pa.provision import get_provision_handler
from azurelinuxagent.ga.update import get_update_handler
def get_daemon_handler():
return DaemonHandler()
class DaemonHandler(object):
def __init__(self, distro):
self.distro = distro
"""
Main thread of daemon. It will invoke other threads to do actual work
"""
def __init__(self):
self.running = True
self.osutil = get_osutil()
self.protocol_util = get_protocol_util()
self.scvmm_handler = get_scvmm_handler()
self.resourcedisk_handler = get_resourcedisk_handler()
self.monitor_handler = get_monitor_handler()
self.env_handler = get_env_handler()
self.provision_handler = get_provision_handler()
self.update_handler = get_update_handler()
def run(self):
logger.info("{0} Version:{1}", AGENT_LONG_NAME, AGENT_VERSION)
@@ -58,6 +77,7 @@ class DaemonHandler(object):
logger.info("Sleep 15 seconds and restart daemon")
time.sleep(15)
def check_pid(self):
"""Check whether daemon is already running"""
pid = None
@@ -65,7 +85,7 @@ class DaemonHandler(object):
if os.path.isfile(pid_file):
pid = fileutil.read_file(pid_file)
if self.distro.osutil.check_pid_alive(pid):
if self.osutil.check_pid_alive(pid):
logger.info("Daemon is already running: {0}", pid)
sys.exit(0)
@@ -79,25 +99,19 @@ class DaemonHandler(object):
os.chdir(conf.get_lib_dir())
if conf.get_detect_scvmm_env():
if self.distro.scvmm_handler.run():
return
self.distro.provision_handler.run()
self.scvmm_handler.run()
if conf.get_resourcedisk_format():
self.distro.resource_disk_handler.run()
try:
protocol = self.distro.protocol_util.detect_protocol()
except ProtocolError as e:
logger.error("Failed to detect protocol, exit", e)
return
self.resourcedisk_handler.run()
self.distro.event_handler.run()
self.distro.env_handler.run()
self.protocol_util.clear_protocol()
self.provision_handler.run()
self.monitor_handler.run()
self.env_handler.run()
while self.running:
#Handle extensions
self.distro.ext_handlers_handler.run()
self.update_handler.run()
time.sleep(25)
@@ -24,19 +24,23 @@ import time
import datetime
import threading
import platform
import azurelinuxagent.logger as logger
import azurelinuxagent.conf as conf
from azurelinuxagent.event import WALAEventOperation, add_event
from azurelinuxagent.exception import EventError, ProtocolError, OSUtilError
from azurelinuxagent.future import ustr
from azurelinuxagent.utils.textutil import parse_doc, findall, find, getattrib
from azurelinuxagent.protocol.restapi import TelemetryEventParam, \
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.event import WALAEventOperation, add_event
from azurelinuxagent.common.exception import EventError, ProtocolError, \
OSUtilError
from azurelinuxagent.common.future import ustr
from azurelinuxagent.common.utils.textutil import parse_doc, findall, find, \
getattrib
from azurelinuxagent.common.protocol.restapi import TelemetryEventParam, \
TelemetryEventList, \
TelemetryEvent, \
set_properties, get_properties
from azurelinuxagent.metadata import DISTRO_NAME, DISTRO_VERSION, \
from azurelinuxagent.common.version import DISTRO_NAME, DISTRO_VERSION, \
DISTRO_CODE_NAME, AGENT_LONG_VERSION
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.protocol import get_protocol_util
def parse_event(data_str):
try:
@@ -76,10 +80,13 @@ def parse_json_event(data_str):
set_properties("TelemetryEvent", event, data)
return event
def get_monitor_handler():
return MonitorHandler()
class MonitorHandler(object):
def __init__(self, distro):
self.distro = distro
def __init__(self):
self.osutil = get_osutil()
self.protocol_util = get_protocol_util()
self.sysinfo = []
def run(self):
@@ -99,15 +106,15 @@ class MonitorHandler(object):
self.sysinfo.append(TelemetryEventParam("GAVersion", AGENT_LONG_VERSION))
try:
ram = self.distro.osutil.get_total_mem()
processors = self.distro.osutil.get_processor_cores()
ram = self.osutil.get_total_mem()
processors = self.osutil.get_processor_cores()
self.sysinfo.append(TelemetryEventParam("RAM", ram))
self.sysinfo.append(TelemetryEventParam("Processors", processors))
except OSUtilError as e:
logger.warn("Failed to get system info: {0}", e)
try:
protocol = self.distro.protocol_util.get_protocol()
protocol = self.protocol_util.get_protocol()
vminfo = protocol.get_vminfo()
self.sysinfo.append(TelemetryEventParam("VMName",
vminfo.vmName))
@@ -161,7 +168,7 @@ class MonitorHandler(object):
return
try:
protocol = self.distro.protocol_util.get_protocol()
protocol = self.protocol_util.get_protocol()
protocol.report_event(event_list)
except ProtocolError as e:
logger.error("{0}", e)
@@ -0,0 +1,20 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.daemon.resourcedisk.factory import get_resourcedisk_handler
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,13 +18,14 @@
import os
import re
import threading
import azurelinuxagent.logger as logger
from azurelinuxagent.future import ustr
import azurelinuxagent.conf as conf
from azurelinuxagent.event import add_event, WALAEventOperation
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
from azurelinuxagent.exception import ResourceDiskError
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.event import add_event, WALAEventOperation
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
from azurelinuxagent.common.exception import ResourceDiskError
from azurelinuxagent.common.osutil import get_osutil
DATALOSS_WARNING_FILE_NAME="DATALOSS_WARNING_README.txt"
DATA_LOSS_WARNING="""\
@@ -40,8 +39,8 @@ For additional details to please refer to the MSDN documentation at : http://msd
"""
class ResourceDiskHandler(object):
def __init__(self, distro):
self.distro = distro
def __init__(self):
self.osutil = get_osutil()
def start_activate_resource_disk(self):
disk_thread = threading.Thread(target = self.run)
@@ -81,13 +80,13 @@ class ResourceDiskHandler(object):
logger.error("Failed to enable swap {0}", e)
def mount_resource_disk(self, mount_point, fs):
device = self.distro.osutil.device_for_ide_port(1)
device = self.osutil.device_for_ide_port(1)
if device is None:
raise ResourceDiskError("unable to detect disk topology")
device = "/dev/" + device
mountlist = shellutil.run_get_output("mount")[1]
existing = self.distro.osutil.get_mount_point(mountlist, device)
existing = self.osutil.get_mount_point(mountlist, device)
if(existing):
logger.info("Resource disk {0}1 is already mounted", device)
@@ -0,0 +1,33 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
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
from .default import ResourceDiskHandler
from .freebsd import FreeBSDResourceDiskHandler
def get_resourcedisk_handler(distro_name=DISTRO_NAME,
distro_version=DISTRO_VERSION,
distro_full_name=DISTRO_FULL_NAME):
if distro_name == "freebsd":
return FreeBSDResourceDiskHandler()
return ResourceDiskHandler()
@@ -16,12 +16,11 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
import azurelinuxagent.logger as logger
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
from azurelinuxagent.distro.default.resourceDisk import ResourceDiskHandler
from azurelinuxagent.exception import ResourceDiskError
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
from azurelinuxagent.common.exception import ResourceDiskError
from azurelinuxagent.daemon.resourcedisk.default import ResourceDiskHandler
class FreeBSDResourceDiskHandler(ResourceDiskHandler):
"""
@@ -35,8 +34,8 @@ class FreeBSDResourceDiskHandler(ResourceDiskHandler):
1. MBR: The resource disk partition is /dev/da1s1
2. GPT: The resource disk partition is /dev/da1p2, /dev/da1p1 is for reserved usage.
"""
def __init__(self, distro):
super(FreeBSDResourceDiskHandler, self).__init__(distro)
def __init__(self):
super(FreeBSDResourceDiskHandler, self).__init__()
@staticmethod
def parse_gpart_list(data):
@@ -95,7 +94,7 @@ class FreeBSDResourceDiskHandler(ResourceDiskHandler):
# 3. Mount partition
mount_list = shellutil.run_get_output("mount")[1]
existing = self.distro.osutil.get_mount_point(mount_list, partition)
existing = self.osutil.get_mount_point(mount_list, partition)
if existing:
logger.info("Resource disk {0} is already mounted", partition)
@@ -18,31 +18,44 @@
#
import os
import sys
import subprocess
import azurelinuxagent.logger as logger
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.osutil import get_osutil
VMM_CONF_FILE_NAME = "linuxosconfiguration.xml"
VMM_STARTUP_SCRIPT_NAME= "install"
def get_scvmm_handler():
return ScvmmHandler()
class ScvmmHandler(object):
def __init__(self, distro):
self.distro = distro
def __init__(self):
self.osutil = get_osutil()
def detect_scvmm_env(self):
logger.info("Detecting Microsoft System Center VMM Environment")
self.distro.osutil.mount_dvd(max_retry=1, chk_err=False)
mount_point = self.distro.osutil.get_dvd_mount_point()
self.osutil.mount_dvd(max_retry=1, chk_err=False)
mount_point = conf.get_dvd_mount_point()
found = os.path.isfile(os.path.join(mount_point, VMM_CONF_FILE_NAME))
if found:
self.start_scvmm_agent()
else:
self.distro.osutil.umount_dvd(chk_err=False)
self.osutil.umount_dvd(chk_err=False)
return found
def start_scvmm_agent(self):
logger.info("Starting Microsoft System Center VMM Initialization "
"Process")
mount_point = self.distro.osutil.get_dvd_mount_point()
mount_point = conf.get_dvd_mount_point()
startup_script = os.path.join(mount_point, VMM_STARTUP_SCRIPT_NAME)
subprocess.Popen(["/bin/bash", startup_script, "-p " + mount_point])
devnull = open(os.devnull, 'w')
subprocess.Popen(["/bin/bash", startup_script, "-p " + mount_point],
stdout=devnull, stderr=devnull)
def run(self):
if self.detect_scvmm_env():
self.start_scvmm_agent()
logger.info("Exiting")
sys.exit(0)
-29
View File
@@ -1,29 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.distro.default.distro import DefaultDistro
from azurelinuxagent.distro.coreos.osutil import CoreOSUtil
from azurelinuxagent.distro.coreos.deprovision import CoreOSDeprovisionHandler
class CoreOSDistro(DefaultDistro):
def __init__(self):
super(CoreOSDistro, self).__init__()
self.osutil = CoreOSUtil()
self.deprovision_handler = CoreOSDeprovisionHandler(self)
-27
View File
@@ -1,27 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.distro.default.distro import DefaultDistro
from azurelinuxagent.distro.debian.osutil import DebianOSUtil
class DebianDistro(DefaultDistro):
def __init__(self):
super(DebianDistro, self).__init__()
self.osutil = DebianOSUtil()
-51
View File
@@ -1,51 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.conf import ConfigurationProvider
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
from azurelinuxagent.distro.default.daemon import DaemonHandler
from azurelinuxagent.distro.default.init import InitHandler
from azurelinuxagent.distro.default.monitor import MonitorHandler
from azurelinuxagent.distro.default.dhcp import DhcpHandler
from azurelinuxagent.distro.default.protocolUtil import ProtocolUtil
from azurelinuxagent.distro.default.scvmm import ScvmmHandler
from azurelinuxagent.distro.default.env import EnvHandler
from azurelinuxagent.distro.default.provision import ProvisionHandler
from azurelinuxagent.distro.default.resourceDisk import ResourceDiskHandler
from azurelinuxagent.distro.default.extension import ExtHandlersHandler
from azurelinuxagent.distro.default.deprovision import DeprovisionHandler
class DefaultDistro(object):
"""
"""
def __init__(self):
self.osutil = DefaultOSUtil()
self.protocol_util = ProtocolUtil(self)
self.init_handler = InitHandler(self)
self.daemon_handler = DaemonHandler(self)
self.event_handler = MonitorHandler(self)
self.dhcp_handler = DhcpHandler(self)
self.scvmm_handler = ScvmmHandler(self)
self.env_handler = EnvHandler(self)
self.provision_handler = ProvisionHandler(self)
self.resource_disk_handler = ResourceDiskHandler(self)
self.ext_handlers_handler = ExtHandlersHandler(self)
self.deprovision_handler = DeprovisionHandler(self)
-53
View File
@@ -1,53 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
import os
import azurelinuxagent.conf as conf
import azurelinuxagent.logger as logger
import azurelinuxagent.event as event
class InitHandler(object):
def __init__(self, distro):
self.distro = distro
def run(self, verbose):
#Init stdout log
level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
logger.add_logger_appender(logger.AppenderType.STDOUT, level)
#Init config
conf_file_path = self.distro.osutil.get_agent_conf_file_path()
conf.load_conf_from_file(conf_file_path)
#Init log
verbose = verbose or conf.get_logs_verbose()
level = logger.LogLevel.VERBOSE if verbose else logger.LogLevel.INFO
logger.add_logger_appender(logger.AppenderType.FILE, level,
path="/var/log/waagent.log")
logger.add_logger_appender(logger.AppenderType.CONSOLE, level,
path="/dev/console")
#Init event reporter
event_dir = os.path.join(conf.get_lib_dir(), "events")
event.init_event_logger(event_dir)
event.enable_unhandled_err_dump("WALA")
-29
View File
@@ -1,29 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.distro.default.distro import DefaultDistro
from azurelinuxagent.distro.freebsd.resourceDisk import FreeBSDResourceDiskHandler
from azurelinuxagent.distro.freebsd.osutil import FreeBSDOSUtil
class FreeBSDDistro(DefaultDistro):
def __init__(self):
super(FreeBSDDistro, self).__init__()
self.osutil = FreeBSDOSUtil()
self.resource_disk_handler = FreeBSDResourceDiskHandler(self)
-19
View File
@@ -1,19 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
-31
View File
@@ -1,31 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.distro.default.distro import DefaultDistro
from azurelinuxagent.distro.redhat.osutil import RedhatOSUtil, Redhat6xOSUtil
class Redhat6xDistro(DefaultDistro):
def __init__(self):
super(Redhat6xDistro, self).__init__()
self.osutil = Redhat6xOSUtil()
class RedhatDistro(DefaultDistro):
def __init__(self):
super(RedhatDistro, self).__init__()
self.osutil = RedhatOSUtil()
-19
View File
@@ -1,19 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
-19
View File
@@ -1,19 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
-55
View File
@@ -1,55 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.distro.default.distro import DefaultDistro
from azurelinuxagent.distro.ubuntu.osutil import Ubuntu14OSUtil, \
Ubuntu12OSUtil, \
UbuntuOSUtil, \
UbuntuSnappyOSUtil
from azurelinuxagent.distro.ubuntu.provision import UbuntuProvisionHandler
from azurelinuxagent.distro.ubuntu.deprovision import UbuntuDeprovisionHandler
class UbuntuDistro(DefaultDistro):
def __init__(self):
super(UbuntuDistro, self).__init__()
self.osutil = UbuntuOSUtil()
self.provision_handler = UbuntuProvisionHandler(self)
self.deprovision_handler = UbuntuDeprovisionHandler(self)
class Ubuntu12Distro(DefaultDistro):
def __init__(self):
super(Ubuntu12Distro, self).__init__()
self.osutil = Ubuntu12OSUtil()
self.provision_handler = UbuntuProvisionHandler(self)
self.deprovision_handler = UbuntuDeprovisionHandler(self)
class Ubuntu14Distro(DefaultDistro):
def __init__(self):
super(Ubuntu14Distro, self).__init__()
self.osutil = Ubuntu14OSUtil()
self.provision_handler = UbuntuProvisionHandler(self)
self.deprovision_handler = UbuntuDeprovisionHandler(self)
class UbuntuSnappyDistro(DefaultDistro):
def __init__(self):
super(UbuntuSnappyDistro, self).__init__()
self.osutil = UbuntuSnappyOSUtil()
self.provision_handler = UbuntuProvisionHandler(self)
self.deprovision_handler = UbuntuDeprovisionHandler(self)
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,20 +22,24 @@ import time
import json
import subprocess
import shutil
import azurelinuxagent.conf as conf
import azurelinuxagent.logger as logger
from azurelinuxagent.event import add_event, WALAEventOperation
from azurelinuxagent.exception import ExtensionError, ProtocolError, HttpError
from azurelinuxagent.future import ustr
from azurelinuxagent.metadata import AGENT_VERSION
from azurelinuxagent.protocol.restapi import ExtHandlerStatus, ExtensionStatus, \
ExtensionSubStatus, Extension, \
VMStatus, ExtHandler, \
get_properties, set_properties
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.restutil as restutil
import azurelinuxagent.utils.shellutil as shellutil
from azurelinuxagent.utils.textutil import Version
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.logger as logger
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
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.restutil as restutil
import azurelinuxagent.common.utils.shellutil as shellutil
from azurelinuxagent.common.utils.textutil import Version
from azurelinuxagent.common.protocol import get_protocol_util
#HandlerEnvironment.json schema version
HANDLER_ENVIRONMENT_VERSION = 1.0
@@ -103,9 +107,12 @@ class ExtHandlerState(object):
Installed = "Installed"
Enabled = "Enabled"
def get_exthandlers_handler():
return ExtHandlersHandler()
class ExtHandlersHandler(object):
def __init__(self, distro):
self.distro = distro
def __init__(self):
self.protocol_util = get_protocol_util()
self.ext_handlers = None
self.last_etag = None
self.log_report = False
@@ -113,7 +120,7 @@ class ExtHandlersHandler(object):
def run(self):
ext_handlers, etag = None, None
try:
self.protocol = self.distro.protocol_util.get_protocol()
self.protocol = self.protocol_util.get_protocol()
ext_handlers, etag = self.protocol.get_ext_handlers()
except ProtocolError as e:
add_event(name="WALA", is_success=False, message=ustr(e))
+278
View File
@@ -0,0 +1,278 @@
# Windows Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
import os
import json
import time
import subprocess
import signal
import sys
import zipfile
from azurelinuxagent.common.exception import UpdateError, ProtocolError
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.event import add_event
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.restutil as restutil
from azurelinuxagent.common.version import AGENT_VERSION
from azurelinuxagent.common.utils.textutil import Version
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.protocol import get_protocol_util
def get_update_handler():
return UpdateHandler()
GA_DIR = 'GuestAgent' # Dir name for guest agent bin and data
GA_ERR = 'error' # File name for guest agent error record
MAX_FAILURE = 3 # Max failure allowed for guest agent before blacklisted
RETAIN_INTERVAL = 24 * 60 * 60 # Retain interval for black list
"""
Handles self update logic
"""
class UpdateHandler(object):
def __init__(self):
self.osutil = get_osutil()
self.protocol_util = get_protocol_util()
self.last_etag = None
self.agents = []
self.error_record = {}
def run(self):
"""
1. If self-update is enabled, check for new versions.
otherwise, use current agent
2. Invoke run-exthandlers task
"""
self.mk_ga_dir()
self.load_error_record()
updated = self.check_for_update()
if not updated:
return
latest_agent = None
if conf.get_autoupdate_enabled():
logger.info("Auto update enabled")
latest_agent = self.get_latest_agent()
try:
self.run_extensions(latest_agent)
except UpdateError as e:
add_event(u"WALA", is_success=False, message=ustr(e))
if latest_agent is not None:
latest_agent.err.mark_failure()
self.save_error_record()
def mk_ga_dir(self):
dir_path = os.path.join(conf.get_lib_dir(), GA_DIR)
fileutil.mkdir(dir_path, mode=0o700)
def get_latest_agent(self):
available_agent = [agent for agent in self.agents \
if not agent.err.is_blacklisted()]
return available_agent[0] if len(available_agent) >= 1 else None
def run_extensions(self, latest_agent):
agent_bin = sys.argv[0]
if latest_agent is not None:
logger.info(u"The latest guest agent version is : {0}",
latest_agent.version)
agent_bin = latest_agent.get_agent_bin()
if not latest_agent.is_downloaded():
try:
latest_agent.download()
except Exception as e:
raise UpdateError(u"Download failed", e)
devnull = open(os.devnull, 'w')
try:
child = subprocess.Popen([agent_bin, 'run-exthandlers'],
stdout=devnull, stderr=devnull)
except Exception as e:
raise UpdateError(u"Failed to launch task 'run-exthandlers'", e)
ret = child.wait()
if ret == None or ret != 0:
msg = u"Task 'run-exthandlers' returns none-zero code: {0}".format(1)
raise UpdateError(msg)
def check_for_update(self):
"""Get latest version not in black list"""
self.agents = []
try:
protocol = self.protocol_util.get_protocol()
manifest_list, etag = protocol.get_vmagent_manifests()
except ProtocolError as e:
add_event(u"WALA", is_success=False, message=ustr(e))
return False
if self.last_etag is not None and self.last_etag == etag:
logger.verb("No change to ext handler config:{0}, skip", etag)
return False
logger.info("Check for update")
family = conf.get_autoupdate_gafamily()
manifests = [manifest for manifest in manifest_list.vmAgentManifests \
if manifest.family == family]
if len(manifests) == 0:
message = u"No avaiable guest agent found for: {0}".format(family)
add_event(u"WALA", message=message)
try:
pkg_list = protocol.get_vmagent_pkgs(manifests[0])
except ProtocolError as e:
message= u"Failed to get GA package list: {0}".format(e)
add_event("WALA", is_success=False, message=message)
return
#Only considering versions that is larger than current
pkgs = [pkg for pkg in pkg_list.versions \
if Version(pkg.version) > Version(AGENT_VERSION)]
pkgs = sorted(pkgs, key=lambda pkg : Version(pkg.version), reverse=True)
for pkg in pkgs:
ga_err = self.error_record.get(pkg.version)
if ga_err is None:
ga_err = GuestAgentError(version=pkg.version)
agent = GuestAgent(pkg, ga_err)
self.agents.append(agent)
#Update error record list.
#Only keep the records for available agent versions
self.error_record = {}
for agent in self.agents:
self.error_record[agent.version] = agent.err
return True
def load_error_record(self):
self.error_record = {}
file_path = os.path.join(conf.get_lib_dir(), GA_DIR, GA_ERR)
if not os.path.isfile(file_path):
return
try:
error_data_list = json.loads(fileutil.read_file(file_path))
for error_data in error_data_list:
ga_err = GuestAgentError()
ga_err.from_dict(error_data)
ga_err.clear_old_failure()
self.error_record[ga_err.version] = ga_err
except (IOError, ValueError) as e:
message = u"Failed to load GA error record: {0}".format(e)
add_event(u"WALA", is_success=False, message=message)
def save_error_record(self):
error_data_list = []
for err in self.error_record.values():
error_data = err.to_dict()
error_data_list.append(error_data)
file_path = os.path.join(conf.get_lib_dir(), GA_DIR, GA_ERR)
try:
fileutil.write_file(file_path, json.dumps(error_data_list))
except (IOError, ValueError) as e:
message = u"Failed to save GA error record: {0}".format(e)
add_event(u"WALA", is_success=False, message=message)
class GuestAgent(object):
def __init__(self, pkg, err):
self.version = pkg.version
self.pkg = pkg
self.err = err
def get_agent_bin(self):
file_name = "WALinuxAgent-{0}.egg".format(self.version)
return os.path.join(self.get_agent_dir(), file_name)
def get_agent_dir(self):
dir_name = "WALinuxAgent-{0}".format(self.version)
return os.path.join(conf.get_lib_dir(), GA_DIR, dir_name)
def get_agent_pkg_file(self):
pkg_file_name = "WALinuxAgent-{0}.zip".format(self.version)
return os.path.join(conf.get_lib_dir(), GA_DIR, pkg_file_name)
def is_downloaded(self):
return os.path.isfile(self.get_agent_bin())
def download(self):
logger.info(u"Download guest agent: {0}", self.version)
add_event(u"WALA", message="Start downloading guest agent package")
package = None
for uri in self.pkg.uris:
try:
resp = restutil.http_get(uri.uri, chk_proxy=True)
if resp.status == restutil.httpclient.OK:
package = resp.read()
break
except restutil.HttpError as e:
logger.warn("Failed download guest agent from: {0}", uri.uri)
if package is None:
raise UpdateError("Failed to download guest agent package")
logger.info("Unpack guest agent package")
pkg_file = self.get_agent_pkg_file()
fileutil.write_file(pkg_file, bytearray(package), asbin=True)
zipfile.ZipFile(pkg_file).extractall(self.get_agent_dir())
add_event(name="WALA", message="Download guest agent package succeeded")
class GuestAgentError(object):
def __init__(self, version=None, last_failure=0, failure_count=0):
self.version = version
self.last_failure = last_failure
self.failure_count = failure_count
def mark_failure(self):
self.last_failure = time.time()
self.failure_count += 1
def clear_old_failure(self):
"""Clear failure recored"""
if self.last_failure < (time.time() - RETAIN_INTERVAL):
self.last_failure = 0
self.failure_count = 0
def is_blacklisted(self):
return self.failure_count >= MAX_FAILURE
def from_dict(self, data):
self.version = data.get(u"version")
self.last_failure = data.get(u"last_failure", 0)
self.failure_count = data.get(u"failure_count", 0)
def to_dict(self):
data = {
u"version": self.version,
u"last_failure": self.last_failure,
u"failure_count": self.failure_count,
}
return data
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -0,0 +1,20 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.pa.deprovision.factory import get_deprovision_handler
__all__ = ["get_deprovision_handler"]
@@ -17,12 +17,13 @@
# Requires Python 2.4+ and Openssl 1.0+
#
import azurelinuxagent.utils.fileutil as fileutil
from azurelinuxagent.distro.default.deprovision import DeprovisionHandler, DeprovisionAction
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.pa.deprovision.default import DeprovisionHandler, \
DeprovisionAction
class CoreOSDeprovisionHandler(DeprovisionHandler):
def __init__(self, distro):
self.distro = distro
def __init__(self):
super(CoreOSDeprovisionHandler, self).__init__()
def setup(self, deluser):
warnings, actions = super(CoreOSDeprovisionHandler, self).setup(deluser)
@@ -17,11 +17,13 @@
# Requires Python 2.4+ and Openssl 1.0+
#
import azurelinuxagent.conf as conf
from azurelinuxagent.exception import ProtocolError
from azurelinuxagent.future import read_input
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.exception import ProtocolError
from azurelinuxagent.common.future import read_input
import azurelinuxagent.common.utils.fileutil as fileutil
import azurelinuxagent.common.utils.shellutil as shellutil
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.protocol import get_protocol_util
class DeprovisionAction(object):
def __init__(self, func, args=[], kwargs={}):
@@ -33,19 +35,20 @@ class DeprovisionAction(object):
self.func(*self.args, **self.kwargs)
class DeprovisionHandler(object):
def __init__(self, distro):
self.distro = distro
def __init__(self):
self.osutil = get_osutil()
self.protocol_util = get_protocol_util()
def del_root_password(self, warnings, actions):
warnings.append("WARNING! root password will be disabled. "
"You will not be able to login as root.")
actions.append(DeprovisionAction(self.distro.osutil.del_root_password))
actions.append(DeprovisionAction(self.osutil.del_root_password))
def del_user(self, warnings, actions):
try:
ovfenv = self.distro.protocol_util.get_ovf_env()
ovfenv = self.protocol_util.get_ovf_env()
except ProtocolError:
warnings.append("WARNING! ovf-env.xml is not found.")
warnings.append("WARNING! Skip delete user.")
@@ -54,7 +57,7 @@ class DeprovisionHandler(object):
username = ovfenv.username
warnings.append(("WARNING! {0} account and entire home directory "
"will be deleted.").format(username))
actions.append(DeprovisionAction(self.distro.osutil.del_account,
actions.append(DeprovisionAction(self.osutil.del_account,
[username]))
@@ -65,7 +68,7 @@ class DeprovisionHandler(object):
def stop_agent_service(self, warnings, actions):
warnings.append("WARNING! The waagent service will be stopped.")
actions.append(DeprovisionAction(self.distro.osutil.stop_agent_service))
actions.append(DeprovisionAction(self.osutil.stop_agent_service))
def del_files(self, warnings, actions):
files_to_del = ['/root/.bash_history', '/var/log/waagent.log']
@@ -85,9 +88,9 @@ class DeprovisionHandler(object):
def reset_hostname(self, warnings, actions):
localhost = ["localhost.localdomain"]
actions.append(DeprovisionAction(self.distro.osutil.set_hostname,
actions.append(DeprovisionAction(self.osutil.set_hostname,
localhost))
actions.append(DeprovisionAction(self.distro.osutil.set_dhcp_hostname,
actions.append(DeprovisionAction(self.osutil.set_dhcp_hostname,
localhost))
def setup(self, deluser):
+36
View File
@@ -0,0 +1,36 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
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
from .default import DeprovisionHandler
from .coreos import CoreOSDeprovisionHandler
from .ubuntu import UbuntuDeprovisionHandler
def get_deprovision_handler(distro_name=DISTRO_NAME,
distro_version=DISTRO_VERSION,
distro_full_name=DISTRO_FULL_NAME):
if distro_name == "ubuntu":
return UbuntuDeprovisionHandler()
if distro_name == "coreos":
return CoreOSDeprovisionHandler()
return DeprovisionHandler()
@@ -18,9 +18,10 @@
#
import os
import azurelinuxagent.logger as logger
import azurelinuxagent.utils.fileutil as fileutil
from azurelinuxagent.distro.default.deprovision import DeprovisionHandler, DeprovisionAction
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.pa.deprovision.default import DeprovisionHandler, \
DeprovisionAction
def del_resolv():
if os.path.realpath('/etc/resolv.conf') != '/run/resolvconf/resolv.conf':
@@ -33,8 +34,8 @@ def del_resolv():
class UbuntuDeprovisionHandler(DeprovisionHandler):
def __init__(self, distro):
super(UbuntuDeprovisionHandler, self).__init__(distro)
def __init__(self):
super(UbuntuDeprovisionHandler, self).__init__()
def setup(self, deluser):
warnings, actions = super(UbuntuDeprovisionHandler, self).setup(deluser)
+18
View File
@@ -0,0 +1,18 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.pa.provision.factory import get_provision_handler
@@ -20,21 +20,25 @@ Provision handler
"""
import os
import azurelinuxagent.logger as logger
from azurelinuxagent.future import ustr
import azurelinuxagent.conf as conf
from azurelinuxagent.event import add_event, WALAEventOperation
from azurelinuxagent.exception import ProvisionError, ProtocolError, OSUtilError
from azurelinuxagent.protocol.restapi import ProvisionStatus
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.event import add_event, WALAEventOperation
from azurelinuxagent.common.exception import ProvisionError, ProtocolError, \
OSUtilError
from azurelinuxagent.common.protocol.restapi import ProvisionStatus
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.protocol import get_protocol_util
CUSTOM_DATA_FILE="CustomData"
class ProvisionHandler(object):
def __init__(self, distro):
self.distro = distro
def __init__(self):
self.osutil = get_osutil()
self.protocol_util = get_protocol_util()
def run(self):
#If provision is not enabled, return
@@ -49,12 +53,12 @@ class ProvisionHandler(object):
logger.info("Run provision handler.")
logger.info("Copy ovf-env.xml.")
try:
ovfenv = self.distro.protocol_util.copy_ovf_env()
ovfenv = self.protocol_util.copy_ovf_env()
except ProtocolError as e:
self.report_event("Failed to copy ovf-env.xml: {0}".format(e))
return
self.distro.protocol_util.detect_protocol_by_file()
self.protocol_util.get_protocol_by_file()
self.report_not_ready("Provisioning", "Starting")
@@ -95,50 +99,50 @@ class ProvisionHandler(object):
logger.info("Handle ovf-env.xml.")
try:
logger.info("Set host name.")
self.distro.osutil.set_hostname(ovfenv.hostname)
self.osutil.set_hostname(ovfenv.hostname)
logger.info("Publish host name.")
self.distro.osutil.publish_hostname(ovfenv.hostname)
self.osutil.publish_hostname(ovfenv.hostname)
self.config_user_account(ovfenv)
self.save_customdata(ovfenv)
if conf.get_delete_root_password():
self.distro.osutil.del_root_password()
self.osutil.del_root_password()
except OSUtilError as e:
raise ProvisionError("Failed to handle ovf-env.xml: {0}".format(e))
def config_user_account(self, ovfenv):
logger.info("Create user account if not exists")
self.distro.osutil.useradd(ovfenv.username)
self.osutil.useradd(ovfenv.username)
if ovfenv.user_password is not None:
logger.info("Set user password.")
crypt_id = conf.get_password_cryptid()
salt_len = conf.get_password_crypt_salt_len()
self.distro.osutil.chpasswd(ovfenv.username, ovfenv.user_password,
self.osutil.chpasswd(ovfenv.username, ovfenv.user_password,
crypt_id=crypt_id, salt_len=salt_len)
logger.info("Configure sudoer")
self.distro.osutil.conf_sudoer(ovfenv.username, nopasswd=ovfenv.user_password is None)
self.osutil.conf_sudoer(ovfenv.username, nopasswd=ovfenv.user_password is None)
logger.info("Configure sshd")
self.distro.osutil.conf_sshd(ovfenv.disable_ssh_password_auth)
self.osutil.conf_sshd(ovfenv.disable_ssh_password_auth)
#Disable selinux temporary
sel = self.distro.osutil.is_selinux_enforcing()
sel = self.osutil.is_selinux_enforcing()
if sel:
self.distro.osutil.set_selinux_enforce(0)
self.osutil.set_selinux_enforce(0)
self.deploy_ssh_pubkeys(ovfenv)
self.deploy_ssh_keypairs(ovfenv)
if sel:
self.distro.osutil.set_selinux_enforce(1)
self.osutil.set_selinux_enforce(1)
self.distro.osutil.restart_ssh_service()
self.osutil.restart_ssh_service()
def save_customdata(self, ovfenv):
customdata = ovfenv.customdata
@@ -148,7 +152,8 @@ class ProvisionHandler(object):
logger.info("Save custom data")
lib_dir = conf.get_lib_dir()
if conf.get_decode_customdata():
customdata= self.distro.osutil.decode_customdata(customdata)
customdata= self.osutil.decode_customdata(customdata)
customdata_file = os.path.join(lib_dir, CUSTOM_DATA_FILE)
fileutil.write_file(customdata_file, customdata)
@@ -160,12 +165,12 @@ class ProvisionHandler(object):
def deploy_ssh_pubkeys(self, ovfenv):
for pubkey in ovfenv.ssh_pubkeys:
logger.info("Deploy ssh public key.")
self.distro.osutil.deploy_ssh_pubkey(ovfenv.username, pubkey)
self.osutil.deploy_ssh_pubkey(ovfenv.username, pubkey)
def deploy_ssh_keypairs(self, ovfenv):
for keypair in ovfenv.ssh_keypairs:
logger.info("Deploy ssh key pairs.")
self.distro.osutil.deploy_ssh_keypair(ovfenv.username, keypair)
self.osutil.deploy_ssh_keypair(ovfenv.username, keypair)
def report_event(self, message, is_success=False):
add_event(name="WALA", message=message, is_success=is_success,
@@ -175,7 +180,7 @@ class ProvisionHandler(object):
status = ProvisionStatus(status="NotReady", subStatus=sub_status,
description=description)
try:
protocol = self.distro.protocol_util.get_protocol()
protocol = self.protocol_util.get_protocol()
protocol.report_provision_status(status)
except ProtocolError as e:
self.report_event(ustr(e))
@@ -184,7 +189,7 @@ class ProvisionHandler(object):
status = ProvisionStatus(status="Ready")
status.properties.certificateThumbprint = thumbprint
try:
protocol = self.distro.protocol_util.get_protocol()
protocol = self.protocol_util.get_protocol()
protocol.report_provision_status(status)
except ProtocolError as e:
self.report_event(ustr(e))
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,16 +15,18 @@
# Requires Python 2.4+ and Openssl 1.0+
#
from azurelinuxagent.distro.default.distro import DefaultDistro
from azurelinuxagent.distro.suse.osutil import SUSE11OSUtil, SUSEOSUtil
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
from .default import ProvisionHandler
from .ubuntu import UbuntuProvisionHandler
class SUSE11Distro(DefaultDistro):
def __init__(self):
super(SUSE11Distro, self).__init__()
self.osutil = SUSE11OSUtil()
def get_provision_handler(distro_name=DISTRO_NAME,
distro_version=DISTRO_VERSION,
distro_full_name=DISTRO_FULL_NAME):
if distro_name == "ubuntu":
return UbuntuProvisionHandler()
class SUSEDistro(DefaultDistro):
def __init__(self):
super(SUSEDistro, self).__init__()
self.osutil = SUSEOSUtil()
return ProvisionHandler()
@@ -19,22 +19,22 @@
import os
import time
import azurelinuxagent.logger as logger
from azurelinuxagent.future import ustr
import azurelinuxagent.conf as conf
import azurelinuxagent.protocol.ovfenv as ovfenv
from azurelinuxagent.event import add_event, WALAEventOperation
from azurelinuxagent.exception import ProvisionError, ProtocolError
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.fileutil as fileutil
from azurelinuxagent.distro.default.provision import ProvisionHandler
import azurelinuxagent.common.logger as logger
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.protocol.ovfenv as ovfenv
from azurelinuxagent.common.event import add_event, WALAEventOperation
from azurelinuxagent.common.exception import ProvisionError, ProtocolError
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.pa.provision.default import ProvisionHandler
"""
On ubuntu image, provision could be disabled.
"""
class UbuntuProvisionHandler(ProvisionHandler):
def __init__(self, distro):
self.distro = distro
def __init__(self):
super(UbuntuProvisionHandler, self).__init__()
def run(self):
#If provision is enabled, run default provision handler
@@ -50,7 +50,7 @@ class UbuntuProvisionHandler(ProvisionHandler):
logger.info("Waiting cloud-init to copy ovf-env.xml.")
self.wait_for_ovfenv()
protocol = self.distro.protocol_util.detect_protocol()
protocol = self.protocol_util.get_protocol()
self.report_not_ready("Provisioning", "Starting")
logger.info("Sleep 15 seconds to prevent throttling")
time.sleep(15) #Sleep to prevent throttling
@@ -75,7 +75,7 @@ class UbuntuProvisionHandler(ProvisionHandler):
"""
for retry in range(0, max_retry):
try:
self.distro.protocol_util.get_ovf_env()
self.protocol_util.get_ovf_env()
return
except ProtocolError:
if retry < max_retry - 1:
-19
View File
@@ -1,19 +0,0 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
+3 -3
View File
@@ -18,11 +18,11 @@
#
import os
from azurelinuxagent.metadata import AGENT_NAME, AGENT_VERSION, \
from azurelinuxagent.common.version import AGENT_NAME, AGENT_VERSION, \
AGENT_DESCRIPTION, \
DISTRO_NAME, DISTRO_VERSION, DISTRO_FULL_NAME
from azurelinuxagent.agent import Agent
from azurelinuxagent.common.osutil import get_osutil
import setuptools
from setuptools import find_packages
from setuptools.command.install import install as _install
@@ -158,7 +158,7 @@ class install(_install):
def run(self):
_install.run(self)
if self.register_service:
Agent(False).register_service()
get_osutil().register_agent_service()
setuptools.setup(name=AGENT_NAME,
version=AGENT_VERSION,
-3
View File
@@ -14,6 +14,3 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,14 +14,10 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
from azurelinuxagent.distro.loader import get_distro
from azurelinuxagent.exception import *
from azurelinuxagent.distro.default.daemon import *
from azurelinuxagent.common.exception import *
from azurelinuxagent.daemon import *
class MockDaemonCall(object):
def __init__(self, daemon_handler, count):
@@ -38,26 +34,30 @@ class MockDaemonCall(object):
@patch("time.sleep")
class TestDaemon(AgentTestCase):
def test_daemon_restart(self, mock_sleep):
distro = get_distro()
mock_daemon = Mock(side_effect=MockDaemonCall(distro.daemon_handler, 2))
distro.daemon_handler.daemon = mock_daemon
distro.daemon_handler.check_pid = Mock()
distro.daemon_handler.run()
#Mock daemon function
daemon_handler = get_daemon_handler()
mock_daemon = Mock(side_effect=MockDaemonCall(daemon_handler, 2))
daemon_handler.daemon = mock_daemon
daemon_handler.check_pid = Mock()
daemon_handler.run()
mock_sleep.assert_any_call(15)
self.assertEquals(2, distro.daemon_handler.daemon.call_count)
self.assertEquals(2, daemon_handler.daemon.call_count)
@patch("azurelinuxagent.distro.default.daemon.conf")
@patch("azurelinuxagent.distro.default.daemon.sys.exit")
@patch("azurelinuxagent.daemon.main.conf")
@patch("azurelinuxagent.daemon.main.sys.exit")
def test_check_pid(self, mock_exit, mock_conf, mock_sleep):
distro = get_distro()
daemon_handler = get_daemon_handler()
mock_pid_file = os.path.join(self.tmp_dir, "pid")
mock_conf.get_agent_pid_file_path = Mock(return_value=mock_pid_file)
distro.daemon_handler.check_pid()
daemon_handler.check_pid()
self.assertTrue(os.path.isfile(mock_pid_file))
distro.daemon_handler.check_pid()
daemon_handler.check_pid()
mock_exit.assert_any_call(0)
if __name__ == '__main__':
@@ -14,13 +14,10 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
from azurelinuxagent.exception import *
from azurelinuxagent.distro.default.monitor import *
from azurelinuxagent.common.exception import *
from azurelinuxagent.daemon.monitor import *
class TestMonitor(AgentTestCase):
def test_parse_xml_event(self):
Binary file not shown.
+5 -25
View File
@@ -1,36 +1,16 @@
<Extensions version="1.0.0.0" goalStateIncarnation="9"><GuestAgentExtension xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<GAFamilies>
<GAFamily>
<Name>Win8</Name>
<Name>Prod</Name>
<Uris>
<Uri>http://rdfepirv2hknprdstr03.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr04.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr05.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr06.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr07.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr08.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr09.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr10.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr11.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr12.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://zrdfepirv2hk2prdstr01.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win8_asiaeast_manifest.xml</Uri>
<Uri>http://manifest_of_ga.xml</Uri>
</Uris>
</GAFamily>
<GAFamily>
<Name>Win7</Name>
<Name>Test</Name>
<Uris>
<Uri>http://rdfepirv2hknprdstr03.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr04.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr05.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr06.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr07.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr08.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr09.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr10.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr11.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://rdfepirv2hknprdstr12.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
<Uri>http://zrdfepirv2hk2prdstr01.blob.core.windows.net/bfd5c281a7dc4e4b84381eb0b47e3aaf/Microsoft.WindowsAzure.GuestAgent_Win7_asiaeast_manifest.xml</Uri>
</Uris>
<Uri>http://manifest_of_ga.xml</Uri>
</Uris>
</GAFamily>
</GAFamilies>
</GuestAgentExtension>
+48
View File
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<PluginVersionManifest xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Plugins>
<Plugin>
<Version>1.0.0</Version>
<Uris>
<Uri>http://foo.bar/zar/OSTCExtensions.WALinuxAgent__1.0.0</Uri>
</Uris>
</Plugin>
<Plugin>
<Version>1.1.0</Version>
<Uris>
<Uri>http://foo.bar/zar/OSTCExtensions.WALinuxAgent__1.1.0</Uri>
</Uris>
</Plugin>
<Plugin>
<Version>2.0.0</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__2.0.0</Uri></Uris>
</Plugin>
<Plugin>
<Version>2.1.0</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__2.1.0</Uri></Uris>
</Plugin>
<Plugin>
<Version>2.1.1</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__2.1.1</Uri></Uris>
</Plugin>
<Plugin>
<Version>2.2.0</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__2.2.0</Uri></Uris>
</Plugin>
<Plugin>
<Version>3.0</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__3.0</Uri></Uris>
</Plugin>
<Plugin>
<Version>3.1</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__3.1</Uri></Uris>
</Plugin>
<Plugin>
<Version>4.0.0.0</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__3.0</Uri></Uris>
</Plugin>
<Plugin>
<Version>4.0.0.1</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__3.1</Uri></Uris>
</Plugin>
<Plugin>
<Version>4.1.0.0</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__3.1</Uri></Uris>
</Plugin>
<Plugin>
<Version>99999.0.0.0</Version><Uris><Uri>http://host/OSTCExtensions.WALinuxAgent__99999.0.0.0</Uri></Uris>
</Plugin>
</Plugins>
</PluginVersionManifest>
-19
View File
@@ -1,19 +0,0 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
-36
View File
@@ -1,36 +0,0 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
from azurelinuxagent.distro.loader import get_distro
from azurelinuxagent.distro.default.distro import DefaultDistro
class TestDistroLoader(AgentTestCase):
@distros()
def test_distro_loader(self, *distro_args):
distro = get_distro(*distro_args)
self.assertNotEquals(None, distro)
self.assertNotEquals(DefaultDistro, type(distro))
if __name__ == '__main__':
unittest.main()
@@ -1,5 +1,3 @@
# Microsoft Azure Linux Agent
#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,19 +14,16 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.protocol.mockwiredata import *
from azurelinuxagent.exception import *
from azurelinuxagent.distro.loader import get_distro
from azurelinuxagent.protocol.wire import WireProtocol
from azurelinuxagent.distro.default.extension import ExtHandlerInstance
from azurelinuxagent.common.exception import *
from azurelinuxagent.common.protocol import get_protocol_util
from azurelinuxagent.ga.exthandlers import *
from azurelinuxagent.common.protocol.wire import WireProtocol
@patch("time.sleep")
@patch("azurelinuxagent.protocol.wire.CryptUtil")
@patch("azurelinuxagent.utils.restutil.http_get")
@patch("azurelinuxagent.common.protocol.wire.CryptUtil")
@patch("azurelinuxagent.common.utils.restutil.http_get")
class TestExtension(AgentTestCase):
def _assert_handler_status(self, report_vm_status, expected_status,
@@ -50,31 +47,32 @@ class TestExtension(AgentTestCase):
def _create_mock(self, test_data, mock_http_get, MockCryptUtil, _):
"""Test enable/disable/unistall of an extension"""
distro = get_distro()
handler = get_exthandlers_handler()
#Mock protocol to return test data
mock_http_get.side_effect = test_data.mock_http_get
MockCryptUtil.side_effect = test_data.mock_crypt_util
protocol = WireProtocol("foo.bar")
protocol.detect()
protocol.report_ext_status = MagicMock()
protocol.report_vm_status = MagicMock()
distro.protocol_util.get_protocol = Mock(return_value=protocol)
handler.protocol_util.get_protocol = Mock(return_value=protocol)
return distro, protocol
return handler, protocol
def test_ext_handler(self, *args):
test_data = WireProtocolData(DATA_FILE)
distro, protocol = self._create_mock(test_data, *args)
exthandlers_handler, protocol = self._create_mock(test_data, *args)
#Test enable scenario.
distro.ext_handlers_handler.run()
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)
#Test goal state not changed
distro.ext_handlers_handler.run()
exthandlers_handler.run()
self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.0.0")
#Test goal state changed
@@ -82,7 +80,7 @@ class TestExtension(AgentTestCase):
"<Incarnation>2<")
test_data.ext_conf = test_data.ext_conf.replace("seqNo=\"0\"",
"seqNo=\"1\"")
distro.ext_handlers_handler.run()
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", 1)
@@ -92,7 +90,7 @@ class TestExtension(AgentTestCase):
test_data.ext_conf = test_data.ext_conf.replace("1.0.0", "1.1.0")
test_data.ext_conf = test_data.ext_conf.replace("seqNo=\"1\"",
"seqNo=\"2\"")
distro.ext_handlers_handler.run()
exthandlers_handler.run()
self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.1.0")
self._assert_ext_status(protocol.report_ext_status, "success", 2)
@@ -100,7 +98,7 @@ class TestExtension(AgentTestCase):
test_data.goal_state = test_data.goal_state.replace("<Incarnation>3<",
"<Incarnation>4<")
test_data.ext_conf = test_data.ext_conf.replace("enabled", "disabled")
distro.ext_handlers_handler.run()
exthandlers_handler.run()
self._assert_handler_status(protocol.report_vm_status, "NotReady",
1, "1.1.0")
@@ -108,56 +106,56 @@ class TestExtension(AgentTestCase):
test_data.goal_state = test_data.goal_state.replace("<Incarnation>4<",
"<Incarnation>5<")
test_data.ext_conf = test_data.ext_conf.replace("disabled", "uninstall")
distro.ext_handlers_handler.run()
exthandlers_handler.run()
self._assert_no_handler_status(protocol.report_vm_status)
#Test uninstall again!
test_data.goal_state = test_data.goal_state.replace("<Incarnation>5<",
"<Incarnation>6<")
distro.ext_handlers_handler.run()
exthandlers_handler.run()
self._assert_no_handler_status(protocol.report_vm_status)
def test_ext_handler_no_settings(self, *args):
test_data = WireProtocolData(DATA_FILE_EXT_NO_SETTINGS)
distro, protocol = self._create_mock(test_data, *args)
exthandlers_handler, protocol = self._create_mock(test_data, *args)
distro.ext_handlers_handler.run()
exthandlers_handler.run()
self._assert_handler_status(protocol.report_vm_status, "Ready", 0, "1.0.0")
def test_ext_handler_no_public_settings(self, *args):
test_data = WireProtocolData(DATA_FILE_EXT_NO_PUBLIC)
distro, protocol = self._create_mock(test_data, *args)
exthandlers_handler, protocol = self._create_mock(test_data, *args)
distro.ext_handlers_handler.run()
exthandlers_handler.run()
self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.0.0")
def test_ext_handler_no_ext(self, *args):
test_data = WireProtocolData(DATA_FILE_NO_EXT)
distro, protocol = self._create_mock(test_data, *args)
exthandlers_handler, protocol = self._create_mock(test_data, *args)
#Assert no extension handler status
distro.ext_handlers_handler.run()
exthandlers_handler.run()
self._assert_no_handler_status(protocol.report_vm_status)
@patch('azurelinuxagent.distro.default.extension.add_event')
@patch('azurelinuxagent.ga.exthandlers.add_event')
def test_ext_handler_download_failure(self, mock_add_event, *args):
test_data = WireProtocolData(DATA_FILE)
distro, protocol = self._create_mock(test_data, *args)
exthandlers_handler, protocol = self._create_mock(test_data, *args)
protocol.download_ext_handler_pkg = Mock(side_effect=ProtocolError)
distro.ext_handlers_handler.run()
exthandlers_handler.run()
args, kw = mock_add_event.call_args
self.assertEquals(False, kw['is_success'])
self.assertEquals("OSTCExtensions.ExampleHandlerLinux", kw['name'])
self.assertEquals("Download", kw['op'])
@patch('azurelinuxagent.distro.default.extension.fileutil')
@patch('azurelinuxagent.ga.exthandlers.fileutil')
def test_ext_handler_io_error(self, mock_fileutil, *args):
test_data = WireProtocolData(DATA_FILE)
distro, protocol = self._create_mock(test_data, *args)
exthandlers_handler, protocol = self._create_mock(test_data, *args)
mock_fileutil.write_file.return_value = IOError("Mock IO Error")
distro.ext_handlers_handler.run()
exthandlers_handler.run()
def _assert_ext_status(self, report_ext_status, expected_status,
expected_seq_no):
@@ -169,8 +167,8 @@ class TestExtension(AgentTestCase):
def test_ext_handler_no_reporting_status(self, *args):
test_data = WireProtocolData(DATA_FILE)
distro, protocol = self._create_mock(test_data, *args)
distro.ext_handlers_handler.run()
exthandlers_handler, protocol = self._create_mock(test_data, *args)
exthandlers_handler.run()
self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.0.0")
#Remove status file and re-run collecting extension status
@@ -180,7 +178,7 @@ class TestExtension(AgentTestCase):
self.assertTrue(os.path.isfile(status_file))
os.remove(status_file)
distro.ext_handlers_handler.run()
exthandlers_handler.run()
self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.0.0")
self._assert_ext_status(protocol.report_ext_status, "error", 0)
+136
View File
@@ -0,0 +1,136 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
from tests.tools import *
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.common.protocol.wire import *
from azurelinuxagent.common.exception import UpdateError
from azurelinuxagent.ga.update import *
from tests.protocol.mockwiredata import *
class TestUpdate(AgentTestCase):
def test_error_record(self):
update_handler = get_update_handler()
update_handler.mk_ga_dir()
#Save error record
err = GuestAgentError(version="1.0")
update_handler.error_record[err.version] = err
update_handler.save_error_record()
#Load error record
update_handler = get_update_handler()
update_handler.load_error_record()
self.assertNotEquals(None, update_handler.error_record.get("1.0"))
#Mark failure and save again
err = update_handler.error_record.get("1.0")
err.mark_failure()
update_handler.save_error_record()
#Re-load the error record and check
update_handler = get_update_handler()
update_handler.load_error_record()
self.assertNotEquals(None, update_handler.error_record.get("1.0"))
err = update_handler.error_record.get("1.0")
self.assertNotEquals(0, err.failure_count)
self.assertNotEquals(0, err.last_failure)
@patch("time.sleep")
@patch("azurelinuxagent.common.protocol.wire.CryptUtil")
@patch("azurelinuxagent.common.utils.restutil.http_get")
def test_check_update(self, mock_http_get, MockCryptUtil, _):
update_handler = get_update_handler()
test_data = WireProtocolData(DATA_FILE)
mock_http_get.side_effect = test_data.mock_http_get
MockCryptUtil.side_effect = test_data.mock_crypt_util
protocol = WireProtocol("foo.bar")
protocol.detect()
update_handler.protocol_util.get_protocol = Mock(return_value=protocol)
update_handler.check_for_update()
self.assertNotEquals(0, update_handler.agents)
latest_agent = update_handler.get_latest_agent()
self.assertNotEquals(None, latest_agent)
self.assertEquals("99999.0.0.0", latest_agent.version)
#Only should consider versions >= current version
self.assertFalse("1.0.0" in update_handler.error_record)
def test_run_extension(self):
update_handler = get_update_handler()
#Create a mock guest agent instance
test_script = os.path.join(self.tmp_dir, "mock_success")
pkg = ExtHandlerPackage(version="1.0")
latest_agent = GuestAgent(pkg, GuestAgentError(version=pkg.version))
latest_agent.get_agent_bin = Mock(return_value=test_script)
#Create a test script to mock invoking run-extensions success
fileutil.write_file(test_script, "#!/bin/bash\nexit 0")
fileutil.chmod(test_script, 0o700)
update_handler.run_extensions(latest_agent)
#Create a test script to mock invoking run-extensions failure
fileutil.write_file(test_script, "#!/bin/bash\nexit 1")
self.assertRaises(UpdateError, update_handler.run_extensions,
latest_agent)
class TestGuestAgent(AgentTestCase):
@patch("azurelinuxagent.ga.update.restutil.http_get")
def test_download(self, mock_http_get):
update_handler = get_update_handler()
update_handler.mk_ga_dir()
ga_pkg = load_bin_data("ga/WALinuxAgent-2.1.5.rc0.zip")
ga_pkg_resp = MagicMock()
ga_pkg_resp.status = restutil.httpclient.OK
ga_pkg_resp.read = Mock(return_value=ga_pkg)
mock_http_get.return_value= ga_pkg_resp
pkg = ExtHandlerPackage(version="2.1.5.rc0")
pkg.uris.append(ExtHandlerPackageUri())
agent = GuestAgent(pkg, GuestAgentError(version=pkg.version))
agent.download()
self.assertTrue(agent.is_downloaded())
class TestGuestAgentError(AgentTestCase):
def test_mark_failure(self):
err = GuestAgentError()
self.assertFalse(err.is_blacklisted())
for i in range(0, MAX_FAILURE):
err.mark_failure()
#Assume agent failed >= MAX_FAILURE, it should be blacklisted
self.assertTrue(err.is_blacklisted())
self.assertEqual(MAX_FAILURE, err.failure_count)
#Clear old failure won't clear recent failure
err.clear_old_failure()
self.assertTrue(err.is_blacklisted())
#Unless we set the failure to earlier than (now - RETAIN_INTERVAL)
err.last_failure -= RETAIN_INTERVAL * 2
err.clear_old_failure()
self.assertFalse(err.is_blacklisted())
if __name__ == '__main__':
unittest.main()
+16
View File
@@ -0,0 +1,16 @@
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#
@@ -14,33 +14,33 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
from azurelinuxagent.distro.loader import get_distro
from azurelinuxagent.distro.default.protocolUtil import *
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.protocol import OVF_FILE_NAME
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.pa.provision import get_provision_handler
class TestProvision(AgentTestCase):
@distros("redhat")
def test_provision(self, distro_name, distro_version, distro_full_name):
distro = get_distro(distro_name, distro_version, distro_full_name)
distro.osutil = MagicMock()
distro.osutil.decode_customdata = Mock(return_value="")
distro.protocol_util.detect_protocol_by_file = MagicMock()
distro.protocol_util.get_protocol = MagicMock()
provision_handler = get_provision_handler(distro_name, distro_version,
distro_full_name)
mock_osutil = MagicMock()
mock_osutil.decode_customdata = Mock(return_value="")
provision_handler.osutil = mock_osutil
provision_handler.protocol_util.osutil = mock_osutil
provision_handler.protocol_util.get_protocol_by_file = MagicMock()
provision_handler.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)
handler = distro.provision_handler
handler.run()
provision_handler.run()
if __name__ == '__main__':
unittest.main()
-3
View File
@@ -14,6 +14,3 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
+2 -5
View File
@@ -14,13 +14,10 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
from azurelinuxagent.future import httpclient
from azurelinuxagent.utils.cryptutil import CryptUtil
from azurelinuxagent.common.future import httpclient
from azurelinuxagent.common.utils.cryptutil import CryptUtil
DATA_FILE = {
"identity": "metadata/identity.json",
+6 -5
View File
@@ -14,13 +14,10 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
from azurelinuxagent.future import httpclient
from azurelinuxagent.utils.cryptutil import CryptUtil
from azurelinuxagent.common.future import httpclient
from azurelinuxagent.common.utils.cryptutil import CryptUtil
DATA_FILE = {
"version_info": "wire/version_info.xml",
@@ -30,6 +27,7 @@ DATA_FILE = {
"certs": "wire/certs.xml",
"ext_conf": "wire/ext_conf.xml",
"manifest": "wire/manifest.xml",
"ga_manifest" : "wire/ga_manifest.xml",
"trans_prv": "wire/trans_prv",
"trans_cert": "wire/trans_cert",
"test_ext": "ext/sample_ext.zip"
@@ -62,6 +60,7 @@ class WireProtocolData(object):
self.certs = load_data(data_files.get("certs"))
self.ext_conf = load_data(data_files.get("ext_conf"))
self.manifest = load_data(data_files.get("manifest"))
self.ga_manifest = load_data(data_files.get("ga_manifest"))
self.trans_prv = load_data(data_files.get("trans_prv"))
self.trans_cert = load_data(data_files.get("trans_cert"))
self.ext = load_bin_data(data_files.get("test_ext"))
@@ -82,6 +81,8 @@ class WireProtocolData(object):
content = self.ext_conf
elif "manifest.xml" in url:
content = self.manifest
elif "manifest_of_ga.xml" in url:
content = self.ga_manifest
elif "ExampleHandlerLinux" in url:
content = self.ext
resp = MagicMock()
+3 -6
View File
@@ -14,17 +14,14 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
from tests.protocol.mockmetadata import *
from azurelinuxagent.utils.restutil import httpclient
from azurelinuxagent.protocol.metadata import MetadataProtocol
from azurelinuxagent.common.utils.restutil import httpclient
from azurelinuxagent.common.protocol.metadata import MetadataProtocol
@patch("time.sleep")
@patch("azurelinuxagent.protocol.metadata.restutil")
@patch("azurelinuxagent.common.protocol.metadata.restutil")
class TestWireProtocolGetters(AgentTestCase):
def _test_getters(self, test_data, mock_restutil ,_):
mock_restutil.http_get.side_effect = test_data.mock_http_get
@@ -14,72 +14,64 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
from azurelinuxagent.distro.loader import get_distro
from azurelinuxagent.exception import *
from azurelinuxagent.distro.default.protocolUtil import *
from azurelinuxagent.common.exception import *
from azurelinuxagent.common.protocol import get_protocol_util, \
TAG_FILE_NAME
@patch("time.sleep")
class TestProtocolUtil(AgentTestCase):
@distros()
@patch("azurelinuxagent.distro.default.protocolUtil.MetadataProtocol")
@patch("azurelinuxagent.distro.default.protocolUtil.WireProtocol")
def test_detect_protocol(self, distro_name, distro_version, distro_full_name,
WireProtocol, MetadataProtocol, _, *distro_args):
@patch("azurelinuxagent.common.protocol.util.MetadataProtocol")
@patch("azurelinuxagent.common.protocol.util.WireProtocol")
def test_detect_protocol(self, WireProtocol, MetadataProtocol, _):
WireProtocol.return_value = MagicMock()
MetadataProtocol.return_value = MagicMock()
protocol_util = get_protocol_util()
distro = get_distro(distro_name, distro_version, distro_full_name)
distro.dhcp_handler = MagicMock()
distro.dhcp_handler.endpoint = "foo.bar"
protocol_util.dhcp_handler = MagicMock()
protocol_util.dhcp_handler.endpoint = "foo.bar"
#Test wire protocol is available
protocol = distro.protocol_util.detect_protocol()
protocol = protocol_util.get_protocol()
self.assertEquals(WireProtocol.return_value, protocol)
#Test wire protocol is not available
distro.protocol_util.protocol = None
WireProtocol.side_effect = ProtocolError()
protocol_util.clear_protocol()
WireProtocol.return_value.detect.side_effect = ProtocolError()
protocol = distro.protocol_util.detect_protocol()
protocol = protocol_util.get_protocol()
self.assertEquals(MetadataProtocol.return_value, protocol)
#Test no protocol is available
distro.protocol_util.protocol = None
WireProtocol.side_effect = ProtocolError()
MetadataProtocol.side_effect = ProtocolError()
self.assertRaises(ProtocolError, distro.protocol_util.detect_protocol)
protocol_util.clear_protocol()
WireProtocol.return_value.detect.side_effect = ProtocolError()
@distros()
def test_detect_protocol_by_file(self, distro_name, distro_version,
distro_full_name, _):
distro = get_distro(distro_name, distro_version, distro_full_name)
protocol_util = distro.protocol_util
MetadataProtocol.return_value.detect.side_effect = ProtocolError()
self.assertRaises(ProtocolError, protocol_util.get_protocol)
def test_detect_protocol_by_file(self, _):
protocol_util = get_protocol_util()
protocol_util._detect_wire_protocol = Mock()
protocol_util._detect_metadata_protocol = Mock()
tag_file = os.path.join(self.tmp_dir, TAG_FILE_NAME)
#Test tag file doesn't exist
protocol_util.detect_protocol_by_file()
protocol_util.get_protocol_by_file()
protocol_util._detect_wire_protocol.assert_any_call()
protocol_util._detect_metadata_protocol.assert_not_called()
#Test tag file exists
protocol_util.protocol = None
protocol_util.clear_protocol()
protocol_util._detect_wire_protocol.reset_mock()
protocol_util._detect_metadata_protocol.reset_mock()
with open(tag_file, "w+") as tag_fd:
tag_fd.write("")
protocol_util.detect_protocol_by_file()
protocol_util.get_protocol_by_file()
protocol_util._detect_metadata_protocol.assert_any_call()
protocol_util._detect_wire_protocol.assert_not_called()
+1 -4
View File
@@ -14,9 +14,6 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
import uuid
@@ -24,7 +21,7 @@ import unittest
import os
import shutil
import time
from azurelinuxagent.protocol.restapi import *
from azurelinuxagent.common.protocol.restapi import *
class SampleDataContract(DataContract):
def __init__(self):
+6 -9
View File
@@ -14,9 +14,6 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
from tests.protocol.mockwiredata import *
@@ -24,18 +21,18 @@ import uuid
import unittest
import os
import time
from azurelinuxagent.utils.restutil import httpclient
from azurelinuxagent.utils.cryptutil import CryptUtil
from azurelinuxagent.protocol.restapi import *
from azurelinuxagent.protocol.wire import WireClient, WireProtocol, \
from azurelinuxagent.common.utils.restutil import httpclient
from azurelinuxagent.common.utils.cryptutil import CryptUtil
from azurelinuxagent.common.protocol.restapi import *
from azurelinuxagent.common.protocol.wire import WireClient, WireProtocol, \
TRANSPORT_PRV_FILE_NAME, \
TRANSPORT_CERT_FILE_NAME
data_with_bom = b'\xef\xbb\xbfhehe'
@patch("time.sleep")
@patch("azurelinuxagent.protocol.wire.CryptUtil")
@patch("azurelinuxagent.protocol.wire.restutil")
@patch("azurelinuxagent.common.protocol.wire.CryptUtil")
@patch("azurelinuxagent.common.protocol.wire.restutil")
class TestWireProtocolGetters(AgentTestCase):
def _test_getters(self, test_data, mock_restutil, MockCryptUtil, _):
+26
View File
@@ -0,0 +1,26 @@
from tests.tools import *
import azurelinuxagent.common.osutil as osutil
import azurelinuxagent.common.dhcp as dhcp
import azurelinuxagent.common.protocol as protocol
import azurelinuxagent.pa.provision as provision
import azurelinuxagent.pa.deprovision as deprovision
import azurelinuxagent.daemon as daemon
import azurelinuxagent.daemon.resourcedisk as resourcedisk
import azurelinuxagent.daemon.scvmm as scvmm
import azurelinuxagent.daemon.monitor as monitor
import azurelinuxagent.ga.update as update
import azurelinuxagent.ga.exthandlers as exthandlers
class TestImportHandler(AgentTestCase):
def test_get_handler(self):
osutil.get_osutil()
protocol.get_protocol_util()
dhcp.get_dhcp_handler()
provision.get_provision_handler()
deprovision.get_deprovision_handler()
daemon.get_daemon_handler()
resourcedisk.get_resourcedisk_handler()
scvmm.get_scvmm_handler()
monitor.get_monitor_handler()
update.get_update_handler()
exthandlers.get_exthandlers_handler()
+3 -6
View File
@@ -14,9 +14,6 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
"""
Define util functions for unit test
@@ -30,9 +27,9 @@ import shutil
import json
import tempfile
from functools import wraps
import azurelinuxagent.conf as conf
import azurelinuxagent.logger as logger
import azurelinuxagent.event as event
import azurelinuxagent.common.conf as conf
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.event as event
#Import mock module for Python2 and Python3
try:
-3
View File
@@ -14,6 +14,3 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
+2 -5
View File
@@ -14,17 +14,14 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
import uuid
import unittest
import os
import sys
from azurelinuxagent.future import ustr
import azurelinuxagent.utils.fileutil as fileutil
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.utils.fileutil as fileutil
class TestFileOperations(AgentTestCase):
def test_read_write_file(self):
+6 -9
View File
@@ -14,17 +14,14 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import AgentTestCase, patch, Mock, MagicMock
import uuid
import unittest
import os
import azurelinuxagent.utils.restutil as restutil
from azurelinuxagent.future import ustr, httpclient
import azurelinuxagent.logger as logger
import azurelinuxagent.common.utils.restutil as restutil
from azurelinuxagent.common.future import ustr, httpclient
import azurelinuxagent.common.logger as logger
class TestHttpOperations(AgentTestCase):
@@ -57,8 +54,8 @@ class TestHttpOperations(AgentTestCase):
self.assertEquals(rel_uri, "None")
@patch("azurelinuxagent.future.httpclient.HTTPSConnection")
@patch("azurelinuxagent.future.httpclient.HTTPConnection")
@patch("azurelinuxagent.common.future.httpclient.HTTPSConnection")
@patch("azurelinuxagent.common.future.httpclient.HTTPConnection")
def test_http_request(self, HTTPConnection, HTTPSConnection):
mock_httpconn = MagicMock()
mock_httpresp = MagicMock()
@@ -98,7 +95,7 @@ class TestHttpOperations(AgentTestCase):
self.assertEquals("_(:3| <)_", resp.read())
@patch("time.sleep")
@patch("azurelinuxagent.utils.restutil._http_request")
@patch("azurelinuxagent.common.utils.restutil._http_request")
def test_http_request_with_retry(self, _http_request, sleep):
mock_httpresp = MagicMock()
mock_httpresp.read = Mock(return_value="hehe")
+1 -4
View File
@@ -15,15 +15,12 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
import uuid
import unittest
import os
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.common.utils.shellutil as shellutil
import test
class TestrunCmd(AgentTestCase):
+3 -6
View File
@@ -14,17 +14,14 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
# Implements parts of RFC 2131, 1541, 1497 and
# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx
# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx
from tests.tools import *
import uuid
import unittest
import os
from azurelinuxagent.future import ustr
import azurelinuxagent.utils.textutil as textutil
from azurelinuxagent.utils.textutil import Version
from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.utils.textutil as textutil
from azurelinuxagent.common.utils.textutil import Version
class TestTextUtil(AgentTestCase):
def test_get_password_hash(self):