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()
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)
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)
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)
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)