diff --git a/internal/cli/kraft/run/run.go b/internal/cli/kraft/run/run.go index b9366f3b1..f29a19f39 100644 --- a/internal/cli/kraft/run/run.go +++ b/internal/cli/kraft/run/run.go @@ -14,6 +14,7 @@ import ( "github.com/MakeNowJust/heredoc" "github.com/rancher/wrangler/pkg/signals" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -28,6 +29,7 @@ import ( "kraftkit.sh/machine/network" mplatform "kraftkit.sh/machine/platform" "kraftkit.sh/packmanager" + "kraftkit.sh/unikraft/arch" ) type RunOptions struct { @@ -259,6 +261,12 @@ func (opts *RunOptions) Run(ctx context.Context, args []string) error { return err } + if _, found := arch.ArchitecturesByName()[opts.Architecture]; !found { + log.G(ctx).WithFields(logrus.Fields{ + "arch": opts.Architecture, + }).Warn("unknown or incompatible") + } + machine := &machineapi.Machine{ ObjectMeta: metav1.ObjectMeta{}, Spec: machineapi.MachineSpec{ diff --git a/internal/cli/kraft/run/runner_kernel.go b/internal/cli/kraft/run/runner_kernel.go index a2f84f808..d89a948c1 100644 --- a/internal/cli/kraft/run/runner_kernel.go +++ b/internal/cli/kraft/run/runner_kernel.go @@ -12,6 +12,7 @@ import ( machineapi "kraftkit.sh/api/machine/v1alpha1" "kraftkit.sh/unikraft" + "kraftkit.sh/unikraft/arch" ) // runnerKernel is a simple runner used for instantiating a prebuilt Unikraft @@ -65,11 +66,11 @@ func (runner *runnerKernel) Prepare(ctx context.Context, opts *RunOptions, machi switch fe.Machine { case elf.EM_X86_64, elf.EM_386: - machine.Spec.Architecture = "x86_64" + machine.Spec.Architecture = arch.ArchitectureX86_64.String() case elf.EM_ARM: - machine.Spec.Architecture = "arm" + machine.Spec.Architecture = arch.ArchitectureArm.String() case elf.EM_AARCH64: - machine.Spec.Architecture = "arm64" + machine.Spec.Architecture = arch.ArchitectureArm64.String() default: return fmt.Errorf("unsupported kernel architecture: %v", fe.Machine.String()) } diff --git a/internal/cli/kraft/run/utils.go b/internal/cli/kraft/run/utils.go index 9174e3c5c..536c7d70b 100644 --- a/internal/cli/kraft/run/utils.go +++ b/internal/cli/kraft/run/utils.go @@ -261,8 +261,7 @@ func (opts *RunOptions) prepareRootfs(ctx context.Context, machine *machineapi.M fmt.Sprintf(initrd.DefaultInitramfsArchFileName, machine.Spec.Architecture), ) - fi, err := os.Stat(machine.Status.InitrdPath) - if err != nil { + if _, err := os.Stat(machine.Status.InitrdPath); err != nil { ramfs, err := initrd.New(ctx, opts.Rootfs, initrd.WithOutput(machine.Status.InitrdPath), @@ -277,18 +276,20 @@ func (opts *RunOptions) prepareRootfs(ctx context.Context, machine *machineapi.M return fmt.Errorf("could not prepare initramfs: %w", err) } - if _, err = ramfs.Build(ctx); err != nil { + if machine.Status.InitrdPath, err = ramfs.Build(ctx); err != nil { return err } } - // Warn if the initrd path is greater than allocated memory - memRequest := machine.Spec.Resources.Requests[corev1.ResourceMemory] - if memRequest.Value() < fi.Size() { - log.G(ctx).Warnf("requested memory (%s) is less than initramfs (%s)", - humanize.Bytes(uint64(memRequest.Value())), - humanize.Bytes(uint64(fi.Size())), - ) + if fi, err := os.Stat(machine.Status.InitrdPath); err == nil { + // Warn if the initrd path is greater than allocated memory + memRequest := machine.Spec.Resources.Requests[corev1.ResourceMemory] + if memRequest.Value() < fi.Size() { + log.G(ctx).Warnf("requested memory (%s) is less than initramfs (%s)", + humanize.Bytes(uint64(memRequest.Value())), + humanize.Bytes(uint64(fi.Size())), + ) + } } return nil diff --git a/unikraft/arch/architecture.go b/unikraft/arch/architecture.go index e873bb270..c732ffcec 100644 --- a/unikraft/arch/architecture.go +++ b/unikraft/arch/architecture.go @@ -15,6 +15,63 @@ import ( "kraftkit.sh/unikraft/component" ) +type ArchitectureName string + +const ( + ArchitectureUnknown = ArchitectureName("unknown") + ArchitectureX86_64 = ArchitectureName("x86_64") + ArchitectureArm64 = ArchitectureName("arm64") + ArchitectureArm = ArchitectureName("arm") +) + +// String implements fmt.Stringer +func (ht ArchitectureName) String() string { + return string(ht) +} + +// ArchitectureByName returns the architecture for a given name. +// If the name is not known, it returns it unchanged. +func ArchitectureByName(name string) ArchitectureName { + architectures := ArchitecturesByName() + if _, ok := architectures[name]; !ok { + return ArchitectureUnknown + } + return architectures[name] +} + +// ArchitecturesByName returns the list of known architectures and their name alises. +func ArchitecturesByName() map[string]ArchitectureName { + return map[string]ArchitectureName{ + "x86_64": ArchitectureX86_64, + "arm64": ArchitectureArm64, + "arm": ArchitectureArm, + } +} + +// Architectures returns all the unique Architectures. +func Architectures() []ArchitectureName { + return []ArchitectureName{ + ArchitectureX86_64, + ArchitectureArm64, + ArchitectureArm, + } +} + +// ArchitectureAliases returns all the name alises for a given architecture. +func ArchitectureAliases() map[ArchitectureName][]string { + aliases := map[ArchitectureName][]string{} + + for alias, plat := range ArchitecturesByName() { + if aliases[plat] == nil { + aliases[plat] = make([]string, 0) + } + + aliases[plat] = append(aliases[plat], alias) + } + + return aliases +} + type Architecture interface { component.Component } @@ -110,12 +167,12 @@ func (ac ArchitectureConfig) KConfig() kconfig.KeyValueMap { var arch strings.Builder arch.WriteString(kconfig.Prefix) - switch ac.Name() { - case "x86_64", "amd64": + switch ArchitectureName(ac.Name()) { + case ArchitectureX86_64: arch.WriteString("ARCH_X86_64") - case "arm32": + case ArchitectureArm: arch.WriteString("ARCH_ARM_32") - case "arm64": + case ArchitectureArm64: arch.WriteString("ARCH_ARM_64") }