From 340af0a9ce8caadd6b65e5e12fe254ac5cfb5a1c Mon Sep 17 00:00:00 2001 From: Serge Hallyn Date: Mon, 11 Dec 2023 12:54:02 -0600 Subject: [PATCH] mosb publish: auto-fill bootkit and hostfs layers If bootkit layer is not specified, then add the one for the specified trust org. If hostfs layer is not specified, use the upstream demo one. This makes less paperwork for the user. Add a '--skip-boot' option to mosb manifest publish, for use when we are testing fake mosctl install. .github/workflows/build.yml: fetch the git tags, because mosb must know which tag to use when filling in a rootfs entry. Signed-off-by: Serge Hallyn --- .github/workflows/build.yml | 4 +++- Makefile | 2 ++ cmd/mosb/manifest.go | 4 ++++ pkg/mosconfig/files.go | 38 +++++++++++++++++++++++++++++++++++++ pkg/mosconfig/install.go | 38 +++++++++++++++++++++++++++++++------ pkg/mosconfig/mkboot.go | 4 ++-- pkg/trust/const.go | 1 + tests/helpers.bash | 2 +- tests/launch.bats | 16 ++-------------- tests/mount.bats | 4 ++-- 10 files changed, 87 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5f3a3e9..18889cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,8 @@ jobs: echo "PATH=$HOME/bin:$PATH" >> $GITHUB_ENV - name: Check out git uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Set up golang uses: actions/setup-go@v3 with: @@ -77,7 +79,7 @@ jobs: dir: 'layers' build-args: | ZOT_VERSION=2.0.0-rc5 - ROOTFS_VERSION=v0.0.17.231018 + ROOTFS_VERSION=v0.0.18.231121 TOPDIR=${{ env.TOPDIR }} url: docker://zothub.io/machine/bootkit layer-type: squashfs diff --git a/Makefile b/Makefile index 64e8853..3a6454b 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ else #error "Unsupported architecture: $(archout)" endif +CLEAN_VERSION ?= $(shell git describe --abbrev=0) MAIN_VERSION ?= $(shell git describe --always --dirty || echo no-git) ifeq ($(MAIN_VERSION),$(filter $(MAIN_VERSION), "", no-git)) $(error "Bad value for MAIN_VERSION: '$(MAIN_VERSION)'") @@ -33,6 +34,7 @@ all: mosctl mosb trust $(ZOT) $(ORAS) $(REGCTL) VERSION_LDFLAGS=-X github.com/project-machine/mos/pkg/mosconfig.Version=$(MAIN_VERSION) \ -X github.com/project-machine/mos/pkg/trust.Version=$(MAIN_VERSION) \ + -X github.com/project-machine/mos/pkg/trust.RelVersion=$(CLEAN_VERSION) \ -X github.com/project-machine/mos/pkg/mosconfig.LayerVersion=0.0.4 \ -X github.com/project-machine/mos/pkg/trust.BootkitVersion=$(BOOTKIT_VERSION) diff --git a/cmd/mosb/manifest.go b/cmd/mosb/manifest.go index db33f31..f0613e8 100644 --- a/cmd/mosb/manifest.go +++ b/cmd/mosb/manifest.go @@ -37,6 +37,10 @@ var manifestCmd = cli.Command{ Usage: "Password to authenticate to OCI repository. Taken from stdin if user but no password is provided", Value: "", }, + cli.BoolFlag{ + Name: "skip-boot, skip-bootkit", + Usage: "Do not add in a bootkit layer", + }, }, }, }, diff --git a/pkg/mosconfig/files.go b/pkg/mosconfig/files.go index 24ce049..8aab653 100644 --- a/pkg/mosconfig/files.go +++ b/pkg/mosconfig/files.go @@ -274,6 +274,44 @@ type ImportFile struct { UpdateType UpdateType `yaml:"update_type"` } +func (i *ImportFile) HasTarget(name string) bool { + for _, t := range i.Targets { + if t.ServiceName == name { + return true + } + } + return false +} + +func (i *ImportFile) CompleteTargets(keyProject string) (UserTargets, error) { + if !i.HasTarget("hostfs") { + s := fmt.Sprintf("docker://zothub.io/machine/bootkit/demo-target-rootfs:%s-squashfs", trust.RelVersion) + newT := UserTarget{ + ServiceName: "hostfs", + ServiceType: "hostfs", + Source: s, + Version: trust.BootkitVersion, + Network: TargetNetwork{Type: HostNetwork}, + } + i.Targets = append(i.Targets, newT) + } + if !i.HasTarget("bootkit") { + bootkitDir, err := bootkitDir(keyProject) + if err != nil { + return UserTargets{}, err + } + newT := UserTarget{ + ServiceName: "bootkit", + Source: fmt.Sprintf("oci:%s/oci:bootkit-squashfs", bootkitDir), + Version: "1.0.0", + ServiceType: "fs-only", + Network: TargetNetwork{Type: HostNetwork}, + } + i.Targets = append(i.Targets, newT) + } + return i.Targets, nil +} + type UserTarget struct { ServiceName string `yaml:"service_name"` // name of target Source string `yaml:"source"` // docker url from which to fetch diff --git a/pkg/mosconfig/install.go b/pkg/mosconfig/install.go index 31f03ad..e59dffd 100644 --- a/pkg/mosconfig/install.go +++ b/pkg/mosconfig/install.go @@ -112,10 +112,11 @@ func (is *InstallSource) SaveToZot(zotport int, name string) error { } type InstallOpts struct { - RFS string - CaPath string - ConfigDir string - StoreDir string + RFS string + CaPath string + ConfigDir string + StoreDir string + SkipBootkit bool } func InitializeMos(ctx *cli.Context, opts InstallOpts) error { @@ -291,10 +292,15 @@ func PublishManifestFromArgs(ctx *cli.Context) error { return fmt.Errorf("file is a required positional argument") } infile := args[0] - return PublishManifest(proj, repo, destpath, infile) + return PublishManifest(proj, repo, destpath, infile, ctx.Bool("skip-bootkit")) } -func PublishManifest(project, repo, destpath, manifestpath string) error { +const ( + SkipBootkit = true + UseBootkit = false +) + +func PublishManifest(project, repo, destpath, manifestpath string, skipBootkit bool) error { b, err := os.ReadFile(manifestpath) if err != nil { return errors.Wrapf(err, "Error reading %s", manifestpath) @@ -310,6 +316,13 @@ func PublishManifest(project, repo, destpath, manifestpath string) error { return errors.Errorf("Unknown import file version: %d (I know about %d)", imports.Version, CurrentInstallFileVersion) } + if !skipBootkit { + imports.Targets, err = imports.CompleteTargets(project) + if err != nil { + return err + } + } + install := InstallFile{ Version: imports.Version, Product: imports.Product, @@ -565,6 +578,19 @@ func PostArtifact(refDigest digest.Digest, refSize int64, path, mediatype, dest return nil } +func bootkitDir(name string) (string, error) { + s := strings.SplitN(name, ":", 2) + if len(s) != 2 { + return "", fmt.Errorf("Invalid project name: use keyset:project") + } + keyset := s[0] + h, err := os.UserHomeDir() + if err != nil { + return "", err + } + return filepath.Join(h, ".local", "share", "machine", "trust", "keys", keyset, "bootkit"), nil +} + func projectDir(name string) (string, error) { s := strings.SplitN(name, ":", 2) if len(s) != 2 { diff --git a/pkg/mosconfig/mkboot.go b/pkg/mosconfig/mkboot.go index 605134a..e3edc16 100644 --- a/pkg/mosconfig/mkboot.go +++ b/pkg/mosconfig/mkboot.go @@ -497,7 +497,7 @@ func BuildProvisioner(keysetName, projectName, isofile string) error { } fullproject := keysetName + ":" + projectName - err = PublishManifest(fullproject, repo, name, manifestpath) + err = PublishManifest(fullproject, repo, name, manifestpath, SkipBootkit) if err != nil { return errors.Wrapf(err, "Failed writing manifest artifacts to local zot") } @@ -556,7 +556,7 @@ func BuildInstaller(keysetName, projectName, isofile string) error { } fullproject := keysetName + ":" + projectName - err = PublishManifest(fullproject, repo, name, manifestpath) + err = PublishManifest(fullproject, repo, name, manifestpath, SkipBootkit) if err != nil { return errors.Wrapf(err, "Failed writing manifest artifacts to local zot") } diff --git a/pkg/trust/const.go b/pkg/trust/const.go index ae0eb8d..5e8f5bb 100644 --- a/pkg/trust/const.go +++ b/pkg/trust/const.go @@ -57,4 +57,5 @@ var SBFPartitionTypeID = [16]byte{ const MiB, GiB = uint64(1024 * 1024), uint64(1024 * 1024 * 1024) var Version string +var RelVersion string var BootkitVersion string diff --git a/tests/helpers.bash b/tests/helpers.bash index 3af416d..47f1964 100644 --- a/tests/helpers.bash +++ b/tests/helpers.bash @@ -260,7 +260,7 @@ function good_install { write_install_yaml "$spectype" ./mosb manifest publish \ --repo ${ZOT_HOST}:${ZOT_PORT} --name puzzleos/install:1.0.0 \ - --project snakeoil:default $TMPD/manifest.yaml + --project snakeoil:default --skip-bootkit $TMPD/manifest.yaml rm $TMPD/manifest.yaml mkdir -p $TMPD/factory/secure cp "$CA_PEM" "$TMPD/factory/secure/manifestCA.pem" diff --git a/tests/launch.bats b/tests/launch.bats index a9bcf47..c49efa7 100644 --- a/tests/launch.bats +++ b/tests/launch.bats @@ -18,18 +18,12 @@ function teardown() { # Publish a manifest pointing at an rfs on zothub.io # TODO - we do need to include a bootkit layer to set up # an ESP. + git describe --abbrev=0 cat > "${TMPD}/manifest.yaml" << EOF version: 1 product: default update_type: complete targets: - - service_name: hostfs - source: "docker://zothub.io/machine/bootkit/demo-target-rootfs:0.0.4-squashfs" - version: 1.0.0 - service_type: hostfs - nsgroup: "none" - network: - type: none - service_name: zot source: "docker://zothub.io/machine/bootkit/demo-zot:0.0.4-squashfs" version: 1.0.0 @@ -41,15 +35,9 @@ targets: ports: - host: 80 container: 5000 - - service_name: bootkit - source: "oci:$HOME/.local/share/machine/trust/keys/snakeoil/bootkit/oci:bootkit-squashfs" - version: 1.0.0 - service_type: fs-only - nsgroup: "none" - network: - type: none EOF + cat "${TMPD}/manifest.yaml" mosb --debug manifest publish \ --project snakeoil:default \ --repo 127.0.0.1:${ZOT_PORT} --name machine/install:1.0.0 \ diff --git a/tests/mount.bats b/tests/mount.bats index 9980859..b70b90c 100644 --- a/tests/mount.bats +++ b/tests/mount.bats @@ -31,7 +31,7 @@ EOF @test "mount ro livecd filesystem" { write_install_yaml "livecd" - ./mosb manifest publish --product snakeoil:default \ + ./mosb manifest publish --product snakeoil:default --skip-bootkit \ --repo ${ZOT_HOST}:${ZOT_PORT} --name machine/livecd:1.0.0 \ $TMPD/manifest.yaml @@ -59,7 +59,7 @@ EOF @test "mount rw livecd filesystem" { write_install_yaml "livecd" - ./mosb manifest publish --product snakeoil:default \ + ./mosb manifest publish --product snakeoil:default --skip-bootkit \ --repo ${ZOT_HOST}:${ZOT_PORT} --name machine/livecd:1.0.0 \ $TMPD/manifest.yaml