aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbdulwasiu Apalowo <abdulwasiuapalowo@gmail.com>2022-12-23 00:33:21 +0100
committerAbdulwasiu Apalowo <abdulwasiuapalowo@gmail.com>2023-01-10 14:18:55 +0100
commit0924161b2c0cd2752312e00170e0165931ff24f9 (patch)
treebbb7d89405bd39f29f8b1a2d9429cdc687277532
parent73fb1c622c0351b08129b414c5232a8a933d9842 (diff)
downloadlibvirt-ci-0924161b2c0cd2752312e00170e0165931ff24f9.zip
libvirt-ci-0924161b2c0cd2752312e00170e0165931ff24f9.tar.gz
libvirt-ci-0924161b2c0cd2752312e00170e0165931ff24f9.tar.bz2
lcitool container: Add "build" subcommand
This adds the "build" subcommand which is used to build container image from args.projects and args.target. The Dockerfile string generated from using the `DockerfileFormatter` class is copied to a temporary file which is passed to the build command. Tags are generated by prefixing the target name with "lcitool.", e.g "lcitool.fedora-36" to prevent trashing the output of "podman images" with incomprehensible tags. If an image is present, it is removed before starting another build to ensure the image is built from scratch. Ensure that (--target & --projects) arguments are passed with "build" subcommand. Signed-off-by: Abdulwasiu Apalowo <abdulwasiuapalowo@gmail.com>
-rw-r--r--lcitool/application.py44
-rw-r--r--lcitool/commandline.py19
2 files changed, 63 insertions, 0 deletions
diff --git a/lcitool/application.py b/lcitool/application.py
index 5b12d18..c5bbbab 100644
--- a/lcitool/application.py
+++ b/lcitool/application.py
@@ -6,9 +6,11 @@
import logging
import sys
+import textwrap
from pathlib import Path
from pkg_resources import resource_filename
+from tempfile import TemporaryDirectory, NamedTemporaryFile
from lcitool import util, LcitoolError
from lcitool.config import Config
@@ -326,6 +328,48 @@ class Application:
else:
print("No engine available")
+ def _action_container_build(self, args):
+ self._entrypoint_debug(args)
+
+ params = {}
+ client = self._get_client(args.engine)
+
+ container_tempdir = TemporaryDirectory(prefix="container",
+ dir=util.get_temp_dir())
+ params["tempdir"] = container_tempdir.name
+
+ tag = f"lcitool.{args.target}"
+
+ # remove image and prepare to build a new one.
+ client.rmi(tag)
+
+ targets = Targets()
+ packages = Packages()
+ projects = Projects()
+ projects_expanded = projects.expand_names(args.projects)
+ target = BuildTarget(targets, packages, args.target, args.cross_arch)
+
+ _file = None
+ file_content = DockerfileFormatter(projects).format(
+ target,
+ projects_expanded
+ )
+ with NamedTemporaryFile("w",
+ delete=False,
+ dir=params["tempdir"]) as fd:
+ fd.write(textwrap.dedent(file_content))
+ _file = fd.name
+
+ log.debug(f"Generated dockerfile copied to {_file}")
+
+ try:
+ client.build(tag=tag, filepath=_file, **params)
+ except ContainerError as ex:
+ raise ApplicationError(ex.message)
+
+ log.debug(f"Generated image tag --> {tag}")
+ print(f"Image '{tag}' successfully built.")
+
def run(self, args):
try:
util.set_extra_data_dir(args.data_dir)
diff --git a/lcitool/commandline.py b/lcitool/commandline.py
index 8bd60c6..9e69c49 100644
--- a/lcitool/commandline.py
+++ b/lcitool/commandline.py
@@ -298,6 +298,14 @@ class CommandLine:
)
container_engineparser.set_defaults(func=Application._action_list_engines)
+ build_containerparser = containersubparser.add_parser(
+ "build",
+ help="Build container image",
+ parents=[installtargetopt, container_projectopt, engineopt,
+ crossarchopt],
+ )
+ build_containerparser.set_defaults(func=Application._action_container_build)
+
# Validate "container" args
def _validate(self, args):
"""
@@ -308,6 +316,17 @@ class CommandLine:
:return: args.
"""
+ if vars(args).get("container") \
+ and args.container in ["build", "run", "shell"]:
+
+ # Ensure that (--target & --projects) argument are passed with
+ # "build" subcommand.
+ if args.container == "build":
+ if args.projects and args.target:
+ return args
+ else:
+ log.error("--target and --projects are required")
+ sys.exit(1)
return args
def parse(self):