Skip to content

Commit

Permalink
Add container build/remove image commands
Browse files Browse the repository at this point in the history
fixes: #424
  • Loading branch information
gerrod3 committed Apr 25, 2022
1 parent 4657acc commit 866f571
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES/424.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added container build/remove image commands.
11 changes: 11 additions & 0 deletions pulpcore/cli/container/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class PulpContainerRepositoryContext(PulpContainerBaseRepositoryContext):
"pulpexport": [PluginRequirement("container", "2.8.0.dev")],
"tag": [PluginRequirement("container", "2.3.0")],
"roles": [PluginRequirement("container", "2.11.0.dev")],
"build": [PluginRequirement("container", "1.1.0")],
}

def modify(
Expand Down Expand Up @@ -143,6 +144,16 @@ def copy_manifest(
body = self.preprocess_body(body)
return self.call("copy_manifests", parameters={self.HREF: self.pulp_href}, body=body)

def build_image(
self,
container_artifact: str,
tag: Optional[str],
artifacts: Optional[str],
) -> Any:
body = {"containerfile_artifact": container_artifact, "tag": tag, "artifacts": artifacts}
body = self.preprocess_body(body)
return self.call("build_image", parameters={self.HREF: self.pulp_href}, body=body)


class PulpContainerPushRepositoryContext(PulpContainerBaseRepositoryContext):
HREF = "container_container_push_repository_href"
Expand Down
96 changes: 95 additions & 1 deletion pulpcore/cli/container/repository.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import json
import re
from typing import Any, Dict, List, Optional
from pathlib import Path
from typing import Any, Dict, List, Optional, Union

import click

from pulpcore.cli.common.context import (
EntityFieldDefinition,
PulpContext,
PulpEntityContext,
PulpRemoteContext,
PulpRepositoryContext,
pass_pulp_context,
pass_repository_context,
)
from pulpcore.cli.common.generic import (
Expand All @@ -17,6 +21,7 @@
label_command,
label_select_option,
list_command,
load_json_callback,
name_option,
pulp_group,
repository_content_command,
Expand All @@ -41,6 +46,7 @@
PulpContainerRepositoryContext,
PulpContainerTagContext,
)
from pulpcore.cli.core.context import PulpArtifactContext
from pulpcore.cli.core.generic import task_command

translation = get_translation(__name__)
Expand All @@ -57,6 +63,22 @@ def _tag_callback(ctx: click.Context, param: click.Parameter, value: str) -> str
return value


def _directory_or_json_callback(
ctx: click.Context, param: click.Parameter, value: Optional[str]
) -> Union[str, Path, None]:
if not value:
return value
uvalue: Union[str, Path]
try:
uvalue = load_json_callback(ctx, param, value)
except click.ClickException:
uvalue = Path(value)
if not uvalue.exists() or not uvalue.is_dir():
raise click.ClickException(_("{} is not a valid directory").format(value))

return uvalue


source_option = resource_option(
"--source",
default_plugin="container",
Expand Down Expand Up @@ -286,3 +308,75 @@ def copy_manifest(
digests=digests or None,
media_types=media_types or None,
)


def upload_file(pulp_ctx: PulpContext, file_location: str) -> str:
try:
with click.open_file(file_location, "r") as fp:
artifact_ctx = PulpArtifactContext(pulp_ctx)
click.echo(_("Uploading {} as artifact").format(file_location))
artifact_href = artifact_ctx.upload(fp)
except OSError:
raise click.ClickException(
_("Failed to load content from {file}").format(file=file_location)
)
click.echo(_("Uploaded file: {}").format(artifact_href))
return artifact_href # type: ignore


@repository.command(allowed_with_contexts=container_context)
@name_option
@href_option
@click.option(
"--containerfile",
help=_(
"An artifact href of an uploaded Containerfile. Can also be a local Containerfile to be"
" uploaded using @."
),
required=True,
)
@click.option("--tag", help=_("A tag name for the new image being built."))
@click.option(
"--artifacts",
help=_(
"Directory of files to be uploaded and used during the build. Or a JSON string where each"
" key is an artifact href and the value is it's relative path (name) inside the "
"/pulp_working_directory of the build container executing the Containerfile."
),
callback=_directory_or_json_callback,
)
@pass_repository_context
@pass_pulp_context
def build_image(
pulp_ctx: PulpContext,
repository_ctx: PulpContainerRepositoryContext,
containerfile: str,
tag: Optional[str],
artifacts: Union[str, Path, None],
) -> None:
if not repository_ctx.capable("build"):
raise click.ClickException(_("Repository does not support image building."))

container_artifact_href: str
artifacts_json: Optional[str] = None
# Upload necessary files as artifacts if specified
if containerfile[0] == "@":
container_artifact_href = upload_file(pulp_ctx, containerfile[1:])
else:
artifact_ctx = PulpArtifactContext(pulp_ctx, pulp_href=containerfile)
container_artifact_href = artifact_ctx.pulp_href

if artifacts:
if isinstance(artifacts, Path):
# Upload files in directory
artifact_hrefs = {}
for child in artifacts.iterdir():
# Can the directory structure be non-flat?
if child.is_file():
artifact_href = upload_file(pulp_ctx, str(child))
artifact_hrefs[artifact_href] = child.name
artifacts_json = json.dumps(artifact_hrefs)
else:
artifacts_json = artifacts

repository_ctx.build_image(container_artifact_href, tag, artifacts_json)

0 comments on commit 866f571

Please sign in to comment.