cloud/agent: migrate to bringup package
Change-Id: Ibe89c37cae058395723c9ed5ad5914d62a9af891
Reviewed-on: https://review.monogon.dev/c/monogon/+/3392
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/cloud/agent/BUILD.bazel b/cloud/agent/BUILD.bazel
index 2574ad4..db3ee51 100644
--- a/cloud/agent/BUILD.bazel
+++ b/cloud/agent/BUILD.bazel
@@ -6,7 +6,6 @@
"agent.go",
"hwreport.go",
"install.go",
- "main.go",
],
embedsrcs = [
"//metropolis/node/core/abloader", #keep
@@ -19,7 +18,7 @@
"//metropolis/node/core/devmgr",
"//metropolis/node/core/network",
"//osbase/blockdev",
- "//osbase/bootparam",
+ "//osbase/bringup",
"//osbase/build/mkimage/osimage",
"//osbase/efivarfs",
"//osbase/logtree",
diff --git a/cloud/agent/agent.go b/cloud/agent/agent.go
index 4430424..e0bfd81 100644
--- a/cloud/agent/agent.go
+++ b/cloud/agent/agent.go
@@ -20,12 +20,18 @@
apb "source.monogon.dev/cloud/agent/api"
bpb "source.monogon.dev/cloud/bmaas/server/api"
+
"source.monogon.dev/metropolis/node/core/devmgr"
"source.monogon.dev/metropolis/node/core/network"
+ "source.monogon.dev/osbase/bringup"
"source.monogon.dev/osbase/pki"
"source.monogon.dev/osbase/supervisor"
)
+func main() {
+ bringup.Runnable(agentRunnable).Run()
+}
+
// This is similar to rpc.NewEphemeralCredentials, but that only deals with
// Metropolis-style certificate verification.
func newEphemeralCert(private ed25519.PrivateKey) (*tls.Certificate, error) {
@@ -51,11 +57,6 @@
// Main runnable for the agent.
func agentRunnable(ctx context.Context) error {
l := supervisor.Logger(ctx)
- // Mount this late so we don't just crash when not booted with EFI.
- isEFIBoot := false
- if err := mkdirAndMount("/sys/firmware/efi/efivars", "efivarfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV); err == nil {
- isEFIBoot = true
- }
agentInitRaw, err := os.ReadFile("/init.pb")
if err != nil {
return fmt.Errorf("unable to read spec file from takeover: %w", err)
@@ -166,7 +167,7 @@
installationReport = &bpb.OSInstallationReport{
Generation: res.InstallationRequest.Generation,
}
- if err := install(res.InstallationRequest, agentInit.NetworkConfig, l, isEFIBoot); err != nil {
+ if err := install(res.InstallationRequest, agentInit.NetworkConfig, l); err != nil {
l.Errorf("Installation failed: %v", err)
installationReport.Result = &bpb.OSInstallationReport_Error_{
Error: &bpb.OSInstallationReport_Error{
diff --git a/cloud/agent/install.go b/cloud/agent/install.go
index 7752517..29641bd 100644
--- a/cloud/agent/install.go
+++ b/cloud/agent/install.go
@@ -8,6 +8,7 @@
"fmt"
"io/fs"
"net/http"
+ "os"
"path/filepath"
"github.com/cenkalti/backoff/v4"
@@ -41,17 +42,18 @@
// install dispatches OSInstallationRequests to the appropriate installer
// method
-func install(req *bpb.OSInstallationRequest, netConfig *npb.Net, l logtree.LeveledLogger, isEFIBoot bool) error {
+func install(req *bpb.OSInstallationRequest, netConfig *npb.Net, l logtree.LeveledLogger) error {
switch reqT := req.Type.(type) {
case *bpb.OSInstallationRequest_Metropolis:
- return installMetropolis(reqT.Metropolis, netConfig, l, isEFIBoot)
+ return installMetropolis(reqT.Metropolis, netConfig, l)
default:
return errors.New("unknown installation request type")
}
}
-func installMetropolis(req *bpb.MetropolisInstallationRequest, netConfig *npb.Net, l logtree.LeveledLogger, isEFIBoot bool) error {
- if !isEFIBoot {
+func installMetropolis(req *bpb.MetropolisInstallationRequest, netConfig *npb.Net, l logtree.LeveledLogger) error {
+ // Validate we are running via EFI.
+ if _, err := os.Stat("/sys/firmware/efi"); os.IsNotExist(err) {
//nolint:ST1005
return errors.New("Monogon OS can only be installed on EFI-booted machines, this one is not")
}
diff --git a/cloud/agent/main.go b/cloud/agent/main.go
deleted file mode 100644
index 511e688..0000000
--- a/cloud/agent/main.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package main
-
-import (
- "context"
- "fmt"
- "os"
- "regexp"
-
- "golang.org/x/sys/unix"
-
- "source.monogon.dev/osbase/bootparam"
- "source.monogon.dev/osbase/logtree"
- "source.monogon.dev/osbase/supervisor"
-)
-
-var validTTYRegexp = regexp.MustCompile(`^[a-zA-Z0-9]+$`)
-
-func main() {
- setupMounts()
-
- // Set up logger for the Agent. Parse consoles from the kernel command line
- // as well as adding the two standard tty0/ttyS0 consoles.
- consoles := make(map[string]bool)
- cmdline, err := os.ReadFile("/proc/cmdline")
- if err == nil {
- params, _, err := bootparam.Unmarshal(string(cmdline))
- if err == nil {
- consoles = params.Consoles()
- }
- }
- consoles["tty0"] = true
- consoles["ttyS0"] = true
-
- lt := logtree.New()
- for path := range consoles {
- f, err := os.OpenFile("/dev/"+path, os.O_WRONLY, 0)
- if err != nil {
- continue
- }
- reader, err := lt.Read("", logtree.WithChildren(), logtree.WithStream())
- if err != nil {
- panic(fmt.Sprintf("could not set up root log reader: %v", err))
- }
- go func() {
- for {
- p := <-reader.Stream
- fmt.Fprintf(f, "%s\n", p.String())
- }
- }()
- }
-
- sCtx := context.Background()
- supervisor.New(sCtx, agentRunnable, supervisor.WithExistingLogtree(lt))
- select {}
-}
-
-func mkdirAndMount(dir, fs string, flags uintptr) error {
- if err := os.MkdirAll(dir, 0o755); err != nil {
- return fmt.Errorf("could not make %s: %w", dir, err)
- }
- if err := unix.Mount(fs, dir, fs, flags, ""); err != nil {
- return fmt.Errorf("could not mount %s on %s: %w", fs, dir, err)
- }
- return nil
-}
-
-// setupMounts sets up basic mounts like sysfs, procfs, devtmpfs and cgroups.
-// This should be called early during init as a lot of processes depend on this
-// being available.
-func setupMounts() error {
- // Set up target filesystems.
- for _, el := range []struct {
- dir string
- fs string
- flags uintptr
- }{
- {"/sys", "sysfs", unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV},
- {"/sys/kernel/tracing", "tracefs", unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV},
- {"/sys/fs/pstore", "pstore", unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV},
- {"/proc", "proc", unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV},
- {"/dev", "devtmpfs", unix.MS_NOEXEC | unix.MS_NOSUID},
- {"/dev/pts", "devpts", unix.MS_NOEXEC | unix.MS_NOSUID},
- } {
- if err := mkdirAndMount(el.dir, el.fs, el.flags); err != nil {
- return err
- }
- }
- return nil
-}