summaryrefslogtreecommitdiff
path: root/azurelinuxagent/pa
diff options
context:
space:
mode:
Diffstat (limited to 'azurelinuxagent/pa')
-rw-r--r--azurelinuxagent/pa/deprovision/clearlinux.py31
-rw-r--r--azurelinuxagent/pa/deprovision/default.py17
-rw-r--r--azurelinuxagent/pa/deprovision/factory.py3
-rw-r--r--azurelinuxagent/pa/deprovision/ubuntu.py33
-rw-r--r--azurelinuxagent/pa/provision/default.py106
-rw-r--r--azurelinuxagent/pa/provision/ubuntu.py14
-rw-r--r--azurelinuxagent/pa/rdma/centos.py45
7 files changed, 164 insertions, 85 deletions
diff --git a/azurelinuxagent/pa/deprovision/clearlinux.py b/azurelinuxagent/pa/deprovision/clearlinux.py
new file mode 100644
index 0000000..097891b
--- /dev/null
+++ b/azurelinuxagent/pa/deprovision/clearlinux.py
@@ -0,0 +1,31 @@
+# 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 azurelinuxagent.common.utils.fileutil as fileutil
+from azurelinuxagent.pa.deprovision.default import DeprovisionHandler, \
+ DeprovisionAction
+
+class ClearLinuxDeprovisionHandler(DeprovisionHandler):
+ def __init__(self, distro):
+ self.distro = distro
+
+ def setup(self, deluser):
+ warnings, actions = super(ClearLinuxDeprovisionHandler, self).setup(deluser)
+ # Probably should just wipe /etc and /var here
+ return warnings, actions
diff --git a/azurelinuxagent/pa/deprovision/default.py b/azurelinuxagent/pa/deprovision/default.py
index b570c31..a702d3f 100644
--- a/azurelinuxagent/pa/deprovision/default.py
+++ b/azurelinuxagent/pa/deprovision/default.py
@@ -17,6 +17,8 @@
# Requires Python 2.4+ and Openssl 1.0+
#
+import signal
+import sys
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.exception import ProtocolError
from azurelinuxagent.common.future import read_input
@@ -38,6 +40,7 @@ class DeprovisionHandler(object):
def __init__(self):
self.osutil = get_osutil()
self.protocol_util = get_protocol_util()
+ signal.signal(signal.SIGINT, self.handle_interrupt_signal)
def del_root_password(self, warnings, actions):
warnings.append("WARNING! root password will be disabled. "
@@ -63,8 +66,8 @@ class DeprovisionHandler(object):
def regen_ssh_host_key(self, warnings, actions):
warnings.append("WARNING! All SSH host key pairs will be deleted.")
- actions.append(DeprovisionAction(shellutil.run,
- ['rm -f /etc/ssh/ssh_host_*key*']))
+ actions.append(DeprovisionAction(fileutil.rm_files,
+ ['/etc/ssh/ssh_host_*key*']))
def stop_agent_service(self, warnings, actions):
warnings.append("WARNING! The waagent service will be stopped.")
@@ -74,6 +77,11 @@ class DeprovisionHandler(object):
files_to_del = ['/root/.bash_history', '/var/log/waagent.log']
actions.append(DeprovisionAction(fileutil.rm_files, files_to_del))
+ def del_resolv(self, warnings, actions):
+ warnings.append("WARNING! /etc/resolv.conf will be deleted.")
+ files_to_del = ["/etc/resolv.conf"]
+ actions.append(DeprovisionAction(fileutil.rm_files, files_to_del))
+
def del_dhcp_lease(self, warnings, actions):
warnings.append("WARNING! Cached DHCP leases will be deleted.")
dirs_to_del = ["/var/lib/dhclient", "/var/lib/dhcpcd", "/var/lib/dhcp"]
@@ -109,6 +117,7 @@ class DeprovisionHandler(object):
self.del_lib_dir(warnings, actions)
self.del_files(warnings, actions)
+ self.del_resolv(warnings, actions)
if deluser:
self.del_user(warnings, actions)
@@ -128,4 +137,8 @@ class DeprovisionHandler(object):
for action in actions:
action.invoke()
+ def handle_interrupt_signal(self, frame):
+ print("Deprovision is interrupted.")
+ sys.exit(0)
+
diff --git a/azurelinuxagent/pa/deprovision/factory.py b/azurelinuxagent/pa/deprovision/factory.py
index dd01633..72a5be1 100644
--- a/azurelinuxagent/pa/deprovision/factory.py
+++ b/azurelinuxagent/pa/deprovision/factory.py
@@ -21,6 +21,7 @@ from azurelinuxagent.common.version import DISTRO_NAME, DISTRO_VERSION, \
DISTRO_FULL_NAME
from .default import DeprovisionHandler
+from .clearlinux import ClearLinuxDeprovisionHandler
from .coreos import CoreOSDeprovisionHandler
from .ubuntu import UbuntuDeprovisionHandler
@@ -31,6 +32,8 @@ def get_deprovision_handler(distro_name=DISTRO_NAME,
return UbuntuDeprovisionHandler()
if distro_name == "coreos":
return CoreOSDeprovisionHandler()
+ if distro_name == "clear linux":
+ return ClearLinuxDeprovisionHandler()
return DeprovisionHandler()
diff --git a/azurelinuxagent/pa/deprovision/ubuntu.py b/azurelinuxagent/pa/deprovision/ubuntu.py
index 14f90de..b45d415 100644
--- a/azurelinuxagent/pa/deprovision/ubuntu.py
+++ b/azurelinuxagent/pa/deprovision/ubuntu.py
@@ -18,30 +18,25 @@
#
import os
-import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.pa.deprovision.default import DeprovisionHandler, \
- DeprovisionAction
-
-def del_resolv():
- if os.path.realpath('/etc/resolv.conf') != '/run/resolvconf/resolv.conf':
- logger.info("resolvconf is not configured. Removing /etc/resolv.conf")
- fileutil.rm_files('/etc/resolv.conf')
- else:
- logger.info("resolvconf is enabled; leaving /etc/resolv.conf intact")
- fileutil.rm_files('/etc/resolvconf/resolv.conf.d/tail',
- '/etc/resolvconf/resolv.conf.d/originial')
+ DeprovisionAction
class UbuntuDeprovisionHandler(DeprovisionHandler):
def __init__(self):
super(UbuntuDeprovisionHandler, self).__init__()
- def setup(self, deluser):
- warnings, actions = super(UbuntuDeprovisionHandler, self).setup(deluser)
- warnings.append("WARNING! Nameserver configuration in "
- "/etc/resolvconf/resolv.conf.d/{tail,originial} "
- "will be deleted.")
- actions.append(DeprovisionAction(del_resolv))
- return warnings, actions
-
+ def del_resolv(self, warnings, actions):
+ if os.path.realpath(
+ '/etc/resolv.conf') != '/run/resolvconf/resolv.conf':
+ warnings.append("WARNING! /etc/resolv.conf will be deleted.")
+ files_to_del = ["/etc/resolv.conf"]
+ actions.append(DeprovisionAction(fileutil.rm_files, files_to_del))
+ else:
+ warnings.append("WARNING! /etc/resolvconf/resolv.conf.d/tail "
+ "and /etc/resolvconf/resolv.conf.d/original will "
+ "be deleted.")
+ files_to_del = ["/etc/resolvconf/resolv.conf.d/tail",
+ "/etc/resolvconf/resolv.conf.d/original"]
+ actions.append(DeprovisionAction(fileutil.rm_files, files_to_del))
diff --git a/azurelinuxagent/pa/provision/default.py b/azurelinuxagent/pa/provision/default.py
index b07c147..e851036 100644
--- a/azurelinuxagent/pa/provision/default.py
+++ b/azurelinuxagent/pa/provision/default.py
@@ -25,69 +25,71 @@ from azurelinuxagent.common.future import ustr
import azurelinuxagent.common.conf as conf
from azurelinuxagent.common.event import add_event, WALAEventOperation
from azurelinuxagent.common.exception import ProvisionError, ProtocolError, \
- OSUtilError
+ OSUtilError
from azurelinuxagent.common.protocol.restapi import ProvisionStatus
import azurelinuxagent.common.utils.shellutil as shellutil
import azurelinuxagent.common.utils.fileutil as fileutil
from azurelinuxagent.common.osutil import get_osutil
from azurelinuxagent.common.protocol import get_protocol_util
-CUSTOM_DATA_FILE="CustomData"
+CUSTOM_DATA_FILE = "CustomData"
-class ProvisionHandler(object):
+class ProvisionHandler(object):
def __init__(self):
self.osutil = get_osutil()
self.protocol_util = get_protocol_util()
def run(self):
- #If provision is not enabled, return
- if not conf.get_provision_enabled():
- logger.info("Provisioning is disabled. Skip.")
- return
-
+ # if provisioning is already done, return
provisioned = os.path.join(conf.get_lib_dir(), "provisioned")
if os.path.isfile(provisioned):
+ logger.info("Provisioning already completed, skipping.")
return
- logger.info("Run provision handler.")
- logger.info("Copy ovf-env.xml.")
- try:
- ovfenv = self.protocol_util.copy_ovf_env()
- except ProtocolError as e:
- self.report_event("Failed to copy ovf-env.xml: {0}".format(e))
- return
-
- self.protocol_util.get_protocol_by_file()
-
- self.report_not_ready("Provisioning", "Starting")
-
- try:
- logger.info("Start provisioning")
- self.provision(ovfenv)
- fileutil.write_file(provisioned, "")
- thumbprint = self.reg_ssh_host_key()
- logger.info("Finished provisioning")
- except ProvisionError as e:
- logger.error("Provision failed: {0}", e)
- self.report_not_ready("ProvisioningFailed", ustr(e))
- self.report_event(ustr(e))
- return
-
+ thumbprint = None
+ # If provision is not enabled, report ready and then return
+ if not conf.get_provision_enabled():
+ logger.info("Provisioning is disabled, skipping.")
+ else:
+ logger.info("Running provisioning handler")
+ try:
+ logger.info("Copying ovf-env.xml")
+ ovf_env = self.protocol_util.copy_ovf_env()
+ self.protocol_util.get_protocol_by_file()
+ self.report_not_ready("Provisioning", "Starting")
+ logger.info("Starting provisioning")
+ self.provision(ovf_env)
+ thumbprint = self.reg_ssh_host_key()
+ self.osutil.restart_ssh_service()
+ self.report_event("Provision succeed", is_success=True)
+ except ProtocolError as e:
+ logger.error("[ProtocolError] Provisioning failed: {0}", e)
+ self.report_not_ready("ProvisioningFailed", ustr(e))
+ self.report_event("Failed to copy ovf-env.xml: {0}".format(e))
+ return
+ except ProvisionError as e:
+ logger.error("[ProvisionError] Provisioning failed: {0}", e)
+ self.report_not_ready("ProvisioningFailed", ustr(e))
+ self.report_event(ustr(e))
+ return
+ # write out provisioned file and report Ready
+ fileutil.write_file(provisioned, "")
self.report_ready(thumbprint)
- self.report_event("Provision succeed", is_success=True)
-
+ logger.info("Provisioning complete")
+
def reg_ssh_host_key(self):
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))
+ fileutil.rm_files("/etc/ssh/ssh_host_*key*")
+ keygen_cmd = "ssh-keygen -N '' -t {0} -f /etc/ssh/ssh_host_{1}_key"
+ shellutil.run(keygen_cmd.format(keypair_type, keypair_type))
thumbprint = self.get_ssh_host_key_thumbprint(keypair_type)
return thumbprint
def get_ssh_host_key_thumbprint(self, keypair_type):
- cmd = "ssh-keygen -lf /etc/ssh/ssh_host_{0}_key.pub".format(keypair_type)
+ cmd = "ssh-keygen -lf /etc/ssh/ssh_host_{0}_key.pub".format(
+ keypair_type)
ret = shellutil.run_get_output(cmd)
if ret[0] == 0:
return ret[1].rstrip().split()[1].replace(':', '')
@@ -107,13 +109,13 @@ class ProvisionHandler(object):
self.config_user_account(ovfenv)
self.save_customdata(ovfenv)
-
+
if conf.get_delete_root_password():
self.osutil.del_root_password()
except OSUtilError as e:
raise ProvisionError("Failed to handle ovf-env.xml: {0}".format(e))
-
+
def config_user_account(self, ovfenv):
logger.info("Create user account if not exists")
self.osutil.useradd(ovfenv.username)
@@ -123,27 +125,18 @@ class ProvisionHandler(object):
crypt_id = conf.get_password_cryptid()
salt_len = conf.get_password_crypt_salt_len()
self.osutil.chpasswd(ovfenv.username, ovfenv.user_password,
- crypt_id=crypt_id, salt_len=salt_len)
-
+ crypt_id=crypt_id, salt_len=salt_len)
+
logger.info("Configure sudoer")
- self.osutil.conf_sudoer(ovfenv.username, nopasswd=ovfenv.user_password is None)
+ self.osutil.conf_sudoer(ovfenv.username,
+ nopasswd=ovfenv.user_password is None)
logger.info("Configure sshd")
self.osutil.conf_sshd(ovfenv.disable_ssh_password_auth)
- #Disable selinux temporary
- sel = self.osutil.is_selinux_enforcing()
- if sel:
- self.osutil.set_selinux_enforce(0)
-
self.deploy_ssh_pubkeys(ovfenv)
self.deploy_ssh_keypairs(ovfenv)
- if sel:
- self.osutil.set_selinux_enforce(1)
-
- self.osutil.restart_ssh_service()
-
def save_customdata(self, ovfenv):
customdata = ovfenv.customdata
if customdata is None:
@@ -152,11 +145,11 @@ class ProvisionHandler(object):
logger.info("Save custom data")
lib_dir = conf.get_lib_dir()
if conf.get_decode_customdata():
- customdata= self.osutil.decode_customdata(customdata)
+ customdata = self.osutil.decode_customdata(customdata)
customdata_file = os.path.join(lib_dir, CUSTOM_DATA_FILE)
fileutil.write_file(customdata_file, customdata)
-
+
if conf.get_execute_customdata():
logger.info("Execute custom data")
os.chmod(customdata_file, 0o700)
@@ -183,6 +176,7 @@ class ProvisionHandler(object):
protocol = self.protocol_util.get_protocol()
protocol.report_provision_status(status)
except ProtocolError as e:
+ logger.error("Reporting NotReady failed: {0}", e)
self.report_event(ustr(e))
def report_ready(self, thumbprint=None):
@@ -192,5 +186,5 @@ class ProvisionHandler(object):
protocol = self.protocol_util.get_protocol()
protocol.report_provision_status(status)
except ProtocolError as e:
+ logger.error("Reporting Ready failed: {0}", e)
self.report_event(ustr(e))
-
diff --git a/azurelinuxagent/pa/provision/ubuntu.py b/azurelinuxagent/pa/provision/ubuntu.py
index c334f23..7f2bce3 100644
--- a/azurelinuxagent/pa/provision/ubuntu.py
+++ b/azurelinuxagent/pa/provision/ubuntu.py
@@ -32,12 +32,14 @@ from azurelinuxagent.pa.provision.default import ProvisionHandler
"""
On ubuntu image, provision could be disabled.
"""
+
+
class UbuntuProvisionHandler(ProvisionHandler):
def __init__(self):
super(UbuntuProvisionHandler, self).__init__()
def run(self):
- #If provision is enabled, run default provision handler
+ # If provision is enabled, run default provision handler
if conf.get_provision_enabled():
super(UbuntuProvisionHandler, self).run()
return
@@ -49,23 +51,21 @@ class UbuntuProvisionHandler(ProvisionHandler):
logger.info("Waiting cloud-init to copy ovf-env.xml.")
self.wait_for_ovfenv()
-
- protocol = self.protocol_util.get_protocol()
+ self.protocol_util.get_protocol()
self.report_not_ready("Provisioning", "Starting")
- logger.info("Sleep 15 seconds to prevent throttling")
- time.sleep(15) #Sleep to prevent throttling
+ logger.info("Sleeping 1 second to avoid throttling.")
+ time.sleep(1)
try:
logger.info("Wait for ssh host key to be generated.")
thumbprint = self.wait_for_ssh_host_key()
fileutil.write_file(provisioned, "")
logger.info("Finished provisioning")
-
except ProvisionError as e:
logger.error("Provision failed: {0}", e)
self.report_not_ready("ProvisioningFailed", ustr(e))
self.report_event(ustr(e))
return
-
+
self.report_ready(thumbprint)
self.report_event("Provision succeed", is_success=True)
diff --git a/azurelinuxagent/pa/rdma/centos.py b/azurelinuxagent/pa/rdma/centos.py
index c527e1b..8ad09c5 100644
--- a/azurelinuxagent/pa/rdma/centos.py
+++ b/azurelinuxagent/pa/rdma/centos.py
@@ -20,6 +20,7 @@
import glob
import os
import re
+import time
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.shellutil as shellutil
from azurelinuxagent.common.rdma import RDMAHandler
@@ -47,6 +48,17 @@ class CentOSRDMAHandler(RDMAHandler):
Install the KVP daemon and the appropriate RDMA driver package for the
RDMA firmware.
"""
+
+ # Check and install the KVP deamon if it not running
+ time.sleep(10) # give some time for the hv_hvp_daemon to start up.
+ kvpd_running = RDMAHandler.is_kvp_daemon_running()
+ logger.info('RDMA: kvp daemon running: %s' % kvpd_running)
+ if not kvpd_running:
+ self.check_or_install_kvp_daemon()
+ time.sleep(10) # wait for post-install reboot or kvp to come up
+
+ # Find out RDMA firmware version and see if the existing package needs
+ # updating or if the package is missing altogether (and install it)
fw_version = RDMAHandler.get_rdma_version()
if not fw_version:
raise Exception('Cannot determine RDMA firmware version')
@@ -187,12 +199,20 @@ class CentOSRDMAHandler(RDMAHandler):
raise Exception(
"Failed to install RDMA {0} package".format(pkg_type))
+ @staticmethod
+ def is_package_installed(pkg):
+ """Runs rpm -q and checks return code to find out if a package
+ is installed"""
+ return shellutil.run("rpm -q %s" % pkg, chk_err=False) == 0
+
def uninstall_kvp_driver_package_if_exists(self):
+ logger.info('RDMA: deleting existing kvp driver packages')
+
kvp_pkgs = [self.hyper_v_package_name,
self.hyper_v_package_name_new]
for kvp_pkg in kvp_pkgs:
- if shellutil.run("rpm -q %s" % kvp_pkg, chk_err=False) != 0:
+ if not self.is_package_installed(kvp_pkg):
logger.info(
"RDMA: kvp package %s does not exist, skipping" % kvp_pkg)
else:
@@ -201,3 +221,26 @@ class CentOSRDMAHandler(RDMAHandler):
logger.info("RDMA: successfully erased package")
else:
logger.error("RDMA: failed to erase package")
+
+ def check_or_install_kvp_daemon(self):
+ """Checks if kvp daemon package is installed, if not installs the
+ package and reboots the machine.
+ """
+ logger.info("RDMA: Checking kvp daemon packages.")
+ kvp_pkgs = [self.hyper_v_package_name,
+ self.hyper_v_package_name_new]
+
+ for pkg in kvp_pkgs:
+ logger.info("RDMA: Checking if package %s installed" % pkg)
+ installed = self.is_package_installed(pkg)
+ if installed:
+ raise Exception('RDMA: package %s is installed, but the kvp daemon is not running' % pkg)
+
+ kvp_pkg_to_install=self.hyper_v_package_name
+ logger.info("RDMA: no kvp drivers installed, will install '%s'" % kvp_pkg_to_install)
+ logger.info("RDMA: trying to install kvp package '%s'" % kvp_pkg_to_install)
+ if self.install_package(kvp_pkg_to_install) != 0:
+ raise Exception("RDMA: failed to install kvp daemon package '%s'" % kvp_pkg_to_install)
+ logger.info("RDMA: package '%s' successfully installed" % kvp_pkg_to_install)
+ logger.info("RDMA: Machine will now be rebooted.")
+ self.reboot_system() \ No newline at end of file