summaryrefslogtreecommitdiff
path: root/pkg/machine/qemu/machine.go
diff options
context:
space:
mode:
authorcdoern <cbdoer23@g.holycross.edu>2022-04-12 22:21:33 -0400
committercdoern <cbdoer23@g.holycross.edu>2022-04-25 14:14:45 -0400
commitd441a711e5590cc579ae0e0a73ea463718d4d79e (patch)
tree415249c671acb4223867b879749efa5221786fe9 /pkg/machine/qemu/machine.go
parentba6356280a86531d3cda7016859aef98bb3d8272 (diff)
downloadpodman-d441a711e5590cc579ae0e0a73ea463718d4d79e.tar.gz
podman-d441a711e5590cc579ae0e0a73ea463718d4d79e.tar.bz2
podman-d441a711e5590cc579ae0e0a73ea463718d4d79e.zip
machine starting status
podman machine was using the file modification time to get the running status add three new config entries Starting (bool) Created (time) LastUp (time) to actually keep track of when these events happened. This means we can use the config file to actually store this data and not mess up the created/last-up time. This fixes the issues where the machine would report running 15 seconds before it was up. Also fixes the issue of modifying the file manually and saying the machine is "up" [NO NEW TESTS NEEDED] resolves #13711 Signed-off-by: cdoern <cbdoer23@g.holycross.edu>
Diffstat (limited to 'pkg/machine/qemu/machine.go')
-rw-r--r--pkg/machine/qemu/machine.go75
1 files changed, 55 insertions, 20 deletions
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 66f5291c1..c54d18a4b 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -95,6 +95,8 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) {
vm.Memory = opts.Memory
vm.DiskSize = opts.DiskSize
+ vm.Created = time.Now()
+
// Find the qemu executable
cfg, err := config.Default()
if err != nil {
@@ -439,7 +441,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
return nil
}
- state, err := v.State()
+ state, err := v.State(false)
if err != nil {
return err
}
@@ -480,6 +482,17 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
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() {
logrus.Errorf("machine %q is incompatible with this release of podman and needs to be recreated, starting for recovery only", v.Name)
}
@@ -501,6 +514,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return err
}
}
+
// If the qemusocketpath exists and the vm is off/down, we should rm
// it before the dial as to avoid a segv
if err := v.QMPMonitor.Address.Delete(); err != nil {
@@ -581,14 +595,14 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
}
if len(v.Mounts) > 0 {
- state, err := v.State()
+ state, err := v.State(true)
if err != nil {
return err
}
listening := v.isListening()
for state != machine.Running || !listening {
time.Sleep(100 * time.Millisecond)
- state, err = v.State()
+ state, err = v.State(true)
if err != nil {
return err
}
@@ -630,7 +644,6 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
}
v.waitAPIAndPrintInfo(forwardState, forwardSock)
-
return nil
}
@@ -639,9 +652,10 @@ func (v *MachineVM) checkStatus(monitor *qmp.SocketMonitor) (machine.Status, err
// {"return": {"status": "running", "singlestep": false, "running": true}}
type statusDetails struct {
- Status string `json:"status"`
- Step bool `json:"singlestep"`
- Running bool `json:"running"`
+ Status string `json:"status"`
+ Step bool `json:"singlestep"`
+ Running bool `json:"running"`
+ Starting bool `json:"starting"`
}
type statusResponse struct {
Response statusDetails `json:"return"`
@@ -727,6 +741,11 @@ func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error {
if p == nil && err != nil {
return err
}
+
+ v.LastUp = time.Now()
+ if err := v.writeConfig(); err != nil { // keep track of last up
+ return err
+ }
// Kill the process
if err := p.Kill(); err != nil {
return err
@@ -748,7 +767,7 @@ func (v *MachineVM) Stop(_ string, _ machine.StopOptions) error {
disconnected = true
waitInternal := 250 * time.Millisecond
for i := 0; i < 5; i++ {
- state, err := v.State()
+ state, err := v.State(false)
if err != nil {
return err
}
@@ -800,7 +819,7 @@ func (v *MachineVM) Remove(_ string, opts machine.RemoveOptions) (string, func()
)
// cannot remove a running vm unless --force is used
- state, err := v.State()
+ state, err := v.State(false)
if err != nil {
return "", nil, err
}
@@ -866,12 +885,19 @@ func (v *MachineVM) Remove(_ string, opts machine.RemoveOptions) (string, func()
}, nil
}
-func (v *MachineVM) State() (machine.Status, error) {
+func (v *MachineVM) State(bypass bool) (machine.Status, error) {
// Check if qmp socket path exists
if _, err := os.Stat(v.QMPMonitor.Address.GetPath()); os.IsNotExist(err) {
return "", nil
}
+ err := v.update()
+ if err != nil {
+ return "", err
+ }
// 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)
if err != nil {
// FIXME: this error should probably be returned
@@ -902,7 +928,7 @@ func (v *MachineVM) isListening() bool {
// SSH opens an interactive SSH session to the vm specified.
// Added ssh function to VM interface: pkg/machine/config/go : line 58
func (v *MachineVM) SSH(_ string, opts machine.SSHOptions) error {
- state, err := v.State()
+ state, err := v.State(true)
if err != nil {
return err
}
@@ -1016,20 +1042,29 @@ func getVMInfos() ([]*machine.ListResponse, error) {
listEntry.Port = vm.Port
listEntry.RemoteUsername = vm.RemoteUsername
listEntry.IdentityPath = vm.IdentityPath
- fi, err := os.Stat(fullPath)
- if err != nil {
- return err
+ listEntry.CreatedAt = vm.Created
+
+ if listEntry.CreatedAt.IsZero() {
+ listEntry.CreatedAt = time.Now()
+ vm.Created = time.Now()
+ if err := vm.writeConfig(); err != nil {
+ return err
+ }
}
- listEntry.CreatedAt = fi.ModTime()
- fi, err = os.Stat(vm.getImageFile())
+ state, err := vm.State(false)
if err != nil {
return err
}
- listEntry.LastUp = fi.ModTime()
- state, err := vm.State()
- if err != nil {
- return err
+
+ if !vm.LastUp.IsZero() {
+ listEntry.LastUp = vm.LastUp
+ } else {
+ listEntry.LastUp = vm.Created
+ vm.Created = time.Now()
+ if err := vm.writeConfig(); err != nil {
+ return err
+ }
}
if state == machine.Running {
listEntry.Running = true