def _test_get_cbinit_dir(self, mock_escape_path, mock_ntpath, arch="None", no_error=True): mock_excute_function = mock.Mock() mock_location = mock.Mock() mock_location.strip.return_value = "fake_location" mock_escape_path.return_value = "fake location" side_effect_list = [arch] + [mock_location] if arch == "AMD64": side_effect_list.append(mock_location) side_effect_list.append("fake_status") if no_error: side_effect_list.append("true") else: side_effect_list.append("fake_status") mock_excute_function.side_effect = side_effect_list if no_error: mock_ntpath.join.return_value = "fake path" result = windows.get_cbinit_dir(mock_excute_function) self.assertEqual(result, "fake path") mock_ntpath.join.assert_called_once_with( "fake_location", "Cloudbase Solutions", "Cloudbase-Init") else: from argus import exceptions with self.assertRaises(exceptions.ArgusError) as ex: result = windows.get_cbinit_dir(mock_excute_function) self.assertEqual(ex.exception.message, 'Cloudbase-Init ' 'installation directory not found')
def _test_get_cbinit_dir(self, mock_escape_path, mock_ntpath, arch="None", no_error=True): mock_excute_function = mock.Mock() mock_location = mock.Mock() mock_location.strip.return_value = "fake_location" mock_escape_path.return_value = "fake location" side_effect_list = [arch] + [mock_location] if arch == "AMD64": side_effect_list.append(mock_location) side_effect_list.append("fake_status") if no_error: side_effect_list.append("true") else: side_effect_list.append("fake_status") mock_excute_function.side_effect = side_effect_list if no_error: mock_ntpath.join.return_value = "fake path" result = windows.get_cbinit_dir(mock_excute_function) self.assertEqual(result, "fake path") mock_ntpath.join.assert_called_once_with("fake_location", "Cloudbase Solutions", "Cloudbase-Init") else: from argus import exceptions with self.assertRaises(exceptions.ArgusError) as ex: result = windows.get_cbinit_dir(mock_excute_function) self.assertEqual( ex.exception.message, 'Cloudbase-Init ' 'installation directory not found')
def install_cbinit(self): """Proceed on checking if Cloudbase-Init should be installed.""" try: introspection.get_cbinit_dir(self._execute) except exceptions.ArgusError: self._backend.remote_client.manager.install_cbinit() self._grab_cbinit_installation_log() else: # If the directory already exists, # we won't be installing Cloudbase-Init. LOG.info("Cloudbase-Init is already installed, " "skipping installation.")
def replace_install(self): """Replace the cb-init installed files with the downloaded ones. For the same file names, there will be a replace. The new ones will just be added and the other files will be left there. So it's more like an update. """ link = self._conf.argus.patch_install if not link: return LOG.info("Replacing cloudbaseinit's files...") LOG.debug("Download and extract installation bundle.") if link.startswith("\\\\"): cmd = 'copy "{}" "C:\\install.zip"'.format(link) else: cmd = ("powershell Invoke-webrequest -uri " "{} -outfile 'C:\\install.zip'" .format(link)) self._execute(cmd) cmds = [ "Add-Type -A System.IO.Compression.FileSystem", "[IO.Compression.ZipFile]::ExtractToDirectory(" "'C:\\install.zip', 'C:\\install')" ] cmd = 'powershell {}'.format("; ".join(cmds)) self._execute(cmd) LOG.debug("Replace old files with the new ones.") cbdir = introspection.get_cbinit_dir(self._execute) self._execute('xcopy /y /e /q "C:\\install\\Cloudbase-Init"' ' "{}"'.format(cbdir))
def replace_install(self): """Replace the cb-init installed files with the downloaded ones. For the same file names, there will be a replace. The new ones will just be added and the other files will be left there. So it's more like an update. """ link = self._conf.argus.patch_install if not link: return LOG.info("Replacing cloudbaseinit's files...") LOG.debug("Download and extract installation bundle.") if link.startswith("\\\\"): cmd = 'copy "{}" "C:\\install.zip"'.format(link) self._execute(cmd, command_type=util.CMD) else: location = r'C:\install.zip' self._backend.remote_client.manager.download( uri=link, location=location) cmds = [ "Add-Type -A System.IO.Compression.FileSystem", "[IO.Compression.ZipFile]::ExtractToDirectory(" "'C:\\install.zip', 'C:\\install')" ] cmd = '{}'.format("; ".join(cmds)) self._execute(cmd, command_type=util.POWERSHELL) LOG.debug("Replace old files with the new ones.") cbdir = introspection.get_cbinit_dir(self._execute) self._execute('xcopy /y /e /q "C:\\install\\Cloudbase-Init"' ' "{}"'.format(cbdir), command_type=util.CMD)
def wait_cbinit_finalization(self): cbdir = introspection.get_cbinit_dir(self._execute) paths = [ ntpath.join(cbdir, "log", name) for name in ["cloudbase-init-unattend.log", "cloudbase-init.log"] ] self._wait_cbinit_finalization(searched_paths=paths)
def _config_specific_paths(self): """Populate the ConfigParser object with instance specific values.""" cbinit_dir = introspect.get_cbinit_dir(self._execute) self.set_conf_value("bsdtar_path", ntpath.join(cbinit_dir, r'bin\bsdtar.exe')) self.set_conf_value("local_scripts_path", ntpath.join(cbinit_dir, 'LocalScripts\\')) self.set_conf_value("logdir", ntpath.join(cbinit_dir, "log\\")) self.set_conf_value("mtools_path", ntpath.join(cbinit_dir, "bin\\"))
def pre_sysprep(self): super(CloudbaseinitLocalScriptsRecipe, self).pre_sysprep() LOG.info("Download reboot-required local script.") cbdir = introspection.get_cbinit_dir(self._execute) cmd = ("powershell Invoke-WebRequest -uri " "{}/windows/reboot.cmd -outfile " "'C:\\Scripts\\reboot.cmd'") cmd = cmd.format(self._conf.argus.resources, cbdir) self._execute(cmd)
def cbinit_cleanup(self): """Cleans up Cloudbase-Init if the installation failed.""" LOG.debug("Cleaning up Cloudbase-Init from the instance.") try: cbinit_dir = introspection.get_cbinit_dir(self._execute) self.rmdir(ntpath.dirname(cbinit_dir)) except exceptions.ArgusError as exc: LOG.warning("Could not cleanup Cloudbase-Init: %s", exc) return False else: return True
def wait_cbinit_finalization(self): cbdir = introspection.get_cbinit_dir(self._execute) paths = [ntpath.join(cbdir, "log", name) for name in ["cloudbase-init-unattend.log", "cloudbase-init.log"]] LOG.debug("Check the heartbeat patch ...") self._backend.remote_client.manager.check_cbinit_service( searched_paths=paths) LOG.debug("Wait for the CloudBase Initit service to stop ...") self._backend.remote_client.manager.wait_cbinit_service()
def wait_cbinit_finalization(self): cbdir = introspection.get_cbinit_dir(self._execute) paths = [ntpath.join(cbdir, "log", name) for name in ["cloudbase-init-unattend.log", "cloudbase-init.log"]] LOG.debug("Check the heartbeat patch ...") self._backend.remote_client.manager.check_cbinit_service( searched_paths=paths) LOG.debug("Wait for the Cloudbase-Init service to stop ...") self._backend.remote_client.manager.wait_cbinit_service()
def inject_cbinit_config(self): """Inject the Cloudbase-Init config in the right place.""" cbinit_dir = introspection.get_cbinit_dir(self._execute) conf_dir = ntpath.join(cbinit_dir, "conf") needed_directories = [ ntpath.join(cbinit_dir, "log"), conf_dir, ] for directory in needed_directories: self._make_dir_if_needed(directory) self._cbinit_conf.apply_config(conf_dir) self._cbinit_unattend_conf.apply_config(conf_dir)
def get_cb_init_files(self, location, files): LOG.info("Obtaining Cloudbase-Init files from %s" % location) if not CONFIG.argus.output_directory: LOG.warning("The output directory wasn't given, " "the files will not be grabbed.") return instance_id = self._backend.instance_server()['id'] scenario_name = argus_log.get_log_extra_item(LOG, 'scenario') cbdir = introspection.get_cbinit_dir(self._execute) cb_files = files renamed_cb_files = [] cb_files_path = [] renamed_cb_files_path = [] for cb_file in cb_files: renamed_cb_files.append(scenario_name + "-" + instance_id + "-" + cb_file) for cb_file in cb_files: file_path = os.path.join(cbdir, r"{location}\{file}".format( location=location, file=cb_file)) renamed_path = (os.path.join(cbdir, (r"{location}\{scenario}-{instance}-" "-{file}". format(location=location, scenario=scenario_name, instance=instance_id, file=cb_file)))) cb_files_path.append(file_path) renamed_cb_files_path.append(renamed_path) files_to_rename = list(zip(cb_files_path, renamed_cb_files_path)) for current_name, renamed in files_to_rename: self._backend.remote_client.manager.copy_file(current_name, renamed) source_destination = list(zip(renamed_cb_files_path, renamed_cb_files)) for source, destination in source_destination: path = os.path.join(CONFIG.argus.output_directory, destination) self.transfer_encoded_file_b64(source, path)
def get_cb_init_files(self, location, files): LOG.info("Obtaining Cloudbase-Init files from %s" % location) if not CONFIG.argus.output_directory: LOG.warning("The output directory wasn't given, " "the files will not be grabbed.") return instance_id = self._backend.instance_server()['id'] scenario_name = argus_log.get_log_extra_item(LOG, 'scenario') cbdir = introspection.get_cbinit_dir(self._execute) cb_files = files renamed_cb_files = [] cb_files_path = [] renamed_cb_files_path = [] for cb_file in cb_files: renamed_cb_files.append(scenario_name + "-" + instance_id + "-" + cb_file) for cb_file in cb_files: file_path = os.path.join( cbdir, r"{location}\{file}".format(location=location, file=cb_file)) renamed_path = (os.path.join( cbdir, (r"{location}\{scenario}-{instance}-" "-{file}".format(location=location, scenario=scenario_name, instance=instance_id, file=cb_file)))) cb_files_path.append(file_path) renamed_cb_files_path.append(renamed_path) files_to_rename = list(zip(cb_files_path, renamed_cb_files_path)) for current_name, renamed in files_to_rename: self._backend.remote_client.manager.copy_file( current_name, renamed) source_destination = list(zip(renamed_cb_files_path, renamed_cb_files)) for source, destination in source_destination: path = os.path.join(CONFIG.argus.output_directory, destination) self.transfer_encoded_file_b64(source, path)
def replace_install(self): """Replace the Cloudbase-Init installed files with the downloaded ones. For the same file names, there will be a replace. The new ones will just be added and the other files will be left there. So it's more like an update. """ link = CONFIG.argus.patch_install if not link: return LOG.info("Replacing Cloudbase-Init's files with %s", link) LOG.debug("Download and extract installation bundle.") if link.startswith("\\\\"): cmd = 'copy "{}" "C:\\install.zip"'.format(link) self._execute(cmd, command_type=util.CMD) else: location = r'C:\install.zip' self._backend.remote_client.manager.download( uri=link, location=location) cmds = [ "Add-Type -A System.IO.Compression.FileSystem", "[IO.Compression.ZipFile]::ExtractToDirectory(" "'C:\\install.zip', 'C:\\install')" ] cmd = '{}'.format("; ".join(cmds)) self._execute(cmd, command_type=util.POWERSHELL) LOG.debug("Replace old files with the new ones.") cbdir = introspection.get_cbinit_dir(self._execute) self._execute('xcopy /y /e /q "C:\\install"' ' "{}"'.format(cbdir), command_type=util.CMD) # Update the new changes resource_location = "windows/updateCbinit.ps1" self._backend.remote_client.manager.execute_powershell_resource_script( resource_location=resource_location)