|
37 | 37 |
|
38 | 38 | import argparse
|
39 | 39 | import configparser
|
| 40 | +import contextlib |
40 | 41 | import logging
|
41 | 42 | import os
|
42 | 43 | import pathlib
|
@@ -267,13 +268,13 @@ def container_build(cli, target):
|
267 | 268 | """Construct and execute a command to build the target container image."""
|
268 | 269 | eng = container_engine(cli)
|
269 | 270 | # For docker cross-builds we need to use buildx
|
270 |
| - if "docker" in eng and target.arch != host_arch(): |
271 |
| - tasks = _buildx_build_tasks(cli, target) |
272 |
| - else: |
273 |
| - tasks = _common_build_tasks(cli, target) |
274 |
| - |
275 |
| - for task in tasks: |
276 |
| - run(cli, **task) |
| 271 | + with edited_containerfile(cli, target) as containerfile: |
| 272 | + if "docker" in eng and target.arch != host_arch(): |
| 273 | + tasks = _buildx_build_tasks(cli, target, containerfile) |
| 274 | + else: |
| 275 | + tasks = _common_build_tasks(cli, target, containerfile) |
| 276 | + for task in tasks: |
| 277 | + run(cli, **task) |
277 | 278 |
|
278 | 279 |
|
279 | 280 | def create_common_container_engine_args(cli, target, containerfile=""):
|
@@ -302,6 +303,99 @@ def create_common_container_engine_args(cli, target, containerfile=""):
|
302 | 303 | return [str(a) for a in args]
|
303 | 304 |
|
304 | 305 |
|
| 306 | +@contextlib.contextmanager |
| 307 | +def edited_containerfile(cli, target): |
| 308 | + if "sambacc" not in cli.customizations(): |
| 309 | + yield target_containerfile(target) |
| 310 | + return |
| 311 | + orig_containerfile = target_containerfile(target) |
| 312 | + try: |
| 313 | + wip = ( |
| 314 | + orig_containerfile.parent |
| 315 | + / f".{orig_containerfile.name}.{os.getpid()}.tmp" |
| 316 | + ) |
| 317 | + with open(wip, "w") as fh: |
| 318 | + for line in _sambacc_prefix(cli): |
| 319 | + fh.write(line) |
| 320 | + fh.write("\n") |
| 321 | + replacements = {"sambacc": _sambacc_install(cli)} |
| 322 | + for line, meta in _scan_containerfile(orig_containerfile): |
| 323 | + if meta in replacements: |
| 324 | + for line in replacements[meta]: |
| 325 | + fh.write(line) |
| 326 | + fh.write("\n") |
| 327 | + replacements.pop(meta, None) |
| 328 | + continue |
| 329 | + elif meta: |
| 330 | + continue |
| 331 | + fh.write(line) |
| 332 | + with open(wip) as fh: |
| 333 | + print(fh.read()) |
| 334 | + yield wip |
| 335 | + finally: |
| 336 | + wip.unlink(missing_ok=True) |
| 337 | + |
| 338 | + |
| 339 | +def _sambacc_prefix(cli): |
| 340 | + cfg = cli.customizations()["sambacc"] |
| 341 | + base_image = cfg.get("base_image", "quay.io/samba.org/sambacc:latest") |
| 342 | + sambacc_ver = cfg.get("sambacc_ver", "master") |
| 343 | + sambacc_repo = cfg.get( |
| 344 | + "sambacc_repo", "https://github.com/samba-in-kubernetes/sambacc" |
| 345 | + ) |
| 346 | + distname = cfg.get("distname", "latest") |
| 347 | + distpath = f"/srv/dist/{distname}" |
| 348 | + yield "# --- sambacc prefix ---" |
| 349 | + yield f"FROM {base_image} AS sccbuilder" |
| 350 | + yield f"ARG SAMBACC_VER={sambacc_ver}" |
| 351 | + yield f"ARG SAMBACC_REPO={sambacc_repo}" |
| 352 | + yield ( |
| 353 | + f"RUN SAMBACC_DISTNAME={distname}" |
| 354 | + " /usr/local/bin/build.sh ${SAMBACC_VER} ${SAMBACC_REPO}" |
| 355 | + ) |
| 356 | + yield ( |
| 357 | + "RUN dnf install -y /usr/bin/createrepo_c" |
| 358 | + f" && createrepo_c {distpath}" |
| 359 | + f" && echo -e '[sambacc]\\nbaseurl=file://{distpath}\\nenabled=1\\ngpgcheck=0\\n'" |
| 360 | + f" > {distpath}/sambacc.repo" |
| 361 | + ) |
| 362 | + yield "# --- sambacc prefix ---" |
| 363 | + yield "" |
| 364 | + |
| 365 | + |
| 366 | +def _sambacc_install(cli): |
| 367 | + cfg = cli.customizations()["sambacc"] |
| 368 | + distname = cfg.get("distname", "latest") |
| 369 | + distpath = f"/srv/dist/{distname}" |
| 370 | + yield "# --- begin modified sambacc install ---" |
| 371 | + yield ( |
| 372 | + "RUN" |
| 373 | + f" --mount=type=bind,from=sccbuilder,source={distpath},destination={distpath}" |
| 374 | + f" bash -x /usr/local/bin/install-sambacc.sh {distpath}" |
| 375 | + " ${SAMBACC_VERSION_SUFFIX}" |
| 376 | + ) |
| 377 | + yield "# --- end modified sambacc install ---" |
| 378 | + yield "" |
| 379 | + |
| 380 | + |
| 381 | +def _scan_containerfile(path, tags="sambacc"): |
| 382 | + tags = tags.split() |
| 383 | + active_tag = None |
| 384 | + with open(path) as fh: |
| 385 | + for line in fh: |
| 386 | + for tag in tags: |
| 387 | + if f"---begin {tag}---" in line: |
| 388 | + active_tag = tag |
| 389 | + yield line, active_tag |
| 390 | + for tag in tags: |
| 391 | + if f"---end {tag}--" in line: |
| 392 | + if tag != active_tag: |
| 393 | + raise ValueError( |
| 394 | + f"bad tag: {tag}, expected {active_tag}" |
| 395 | + ) |
| 396 | + active_tag = None |
| 397 | + |
| 398 | + |
305 | 399 | def container_push(cli, push_name):
|
306 | 400 | """Construct and execute a command to push a container image."""
|
307 | 401 | args = [container_engine(cli), "push", push_name]
|
@@ -350,9 +444,7 @@ def kind_source_dir(kind):
|
350 | 444 |
|
351 | 445 | def target_containerfile(target):
|
352 | 446 | """Return the path to a containerfile given an image target."""
|
353 |
| - return str( |
354 |
| - kind_source_dir(target.name) / f"Containerfile.{target.distro}" |
355 |
| - ) |
| 447 | + return kind_source_dir(target.name) / f"Containerfile.{target.distro}" |
356 | 448 |
|
357 | 449 |
|
358 | 450 | def host_arch():
|
|
0 commit comments