-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create-container-image/SourceToImage - init add
- Loading branch information
Showing
5 changed files
with
1,069 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
231 changes: 231 additions & 0 deletions
231
src/ploigos_step_runner/step_implementers/create_container_image/source_to_image.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
"""`StepImplementer` for the `create-container-image step` using Source-to-Image (s2i) | ||
to create a Containerfile that can be built by another `StepImplementer`, such as Buildah. | ||
Step Configuration | ||
------------------ | ||
Step configuration expected as input to this step. | ||
Could come from: | ||
* static configuration | ||
* runtime configuration | ||
* previous step results | ||
Configuration Key | Required? | Default | Description | ||
------------------------------|-----------|---------|----------- | ||
`s2i-builder-image` | True | | Container image tag to use as the s2i builder image. | ||
`s2i-image-scripts-url` | False | | Location of the s2i scripts in the given `s2i-builder-image`. \ | ||
If not given s2i will assume they are in `image:///usr/libexec/s2i`. \ | ||
<br/> \ | ||
EX:<br/> \ | ||
s2i-builder-image: registry.redhat.io/redhat-openjdk-18/openjdk18-openshift <br/> \ | ||
s2i-image-scripts-url: `image:///usr/local/s2i` | ||
`s2i-loglevel` | False | 1 | s2i log level to specify. See s2i docs. | ||
`s2i-additional-arguments` | False | `[]` | List of additional arguments to append to s2i call. | ||
`context` | True | `'.'` | Context to build the container image in | ||
`tls-verify` | True | `True` | Whether to verify TLS when pulling parent images | ||
`containers-config-auth-file` | False | | Path to the container registry authentication \ | ||
file to use for container registry authentication. \ | ||
If one is not provided one will be created in the \ | ||
working directory. | ||
`container-registries` | False | | Hash of container registries to authenticate with. | ||
Result Artifacts | ||
---------------- | ||
Results artifacts output by this step. | ||
Result Artifact Key | Description | ||
----------------------------------------|------------ | ||
`container-image-registry-uri` | Registry URI poriton of the container image tag of the built container image. | ||
`container-image-registry-organization` | Organization portion of the container image tag of the built container image. | ||
`container-image-repository` | Repository portion of the container image tag of the built container image. | ||
`container-image-name` | Another way to reference the repository portion of the container image tag \ | ||
of the built container image. | ||
`container-image-version` | Version portion of the container image tag of the built container image. | ||
`container-image-tag` | Full container image tag of the built container, including the registry URI. <br/> \ | ||
Takes the form of: \ | ||
`container-image-registry-organization/container-image-repository:container-image-version` | ||
`container-image-short-tag` | Short container image tag of the built container image, excluding the registry URI. <br/> \ | ||
Takes the form of: \ | ||
`container-image-registry-uri/container-image-registry-organization/container-image-repository:container-image-version` | ||
"""# pylint: disable=line-too-long | ||
|
||
import os | ||
import sys | ||
from distutils import util | ||
|
||
import sh | ||
from ploigos_step_runner import StepImplementer, StepResult | ||
from ploigos_step_runner.utils.containers import (container_registries_login, | ||
inspect_container_image) | ||
|
||
DEFAULT_CONFIG = { | ||
'context': '.', | ||
'tls-verify': True, | ||
's2i-additional-arguments': [], | ||
's2i-loglevel': 1 | ||
} | ||
|
||
REQUIRED_CONFIG_OR_PREVIOUS_STEP_RESULT_ARTIFACT_KEYS = [ | ||
'context', | ||
'tls-verify', | ||
's2i-builder-image', | ||
'organization', | ||
'service-name', | ||
'application-name' | ||
] | ||
|
||
class SourceToImage(StepImplementer): | ||
"""`StepImplementer` for the `create-container-image step` using Source-to-Image (s2i) | ||
to create a Containerfile that can be built by another `StepImplementer`, such as Buildah. | ||
""" | ||
|
||
CONTAINER_LABEL_SCRIPTS_URL = 'io.openshift.s2i.scripts-url' | ||
|
||
@staticmethod | ||
def step_implementer_config_defaults(): | ||
"""Getter for the StepImplementer's configuration defaults. | ||
Notes | ||
----- | ||
These are the lowest precedence configuration values. | ||
Returns | ||
------- | ||
dict | ||
Default values to use for step configuration values. | ||
""" | ||
return DEFAULT_CONFIG | ||
|
||
@staticmethod | ||
def _required_config_or_result_keys(): | ||
"""Getter for step configuration or previous step result artifacts that are required before | ||
running this step. | ||
See Also | ||
-------- | ||
_validate_required_config_or_previous_step_result_artifact_keys | ||
Returns | ||
------- | ||
array_list | ||
Array of configuration keys or previous step result artifacts | ||
that are required before running the step. | ||
""" | ||
return REQUIRED_CONFIG_OR_PREVIOUS_STEP_RESULT_ARTIFACT_KEYS | ||
|
||
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_uri=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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.