Merge pull request #22941 from ashley-cui/machreset

Podman machine resets all providers
This commit is contained in:
openshift-merge-bot[bot]
2024-07-01 19:24:18 +00:00
committed by GitHub
5 changed files with 85 additions and 48 deletions

View File

@ -7,14 +7,14 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"text/tabwriter"
"github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/completion"
"github.com/containers/podman/v5/cmd/podman/registry" "github.com/containers/podman/v5/cmd/podman/registry"
"github.com/containers/podman/v5/cmd/podman/validate" "github.com/containers/podman/v5/cmd/podman/validate"
"github.com/containers/podman/v5/pkg/machine" "github.com/containers/podman/v5/pkg/machine"
"github.com/containers/podman/v5/pkg/machine/env" provider2 "github.com/containers/podman/v5/pkg/machine/provider"
"github.com/containers/podman/v5/pkg/machine/shim" "github.com/containers/podman/v5/pkg/machine/shim"
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -23,7 +23,6 @@ var (
Use: "reset [options]", Use: "reset [options]",
Short: "Remove all machines", Short: "Remove all machines",
Long: "Remove all machines, configurations, data, and cached images", Long: "Remove all machines, configurations, data, and cached images",
PersistentPreRunE: machinePreRunE,
RunE: reset, RunE: reset,
Args: validate.NoArgs, Args: validate.NoArgs,
Example: `podman machine reset`, Example: `podman machine reset`,
@ -51,21 +50,19 @@ func reset(_ *cobra.Command, _ []string) error {
err error err error
) )
dirs, err := env.GetMachineDirs(provider.VMType()) providers, err := provider2.GetAll(resetOptions.Force)
if err != nil {
return err
}
// TODO we could consider saying we get a list of vms but can proceed
// to just delete all local disk dirs, etc. Maybe a --proceed?
mcs, err := vmconfigs.LoadMachinesInDir(dirs)
if err != nil { if err != nil {
return err return err
} }
if !resetOptions.Force { if !resetOptions.Force {
vms := vmNamesFromMcs(mcs) listResponse, err := shim.List(providers, machine.ListOptions{})
resetConfirmationMessage(vms) if err != nil {
return err
}
resetConfirmationMessage(listResponse)
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
fmt.Print("\nAre you sure you want to continue? [y/N] ") fmt.Print("\nAre you sure you want to continue? [y/N] ")
answer, err := reader.ReadString('\n') answer, err := reader.ReadString('\n')
@ -76,24 +73,18 @@ func reset(_ *cobra.Command, _ []string) error {
return nil return nil
} }
} }
return shim.Reset(providers, resetOptions)
// resetErr can be nil or a multi-error
return shim.Reset(dirs, provider, mcs)
} }
func resetConfirmationMessage(vms []string) { func resetConfirmationMessage(listResponse []*machine.ListResponse) {
fmt.Println("Warning: this command will delete all existing Podman machines") fmt.Println("Warning: this command will delete all existing Podman machines")
fmt.Println("and all of the configuration and data directories for Podman machines") fmt.Println("and all of the configuration and data directories for Podman machines")
fmt.Printf("\nThe following machine(s) will be deleted:\n\n") fmt.Printf("\nThe following machine(s) will be deleted:\n\n")
for _, msg := range vms { w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
fmt.Printf("%s\n", msg) fmt.Fprintln(w, "NAME\tPROVIDER")
}
}
func vmNamesFromMcs(mcs map[string]*vmconfigs.MachineConfig) []string { for _, m := range listResponse {
keys := make([]string, 0, len(mcs)) fmt.Fprintf(w, "%s\t%s\n", m.Name, m.VMType)
for k := range mcs {
keys = append(keys, k)
} }
return keys w.Flush()
} }

View File

@ -38,6 +38,10 @@ func Get() (vmconfigs.VMProvider, error) {
} }
} }
func GetAll(_ bool) ([]vmconfigs.VMProvider, error) {
return []vmconfigs.VMProvider{new(qemu.QEMUStubber)}, nil
}
// SupportedProviders returns the providers that are supported on the host operating system // SupportedProviders returns the providers that are supported on the host operating system
func SupportedProviders() []define.VMType { func SupportedProviders() []define.VMType {
return []define.VMType{define.QemuVirt} return []define.VMType{define.QemuVirt}

View File

@ -42,6 +42,13 @@ func Get() (vmconfigs.VMProvider, error) {
} }
} }
func GetAll(_ bool) ([]vmconfigs.VMProvider, error) {
return []vmconfigs.VMProvider{
new(applehv.AppleHVStubber),
new(libkrun.LibKrunStubber),
}, nil
}
// SupportedProviders returns the providers that are supported on the host operating system // SupportedProviders returns the providers that are supported on the host operating system
func SupportedProviders() []define.VMType { func SupportedProviders() []define.VMType {
supported := []define.VMType{define.AppleHvVirt} supported := []define.VMType{define.AppleHvVirt}

View File

@ -43,6 +43,18 @@ func Get() (vmconfigs.VMProvider, error) {
} }
} }
func GetAll(force bool) ([]vmconfigs.VMProvider, error) {
providers := []vmconfigs.VMProvider{
new(wsl.WSLStubber),
}
if !wsl.HasAdminRights() && !force {
logrus.Warn("managing hyperv machines require admin authority.")
} else {
providers = append(providers, new(hyperv.HyperVStubber))
}
return providers, nil
}
// SupportedProviders returns the providers that are supported on the host operating system // SupportedProviders returns the providers that are supported on the host operating system
func SupportedProviders() []define.VMType { func SupportedProviders() []define.VMType {
return []define.VMType{define.HyperVVirt, define.WSLVirt} return []define.VMType{define.HyperVVirt, define.WSLVirt}

View File

@ -636,10 +636,25 @@ func confirmationMessage(files []string) {
} }
} }
func Reset(dirs *machineDefine.MachineDirs, mp vmconfigs.VMProvider, mcs map[string]*vmconfigs.MachineConfig) error { func Reset(mps []vmconfigs.VMProvider, opts machine.ResetOptions) error {
var resetErrors *multierror.Error var resetErrors *multierror.Error
removeDirs := []*machineDefine.MachineDirs{}
for _, p := range mps {
d, err := env.GetMachineDirs(p.VMType())
if err != nil {
resetErrors = multierror.Append(resetErrors, err)
continue
}
mcs, err := vmconfigs.LoadMachinesInDir(d)
if err != nil {
resetErrors = multierror.Append(resetErrors, err)
continue
}
removeDirs = append(removeDirs, d)
for _, mc := range mcs { for _, mc := range mcs {
err := Stop(mc, mp, dirs, true) err := Stop(mc, p, d, true)
if err != nil { if err != nil {
resetErrors = multierror.Append(resetErrors, err) resetErrors = multierror.Append(resetErrors, err)
} }
@ -647,7 +662,7 @@ func Reset(dirs *machineDefine.MachineDirs, mp vmconfigs.VMProvider, mcs map[str
if err != nil { if err != nil {
resetErrors = multierror.Append(resetErrors, err) resetErrors = multierror.Append(resetErrors, err)
} }
_, providerRm, err := mp.Remove(mc) _, providerRm, err := p.Remove(mc)
if err != nil { if err != nil {
resetErrors = multierror.Append(resetErrors, err) resetErrors = multierror.Append(resetErrors, err)
} }
@ -659,15 +674,23 @@ func Reset(dirs *machineDefine.MachineDirs, mp vmconfigs.VMProvider, mcs map[str
resetErrors = multierror.Append(resetErrors, err) resetErrors = multierror.Append(resetErrors, err)
} }
} }
}
// Delete the various directories // Delete the various directories
// We do this after all the provider rm's, since providers may still share the base machine dir.
// Note: we cannot delete the machine run dir blindly like this because // Note: we cannot delete the machine run dir blindly like this because
// other things live there like the podman.socket and so forth. // other things live there like the podman.socket and so forth.
for _, dir := range removeDirs {
// in linux this ~/.local/share/containers/podman/machine // in linux this ~/.local/share/containers/podman/machine
dataDirErr := utils.GuardedRemoveAll(filepath.Dir(dirs.DataDir.GetPath())) dataDirErr := utils.GuardedRemoveAll(filepath.Dir(dir.DataDir.GetPath()))
if !errors.Is(dataDirErr, os.ErrNotExist) {
resetErrors = multierror.Append(resetErrors, dataDirErr)
}
// in linux this ~/.config/containers/podman/machine // in linux this ~/.config/containers/podman/machine
confDirErr := utils.GuardedRemoveAll(filepath.Dir(dirs.ConfigDir.GetPath())) confDirErr := utils.GuardedRemoveAll(filepath.Dir(dir.ConfigDir.GetPath()))
resetErrors = multierror.Append(resetErrors, confDirErr, dataDirErr) if !errors.Is(confDirErr, os.ErrNotExist) {
resetErrors = multierror.Append(resetErrors, confDirErr)
}
}
return resetErrors.ErrorOrNil() return resetErrors.ErrorOrNil()
} }