Ejemplo n.º 1
0
 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))
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
 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)
Ejemplo n.º 4
0
 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))
Ejemplo n.º 5
0
 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))
Ejemplo n.º 6
0
 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))
Ejemplo n.º 7
0
    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