def test_dict_of_config_values(self, container_registry_login_mock): registries = { 'registry.redhat.io': ConfigValue({ 'username': '******', 'password': '******' }), 'registry.internal.example.xyz': ConfigValue({ 'username': '******', 'password': '******' }) } container_registries_login(registries) calls = [ call(container_registry_uri='registry.redhat.io', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=True, containers_config_auth_file=None), call(container_registry_uri='registry.internal.example.xyz', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=True, containers_config_auth_file=None) ] container_registry_login_mock.assert_has_calls(calls)
def test_given_command_short_name_exists(self, container_registry_login_mock): registries = { 'registry.redhat.io': { 'username': '******', 'password': '******' }, 'registry.internal.example.xyz': { 'username': '******', 'password': '******' } } container_registries_login(registries=registries, container_command_short_name='fake-podman') calls = [ call(container_registry_uri='registry.redhat.io', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=True, containers_config_auth_file=None, container_command_short_name='fake-podman'), call(container_registry_uri='registry.internal.example.xyz', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=True, containers_config_auth_file=None, container_command_short_name='fake-podman') ] container_registry_login_mock.assert_has_calls(calls)
def test_list_of_dicts_with_containers_config_auth_file( self, container_registry_login_mock): registries = { 'registry.redhat.io': { 'username': '******', 'password': '******', 'tls-verify': False }, 'registry.internal.example.xyz': { 'username': '******', 'password': '******', 'tls-verify': True } } container_registries_login(registries, '/tmp/mock/auth.json') calls = [ call(container_registry_uri='registry.redhat.io', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=True, containers_config_auth_file='/tmp/mock/auth.json'), call(container_registry_uri='registry.internal.example.xyz', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=True, containers_config_auth_file='/tmp/mock/auth.json') ] container_registry_login_mock.assert_has_calls(calls)
def test_list_of_dicts_with_tls_verify_value( self, container_registry_login_mock): registries = [{ 'uri': 'registry.redhat.io', 'username': '******', 'password': '******', 'tls-verify': False }, { 'uri': 'registry.internal.example.xyz', 'username': '******', 'password': '******', 'tls-verify': True }] container_registries_login(registries) calls = [ call(container_registry_uri='registry.redhat.io', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=False, containers_config_auth_file=None, container_command_short_name=None), call(container_registry_uri='registry.internal.example.xyz', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=True, containers_config_auth_file=None, container_command_short_name=None) ] container_registry_login_mock.assert_has_calls(calls)
def test_dict_of_dicts_with_uri_keys(self, container_registry_login_mock): registries = { 'redhat': { 'uri': 'registry.redhat.io', 'username': '******', 'password': '******' }, 'internal': { 'uri': 'registry.internal.example.xyz', 'username': '******', 'password': '******' } } container_registries_login(registries) calls = [ call(container_registry_uri='registry.redhat.io', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=True, containers_config_auth_file=None, container_command_short_name=None), call(container_registry_uri='registry.internal.example.xyz', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=True, containers_config_auth_file=None, container_command_short_name=None) ] container_registry_login_mock.assert_has_calls(calls)
def test_list_of_dicts(self, container_registry_login_mock): registries = [{ 'uri': 'registry.redhat.io', 'username': '******', 'password': '******' }, { 'uri': 'registry.internal.example.xyz', 'username': '******', 'password': '******' }] container_registries_login(registries, containers_config_tls_verify=False) calls = [ call(container_registry_uri='registry.redhat.io', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=False, containers_config_auth_file=None), call(container_registry_uri='registry.internal.example.xyz', container_registry_username='******', container_registry_password='******', container_registry_tls_verify=False, containers_config_auth_file=None) ] container_registry_login_mock.assert_has_calls(calls)
def _run_step(self): """Runs the step implemented by this StepImplementer. Returns ------- StepResult Object containing the dictionary results of this step. """ step_result = StepResult.from_step_implementer(self) image_version = self.get_value('container-image-version').lower() application_name = self.get_value('application-name') service_name = self.get_value('service-name') organization = self.get_value('organization') image_tar_file = self.get_value('image-tar-file') destination_url = self.get_value('destination-url') image_registry_uri = destination_url image_registry_organization = organization image_repository = f"{application_name}-{service_name}" image_tag = f"{image_registry_uri}/{image_registry_organization}" \ f"/{image_repository}:{image_version}" try: # login to any provider container registries # NOTE: important to specify the auth file because depending on the context this is # being run in python process may not have permissions to default location containers_config_auth_file = self.get_value('containers-config-auth-file') container_registries_login( registries=self.get_value('container-registries'), containers_config_auth_file=containers_config_auth_file ) # push image sh.skopeo.copy( # pylint: disable=no-member f"--src-tls-verify={str(self.get_value('src-tls-verify'))}", f"--dest-tls-verify={str(self.get_value('dest-tls-verify'))}", f"--authfile={containers_config_auth_file}", f'docker-archive:{image_tar_file}', f'docker://{image_tag}', _out=sys.stdout, _err=sys.stderr, _tee='err' ) except sh.ErrorReturnCode as error: step_result.success = False step_result.message = f'Error pushing container image ({image_tar_file}) ' \ f' to tag ({image_tag}) using skopeo: {error}' step_result.add_artifact(name='container-image-registry-uri', value=image_registry_uri) step_result.add_artifact( name='container-image-registry-organization', value=image_registry_organization ) step_result.add_artifact(name='container-image-repository', value=image_repository) step_result.add_artifact(name='container-image-name', value=image_repository) step_result.add_artifact(name='container-image-version', value=image_version) step_result.add_artifact(name='container-image-tag', value=image_tag) return step_result
def test_list_of_dicts_missing_username(self): registries = [{'uri': 'registry.redhat.io', 'password': '******'}] with self.assertRaisesRegex( AssertionError, r"Configuration for container registry " r"must specify a 'username': {'uri': 'registry.redhat.io', 'password': '******'}" ): container_registries_login(registries)
def test_dict_of_dicts_missing_password(self): registries = {'registry.redhat.io': {'username': '******'}} with self.assertRaisesRegex( AssertionError, r"Configuration for container registry \(registry.redhat.io\) " r"must specify a 'password': {'username': '******'}" ): container_registries_login(registries)
def test_registries_none(self, container_registry_login): registries = None container_registries_login(registries) container_registry_login.assert_not_called()
def _run_step(self): """Runs the step implemented by this StepImplementer. Returns ------- StepResult Object containing the dictionary results of this step. """ step_result = StepResult.from_step_implementer(self) # get the pgp private key to sign the image with signer_pgp_private_key = self.get_value([ 'signer-pgp-private-key', 'container-image-signer-pgp-private-key' ]) # get the uri to the image to sign container_image_address = self._get_deploy_time_container_image_address( ) image_signatures_directory = self.create_working_dir_sub_dir( sub_dir_relative_path='image-signature') try: # import the PGP key and get the finger print signer_pgp_private_key_fingerprint = import_pgp_key( pgp_private_key=signer_pgp_private_key) step_result.add_artifact( name='container-image-signature-signer-private-key-fingerprint', value=signer_pgp_private_key_fingerprint) # login to any provider container registries # NOTE 1: can not use auth file, even though we want to, because podman image sign # does not accept authfile. # https://github.com/containers/podman/issues/10866 # NOTE 2: have to force login to use podman because even though logging in with # any of the tools should work, in testing the podman sign only worked # from within the python virtual environment if the login happened with podman. container_registries_login( registries=self.get_value('container-registries'), containers_config_tls_verify=util.strtobool( self.get_value('src-tls-verify')), container_command_short_name='podman') # sign the image signature_file_path = PodmanSign.__sign_image( pgp_private_key_fingerprint=signer_pgp_private_key_fingerprint, image_signatures_directory=image_signatures_directory, container_image_address=container_image_address) step_result.add_artifact( name='container-image-signed-address', value=container_image_address, ) step_result.add_artifact( name='container-image-signature-file-path', value=signature_file_path, ) signature_name = os.path.relpath(signature_file_path, image_signatures_directory) step_result.add_artifact(name='container-image-signature-name', value=signature_name) # upload the image signature container_image_signature_destination_url = self.get_value( 'container-image-signature-destination-url') if container_image_signature_destination_url: container_image_signature_destination_uri = \ f"{container_image_signature_destination_url}/{signature_name}" step_result.add_artifact( name='container-image-signature-uri', description='URI of the uploaded container image signature', value=container_image_signature_destination_uri) upload_result = upload_file( file_path=signature_file_path, destination_uri=container_image_signature_destination_uri, username=self.get_value( 'container-image-signature-destination-username'), password=self.get_value( 'container-image-signature-destination-password')) step_result.add_artifact( name='container-image-signature-upload-results', description='Results of uploading the container image signature' \ ' to the given destination.', value=upload_result ) except (RuntimeError, StepRunnerException) as error: step_result.success = False step_result.message = str(error) return step_result
def _run_step(self): """Runs the step implemented by this StepImplementer. Returns ------- StepResult Object containing the dictionary results of this step. """ step_result = StepResult.from_step_implementer(self) # get config image_spec_file = self.get_value('imagespecfile') tls_verify = self.get_value('tls-verify') if isinstance(tls_verify, str): tls_verify = bool(util.strtobool(tls_verify)) # create local build tag image_registry_organization = self.get_value('organization') build_full_tag, build_short_tag, image_registry_uri, image_repository, image_version = \ determine_container_image_build_tag_info( image_version=self.get_value('container-image-version'), organization=image_registry_organization, application_name=self.get_value('application-name'), service_name=self.get_value('service-name') ) try: # login to any provider container registries # NOTE: important to specify the auth file because depending on the context this is # being run in python process may not have permissions to default location containers_config_auth_file = self.get_value('containers-config-auth-file') if not containers_config_auth_file: containers_config_auth_file = os.path.join( self.work_dir_path, 'container-auth.json' ) container_registries_login( registries=self.get_value('container-registries'), containers_config_auth_file=containers_config_auth_file, containers_config_tls_verify=tls_verify ) # perform build sh.buildah.bud( # pylint: disable=no-member '--format=' + self.get_value('format'), '--tls-verify=' + str(tls_verify).lower(), '--layers', '-f', image_spec_file, '-t', build_full_tag, '--authfile', containers_config_auth_file, self.get_value('context'), _out=sys.stdout, _err=sys.stderr, _tee='err' ) except sh.ErrorReturnCode as error: # pylint: disable=undefined-variable step_result.success = False step_result.message = 'Issue invoking buildah bud with given image ' \ f'specification file ({image_spec_file}): {error}' return step_result # add artifacts step_result.add_artifact( name='container-image-registry-uri', value=image_registry_uri, description='Registry URI poriton of the container image tag' \ ' of the built container image.' ) step_result.add_artifact( name='container-image-registry-organization', value=image_registry_organization, description='Organization portion of the container image tag' \ ' of the built container image.' ) step_result.add_artifact( name='container-image-repository', value=image_repository, description='Repository portion of the container image tag' \ ' of the built container image.' ) step_result.add_artifact( name='container-image-name', value=image_repository, description='Another way to reference the' \ ' repository portion of the container image tag of the built container image.' ) step_result.add_artifact( name='container-image-version', value=image_version, description='Version portion of the container image tag of the built container image.' ) step_result.add_artifact( name='container-image-tag', value=build_full_tag, description='Full container image tag of the built container,' \ ' including the registry URI.' ) step_result.add_artifact( name='container-image-short-tag', value=build_short_tag, description='Short container image tag of the built container image,' \ ' excluding the registry URI.' ) return step_result
def _run_step(self): """Runs the step implemented by this StepImplementer. Returns ------- StepResult Object containing the dictionary results of this step. """ step_result = StepResult.from_step_implementer(self) context = self.get_value('context') image_spec_file = self.get_value('imagespecfile') image_spec_file_location = context + '/' + image_spec_file application_name = self.get_value('application-name') service_name = self.get_value('service-name') tls_verify = self.get_value('tls-verify') if not os.path.exists(image_spec_file_location): step_result.success = False step_result.message = 'Image specification file does not exist in location: ' \ f'{image_spec_file_location}' return step_result image_tag_version = self.get_value('container-image-version') if image_tag_version is None: image_tag_version = 'latest' print('No image tag version found in metadata. Using latest') destination = "localhost/{application_name}/{service_name}".format( application_name=application_name, service_name=service_name) tag = "{destination}:{version}".format(destination=destination, version=image_tag_version) try: # login to any provider container registries # NOTE: important to specify the auth file because depending on the context this is # being run in python process may not have permissions to default location containers_config_auth_file = self.get_value( 'containers-config-auth-file') container_registries_login( registries=self.get_value('container-registries'), containers_config_auth_file=containers_config_auth_file, containers_config_tls_verify=tls_verify) # perform build # # NOTE: using --storage-driver=vfs so that container does not need escalated privileges # vfs is less efficient then fuse (which would require host mounts), # but such is the price we pay for security. sh.buildah.bud( # pylint: disable=no-member '--storage-driver=vfs', '--format=' + self.get_value('format'), '--tls-verify=' + str(tls_verify).lower(), '--layers', '-f', image_spec_file, '-t', tag, '--authfile', containers_config_auth_file, context, _out=sys.stdout, _err=sys.stderr, _tee='err') step_result.add_artifact(name='container-image-version', value=tag) except sh.ErrorReturnCode as error: # pylint: disable=undefined-variable step_result.success = False step_result.message = 'Issue invoking buildah bud with given image ' \ f'specification file ({image_spec_file}): {error}' return step_result image_tar_file = f'image-{application_name}-{service_name}-{image_tag_version}.tar' image_tar_path = os.path.join(self.work_dir_path, image_tar_file) try: # Check to see if the tar docker-archive file already exists # this needs to be run as buildah does not support overwritting # existing files. # # NOTE: using --storage-driver=vfs so that container does not need escalated privileges # vfs is less efficient then fuse (which would require host mounts), # but such is the price we pay for security. if os.path.exists(image_tar_path): os.remove(image_tar_path) sh.buildah.push( # pylint: disable=no-member '--storage-driver=vfs', tag, "docker-archive:" + image_tar_path, _out=sys.stdout, _err=sys.stderr, _tee='err') step_result.add_artifact(name='image-tar-file', value=image_tar_path) except sh.ErrorReturnCode as error: # pylint: disable=undefined-variable step_result.success = False step_result.message = f'Issue invoking buildah push to tar file ' \ f'({image_tar_path}): {error}' return step_result return step_result
def _run_step(self): # pylint: disable=too-many-locals """Runs the step implemented by this StepImplementer. Returns ------- StepResult Object containing the dictionary results of this step. """ step_result = StepResult.from_step_implementer(self) # get src image config pull_registry_type = self.get_value([ 'container-image-pull-registry-type', 'container-image-registry-type' ]) container_image_pull_address = self.get_value( ['container-image-pull-address', 'container-image-build-address']) source_tls_verify = self.get_value( ['source-tls-verify', 'src-tls-verify']) if isinstance(source_tls_verify, str): source_tls_verify = bool(util.strtobool(source_tls_verify)) # create destination config push_registry_type = self.get_value([ 'container-image-push-registry-type', 'container-image-registry-type' ]) container_image_push_registry = self.get_value( ['container-image-push-registry', 'destination-url']) container_image_push_repository = self.get_value( ['container-image-push-repository', 'container-image-repository']) container_image_push_tag = self.get_value([ 'container-image-push-tag', 'container-image-tag', 'container-image-version' ]) dest_tls_verify = self.get_value('dest-tls-verify') if isinstance(dest_tls_verify, str): dest_tls_verify = bool(util.strtobool(dest_tls_verify)) container_image_push_short_address = \ f"{container_image_push_repository}:{container_image_push_tag}" container_image_push_address_by_tag = f"{container_image_push_registry}" \ f"/{container_image_push_short_address}" try: # login to any provider container registries # NOTE: important to specify the auth file because depending on the context this is # being run in python process may not have permissions to default location containers_config_auth_file = self.get_value( 'containers-config-auth-file') if not containers_config_auth_file: containers_config_auth_file = os.path.join( self.work_dir_path, 'container-auth.json') container_registries_login( registries=self.get_value('container-registries'), containers_config_auth_file=containers_config_auth_file, containers_config_tls_verify=dest_tls_verify) # push image sh.skopeo.copy( # pylint: disable=no-member f"--src-tls-verify={str(source_tls_verify).lower()}", f"--dest-tls-verify={str(dest_tls_verify).lower()}", f"--authfile={containers_config_auth_file}", f'{pull_registry_type}{container_image_pull_address}', f'{push_registry_type}{container_image_push_address_by_tag}', _out=sys.stdout, _err=sys.stderr, _tee='err') except sh.ErrorReturnCode as error: step_result.success = False step_result.message = f'Error pushing container image ({container_image_pull_address}) ' \ f' to tag ({container_image_push_address_by_tag}) using skopeo: {error}' # add address part artifacts step_result.add_artifact( name='container-image-push-registry', value=container_image_push_registry, description= 'Container image registry container image was pushed to.') step_result.add_artifact( name='container-image-push-repository', value=container_image_push_repository, description= 'Container image repository container image was pushed to.') step_result.add_artifact( name='container-image-push-tag', value=container_image_push_tag, description='Container image tag container image was pushed to.') # add address by tag artifacts step_result.add_artifact( name='container-image-address-by-tag', value=container_image_push_address_by_tag, description='Pushed container image address by tag.') step_result.add_artifact( name='container-image-short-address-by-tag', value=container_image_push_short_address, description= 'Pushed container image short address (no registry) by tag.') # add address by digest artifacts if step_result.success: try: print("Get pushed container image digest") container_image_digest = get_container_image_digest( container_image_address=container_image_push_address_by_tag, containers_config_auth_file=containers_config_auth_file) container_image_short_address_by_digest = \ f"{container_image_push_repository}@{container_image_digest}" container_image_address_by_digest = \ f"{container_image_push_registry}/{container_image_short_address_by_digest}" step_result.add_artifact( name='container-image-push-digest', value=container_image_digest, description= 'Container image digest container image was pushed to.') step_result.add_artifact( name='container-image-address-by-digest', value=container_image_address_by_digest, description='Pushed container image address by digest.') step_result.add_artifact( name='container-image-short-address-by-digest', value=container_image_short_address_by_digest, description= 'Pushed container image short address (no registry) by digest.' ) except RuntimeError as error: step_result.success = False step_result.message = f"Error getting pushed container image digest: {error}" return step_result
def _run_step(self): """Runs the step implemented by this StepImplementer. Returns ------- StepResult Object containing the dictionary results of this step. """ step_result = StepResult.from_step_implementer(self) # get config image_pull_tag = self.get_value( ['container-image-pull-tag', 'container-image-tag']) pull_repository_type = self.get_value([ 'container-image-pull-repository-type', 'container-image-repository-type' ]) push_repository_type = self.get_value([ 'container-image-push-repository-type', 'container-image-repository-type' ]) dest_tls_verify = self.get_value('dest-tls-verify') if isinstance(dest_tls_verify, str): dest_tls_verify = bool(util.strtobool(dest_tls_verify)) source_tls_verify = self.get_value( ['source-tls-verify', 'src-tls-verify']) if isinstance(source_tls_verify, str): source_tls_verify = bool(util.strtobool(source_tls_verify)) # create push tag image_version = self.get_value('container-image-version') if image_version is None: image_version = 'latest' print('No image tag version found in metadata. Using latest') image_version = image_version.lower() image_registry_uri = self.get_value('destination-url') image_registry_organization = self.get_value('organization') image_repository = f"{self.get_value('application-name')}-{self.get_value('service-name')}" image_push_short_tag = f"{image_registry_organization}/{image_repository}:{image_version}" image_push_tag = f"{image_registry_uri}/{image_push_short_tag}" try: # login to any provider container registries # NOTE: important to specify the auth file because depending on the context this is # being run in python process may not have permissions to default location containers_config_auth_file = self.get_value( 'containers-config-auth-file') if not containers_config_auth_file: containers_config_auth_file = os.path.join( self.work_dir_path, 'container-auth.json') container_registries_login( registries=self.get_value('container-registries'), containers_config_auth_file=containers_config_auth_file, containers_config_tls_verify=dest_tls_verify) # push image sh.skopeo.copy( # pylint: disable=no-member f"--src-tls-verify={str(source_tls_verify).lower()}", f"--dest-tls-verify={str(dest_tls_verify).lower()}", f"--authfile={containers_config_auth_file}", f'{pull_repository_type}{image_pull_tag}', f'{push_repository_type}{image_push_tag}', _out=sys.stdout, _err=sys.stderr, _tee='err') except sh.ErrorReturnCode as error: step_result.success = False step_result.message = f'Error pushing container image ({image_pull_tag}) ' \ f' to tag ({image_push_tag}) using skopeo: {error}' # add artifacts step_result.add_artifact( name='container-image-registry-uri', value=image_registry_uri, description='Registry URI poriton of the container image tag' \ ' of the pushed container image.' ) step_result.add_artifact( name='container-image-registry-organization', value=image_registry_organization, description='Organization portion of the container image tag' \ ' of the pushed container image.' ) step_result.add_artifact( name='container-image-repository', value=image_repository, description='Repository portion of the container image tag' \ ' of the pushed container image.' ) step_result.add_artifact( name='container-image-name', value=image_repository, description='Another way to reference the' \ ' repository portion of the container image tag of the pushed container image.' ) step_result.add_artifact( name='container-image-version', value=image_version, description= 'Version portion of the container image tag of the pushed container image.' ) step_result.add_artifact( name='container-image-tag', value=image_push_tag, description='Full container image tag of the pushed container,' \ ' including the registry URI.' ) step_result.add_artifact( name='container-image-short-tag', value=image_push_short_tag, description='Short container image tag of the pushed container image,' \ ' excluding the registry URI.' ) return step_result
def _run_step(self): """Runs the step implemented by this StepImplementer. Returns ------- StepResult Object containing the dictionary results of this step. """ step_result = StepResult.from_step_implementer(self) # get values builder_image = self.get_value('s2i-builder-image') # determine tls flag tls_verify = self.get_value('tls-verify') if isinstance(tls_verify, str): tls_verify = bool(util.strtobool(tls_verify)) if tls_verify: s2i_tls_flags = ['--tlsverify'] else: s2i_tls_flags = [] # determine the generated imagespec file s2i_working_dir = self.create_working_dir_sub_dir('s2i-context') imagespecfile = self.write_working_file( os.path.join(s2i_working_dir, 'Containerfile.s2i-gen')) # determine image scripts url flags # use user provided url if given, # else try and inspect from builder image s2i_image_scripts_url = self.get_value('s2i-image-scripts-url') if not s2i_image_scripts_url: print( 'Attempt to inspect builder image for label for image scripts url' ) # attempt to auth with container image registries # login to any provider container registries # NOTE: important to specify the auth file because depending on the context this is # being run in python process may not have permissions to default location containers_config_auth_file = self.get_value( 'containers-config-auth-file') if not containers_config_auth_file: containers_config_auth_file = os.path.join( self.work_dir_path, 'container-auth.json') try: container_registries_login( registries=self.get_value('container-registries'), containers_config_auth_file=containers_config_auth_file, containers_config_tls_verify=tls_verify) except RuntimeError as error: step_result.message += "WARNING: error authenticating with" \ " container image registries to be able to pull s2i builder image" \ f" to inspect for image scripts url: {error}\n" # if not given, attempt to get from builder image labels try: container_image_details = inspect_container_image( container_image_address=builder_image, containers_config_auth_file=containers_config_auth_file) s2i_image_scripts_url = container_image_details['OCIv1']['config']['Labels']\ [SourceToImage.CONTAINER_LABEL_SCRIPTS_URL] except RuntimeError as error: step_result.message += "WARNING: failed to inspect s2i builder image" \ f" ({builder_image}) to dynamically determine image scripts url." \ f" S2I default will be used: {error}\n" except KeyError as error: step_result.message += "WARNING: failed to find s2i scripts url label" \ f" ({SourceToImage.CONTAINER_LABEL_SCRIPTS_URL}) on s2i builder image" \ f" ({builder_image}) to dynamically determine image scripts url." \ f" S2I default will be used: Could not find key ({error}).\n" # if determined image scripts url set the flag # else s2i will use its default (image:///usr/libexec/s2i) if s2i_image_scripts_url: s2i_image_scripts_url_flags = [ '--image-scripts-url', s2i_image_scripts_url ] else: s2i_image_scripts_url_flags = [] try: # perform build print( 'Use s2i to generate imagespecfile and accompanying resources') sh.s2i.build( # pylint: disable=no-member self.get_value('context'), builder_image, '--loglevel', self.get_value('s2i-loglevel'), *s2i_tls_flags, '--as-dockerfile', imagespecfile, *s2i_image_scripts_url_flags, *self.get_value('s2i-additional-arguments'), _out=sys.stdout, _err=sys.stderr, _tee='err') except sh.ErrorReturnCode as error: # pylint: disable=undefined-variable step_result.success = False step_result.message += f'Issue invoking s2i build: {error}' # add artifacts step_result.add_artifact( name='imagespecfile', value=imagespecfile, description= 'File defining the container image to build generated by s2i') step_result.add_artifact( name='context', value=s2i_working_dir, description= 'Context to use when building the imagespecfile generated by S2I.') return step_result
def _run_step(self): """Runs the step implemented by this StepImplementer. Returns ------- StepResult Object containing the dictionary results of this step. """ step_result = StepResult.from_step_implementer(self) # get config image_spec_file = self.get_value('imagespecfile') tls_verify = self.get_value('tls-verify') if isinstance(tls_verify, str): tls_verify = bool(util.strtobool(tls_verify)) # create local build tag container_image_build_address, container_image_build_short_address, \ contaimer_image_registry, container_image_repository, container_image_tag = \ determine_container_image_address_info( contaimer_image_registry='localhost', container_image_tag=self.get_value([ 'container-image-tag', 'container-image-version' ]), organization=self.get_value('organization'), application_name=self.get_value('application-name'), service_name=self.get_value('service-name') ) try: # login to any provider container registries # NOTE: important to specify the auth file because depending on the context this is # being run in python process may not have permissions to default location containers_config_auth_file = self.get_value('containers-config-auth-file') if not containers_config_auth_file: containers_config_auth_file = os.path.join( self.work_dir_path, 'container-auth.json' ) container_registries_login( registries=self.get_value('container-registries'), containers_config_auth_file=containers_config_auth_file, containers_config_tls_verify=tls_verify ) # perform build sh.buildah.bud( # pylint: disable=no-member '--format=' + self.get_value('format'), '--tls-verify=' + str(tls_verify).lower(), '--layers', '-f', image_spec_file, '-t', container_image_build_address, '--authfile', containers_config_auth_file, self.get_value('context'), _out=sys.stdout, _err=sys.stderr, _tee='err' ) except sh.ErrorReturnCode as error: # pylint: disable=undefined-variable step_result.success = False step_result.message = 'Issue invoking buildah bud with given image ' \ f'specification file ({image_spec_file}): {error}' # get image digest container_image_digest = None if step_result.success: try: print("Get container image digest") container_image_digest = get_container_image_digest( container_image_address=container_image_build_address ) except RuntimeError as error: step_result.success = False step_result.message = f"Error getting built container image digest: {error}" # add artifacts add_container_build_step_result_artifacts( step_result=step_result, contaimer_image_registry=contaimer_image_registry, container_image_repository=container_image_repository, container_image_tag=container_image_tag, container_image_digest=container_image_digest, container_image_build_address=container_image_build_address, container_image_build_short_address=container_image_build_short_address ) return step_result