diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f1e1ff --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +coverage.out diff --git a/Earthfile b/Earthfile index ffe233a..f24f648 100644 --- a/Earthfile +++ b/Earthfile @@ -2,10 +2,28 @@ VERSION 0.6 # Note the base image needs to have dracut. # TODO: This needs to come from pre-built kernels in c3os repos, immucore included. # Framework images should use our initrd -ARG BASE_IMAGE=quay.io/kairos/core-opensuse-leap +ARG FLAVOR=core-opensuse-leap +ARG BASE_IMAGE=quay.io/kairos/$FLAVOR +ARG OSBUILDER_IMAGE=quay.io/kairos/osbuilder-tools +ARG ISO_NAME=$FLAVOR-immucore ARG GO_VERSION=1.18 -ARG GOLINT_VERSION=1.47.3 +ARG GOLINT_VERSION=v1.47.3 + +version: + FROM alpine + RUN apk add git + COPY . ./ + RUN --no-cache echo $(git describe --always --tags --dirty) > VERSION + ARG VERSION=$(cat VERSION) + SAVE ARTIFACT VERSION VERSION + +golang-image: + ARG GO_VERSION + FROM golang:$GO_VERSION + WORKDIR /build + COPY go.mod go.sum ./ + RUN go mod download go-deps: ARG GO_VERSION @@ -18,7 +36,7 @@ go-deps: SAVE ARTIFACT go.sum AS LOCAL go.sum test: - FROM +go-deps + FROM +golang-image WORKDIR /build RUN go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo COPY . . @@ -26,25 +44,25 @@ test: SAVE ARTIFACT coverage.out AS LOCAL coverage.out lint: - ARG GO_VERSION - FROM golang:$GO_VERSION ARG GOLINT_VERSION - RUN wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v$GOLINT_VERSION + FROM golangci/golangci-lint:$GOLINT_VERSION WORKDIR /build COPY . . RUN golangci-lint run build-immucore: - FROM golang:alpine - RUN apk add git - COPY . /work + FROM +golang-image + COPY +version/VERSION ./ + ARG VERSION=$(cat VERSION) WORKDIR /work - ARG VERSION="$(git describe --tags)" + COPY . /work RUN CGO_ENABLED=0 go build -o immucore -ldflags "-X main.Version=$VERSION" - SAVE ARTIFACT /work/immucore AS LOCAL immucore + SAVE ARTIFACT /work/immucore AS LOCAL build/immucore-$VERSION build-dracut: FROM $BASE_IMAGE + COPY +version/VERSION ./ + ARG VERSION=$(cat VERSION) COPY . /work COPY +build-immucore/immucore /usr/bin/immucore WORKDIR /work @@ -54,32 +72,37 @@ build-dracut: dracut -f "/boot/initrd-${kernel}" "${kernel}" && \ ln -sf "initrd-${kernel}" /boot/initrd ARG INITRD=$(readlink -f /boot/initrd) - SAVE ARTIFACT $INITRD AS LOCAL initrd + SAVE ARTIFACT $INITRD Initrd AS LOCAL build/initrd-$VERSION image: FROM $BASE_IMAGE - ARG IMAGE=dracut + COPY +version/VERSION ./ + ARG VERSION=$(cat VERSION) ARG INITRD=$(readlink -f /boot/initrd) - ARG NAME=$(basename $INITRD) - COPY +build-dracut/$NAME $INITRD + COPY +build-dracut/Initrd $INITRD # For initrd use COPY +build-immucore/immucore /usr/bin/immucore RUN ln -s /usr/lib/systemd/systemd /init + SAVE IMAGE $FLAVOR-immucore:$VERSION - SAVE IMAGE $IMAGE +image-rootfs: + FROM +image + SAVE ARTIFACT --keep-own /. rootfs -iso: - ARG ISO_NAME=test - FROM quay.io/kairos/osbuilder-tools +grub-files: + FROM alpine + RUN apk add wget + RUN wget https://raw.githubusercontent.com/c3os-io/c3os/master/overlay/files-iso/boot/grub2/grub.cfg -O grub.cfg + SAVE ARTIFACT --keep-own grub.cfg grub.cfg +iso: + FROM $OSBUILDER_IMAGE + ARG ISO_NAME + COPY +version/VERSION ./ + ARG VERSION=$(cat VERSION) WORKDIR /build - RUN zypper in -y jq docker wget - RUN mkdir -p files-iso/boot/grub2 - RUN wget https://raw.githubusercontent.com/c3os-io/c3os/master/overlay/files-iso/boot/grub2/grub.cfg -O files-iso/boot/grub2/grub.cfg - WITH DOCKER --allow-privileged --load $IMG=(+image) - RUN /entrypoint.sh --name $ISO_NAME --debug build-iso --date=false --local --overlay-iso /build/files-iso dracut:latest --output /build/ - END - # See: https://github.com/rancher/elemental-cli/issues/228 - RUN sha256sum $ISO_NAME.iso > $ISO_NAME.iso.sha256 - SAVE ARTIFACT /build/$ISO_NAME.iso iso AS LOCAL build/$ISO_NAME.iso - SAVE ARTIFACT /build/$ISO_NAME.iso.sha256 sha256 AS LOCAL build/$ISO_NAME.iso.sha256 \ No newline at end of file + COPY --keep-own +grub-files/grub.cfg /build/files-iso/boot/grub2/grub.cfg + COPY --keep-own +image-rootfs/rootfs /build/rootfs + RUN /entrypoint.sh --name $ISO_NAME --debug build-iso --squash-no-compression --date=false --local --overlay-iso /build/files-iso --output /build/ dir:/build/rootfs + SAVE ARTIFACT /build/$ISO_NAME.iso iso AS LOCAL build/$ISO_NAME-$VERSION.iso + SAVE ARTIFACT /build/$ISO_NAME.iso.sha256 sha256 AS LOCAL build/$ISO_NAME-$VERSION.iso.sha256 \ No newline at end of file diff --git a/dracut/28immucore/generator.sh b/dracut/28immucore/generator.sh old mode 100644 new mode 100755 diff --git a/dracut/28immucore/module-setup.sh b/dracut/28immucore/module-setup.sh old mode 100644 new mode 100755 index 72f11fa..a1c2531 --- a/dracut/28immucore/module-setup.sh +++ b/dracut/28immucore/module-setup.sh @@ -23,7 +23,6 @@ install() { declare moddir=${moddir} declare systemdutildir=${systemdutildir} declare systemdsystemunitdir=${systemdsystemunitdir} - declare initdir="${initdir}" inst_multiple \ immucore diff --git a/earthly.sh b/earthly.sh new file mode 100755 index 0000000..b9b8a4d --- /dev/null +++ b/earthly.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run --privileged -v /var/run/docker.sock:/var/run/docker.sock --rm -t -v $(pwd):/workspace -v earthly-tmp:/tmp/earthly:rw earthly/earthly:v0.6.21 --allow-privileged $@ diff --git a/go.mod b/go.mod index 534821a..497884b 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,8 @@ go 1.19 require ( github.com/containerd/containerd v1.6.15 github.com/deniswernert/go-fstab v0.0.0-20141204152952-eb4090f26517 + github.com/hashicorp/go-multierror v1.1.1 + github.com/joho/godotenv v1.4.0 github.com/kairos-io/kairos v1.5.0 github.com/moby/sys/mountinfo v0.5.0 github.com/onsi/ginkgo/v2 v2.7.1 @@ -29,8 +31,6 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/gookit/color v1.5.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/joho/godotenv v1.4.0 // indirect github.com/kendru/darwin/go/depgraph v0.0.0-20221105232959-877d6a81060c // indirect github.com/lithammer/fuzzysearch v1.1.5 // indirect github.com/mattn/go-colorable v0.1.13 // indirect diff --git a/go.sum b/go.sum index 31fb1c4..6e6a7d6 100644 --- a/go.sum +++ b/go.sum @@ -652,8 +652,6 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spectrocloud-labs/herd v0.2.1 h1:Z08zjr8i+DFD6hB/51FnMSDIf2Q3nKGtA25UMYJwKMI= -github.com/spectrocloud-labs/herd v0.2.1/go.mod h1:fcZ8fjFcEJUM7qF6YcgxF3z8CCLjJeF7r4K1m8JQbHs= github.com/spectrocloud-labs/herd v0.3.0 h1:n/VmHC/3NKfteYhiBonlFtohMRiMGuc6in0krqkyWMw= github.com/spectrocloud-labs/herd v0.3.0/go.mod h1:RHPSzrH+Jd05+ewEpqk8ZgBgTsnHN8erkxwRdQAiw3Q= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= diff --git a/internal/cmd/commands.go b/internal/cmd/commands.go index 6c21283..a68af88 100644 --- a/internal/cmd/commands.go +++ b/internal/cmd/commands.go @@ -23,15 +23,19 @@ Sends a generic event payload with the configuration found in the scanned direct Aliases: []string{}, Flags: []cli.Flag{}, Action: func(c *cli.Context) error { - log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).With().Caller().Logger() g := herd.DAG() - s := &mount.State{Rootdir: "/"} + s := &mount.State{Logger: log.Logger, Rootdir: "/"} - s.Register(g) + err := s.Register(g) + if err != nil { + s.Logger.Err(err) + return err + } log.Print(s.WriteDAG(g)) - return nil + return err //return g.Run(context.Background()) }, }, diff --git a/pkg/mount/mount.go b/pkg/mount/mount.go index ee34d7a..5f601e6 100644 --- a/pkg/mount/mount.go +++ b/pkg/mount/mount.go @@ -3,6 +3,7 @@ package mount import ( "context" "fmt" + "github.com/rs/zerolog" "os" "path/filepath" "strings" @@ -18,6 +19,7 @@ import ( ) type State struct { + Logger zerolog.Logger Rootdir string // e.g. /sysroot inside initrd with pivot, / with nopivot TargetImage string // e.g. /cOS/active.img TargetLabel string // e.g. COS_ACTIVE @@ -66,7 +68,9 @@ func (s *State) WriteFstab(fstabFile string) func(context.Context) error { return err } defer f.Close() - if _, err := f.WriteString(fmt.Sprintf("%s\n", fst.String())); err != nil { + toWrite := fmt.Sprintf("%s\n", fst.String()) + s.Logger.Debug().Str("fstab", toWrite) + if _, err := f.WriteString(toWrite); err != nil { return err } } @@ -78,12 +82,15 @@ func (s *State) WriteFstab(fstabFile string) func(context.Context) error { // ln -sf -t / /sysroot/system func (s *State) RunStageOp(stage string) func(context.Context) error { return func(ctx context.Context) error { - _, err := utils.SH(fmt.Sprintf("elemental run-stage %s", stage)) + cmd := fmt.Sprintf("elemental run-stage %s", stage) + s.Logger.Debug().Str("cmd", cmd) + _, err := utils.SH(cmd) return err } } func (s *State) MountOP(what, where, t string, options []string, timeout time.Duration) func(context.Context) error { + s.Logger.Debug().Str("what", what).Str("where", where).Str("type", t) return func(c context.Context) error { for { select { @@ -94,11 +101,11 @@ func (s *State) MountOP(what, where, t string, options []string, timeout time.Du Source: what, Options: options, } - fstab := mountToStab(mountPoint) - fstab.File = where + tmpFstab := mountToStab(mountPoint) + tmpFstab.File = where op := mountOperation{ MountOption: mountPoint, - FstabEntry: *fstab, + FstabEntry: *tmpFstab, Target: where, } @@ -107,7 +114,7 @@ func (s *State) MountOP(what, where, t string, options []string, timeout time.Du continue } - s.fstabs = append(s.fstabs, fstab) + s.fstabs = append(s.fstabs, tmpFstab) return nil case <-c.Done(): @@ -152,6 +159,7 @@ func readEnv(file string) (map[string]string, error) { } func (s *State) Register(g *herd.Graph) error { + var err error // TODO: add hooks, fstab (might have missed some), systemd compat // TODO: We should also set tmpfs here (not -related) @@ -163,7 +171,8 @@ func (s *State) Register(g *herd.Graph) error { // This is legacy - in UKI we don't need to found the img, this needs to run in a conditional if s.MountRoot { // setup loopback mount for the image target for booting - g.Add(opDiscoverState, + s.Logger.Debug().Str("what", opDiscoverState).Msg("Add operation") + err = g.Add(opDiscoverState, herd.WithDeps(opMountState), herd.WithCallback( func(ctx context.Context) error { @@ -171,9 +180,13 @@ func (s *State) Register(g *herd.Graph) error { return err }, )) + if err != nil { + s.Logger.Err(err) + } // mount the state partition so to find the loopback device - g.Add(opMountState, + s.Logger.Debug().Str("what", opMountState).Msg("Add operation") + err = g.Add(opMountState, herd.WithCallback( s.MountOP( "/dev/disk/by-label/COS_STATE", @@ -184,9 +197,13 @@ func (s *State) Register(g *herd.Graph) error { }, 60*time.Second), ), ) + if err != nil { + s.Logger.Err(err) + } // mount the loopback device as root of the fs - g.Add(opMountRoot, + s.Logger.Debug().Str("what", opMountRoot).Msg("Add operation") + err = g.Add(opMountRoot, herd.WithDeps(opDiscoverState), herd.WithCallback( s.MountOP( @@ -204,6 +221,9 @@ func (s *State) Register(g *herd.Graph) error { }, 60*time.Second), ), ) + if err != nil { + s.Logger.Err(err) + } } @@ -214,11 +234,16 @@ func (s *State) Register(g *herd.Graph) error { // TODO: this needs to be run after state is discovered // TODO: add symlink if Rootdir != "" // TODO: chroot? - g.Add(opRootfsHook, mountRootCondition, herd.WithDeps(opMountOEM), herd.WithCallback(s.RunStageOp("rootfs"))) + s.Logger.Debug().Str("what", opRootfsHook).Msg("Add operation") + err = g.Add(opRootfsHook, mountRootCondition, herd.WithDeps(opMountOEM), herd.WithCallback(s.RunStageOp("rootfs"))) + if err != nil { + s.Logger.Err(err) + } // /run/cos-layout.env // populate state bindmounts, overlaymounts, custommounts - g.Add(opLoadConfig, + s.Logger.Debug().Str("what", opLoadConfig).Msg("Add operation") + err = g.Add(opLoadConfig, herd.WithDeps(opRootfsHook), herd.WithCallback(func(ctx context.Context) error { @@ -237,12 +262,15 @@ func (s *State) Register(g *herd.Graph) error { // s.CustomMounts = strings.Split(env["VOLUMES"], " ") return nil })) - + if err != nil { + s.Logger.Err(err) + } // end sysroot mount // overlay mount start if rootFSType(s.Rootdir) != "overlay" { - g.Add(opMountBaseOverlay, + s.Logger.Debug().Str("what", opMountBaseOverlay).Msg("Add operation") + err = g.Add(opMountBaseOverlay, herd.WithCallback( func(ctx context.Context) error { op, err := baseOverlay(profile.Overlay{ @@ -257,13 +285,16 @@ func (s *State) Register(g *herd.Graph) error { }, ), ) + if err != nil { + s.Logger.Err(err) + } } overlayCondition := herd.ConditionalOption(func() bool { return rootFSType(s.Rootdir) != "overlay" }, herd.WithDeps(opMountBaseOverlay)) // TODO: Add fsck // mount overlay - - g.Add( + s.Logger.Debug().Str("what", opOverlayMount).Msg("Add operation") + err = g.Add( opOverlayMount, overlayCondition, herd.WithDeps(opLoadConfig), @@ -284,8 +315,11 @@ func (s *State) Register(g *herd.Graph) error { }, ), ) - - g.Add( + if err != nil { + s.Logger.Err(err) + } + s.Logger.Debug().Str("what", opCustomMounts).Msg("Add operation") + err = g.Add( opCustomMounts, mountRootCondition, overlayCondition, @@ -309,10 +343,13 @@ func (s *State) Register(g *herd.Graph) error { return err }), ) + if err != nil { + s.Logger.Err(err) + } - // mount state // mount state is defined over a custom mount (/usr/local/.state for instance, needs to be mounted over a device) - g.Add( + s.Logger.Debug().Str("what", opMountBind).Msg("Add operation") + err = g.Add( opMountBind, overlayCondition, mountRootCondition, @@ -334,9 +371,13 @@ func (s *State) Register(g *herd.Graph) error { }, ), ) + if err != nil { + s.Logger.Err(err) + } // overlay mount end - g.Add(opMountOEM, + s.Logger.Debug().Str("what", opMountOEM).Msg("Add operation") + err = g.Add(opMountOEM, overlayCondition, mountRootCondition, herd.WithCallback( @@ -355,13 +396,18 @@ func (s *State) Register(g *herd.Graph) error { }, 60*time.Second), ), ) - - g.Add(opWriteFstab, + if err != nil { + s.Logger.Err(err) + } + s.Logger.Debug().Str("what", opWriteFstab).Msg("Add operation") + err = g.Add(opWriteFstab, overlayCondition, mountRootCondition, herd.WithDeps(opMountOEM, opCustomMounts, opMountBind, opOverlayMount), herd.WeakDeps, herd.WithCallback(s.WriteFstab(s.FStabFile))) - - return nil + if err != nil { + s.Logger.Err(err) + } + return err }