diff --git a/azurelinuxagent/common/osutil/default.py b/azurelinuxagent/common/osutil/default.py index 577e0e5140..b66fdcceaa 100644 --- a/azurelinuxagent/common/osutil/default.py +++ b/azurelinuxagent/common/osutil/default.py @@ -280,15 +280,17 @@ def conf_sshd(self, disable_password): def get_dvd_device(self, dev_dir='/dev'): - patten=r'(sr[0-9]|hd[c-z]|cdrom[0-9]|cd[0-9])' - for dvd in [re.match(patten, dev) for dev in os.listdir(dev_dir)]: + pattern=r'(sr[0-9]|hd[c-z]|cdrom[0-9]|cd[0-9])' + for dvd in [re.match(pattern, dev) for dev in os.listdir(dev_dir)]: if dvd is not None: return "/dev/{0}".format(dvd.group(0)) raise OSUtilError("Failed to get dvd device") - def mount_dvd(self, max_retry=6, chk_err=True): - dvd = self.get_dvd_device() - mount_point = conf.get_dvd_mount_point() + def mount_dvd(self, max_retry=6, chk_err=True, dvd=None, mount_point=None): + if dvd is None: + dvd = self.get_dvd_device() + if mount_point is None: + 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 @@ -310,8 +312,9 @@ def mount_dvd(self, max_retry=6, chk_err=True): if chk_err: raise OSUtilError("Failed to mount dvd.") - def umount_dvd(self, chk_err=True): - mount_point = conf.get_dvd_mount_point() + def umount_dvd(self, chk_err=True, mount_point=None): + if mount_point is None: + 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.") @@ -322,7 +325,13 @@ def eject_dvd(self, chk_err=True): if chk_err and retcode != 0: raise OSUtilError("Failed to eject dvd: ret={0}".format(retcode)) - def load_atappix_mod(self): + def try_load_atapiix_mod(self): + try: + self.load_atapiix_mod() + except: + logger.warn("could not load ATAPI driver") + + def load_atapiix_mod(self): if self.is_atapiix_mod_loaded(): return ret, kern_version = shellutil.run_get_output("uname -r") diff --git a/azurelinuxagent/daemon/main.py b/azurelinuxagent/daemon/main.py index 35397323ac..0a83461b4a 100644 --- a/azurelinuxagent/daemon/main.py +++ b/azurelinuxagent/daemon/main.py @@ -100,7 +100,7 @@ def daemon(self): if conf.get_detect_scvmm_env(): self.scvmm_handler.run() - + if conf.get_resourcedisk_format(): self.resourcedisk_handler.run() diff --git a/azurelinuxagent/daemon/scvmm.py b/azurelinuxagent/daemon/scvmm.py index 0df1845163..88ac381116 100644 --- a/azurelinuxagent/daemon/scvmm.py +++ b/azurelinuxagent/daemon/scvmm.py @@ -17,6 +17,7 @@ # Requires Python 2.4+ and Openssl 1.0+ # +import re import os import sys import subprocess @@ -34,21 +35,34 @@ class ScvmmHandler(object): def __init__(self): self.osutil = get_osutil() - def detect_scvmm_env(self): + def detect_scvmm_env(self, dev_dir='/dev/'): logger.info("Detecting Microsoft System Center VMM Environment") - self.osutil.mount_dvd(max_retry=1, chk_err=False) + found=False + + # try to load the ATAPI driver, continue on failure + self.osutil.try_load_atapiix_mod() + + # cycle through all available /dev/sr*|hd*|cdrom*|cd* looking for the scvmm configuration file mount_point = conf.get_dvd_mount_point() - found = os.path.isfile(os.path.join(mount_point, VMM_CONF_FILE_NAME)) - if found: - self.start_scvmm_agent() - else: - self.osutil.umount_dvd(chk_err=False) + for dvds in [re.match(r'(sr[0-9]|hd[c-z]|cdrom[0-9]?|cd[0-9]+)', dev) for dev in os.listdir(dev_dir)]: + if dvds is None: + continue + dvd = dev_dir + dvds.group(0) + self.osutil.mount_dvd(max_retry=1, chk_err=False, dvd=dvd, mount_point=mount_point) + found = os.path.isfile(os.path.join(mount_point, VMM_CONF_FILE_NAME)) + if found: + self.start_scvmm_agent(mount_point=mount_point) + break + else: + self.osutil.umount_dvd(chk_err=False, mount_point=mount_point) + return found - def start_scvmm_agent(self): + def start_scvmm_agent(self, mount_point=None): logger.info("Starting Microsoft System Center VMM Initialization " "Process") - mount_point = conf.get_dvd_mount_point() + if mount_point is None: + mount_point = conf.get_dvd_mount_point() startup_script = os.path.join(mount_point, VMM_STARTUP_SCRIPT_NAME) devnull = open(os.devnull, 'w') subprocess.Popen(["/bin/bash", startup_script, "-p " + mount_point], diff --git a/tests/distro/test_resourceDisk.py b/tests/distro/test_resourceDisk.py index 6a8284faa3..198fd49d1e 100644 --- a/tests/distro/test_resourceDisk.py +++ b/tests/distro/test_resourceDisk.py @@ -19,11 +19,7 @@ # http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx from tests.tools import * -import azurelinuxagent.distro.default.resourceDisk as resourceDisk -from azurelinuxagent.distro.loader import get_distro -from azurelinuxagent.distro.default.protocolUtil import * -import azurelinuxagent.utils.fileutil as fileutil - +from azurelinuxagent.daemon.resourcedisk import get_resourcedisk_handler class TestResourceDisk(AgentTestCase): def test_mkfile(self): @@ -34,7 +30,7 @@ def test_mkfile(self): os.remove(test_file) # execute - get_distro().resource_disk_handler.mkfile(test_file, file_size) + get_resourcedisk_handler().mkfile(test_file, file_size) # assert assert os.path.exists(test_file) diff --git a/tests/distro/test_scvmm.py b/tests/distro/test_scvmm.py new file mode 100644 index 0000000000..18252d4db0 --- /dev/null +++ b/tests/distro/test_scvmm.py @@ -0,0 +1,111 @@ +# Copyright 2014 Microsoft Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Requires Python 2.4+ and Openssl 1.0+ +# +# Implements parts of RFC 2131, 1541, 1497 and +# http://msdn.microsoft.com/en-us/library/cc227282%28PROT.10%29.aspx +# http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx + +<<<<<<< HEAD + +import mock +from tests.tools import * + +import azurelinuxagent.daemon.scvmm as scvmm +from azurelinuxagent.daemon.main import * +from azurelinuxagent.common.osutil.default import DefaultOSUtil +======= +import azurelinuxagent.distro.default.scvmm as scvmm +import azurelinuxagent.distro.default.osutil as osutil +import mock +from tests.tools import * +from azurelinuxagent.distro.loader import get_distro +from azurelinuxagent.distro.default.protocolUtil import * + +>>>>>>> ab2e3c3... fixes for SCVMM + +class TestSCVMM(AgentTestCase): + def test_scvmm_detection_with_file(self): + # setup + conf.get_dvd_mount_point = Mock(return_value=self.tmp_dir) + conf.get_detect_scvmm_env = Mock(return_value=True) + scvmm_file = os.path.join(self.tmp_dir, scvmm.VMM_CONF_FILE_NAME) + fileutil.write_file(scvmm_file, "") + + patch = mock.patch.object(scvmm.ScvmmHandler, 'start_scvmm_agent').start() + + # execute +<<<<<<< HEAD + get_daemon_handler().daemon() +======= + get_distro().daemon_handler.daemon() +>>>>>>> ab2e3c3... fixes for SCVMM + + # assert + patch.assert_called() + + # cleanup + os.remove(scvmm_file) + + + def test_scvmm_detection_with_multiple_cdroms(self): + # setup + conf.get_dvd_mount_point = Mock(return_value=self.tmp_dir) + conf.get_detect_scvmm_env = Mock(return_value=True) + +<<<<<<< HEAD + patch_mount = mock.patch.object(DefaultOSUtil, 'mount_dvd').start() + + # execute + with patch('os.listdir', return_value=["sr0", "sr1", "sr2"]): + scvmm.ScvmmHandler().detect_scvmm_env() +======= + patch_mount = mock.patch.object(osutil.DefaultOSUtil, 'mount_dvd').start() + + # execute + with patch('os.listdir', return_value=["sr0", "sr1", "sr2"]): + scvmm.ScvmmHandler(get_distro()).detect_scvmm_env() +>>>>>>> ab2e3c3... fixes for SCVMM + + # assert + assert patch_mount.call_count == 3 + assert patch_mount.call_args_list[0][1]['dvd'] == '/dev/sr0' + assert patch_mount.call_args_list[1][1]['dvd'] == '/dev/sr1' + assert patch_mount.call_args_list[2][1]['dvd'] == '/dev/sr2' + + + def test_scvmm_detection_without_file(self): + # setup + conf.get_dvd_mount_point = Mock(return_value=self.tmp_dir) + conf.get_detect_scvmm_env = Mock(return_value=True) + scvmm_file = os.path.join(self.tmp_dir, scvmm.VMM_CONF_FILE_NAME) + if os.path.exists(scvmm_file): + os.remove(scvmm_file) + + patch_start = mock.patch.object(scvmm.ScvmmHandler, 'start_scvmm_agent').start() + + # execute +<<<<<<< HEAD + scvmm.ScvmmHandler().detect_scvmm_env() +======= + scvmm.ScvmmHandler(get_distro()).detect_scvmm_env() +>>>>>>> ab2e3c3... fixes for SCVMM + + # assert + patch_start.assert_not_called() + + +if __name__ == '__main__': + unittest.main()