コード例 #1
0
    def _inject_into_repo_files(self, build_dir: BuildDir):
        """Inject repo files into a relative directory inside the build context"""
        host_repos_path = build_dir.path / RELATIVE_REPOS_PATH
        self.log.info("creating directory for yum repos: %s", host_repos_path)
        os.mkdir(host_repos_path)
        allow_repo_dir_in_dockerignore(build_dir.path)

        for repo in self.yum_repos[build_dir.platform]:
            # Update every repo accordingly in a repofile
            # input_buf ---- updated ----> updated_buf
            with StringIO(repo.content.decode()) as input_buf, StringIO(
            ) as updated_buf:
                for line in input_buf:
                    updated_buf.write(line)
                    # Apply sslcacert to every repo in a repofile
                    if line.lstrip().startswith(
                            '[') and self._builder_ca_bundle:
                        updated_buf.write(
                            f'sslcacert=/tmp/{self._ca_bundle_pem}\n')

                yum_repo = YumRepo(repourl=repo.dst_filename,
                                   content=updated_buf.getvalue(),
                                   dst_repos_dir=host_repos_path,
                                   add_hash=False)
                yum_repo.write_content()
コード例 #2
0
    def run(self):
        """
        build image inside current environment;
        it's expected this may run within (privileged) docker container


        Input:
            df_dir
            image

        Output:
            BuildResult
            built_image_info
            image_id
        """
        builder = self.workflow.builder

        allow_repo_dir_in_dockerignore(builder.df_dir)
        logs_gen = self.tasker.build_image_from_path(
            builder.df_dir, builder.image, buildargs=builder.buildargs)

        self.log.debug('build is submitted, waiting for it to finish')
        try:
            command_result = wait_for_command(logs_gen)
        except docker.errors.APIError as ex:
            return BuildResult(logs=[], fail_reason=ex.explanation)

        if command_result.is_failed():
            return BuildResult(logs=command_result.logs,
                               fail_reason=command_result.error)
        else:
            image_id = builder.get_built_image_info()['Id']
            if ':' not in image_id:
                # Older versions of the daemon do not include the prefix
                image_id = 'sha256:{}'.format(image_id)

            return BuildResult(logs=command_result.logs, image_id=image_id)
コード例 #3
0
    def run(self):
        """
        build image inside current environment;
        it's expected this may run within (privileged) docker container


        Input:
            df_dir
            image

        Output:
            BuildResult
            built_image_info
            image_id
        """
        builder = self.workflow.builder

        allow_repo_dir_in_dockerignore(builder.df_dir)
        logs_gen = self.tasker.build_image_from_path(builder.df_dir,
                                                     builder.image)

        self.log.debug('build is submitted, waiting for it to finish')
        try:
            command_result = wait_for_command(logs_gen)
        except docker.errors.APIError as ex:
            return BuildResult(logs=[], fail_reason=ex.explanation)

        if command_result.is_failed():
            return BuildResult(logs=command_result.logs,
                               fail_reason=command_result.error)
        else:
            image_id = builder.get_built_image_info()['Id']
            if ':' not in image_id:
                # Older versions of the daemon do not include the prefix
                image_id = 'sha256:{}'.format(image_id)

            return BuildResult(logs=command_result.logs, image_id=image_id)
コード例 #4
0
    def run(self):
        """
        Build image inside current environment using imagebuilder;
        It's expected this may run within (privileged) docker container.

        Returns:
            BuildResult
        """
        builder = self.workflow.builder

        image = builder.image.to_str()

        allow_repo_dir_in_dockerignore(builder.df_dir)

        process_args = ['imagebuilder', '-t', image]
        for buildarg, buildargval in builder.buildargs.items():
            process_args.append('--build-arg')
            process_args.append('%s=%s' % (buildarg, buildargval))
        process_args.append(builder.df_dir)

        ib_process = subprocess.Popen(process_args,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.STDOUT,
                                      universal_newlines=True,
                                      encoding='utf-8',
                                      errors='replace')

        self.log.debug(
            'imagebuilder build has begun; waiting for it to finish')
        self.log.debug(process_args)
        output = []
        while True:
            poll = ib_process.poll()
            out = ib_process.stdout.readline()
            if out:
                self.log.info('%s', out.rstrip())
                output.append(out)
            elif poll is not None:
                break

        if ib_process.returncode != 0:
            # in the case of an apparent failure, single out the last line to
            # include in the failure summary.
            err = output[
                -1] if output else "<imagebuilder had bad exit code but no output>"
            return BuildResult(
                logs=output,
                fail_reason="image build failed (rc={}): {}".format(
                    ib_process.returncode, err),
            )

        image_id = builder.get_built_image_info()['Id']
        if ':' not in image_id:
            # Older versions of the daemon do not include the prefix
            image_id = 'sha256:{}'.format(image_id)

        # since we need no squash, export the image for local operations like squash would have
        self.log.info("fetching image %s from docker", image)
        output_path = os.path.join(self.workflow.source.workdir,
                                   EXPORTED_SQUASHED_IMAGE_NAME)
        try:
            # docker-py 1.x
            with open(output_path, "w") as image_file:
                image_file.write(self.tasker.get_image(image).data)
        except AttributeError:
            # docker-py 3.x
            with open(output_path, "wb") as image_file:
                for chunk in self.tasker.get_image(image):
                    image_file.write(chunk)

        img_metadata = get_exported_image_metadata(output_path,
                                                   IMAGE_TYPE_DOCKER_ARCHIVE)
        self.workflow.exported_image_sequence.append(img_metadata)

        return BuildResult(logs=output,
                           image_id=image_id,
                           skip_layer_squash=True)
コード例 #5
0
    def run(self):
        """
        Build image inside current environment using imagebuilder;
        It's expected this may run within (privileged) docker container.

        Returns:
            BuildResult
        """
        builder = self.workflow.builder

        image = builder.image.to_str()
        # TODO: directly invoke go imagebuilder library in shared object via python module
        kwargs = dict(stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
        encoding_params = dict(encoding='utf-8', errors='replace')
        if not PY2:
            kwargs.update(encoding_params)

        allow_repo_dir_in_dockerignore(builder.df_dir)
        ib_process = subprocess.Popen(['imagebuilder', '-t', image, builder.df_dir], **kwargs)

        self.log.debug('imagebuilder build has begun; waiting for it to finish')
        output = []
        while True:
            poll = ib_process.poll()
            out = ib_process.stdout.readline()
            out = out.decode(**encoding_params) if PY2 else out
            if out:
                self.log.info('%s', out.rstrip())
                output.append(out)
            elif poll is not None:
                break

        if ib_process.returncode != 0:
            # in the case of an apparent failure, single out the last line to
            # include in the failure summary.
            err = output[-1] if output else "<imagebuilder had bad exit code but no output>"
            return BuildResult(
                logs=output,
                fail_reason="image build failed (rc={}): {}".format(ib_process.returncode, err),
            )

        image_id = builder.get_built_image_info()['Id']
        if ':' not in image_id:
            # Older versions of the daemon do not include the prefix
            image_id = 'sha256:{}'.format(image_id)

        # since we need no squash, export the image for local operations like squash would have
        self.log.info("fetching image %s from docker", image)
        output_path = os.path.join(self.workflow.source.workdir, EXPORTED_SQUASHED_IMAGE_NAME)
        try:
            # docker-py 1.x
            with open(output_path, "w") as image_file:
                image_file.write(self.tasker.d.get_image(image).data)
        except AttributeError:
            # docker-py 3.x
            with open(output_path, "wb") as image_file:
                for chunk in self.tasker.d.get_image(image):
                    image_file.write(chunk)

        img_metadata = get_exported_image_metadata(output_path, IMAGE_TYPE_DOCKER_ARCHIVE)
        self.workflow.exported_image_sequence.append(img_metadata)

        return BuildResult(logs=output, image_id=image_id, skip_layer_squash=True)