mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-08-21 15:57:54 +00:00
Use `Default()` instead of re-loading containers.conf. Also rework how the containers.conf objects are handled for parsing the CLI. Previously, we were conflating "loading the defaults" with "storing values from the CLI" with "libpod may further change fields" which ultimately led to various bugs and test failues. To address the issue, separate the defaults from the values from the CLI and properly name the fields to make the semantics less ambiguous. [NO NEW TESTS NEEDED] as it's not a functional change. Fixes: containers/common/issues/1200 Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
161 lines
5.3 KiB
Go
161 lines
5.3 KiB
Go
//go:build amd64 || arm64
|
|
// +build amd64 arm64
|
|
|
|
package machine
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/containers/common/pkg/completion"
|
|
"github.com/containers/podman/v4/cmd/podman/registry"
|
|
"github.com/containers/podman/v4/libpod/events"
|
|
"github.com/containers/podman/v4/pkg/machine"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
initCmd = &cobra.Command{
|
|
Use: "init [options] [NAME]",
|
|
Short: "Initialize a virtual machine",
|
|
Long: "initialize a virtual machine ",
|
|
PersistentPreRunE: rootlessOnly,
|
|
RunE: initMachine,
|
|
Args: cobra.MaximumNArgs(1),
|
|
Example: `podman machine init myvm`,
|
|
ValidArgsFunction: completion.AutocompleteNone,
|
|
}
|
|
|
|
initOpts = machine.InitOptions{}
|
|
defaultMachineName = machine.DefaultMachineName
|
|
now bool
|
|
)
|
|
|
|
// maxMachineNameSize is set to thirty to limit huge machine names primarily
|
|
// because macOS has a much smaller file size limit.
|
|
const maxMachineNameSize = 30
|
|
|
|
func init() {
|
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
|
Command: initCmd,
|
|
Parent: machineCmd,
|
|
})
|
|
flags := initCmd.Flags()
|
|
cfg := registry.PodmanConfig()
|
|
|
|
cpusFlagName := "cpus"
|
|
flags.Uint64Var(
|
|
&initOpts.CPUS,
|
|
cpusFlagName, cfg.ContainersConfDefaultsRO.Machine.CPUs,
|
|
"Number of CPUs",
|
|
)
|
|
_ = initCmd.RegisterFlagCompletionFunc(cpusFlagName, completion.AutocompleteNone)
|
|
|
|
diskSizeFlagName := "disk-size"
|
|
flags.Uint64Var(
|
|
&initOpts.DiskSize,
|
|
diskSizeFlagName, cfg.ContainersConfDefaultsRO.Machine.DiskSize,
|
|
"Disk size in GB",
|
|
)
|
|
|
|
_ = initCmd.RegisterFlagCompletionFunc(diskSizeFlagName, completion.AutocompleteNone)
|
|
|
|
memoryFlagName := "memory"
|
|
flags.Uint64VarP(
|
|
&initOpts.Memory,
|
|
memoryFlagName, "m", cfg.ContainersConfDefaultsRO.Machine.Memory,
|
|
"Memory in MB",
|
|
)
|
|
_ = initCmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
|
|
|
|
flags.BoolVar(
|
|
&now,
|
|
"now", false,
|
|
"Start machine now",
|
|
)
|
|
timezoneFlagName := "timezone"
|
|
defaultTz := cfg.ContainersConfDefaultsRO.TZ()
|
|
if len(defaultTz) < 1 {
|
|
defaultTz = "local"
|
|
}
|
|
flags.StringVar(&initOpts.TimeZone, timezoneFlagName, defaultTz, "Set timezone")
|
|
_ = initCmd.RegisterFlagCompletionFunc(timezoneFlagName, completion.AutocompleteDefault)
|
|
|
|
flags.BoolVar(
|
|
&initOpts.ReExec,
|
|
"reexec", false,
|
|
"process was rexeced",
|
|
)
|
|
_ = flags.MarkHidden("reexec")
|
|
|
|
UsernameFlagName := "username"
|
|
flags.StringVar(&initOpts.Username, UsernameFlagName, cfg.ContainersConfDefaultsRO.Machine.User, "Username used in qcow image")
|
|
_ = initCmd.RegisterFlagCompletionFunc(UsernameFlagName, completion.AutocompleteDefault)
|
|
|
|
ImagePathFlagName := "image-path"
|
|
flags.StringVar(&initOpts.ImagePath, ImagePathFlagName, cfg.ContainersConfDefaultsRO.Machine.Image, "Path to qcow image")
|
|
_ = initCmd.RegisterFlagCompletionFunc(ImagePathFlagName, completion.AutocompleteDefault)
|
|
|
|
VolumeFlagName := "volume"
|
|
flags.StringArrayVarP(&initOpts.Volumes, VolumeFlagName, "v", cfg.ContainersConfDefaultsRO.Machine.Volumes, "Volumes to mount, source:target")
|
|
_ = initCmd.RegisterFlagCompletionFunc(VolumeFlagName, completion.AutocompleteDefault)
|
|
|
|
VolumeDriverFlagName := "volume-driver"
|
|
flags.StringVar(&initOpts.VolumeDriver, VolumeDriverFlagName, "", "Optional volume driver")
|
|
_ = initCmd.RegisterFlagCompletionFunc(VolumeDriverFlagName, completion.AutocompleteDefault)
|
|
|
|
IgnitionPathFlagName := "ignition-path"
|
|
flags.StringVar(&initOpts.IgnitionPath, IgnitionPathFlagName, "", "Path to ignition file")
|
|
_ = initCmd.RegisterFlagCompletionFunc(IgnitionPathFlagName, completion.AutocompleteDefault)
|
|
|
|
rootfulFlagName := "rootful"
|
|
flags.BoolVar(&initOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
|
|
}
|
|
|
|
func initMachine(cmd *cobra.Command, args []string) error {
|
|
var (
|
|
err error
|
|
vm machine.VM
|
|
)
|
|
|
|
provider := GetSystemDefaultProvider()
|
|
initOpts.Name = defaultMachineName
|
|
if len(args) > 0 {
|
|
if len(args[0]) > maxMachineNameSize {
|
|
return fmt.Errorf("machine name %q must be %d characters or less", args[0], maxMachineNameSize)
|
|
}
|
|
initOpts.Name = args[0]
|
|
}
|
|
if _, err := provider.LoadVMByName(initOpts.Name); err == nil {
|
|
return fmt.Errorf("%s: %w", initOpts.Name, machine.ErrVMAlreadyExists)
|
|
}
|
|
for idx, vol := range initOpts.Volumes {
|
|
initOpts.Volumes[idx] = os.ExpandEnv(vol)
|
|
}
|
|
vm, err = provider.NewMachine(initOpts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if finished, err := vm.Init(initOpts); err != nil || !finished {
|
|
// Finished = true, err = nil - Success! Log a message with further instructions
|
|
// Finished = false, err = nil - The installation is partially complete and podman should
|
|
// exit gracefully with no error and no success message.
|
|
// Examples:
|
|
// - a user has chosen to perform their own reboot
|
|
// - reexec for limited admin operations, returning to parent
|
|
// Finished = *, err != nil - Exit with an error message
|
|
return err
|
|
}
|
|
newMachineEvent(events.Init, events.Event{Name: initOpts.Name})
|
|
fmt.Println("Machine init complete")
|
|
|
|
if now {
|
|
return start(cmd, args)
|
|
}
|
|
extra := ""
|
|
if initOpts.Name != defaultMachineName {
|
|
extra = " " + initOpts.Name
|
|
}
|
|
fmt.Printf("To start your machine run:\n\n\tpodman machine start%s\n\n", extra)
|
|
return err
|
|
}
|