mirror of
https://github.com/containers/podman.git
synced 2025-06-19 16:33:24 +08:00
BIN
capture.pcap
Normal file
BIN
capture.pcap
Normal file
Binary file not shown.
@ -59,7 +59,7 @@ func inspect(cmd *cobra.Command, args []string) error {
|
|||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
state, err := vm.State()
|
state, err := vm.State(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
continue
|
continue
|
||||||
|
@ -121,7 +121,7 @@ type VM interface {
|
|||||||
Set(name string, opts SetOptions) error
|
Set(name string, opts SetOptions) error
|
||||||
SSH(name string, opts SSHOptions) error
|
SSH(name string, opts SSHOptions) error
|
||||||
Start(name string, opts StartOptions) error
|
Start(name string, opts StartOptions) error
|
||||||
State() (Status, error)
|
State(bypass bool) (Status, error)
|
||||||
Stop(name string, opts StopOptions) error
|
Stop(name string, opts StopOptions) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,12 @@ type MachineVM struct {
|
|||||||
ResourceConfig
|
ResourceConfig
|
||||||
// SSHConfig for accessing the remote vm
|
// SSHConfig for accessing the remote vm
|
||||||
SSHConfig
|
SSHConfig
|
||||||
|
// Starting tells us whether the machine is running or if we have just dialed it to start it
|
||||||
|
Starting bool
|
||||||
|
// Created contains the original created time instead of querying the file mod time
|
||||||
|
Created time.Time
|
||||||
|
// LastUp contains the last recorded uptime
|
||||||
|
LastUp time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageConfig describes the bootable image for the VM
|
// ImageConfig describes the bootable image for the VM
|
||||||
|
@ -94,6 +94,8 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) {
|
|||||||
vm.Memory = opts.Memory
|
vm.Memory = opts.Memory
|
||||||
vm.DiskSize = opts.DiskSize
|
vm.DiskSize = opts.DiskSize
|
||||||
|
|
||||||
|
vm.Created = time.Now()
|
||||||
|
|
||||||
// Find the qemu executable
|
// Find the qemu executable
|
||||||
cfg, err := config.Default()
|
cfg, err := config.Default()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -436,7 +438,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
state, err := v.State()
|
state, err := v.State(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -477,6 +479,17 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
|
|||||||
wait = time.Millisecond * 500
|
wait = time.Millisecond * 500
|
||||||
)
|
)
|
||||||
|
|
||||||
|
v.Starting = true
|
||||||
|
if err := v.writeConfig(); err != nil {
|
||||||
|
return fmt.Errorf("writing JSON file: %w", err)
|
||||||
|
}
|
||||||
|
defer func() error {
|
||||||
|
v.Starting = false
|
||||||
|
if err := v.writeConfig(); err != nil {
|
||||||
|
return fmt.Errorf("writing JSON file: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}()
|
||||||
if v.isIncompatible() {
|
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)
|
logrus.Errorf("machine %q is incompatible with this release of podman and needs to be recreated, starting for recovery only", v.Name)
|
||||||
}
|
}
|
||||||
@ -498,6 +511,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the qemusocketpath exists and the vm is off/down, we should rm
|
// If the qemusocketpath exists and the vm is off/down, we should rm
|
||||||
// it before the dial as to avoid a segv
|
// it before the dial as to avoid a segv
|
||||||
if err := v.QMPMonitor.Address.Delete(); err != nil {
|
if err := v.QMPMonitor.Address.Delete(); err != nil {
|
||||||
@ -589,14 +603,14 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(v.Mounts) > 0 {
|
if len(v.Mounts) > 0 {
|
||||||
state, err := v.State()
|
state, err := v.State(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
listening := v.isListening()
|
listening := v.isListening()
|
||||||
for state != machine.Running || !listening {
|
for state != machine.Running || !listening {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
state, err = v.State()
|
state, err = v.State(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -638,7 +652,6 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
v.waitAPIAndPrintInfo(forwardState, forwardSock)
|
v.waitAPIAndPrintInfo(forwardState, forwardSock)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,9 +660,10 @@ func (v *MachineVM) checkStatus(monitor *qmp.SocketMonitor) (machine.Status, err
|
|||||||
// {"return": {"status": "running", "singlestep": false, "running": true}}
|
// {"return": {"status": "running", "singlestep": false, "running": true}}
|
||||||
|
|
||||||
type statusDetails struct {
|
type statusDetails struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Step bool `json:"singlestep"`
|
Step bool `json:"singlestep"`
|
||||||
Running bool `json:"running"`
|
Running bool `json:"running"`
|
||||||
|
Starting bool `json:"starting"`
|
||||||
}
|
}
|
||||||
type statusResponse struct {
|
type statusResponse struct {
|
||||||
Response statusDetails `json:"return"`
|
Response statusDetails `json:"return"`
|
||||||
@ -735,6 +749,11 @@ func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error {
|
|||||||
if p == nil && err != nil {
|
if p == nil && err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v.LastUp = time.Now()
|
||||||
|
if err := v.writeConfig(); err != nil { // keep track of last up
|
||||||
|
return err
|
||||||
|
}
|
||||||
// Kill the process
|
// Kill the process
|
||||||
if err := p.Kill(); err != nil {
|
if err := p.Kill(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -756,7 +775,7 @@ func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error {
|
|||||||
disconnected = true
|
disconnected = true
|
||||||
waitInternal := 250 * time.Millisecond
|
waitInternal := 250 * time.Millisecond
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
state, err := v.State()
|
state, err := v.State(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -808,7 +827,7 @@ func (v *MachineVM) Remove(_ string, opts machine.RemoveOptions) (string, func()
|
|||||||
)
|
)
|
||||||
|
|
||||||
// cannot remove a running vm unless --force is used
|
// cannot remove a running vm unless --force is used
|
||||||
state, err := v.State()
|
state, err := v.State(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
@ -874,12 +893,19 @@ func (v *MachineVM) Remove(_ string, opts machine.RemoveOptions) (string, func()
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MachineVM) State() (machine.Status, error) {
|
func (v *MachineVM) State(bypass bool) (machine.Status, error) {
|
||||||
// Check if qmp socket path exists
|
// Check if qmp socket path exists
|
||||||
if _, err := os.Stat(v.QMPMonitor.Address.GetPath()); os.IsNotExist(err) {
|
if _, err := os.Stat(v.QMPMonitor.Address.GetPath()); os.IsNotExist(err) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
err := v.update()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
// Check if we can dial it
|
// Check if we can dial it
|
||||||
|
if v.Starting && !bypass {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
monitor, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address.GetPath(), v.QMPMonitor.Timeout)
|
monitor, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address.GetPath(), v.QMPMonitor.Timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME: this error should probably be returned
|
// FIXME: this error should probably be returned
|
||||||
@ -910,7 +936,7 @@ func (v *MachineVM) isListening() bool {
|
|||||||
// SSH opens an interactive SSH session to the vm specified.
|
// SSH opens an interactive SSH session to the vm specified.
|
||||||
// Added ssh function to VM interface: pkg/machine/config/go : line 58
|
// Added ssh function to VM interface: pkg/machine/config/go : line 58
|
||||||
func (v *MachineVM) SSH(_ string, opts machine.SSHOptions) error {
|
func (v *MachineVM) SSH(_ string, opts machine.SSHOptions) error {
|
||||||
state, err := v.State()
|
state, err := v.State(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1024,20 +1050,29 @@ func getVMInfos() ([]*machine.ListResponse, error) {
|
|||||||
listEntry.Port = vm.Port
|
listEntry.Port = vm.Port
|
||||||
listEntry.RemoteUsername = vm.RemoteUsername
|
listEntry.RemoteUsername = vm.RemoteUsername
|
||||||
listEntry.IdentityPath = vm.IdentityPath
|
listEntry.IdentityPath = vm.IdentityPath
|
||||||
fi, err := os.Stat(fullPath)
|
listEntry.CreatedAt = vm.Created
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
listEntry.CreatedAt = fi.ModTime()
|
|
||||||
|
|
||||||
fi, err = os.Stat(vm.getImageFile())
|
if listEntry.CreatedAt.IsZero() {
|
||||||
|
listEntry.CreatedAt = time.Now()
|
||||||
|
vm.Created = time.Now()
|
||||||
|
if err := vm.writeConfig(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state, err := vm.State(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
listEntry.LastUp = fi.ModTime()
|
|
||||||
state, err := vm.State()
|
if !vm.LastUp.IsZero() {
|
||||||
if err != nil {
|
listEntry.LastUp = vm.LastUp
|
||||||
return err
|
} else {
|
||||||
|
listEntry.LastUp = vm.Created
|
||||||
|
vm.Created = time.Now()
|
||||||
|
if err := vm.writeConfig(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if state == machine.Running {
|
if state == machine.Running {
|
||||||
listEntry.Running = true
|
listEntry.Running = true
|
||||||
|
@ -1028,7 +1028,7 @@ func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
|
|||||||
|
|
||||||
// TODO: We need to rename isRunning to State(); I do not have a
|
// TODO: We need to rename isRunning to State(); I do not have a
|
||||||
// windows system to test this on.
|
// windows system to test this on.
|
||||||
func (v *MachineVM) State() (machine.Status, error) {
|
func (v *MachineVM) State(bypass bool) (machine.Status, error) {
|
||||||
return "", define.ErrNotImplemented
|
return "", define.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user