podman system reset removed machines incorrectly

podman system reset did not clean up machines fully, leaving some config
files, and breaking machines. Now it removes all machines files fully.

Signed-off-by: Ashley Cui <acui@redhat.com>
This commit is contained in:
Ashley Cui
2022-04-27 16:56:48 -04:00
parent 698cb730a1
commit 80744c6441
19 changed files with 230 additions and 20 deletions

View File

@ -117,7 +117,7 @@ func initMachine(cmd *cobra.Command, args []string) error {
vm machine.VM vm machine.VM
) )
provider := getSystemDefaultProvider() provider := GetSystemDefaultProvider()
initOpts.Name = defaultMachineName initOpts.Name = defaultMachineName
if len(args) > 0 { if len(args) > 0 {
if len(args[0]) > maxMachineNameSize { if len(args[0]) > maxMachineNameSize {

View File

@ -52,7 +52,7 @@ func inspect(cmd *cobra.Command, args []string) error {
args = append(args, defaultMachineName) args = append(args, defaultMachineName)
} }
vms := make([]machine.InspectInfo, 0, len(args)) vms := make([]machine.InspectInfo, 0, len(args))
provider := getSystemDefaultProvider() provider := GetSystemDefaultProvider()
for _, vmName := range args { for _, vmName := range args {
vm, err := provider.LoadVMByName(vmName) vm, err := provider.LoadVMByName(vmName)
if err != nil { if err != nil {

View File

@ -85,7 +85,7 @@ func list(cmd *cobra.Command, args []string) error {
listFlag.format = "{{.Name}}\n" listFlag.format = "{{.Name}}\n"
} }
provider := getSystemDefaultProvider() provider := GetSystemDefaultProvider()
listResponse, err = provider.List(opts) listResponse, err = provider.List(opts)
if err != nil { if err != nil {
return errors.Wrap(err, "error listing vms") return errors.Wrap(err, "error listing vms")

View File

@ -51,7 +51,7 @@ func autocompleteMachine(cmd *cobra.Command, args []string, toComplete string) (
func getMachines(toComplete string) ([]string, cobra.ShellCompDirective) { func getMachines(toComplete string) ([]string, cobra.ShellCompDirective) {
suggestions := []string{} suggestions := []string{}
provider := getSystemDefaultProvider() provider := GetSystemDefaultProvider()
machines, err := provider.List(machine.ListOptions{}) machines, err := provider.List(machine.ListOptions{})
if err != nil { if err != nil {
cobra.CompErrorln(err.Error()) cobra.CompErrorln(err.Error())

View File

@ -8,6 +8,6 @@ import (
"github.com/containers/podman/v4/pkg/machine/qemu" "github.com/containers/podman/v4/pkg/machine/qemu"
) )
func getSystemDefaultProvider() machine.Provider { func GetSystemDefaultProvider() machine.Provider {
return qemu.GetQemuProvider() return qemu.GetQemuProvider()
} }

View File

@ -5,6 +5,6 @@ import (
"github.com/containers/podman/v4/pkg/machine/wsl" "github.com/containers/podman/v4/pkg/machine/wsl"
) )
func getSystemDefaultProvider() machine.Provider { func GetSystemDefaultProvider() machine.Provider {
return wsl.GetWSLProvider() return wsl.GetWSLProvider()
} }

View File

@ -60,7 +60,7 @@ func rm(cmd *cobra.Command, args []string) error {
vmName = args[0] vmName = args[0]
} }
provider := getSystemDefaultProvider() provider := GetSystemDefaultProvider()
vm, err = provider.LoadVMByName(vmName) vm, err = provider.LoadVMByName(vmName)
if err != nil { if err != nil {
return err return err

View File

@ -83,7 +83,7 @@ func setMachine(cmd *cobra.Command, args []string) error {
if len(args) > 0 && len(args[0]) > 0 { if len(args) > 0 && len(args[0]) > 0 {
vmName = args[0] vmName = args[0]
} }
provider := getSystemDefaultProvider() provider := GetSystemDefaultProvider()
vm, err = provider.LoadVMByName(vmName) vm, err = provider.LoadVMByName(vmName)
if err != nil { if err != nil {
return err return err

View File

@ -51,7 +51,7 @@ func ssh(cmd *cobra.Command, args []string) error {
// Set the VM to default // Set the VM to default
vmName := defaultMachineName vmName := defaultMachineName
provider := getSystemDefaultProvider() provider := GetSystemDefaultProvider()
// If len is greater than 0, it means we may have been // If len is greater than 0, it means we may have been
// provided the VM name. If so, we check. The VM name, // provided the VM name. If so, we check. The VM name,

View File

@ -41,7 +41,7 @@ func start(cmd *cobra.Command, args []string) error {
vmName = args[0] vmName = args[0]
} }
provider := getSystemDefaultProvider() provider := GetSystemDefaultProvider()
vm, err = provider.LoadVMByName(vmName) vm, err = provider.LoadVMByName(vmName)
if err != nil { if err != nil {
return err return err

View File

@ -40,7 +40,7 @@ func stop(cmd *cobra.Command, args []string) error {
if len(args) > 0 && len(args[0]) > 0 { if len(args) > 0 && len(args[0]) > 0 {
vmName = args[0] vmName = args[0]
} }
provider := getSystemDefaultProvider() provider := GetSystemDefaultProvider()
vm, err = provider.LoadVMByName(vmName) vm, err = provider.LoadVMByName(vmName)
if err != nil { if err != nil {
return err return err

View File

@ -61,7 +61,9 @@ func reset(cmd *cobra.Command, args []string) {
- all pods - all pods
- all images - all images
- all networks - all networks
- all build cache`) - all build cache
- all machines`)
if len(listCtn) > 0 { if len(listCtn) > 0 {
fmt.Println(`WARNING! The following external containers will be purged:`) fmt.Println(`WARNING! The following external containers will be purged:`)
// print first 12 characters of ID and first configured name alias // print first 12 characters of ID and first configured name alias
@ -103,5 +105,11 @@ func reset(cmd *cobra.Command, args []string) {
//nolint:gocritic //nolint:gocritic
os.Exit(define.ExecErrorCodeGeneric) os.Exit(define.ExecErrorCodeGeneric)
} }
// Shutdown podman-machine and delete all machine files
if err := resetMachine(); err != nil {
logrus.Error(err)
}
os.Exit(0) os.Exit(0)
} }

View File

@ -0,0 +1,13 @@
//go:build (amd64 && !remote) || (arm64 && !remote)
// +build amd64,!remote arm64,!remote
package system
import (
cmdMach "github.com/containers/podman/v4/cmd/podman/machine"
)
func resetMachine() error {
provider := cmdMach.GetSystemDefaultProvider()
return provider.RemoveAndCleanMachines()
}

View File

@ -0,0 +1,8 @@
//go:build !amd64 && !arm64
// +build !amd64,!arm64
package system
func resetMachine() error {
return nil
}

View File

@ -7,7 +7,7 @@ podman\-system\-reset - Reset storage back to initial state
**podman system reset** [*options*] **podman system reset** [*options*]
## DESCRIPTION ## DESCRIPTION
**podman system reset** removes all pods, containers, images, networks and volumes. **podman system reset** removes all pods, containers, images, networks and volumes, and machines.
This command must be run **before** changing any of the following fields in the This command must be run **before** changing any of the following fields in the
`containers.conf` or `storage.conf` files: `driver`, `static_dir`, `tmp_dir` `containers.conf` or `storage.conf` files: `driver`, `static_dir`, `tmp_dir`
@ -36,6 +36,7 @@ WARNING! This will remove:
- all images - all images
- all networks - all networks
- all build cache - all build cache
- all machines
Are you sure you want to continue? [y/N] y Are you sure you want to continue? [y/N] y
``` ```

View File

@ -52,6 +52,7 @@ type Provider interface {
List(opts ListOptions) ([]*ListResponse, error) List(opts ListOptions) ([]*ListResponse, error)
IsValidVMName(name string) (bool, error) IsValidVMName(name string) (bool, error)
CheckExclusiveActiveVM() (bool, string, error) CheckExclusiveActiveVM() (bool, string, error)
RemoveAndCleanMachines() error
} }
type RemoteConnectionType string type RemoteConnectionType string
@ -170,11 +171,11 @@ func (rc RemoteConnectionType) MakeSSHURL(host, path, port, userName string) url
// GetDataDir returns the filepath where vm images should // GetDataDir returns the filepath where vm images should
// live for podman-machine. // live for podman-machine.
func GetDataDir(vmType string) (string, error) { func GetDataDir(vmType string) (string, error) {
data, err := homedir.GetDataHome() dataDirPrefix, err := DataDirPrefix()
if err != nil { if err != nil {
return "", err return "", err
} }
dataDir := filepath.Join(data, "containers", "podman", "machine", vmType) dataDir := filepath.Join(dataDirPrefix, vmType)
if _, err := os.Stat(dataDir); !os.IsNotExist(err) { if _, err := os.Stat(dataDir); !os.IsNotExist(err) {
return dataDir, nil return dataDir, nil
} }
@ -182,14 +183,24 @@ func GetDataDir(vmType string) (string, error) {
return dataDir, mkdirErr return dataDir, mkdirErr
} }
// GetConfigDir returns the filepath to where configuration // DataDirPrefix returns the path prefix for all machine data files
// files for podman-machine should live func DataDirPrefix() (string, error) {
func GetConfDir(vmType string) (string, error) { data, err := homedir.GetDataHome()
conf, err := homedir.GetConfigHome()
if err != nil { if err != nil {
return "", err return "", err
} }
confDir := filepath.Join(conf, "containers", "podman", "machine", vmType) dataDir := filepath.Join(data, "containers", "podman", "machine")
return dataDir, nil
}
// GetConfigDir returns the filepath to where configuration
// files for podman-machine should live
func GetConfDir(vmType string) (string, error) {
confDirPrefix, err := ConfDirPrefix()
if err != nil {
return "", err
}
confDir := filepath.Join(confDirPrefix, vmType)
if _, err := os.Stat(confDir); !os.IsNotExist(err) { if _, err := os.Stat(confDir); !os.IsNotExist(err) {
return confDir, nil return confDir, nil
} }
@ -197,6 +208,16 @@ func GetConfDir(vmType string) (string, error) {
return confDir, mkdirErr return confDir, mkdirErr
} }
// ConfDirPrefix returns the path prefix for all machine config files
func ConfDirPrefix() (string, error) {
conf, err := homedir.GetConfigHome()
if err != nil {
return "", err
}
confDir := filepath.Join(conf, "containers", "podman", "machine")
return confDir, nil
}
// ResourceConfig describes physical attributes of the machine // ResourceConfig describes physical attributes of the machine
type ResourceConfig struct { type ResourceConfig struct {
// CPUs to be assigned to the VM // CPUs to be assigned to the VM

View File

@ -1543,3 +1543,79 @@ func (v *MachineVM) editCmdLine(flag string, value string) {
v.CmdLine = append(v.CmdLine, []string{flag, value}...) v.CmdLine = append(v.CmdLine, []string{flag, value}...)
} }
} }
// RemoveAndCleanMachines removes all machine and cleans up any other files associatied with podman machine
func (p *Provider) RemoveAndCleanMachines() error {
var (
vm machine.VM
listResponse []*machine.ListResponse
opts machine.ListOptions
destroyOptions machine.RemoveOptions
)
destroyOptions.Force = true
var prevErr error
listResponse, err := p.List(opts)
if err != nil {
return err
}
for _, mach := range listResponse {
vm, err = p.LoadVMByName(mach.Name)
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
}
_, remove, err := vm.Remove(mach.Name, destroyOptions)
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
} else {
if err := remove(); err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
}
}
}
// Clean leftover files in data dir
dataDir, err := machine.DataDirPrefix()
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
} else {
err := os.RemoveAll(dataDir)
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
}
}
// Clean leftover files in conf dir
confDir, err := machine.ConfDirPrefix()
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
} else {
err := os.RemoveAll(confDir)
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
}
}
return prevErr
}

View File

@ -1442,3 +1442,79 @@ func (v *MachineVM) getResources() (resources machine.ResourceConfig) {
resources.DiskSize = getDiskSize(v) resources.DiskSize = getDiskSize(v)
return return
} }
// RemoveAndCleanMachines removes all machine and cleans up any other files associatied with podman machine
func (p *Provider) RemoveAndCleanMachines() error {
var (
vm machine.VM
listResponse []*machine.ListResponse
opts machine.ListOptions
destroyOptions machine.RemoveOptions
)
destroyOptions.Force = true
var prevErr error
listResponse, err := p.List(opts)
if err != nil {
return err
}
for _, mach := range listResponse {
vm, err = p.LoadVMByName(mach.Name)
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
}
_, remove, err := vm.Remove(mach.Name, destroyOptions)
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
} else {
if err := remove(); err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
}
}
}
// Clean leftover files in data dir
dataDir, err := machine.DataDirPrefix()
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
} else {
err := os.RemoveAll(dataDir)
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
}
}
// Clean leftover files in conf dir
confDir, err := machine.ConfDirPrefix()
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
} else {
err := os.RemoveAll(confDir)
if err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
prevErr = err
}
}
return prevErr
}

View File

@ -89,5 +89,12 @@ var _ = Describe("podman system reset", func() {
Expect(session).Should(Exit(0)) Expect(session).Should(Exit(0))
// default network should exists // default network should exists
Expect(session.OutputToStringArray()).To(HaveLen(1)) Expect(session.OutputToStringArray()).To(HaveLen(1))
// TODO: machine tests currently don't run outside of the machine test pkg
// no machines are created here to cleanup
session = podmanTest.Podman([]string{"machine", "list", "-q"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.OutputToStringArray()).To(BeEmpty())
}) })
}) })