Skip to content

Commit

Permalink
osbuild: --checkpoint can now use globs
Browse files Browse the repository at this point in the history
When developing or rebuilding manifests a lot it is common to want to
checkpoint everything to the store. It seems we all have small shell
scripts hanging around for this.

Let `--checkpoint` take a shell-like glob such as `--checkpoint="*"` to
checkpoint everything.

Note that there's a behavioral change here; previously `osbuild
--checkpoint=a` would error if that specific checkpoint wasn't found.
Now `osbuild` will only error if nothing was selected by the passed
globs.
  • Loading branch information
supakeen authored and achilleas-k committed Aug 4, 2023
1 parent 14d3163 commit 427e82e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 21 deletions.
9 changes: 4 additions & 5 deletions osbuild/main_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def parse_arguments(sys_argv):
parser.add_argument("--cache-max-size", metavar="SIZE", type=parse_size, default=None,
help="maximum size of the cache (bytes) or 'unlimited' for no restriction")
parser.add_argument("--checkpoint", metavar="ID", action="append", type=str, default=None,
help="stage to commit to the object store during build (can be passed multiple times)")
help="stage to commit to the object store during build (can be passed multiple times), accepts globs")
parser.add_argument("--export", metavar="ID", action="append", type=str, default=[],
help="object to export, can be passed multiple times")
parser.add_argument("--json", action="store_true",
Expand Down Expand Up @@ -127,10 +127,9 @@ def osbuild_cli():
return 1

if args.checkpoint:
missed = manifest.mark_checkpoints(args.checkpoint)
if missed:
for checkpoint in missed:
print(f"Checkpoint {vt.bold}{checkpoint}{vt.reset} not found!")
marked = manifest.mark_checkpoints(args.checkpoint)
if not marked:
print("No checkpoints matched provided patterns!")
print(f"{vt.reset}{vt.bold}{vt.red}Failed{vt.reset}")
return 1

Expand Down
36 changes: 20 additions & 16 deletions osbuild/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import hashlib
import json
import os
from fnmatch import fnmatch
from typing import Dict, Generator, Iterable, Iterator, List, Optional

from . import buildroot, host, objectstore, remoteloop
Expand Down Expand Up @@ -472,27 +473,30 @@ def build(self, store, pipelines, monitor, libdir, stage_timeout=None):

return results

def mark_checkpoints(self, checkpoints):
points = set(checkpoints)
def mark_checkpoints(self, patterns):
"""Match pipeline names, stage ids, and stage names against an iterable
of `fnmatch`-patterns."""
selected = []

def mark_stage(stage):
c = stage.id
if c in points:
stage.checkpoint = True
points.remove(c)
def matching(haystack):
return any(fnmatch(haystack, p) for p in patterns)

def mark_pipeline(pl):
if pl.name in points and pl.stages:
pl.stages[-1].checkpoint = True
points.remove(pl.name)
for pipeline in self.pipelines.values():
# checkpoints are marked on stages, if a pipeline has no stages we
# can't mark it
if not pipeline.stages:
continue

for stage in pl.stages:
mark_stage(stage)
if matching(pipeline.name):
selected.append(pipeline.name)
pipeline.stages[-1].checkpoint = True

for pl in self.pipelines.values():
mark_pipeline(pl)
for stage in pipeline.stages:
if matching(stage.id) or matching(stage.name):
selected.append(stage.id)
stage.checkpoint = True

return points
return selected

def get(self, name_or_id: str) -> Optional[Pipeline]:
pl = self.pipelines.get(name_or_id)
Expand Down

0 comments on commit 427e82e

Please sign in to comment.