Skip to content

Commit

Permalink
Quadlet: add -list-images
Browse files Browse the repository at this point in the history
Add a new `-list-images` string flag Quadlet which will write a list of
images mentioned in `.image` Quadlets to specified file.

In order to avoid disk bloat, many bootable containers do not embed
application-container images.  Hence, those must be pulled in _some_
use-case dependent way.  Quadlet is perfectly capable of pulling the
images on boot or on demand but that does not satisfy all use cases as
it slows down boot or initialization of the workloads.  In those cases,
we want a `bootc upgrade` to first pull down the bootable container
image and then analyze its root FS to extract all referenced images in
(rootful) `.image` Quadlets.  This change is a first step in this
direction.

Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
  • Loading branch information
vrothberg committed Jun 21, 2024
1 parent a2bf49a commit 95f23b7
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 6 deletions.
39 changes: 33 additions & 6 deletions cmd/quadlet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ import (
// for more details.

var (
verboseFlag bool // True if -v passed
noKmsgFlag bool
isUserFlag bool // True if run as quadlet-user-generator executable
dryRunFlag bool // True if -dryrun is used
versionFlag bool // True if -version is used
verboseFlag bool // True if -v passed
noKmsgFlag bool
isUserFlag bool // True if run as quadlet-user-generator executable
dryRunFlag bool // True if -dryrun is used
versionFlag bool // True if -version is used
listImagesFlag string // Set if -list-images is used
)

const (
Expand Down Expand Up @@ -549,7 +550,7 @@ func process() error {
prevError = err
}

if !dryRunFlag && flag.NArg() < 1 {
if !dryRunFlag && flag.NArg() < 1 && len(listImagesFlag) == 0 {
reportError(errors.New("missing output directory argument"))
return prevError
}
Expand Down Expand Up @@ -586,6 +587,31 @@ func process() error {
}
}

if len(listImagesFlag) > 0 {
fd, err := os.OpenFile(listImagesFlag, os.O_WRONLY, 0644)
if err != nil {
return err
}
for _, unit := range units {
if !strings.HasSuffix(unit.Filename, ".image") {
continue
}
imageName, err := quadlet.ListImage(unit)
if err != nil {
reportError(err)
}
if !isUnambiguousName(imageName) {
Logf("Warning: %s specifies the image \"%s\" which not a fully qualified image name and is hence being ignored.", unit.Filename, imageName)
continue
}
fmt.Fprintf(fd, "%s\n", imageName)
}
if err := fd.Close(); err != nil {
reportError(err)
}
return prevError
}

if !dryRunFlag {
err := os.MkdirAll(outputPath, os.ModePerm)
if err != nil {
Expand Down Expand Up @@ -681,4 +707,5 @@ func init() {
flag.BoolVar(&isUserFlag, "user", false, "Run as systemd user")
flag.BoolVar(&dryRunFlag, "dryrun", false, "Run in dryrun mode printing debug information")
flag.BoolVar(&versionFlag, "version", false, "Print version information and exit")
flag.StringVar(&listImagesFlag, "list-images", "", "Write a list of all images being references in .image Quadlets to specified file")
}
15 changes: 15 additions & 0 deletions pkg/systemd/quadlet/quadlet.go
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,21 @@ func ConvertKube(kube *parser.UnitFile, names map[string]string, isUser bool) (*
return service, nil
}

func ListImage(image *parser.UnitFile) (string, error) {
// Even if we're only interested in the Image= of the unit, it should
// still be valid.
if err := checkForUnknownKeys(image, ImageGroup, supportedImageKeys); err != nil {
return "", err
}

imageName, ok := image.Lookup(ImageGroup, KeyImage)
if !ok || len(imageName) == 0 {
return "", fmt.Errorf("no Image key specified")
}

return imageName, nil
}

func ConvertImage(image *parser.UnitFile) (*parser.UnitFile, string, error) {
service := image.Dup()
service.Filename = replaceExtension(image.Filename, ".service", "", "-image")
Expand Down
37 changes: 37 additions & 0 deletions test/system/252-quadlet.bats
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,43 @@ EOF
run_podman network rm podman-default-kube-network
}

@test "quadlet - list images" {
local quadlet_tmpdir=$PODMAN_TMPDIR/quadlets
mkdir -p $quadlet_tmpdir

local image_name_1=quay.io/quadlet/image:1
local image_name_2=quay.io/quadlet/image:2
local image_name_3=quay.io/quadlet/image:3

cat > $PODMAN_TMPDIR/1.image <<EOF
[Image]
Image=$image_name_1
EOF
cat > $quadlet_tmpdir/2.image <<EOF
[Image]
Image=$image_name_2
EOF
cat > $quadlet_tmpdir/3.image <<EOF
[Image]
Image=$image_name_3
EOF
cat > $quadlet_tmpdir/1.container <<EOF
[Image]
Image=quay.io/do/not/parse:me
EOF

local image_file=$quadlet_tmpdir/image_file
touch $image_file

QUADLET_UNIT_DIRS=$PODMAN_TMPDIR run \
timeout --foreground -v --kill=10 $PODMAN_TIMEOUT \
$QUADLET -list-images=$image_file

assert "$(< $image_file)" = "$image_name_1
$image_name_2
$image_name_3" "-list-images=FILE lists all images referenced in .image Quadlets"
}

@test "quadlet - image files" {
local quadlet_tmpdir=$PODMAN_TMPDIR/quadlets

Expand Down

0 comments on commit 95f23b7

Please sign in to comment.