mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
Merge pull request #13523 from n1hility/tolerate-old-machine
Tolerate old machine images, but warn they should be recreated
This commit is contained in:
@ -57,10 +57,6 @@ func start(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
return errors.Wrapf(machine.ErrMultipleActiveVM, "cannot start VM %s. VM %s is currently running", vmName, activeName)
|
return errors.Wrapf(machine.ErrMultipleActiveVM, "cannot start VM %s. VM %s is currently running", vmName, activeName)
|
||||||
}
|
}
|
||||||
vm, err = provider.LoadVMByName(vmName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("Starting machine %q\n", vmName)
|
fmt.Printf("Starting machine %q\n", vmName)
|
||||||
if err := vm.Start(vmName, machine.StartOptions{}); err != nil {
|
if err := vm.Start(vmName, machine.StartOptions{}); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -134,7 +134,7 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) {
|
|||||||
// LoadByName reads a json file that describes a known qemu vm
|
// LoadByName reads a json file that describes a known qemu vm
|
||||||
// and returns a vm instance
|
// and returns a vm instance
|
||||||
func (p *Provider) LoadVMByName(name string) (machine.VM, error) {
|
func (p *Provider) LoadVMByName(name string) (machine.VM, error) {
|
||||||
vm := new(MachineVM)
|
vm := &MachineVM{UID: -1} // posix reserves -1, so use it to signify undefined
|
||||||
vmConfigDir, err := machine.GetConfDir(vmtype)
|
vmConfigDir, err := machine.GetConfDir(vmtype)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -373,6 +373,10 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
|
|||||||
wait time.Duration = time.Millisecond * 500
|
wait time.Duration = time.Millisecond * 500
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if v.isIncompatible() {
|
||||||
|
logrus.Errorf("machine %q is incompatible with this release of podman and needs to be recreated, starting for recovery only", v.Name)
|
||||||
|
}
|
||||||
|
|
||||||
forwardSock, forwardState, err := v.startHostNetworking()
|
forwardSock, forwardState, err := v.startHostNetworking()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("unable to start host networking: %q", err)
|
return errors.Errorf("unable to start host networking: %q", err)
|
||||||
@ -506,7 +510,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waitAPIAndPrintInfo(forwardState, forwardSock, v.Rootful, v.Name)
|
v.waitAPIAndPrintInfo(forwardState, forwardSock)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -975,7 +979,11 @@ func (v *MachineVM) startHostNetworking() (string, apiForwardingState, error) {
|
|||||||
// Add the ssh port
|
// Add the ssh port
|
||||||
cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", v.Port)}...)
|
cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", v.Port)}...)
|
||||||
|
|
||||||
cmd, forwardSock, state := v.setupAPIForwarding(cmd)
|
var forwardSock string
|
||||||
|
var state apiForwardingState
|
||||||
|
if !v.isIncompatible() {
|
||||||
|
cmd, forwardSock, state = v.setupAPIForwarding(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
if logrus.GetLevel() == logrus.DebugLevel {
|
if logrus.GetLevel() == logrus.DebugLevel {
|
||||||
cmd = append(cmd, "--debug")
|
cmd = append(cmd, "--debug")
|
||||||
@ -1043,6 +1051,10 @@ func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwa
|
|||||||
return cmd, dockerSock, dockerGlobal
|
return cmd, dockerSock, dockerGlobal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *MachineVM) isIncompatible() bool {
|
||||||
|
return v.UID == -1
|
||||||
|
}
|
||||||
|
|
||||||
func (v *MachineVM) getForwardSocketPath() (string, error) {
|
func (v *MachineVM) getForwardSocketPath() (string, error) {
|
||||||
path, err := machine.GetDataDir(v.Name)
|
path, err := machine.GetDataDir(v.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1102,46 +1114,66 @@ func waitAndPingAPI(sock string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitAPIAndPrintInfo(forwardState apiForwardingState, forwardSock string, rootFul bool, name string) {
|
func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forwardSock string) {
|
||||||
if forwardState != noForwarding {
|
suffix := ""
|
||||||
suffix := ""
|
if v.Name != machine.DefaultMachineName {
|
||||||
if name != machine.DefaultMachineName {
|
suffix = " " + v.Name
|
||||||
suffix = " " + name
|
}
|
||||||
}
|
|
||||||
waitAndPingAPI(forwardSock)
|
|
||||||
if !rootFul {
|
|
||||||
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
|
|
||||||
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
|
|
||||||
fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
|
|
||||||
fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("API forwarding listening on: %s\n", forwardSock)
|
if v.isIncompatible() {
|
||||||
if forwardState == dockerGlobal {
|
fmt.Fprintf(os.Stderr, "\n!!! ACTION REQUIRED: INCOMPATIBLE MACHINE !!!\n")
|
||||||
fmt.Printf("Docker API clients default to this address. You do not need to set DOCKER_HOST.\n\n")
|
|
||||||
} else {
|
fmt.Fprintf(os.Stderr, "\nThis machine was created by an older podman release that is incompatible\n")
|
||||||
stillString := "still "
|
fmt.Fprintf(os.Stderr, "with this release of podman. It has been started in a limited operational\n")
|
||||||
switch forwardState {
|
fmt.Fprintf(os.Stderr, "mode to allow you to copy any necessary files before recreating it. This\n")
|
||||||
case notInstalled:
|
fmt.Fprintf(os.Stderr, "can be accomplished with the following commands:\n\n")
|
||||||
fmt.Printf("\nThe system helper service is not installed; the default Docker API socket\n")
|
fmt.Fprintf(os.Stderr, "\t# Login and copy desired files (Optional)\n")
|
||||||
fmt.Printf("address can't be used by podman. ")
|
fmt.Fprintf(os.Stderr, "\t# podman machine ssh%s tar cvPf - /path/to/files > backup.tar\n\n", suffix)
|
||||||
if helper := findClaimHelper(); len(helper) > 0 {
|
fmt.Fprintf(os.Stderr, "\t# Recreate machine (DESTRUCTIVE!) \n")
|
||||||
fmt.Printf("If you would like to install it run the\nfollowing commands:\n")
|
fmt.Fprintf(os.Stderr, "\tpodman machine stop%s\n", suffix)
|
||||||
fmt.Printf("\n\tsudo %s install\n", helper)
|
fmt.Fprintf(os.Stderr, "\tpodman machine rm -f%s\n", suffix)
|
||||||
fmt.Printf("\tpodman machine stop%s; podman machine start%s\n\n", suffix, suffix)
|
fmt.Fprintf(os.Stderr, "\tpodman machine init --now%s\n\n", suffix)
|
||||||
}
|
fmt.Fprintf(os.Stderr, "\t# Copy back files (Optional)\n")
|
||||||
case machineLocal:
|
fmt.Fprintf(os.Stderr, "\t# cat backup.tar | podman machine ssh%s tar xvPf - \n\n", suffix)
|
||||||
fmt.Printf("\nAnother process was listening on the default Docker API socket address.\n")
|
}
|
||||||
case claimUnsupported:
|
|
||||||
fallthrough
|
if forwardState == noForwarding {
|
||||||
default:
|
return
|
||||||
stillString = ""
|
}
|
||||||
|
|
||||||
|
waitAndPingAPI(forwardSock)
|
||||||
|
if !v.Rootful {
|
||||||
|
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
|
||||||
|
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
|
||||||
|
fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
|
||||||
|
fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("API forwarding listening on: %s\n", forwardSock)
|
||||||
|
if forwardState == dockerGlobal {
|
||||||
|
fmt.Printf("Docker API clients default to this address. You do not need to set DOCKER_HOST.\n\n")
|
||||||
|
} else {
|
||||||
|
stillString := "still "
|
||||||
|
switch forwardState {
|
||||||
|
case notInstalled:
|
||||||
|
fmt.Printf("\nThe system helper service is not installed; the default Docker API socket\n")
|
||||||
|
fmt.Printf("address can't be used by podman. ")
|
||||||
|
if helper := findClaimHelper(); len(helper) > 0 {
|
||||||
|
fmt.Printf("If you would like to install it run the\nfollowing commands:\n")
|
||||||
|
fmt.Printf("\n\tsudo %s install\n", helper)
|
||||||
|
fmt.Printf("\tpodman machine stop%s; podman machine start%s\n\n", suffix, suffix)
|
||||||
}
|
}
|
||||||
|
case machineLocal:
|
||||||
fmt.Printf("You can %sconnect Docker API clients by setting DOCKER_HOST using the\n", stillString)
|
fmt.Printf("\nAnother process was listening on the default Docker API socket address.\n")
|
||||||
fmt.Printf("following command in your terminal session:\n")
|
case claimUnsupported:
|
||||||
fmt.Printf("\n\texport DOCKER_HOST='unix://%s'\n\n", forwardSock)
|
fallthrough
|
||||||
|
default:
|
||||||
|
stillString = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("You can %sconnect Docker API clients by setting DOCKER_HOST using the\n", stillString)
|
||||||
|
fmt.Printf("following command in your terminal session:\n")
|
||||||
|
fmt.Printf("\n\texport DOCKER_HOST='unix://%s'\n\n", forwardSock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user