def __buildah_import_image_from_tar(image_tar_file, container_name): """Import a container image using buildah form a TAR file. Parameters ---------- image_tar_file : str Path to TAR file to import as a container image. container_name : str name for the working container. Returns ------- str Name of the imported container. """ # import image tar file to vfs file system try: sh.buildah( # pylint: disable=no-member 'from', '--storage-driver', 'vfs', '--name', container_name, f"docker-archive:{image_tar_file}", _out=sys.stdout, _err=sys.stderr, _tee='err') except sh.ErrorReturnCode as error: raise RuntimeError( f'Unexpected runtime error importing the image ({image_tar_file}): {error}' ) from error return container_name
def create_container_from_image( image_address, repository_type='container-storage:' ): """Import a container image using buildah form a TAR file. Parameters ---------- image_address : str Image tag to create a container from. ex: * localhost/my-app:latest * quay.io/my-org/my-app:latest * docker-archive:/local/path/to/my-app-container-image.tar container_name : str name for the working container. repository_type : str The type of repository to mount the given image tag from. See https://github.com/containers/skopeo for details on different repository types. Returns ------- str Name of the imported container. Raises ------ RuntimeError If error importing image. """ container_name = None try: buildah_from_out_buff = StringIO() buildah_from_out_callback = create_sh_redirect_to_multiple_streams_fn_callback([ sys.stdout, buildah_from_out_buff ]) sh.buildah( # pylint: disable=no-member 'from', f"{repository_type}{image_address}", _out=buildah_from_out_callback, _err=sys.stderr, _tee='err' ) container_name = buildah_from_out_buff.getvalue().rstrip() except sh.ErrorReturnCode as error: raise RuntimeError( f'Error creating container from image ({image_address}): {error}' ) from error return container_name
def _run_step(self): # pylint: disable=too-many-locals """Runs the TSSC step implemented by this StepImplementer. Returns ------- dict Results of running this step. """ image_tar_file = '' if(self.get_step_results(DefaultSteps.CREATE_CONTAINER_IMAGE) and \ self.get_step_results(DefaultSteps.CREATE_CONTAINER_IMAGE).get('image-tar-file')): image_tar_file = self.\ get_step_results(DefaultSteps.CREATE_CONTAINER_IMAGE)['image-tar-file'] else: raise RuntimeError('Missing image tar file from ' + DefaultSteps.CREATE_CONTAINER_IMAGE) log_level = 'info' if self.get_config_value('log-level'): log_level = self.get_config_value('log-level') buildah_containers_pre_import_result = sh.buildah( # pylint: disable=no-member '--storage-driver', 'vfs', 'containers', '-q', _out=sys.stdout, _err=sys.stderr, _tee=True) num_containers = buildah_containers_pre_import_result.stdout.count( b'\n') if num_containers > 0: raise ValueError('Zero vfs base containers should be running') try: # import image tar file to vfs file system sh.buildah( # pylint: disable=no-member 'from', '--storage-driver', 'vfs', '--log-level', log_level, f"docker-archive:{image_tar_file}", _out=sys.stdout, _err=sys.stderr) # get container id buildah_containers_result = sh.buildah( # pylint: disable=no-member '--storage-driver', 'vfs', 'containers', '-q', _out=sys.stdout, _err=sys.stderr, _tee=True) container_id = buildah_containers_result.stdout.rstrip() print(f"container_id to scan = {container_id}") # baking `buildah unshare` command to wrap other buildah commands with # so that container does not need to be running in a privilaged mode to be able # to function buildah_unshare_comand = sh.buildah.bake('unshare') # pylint: disable=no-member # mount the container filesystem and get mount path # # NOTE: run in the context of `buildah unshare` so that container does not # need to be run in a privilaged mode buildah_mount_command = buildah_unshare_comand.bake( "buildah", "mount") buildah_mount_result = buildah_mount_command('--storage-driver', 'vfs', container_id, _out=sys.stdout, _err=sys.stderr, _tee=True) mount_path = buildah_mount_result.stdout.rstrip() print(f"mount_path to scan = {mount_path}") # Execute scan in the context of buildah unshare # # NOTE: run in the context of `buildah unshare` so that container does not # need to be run in a privilaged mode scan_input_file = self.get_config_value('scap-input-file').rstrip() scan_output_absolute_path = self.write_working_file( 'scap-compliance-output.txt', b'') scan_report_absolute_path = self.write_working_file( 'scap-compliance-report.html', b'') oscap_chroot_command = buildah_unshare_comand.bake("oscap-chroot") oscap_result = oscap_chroot_command(mount_path, 'oval', 'eval', '--report', scan_report_absolute_path, scan_input_file, _out=sys.stdout, _err=sys.stderr, _tee=True) oscap_result_file = open(scan_output_absolute_path, "w+") oscap_result_file.write(oscap_result.stdout.decode("utf-8")) oscap_result_file.close() print( "Compliance Scan Completed. Report found at following path: " + scan_report_absolute_path) except sh.ErrorReturnCode as error: raise RuntimeError('Unexpected runtime error') from error results = { 'result': { 'success': True, 'message': 'container-image-static-compliance-scan step completed', }, 'report-artifacts': [{ 'name': 'container-image-static-compliance-scan result set', 'path': 'file://' + scan_report_absolute_path }] } return results