debian-forge-cli/cmd/image-builder/describeimg.go
Michael Vogt 0f348301d9 main: add base partition table to describe-image
This commit adds the (base) partition table to the `describe-image`
command. It needs https://github.com/osbuild/images/pull/1376

It currently looks like:
```yaml
$ image-builder describe-image qcow2 --distro fedora-41
@WARNING - the output format is not stable yet and may change
distro: fedora-41
...
partition_table:
  uuid: D209C89E-EA5E-4FBD-B161-B461CCE297E0
  type: gpt
  partitions:
    - size: 1048576
      type: 21686148-6449-6E6F-744E-656564454649
      bootable: true
      uuid: FAC7F1FB-3E8D-4137-A512-961DE09A5549
    - size: 209715200
      type: C12A7328-F81F-11D2-BA4B-00A0C93EC93B
      uuid: 68B2905B-DF3E-4FB3-80FA-49D1E773AA33
      payload:
        type: vfat
        uuid: 7B77-95E7
        label: EFI-SYSTEM
        mountpoint: /boot/efi
        fstab_options: defaults,uid=0,gid=0,umask=077,shortname=winnt
        fstab_passno: 2
    - size: 524288000
      type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4
      uuid: CB07C243-BC44-4717-853E-28852021225B
      payload:
        type: ext4
        label: boot
        mountpoint: /boot
        fstab_options: defaults
    - size: 2147483648
      type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4
      uuid: 6264D520-3FB9-423F-8AB8-7A0A8E3D3562
      payload:
        type: ext4
        label: root
        mountpoint: /
        fstab_options: defaults
```
2025-04-03 17:25:16 +00:00

117 lines
3.3 KiB
Go

package main
import (
"errors"
"fmt"
"io"
"slices"
"gopkg.in/yaml.v3"
"github.com/osbuild/images/pkg/blueprint"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/defs"
"github.com/osbuild/images/pkg/imagefilter"
)
// Use yaml output by default because it is both nicely human and
// machine readable and parts of our image defintions will be written
// in yaml too. This means this should be a possible input a
// "flattended" image definiton.
type describeImgYAML struct {
Distro string `yaml:"distro"`
Type string `yaml:"type"`
Arch string `yaml:"arch"`
// XXX: think about ordering (as this is what the user will see)
OsVersion string `yaml:"os_version"`
Bootmode string `yaml:"bootmode"`
PartitionType string `yaml:"partition_type"`
DefaultFilename string `yaml:"default_filename"`
BuildPipelines []string `yaml:"build_pipelines"`
PayloadPipelines []string `yaml:"payload_pipelines"`
Packages map[string]*packagesYAML `yaml:"packages"`
PartitionTable *disk.PartitionTable `yaml:"partition_table,omitempty"`
}
type packagesYAML struct {
Include []string `yaml:"include"`
Exclude []string `yaml:"exclude"`
}
func packageSetsFor(imgType distro.ImageType) (map[string]*packagesYAML, error) {
var bp blueprint.Blueprint
manifest, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, nil)
if err != nil {
return nil, err
}
res := make(map[string]*packagesYAML)
for pipelineName, pkgSets := range manifest.GetPackageSetChains() {
incM := map[string]bool{}
excM := map[string]bool{}
for _, pkgSet := range pkgSets {
for _, s := range pkgSet.Include {
incM[s] = true
}
for _, s := range pkgSet.Exclude {
excM[s] = true
}
}
inc := make([]string, 0, len(incM))
exc := make([]string, 0, len(excM))
for name := range incM {
inc = append(inc, name)
}
for name := range excM {
exc = append(exc, name)
}
slices.Sort(inc)
slices.Sort(exc)
res[pipelineName] = &packagesYAML{
Include: inc,
Exclude: exc,
}
}
return res, nil
}
// XXX: should this live in images instead?
func describeImage(img *imagefilter.Result, out io.Writer) error {
// see
// https://github.com/osbuild/images/pull/1019#discussion_r1832376568
// for what is available on an image (without depsolve or partitioning)
pkgSets, err := packageSetsFor(img.ImgType)
if err != nil {
return err
}
partTable, err := img.ImgType.BasePartitionTable()
if err != nil && !errors.Is(err, defs.ErrNoPartitionTableForImgType) {
return err
}
outYaml := &describeImgYAML{
Distro: img.Distro.Name(),
OsVersion: img.Distro.OsVersion(),
Arch: img.Arch.Name(),
Type: img.ImgType.Name(),
Bootmode: img.ImgType.BootMode().String(),
PartitionType: img.ImgType.PartitionType().String(),
DefaultFilename: img.ImgType.Filename(),
BuildPipelines: img.ImgType.BuildPipelines(),
PayloadPipelines: img.ImgType.PayloadPipelines(),
Packages: pkgSets,
PartitionTable: partTable,
}
// deliberately break the yaml until the feature is stable
fmt.Fprint(out, "@WARNING - the output format is not stable yet and may change\n")
enc := yaml.NewEncoder(out)
enc.SetIndent(2)
return enc.Encode(outYaml)
}