-
Notifications
You must be signed in to change notification settings - Fork 653
/
Copy pathsave_restore_arm64.go
76 lines (66 loc) · 2.3 KB
/
save_restore_arm64.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//go:build darwin && arm64 && !no_vz
package vz
import (
"errors"
"fmt"
"os"
"github.com/Code-Hex/vz/v3"
"github.com/sirupsen/logrus"
)
func saveVM(vm *vz.VirtualMachine, machineStatePath string) error {
if !vm.CanPause() {
return fmt.Errorf("can't pause the VZ machine")
}
// Remove the old machine state file if it exists,
// because saving the machine state will fail if the file already exists.
if err := os.Remove(machineStatePath); err != nil && !errors.Is(err, os.ErrNotExist) {
logrus.WithError(err).Errorf("Failed to remove the old VZ machine state file %q", machineStatePath)
return err
}
logrus.Info("Pausing VZ")
if err := vm.Pause(); err != nil {
return err
}
// If we can't stop the machine after pausing, saving the machine state will be useless.
// So we should check this before saving the machine state.
if !vm.CanStop() {
return fmt.Errorf("can't stop the VZ machine after pausing")
}
logrus.Info("Saving VZ machine state for resuming later")
if err := vm.SaveMachineStateToPath(machineStatePath); err != nil {
// If we fail to save the machine state, we should resume the machine to call RequestStop() later
logrus.WithError(err).Errorf("Failed to save the machine state to %q", machineStatePath)
if resumeError := vm.Resume(); resumeError != nil {
return resumeError
}
return err
}
logrus.Info("Stopping VZ")
if err := vm.Stop(); err != nil {
// If we fail to stop the machine, we should resume the machine to call RequestStop() later
logrus.WithError(err).Error("Failed to stop the VZ machine")
if resumeError := vm.Resume(); resumeError != nil {
return resumeError
}
return err
}
return nil
}
func restoreVM(vm *vz.VirtualMachine, machineStatePath string) error {
if _, err := os.Stat(machineStatePath); err != nil {
return err
}
logrus.Info("Saved VZ machine state found, resuming VZ")
if err := vm.RestoreMachineStateFromURL(machineStatePath); err != nil {
return err
}
if err := vm.Resume(); err != nil {
return err
}
// Remove the machine state file after resuming the machine
if err := os.Remove(machineStatePath); err != nil {
// We should log the error but continue the process, because the machine state is already restored
logrus.WithError(err).Errorf("Failed to remove the VZ machine state file %q", machineStatePath)
}
return nil
}