mirror of
https://github.com/clearlinux/WALinuxAgent.git
synced 2026-09-06 13:51:29 +00:00
Merge pull request #200 from brendandixon/2.1_selfupdate
Separate provision agent and guest agent
This commit is contained in:
+82
-19
@@ -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):
|
||||
@@ -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):
|
||||
+3
-6
@@ -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()
|
||||
|
||||
+95
-54
@@ -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():
|
||||
@@ -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
|
||||
+12
-13
@@ -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()
|
||||
|
||||
+8
-9
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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+
|
||||
#
|
||||
|
||||
@@ -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()
|
||||
@@ -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+
|
||||
#
|
||||
|
||||
@@ -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+
|
||||
#
|
||||
|
||||
@@ -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))
|
||||
@@ -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"]
|
||||
+5
-4
@@ -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)
|
||||
+16
-13
@@ -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):
|
||||
@@ -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()
|
||||
|
||||
+6
-5
@@ -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)
|
||||
@@ -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
|
||||
+33
-28
@@ -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()
|
||||
|
||||
+13
-13
@@ -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:
|
||||
@@ -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+
|
||||
#
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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, _):
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user