зеркало из https://github.com/Azure/WALinuxAgent.git
Remove globle variables
This commit is contained in:
Родитель
d5a2bb12be
Коммит
e875ac866f
|
@ -29,27 +29,60 @@ from azurelinuxagent.metadata import AGENT_NAME, AGENT_LONG_VERSION, \
|
|||
DISTRO_NAME, DISTRO_VERSION, \
|
||||
PY_VERSION_MAJOR, PY_VERSION_MINOR, \
|
||||
PY_VERSION_MICRO
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
from azurelinuxagent.handler import HANDLERS
|
||||
|
||||
from azurelinuxagent.distro.loader import get_distro
|
||||
|
||||
def init(verbose):
|
||||
"""
|
||||
Initialize agent running environment.
|
||||
"""
|
||||
HANDLERS.init_handler.init(verbose)
|
||||
class Agent(object):
|
||||
def __init__(self, verbose):
|
||||
"""
|
||||
Initialize agent running environment.
|
||||
"""
|
||||
self.distro = get_distro();
|
||||
self.distro.init_handler.run(verbose)
|
||||
|
||||
def run():
|
||||
"""
|
||||
Run agent daemon
|
||||
"""
|
||||
HANDLERS.main_handler.run()
|
||||
def daemon(self):
|
||||
"""
|
||||
Run agent daemon
|
||||
"""
|
||||
self.distro.daemon_handler.run()
|
||||
|
||||
def deprovision(force=False, deluser=False):
|
||||
def deprovision(self, force=False, deluser=False):
|
||||
"""
|
||||
Run deprovision command
|
||||
"""
|
||||
self.distro.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()
|
||||
print("Start {0} service".format(AGENT_NAME))
|
||||
self.distro.osutil.start_agent_service()
|
||||
|
||||
def main(args):
|
||||
"""
|
||||
Run deprovision command
|
||||
Parse command line arguments, exit with usage() on error.
|
||||
Invoke different methods according to different command
|
||||
"""
|
||||
HANDLERS.deprovision_handler.deprovision(force=force, deluser=deluser)
|
||||
command, force, verbose = parse_args(args)
|
||||
if command == "version":
|
||||
version()
|
||||
elif command == "help":
|
||||
usage()
|
||||
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()
|
||||
|
||||
def parse_args(sys_args):
|
||||
"""
|
||||
|
@ -108,34 +141,3 @@ def start():
|
|||
devnull = open(os.devnull, 'w')
|
||||
subprocess.Popen([sys.argv[0], '-daemon'], stdout=devnull, stderr=devnull)
|
||||
|
||||
def register_service():
|
||||
"""
|
||||
Register agent as a service
|
||||
"""
|
||||
print("Register {0} service".format(AGENT_NAME))
|
||||
OSUTIL.register_agent_service()
|
||||
print("Start {0} service".format(AGENT_NAME))
|
||||
OSUTIL.start_agent_service()
|
||||
|
||||
def main():
|
||||
"""
|
||||
Parse command line arguments, exit with usage() on error.
|
||||
Invoke different methods according to different command
|
||||
"""
|
||||
command, force, verbose = parse_args(sys.argv[1:])
|
||||
if command == "version":
|
||||
version()
|
||||
elif command == "help":
|
||||
usage()
|
||||
else:
|
||||
init(verbose)
|
||||
if command == "deprovision+user":
|
||||
deprovision(force, deluser=True)
|
||||
elif command == "deprovision":
|
||||
deprovision(force, deluser=False)
|
||||
elif command == "start":
|
||||
start()
|
||||
elif command == "register-service":
|
||||
register_service()
|
||||
elif command == "daemon":
|
||||
run()
|
||||
|
|
|
@ -43,11 +43,11 @@ class ConfigurationProvider(object):
|
|||
else:
|
||||
self.values[parts[0]] = None
|
||||
|
||||
def get(self, key, default_val=None):
|
||||
def get(self, key, default_val):
|
||||
val = self.values.get(key)
|
||||
return val if val is not None else default_val
|
||||
|
||||
def get_switch(self, key, default_val=False):
|
||||
def get_switch(self, key, default_val):
|
||||
val = self.values.get(key)
|
||||
if val is not None and val.lower() == 'y':
|
||||
return True
|
||||
|
@ -55,7 +55,7 @@ class ConfigurationProvider(object):
|
|||
return False
|
||||
return default_val
|
||||
|
||||
def get_int(self, key, default_val=-1):
|
||||
def get_int(self, key, default_val):
|
||||
try:
|
||||
return int(self.values.get(key))
|
||||
except TypeError:
|
||||
|
@ -64,9 +64,9 @@ class ConfigurationProvider(object):
|
|||
return default_val
|
||||
|
||||
|
||||
__config__ = ConfigurationProvider()
|
||||
__conf__ = ConfigurationProvider()
|
||||
|
||||
def load_conf(conf_file_path, conf=__config__):
|
||||
def load_conf_from_file(conf_file_path, conf=__conf__):
|
||||
"""
|
||||
Load conf file from: conf_file_path
|
||||
"""
|
||||
|
@ -80,30 +80,75 @@ def load_conf(conf_file_path, conf=__config__):
|
|||
raise AgentConfigError(("Failed to load conf file:{0}, {1}"
|
||||
"").format(conf_file_path, err))
|
||||
|
||||
def get(key, default_val=None, conf=__config__):
|
||||
"""
|
||||
Get option value by key, return default_val if not found
|
||||
"""
|
||||
if conf is not None:
|
||||
return conf.get(key, default_val)
|
||||
else:
|
||||
return default_val
|
||||
def get_lib_dir(conf=__conf__):
|
||||
return conf.get("Lib.Dir", "/var/lib/waagent")
|
||||
|
||||
def get_switch(key, default_val=None, conf=__config__):
|
||||
"""
|
||||
Get bool option value by key, return default_val if not found
|
||||
"""
|
||||
if conf is not None:
|
||||
return conf.get_switch(key, default_val)
|
||||
else:
|
||||
return default_val
|
||||
def get_dvd_mount_point(conf=__conf__):
|
||||
return conf.get("DVD.MountPoint", "/mnt/cdrom/secure")
|
||||
|
||||
def get_int(key, default_val=None, conf=__config__):
|
||||
"""
|
||||
Get int option value by key, return default_val if not found
|
||||
"""
|
||||
if conf is not None:
|
||||
return conf.get_int(key, default_val)
|
||||
else:
|
||||
return default_val
|
||||
def get_agent_pid_file_path(conf=__conf__):
|
||||
return conf.get("Pid.File", "/mnt/cdrom/secure")
|
||||
|
||||
def get_ext_log_dir(conf=__conf__):
|
||||
return conf.get("Extension.LogDir", "/var/log/azure")
|
||||
|
||||
def get_openssl_cmd(conf=__conf__):
|
||||
return conf.get("OS.OpensslPath", "/usr/bin/openssl")
|
||||
|
||||
def get_home_dir(conf=__conf__):
|
||||
return conf.get("OS.HomeDir", "/home")
|
||||
|
||||
def get_passwd_file_path(conf=__conf__):
|
||||
return conf.get("OS.PasswordPath", "/etc/shadow")
|
||||
|
||||
def get_sshd_conf_file_path(conf=__conf__):
|
||||
return conf.get("OS.SshdConfigPath", "/etc/ssh/sshd_config")
|
||||
|
||||
def get_root_device_scsi_timeout(conf=__conf__):
|
||||
return conf.get_int("OS.RootDeviceScsiTimeout", None)
|
||||
|
||||
def get_ssh_host_keypair_type(conf=__conf__):
|
||||
return conf.get("Provisioning.SshHostKeyPairType", "rsa")
|
||||
|
||||
def get_provision_enabled(conf=__conf__):
|
||||
return conf.get_switch("Provisioning.Enabled", True)
|
||||
|
||||
def get_regenerate_ssh_host_key(conf=__conf__):
|
||||
return conf.get_switch("Provisioning.RegenerateSshHostKeyPair", False)
|
||||
|
||||
def get_delete_root_password(conf=__conf__):
|
||||
return conf.get_switch("Provisioning.DeleteRootPassword", False)
|
||||
|
||||
def get_password_cryptid(conf=__conf__):
|
||||
return conf.get("Provisioning.PasswordCryptId", "6")
|
||||
|
||||
def get_password_crypt_salt_len(conf=__conf__):
|
||||
return conf.get_int("Provisioning.PasswordCryptSaltLength", 10)
|
||||
|
||||
def get_monitor_hostname(conf=__conf__):
|
||||
return conf.get_switch("Provisioning.MonitorHostName", False)
|
||||
|
||||
def get_httpproxy_host(conf=__conf__):
|
||||
return conf.get("HttpProxy.Host", None)
|
||||
|
||||
def get_httpproxy_port(conf=__conf__):
|
||||
return conf.get("HttpProxy.Port", None)
|
||||
|
||||
def get_detect_scvmm_env(conf=__conf__):
|
||||
return conf.get_switch("DetectScvmmEnv", False)
|
||||
|
||||
def get_resourcedisk_format(conf=__conf__):
|
||||
return conf.get_switch("ResourceDisk.Format", False)
|
||||
|
||||
def get_resourcedisk_enable_swap(conf=__conf__):
|
||||
return conf.get_switch("ResourceDisk.EnableSwap", False)
|
||||
|
||||
def get_resourcedisk_mountpoint(conf=__conf__):
|
||||
return conf.get("ResourceDisk.MountPoint", "/mnt/resource")
|
||||
|
||||
def get_resourcedisk_filesystem(conf=__conf__):
|
||||
return conf.get("ResourceDisk.MountPoint", "/mnt/resource")
|
||||
|
||||
def get_resourcedisk_swap_size_mb(conf=__conf__):
|
||||
return conf.get_int("ResourceDisk.SwapSizeMB", 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,25 +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.metadata import DISTRO_NAME, DISTRO_VERSION
|
||||
import azurelinuxagent.distro.redhat.loader as redhat
|
||||
|
||||
def get_osutil():
|
||||
return redhat.get_osutil()
|
||||
|
|
@ -21,8 +21,8 @@ import azurelinuxagent.utils.fileutil as fileutil
|
|||
from azurelinuxagent.distro.default.deprovision import DeprovisionHandler, DeprovisionAction
|
||||
|
||||
class CoreOSDeprovisionHandler(DeprovisionHandler):
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
|
||||
def setup(self, deluser):
|
||||
warnings, actions = super(CoreOSDeprovisionHandler, self).setup(deluser)
|
||||
|
|
|
@ -17,11 +17,13 @@
|
|||
# Requires Python 2.4+ and Openssl 1.0+
|
||||
#
|
||||
|
||||
from .deprovision import CoreOSDeprovisionHandler
|
||||
from azurelinuxagent.distro.default.handlerFactory import DefaultHandlerFactory
|
||||
from azurelinuxagent.distro.default.distro import DefaultDistro
|
||||
from azurelinuxagent.distro.coreos.osutil import CoreOSUtil
|
||||
from azurelinuxagent.distro.coreos.deprovision import CoreOSDeprovisionHandler
|
||||
|
||||
class CoreOSHandlerFactory(DefaultHandlerFactory):
|
||||
class CoreOSDistro(DefaultDistro):
|
||||
def __init__(self):
|
||||
super(CoreOSHandlerFactory, self).__init__()
|
||||
super(CoreOSDistro, self).__init__()
|
||||
self.osutil = CoreOSUtil()
|
||||
self.deprovision_handler = CoreOSDeprovisionHandler(self)
|
||||
|
|
@ -1,28 +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+
|
||||
#
|
||||
|
||||
|
||||
def get_osutil():
|
||||
from azurelinuxagent.distro.coreos.osutil import CoreOSUtil
|
||||
return CoreOSUtil()
|
||||
|
||||
def get_handlers():
|
||||
from azurelinuxagent.distro.coreos.handlerFactory import CoreOSHandlerFactory
|
||||
return CoreOSHandlerFactory()
|
||||
|
|
@ -35,9 +35,9 @@ from azurelinuxagent.distro.default.osutil import DefaultOSUtil
|
|||
class CoreOSUtil(DefaultOSUtil):
|
||||
def __init__(self):
|
||||
super(CoreOSUtil, self).__init__()
|
||||
self.agent_conf_file_path = '/usr/share/oem/waagent.conf'
|
||||
self.waagent_path='/usr/share/oem/bin/waagent'
|
||||
self.python_path='/usr/share/oem/python/bin'
|
||||
self.conf_file_path = '/usr/share/oem/waagent.conf'
|
||||
if 'PATH' in os.environ:
|
||||
path = "{0}:{1}".format(os.environ['PATH'], self.python_path)
|
||||
else:
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
# Requires Python 2.4+ and Openssl 1.0+
|
||||
#
|
||||
|
||||
from azurelinuxagent.metadata import DISTRO_NAME, DISTRO_VERSION
|
||||
import azurelinuxagent.distro.redhat.loader as redhat
|
||||
from azurelinuxagent.distro.default.distro import DefaultDistro
|
||||
from azurelinuxagent.distro.debian.osutil import DebianOSUtil
|
||||
|
||||
def get_osutil():
|
||||
return redhat.get_osutil()
|
||||
class DebianDistro(DefaultDistro):
|
||||
def __init__(self):
|
||||
super(DebianDistro, self).__init__()
|
||||
self.osutil = DebianOSUtil()
|
||||
|
|
@ -20,51 +20,57 @@
|
|||
import os
|
||||
import time
|
||||
import sys
|
||||
import azurelinuxagent.conf as conf
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.conf as conf
|
||||
from azurelinuxagent.exception import ProtocolError
|
||||
from azurelinuxagent.metadata 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.protocol.dhcp as dhcp
|
||||
from azurelinuxagent.protocol.factory import PROT_FACTORY
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
|
||||
|
||||
class MainHandler(object):
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
class DaemonHandler(object):
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
|
||||
def run(self):
|
||||
logger.info("{0} Version:{1}", AGENT_LONG_NAME, AGENT_VERSION)
|
||||
logger.info("OS: {0} {1}", DISTRO_NAME, DISTRO_VERSION)
|
||||
logger.info("Python: {0}.{1}.{2}", PY_VERSION_MAJOR, PY_VERSION_MINOR,
|
||||
PY_VERSION_MICRO)
|
||||
|
||||
#Create lib dir
|
||||
if not os.path.isdir(self.distro.conf.get_lib_dir()):
|
||||
fileutil.mkdir(self.distro.conf.get_lib_dir(), mode=0o700)
|
||||
os.chdir(self.distro.conf.get_lib_dir())
|
||||
|
||||
event.enable_unhandled_err_dump(AGENT_LONG_NAME)
|
||||
fileutil.write_file(OSUTIL.get_agent_pid_file_path(), text(os.getpid()))
|
||||
#TODO check running daemon
|
||||
fileutil.write_file(self.distro.osutil.get_agent_pid_file_path(),
|
||||
text(os.getpid()))
|
||||
|
||||
if conf.get_switch("DetectScvmmEnv", False):
|
||||
if self.handlers.scvmm_handler.detect_scvmm_env():
|
||||
if conf.get_detect_scvmm_env():
|
||||
if self.distro.scvmm_handler.run():
|
||||
return
|
||||
|
||||
self.distro.provision_handler.run()
|
||||
|
||||
PROT_FACTORY.wait_for_network()
|
||||
if conf.get_resourcedisk_format():
|
||||
self.distro.resource_disk_handler.run()
|
||||
|
||||
self.handlers.provision_handler.process()
|
||||
try:
|
||||
protocol = self.distro.protocol_util.detect_protocol()
|
||||
except ProtocolError as e:
|
||||
logger.error("Failed to detect protocol, exit", e)
|
||||
return
|
||||
|
||||
self.distro.event_handler.run()
|
||||
self.distro.env_handler.run()
|
||||
|
||||
PROT_FACTORY.detect_protocol()
|
||||
|
||||
if conf.get_switch("ResourceDisk.Format", False):
|
||||
self.handlers.resource_disk_handler.start_activate_resource_disk()
|
||||
|
||||
event.EventMonitor().start()
|
||||
self.handlers.env_handler.start()
|
||||
|
||||
while True:
|
||||
#Handle extensions
|
||||
self.handlers.ext_handlers_handler.process()
|
||||
self.distro.ext_distro_handler.run()
|
||||
time.sleep(25)
|
||||
|
|
@ -18,10 +18,8 @@
|
|||
#
|
||||
|
||||
import azurelinuxagent.conf as conf
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
from azurelinuxagent.exception import ProtocolError
|
||||
from azurelinuxagent.future import read_input
|
||||
import azurelinuxagent.protocol as prot
|
||||
import azurelinuxagent.protocol.ovfenv as ovf
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
import azurelinuxagent.utils.shellutil as shellutil
|
||||
|
||||
|
@ -35,20 +33,20 @@ class DeprovisionAction(object):
|
|||
self.func(*self.args, **self.kwargs)
|
||||
|
||||
class DeprovisionHandler(object):
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
|
||||
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(OSUTIL.del_root_password))
|
||||
actions.append(DeprovisionAction(self.distro.osutil.del_root_password))
|
||||
|
||||
def del_user(self, warnings, actions):
|
||||
|
||||
try:
|
||||
ovfenv = ovf.get_ovf_env()
|
||||
except prot.ProtocolError:
|
||||
ovfenv = self.distro.protocol_util.get_ovf_env()
|
||||
except ProtocolError:
|
||||
warnings.append("WARNING! ovf-env.xml is not found.")
|
||||
warnings.append("WARNING! Skip delete user.")
|
||||
return
|
||||
|
@ -56,7 +54,8 @@ class DeprovisionHandler(object):
|
|||
username = ovfenv.username
|
||||
warnings.append(("WARNING! {0} account and entire home directory "
|
||||
"will be deleted.").format(username))
|
||||
actions.append(DeprovisionAction(OSUTIL.del_account, [username]))
|
||||
actions.append(DeprovisionAction(self.distro.osutil.del_account,
|
||||
[username]))
|
||||
|
||||
|
||||
def regen_ssh_host_key(self, warnings, actions):
|
||||
|
@ -66,7 +65,7 @@ class DeprovisionHandler(object):
|
|||
|
||||
def stop_agent_service(self, warnings, actions):
|
||||
warnings.append("WARNING! The waagent service will be stopped.")
|
||||
actions.append(DeprovisionAction(OSUTIL.stop_agent_service))
|
||||
actions.append(DeprovisionAction(self.distro.osutil.stop_agent_service))
|
||||
|
||||
def del_files(self, warnings, actions):
|
||||
files_to_del = ['/root/.bash_history', '/var/log/waagent.log']
|
||||
|
@ -78,26 +77,28 @@ class DeprovisionHandler(object):
|
|||
actions.append(DeprovisionAction(fileutil.rm_dirs, dirs_to_del))
|
||||
|
||||
def del_lib_dir(self, warnings, actions):
|
||||
dirs_to_del = [OSUTIL.get_lib_dir()]
|
||||
dirs_to_del = [conf.get_lib_dir()]
|
||||
actions.append(DeprovisionAction(fileutil.rm_dirs, dirs_to_del))
|
||||
|
||||
def reset_hostname(self, warnings, actions):
|
||||
localhost = ["localhost.localdomain"]
|
||||
actions.append(DeprovisionAction(OSUTIL.set_hostname, localhost))
|
||||
actions.append(DeprovisionAction(OSUTIL.set_dhcp_hostname, localhost))
|
||||
actions.append(DeprovisionAction(self.distro.osutil.set_hostname,
|
||||
localhost))
|
||||
actions.append(DeprovisionAction(self.distro.osutil.set_dhcp_hostname,
|
||||
localhost))
|
||||
|
||||
def setup(self, deluser):
|
||||
warnings = []
|
||||
actions = []
|
||||
|
||||
self.stop_agent_service(warnings, actions)
|
||||
if conf.get_switch("Provisioning.RegenerateSshHostkey", False):
|
||||
if conf.get_regenerate_ssh_host_key():
|
||||
self.regen_ssh_host_key(warnings, actions)
|
||||
|
||||
self.del_dhcp_lease(warnings, actions)
|
||||
self.reset_hostname(warnings, actions)
|
||||
|
||||
if conf.get_switch("Provisioning.DeleteRootPassword", False):
|
||||
if conf.get_delete_root_password():
|
||||
self.del_root_password(warnings, actions)
|
||||
|
||||
self.del_lib_dir(warnings, actions)
|
||||
|
@ -108,7 +109,7 @@ class DeprovisionHandler(object):
|
|||
|
||||
return warnings, actions
|
||||
|
||||
def deprovision(self, force=False, deluser=False):
|
||||
def run(self, force=False, deluser=False):
|
||||
warnings, actions = self.setup(deluser)
|
||||
for warning in warnings:
|
||||
print(warning)
|
||||
|
|
|
@ -21,20 +21,49 @@ import array
|
|||
import time
|
||||
import threading
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
import azurelinuxagent.conf as conf
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
import azurelinuxagent.utils.shellutil as shellutil
|
||||
from azurelinuxagent.utils.textutil import *
|
||||
from azurelinuxagent.protocol.common import ProtocolError
|
||||
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
|
||||
|
||||
DHCP_FILE_NAME = "DHCP"
|
||||
|
||||
class DhcpResponse(object):
|
||||
def __init__(self, resp):
|
||||
endpoint, gateway, routes = parse_dhcp_resp(resp)
|
||||
self.endpoint = endpoint
|
||||
self.gateway = gateway
|
||||
self.routes = routes
|
||||
|
||||
class DhcpHandler(object):
|
||||
"""
|
||||
Azure use DHCP option 245 to pass endpoint ip to VMs.
|
||||
"""
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
self.endpoint = None
|
||||
self.gateway = None
|
||||
self.route = None
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Send dhcp request
|
||||
Configure default gateway and routes
|
||||
Save wire server endpoint if found
|
||||
"""
|
||||
self.send_dhcp_req()
|
||||
self.conf_routes()
|
||||
if self.endpoint is not None:
|
||||
self.distro.osutil.set_wireserver_endpoint(self.endpoint)
|
||||
|
||||
def wait_for_network(self):
|
||||
"""
|
||||
Wait for network stack to be initialized.
|
||||
"""
|
||||
ipv4 = self.distro.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()
|
||||
|
||||
def conf_routes(self):
|
||||
logger.info("Configure routes")
|
||||
|
@ -42,56 +71,56 @@ class DhcpResponse(object):
|
|||
logger.info("Routes:{0}", self.routes)
|
||||
#Add default gateway
|
||||
if self.gateway is not None:
|
||||
OSUTIL.route_add(0 , 0, self.gateway)
|
||||
self.distro.osutil.route_add(0 , 0, self.gateway)
|
||||
if self.routes is not None:
|
||||
for route in self.routes:
|
||||
OSUTIL.route_add(route[0], route[1], route[2])
|
||||
self.distro.osutil.route_add(route[0], route[1], route[2])
|
||||
|
||||
def _load_dhcp_resp():
|
||||
dhcp_file_path = os.path.join(OSUTIL.get_lib_dir(), DHCP_FILE_NAME)
|
||||
resp = fileutil.read_file(dhcp_file_path, asbin=True)
|
||||
return DhcpResponse(resp)
|
||||
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()
|
||||
response = socket_send(request)
|
||||
validate_dhcp_resp(request, response)
|
||||
return response
|
||||
except DhcpError as e:
|
||||
logger.warn("Failed to send DHCP request: {0}", e)
|
||||
time.sleep(duration)
|
||||
return None
|
||||
|
||||
def _fetch_dhcp_resp():
|
||||
logger.info("Send dhcp request")
|
||||
mac_addr = OSUTIL.get_mac_addr()
|
||||
req = build_dhcp_request(mac_addr)
|
||||
resp = send_dhcp_request(req)
|
||||
if resp is None:
|
||||
raise ProtocolError("Failed to receive dhcp response.")
|
||||
dhcp_file_path = os.path.join(OSUTIL.get_lib_dir(), DHCP_FILE_NAME)
|
||||
try:
|
||||
fileutil.write_file(dhcp_file_path, resp, asbin=True)
|
||||
except IOError as e:
|
||||
logger.warn("Failed to save dhcp response: {0}", e)
|
||||
return DhcpResponse(resp)
|
||||
def send_dhcp_req(self):
|
||||
"""
|
||||
Build dhcp request with mac addr
|
||||
Configure route to allow dhcp traffic
|
||||
Stop dhcp service if necessary
|
||||
"""
|
||||
logger.info("Send dhcp request")
|
||||
mac_addr = self.distro.osutil.get_mac_addr()
|
||||
req = build_dhcp_request(mac_addr)
|
||||
|
||||
class DhcpClient(object):
|
||||
def __init__(self):
|
||||
self._resp = None
|
||||
self._lock = threading.Lock()
|
||||
# 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()
|
||||
if missing_default_route:
|
||||
self.distro.osutil.set_route_for_dhcp_broadcast(ifname)
|
||||
|
||||
def get_dhcp_resp(self):
|
||||
self._lock.acquire()
|
||||
try:
|
||||
if self._resp is None:
|
||||
try:
|
||||
self._resp = _load_dhcp_resp()
|
||||
except IOError:
|
||||
self._resp = _fetch_dhcp_resp()
|
||||
return self._resp
|
||||
finally:
|
||||
self._lock.release()
|
||||
# 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()
|
||||
|
||||
def fetch_dhcp_resp(self):
|
||||
self._lock.acquire()
|
||||
try:
|
||||
self._resp = _fetch_dhcp_resp()
|
||||
return self._resp
|
||||
finally:
|
||||
self._lock.release()
|
||||
resp = self._send_dhcp_req(req)
|
||||
|
||||
if self.distro.osutil.is_dhcp_enabled():
|
||||
self.distro.osutil.start_dhcp_service()
|
||||
|
||||
DHCPCLIENT = DhcpClient()
|
||||
if missing_default_route:
|
||||
self.distro.osutil.remove_route_for_dhcp_broadcast(ifname)
|
||||
|
||||
if resp is None:
|
||||
raise DhcpError("Failed to receive dhcp response.")
|
||||
self.endpoint, self.gateway, self.routes = parse_dhcp_resp(resp)
|
||||
|
||||
def validate_dhcp_resp(request, response):
|
||||
bytes_recv = len(response)
|
||||
|
@ -110,20 +139,20 @@ def validate_dhcp_resp(request, response):
|
|||
logger.verb("Cookie not match:\nsend={0},\nreceive={1}",
|
||||
hex_dump3(request, 0xEC, 4),
|
||||
hex_dump3(response, 0xEC, 4))
|
||||
raise ProtocolError("Cookie in dhcp respones doesn't match the request")
|
||||
raise DhcpError("Cookie in dhcp respones doesn't match the request")
|
||||
|
||||
if not compare_bytes(request, response, 4, 4):
|
||||
logger.verb("TransactionID not match:\nsend={0},\nreceive={1}",
|
||||
hex_dump3(request, 4, 4),
|
||||
hex_dump3(response, 4, 4))
|
||||
raise ProtocolError("TransactionID in dhcp respones "
|
||||
raise DhcpError("TransactionID in dhcp respones "
|
||||
"doesn't match the request")
|
||||
|
||||
if not compare_bytes(request, response, 0x1C, 6):
|
||||
logger.verb("Mac Address not match:\nsend={0},\nreceive={1}",
|
||||
hex_dump3(request, 0x1C, 6),
|
||||
hex_dump3(response, 0x1C, 6))
|
||||
raise ProtocolError("Mac Addr in dhcp respones "
|
||||
raise DhcpError("Mac Addr in dhcp respones "
|
||||
"doesn't match the request")
|
||||
|
||||
def parse_route(response, option, i, length, bytes_recv):
|
||||
|
@ -203,53 +232,6 @@ def parse_dhcp_resp(response):
|
|||
i += length + 2
|
||||
return endpoint, gateway, routes
|
||||
|
||||
|
||||
def allow_dhcp_broadcast(func):
|
||||
"""
|
||||
Temporary allow broadcase for dhcp. Remove the route when done.
|
||||
"""
|
||||
def wrapper(*args, **kwargs):
|
||||
missing_default_route = OSUTIL.is_missing_default_route()
|
||||
ifname = OSUTIL.get_if_name()
|
||||
if missing_default_route:
|
||||
OSUTIL.set_route_for_dhcp_broadcast(ifname)
|
||||
result = func(*args, **kwargs)
|
||||
if missing_default_route:
|
||||
OSUTIL.remove_route_for_dhcp_broadcast(ifname)
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
def disable_dhcp_service(func):
|
||||
"""
|
||||
In some distros, dhcp service needs to be shutdown before agent probe
|
||||
endpoint through dhcp.
|
||||
"""
|
||||
def wrapper(*args, **kwargs):
|
||||
if OSUTIL.is_dhcp_enabled():
|
||||
OSUTIL.stop_dhcp_service()
|
||||
result = func(*args, **kwargs)
|
||||
OSUTIL.start_dhcp_service()
|
||||
return result
|
||||
else:
|
||||
return func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
@allow_dhcp_broadcast
|
||||
@disable_dhcp_service
|
||||
def send_dhcp_request(request):
|
||||
__waiting_duration__ = [0, 10, 30, 60, 60]
|
||||
for duration in __waiting_duration__:
|
||||
try:
|
||||
OSUTIL.allow_dhcp_broadcast()
|
||||
response = socket_send(request)
|
||||
validate_dhcp_resp(request, response)
|
||||
return response
|
||||
except ProtocolError as e:
|
||||
logger.warn("Failed to send DHCP request: {0}", e)
|
||||
time.sleep(duration)
|
||||
return None
|
||||
|
||||
def socket_send(request):
|
||||
sock = None
|
||||
try:
|
||||
|
@ -265,7 +247,7 @@ def socket_send(request):
|
|||
response = sock.recv(1024)
|
||||
return response
|
||||
except IOError as e:
|
||||
raise ProtocolError("{0}".format(e))
|
||||
raise DhcpError("{0}".format(e))
|
||||
finally:
|
||||
if sock is not None:
|
||||
sock.close()
|
|
@ -16,8 +16,14 @@
|
|||
#
|
||||
# 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.run import MainHandler
|
||||
from azurelinuxagent.distro.default.event import EventHandler
|
||||
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
|
||||
|
@ -25,10 +31,17 @@ from azurelinuxagent.distro.default.resourceDisk import ResourceDiskHandler
|
|||
from azurelinuxagent.distro.default.extension import ExtHandlersHandler
|
||||
from azurelinuxagent.distro.default.deprovision import DeprovisionHandler
|
||||
|
||||
class DefaultHandlerFactory(object):
|
||||
class DefaultDistro(object):
|
||||
"""
|
||||
"""
|
||||
def __init__(self):
|
||||
self.osutil = DefaultOSUtil()
|
||||
self.protocol_util = ProtocolUtil(self)
|
||||
|
||||
self.init_handler = InitHandler(self)
|
||||
self.main_handler = MainHandler(self)
|
||||
self.daemon_handler = DaemonHandler(self)
|
||||
self.event_handler = EventHandler(self)
|
||||
self.dhcp_handler = DhcpHandler(self)
|
||||
self.scvmm_handler = ScvmmHandler(self)
|
||||
self.env_handler = EnvHandler(self)
|
||||
self.provision_handler = ProvisionHandler(self)
|
|
@ -23,8 +23,6 @@ import threading
|
|||
import time
|
||||
import azurelinuxagent.logger as logger
|
||||
import azurelinuxagent.conf as conf
|
||||
import azurelinuxagent.protocol.dhcp as dhcp
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
|
||||
class EnvHandler(object):
|
||||
"""
|
||||
|
@ -32,37 +30,25 @@ class EnvHandler(object):
|
|||
If dhcp clinet process re-start has occurred, reset routes, dhcp with fabric.
|
||||
|
||||
Monitor scsi disk.
|
||||
If new scsi disk found, set
|
||||
If new scsi disk found, set timeout
|
||||
"""
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
self.monitor = EnvMonitor()
|
||||
|
||||
def start(self):
|
||||
self.monitor.start()
|
||||
|
||||
def stop(self):
|
||||
self.monitor.stop()
|
||||
|
||||
class EnvMonitor(object):
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
self.stopped = True
|
||||
self.hostname = None
|
||||
self.dhcpid = None
|
||||
self.server_thread=None
|
||||
|
||||
def start(self):
|
||||
self.dhcp_resp = dhcp.DHCPCLIENT.get_dhcp_resp()
|
||||
def run(self):
|
||||
if not self.stopped:
|
||||
logger.info("Stop existing env monitor service.")
|
||||
self.stop()
|
||||
|
||||
self.stopped = False
|
||||
logger.info("Start env monitor service.")
|
||||
self.dhcp_resp.conf_routes()
|
||||
self.distro.dhcp_handler.conf_routes()
|
||||
self.hostname = socket.gethostname()
|
||||
self.dhcpid = OSUTIL.get_dhcp_pid()
|
||||
self.dhcpid = self.distro.osutil.get_dhcp_pid()
|
||||
self.server_thread = threading.Thread(target = self.monitor)
|
||||
self.server_thread.setDaemon(True)
|
||||
self.server_thread.start()
|
||||
|
@ -73,11 +59,11 @@ class EnvMonitor(object):
|
|||
If dhcp clinet process re-start has occurred, reset routes.
|
||||
"""
|
||||
while not self.stopped:
|
||||
OSUTIL.remove_rules_files()
|
||||
timeout = conf.get("OS.RootDeviceScsiTimeout", None)
|
||||
self.distro.osutil.remove_rules_files()
|
||||
timeout = conf.get_root_device_scsi_timeout()
|
||||
if timeout is not None:
|
||||
OSUTIL.set_scsi_disks_timeout(timeout)
|
||||
if conf.get_switch("Provisioning.MonitorHostName", False):
|
||||
self.distro.osutil.set_scsi_disks_timeout(timeout)
|
||||
if conf.get_monitor_hostname():
|
||||
self.handle_hostname_update()
|
||||
self.handle_dhclient_restart()
|
||||
time.sleep(5)
|
||||
|
@ -87,25 +73,25 @@ class EnvMonitor(object):
|
|||
if curr_hostname != self.hostname:
|
||||
logger.info("EnvMonitor: Detected host name change: {0} -> {1}",
|
||||
self.hostname, curr_hostname)
|
||||
OSUTIL.set_hostname(curr_hostname)
|
||||
OSUTIL.publish_hostname(curr_hostname)
|
||||
self.distro.osutil.set_hostname(curr_hostname)
|
||||
self.distro.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 = OSUTIL.get_dhcp_pid()
|
||||
self.dhcpid = self.distro.dhcp_handler.get_dhcp_pid()
|
||||
return
|
||||
|
||||
#The dhcp process hasn't changed since last check
|
||||
if os.path.isdir(os.path.join('/proc', self.dhcpid.strip())):
|
||||
return
|
||||
|
||||
newpid = OSUTIL.get_dhcp_pid()
|
||||
newpid = self.distro.osutil.get_dhcp_pid()
|
||||
if newpid is not None and newpid != self.dhcpid:
|
||||
logger.info("EnvMonitor: Detected dhcp client restart. "
|
||||
"Restoring routing table.")
|
||||
self.dhcp_resp.conf_routes()
|
||||
self.distro.dhcp_handler.conf_routes()
|
||||
self.dhcpid = newpid
|
||||
|
||||
def stop(self):
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
# 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 sys
|
||||
import traceback
|
||||
import atexit
|
||||
import json
|
||||
import time
|
||||
import datetime
|
||||
import threading
|
||||
import platform
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.event import WALAEventOperation, add_event
|
||||
from azurelinuxagent.exception import EventError, ProtocolError, OSUtilError
|
||||
from azurelinuxagent.future import text
|
||||
from azurelinuxagent.protocol.restapi import TelemetryEventParam, \
|
||||
TelemetryEventList, \
|
||||
TelemetryEvent, \
|
||||
set_properties, get_properties
|
||||
from azurelinuxagent.metadata import DISTRO_NAME, DISTRO_VERSION, \
|
||||
DISTRO_CODE_NAME, AGENT_VERSION
|
||||
|
||||
|
||||
|
||||
class EventHandler(object):
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
self.sysinfo = []
|
||||
|
||||
def run(self):
|
||||
event_thread = threading.Thread(target = self.daemon)
|
||||
event_thread.setDaemon(True)
|
||||
event_thread.start()
|
||||
|
||||
def init_sysinfo(self):
|
||||
osversion = "{0}:{1}-{2}-{3}:{4}".format(platform.system(),
|
||||
DISTRO_NAME,
|
||||
DISTRO_VERSION,
|
||||
DISTRO_CODE_NAME,
|
||||
platform.release())
|
||||
|
||||
|
||||
self.sysinfo.append(TelemetryEventParam("OSVersion", osversion))
|
||||
self.sysinfo.append(TelemetryEventParam("GAVersion", AGENT_VERSION))
|
||||
|
||||
try:
|
||||
ram = self.distro.osutil.get_total_mem()
|
||||
processors = self.distro.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()
|
||||
vminfo = protocol.get_vminfo()
|
||||
#TODO add more system info
|
||||
self.sysinfo.append(TelemetryEventParam("VMName", vminfo.vmName ))
|
||||
except ProtocolError as e:
|
||||
logger.warn("Failed to get system info: {0}", e)
|
||||
|
||||
def collect_event(self, evt_file_name):
|
||||
try:
|
||||
logger.verb("Found event file: {0}", evt_file_name)
|
||||
with open(evt_file_name, "rb") as evt_file:
|
||||
#if fail to open or delete the file, throw exception
|
||||
json_str = evt_file.read().decode("utf-8",'ignore')
|
||||
logger.verb("Processed event file: {0}", evt_file_name)
|
||||
os.remove(evt_file_name)
|
||||
return json_str
|
||||
except IOError as e:
|
||||
msg = "Failed to process {0}, {1}".format(evt_file_name, e)
|
||||
raise EventError(msg)
|
||||
|
||||
def collect_and_send_events(self):
|
||||
event_list = TelemetryEventList()
|
||||
event_dir = os.path.join(self.distro.osutil.get_lib_dir(), "event")
|
||||
event_files = os.listdir(event_dir)
|
||||
for event_file in event_files:
|
||||
if not event_file.endswith(".tld"):
|
||||
continue
|
||||
event_file_path = os.path.join(event_dir, event_file)
|
||||
try:
|
||||
data_str = self.collect_event(event_file_path)
|
||||
except EventError as e:
|
||||
logger.error("{0}", e)
|
||||
continue
|
||||
try:
|
||||
data = json.loads(data_str)
|
||||
except ValueError as e:
|
||||
logger.verb(data_str)
|
||||
logger.verb("Failed to decode json event file: {0}", e)
|
||||
continue
|
||||
|
||||
event = TelemetryEvent()
|
||||
set_properties("event", event, data)
|
||||
event.parameters.extend(self.sysinfo)
|
||||
event_list.events.append(event)
|
||||
if len(event_list.events) == 0:
|
||||
return
|
||||
|
||||
try:
|
||||
protocol = self.distro.protocol_util.get_protocol()
|
||||
protocol.report_event(event_list)
|
||||
except ProtocolError as e:
|
||||
logger.error("{0}", e)
|
||||
|
||||
def daemon(self):
|
||||
self.init_sysinfo()
|
||||
last_heartbeat = datetime.datetime.min
|
||||
period = datetime.timedelta(hours = 12)
|
||||
while(True):
|
||||
if (datetime.datetime.now()-last_heartbeat) > period:
|
||||
last_heartbeat = datetime.datetime.now()
|
||||
add_event(op=WALAEventOperation.HeartBeat, name="WALA",
|
||||
is_success=True)
|
||||
self.collect_and_send_events()
|
||||
time.sleep(60)
|
|
@ -22,14 +22,15 @@ import time
|
|||
import json
|
||||
import subprocess
|
||||
import shutil
|
||||
import azurelinuxagent.conf as conf
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.future import text
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
from azurelinuxagent.protocol.factory import PROT_FACTORY
|
||||
import azurelinuxagent.protocol.common as prot
|
||||
from azurelinuxagent.metadata import AGENT_VERSION
|
||||
from azurelinuxagent.event import add_event, WALAEventOperation
|
||||
from azurelinuxagent.exception import ExtensionError
|
||||
from azurelinuxagent.exception import ExtensionError, ProtocolError
|
||||
from azurelinuxagent.future import text
|
||||
from azurelinuxagent.metadata import AGENT_VERSION
|
||||
from azurelinuxagent.protocol.restapi import ExtHandlerStatus, ExtensionStatus, \
|
||||
ExtensionSubStatus, Extension, \
|
||||
VMStatus
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
import azurelinuxagent.utils.restutil as restutil
|
||||
import azurelinuxagent.utils.shellutil as shellutil
|
||||
|
@ -72,7 +73,7 @@ def parse_ext_substatus(substatus):
|
|||
validate_has_key(substatus, 'status', 'substatus/status')
|
||||
validate_in_range(substatus['status'], VALID_EXTENSION_STATUS,
|
||||
'substatus/status')
|
||||
status = prot.ExtensionSubStatus()
|
||||
status = ExtensionSubStatus()
|
||||
status.name = substatus.get('name')
|
||||
status.status = substatus.get('status')
|
||||
status.code = substatus.get('code', 0)
|
||||
|
@ -120,7 +121,7 @@ def get_installed_version(target_name):
|
|||
Return the highest version instance with the same name
|
||||
"""
|
||||
installed_version = None
|
||||
lib_dir = OSUTIL.get_lib_dir()
|
||||
lib_dir = conf.get_lib_dir()
|
||||
for dir_name in os.listdir(lib_dir):
|
||||
path = os.path.join(lib_dir, dir_name)
|
||||
if os.path.isdir(path) and dir_name.startswith(target_name):
|
||||
|
@ -139,19 +140,18 @@ class ExtHandlerState(object):
|
|||
|
||||
|
||||
class ExtHandlersHandler(object):
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
|
||||
def process(self):
|
||||
def run(self):
|
||||
try:
|
||||
protocol = PROT_FACTORY.get_protocol()
|
||||
protocol = self.distro.protocol_util.get_protocol()
|
||||
ext_handlers = protocol.get_ext_handlers()
|
||||
except prot.ProtocolError as e:
|
||||
except ProtocolError as e:
|
||||
add_event(name="WALA", is_success=False, message = text(e))
|
||||
return
|
||||
|
||||
|
||||
vm_status = prot.VMStatus()
|
||||
vm_status = VMStatus()
|
||||
vm_status.vmAgent.version = AGENT_VERSION
|
||||
vm_status.vmAgent.status = "Ready"
|
||||
vm_status.vmAgent.message = "Guest Agent is running"
|
||||
|
@ -164,7 +164,7 @@ class ExtHandlersHandler(object):
|
|||
#TODO handle extension in parallel
|
||||
try:
|
||||
pkg_list = protocol.get_ext_handler_pkgs(ext_handler)
|
||||
except prot.ProtocolError as e:
|
||||
except ProtocolError as e:
|
||||
add_event(name="WALA", is_success=False, message=text(e))
|
||||
continue
|
||||
|
||||
|
@ -175,14 +175,14 @@ class ExtHandlersHandler(object):
|
|||
try:
|
||||
logger.verb("Report vm agent status")
|
||||
protocol.report_vm_status(vm_status)
|
||||
except prot.ProtocolError as e:
|
||||
except ProtocolError as e:
|
||||
add_event(name="WALA", is_success=False, message = text(e))
|
||||
|
||||
def process_extension(self, ext_handler, pkg_list):
|
||||
installed_version = get_installed_version(ext_handler.name)
|
||||
if installed_version is not None:
|
||||
handler = ExtHandlerInstance(ext_handler, pkg_list,
|
||||
installed_version, installed=True)
|
||||
handler = ExtHandlerInstance(ext_handler, pkg_list, installed_version,
|
||||
installed=True)
|
||||
else:
|
||||
handler = ExtHandlerInstance(ext_handler, pkg_list,
|
||||
ext_handler.properties.version)
|
||||
|
@ -190,16 +190,17 @@ class ExtHandlersHandler(object):
|
|||
|
||||
if handler.ext_status is not None:
|
||||
try:
|
||||
protocol = PROT_FACTORY.get_protocol()
|
||||
protocol = self.distro.protocol_util.get_protocol()
|
||||
protocol.report_ext_status(handler.name, handler.ext.name,
|
||||
handler.ext_status)
|
||||
except prot.ProtocolError as e:
|
||||
except ProtocolError as e:
|
||||
add_event(name="WALA", is_success=False, message=text(e))
|
||||
|
||||
return handler.handler_status
|
||||
|
||||
class ExtHandlerInstance(object):
|
||||
def __init__(self, ext_handler, pkg_list, curr_version, installed=False):
|
||||
def __init__(self, ext_handler, pkg_list, curr_version,
|
||||
installed=False):
|
||||
self.ext_handler = ext_handler
|
||||
self.name = ext_handler.name
|
||||
self.version = ext_handler.properties.version
|
||||
|
@ -210,10 +211,10 @@ class ExtHandlerInstance(object):
|
|||
self.curr_version = curr_version
|
||||
self.installed = installed
|
||||
self.handler_state = None
|
||||
self.lib_dir = OSUTIL.get_lib_dir()
|
||||
self.lib_dir = conf.get_lib_dir()
|
||||
|
||||
self.ext_status = prot.ExtensionStatus()
|
||||
self.handler_status = prot.ExtHandlerStatus()
|
||||
self.ext_status = ExtensionStatus()
|
||||
self.handler_status = ExtHandlerStatus()
|
||||
self.handler_status.name = self.name
|
||||
self.handler_status.version = self.curr_version
|
||||
|
||||
|
@ -223,7 +224,7 @@ class ExtHandlerInstance(object):
|
|||
self.handler_status.extensions = [self.ext.name]
|
||||
else:
|
||||
#When no extension settings, set sequenceNumber to 0
|
||||
self.ext = prot.Extension(sequenceNumber=0)
|
||||
self.ext = Extension(sequenceNumber=0)
|
||||
self.ext_status.sequenceNumber = self.ext.sequenceNumber
|
||||
|
||||
prefix = "[{0}]".format(self.get_full_name())
|
||||
|
@ -571,7 +572,7 @@ class ExtHandlerInstance(object):
|
|||
|
||||
def collect_heartbeat(self):
|
||||
self.logger.info("Collect heart beat")
|
||||
heartbeat_file = os.path.join(OSUTIL.get_lib_dir(),
|
||||
heartbeat_file = os.path.join(conf.get_lib_dir(),
|
||||
self.get_heartbeat_file())
|
||||
if not os.path.isfile(heartbeat_file):
|
||||
raise ExtensionError("Failed to get heart beat file")
|
||||
|
@ -696,7 +697,7 @@ class ExtHandlerInstance(object):
|
|||
return "{0}-{1}".format(self.name, self.curr_version)
|
||||
|
||||
def get_base_dir(self):
|
||||
return os.path.join(OSUTIL.get_lib_dir(), self.get_full_name())
|
||||
return os.path.join(conf.get_lib_dir(), self.get_full_name())
|
||||
|
||||
def get_status_dir(self):
|
||||
return os.path.join(self.get_base_dir(), "status")
|
||||
|
@ -713,7 +714,7 @@ class ExtHandlerInstance(object):
|
|||
"{0}.settings".format(self.ext.sequenceNumber))
|
||||
|
||||
def get_handler_state_dir(self):
|
||||
return os.path.join(OSUTIL.get_lib_dir(), "handler_state",
|
||||
return os.path.join(conf.get_lib_dir(), "handler_state",
|
||||
self.get_full_name())
|
||||
|
||||
def get_handler_state_file(self):
|
||||
|
@ -735,7 +736,7 @@ class ExtHandlerInstance(object):
|
|||
return os.path.join(self.get_base_dir(), 'HandlerEnvironment.json')
|
||||
|
||||
def get_log_dir(self):
|
||||
return os.path.join(OSUTIL.get_ext_log_dir(), self.name,
|
||||
return os.path.join(conf.get_ext_log_dir(), self.name,
|
||||
self.curr_version)
|
||||
|
||||
class HandlerEnvironment(object):
|
||||
|
|
|
@ -20,33 +20,34 @@
|
|||
import os
|
||||
import azurelinuxagent.conf as conf
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
import azurelinuxagent.event as event
|
||||
|
||||
|
||||
class InitHandler(object):
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
|
||||
def init(self, verbose):
|
||||
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 = OSUTIL.get_conf_file_path()
|
||||
conf.load_conf(conf_file_path)
|
||||
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_switch("Logs.Verbose", False)
|
||||
verbose = verbose or self.distro.conf.get_switch("Logs.Verbose", False)
|
||||
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")
|
||||
|
||||
#Create lib dir
|
||||
fileutil.mkdir(OSUTIL.get_lib_dir(), mode=0o700)
|
||||
os.chdir(OSUTIL.get_lib_dir())
|
||||
#Init event reporter
|
||||
event_dir = os.path.join(self.distro.conf.get_lib_dir(), "events")
|
||||
event.init_event_reporter(event_dir)
|
||||
event.enable_unhandled_err_dump("WALA")
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ import time
|
|||
import pwd
|
||||
import fcntl
|
||||
import azurelinuxagent.logger as logger
|
||||
import azurelinuxagent.conf as conf
|
||||
from azurelinuxagent.exception import OSUtilError
|
||||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
import azurelinuxagent.utils.shellutil as shellutil
|
||||
|
@ -40,44 +42,14 @@ for all distros. Each concrete distro classes could overwrite default behavior
|
|||
if needed.
|
||||
"""
|
||||
|
||||
class OSUtilError(Exception):
|
||||
pass
|
||||
|
||||
class DefaultOSUtil(object):
|
||||
|
||||
def __init__(self):
|
||||
self.lib_dir = "/var/lib/waagent"
|
||||
self.ext_log_dir = "/var/log/azure"
|
||||
self.dvd_mount_point = "/mnt/cdrom/secure"
|
||||
self.ovf_env_file_path = "/mnt/cdrom/secure/ovf-env.xml"
|
||||
self.agent_pid_file_path = "/var/run/waagent.pid"
|
||||
self.passwd_file_path = "/etc/shadow"
|
||||
self.home = '/home'
|
||||
self.sshd_conf_file_path = '/etc/ssh/sshd_config'
|
||||
self.openssl_cmd = '/usr/bin/openssl'
|
||||
self.conf_file_path = '/etc/waagent.conf'
|
||||
self.agent_conf_file_path = '/etc/waagent.conf'
|
||||
self.selinux=None
|
||||
|
||||
def get_lib_dir(self):
|
||||
return self.lib_dir
|
||||
|
||||
def get_ext_log_dir(self):
|
||||
return self.ext_log_dir
|
||||
|
||||
def get_dvd_mount_point(self):
|
||||
return self.dvd_mount_point
|
||||
|
||||
def get_conf_file_path(self):
|
||||
return self.conf_file_path
|
||||
|
||||
def get_ovf_env_file_path_on_dvd(self):
|
||||
return self.ovf_env_file_path
|
||||
|
||||
def get_agent_pid_file_path(self):
|
||||
return self.agent_pid_file_path
|
||||
|
||||
def get_openssl_cmd(self):
|
||||
return self.openssl_cmd
|
||||
def get_agent_conf_file_path(self):
|
||||
return self.agent_conf_file_path
|
||||
|
||||
def get_userentry(self, username):
|
||||
try:
|
||||
|
@ -146,37 +118,37 @@ class DefaultOSUtil(object):
|
|||
|
||||
def del_root_password(self):
|
||||
try:
|
||||
passwd_content = fileutil.read_file(self.passwd_file_path)
|
||||
passwd_file_path = conf.get_passwd_file_path()
|
||||
passwd_content = fileutil.read_file(passwd_file_path)
|
||||
passwd = passwd_content.split('\n')
|
||||
new_passwd = [x for x in passwd if not x.startswith("root:")]
|
||||
new_passwd.insert(0, "root:*LOCK*:14600::::::")
|
||||
fileutil.write_file(self.passwd_file_path, "\n".join(new_passwd))
|
||||
fileutil.write_file(passwd_file_path, "\n".join(new_passwd))
|
||||
except IOError as e:
|
||||
raise OSUtilError("Failed to delete root password:{0}".format(e))
|
||||
|
||||
def get_home(self):
|
||||
return self.home
|
||||
|
||||
def get_pubkey_from_prv(self, file_name):
|
||||
cmd = "{0} rsa -in {1} -pubout 2>/dev/null".format(self.openssl_cmd,
|
||||
openssl_cmd = conf.get_openssl_cmd()
|
||||
cmd = "{0} rsa -in {1} -pubout 2>/dev/null".format(openssl_cmd,
|
||||
file_name)
|
||||
pub = shellutil.run_get_output(cmd)[1]
|
||||
return pub
|
||||
|
||||
def get_pubkey_from_crt(self, file_name):
|
||||
cmd = "{0} x509 -in {1} -pubkey -noout".format(self.openssl_cmd,
|
||||
file_name)
|
||||
openssl_cmd = conf.get_openssl_cmd()
|
||||
cmd = "{0} x509 -in {1} -pubkey -noout".format(openssl_cmd, file_name)
|
||||
pub = shellutil.run_get_output(cmd)[1]
|
||||
return pub
|
||||
|
||||
def _norm_path(self, filepath):
|
||||
home = self.get_home()
|
||||
home = conf.get_home_dir()
|
||||
# Expand HOME variable if present in path
|
||||
path = os.path.normpath(filepath.replace("$HOME", home))
|
||||
return path
|
||||
|
||||
def get_thumbprint_from_crt(self, file_name):
|
||||
cmd="{0} x509 -in {1} -fingerprint -noout".format(self.openssl_cmd,
|
||||
openssl_cmd = conf.get_openssl_cmd()
|
||||
cmd="{0} x509 -in {1} -fingerprint -noout".format(openssl_cmd,
|
||||
file_name)
|
||||
thumbprint = shellutil.run_get_output(cmd)[1]
|
||||
thumbprint = thumbprint.rstrip().split('=')[1].replace(':', '').upper()
|
||||
|
@ -190,7 +162,7 @@ class DefaultOSUtil(object):
|
|||
path = self._norm_path(path)
|
||||
dir_path = os.path.dirname(path)
|
||||
fileutil.mkdir(dir_path, mode=0o700, owner=username)
|
||||
lib_dir = self.get_lib_dir()
|
||||
lib_dir = conf.get_lib_dir()
|
||||
prv_path = os.path.join(lib_dir, thumbprint + '.prv')
|
||||
if not os.path.isfile(prv_path):
|
||||
raise OSUtilError("Can't find {0}.prv".format(thumbprint))
|
||||
|
@ -223,7 +195,7 @@ class DefaultOSUtil(object):
|
|||
raise OSUtilError("Bad public key: {0}".format(value))
|
||||
fileutil.write_file(path, value)
|
||||
elif thumbprint is not None:
|
||||
lib_dir = self.get_lib_dir()
|
||||
lib_dir = conf.get_lib_dir()
|
||||
crt_path = os.path.join(lib_dir, thumbprint + '.crt')
|
||||
if not os.path.isfile(crt_path):
|
||||
raise OSUtilError("Can't find {0}.crt".format(thumbprint))
|
||||
|
@ -280,11 +252,8 @@ class DefaultOSUtil(object):
|
|||
if self.is_selinux_system():
|
||||
return shellutil.run('chcon ' + con + ' ' + path)
|
||||
|
||||
def get_sshd_conf_file_path(self):
|
||||
return self.sshd_conf_file_path
|
||||
|
||||
def set_ssh_client_alive_interval(self):
|
||||
conf_file_path = self.get_sshd_conf_file_path()
|
||||
conf_file_path = conf.get_sshd_conf_file_path()
|
||||
conf = fileutil.read_file(conf_file_path).split("\n")
|
||||
textutil.set_ssh_config(conf, "ClientAliveInterval", "180")
|
||||
fileutil.write_file(conf_file_path, '\n'.join(conf))
|
||||
|
@ -292,7 +261,7 @@ class DefaultOSUtil(object):
|
|||
|
||||
def conf_sshd(self, disable_password):
|
||||
option = "no" if disable_password else "yes"
|
||||
conf_file_path = self.get_sshd_conf_file_path()
|
||||
conf_file_path = conf.get_sshd_conf_file_path()
|
||||
conf = fileutil.read_file(conf_file_path).split("\n")
|
||||
textutil.set_ssh_config(conf, "PasswordAuthentication", option)
|
||||
textutil.set_ssh_config(conf, "ChallengeResponseAuthentication", option)
|
||||
|
@ -309,7 +278,7 @@ class DefaultOSUtil(object):
|
|||
|
||||
def mount_dvd(self, max_retry=6, chk_err=True):
|
||||
dvd = self.get_dvd_device()
|
||||
mount_point = self.get_dvd_mount_point()
|
||||
mount_point = conf.get_dvd_mount_point()
|
||||
mountlist = shellutil.run_get_output("mount")[1]
|
||||
existing = self.get_mount_point(mountlist, dvd)
|
||||
if existing is not None: #Already mounted
|
||||
|
@ -332,7 +301,7 @@ class DefaultOSUtil(object):
|
|||
raise OSUtilError("Failed to mount dvd.")
|
||||
|
||||
def umount_dvd(self, chk_err=True):
|
||||
mount_point = self.get_dvd_mount_point()
|
||||
mount_point = conf.get_dvd_mount_point()
|
||||
retcode = self.umount(mount_point, chk_err=chk_err)
|
||||
if chk_err and retcode != 0:
|
||||
raise OSUtilError("Failed to umount dvd.")
|
||||
|
@ -390,13 +359,14 @@ class DefaultOSUtil(object):
|
|||
"""
|
||||
Create ssl certificate for https communication with endpoint server.
|
||||
"""
|
||||
openssl_cmd = conf.get_openssl_cmd()
|
||||
cmd = ("{0} req -x509 -nodes -subj /CN=LinuxTransport -days 32768 "
|
||||
"-newkey rsa:2048 -keyout {1} "
|
||||
"-out {2}").format(self.openssl_cmd, prv_file, crt_file)
|
||||
"-out {2}").format(openssl_cmd, prv_file, crt_file)
|
||||
shellutil.run(cmd)
|
||||
|
||||
def remove_rules_files(self, rules_files=__RULES_FILES__):
|
||||
lib_dir = self.get_lib_dir()
|
||||
lib_dir = conf.get_lib_dir()
|
||||
for src in rules_files:
|
||||
file_name = fileutil.base_name(src)
|
||||
dest = os.path.join(lib_dir, file_name)
|
||||
|
@ -407,7 +377,7 @@ class DefaultOSUtil(object):
|
|||
shutil.move(src, dest)
|
||||
|
||||
def restore_rules_files(self, rules_files=__RULES_FILES__):
|
||||
lib_dir = self.get_lib_dir()
|
||||
lib_dir = conf.get_lib_dir()
|
||||
for dest in rules_files:
|
||||
filename = fileutil.base_name(dest)
|
||||
src = os.path.join(lib_dir, filename)
|
||||
|
@ -649,4 +619,5 @@ class DefaultOSUtil(object):
|
|||
return int(ret[1])
|
||||
else:
|
||||
raise OSUtilError("Failed to get procerssor cores")
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
# 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 re
|
||||
import shutil
|
||||
import time
|
||||
import threading
|
||||
import azurelinuxagent.conf as conf
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.exception import ProtocolError, OSUtilError, \
|
||||
ProtocolNotFoundError
|
||||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
from azurelinuxagent.protocol.ovfenv import OvfEnv
|
||||
from azurelinuxagent.protocol.wire import WireProtocol
|
||||
from azurelinuxagent.protocol.metadata import MetadataProtocol
|
||||
|
||||
OVF_FILE_NAME = "ovf-env.xml"
|
||||
|
||||
#Tag file to indicate usage of metadata protocol
|
||||
TAG_FILE_NAME = "useMetadataEndpoint.tag"
|
||||
|
||||
PROTOCOL_FILE_NAME = "Protocol"
|
||||
|
||||
#MAX retry times for protocol probing
|
||||
MAX_RETRY = 60
|
||||
|
||||
PROBE_INTERVAL = 10
|
||||
|
||||
ENDPOINT_FILE_NAME = "WireServerEndpoint"
|
||||
|
||||
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
|
||||
self.lock = threading.Lock()
|
||||
|
||||
def copy_ovf_env(self):
|
||||
"""
|
||||
Copy ovf env file from dvd to hard disk.
|
||||
Remove password before save it to the disk
|
||||
"""
|
||||
dvd_mount_point = self.distro.osutil.get_dvd_mount_point()
|
||||
ovf_file_path_on_dvd = self.distro.osutil.get_ovf_env_file_path_on_dvd()
|
||||
tag_file_path_on_dvd = os.path.join(dvd_mount_point, TAG_FILE_NAME)
|
||||
try:
|
||||
self.distro.osutil.mount_dvd()
|
||||
ovfxml = fileutil.read_file(ovf_file_path_on_dvd, remove_bom=True)
|
||||
ovfenv = OvfEnv(ovfxml)
|
||||
ovfxml = re.sub("<UserPassword>.*?<", "<UserPassword>*<", ovfxml)
|
||||
ovf_file_path = os.path.join(conf.get_lib_dir(), OVF_FILE_NAME)
|
||||
fileutil.write_file(ovf_file_path, ovfxml)
|
||||
|
||||
if os.path.isfile(tag_file_path_on_dvd):
|
||||
logger.info("Found {0} in provisioning ISO", TAG_FILE_NAME)
|
||||
tag_file_path = os.path.join(conf.get_lib_dir(), TAG_FILE_NAME)
|
||||
shutil.copyfile(tag_file_path_on_dvd, tag_file_path)
|
||||
|
||||
except (OSUtilError, IOError) as e:
|
||||
raise ProtocolError(text(e))
|
||||
|
||||
try:
|
||||
self.distro.osutil.umount_dvd()
|
||||
self.distro.osutil.eject_dvd()
|
||||
except OSUtilError as e:
|
||||
logger.warn(text(e))
|
||||
|
||||
return ovfenv
|
||||
|
||||
def get_ovf_env(self):
|
||||
"""
|
||||
Load saved ovf-env.xml
|
||||
"""
|
||||
ovf_file_path = os.path.join(conf.get_lib_dir(), OVF_FILE_NAME)
|
||||
if os.path.isfile(ovf_file_path):
|
||||
xml_text = fileutil.read_file(ovf_file_path)
|
||||
return OvfEnv(xml_text)
|
||||
else:
|
||||
raise ProtocolError("ovf-env.xml is missing.")
|
||||
|
||||
def _get_wireserver_endpoint(self):
|
||||
try:
|
||||
file_path = os.path.join(conf.get_lib_dir(), ENDPOINT_FILE_NAME)
|
||||
return fileutil.read_file(file_path)
|
||||
except IOError as e:
|
||||
raise OSUtilError(text(e))
|
||||
|
||||
def _set_wireserver_endpoint(self, endpoint):
|
||||
try:
|
||||
file_path = os.path.join(conf.get_lib_dir(), ENDPOINT_FILE_NAME)
|
||||
fileutil.write_file(file_path, endpoint)
|
||||
except IOError as e:
|
||||
raise OSUtilError(text(e))
|
||||
|
||||
def _detect_wire_protocol(self):
|
||||
endpoint = self.distro.dhcp_handler.endpoint
|
||||
if endpoint is None:
|
||||
logger.info("WireServer endpoint is not found. Rerun dhcp handler")
|
||||
self.distro.dhcp_handler.run()
|
||||
endpoint = self.distro.dhcp_handler.endpoint
|
||||
|
||||
try:
|
||||
protocol = WireProtocol(self.distro.osutil, endpoint)
|
||||
protocol.detect()
|
||||
self._set_wireserver_endpoint(endpoint)
|
||||
return protocol
|
||||
except ProtocolError as e:
|
||||
logger.info("WireServer is not responding. Rerun dhcp handler")
|
||||
self.distro.dhcp_handler.run()
|
||||
raise e
|
||||
|
||||
def _detect_metadata_protocol(self):
|
||||
protocol = MetadataProtocol(self.distro.osutil)
|
||||
protocol.detect()
|
||||
return protocol
|
||||
|
||||
def _detect_protocol(self, protocols):
|
||||
"""
|
||||
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)
|
||||
for retry in range(0, MAX_RETRY):
|
||||
for protocol in protocols:
|
||||
try:
|
||||
if protocol == WireProtocol.__name__:
|
||||
return self._detect_wire_protocol()
|
||||
|
||||
if protocol == MetadataProtocol.__name__:
|
||||
return self._detect_metadata_protocol
|
||||
|
||||
except ProtocolError as e:
|
||||
logger.info("Protocol endpoint not found: {0}, {1}",
|
||||
protocol, e)
|
||||
|
||||
if retry < MAX_RETRY -1:
|
||||
logger.info("Retry detect protocols: retry={0}", retry)
|
||||
time.sleep(PROBE_INTERVAL)
|
||||
raise ProtocolNotFoundError("No protocol found.")
|
||||
|
||||
def _get_protocol(self):
|
||||
"""
|
||||
Get protocol instance based on previous detecting result.
|
||||
"""
|
||||
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")
|
||||
|
||||
protocol_name = fileutil.read_file(protocol_file_path)
|
||||
if protocol_name == WireProtocol.__name__:
|
||||
endpoint = self._get_wireserver_endpoint()
|
||||
return WireProtocol(self.distro.osutil, endpoint)
|
||||
elif protocol_name == MetadataProtocol.__name__:
|
||||
return MetadataProtocol(self.distro.osutil)
|
||||
else:
|
||||
raise ProtocolNotFoundError(("Unknown protocol: {0}"
|
||||
"").format(protocol_name))
|
||||
|
||||
def detect_protocol(self):
|
||||
"""
|
||||
Detect protocol by endpoints
|
||||
|
||||
:returns: protocol instance
|
||||
"""
|
||||
logger.info("Detect protocol endpoints")
|
||||
protocols = [WireProtocol.__name__, MetadataProtocol.__name__]
|
||||
self.lock.acquire()
|
||||
try:
|
||||
if self.protocol is None:
|
||||
self.protocol = self._detect_protocol(protocols)
|
||||
return self.protocol
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
def detect_protocol_by_file(self):
|
||||
"""
|
||||
Detect protocol by tag file.
|
||||
|
||||
If a file "useMetadataEndpoint.tag" is found on provision iso,
|
||||
metedata protocol will be used. No need to probe for wire protocol
|
||||
|
||||
:returns: protocol instance
|
||||
"""
|
||||
logger.info("Detect protocol by file")
|
||||
self.lock.acquire()
|
||||
try:
|
||||
tag_file_path = os.path.join(self.distro.conf.get_lib_dir(),
|
||||
TAG_FILE_NAME)
|
||||
if self.protocol is None:
|
||||
protocols = []
|
||||
if os.path.isfile(tag_file_path):
|
||||
protocols.append(MetadataProtocol.__name__)
|
||||
else:
|
||||
protocols.append(WireProtocol.__name__)
|
||||
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()
|
||||
return self.protocol
|
||||
finally:
|
||||
self.lock.release()
|
||||
return self.protocol
|
||||
|
|
@ -24,11 +24,8 @@ import azurelinuxagent.logger as logger
|
|||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.conf as conf
|
||||
from azurelinuxagent.event import add_event, WALAEventOperation
|
||||
from azurelinuxagent.exception import ProvisionError
|
||||
from azurelinuxagent.utils.osutil import OSUTIL, OSUtilError
|
||||
from azurelinuxagent.protocol.factory import PROT_FACTORY, ProvisionStatus, \
|
||||
ProtocolError
|
||||
import azurelinuxagent.protocol.ovfenv as ovf
|
||||
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
|
||||
|
||||
|
@ -36,49 +33,30 @@ CUSTOM_DATA_FILE="CustomData"
|
|||
|
||||
class ProvisionHandler(object):
|
||||
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
|
||||
def report_event(self, message, is_success=False):
|
||||
add_event(name="WALA", message=message, is_success=is_success,
|
||||
op=WALAEventOperation.Provision)
|
||||
|
||||
def report_not_ready(self, protocol, sub_status, description):
|
||||
status = ProvisionStatus(status="NotReady", subStatus=sub_status,
|
||||
description=description)
|
||||
try:
|
||||
protocol.report_provision_status(status)
|
||||
except ProtocolError as e:
|
||||
self.report_event(text(e))
|
||||
|
||||
def report_ready(self, protocol, thumbprint=None):
|
||||
status = ProvisionStatus(status="Ready")
|
||||
status.properties.certificateThumbprint = thumbprint
|
||||
try:
|
||||
protocol.report_provision_status(status)
|
||||
except ProtocolError as e:
|
||||
self.report_event(text(e))
|
||||
|
||||
def process(self):
|
||||
def run(self):
|
||||
#If provision is not enabled, return
|
||||
if not conf.get_switch("Provisioning.Enabled", True):
|
||||
if not conf.get_provision_enabled():
|
||||
logger.info("Provisioning is disabled. Skip.")
|
||||
return
|
||||
|
||||
provisioned = os.path.join(OSUTIL.get_lib_dir(), "provisioned")
|
||||
provisioned = os.path.join(conf.get_lib_dir(), "provisioned")
|
||||
if os.path.isfile(provisioned):
|
||||
return
|
||||
|
||||
logger.info("Run provision handler.")
|
||||
logger.info("Copy ovf-env.xml.")
|
||||
try:
|
||||
ovfenv = ovf.copy_ovf_env()
|
||||
ovfenv = self.distro.protocol_util.copy_ovf_env()
|
||||
except ProtocolError as e:
|
||||
self.report_event("Failed to copy ovf-env.xml: {0}".format(e))
|
||||
return
|
||||
|
||||
protocol = PROT_FACTORY.detect_protocol_by_file()
|
||||
self.report_not_ready(protocol, "Provisioning", "Starting")
|
||||
self.distro.protocol_util.detect_protocol_by_file()
|
||||
|
||||
self.report_not_ready("Provisioning", "Starting")
|
||||
|
||||
try:
|
||||
logger.info("Start provisioning")
|
||||
|
@ -88,16 +66,16 @@ class ProvisionHandler(object):
|
|||
logger.info("Finished provisioning")
|
||||
except ProvisionError as e:
|
||||
logger.error("Provision failed: {0}", e)
|
||||
self.report_not_ready(protocol, "ProvisioningFailed", text(e))
|
||||
self.report_not_ready("ProvisioningFailed", text(e))
|
||||
self.report_event(text(e))
|
||||
return
|
||||
|
||||
self.report_ready(protocol, thumbprint)
|
||||
self.report_ready(thumbprint)
|
||||
self.report_event("Provision succeed", is_success=True)
|
||||
|
||||
def reg_ssh_host_key(self):
|
||||
keypair_type = conf.get("Provisioning.SshHostKeyPairType", "rsa")
|
||||
if conf.get_switch("Provisioning.RegenerateSshHostKeyPair"):
|
||||
keypair_type = conf.get_ssh_host_keypair_type()
|
||||
if conf.get_regenerate_ssh_host_key():
|
||||
shellutil.run("rm -f /etc/ssh/ssh_host_*key*")
|
||||
shellutil.run(("ssh-keygen -N '' -t {0} -f /etc/ssh/ssh_host_{1}_key"
|
||||
"").format(keypair_type, keypair_type))
|
||||
|
@ -117,66 +95,89 @@ class ProvisionHandler(object):
|
|||
logger.info("Handle ovf-env.xml.")
|
||||
try:
|
||||
logger.info("Set host name.")
|
||||
OSUTIL.set_hostname(ovfenv.hostname)
|
||||
self.distro.osutil.set_hostname(ovfenv.hostname)
|
||||
|
||||
logger.info("Publish host name.")
|
||||
OSUTIL.publish_hostname(ovfenv.hostname)
|
||||
self.distro.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()
|
||||
|
||||
if conf.get_switch("Provisioning.DeleteRootPassword"):
|
||||
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")
|
||||
OSUTIL.useradd(ovfenv.username)
|
||||
self.distro.osutil.useradd(ovfenv.username)
|
||||
|
||||
if ovfenv.user_password is not None:
|
||||
logger.info("Set user password.")
|
||||
crypt_id = conf.get("Provision.PasswordCryptId", "6")
|
||||
salt_len = conf.get_int("Provision.PasswordCryptSaltLength", 10)
|
||||
OSUTIL.chpasswd(ovfenv.username, ovfenv.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,
|
||||
crypt_id=crypt_id, salt_len=salt_len)
|
||||
|
||||
logger.info("Configure sudoer")
|
||||
OSUTIL.conf_sudoer(ovfenv.username, ovfenv.user_password is None)
|
||||
self.distro.osutil.conf_sudoer(ovfenv.username, ovfenv.user_password is None)
|
||||
|
||||
logger.info("Configure sshd")
|
||||
OSUTIL.conf_sshd(ovfenv.disable_ssh_password_auth)
|
||||
self.distro.osutil.conf_sshd(ovfenv.disable_ssh_password_auth)
|
||||
|
||||
#Disable selinux temporary
|
||||
sel = OSUTIL.is_selinux_enforcing()
|
||||
sel = self.distro.osutil.is_selinux_enforcing()
|
||||
if sel:
|
||||
OSUTIL.set_selinux_enforce(0)
|
||||
self.distro.osutil.set_selinux_enforce(0)
|
||||
|
||||
self.deploy_ssh_pubkeys(ovfenv)
|
||||
self.deploy_ssh_keypairs(ovfenv)
|
||||
|
||||
if sel:
|
||||
OSUTIL.set_selinux_enforce(1)
|
||||
self.distro.osutil.set_selinux_enforce(1)
|
||||
|
||||
OSUTIL.restart_ssh_service()
|
||||
self.distro.osutil.restart_ssh_service()
|
||||
|
||||
def save_customdata(self, ovfenv):
|
||||
logger.info("Save custom data")
|
||||
customdata = ovfenv.customdata
|
||||
if customdata is None:
|
||||
return
|
||||
lib_dir = OSUTIL.get_lib_dir()
|
||||
lib_dir = conf.get_lib_dir()
|
||||
fileutil.write_file(os.path.join(lib_dir, CUSTOM_DATA_FILE),
|
||||
OSUTIL.decode_customdata(customdata))
|
||||
self.distro.osutil.decode_customdata(customdata))
|
||||
|
||||
def deploy_ssh_pubkeys(self, ovfenv):
|
||||
for pubkey in ovfenv.ssh_pubkeys:
|
||||
logger.info("Deploy ssh public key.")
|
||||
OSUTIL.deploy_ssh_pubkey(ovfenv.username, pubkey)
|
||||
self.distro.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.")
|
||||
OSUTIL.deploy_ssh_keypair(ovfenv.username, keypair)
|
||||
self.distro.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,
|
||||
op=WALAEventOperation.Provision)
|
||||
|
||||
def report_not_ready(self, sub_status, description):
|
||||
status = ProvisionStatus(status="NotReady", subStatus=sub_status,
|
||||
description=description)
|
||||
try:
|
||||
protocol = self.distro.protocol_util.get_protocol()
|
||||
protocol.report_provision_status(status)
|
||||
except ProtocolError as e:
|
||||
self.report_event(text(e))
|
||||
|
||||
def report_ready(self, thumbprint=None):
|
||||
status = ProvisionStatus(status="Ready")
|
||||
status.properties.certificateThumbprint = thumbprint
|
||||
try:
|
||||
protocol = self.distro.protocol_util.get_protocol()
|
||||
protocol.report_provision_status(status)
|
||||
except ProtocolError as e:
|
||||
self.report_event(text(e))
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ import threading
|
|||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.conf as conf
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
from azurelinuxagent.event import add_event, WALAEventOperation
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
import azurelinuxagent.utils.shellutil as shellutil
|
||||
|
@ -41,8 +40,8 @@ For additional details to please refer to the MSDN documentation at : http://msd
|
|||
"""
|
||||
|
||||
class ResourceDiskHandler(object):
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
|
||||
def start_activate_resource_disk(self):
|
||||
disk_thread = threading.Thread(target = self.run)
|
||||
|
@ -50,17 +49,17 @@ class ResourceDiskHandler(object):
|
|||
|
||||
def run(self):
|
||||
mount_point = None
|
||||
if conf.get_switch("ResourceDisk.Format", False):
|
||||
if conf.get_resourcedisk_format():
|
||||
mount_point = self.activate_resource_disk()
|
||||
if mount_point is not None and \
|
||||
conf.get_switch("ResourceDisk.EnableSwap", False):
|
||||
conf.get_resourcedisk_enable_swap():
|
||||
self.enable_swap(mount_point)
|
||||
|
||||
def activate_resource_disk(self):
|
||||
logger.info("Activate resource disk")
|
||||
try:
|
||||
mount_point = conf.get("ResourceDisk.MountPoint", "/mnt/resource")
|
||||
fs = conf.get("ResourceDisk.Filesystem", "ext3")
|
||||
mount_point = conf.get_resourcedisk_mountpoint()
|
||||
fs = conf.get_resourcedisk_filesystem()
|
||||
mount_point = self.mount_resource_disk(mount_point, fs)
|
||||
warning_file = os.path.join(mount_point, DATALOSS_WARNING_FILE_NAME)
|
||||
try:
|
||||
|
@ -76,19 +75,19 @@ class ResourceDiskHandler(object):
|
|||
def enable_swap(self, mount_point):
|
||||
logger.info("Enable swap")
|
||||
try:
|
||||
size_mb = conf.get_int("ResourceDisk.SwapSizeMB", 0)
|
||||
size_mb = conf.get_resourcedisk_swap_size_mb()
|
||||
self.create_swap_space(mount_point, size_mb)
|
||||
except ResourceDiskError as e:
|
||||
logger.error("Failed to enable swap {0}", e)
|
||||
|
||||
def mount_resource_disk(self, mount_point, fs):
|
||||
device = OSUTIL.device_for_ide_port(1)
|
||||
device = self.distro.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 = OSUTIL.get_mount_point(mountlist, device)
|
||||
existing = self.distro.osutil.get_mount_point(mountlist, device)
|
||||
|
||||
if(existing):
|
||||
logger.info("Resource disk {0}1 is already mounted", device)
|
||||
|
|
|
@ -20,30 +20,29 @@
|
|||
import os
|
||||
import subprocess
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
|
||||
VMM_CONF_FILE_NAME = "linuxosconfiguration.xml"
|
||||
VMM_STARTUP_SCRIPT_NAME= "install"
|
||||
|
||||
class ScvmmHandler(object):
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
|
||||
def detect_scvmm_env(self):
|
||||
logger.info("Detecting Microsoft System Center VMM Environment")
|
||||
OSUTIL.mount_dvd(max_retry=1, chk_err=False)
|
||||
mount_point = OSUTIL.get_dvd_mount_point()
|
||||
self.distro.osutil.mount_dvd(max_retry=1, chk_err=False)
|
||||
mount_point = self.distro.osutil.get_dvd_mount_point()
|
||||
found = os.path.isfile(os.path.join(mount_point, VMM_CONF_FILE_NAME))
|
||||
if found:
|
||||
self.start_scvmm_agent()
|
||||
else:
|
||||
OSUTIL.umount_dvd(chk_err=False)
|
||||
self.distro.osutil.umount_dvd(chk_err=False)
|
||||
return found
|
||||
|
||||
def start_scvmm_agent(self):
|
||||
logger.info("Starting Microsoft System Center VMM Initialization "
|
||||
"Process")
|
||||
mount_point = OSUTIL.get_dvd_mount_point()
|
||||
mount_point = self.distro.osutil.get_dvd_mount_point()
|
||||
startup_script = os.path.join(mount_point, VMM_STARTUP_SCRIPT_NAME)
|
||||
subprocess.Popen(["/bin/bash", startup_script, "-p " + mount_point])
|
||||
|
||||
|
|
|
@ -16,31 +16,51 @@
|
|||
#
|
||||
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.metadata import DISTRO_NAME
|
||||
import azurelinuxagent.distro.default.loader as default_loader
|
||||
from azurelinuxagent.utils.textutil import Version
|
||||
from azurelinuxagent.metadata 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
|
||||
|
||||
|
||||
def get_distro_loader():
|
||||
try:
|
||||
logger.verb("Loading distro implemetation from: {0}", DISTRO_NAME)
|
||||
pkg_name = "azurelinuxagent.distro.{0}.loader".format(DISTRO_NAME)
|
||||
return __import__(pkg_name, fromlist="loader")
|
||||
except (ImportError, ValueError):
|
||||
def get_distro():
|
||||
if DISTRO_NAME == "ubuntu":
|
||||
if Version(DISTRO_VERSION) == Version("12.04") or \
|
||||
Version(DISTRO_VERSION) == Version("12.10"):
|
||||
return Ubuntu12Distro()
|
||||
elif Version(DISTRO_VERSION) == Version("14.04") or \
|
||||
Version(DISTRO_VERSION) == Version("14.10"):
|
||||
return Ubuntu14Distro()
|
||||
elif DISTRO_FULL_NAME == "Snappy Ubuntu Core":
|
||||
return UbuntuSnappyDistro()
|
||||
else:
|
||||
return UbuntuDistro()
|
||||
if DISTRO_NAME == "coreos":
|
||||
return CoreOSDistro()
|
||||
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()
|
||||
else:
|
||||
return SUSEDistro()
|
||||
elif DISTRO_NAME == "debian":
|
||||
return DebianDistro()
|
||||
elif DISTRO_NAME == "redhat" or DISTRO_NAME == "centos" or \
|
||||
DISTRO_NAME == "oracle":
|
||||
if Version(DISTRO_VERSION) < Version(7):
|
||||
return Redhat6xDistro()
|
||||
else:
|
||||
return RedhatDistro()
|
||||
else:
|
||||
logger.warn("Unable to load distro implemetation for {0}.", DISTRO_NAME)
|
||||
logger.warn("Use default distro implemetation instead.")
|
||||
return default_loader
|
||||
|
||||
DISTRO_LOADER = get_distro_loader()
|
||||
|
||||
def get_osutil():
|
||||
try:
|
||||
return DISTRO_LOADER.get_osutil()
|
||||
except AttributeError:
|
||||
return default_loader.get_osutil()
|
||||
|
||||
def get_handlers():
|
||||
try:
|
||||
return DISTRO_LOADER.get_handlers()
|
||||
except AttributeError:
|
||||
return default_loader.get_handlers()
|
||||
return DefaultDistro()
|
||||
|
||||
|
|
|
@ -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+
|
||||
#
|
||||
|
|
@ -17,13 +17,16 @@
|
|||
# Requires Python 2.4+ and Openssl 1.0+
|
||||
#
|
||||
|
||||
from azurelinuxagent.distro.ubuntu.provision import UbuntuProvisionHandler
|
||||
from azurelinuxagent.distro.ubuntu.deprovision import UbuntuDeprovisionHandler
|
||||
from azurelinuxagent.distro.default.handlerFactory import DefaultHandlerFactory
|
||||
from azurelinuxagent.distro.default.distro import DefaultDistro
|
||||
from azurelinuxagent.distro.redhat.osutil import RedhatOSUtil, Redhat6xOSUtil
|
||||
from azurelinuxagent.distro.coreos.deprovision import CoreOSDeprovisionHandler
|
||||
|
||||
class UbuntuHandlerFactory(DefaultHandlerFactory):
|
||||
class Redhat6xDistro(DefaultDistro):
|
||||
def __init__(self):
|
||||
super(UbuntuHandlerFactory, self).__init__()
|
||||
self.provision_handler = UbuntuProvisionHandler(self)
|
||||
self.deprovision_handler = UbuntuDeprovisionHandler(self)
|
||||
super(Redhat6xDistro, self).__init__()
|
||||
self.osutil = Redhat6xOSUtil()
|
||||
|
||||
class RedhatDistro(DefaultDistro):
|
||||
def __init__(self):
|
||||
super(RedhatDistro, self).__init__()
|
||||
self.osutil = RedhatOSUtil()
|
|
@ -1,28 +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.metadata import DISTRO_NAME, DISTRO_VERSION
|
||||
|
||||
def get_osutil():
|
||||
from azurelinuxagent.distro.redhat.osutil import Redhat6xOSUtil, RedhatOSUtil
|
||||
if DISTRO_VERSION < "7":
|
||||
return Redhat6xOSUtil()
|
||||
else:
|
||||
return RedhatOSUtil()
|
||||
|
|
@ -17,12 +17,16 @@
|
|||
# Requires Python 2.4+ and Openssl 1.0+
|
||||
#
|
||||
|
||||
def get_osutil():
|
||||
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
|
||||
return DefaultOSUtil()
|
||||
from azurelinuxagent.distro.default.distro import DefaultDistro
|
||||
from azurelinuxagent.distro.suse.osutil import SUSE11OSUtil, SUSEOSUtil
|
||||
|
||||
def get_handlers():
|
||||
from azurelinuxagent.distro.default.handlerFactory import DefaultHandlerFactory
|
||||
return DefaultHandlerFactory()
|
||||
class SUSE11Distro(DefaultDistro):
|
||||
def __init__(self):
|
||||
super(SUSE11Distro, self).__init__()
|
||||
self.osutil = SUSE11Distro()
|
||||
|
||||
class SUSEDistro(DefaultDistro):
|
||||
def __init__(self):
|
||||
super(SUSEDistro, self).__init__()
|
||||
self.osutil = SUSEOSUtil()
|
||||
|
|
@ -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.metadata import DISTRO_NAME, DISTRO_VERSION, DISTRO_FULL_NAME
|
||||
|
||||
def get_osutil():
|
||||
from azurelinuxagent.distro.suse.osutil import SUSE11OSUtil, SUSEOSUtil
|
||||
if DISTRO_FULL_NAME=='SUSE Linux Enterprise Server' and DISTRO_VERSION < '12' \
|
||||
or DISTRO_FULL_NAME == 'openSUSE' and DISTRO_VERSION < '13.2':
|
||||
return SUSE11OSUtil()
|
||||
else:
|
||||
return SUSEOSUtil()
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
# 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,40 +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.metadata import DISTRO_NAME, DISTRO_VERSION, DISTRO_FULL_NAME
|
||||
|
||||
def get_osutil():
|
||||
from azurelinuxagent.distro.ubuntu.osutil import Ubuntu1204OSUtil, \
|
||||
UbuntuOSUtil, \
|
||||
Ubuntu14xOSUtil, \
|
||||
UbuntuSnappyOSUtil
|
||||
|
||||
if DISTRO_VERSION == "12.04":
|
||||
return Ubuntu1204OSUtil()
|
||||
elif DISTRO_VERSION == "14.04" or DISTRO_VERSION == "14.10":
|
||||
return Ubuntu14xOSUtil()
|
||||
elif DISTRO_FULL_NAME == "Snappy Ubuntu Core":
|
||||
return UbuntuSnappyOSUtil()
|
||||
else:
|
||||
return UbuntuOSUtil()
|
||||
|
||||
def get_handlers():
|
||||
from azurelinuxagent.distro.ubuntu.handlerFactory import UbuntuHandlerFactory
|
||||
return UbuntuHandlerFactory()
|
||||
|
|
@ -31,9 +31,9 @@ import azurelinuxagent.utils.shellutil as shellutil
|
|||
import azurelinuxagent.utils.textutil as textutil
|
||||
from azurelinuxagent.distro.default.osutil import DefaultOSUtil
|
||||
|
||||
class Ubuntu14xOSUtil(DefaultOSUtil):
|
||||
class Ubuntu14OSUtil(DefaultOSUtil):
|
||||
def __init__(self):
|
||||
super(Ubuntu14xOSUtil, self).__init__()
|
||||
super(Ubuntu14OSUtil, self).__init__()
|
||||
|
||||
def start_network(self):
|
||||
return shellutil.run("service networking start", chk_err=False)
|
||||
|
@ -44,16 +44,16 @@ class Ubuntu14xOSUtil(DefaultOSUtil):
|
|||
def start_agent_service(self):
|
||||
return shellutil.run("service walinuxagent start", chk_err=False)
|
||||
|
||||
class Ubuntu1204OSUtil(Ubuntu14xOSUtil):
|
||||
class Ubuntu12OSUtil(Ubuntu14OSUtil):
|
||||
def __init__(self):
|
||||
super(Ubuntu1204OSUtil, self).__init__()
|
||||
super(Ubuntu12OSUtil, self).__init__()
|
||||
|
||||
#Override
|
||||
def get_dhcp_pid(self):
|
||||
ret= shellutil.run_get_output("pidof dhclient3")
|
||||
return ret[1] if ret[0] == 0 else None
|
||||
|
||||
class UbuntuOSUtil(Ubuntu14xOSUtil):
|
||||
class UbuntuOSUtil(Ubuntu14OSUtil):
|
||||
def __init__(self):
|
||||
super(UbuntuOSUtil, self).__init__()
|
||||
|
||||
|
@ -63,7 +63,7 @@ class UbuntuOSUtil(Ubuntu14xOSUtil):
|
|||
def unregister_agent_service(self):
|
||||
return shellutil.run("systemctl mask walinuxagent", chk_err=False)
|
||||
|
||||
class UbuntuSnappyOSUtil(Ubuntu14xOSUtil):
|
||||
class UbuntuSnappyOSUtil(Ubuntu14OSUtil):
|
||||
def __init__(self):
|
||||
super(UbuntuSnappyOSUtil, self).__init__()
|
||||
self.conf_file_path = '/apps/walinuxagent/current/waagent.conf'
|
||||
|
|
|
@ -22,11 +22,9 @@ import time
|
|||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.conf as conf
|
||||
from azurelinuxagent.protocol.factory import PROT_FACTORY
|
||||
import azurelinuxagent.protocol.ovfenv as ovf
|
||||
import azurelinuxagent.protocol.ovfenv as ovfenv
|
||||
from azurelinuxagent.event import add_event, WALAEventOperation
|
||||
from azurelinuxagent.exception import ProvisionError
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
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
|
||||
|
@ -35,25 +33,25 @@ from azurelinuxagent.distro.default.provision import ProvisionHandler
|
|||
On ubuntu image, provision could be disabled.
|
||||
"""
|
||||
class UbuntuProvisionHandler(ProvisionHandler):
|
||||
def __init__(self, handlers):
|
||||
self.handlers = handlers
|
||||
def __init__(self, distro):
|
||||
self.distro = distro
|
||||
|
||||
def process(self):
|
||||
#If provision is enabled, run default provision handler
|
||||
if conf.get_switch("Provisioning.Enabled", False):
|
||||
if conf.get_provision_enabled():
|
||||
super(UbuntuProvisionHandler, self).process()
|
||||
return
|
||||
|
||||
logger.info("run Ubuntu provision handler")
|
||||
provisioned = os.path.join(OSUTIL.get_lib_dir(), "provisioned")
|
||||
provisioned = os.path.join(conf.get_lib_dir(), "provisioned")
|
||||
if os.path.isfile(provisioned):
|
||||
return
|
||||
|
||||
logger.info("Waiting cloud-init to copy ovf-env.xml.")
|
||||
self.wait_for_ovfenv()
|
||||
|
||||
protocol = PROT_FACTORY.detect_protocol_by_file()
|
||||
self.report_not_ready(protocol, "Provisioning", "Starting")
|
||||
protocol = self.distro.protocol_util.detect_protocol_by_file()
|
||||
self.report_not_ready("Provisioning", "Starting")
|
||||
logger.info("Sleep 15 seconds to prevent throttling")
|
||||
time.sleep(15) #Sleep to prevent throttling
|
||||
try:
|
||||
|
@ -64,31 +62,32 @@ class UbuntuProvisionHandler(ProvisionHandler):
|
|||
|
||||
except ProvisionError as e:
|
||||
logger.error("Provision failed: {0}", e)
|
||||
self.report_not_ready(protocol, "ProvisioningFailed", text(e))
|
||||
self.report_not_ready("ProvisioningFailed", text(e))
|
||||
self.report_event(text(e))
|
||||
return
|
||||
|
||||
self.report_ready(protocol, thumbprint)
|
||||
self.report_ready(thumbprint)
|
||||
self.report_event("Provision succeed", is_success=True)
|
||||
|
||||
def wait_for_ovfenv(self, max_retry=60):
|
||||
"""
|
||||
Wait for cloud-init to copy ovf-env.xml file from provision ISO
|
||||
"""
|
||||
ovf_file_path = os.path.join(OSUTIL.get_lib_dir(), ovf.OVF_FILE_NAME)
|
||||
for retry in range(0, max_retry):
|
||||
if os.path.isfile(ovf_file_path):
|
||||
try:
|
||||
self.distro.protocol_util.get_ovf_env()
|
||||
return
|
||||
if retry < max_retry - 1:
|
||||
logger.info("Wait for cloud-init to copy ovf-env.xml")
|
||||
time.sleep(5)
|
||||
except ProtocolError:
|
||||
if retry < max_retry - 1:
|
||||
logger.info("Wait for cloud-init to copy ovf-env.xml")
|
||||
time.sleep(5)
|
||||
raise ProvisionError("ovf-env.xml is not copied")
|
||||
|
||||
def wait_for_ssh_host_key(self, max_retry=60):
|
||||
"""
|
||||
Wait for cloud-init to generate ssh host key
|
||||
"""
|
||||
kepair_type = conf.get("Provisioning.SshHostKeyPairType", "rsa")
|
||||
kepair_type = conf.get_ssh_host_keypair_type()
|
||||
path = '/etc/ssh/ssh_host_{0}_key'.format(kepair_type)
|
||||
for retry in range(0, max_retry):
|
||||
if os.path.isfile(path):
|
||||
|
|
|
@ -25,15 +25,15 @@ import datetime
|
|||
import threading
|
||||
import platform
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.exception import EventError, ProtocolError
|
||||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.protocol as prot
|
||||
from azurelinuxagent.protocol.factory import PROT_FACTORY
|
||||
from azurelinuxagent.protocol.restapi import TelemetryEventParam, \
|
||||
TelemetryEventList, \
|
||||
TelemetryEvent, \
|
||||
set_properties, get_properties
|
||||
from azurelinuxagent.metadata import DISTRO_NAME, DISTRO_VERSION, \
|
||||
DISTRO_CODE_NAME, AGENT_VERSION
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
|
||||
class EventError(Exception):
|
||||
pass
|
||||
|
||||
class WALAEventOperation:
|
||||
HeartBeat="HeartBeat"
|
||||
|
@ -48,132 +48,60 @@ class WALAEventOperation:
|
|||
ActivateResourceDisk="ActivateResourceDisk"
|
||||
UnhandledError="UnhandledError"
|
||||
|
||||
class EventMonitor(object):
|
||||
class EventReporter(object):
|
||||
def __init__(self):
|
||||
self.sysinfo = []
|
||||
self.event_dir = os.path.join(OSUTIL.get_lib_dir(), "events")
|
||||
self.event_dir = None
|
||||
|
||||
def init_sysinfo(self):
|
||||
osversion = "{0}:{1}-{2}-{3}:{4}".format(platform.system(),
|
||||
DISTRO_NAME,
|
||||
DISTRO_VERSION,
|
||||
DISTRO_CODE_NAME,
|
||||
platform.release())
|
||||
def save_event(self, data):
|
||||
if not os.path.exists(self.event_dir):
|
||||
os.mkdir(self.event_dir)
|
||||
os.chmod(self.event_dir, 0o700)
|
||||
if len(os.listdir(self.event_dir)) > 1000:
|
||||
raise EventError("Too many files under: {0}", self.event_dir)
|
||||
|
||||
self.sysinfo.append(prot.TelemetryEventParam("OSVersion", osversion))
|
||||
self.sysinfo.append(prot.TelemetryEventParam("GAVersion",
|
||||
AGENT_VERSION))
|
||||
self.sysinfo.append(prot.TelemetryEventParam("RAM",
|
||||
OSUTIL.get_total_mem()))
|
||||
self.sysinfo.append(prot.TelemetryEventParam("Processors",
|
||||
OSUTIL.get_processor_cores()))
|
||||
filename = os.path.join(self.event_dir, text(int(time.time()*1000000)))
|
||||
try:
|
||||
protocol = PROT_FACTORY.get_protocol()
|
||||
vminfo = protocol.get_vminfo()
|
||||
self.sysinfo.append(prot.TelemetryEventParam("VMName",
|
||||
vminfo.vmName))
|
||||
#TODO add other system info like, subscription id, etc.
|
||||
except prot.ProtocolError as e:
|
||||
logger.warn("Failed to get vm info: {0}", e)
|
||||
|
||||
def start(self):
|
||||
event_thread = threading.Thread(target = self.run)
|
||||
event_thread.setDaemon(True)
|
||||
event_thread.start()
|
||||
|
||||
def collect_event(self, evt_file_name):
|
||||
try:
|
||||
logger.verb("Found event file: {0}", evt_file_name)
|
||||
with open(evt_file_name, "rb") as evt_file:
|
||||
#if fail to open or delete the file, throw exception
|
||||
json_str = evt_file.read().decode("utf-8",'ignore')
|
||||
logger.verb("Processed event file: {0}", evt_file_name)
|
||||
os.remove(evt_file_name)
|
||||
return json_str
|
||||
with open(filename+".tmp",'wb+') as hfile:
|
||||
hfile.write(data.encode("utf-8"))
|
||||
os.rename(filename+".tmp", filename+".tld")
|
||||
except IOError as e:
|
||||
msg = "Failed to process {0}, {1}".format(evt_file_name, e)
|
||||
raise EventError(msg)
|
||||
raise EventError("Failed to write events to file:{0}", e)
|
||||
|
||||
def collect_and_send_events(self):
|
||||
event_list = prot.TelemetryEventList()
|
||||
event_files = os.listdir(self.event_dir)
|
||||
for event_file in event_files:
|
||||
if not event_file.endswith(".tld"):
|
||||
continue
|
||||
event_file_path = os.path.join(self.event_dir, event_file)
|
||||
try:
|
||||
data_str = self.collect_event(event_file_path)
|
||||
except EventError as e:
|
||||
logger.error("{0}", e)
|
||||
continue
|
||||
try:
|
||||
data = json.loads(data_str)
|
||||
except ValueError as e:
|
||||
logger.verb(data_str)
|
||||
logger.verb("Failed to decode json event file: {0}", e)
|
||||
continue
|
||||
def add_event(self, name, op="", is_success=True, duration=0, version="1.0",
|
||||
message="", evt_type="", is_internal=False):
|
||||
log = logger.info if is_success else logger.error
|
||||
log("Event: name={0}, op={1}, message={2}", name, op, message)
|
||||
event = TelemetryEvent(1, "69B669B9-4AF8-4C50-BDC4-6006FA76E975")
|
||||
event.parameters.append(TelemetryEventParam('Name', name))
|
||||
event.parameters.append(TelemetryEventParam('Version', version))
|
||||
event.parameters.append(TelemetryEventParam('IsInternal', is_internal))
|
||||
event.parameters.append(TelemetryEventParam('Operation', op))
|
||||
event.parameters.append(TelemetryEventParam('OperationSuccess',
|
||||
is_success))
|
||||
event.parameters.append(TelemetryEventParam('Message', message))
|
||||
event.parameters.append(TelemetryEventParam('Duration', duration))
|
||||
event.parameters.append(TelemetryEventParam('ExtensionType', evt_type))
|
||||
|
||||
event = prot.TelemetryEvent()
|
||||
prot.set_properties("event", event, data)
|
||||
event.parameters.extend(self.sysinfo)
|
||||
event_list.events.append(event)
|
||||
if len(event_list.events) == 0:
|
||||
return
|
||||
|
||||
data = get_properties(event)
|
||||
try:
|
||||
protocol = PROT_FACTORY.get_protocol()
|
||||
protocol.report_event(event_list)
|
||||
except prot.ProtocolError as e:
|
||||
self.save_event(json.dumps(data))
|
||||
except EventError as e:
|
||||
logger.error("{0}", e)
|
||||
|
||||
def run(self):
|
||||
self.init_sysinfo()
|
||||
last_heartbeat = datetime.datetime.min
|
||||
period = datetime.timedelta(hours = 12)
|
||||
while(True):
|
||||
if (datetime.datetime.now()-last_heartbeat) > period:
|
||||
last_heartbeat = datetime.datetime.now()
|
||||
add_event(op=WALAEventOperation.HeartBeat,
|
||||
name="WALA",is_success=True)
|
||||
self.collect_and_send_events()
|
||||
time.sleep(60)
|
||||
|
||||
def save_event(data):
|
||||
event_dir = os.path.join(OSUTIL.get_lib_dir(), 'events')
|
||||
if not os.path.exists(event_dir):
|
||||
os.mkdir(event_dir)
|
||||
os.chmod(event_dir,0o700)
|
||||
if len(os.listdir(event_dir)) > 1000:
|
||||
raise EventError("Too many files under: {0}", event_dir)
|
||||
|
||||
filename = os.path.join(event_dir, text(int(time.time()*1000000)))
|
||||
try:
|
||||
with open(filename+".tmp",'wb+') as hfile:
|
||||
hfile.write(data.encode("utf-8"))
|
||||
os.rename(filename+".tmp", filename+".tld")
|
||||
except IOError as e:
|
||||
raise EventError("Failed to write events to file:{0}", e)
|
||||
__event_reporter__ = EventReporter()
|
||||
|
||||
def add_event(name, op="", is_success=True, duration=0, version="1.0",
|
||||
message="", evt_type="", is_internal=False):
|
||||
log = logger.info if is_success else logger.error
|
||||
log("Event: name={0}, op={1}, message={2}", name, op, message)
|
||||
event = prot.TelemetryEvent(1, "69B669B9-4AF8-4C50-BDC4-6006FA76E975")
|
||||
event.parameters.append(prot.TelemetryEventParam('Name', name))
|
||||
event.parameters.append(prot.TelemetryEventParam('Version', version))
|
||||
event.parameters.append(prot.TelemetryEventParam('IsInternal', is_internal))
|
||||
event.parameters.append(prot.TelemetryEventParam('Operation', op))
|
||||
event.parameters.append(prot.TelemetryEventParam('OperationSuccess',
|
||||
is_success))
|
||||
event.parameters.append(prot.TelemetryEventParam('Message', message))
|
||||
event.parameters.append(prot.TelemetryEventParam('Duration', duration))
|
||||
event.parameters.append(prot.TelemetryEventParam('ExtensionType', evt_type))
|
||||
message="", evt_type="", is_internal=False,
|
||||
reporter=__event_reporter__):
|
||||
if reporter.event_dir is None:
|
||||
logger.warn("Event reporter is not initialized.")
|
||||
return
|
||||
reporter.add_event(name, op=op, is_success=is_success, duration=duration,
|
||||
version=version, message=message, evt_type=evt_type,
|
||||
is_internal=is_internal)
|
||||
|
||||
data = prot.get_properties(event)
|
||||
try:
|
||||
save_event(json.dumps(data))
|
||||
except EventError as e:
|
||||
logger.error("{0}", e)
|
||||
def init_event_reporter(event_dir, reporter=__event_reporter__):
|
||||
reporter.event_dir = event_dir
|
||||
|
||||
def dump_unhandled_err(name):
|
||||
if hasattr(sys, 'last_type') and hasattr(sys, 'last_value') and \
|
||||
|
@ -185,8 +113,7 @@ def dump_unhandled_err(name):
|
|||
last_traceback)
|
||||
message= "".join(error)
|
||||
add_event(name, is_success=False, message=message,
|
||||
op=WALAEventOperation.UnhandledError)
|
||||
op=WALAEventOperation.UnhandledError)
|
||||
|
||||
def enable_unhandled_err_dump(name):
|
||||
atexit.register(dump_unhandled_err, name)
|
||||
|
||||
|
|
|
@ -63,3 +63,44 @@ class ResourceDiskError(AgentError):
|
|||
def __init__(self, msg):
|
||||
super(ResourceDiskError, self).__init__('000005', msg)
|
||||
|
||||
class DhcpError(AgentError):
|
||||
"""
|
||||
Failed to handle dhcp response
|
||||
"""
|
||||
def __init__(self, msg):
|
||||
super(DhcpError, self).__init__('000006', msg)
|
||||
|
||||
class OSUtilError(AgentError):
|
||||
"""
|
||||
Failed to perform operation to OS configuration
|
||||
"""
|
||||
def __init__(self, msg):
|
||||
super(OSUtilError, self).__init__('000007', msg)
|
||||
|
||||
class ProtocolError(AgentError):
|
||||
"""
|
||||
Azure protocol error
|
||||
"""
|
||||
def __init__(self, msg):
|
||||
super(ProtocolError, self).__init__('000008', msg)
|
||||
|
||||
class ProtocolNotFoundError(ProtocolError):
|
||||
"""
|
||||
Azure protocol endpoint not found
|
||||
"""
|
||||
def __init__(self, msg):
|
||||
super(ProtocolNotFoundError, self).__init__(msg)
|
||||
|
||||
class HttpError(AgentError):
|
||||
"""
|
||||
Http request failure
|
||||
"""
|
||||
def __init__(self, msg):
|
||||
super(HttpError, self).__init__('000009', msg)
|
||||
|
||||
class EventError(AgentError):
|
||||
"""
|
||||
Event reporting error
|
||||
"""
|
||||
def __init__(self, msg):
|
||||
super(EventError, self).__init__('000010', msg)
|
||||
|
|
|
@ -7,15 +7,25 @@ Add alies for python2 and python3 libs and fucntions.
|
|||
if sys.version_info[0]== 3:
|
||||
import http.client as httpclient
|
||||
from urllib.parse import urlparse
|
||||
text = str
|
||||
|
||||
"""Rename Python3 str to ustr"""
|
||||
ustr = str
|
||||
|
||||
bytebuffer = memoryview
|
||||
|
||||
read_input = input
|
||||
|
||||
elif sys.version_info[0] == 2:
|
||||
import httplib as httpclient
|
||||
from urlparse import urlparse
|
||||
text = unicode
|
||||
|
||||
"""Rename Python2 unicode to ustr"""
|
||||
ustr = unicode
|
||||
|
||||
bytebuffer = buffer
|
||||
|
||||
read_input = raw_input
|
||||
|
||||
else:
|
||||
raise ImportError("Unknown python version:{0}".format(sys.version_info))
|
||||
|
||||
|
|
|
@ -1,28 +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+
|
||||
#
|
||||
|
||||
"""
|
||||
Handler handles different tasks like, provisioning, deprovisioning etc.
|
||||
The handlers could be extended for different distros. The default
|
||||
implementation is under azurelinuxagent.distros.default
|
||||
"""
|
||||
import azurelinuxagent.distro.loader as loader
|
||||
|
||||
HANDLERS = loader.get_handlers()
|
||||
|
|
@ -16,5 +16,3 @@
|
|||
#
|
||||
# Requires Python 2.4+ and Openssl 1.0+
|
||||
#
|
||||
|
||||
from azurelinuxagent.protocol.common import *
|
||||
|
|
|
@ -1,126 +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 traceback
|
||||
import time
|
||||
import threading
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.exception import *
|
||||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
from azurelinuxagent.protocol.common import *
|
||||
from azurelinuxagent.protocol.v1 import WireProtocol
|
||||
from azurelinuxagent.protocol.v2 import MetadataProtocol
|
||||
from azurelinuxagent.protocol.ovfenv import TAG_FILE_NAME
|
||||
|
||||
PROTOCOL_FILE_NAME = "Protocol"
|
||||
MAX_RETRY = 60
|
||||
|
||||
|
||||
def _detect_protocol(protocols=[WireProtocol, MetadataProtocol]):
|
||||
protocol_file_path = os.path.join(OSUTIL.get_lib_dir(), PROTOCOL_FILE_NAME)
|
||||
if os.path.isfile(protocol_file_path):
|
||||
os.remove(protocol_file_path)
|
||||
for retry in range(0, MAX_RETRY):
|
||||
for protocol_cls in protocols:
|
||||
try:
|
||||
logger.info("Detecting protocol: {0}", protocol_cls.__name__)
|
||||
protocol = protocol_cls()
|
||||
protocol.initialize()
|
||||
logger.info("Found protocol: {0}", protocol_cls.__name__)
|
||||
fileutil.write_file(protocol_file_path, protocol_cls.__name__)
|
||||
return protocol
|
||||
except ProtocolError as e:
|
||||
logger.info("Protocol endpoint not found: {0}, {1}",
|
||||
protocol_cls.__name__, e)
|
||||
if retry < MAX_RETRY -1:
|
||||
logger.info("Retry detect protocols: retry={0}", retry)
|
||||
time.sleep(10)
|
||||
raise ProtocolNotFound("No protocol found.")
|
||||
|
||||
def _get_protocol():
|
||||
protocol_file_path = os.path.join(OSUTIL.get_lib_dir(),
|
||||
PROTOCOL_FILE_NAME)
|
||||
if not os.path.isfile(protocol_file_path):
|
||||
raise ProtocolError("No protocl found")
|
||||
|
||||
protocol_name = fileutil.read_file(protocol_file_path)
|
||||
if protocol_name == WireProtocol.__name__:
|
||||
protoc0l = WireProtocol()
|
||||
else:
|
||||
protocol = MetadataProtocol()
|
||||
protocol.reinitialize()
|
||||
return protocol
|
||||
|
||||
class ProtocolFactory(object):
|
||||
def __init__(self):
|
||||
self.protocol = None
|
||||
self.lock = threading.Lock()
|
||||
|
||||
def detect_protocol(self):
|
||||
logger.info("Detect protocol endpoints")
|
||||
self.lock.acquire()
|
||||
try:
|
||||
if self.protocol is None:
|
||||
self.protocol = _detect_protocol()
|
||||
return self.protocol
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
def detect_protocol_by_file(self):
|
||||
logger.info("Detect protocol by file")
|
||||
self.lock.acquire()
|
||||
try:
|
||||
tag_file_path = os.path.join(OSUTIL.get_lib_dir(), TAG_FILE_NAME)
|
||||
if self.protocol is None:
|
||||
if os.path.isfile(tag_file_path):
|
||||
protocol = _detect_protocol(protocols=[MetadataProtocol])
|
||||
else:
|
||||
protocol = _detect_protocol(protocols=[WireProtocol])
|
||||
self.protocol = protocol
|
||||
return self.protocol
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
def get_protocol(self):
|
||||
"""
|
||||
Get protocol detected
|
||||
"""
|
||||
self.lock.acquire()
|
||||
try:
|
||||
if self.protocol is None:
|
||||
self.protocol = _get_protocol()
|
||||
return self.protocol
|
||||
finally:
|
||||
self.lock.release()
|
||||
return self.protocol
|
||||
|
||||
def wait_for_network(self):
|
||||
"""
|
||||
Wait for network stack to be initialized
|
||||
"""
|
||||
ipv4 = OSUTIL.get_ip4_addr()
|
||||
while ipv4 == '' or ipv4 == '0.0.0.0':
|
||||
logger.info("Waiting for network.")
|
||||
time.sleep(10)
|
||||
OSUTIL.start_network()
|
||||
ipv4 = OSUTIL.get_ip4_addr()
|
||||
|
||||
PROT_FACTORY = ProtocolFactory()
|
|
@ -20,11 +20,13 @@ import json
|
|||
import shutil
|
||||
import os
|
||||
import time
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
from azurelinuxagent.exception import ProtocolError, HttpError
|
||||
from azurelinuxagent.future import httpclient, text
|
||||
import azurelinuxagent.conf as conf
|
||||
import azurelinuxagent.logger as logger
|
||||
import azurelinuxagent.utils.restutil as restutil
|
||||
import azurelinuxagent.utils.textutil as textutil
|
||||
from azurelinuxagent.protocol.common import *
|
||||
from azurelinuxagent.protocol.restapi import *
|
||||
|
||||
ENDPOINT='169.254.169.254'
|
||||
#TODO use http for azure pack test
|
||||
|
@ -47,7 +49,8 @@ def _add_content_type(headers):
|
|||
|
||||
class MetadataProtocol(Protocol):
|
||||
|
||||
def __init__(self, apiversion=APIVERSION, endpoint=ENDPOINT):
|
||||
def __init__(self, osutil, apiversion=APIVERSION, endpoint=ENDPOINT):
|
||||
self.osutil = osutil
|
||||
self.apiversion = apiversion
|
||||
self.endpoint = endpoint
|
||||
self.identity_uri = BASE_URI.format(self.endpoint, "identity",
|
||||
|
@ -70,7 +73,7 @@ class MetadataProtocol(Protocol):
|
|||
def _get_data(self, url, headers=None):
|
||||
try:
|
||||
resp = restutil.http_get(url, headers=headers)
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError(text(e))
|
||||
|
||||
if resp.status != httpclient.OK:
|
||||
|
@ -86,7 +89,7 @@ class MetadataProtocol(Protocol):
|
|||
headers = _add_content_type(headers)
|
||||
try:
|
||||
resp = restutil.http_put(url, json.dumps(data), headers=headers)
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError(text(e))
|
||||
if resp.status != httpclient.OK:
|
||||
raise ProtocolError("{0} - PUT: {1}".format(resp.status, url))
|
||||
|
@ -95,7 +98,7 @@ class MetadataProtocol(Protocol):
|
|||
headers = _add_content_type(headers)
|
||||
try:
|
||||
resp = restutil.http_post(url, json.dumps(data), headers=headers)
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError(text(e))
|
||||
if resp.status != httpclient.CREATED:
|
||||
raise ProtocolError("{0} - POST: {1}".format(resp.status, url))
|
||||
|
@ -107,25 +110,22 @@ class MetadataProtocol(Protocol):
|
|||
content = fileutil.read_file(file_name)
|
||||
return textutil.get_bytes_from_pem(content)
|
||||
|
||||
def initialize(self):
|
||||
def detect(self):
|
||||
self.get_vminfo()
|
||||
trans_prv_file = os.path.join(OSUTIL.get_lib_dir(),
|
||||
trans_prv_file = os.path.join(conf.get_lib_dir(),
|
||||
TRANSPORT_PRV_FILE_NAME)
|
||||
trans_crt_file = os.path.join(OSUTIL.get_lib_dir(),
|
||||
trans_crt_file = os.path.join(conf.get_lib_dir(),
|
||||
TRANSPORT_CERT_FILE_NAME)
|
||||
OSUTIL.gen_transport_cert(trans_prv_file, trans_crt_file)
|
||||
self.osutil.gen_transport_cert(trans_prv_file, trans_crt_file)
|
||||
|
||||
#"Install" the cert and private key to /var/lib/waagent
|
||||
thumbprint = OSUTIL.get_thumbprint_from_crt(trans_crt_file)
|
||||
prv_file = os.path.join(OSUTIL.get_lib_dir(),
|
||||
thumbprint = self.osutil.get_thumbprint_from_crt(trans_crt_file)
|
||||
prv_file = os.path.join(conf.get_lib_dir(),
|
||||
"{0}.prv".format(thumbprint))
|
||||
crt_file = os.path.join(OSUTIL.get_lib_dir(),
|
||||
crt_file = os.path.join(conf.get_lib_dir(),
|
||||
"{0}.crt".format(thumbprint))
|
||||
shutil.copyfile(trans_prv_file, prv_file)
|
||||
shutil.copyfile(trans_crt_file, crt_file)
|
||||
|
||||
def reinitialize(self):
|
||||
pass
|
||||
|
||||
def get_vminfo(self):
|
||||
vminfo = VMInfo()
|
|
@ -24,67 +24,15 @@ import re
|
|||
import shutil
|
||||
import xml.dom.minidom as minidom
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.exception import ProtocolError
|
||||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
from azurelinuxagent.utils.textutil import parse_doc, findall, find, findtext
|
||||
from azurelinuxagent.utils.osutil import OSUTIL, OSUtilError
|
||||
from azurelinuxagent.protocol.common import ProtocolError
|
||||
|
||||
OVF_FILE_NAME = "ovf-env.xml"
|
||||
|
||||
#Tag file to indicate usage of metadata protocol
|
||||
TAG_FILE_NAME = "useMetadataEndpoint.tag"
|
||||
|
||||
OVF_VERSION = "1.0"
|
||||
OVF_NAME_SPACE = "http://schemas.dmtf.org/ovf/environment/1"
|
||||
WA_NAME_SPACE = "http://schemas.microsoft.com/windowsazure"
|
||||
|
||||
def get_ovf_env():
|
||||
"""
|
||||
Load saved ovf-env.xml
|
||||
"""
|
||||
ovf_file_path = os.path.join(OSUTIL.get_lib_dir(), OVF_FILE_NAME)
|
||||
if os.path.isfile(ovf_file_path):
|
||||
xml_text = fileutil.read_file(ovf_file_path)
|
||||
return OvfEnv(xml_text)
|
||||
else:
|
||||
raise ProtocolError("ovf-env.xml is missing.")
|
||||
|
||||
def copy_ovf_env():
|
||||
"""
|
||||
Copy ovf env file from dvd to hard disk.
|
||||
Remove password before save it to the disk
|
||||
"""
|
||||
try:
|
||||
OSUTIL.mount_dvd()
|
||||
|
||||
ovf_file_path_on_dvd = OSUTIL.get_ovf_env_file_path_on_dvd()
|
||||
ovfxml = fileutil.read_file(ovf_file_path_on_dvd, remove_bom=True)
|
||||
ovfenv = OvfEnv(ovfxml)
|
||||
ovfxml = re.sub("<UserPassword>.*?<", "<UserPassword>*<", ovfxml)
|
||||
ovf_file_path = os.path.join(OSUTIL.get_lib_dir(), OVF_FILE_NAME)
|
||||
fileutil.write_file(ovf_file_path, ovfxml)
|
||||
|
||||
tag_file_path_on_dvd = os.path.join(OSUTIL.get_dvd_mount_point(),
|
||||
TAG_FILE_NAME)
|
||||
if os.path.isfile(tag_file_path_on_dvd):
|
||||
logger.info("Found {0} in provisioning ISO", TAG_FILE_NAME)
|
||||
tag_file_path = os.path.join(OSUTIL.get_lib_dir(), TAG_FILE_NAME)
|
||||
shutil.copyfile(tag_file_path_on_dvd, tag_file_path)
|
||||
|
||||
except IOError as e:
|
||||
raise ProtocolError(text(e))
|
||||
except OSUtilError as e:
|
||||
raise ProtocolError(text(e))
|
||||
|
||||
try:
|
||||
OSUTIL.umount_dvd()
|
||||
OSUTIL.eject_dvd()
|
||||
except OSUtilError as e:
|
||||
logger.warn(text(e))
|
||||
|
||||
return ovfenv
|
||||
|
||||
def _validate_ovf(val, msg):
|
||||
if val is None:
|
||||
raise ProtocolError("Failed to parse OVF XML: {0}".format(msg))
|
||||
|
|
|
@ -22,15 +22,10 @@ import re
|
|||
import json
|
||||
import xml.dom.minidom
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.exception import ProtocolError
|
||||
from azurelinuxagent.future import text
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
|
||||
class ProtocolError(Exception):
|
||||
pass
|
||||
|
||||
class ProtocolNotFound(Exception):
|
||||
pass
|
||||
|
||||
def validata_param(name, val, expected_type):
|
||||
if val is None:
|
||||
raise ProtocolError("{0} is None".format(name))
|
||||
|
@ -211,10 +206,7 @@ class TelemetryEventList(DataContract):
|
|||
|
||||
class Protocol(DataContract):
|
||||
|
||||
def initialize(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def reinitialize(self):
|
||||
def detect(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_vminfo(self):
|
|
@ -23,17 +23,18 @@ import time
|
|||
import traceback
|
||||
import xml.sax.saxutils as saxutils
|
||||
import xml.etree.ElementTree as ET
|
||||
import azurelinuxagent.conf as conf
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.exception import ProtocolError, HttpError, \
|
||||
ProtocolNotFoundError
|
||||
from azurelinuxagent.future import text, httpclient, bytebuffer
|
||||
import azurelinuxagent.utils.restutil as restutil
|
||||
import azurelinuxagent.utils.textutil as textutil
|
||||
from azurelinuxagent.utils.textutil import parse_doc, findall, find, findtext, \
|
||||
getattrib, gettext, remove_bom
|
||||
from azurelinuxagent.utils.osutil import OSUTIL
|
||||
import azurelinuxagent.utils.fileutil as fileutil
|
||||
import azurelinuxagent.utils.shellutil as shellutil
|
||||
from azurelinuxagent.protocol.common import *
|
||||
import azurelinuxagent.protocol.dhcp as dhcp
|
||||
from azurelinuxagent.protocol.restapi import *
|
||||
|
||||
VERSION_INFO_URI = "http://{0}/?comp=versions"
|
||||
GOAL_STATE_URI = "http://{0}/machine/?comp=goalstate"
|
||||
|
@ -65,21 +66,17 @@ class WireProtocolResourceGone(ProtocolError):
|
|||
|
||||
class WireProtocol(Protocol):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
def __init__(self, osutil, endpoint):
|
||||
self.osutil = osutil
|
||||
self.endpoint = endpoint
|
||||
self.client = WireClient(self.endpoint)
|
||||
|
||||
def initialize(self):
|
||||
dhcp_resp = dhcp.DHCPCLIENT.fetch_dhcp_resp()
|
||||
self.client = WireClient(dhcp_resp.endpoint)
|
||||
def detect(self):
|
||||
self.client.check_wire_protocol_version()
|
||||
OSUTIL.gen_transport_cert(TRANSPORT_PRV_FILE_NAME,
|
||||
self.osutil.gen_transport_cert(TRANSPORT_PRV_FILE_NAME,
|
||||
TRANSPORT_CERT_FILE_NAME)
|
||||
self.client.update_goal_state(forced=True)
|
||||
|
||||
def reinitialize(self):
|
||||
dhcp_resp = dhcp.DHCPCLIENT.get_dhcp_resp()
|
||||
self.client = WireClient(dhcp_resp.endpoint)
|
||||
|
||||
def get_vminfo(self):
|
||||
hosting_env = self.client.get_hosting_env()
|
||||
vminfo = VMInfo()
|
||||
|
@ -314,7 +311,7 @@ class StatusBlob(object):
|
|||
self.put_page_blob(url, data)
|
||||
else:
|
||||
raise ProtocolError("Unknown blob type: {0}".format(blob_type))
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError("Failed to upload status blob: {0}".format(e))
|
||||
|
||||
def get_blob_type(self, url):
|
||||
|
@ -326,7 +323,7 @@ class StatusBlob(object):
|
|||
"x-ms-date" : timestamp,
|
||||
'x-ms-version' : self.__class__.__storage_version__
|
||||
})
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError((u"Failed to get status blob type: {0}"
|
||||
u"").format(e))
|
||||
if resp is None or resp.status != httpclient.OK:
|
||||
|
@ -348,7 +345,7 @@ class StatusBlob(object):
|
|||
"Content-Length": text(len(data)),
|
||||
"x-ms-version" : self.__class__.__storage_version__
|
||||
})
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError((u"Failed to upload block blob: {0}"
|
||||
u"").format(e))
|
||||
if resp.status != httpclient.CREATED:
|
||||
|
@ -373,7 +370,7 @@ class StatusBlob(object):
|
|||
"x-ms-blob-content-length" : text(page_blob_size),
|
||||
"x-ms-version" : self.__class__.__storage_version__
|
||||
})
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError((u"Failed to clean up page blob: {0}"
|
||||
u"").format(e))
|
||||
if resp.status != httpclient.CREATED:
|
||||
|
@ -406,7 +403,7 @@ class StatusBlob(object):
|
|||
"x-ms-version" : self.__class__.__storage_version__,
|
||||
"Content-Length": text(page_end - start)
|
||||
})
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError((u"Failed to upload page blob: {0}"
|
||||
u"").format(e))
|
||||
if resp is None or resp.status != httpclient.CREATED:
|
||||
|
@ -506,7 +503,7 @@ class WireClient(object):
|
|||
try:
|
||||
resp = self.call_wireserver(restutil.http_get, uri,
|
||||
headers=headers)
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError(text(e))
|
||||
|
||||
if(resp.status != httpclient.OK):
|
||||
|
@ -550,7 +547,7 @@ class WireClient(object):
|
|||
resp = self.call_storage_service(restutil.http_get,
|
||||
version_uri.uri, None,
|
||||
chk_proxy=True)
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError(text(e))
|
||||
|
||||
if resp.status == httpclient.OK:
|
||||
|
@ -615,7 +612,7 @@ class WireClient(object):
|
|||
xml_text = self.fetch_config(uri, self.get_header())
|
||||
goal_state = GoalState(xml_text)
|
||||
|
||||
incarnation_file = os.path.join(OSUTIL.get_lib_dir(),
|
||||
incarnation_file = os.path.join(conf.get_lib_dir(),
|
||||
INCARNATION_FILE_NAME)
|
||||
|
||||
if not forced:
|
||||
|
@ -633,7 +630,7 @@ class WireClient(object):
|
|||
try:
|
||||
self.goal_state = goal_state
|
||||
file_name = GOAL_STATE_FILE_NAME.format(goal_state.incarnation)
|
||||
goal_state_file = os.path.join(OSUTIL.get_lib_dir(), file_name)
|
||||
goal_state_file = os.path.join(conf.get_lib_dir(), file_name)
|
||||
self.save_cache(goal_state_file, xml_text)
|
||||
self.save_cache(incarnation_file, goal_state.incarnation)
|
||||
self.update_hosting_env(goal_state)
|
||||
|
@ -707,7 +704,7 @@ class WireClient(object):
|
|||
else:
|
||||
error = ("Agent supported wire protocol version: {0} was not "
|
||||
"advised by Fabric.").format(PROTOCOL_VERSION)
|
||||
raise ProtocolNotFound(error)
|
||||
raise ProtocolNotFoundError(error)
|
||||
|
||||
def upload_status_blob(self):
|
||||
ext_conf = self.get_ext_conf()
|
||||
|
@ -725,7 +722,7 @@ class WireClient(object):
|
|||
try:
|
||||
resp = self.call_wireserver(restutil.http_post, role_prop_uri,
|
||||
role_prop, headers = headers)
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError((u"Failed to send role properties: {0}"
|
||||
u"").format(e))
|
||||
if resp.status != httpclient.ACCEPTED:
|
||||
|
@ -746,7 +743,7 @@ class WireClient(object):
|
|||
try:
|
||||
resp = self.call_wireserver(restutil.http_post, health_report_uri,
|
||||
health_report, headers = headers)
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError((u"Failed to send provision status: {0}"
|
||||
u"").format(e))
|
||||
if resp.status != httpclient.OK:
|
||||
|
@ -764,7 +761,7 @@ class WireClient(object):
|
|||
try:
|
||||
header = self.get_header_for_xml_content()
|
||||
resp = self.call_wireserver(restutil.http_post, uri, data, header)
|
||||
except restutil.HttpError as e:
|
||||
except HttpError as e:
|
||||
raise ProtocolError("Failed to send events:{0}".format(e))
|
||||
|
||||
if resp.status != httpclient.OK:
|
||||
|
@ -933,8 +930,8 @@ class Certificates(object):
|
|||
def __init__(self, client, xml_text):
|
||||
logger.verb("Load Certificates.xml")
|
||||
self.client = client
|
||||
self.lib_dir = OSUTIL.get_lib_dir()
|
||||
self.openssl_cmd = OSUTIL.get_openssl_cmd()
|
||||
self.lib_dir = conf.get_lib_dir()
|
||||
self.openssl_cmd = self.client.osutil.get_openssl_cmd()
|
||||
self.cert_list = CertList()
|
||||
self.parse(xml_text)
|
||||
|
||||
|
@ -980,15 +977,15 @@ class Certificates(object):
|
|||
begin_crt = True
|
||||
elif re.match(r'[-]+END.*KEY[-]+', line):
|
||||
tmp_file = self.write_to_tmp_file(index, 'prv', buf)
|
||||
pub = OSUTIL.get_pubkey_from_prv(tmp_file)
|
||||
pub = self.client.osutil.get_pubkey_from_prv(tmp_file)
|
||||
prvs[pub] = tmp_file
|
||||
buf = []
|
||||
index += 1
|
||||
begin_prv = False
|
||||
elif re.match(r'[-]+END.*CERTIFICATE[-]+', line):
|
||||
tmp_file = self.write_to_tmp_file(index, 'crt', buf)
|
||||
pub = OSUTIL.get_pubkey_from_crt(tmp_file)
|
||||
thumbprint = OSUTIL.get_thumbprint_from_crt(tmp_file)
|
||||
pub = self.client.osutil.get_pubkey_from_crt(tmp_file)
|
||||
thumbprint = self.client.osutil.get_thumbprint_from_crt(tmp_file)
|
||||
thumbprints[pub] = thumbprint
|
||||
#Rename crt with thumbprint as the file name
|
||||
crt = "{0}.crt".format(thumbprint)
|
|
@ -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+
|
||||
#
|
||||
|
||||
"""
|
||||
Load OSUtil implementation from azurelinuxagent.distro
|
||||
"""
|
||||
from azurelinuxagent.distro.default.osutil import OSUtilError
|
||||
import azurelinuxagent.distro.loader as loader
|
||||
|
||||
OSUTIL = loader.get_osutil()
|
||||
|
|
@ -21,8 +21,9 @@ import time
|
|||
import platform
|
||||
import os
|
||||
import subprocess
|
||||
import azurelinuxagent.logger as logger
|
||||
import azurelinuxagent.conf as conf
|
||||
import azurelinuxagent.logger as logger
|
||||
from azurelinuxagent.exception import HttpError
|
||||
from azurelinuxagent.future import httpclient, urlparse
|
||||
|
||||
"""
|
||||
|
@ -31,9 +32,6 @@ REST api util functions
|
|||
|
||||
RETRY_WAITING_INTERVAL = 10
|
||||
|
||||
class HttpError(Exception):
|
||||
pass
|
||||
|
||||
def _parse_url(url):
|
||||
o = urlparse(url)
|
||||
rel_uri = o.path
|
||||
|
@ -51,8 +49,8 @@ def get_http_proxy():
|
|||
Get http_proxy and https_proxy from environment variables.
|
||||
Username and password is not supported now.
|
||||
"""
|
||||
host = conf.get("HttpProxy.Host", None)
|
||||
port = conf.get("HttpProxy.Port", None)
|
||||
host = conf.get_httpproxy_host()
|
||||
port = conf.get_httpproxy_port()
|
||||
return (host, port)
|
||||
|
||||
def _http_request(method, host, rel_uri, port=None, data=None, secure=False,
|
||||
|
|
|
@ -71,3 +71,18 @@ OS.OpensslPath=None
|
|||
|
||||
# Detect Scvmm environment, default is n
|
||||
# DetectScvmmEnv=n
|
||||
|
||||
#
|
||||
# Lib.Dir=/var/lib/waagent
|
||||
|
||||
#
|
||||
# DVD.MountPoint=/mnt/cdrom/secure
|
||||
|
||||
#
|
||||
# Pid.File=/var/run/waagent.pid
|
||||
|
||||
#
|
||||
# Extension.LogDir=/var/log/azure
|
||||
|
||||
#
|
||||
# Home.Dir=/home
|
||||
|
|
Загрузка…
Ссылка в новой задаче