def test_installs_new_bootloader(self): contents = factory.make_bytes() loader = self.make_file(contents=contents) install_dir = self.make_dir() dest = os.path.join(install_dir, factory.make_name("loader")) atomic_copy(loader, dest) self.assertThat(dest, FileContains(contents))
def _find_and_copy_bootloaders(self, destination, log_missing=True): """Attempt to copy bootloaders from the previous snapshot :param destination: The path to link the bootloaders to :param log_missing: Log missing files, default True :return: True if all bootloaders have been found and copied, False otherwise. """ boot_sources_base = os.path.realpath(os.path.join(destination, "..")) previous_snapshot = os.path.join(boot_sources_base, "current") files_found = True for bootloader_file in self.bootloader_files: bootloader_src = os.path.join(previous_snapshot, bootloader_file) bootloader_src = os.path.realpath(bootloader_src) bootloader_dst = os.path.join(destination, bootloader_file) if os.path.exists(bootloader_src): # Copy files if their realpath is inside the previous snapshot # as once we're done the previous snapshot is deleted. Symlinks # to other areas of the filesystem are maintained. if boot_sources_base in bootloader_src: atomic_copy(bootloader_src, bootloader_dst) else: atomic_symlink(bootloader_src, bootloader_dst) else: files_found = False if log_missing: err_msg = ( "Unable to find a copy of %s in the SimpleStream or a " "previously downloaded copy. The %s bootloader type " "may not work." % (bootloader_file, self.name) ) try_send_rack_event(EVENT_TYPES.RACK_IMPORT_ERROR, err_msg) maaslog.error(err_msg) return files_found
def test_skips_if_unchanged(self): contents = factory.make_bytes() dest = self.make_file(contents=contents) age_file(dest, 100) original_write_time = os.stat(dest).st_mtime loader = self.make_file(contents=contents) atomic_copy(loader, dest) self.assertThat(dest, FileContains(contents)) self.assertEqual(original_write_time, os.stat(dest).st_mtime)
def test_sweeps_aside_dot_new_if_any(self): contents = factory.make_bytes() loader = self.make_file(contents=contents) dest = self.make_file(contents="Old contents") temp_file = "%s.new" % dest factory.make_file(os.path.dirname(temp_file), name=os.path.basename(temp_file)) atomic_copy(loader, dest) self.assertThat(dest, FileContains(contents))
def test_replaces_file_if_changed(self): contents = factory.make_bytes() loader = self.make_file(contents=contents) dest = self.make_file(contents="Old contents") atomic_copy(loader, dest) self.assertThat(dest, FileContains(contents))
def test_integration(self): loader_contents = factory.make_bytes() loader = self.make_file(contents=loader_contents) destination = self.make_file() atomic_copy(loader, destination) self.assertThat(destination, FileContains(loader_contents))
def _find_and_copy_bootloaders(self, destination, log_missing=True, bootloader_files=None): if bootloader_files is None: bootloader_files = self.bootloader_files boot_sources_base = os.path.realpath(os.path.join(destination, '..')) default_search_path = os.path.join(boot_sources_base, 'current') syslinux_search_path = os.path.join(default_search_path, 'syslinux') # In addition to the default search path search the previous # syslinux subdir as well. Previously MAAS didn't copy all of the # files required for PXE into the root tftp path. Also search the # paths the syslinux-common and pxelinux Ubuntu packages installs files # to on Xenial. search_paths = [ default_search_path, syslinux_search_path, '/usr/lib/PXELINUX', '/usr/lib/syslinux/modules/bios', ] files_found = [] for search_path in search_paths: for bootloader_file in bootloader_files: bootloader_src = os.path.join(search_path, bootloader_file) bootloader_src = os.path.realpath(bootloader_src) bootloader_dst = os.path.join(destination, bootloader_file) if (os.path.exists(bootloader_src) and not os.path.exists(bootloader_dst)): # If the file was found in a previous snapshot copy it as # once we're done the previous snapshot will be deleted. If # the file was found elsewhere on the filesystem create a # symlink so we stay current with that source. if boot_sources_base in bootloader_src: atomic_copy(bootloader_src, bootloader_dst) else: atomic_symlink(bootloader_src, bootloader_dst) files_found.append(bootloader_file) missing_files = [ bootloader_file for bootloader_file in bootloader_files if bootloader_file not in files_found ] if missing_files != []: files_are_missing = True if log_missing: err_msg = ( "Unable to find a copy of %s in the SimpleStream or in " "the system search paths %s. The %s bootloader type may " "not work." % (', '.join(missing_files), ', '.join(search_paths), self.name)) try_send_rack_event(EVENT_TYPES.RACK_IMPORT_ERROR, err_msg) maaslog.error(err_msg) else: files_are_missing = False syslinux_search_paths = [ syslinux_search_path, '/usr/lib/syslinux/modules/bios', ] for search_path in syslinux_search_paths: if os.path.exists(search_path): syslinux_src = os.path.realpath(search_path) syslinux_dst = os.path.join(destination, 'syslinux') if destination in os.path.realpath(syslinux_src): shutil.copy(bootloader_src, bootloader_dst) else: atomic_symlink(syslinux_src, syslinux_dst) break return files_are_missing