Ejemplo n.º 1
0
    def _update(self, f_uncompress, f_compress):
        image = self.get_namespace_data(action="download-action",
                                        label=self.key,
                                        key="file")
        compression = self.get_namespace_data(action="download-action",
                                              label=self.key,
                                              key="compression")
        decompressed = self.get_namespace_data(action="download-action",
                                               label=self.key,
                                               key="decompressed")
        self.logger.info("Modifying %r", image)
        tempdir = self.mkdtemp()
        # Some images are kept compressed. We should decompress first
        if compression and not decompressed:
            self.logger.debug("* decompressing (%s)", compression)
            image = decompress_file(image, compression)
        # extract the archive
        self.logger.debug("* extracting %r", image)
        f_uncompress(image, tempdir)
        os.unlink(image)

        # Add overlays
        self.logger.debug("Overlays:")
        for overlay in self.params["overlays"]:
            label = "%s.%s" % (self.key, overlay)
            overlay_image = None
            path = None
            if overlay == "lava":
                overlay_image = self.get_namespace_data(
                    action="compress-overlay", label="output", key="file")
                path = "/"
            else:
                overlay_image = self.get_namespace_data(
                    action="download-action", label=label, key="file")
                path = self.params["overlays"][overlay]["path"]
            # Take off initial "/" from path, extract relative to this directory
            extract_path = os.path.join(tempdir, path[1:])
            if overlay == "lava" or self.params["overlays"][overlay][
                    "format"] == "tar":
                self.logger.debug("- %s: untar %r to %r", label, overlay_image,
                                  extract_path)
                # In the "validate" function, we check that path startswith '/'
                # and does not contains '..'
                untar_file(overlay_image, extract_path)
            else:
                self.logger.debug("- %s: cp %r to %r", label, overlay_image,
                                  extract_path)
                shutil.copy(overlay_image, extract_path)

        # Recreating the archive
        self.logger.debug("* archiving %r", image)
        f_compress(tempdir, image)
        if compression and not decompressed:
            self.logger.debug("* compressing (%s)", compression)
            image = compress_file(image, compression)
Ejemplo n.º 2
0
    def run(self, connection, max_end_time, args=None):  # pylint: disable=too-many-locals
        if not self.parameters.get('ramdisk', None):  # idempotency
            return connection
        if self.skip:
            return connection
        connection = super(CompressRamdisk, self).run(connection, max_end_time,
                                                      args)
        ramdisk_dir = self.get_namespace_data(action='extract-overlay-ramdisk',
                                              label='extracted_ramdisk',
                                              key='directory')
        ramdisk_data = self.get_namespace_data(
            action='extract-overlay-ramdisk', label='ramdisk_file', key='file')
        if not ramdisk_dir:
            raise LAVABug("Unable to find unpacked ramdisk")
        if not ramdisk_data:
            raise LAVABug("Unable to find ramdisk directory")
        if self.parameters.get('preseed', None):
            if self.parameters["deployment_data"].get("preseed_to_ramdisk",
                                                      None):
                # download action must have completed to get this far
                # some installers (centos) cannot fetch the preseed file via tftp.
                # Instead, put the preseed file into the ramdisk using a given name
                # from deployment_data which we can use in the boot commands.
                filename = self.parameters["deployment_data"][
                    "preseed_to_ramdisk"]
                self.logger.info("Copying preseed file into ramdisk: %s",
                                 filename)
                shutil.copy(
                    self.get_namespace_data(action='download-action',
                                            label='preseed',
                                            key='file'),
                    os.path.join(ramdisk_dir, filename))
                self.set_namespace_data(action=self.name,
                                        label='file',
                                        key='preseed_local',
                                        value=filename)

        with chdir(ramdisk_dir):
            self.logger.info("Building ramdisk %s containing %s", ramdisk_data,
                             ramdisk_dir)
            cmd = "find . | cpio --create --format='newc' > %s" % ramdisk_data
            try:
                # safe to use shell=True here, no external arguments
                log = subprocess.check_output(cmd,
                                              shell=True,
                                              stderr=subprocess.STDOUT)
            except OSError as exc:
                raise InfrastructureError(
                    'Unable to create cpio filesystem: %s' % exc)
            # lazy-logging would mean that the quoting of cmd causes invalid YAML
            self.logger.debug("%s\n%s" % (cmd, log))  # pylint: disable=logging-not-lazy

            # we need to compress the ramdisk with the same method is was submitted with
            compression = self.parameters['ramdisk'].get('compression', None)
            final_file = compress_file(ramdisk_data, compression)

        tftp_dir = os.path.dirname(
            self.get_namespace_data(action='download-action',
                                    label='ramdisk',
                                    key='file'))

        if self.add_header == 'u-boot':
            ramdisk_uboot = final_file + ".uboot"
            self.logger.debug("Adding RAMdisk u-boot header.")
            cmd = ("mkimage -A %s -T ramdisk -C none -d %s %s" %
                   (self.mkimage_arch, final_file, ramdisk_uboot)).split(' ')
            if not self.run_command(cmd):
                raise InfrastructureError(
                    "Unable to add uboot header to ramdisk")
            final_file = ramdisk_uboot

        full_path = os.path.join(tftp_dir, os.path.basename(final_file))
        shutil.move(final_file, full_path)
        self.logger.debug("rename %s to %s", final_file, full_path)
        self.set_namespace_data(action=self.name,
                                label='file',
                                key='full-path',
                                value=full_path)

        if self.parameters['to'] == 'tftp':
            suffix = self.get_namespace_data(action='tftp-deploy',
                                             label='tftp',
                                             key='suffix')
            if not suffix:
                suffix = ''
            self.set_namespace_data(action=self.name,
                                    label='file',
                                    key='ramdisk',
                                    value=os.path.join(
                                        suffix, "ramdisk",
                                        os.path.basename(final_file)))
        else:
            self.set_namespace_data(action=self.name,
                                    label='file',
                                    key='ramdisk',
                                    value=final_file)
        return connection
Ejemplo n.º 3
0
    def run(self, connection, max_end_time):
        if not self.parameters.get("ramdisk"):  # idempotency
            return connection
        if self.skip:
            return connection
        connection = super().run(connection, max_end_time)
        ramdisk_dir = self.get_namespace_data(action="extract-overlay-ramdisk",
                                              label="extracted_ramdisk",
                                              key="directory")
        ramdisk_data = self.get_namespace_data(
            action="extract-overlay-ramdisk", label="ramdisk_file", key="file")
        if not ramdisk_dir:
            raise LAVABug("Unable to find unpacked ramdisk")
        if not ramdisk_data:
            raise LAVABug("Unable to find ramdisk directory")
        if self.parameters.get("preseed"):
            if self.parameters["deployment_data"].get("preseed_to_ramdisk"):
                # download action must have completed to get this far
                # some installers (centos) cannot fetch the preseed file via tftp.
                # Instead, put the preseed file into the ramdisk using a given name
                # from deployment_data which we can use in the boot commands.
                filename = self.parameters["deployment_data"][
                    "preseed_to_ramdisk"]
                self.logger.info("Copying preseed file into ramdisk: %s",
                                 filename)
                shutil.copy(
                    self.get_namespace_data(action="download-action",
                                            label="preseed",
                                            key="file"),
                    os.path.join(ramdisk_dir, filename),
                )
                self.set_namespace_data(action=self.name,
                                        label="file",
                                        key="preseed_local",
                                        value=filename)

        with chdir(ramdisk_dir):
            self.logger.info("Building ramdisk %s containing %s", ramdisk_data,
                             ramdisk_dir)
            cmd = "find . | cpio --create --format='newc' > %s" % ramdisk_data
            try:
                log = subprocess.check_output(  # nosec - safe to use shell=True here, no external arguments
                    cmd,
                    shell=True,
                    stderr=subprocess.STDOUT)
                log = log.decode("utf-8", errors="replace")
            except OSError as exc:
                raise InfrastructureError(
                    "Unable to create cpio filesystem: %s" % exc)
            # lazy-logging would mean that the quoting of cmd causes invalid YAML
            self.logger.debug("%s\n%s" % (cmd, log))

            # we need to compress the ramdisk with the same method is was submitted with
            compression = self.parameters["ramdisk"].get("compression")
            final_file = compress_file(ramdisk_data, compression)

        tftp_dir = os.path.dirname(
            self.get_namespace_data(action="download-action",
                                    label="ramdisk",
                                    key="file"))

        if self.add_header == "u-boot":
            ramdisk_uboot = final_file + ".uboot"
            self.logger.debug("Adding RAMdisk u-boot header.")
            cmd = ("mkimage -A %s -T ramdisk -C none -d %s %s" %
                   (self.mkimage_arch, final_file, ramdisk_uboot)).split(" ")
            if not self.run_command(cmd):
                raise InfrastructureError(
                    "Unable to add uboot header to ramdisk")
            final_file = ramdisk_uboot

        full_path = os.path.join(tftp_dir, os.path.basename(final_file))
        shutil.move(final_file, full_path)
        self.logger.debug("rename %s to %s", final_file, full_path)
        self.set_namespace_data(action=self.name,
                                label="file",
                                key="full-path",
                                value=full_path)

        if self.parameters["to"] == "tftp":
            suffix = self.get_namespace_data(action="tftp-deploy",
                                             label="tftp",
                                             key="suffix")
            if not suffix:
                suffix = ""
            self.set_namespace_data(
                action=self.name,
                label="file",
                key="ramdisk",
                value=os.path.join(suffix, "ramdisk",
                                   os.path.basename(final_file)),
            )
        else:
            self.set_namespace_data(action=self.name,
                                    label="file",
                                    key="ramdisk",
                                    value=final_file)
        return connection
Ejemplo n.º 4
0
    def run(self, connection, max_end_time, args=None):  # pylint: disable=too-many-locals
        if not self.parameters.get('ramdisk', None):  # idempotency
            return connection
        if self.skip:
            return connection
        connection = super(CompressRamdisk, self).run(connection, max_end_time, args)
        ramdisk_dir = self.get_namespace_data(
            action='extract-overlay-ramdisk', label='extracted_ramdisk', key='directory')
        ramdisk_data = self.get_namespace_data(
            action='extract-overlay-ramdisk', label='ramdisk_file', key='file')
        if not ramdisk_dir:
            raise LAVABug("Unable to find unpacked ramdisk")
        if not ramdisk_data:
            raise LAVABug("Unable to find ramdisk directory")
        if self.parameters.get('preseed', None):
            if self.parameters["deployment_data"].get("preseed_to_ramdisk", None):
                # download action must have completed to get this far
                # some installers (centos) cannot fetch the preseed file via tftp.
                # Instead, put the preseed file into the ramdisk using a given name
                # from deployment_data which we can use in the boot commands.
                filename = self.parameters["deployment_data"]["preseed_to_ramdisk"]
                self.logger.info("Copying preseed file into ramdisk: %s", filename)
                shutil.copy(self.get_namespace_data(
                    action='download-action', label='preseed',
                    key='file'), os.path.join(ramdisk_dir, filename))
                self.set_namespace_data(action=self.name, label='file', key='preseed_local', value=filename)

        with chdir(ramdisk_dir):
            self.logger.info("Building ramdisk %s containing %s",
                             ramdisk_data, ramdisk_dir)
            cmd = "find . | cpio --create --format='newc' > %s" % ramdisk_data
            try:
                # safe to use shell=True here, no external arguments
                log = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
            except OSError as exc:
                raise InfrastructureError('Unable to create cpio filesystem: %s' % exc)
            # lazy-logging would mean that the quoting of cmd causes invalid YAML
            self.logger.debug("%s\n%s" % (cmd, log))  # pylint: disable=logging-not-lazy

            # we need to compress the ramdisk with the same method is was submitted with
            compression = self.parameters['ramdisk'].get('compression', None)
            final_file = compress_file(ramdisk_data, compression)

        tftp_dir = os.path.dirname(self.get_namespace_data(
            action='download-action', label='ramdisk', key='file'))

        if self.add_header == 'u-boot':
            ramdisk_uboot = final_file + ".uboot"
            self.logger.debug("Adding RAMdisk u-boot header.")
            cmd = ("mkimage -A %s -T ramdisk -C none -d %s %s" % (self.mkimage_arch, final_file, ramdisk_uboot)).split(' ')
            if not self.run_command(cmd):
                raise InfrastructureError("Unable to add uboot header to ramdisk")
            final_file = ramdisk_uboot

        full_path = os.path.join(tftp_dir, os.path.basename(final_file))
        shutil.move(final_file, full_path)
        self.logger.debug("rename %s to %s", final_file, full_path)
        self.set_namespace_data(
            action=self.name, label='file', key='full-path', value=full_path)

        if self.parameters['to'] == 'tftp':
            suffix = self.get_namespace_data(action='tftp-deploy', label='tftp', key='suffix')
            if not suffix:
                suffix = ''
            self.set_namespace_data(
                action=self.name,
                label='file', key='ramdisk', value=os.path.join(suffix, "ramdisk", os.path.basename(final_file)))
        else:
            self.set_namespace_data(
                action=self.name,
                label='file', key='ramdisk', value=final_file)
        return connection
Ejemplo n.º 5
0
    def run(self, connection, max_end_time):
        if not self.parameters.get("ramdisk"):  # idempotency
            return connection
        if self.skip:
            return connection
        connection = super().run(connection, max_end_time)
        ramdisk_dir = self.get_namespace_data(action="extract-overlay-ramdisk",
                                              label="extracted_ramdisk",
                                              key="directory")
        ramdisk_data = self.get_namespace_data(
            action="extract-overlay-ramdisk", label="ramdisk_file", key="file")
        if not ramdisk_dir:
            raise LAVABug("Unable to find unpacked ramdisk")
        if not ramdisk_data:
            raise LAVABug("Unable to find ramdisk directory")
        if self.parameters.get("preseed"):
            if self.parameters["deployment_data"].get("preseed_to_ramdisk"):
                # download action must have completed to get this far
                # some installers (centos) cannot fetch the preseed file via tftp.
                # Instead, put the preseed file into the ramdisk using a given name
                # from deployment_data which we can use in the boot commands.
                filename = self.parameters["deployment_data"][
                    "preseed_to_ramdisk"]
                self.logger.info("Copying preseed file into ramdisk: %s",
                                 filename)
                shutil.copy(
                    self.get_namespace_data(action="download-action",
                                            label="preseed",
                                            key="file"),
                    os.path.join(ramdisk_dir, filename),
                )
                self.set_namespace_data(action=self.name,
                                        label="file",
                                        key="preseed_local",
                                        value=filename)

        self.logger.info("Building ramdisk %s containing %s", ramdisk_data,
                         ramdisk_dir)
        self.logger.debug(">> %s", cpio(ramdisk_dir, ramdisk_data))

        # we need to compress the ramdisk with the same method is was submitted with
        compression = self.parameters["ramdisk"].get("compression")
        final_file = compress_file(ramdisk_data, compression)

        tftp_dir = os.path.dirname(
            self.get_namespace_data(action="download-action",
                                    label="ramdisk",
                                    key="file"))

        if self.add_header == "u-boot":
            ramdisk_uboot = final_file + ".uboot"
            self.logger.debug("Adding RAMdisk u-boot header.")
            cmd = ("mkimage -A %s -T ramdisk -C none -d %s %s" %
                   (self.mkimage_arch, final_file, ramdisk_uboot)).split(" ")
            if not self.run_command(cmd):
                raise InfrastructureError(
                    "Unable to add uboot header to ramdisk")
            final_file = ramdisk_uboot

        full_path = os.path.join(tftp_dir, os.path.basename(final_file))
        shutil.move(final_file, full_path)
        self.logger.debug("rename %s to %s", final_file, full_path)
        self.set_namespace_data(action=self.name,
                                label="file",
                                key="full-path",
                                value=full_path)

        if self.parameters["to"] == "tftp":
            suffix = self.get_namespace_data(action="tftp-deploy",
                                             label="tftp",
                                             key="suffix")
            if not suffix:
                suffix = ""
            self.set_namespace_data(
                action=self.name,
                label="file",
                key="ramdisk",
                value=os.path.join(suffix, "ramdisk",
                                   os.path.basename(final_file)),
            )
        else:
            self.set_namespace_data(action=self.name,
                                    label="file",
                                    key="ramdisk",
                                    value=final_file)
        return connection