-
Notifications
You must be signed in to change notification settings - Fork 124
/
Copy pathvm-operations.go
139 lines (108 loc) · 5.4 KB
/
vm-operations.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package gcp
import (
"fmt"
"strings"
"time"
"github.com/litmuschaos/litmus-go/pkg/cerrors"
experimentTypes "github.com/litmuschaos/litmus-go/pkg/gcp/gcp-vm-instance-stop/types"
"github.com/litmuschaos/litmus-go/pkg/log"
"github.com/litmuschaos/litmus-go/pkg/utils/retry"
"github.com/palantir/stacktrace"
"github.com/sirupsen/logrus"
"google.golang.org/api/compute/v1"
)
// VMInstanceStop stops a VM Instance
func VMInstanceStop(computeService *compute.Service, instanceName string, gcpProjectID string, instanceZone string) error {
// stop the requisite VM instance
_, err := computeService.Instances.Stop(gcpProjectID, instanceZone, instanceName).Do()
if err != nil {
return cerrors.Error{ErrorCode: cerrors.ErrorTypeChaosInject, Target: fmt.Sprintf("{vmName: %s, zone: %s}", instanceName, instanceZone), Reason: err.Error()}
}
log.InfoWithValues("Stopping VM instance:", logrus.Fields{
"InstanceName": instanceName,
"InstanceZone": instanceZone,
})
return nil
}
// VMInstanceStart starts a VM instance
func VMInstanceStart(computeService *compute.Service, instanceName string, gcpProjectID string, instanceZone string) error {
// start the requisite VM instance
_, err := computeService.Instances.Start(gcpProjectID, instanceZone, instanceName).Do()
if err != nil {
return cerrors.Error{ErrorCode: cerrors.ErrorTypeChaosRevert, Target: fmt.Sprintf("{vmName: %s, zone: %s}", instanceName, instanceZone), Reason: err.Error()}
}
log.InfoWithValues("Starting VM instance:", logrus.Fields{
"InstanceName": instanceName,
"InstanceZone": instanceZone,
})
return nil
}
// WaitForVMInstanceDown will wait for the VM instance to attain the TERMINATED status
func WaitForVMInstanceDown(computeService *compute.Service, timeout int, delay int, instanceName string, gcpProjectID string, instanceZone string) error {
log.Infof("[Status]: Checking %s VM instance status", instanceName)
return retry.
Times(uint(timeout / delay)).
Wait(time.Duration(delay) * time.Second).
Try(func(attempt uint) error {
instanceState, err := GetVMInstanceStatus(computeService, instanceName, gcpProjectID, instanceZone)
if err != nil {
return stacktrace.Propagate(err, "failed to get the vm instance status")
}
log.Infof("The %s vm instance state is %v", instanceName, instanceState)
if instanceState != "TERMINATED" {
return cerrors.Error{ErrorCode: cerrors.ErrorTypeStatusChecks, Target: fmt.Sprintf("{vmName: %s, zone: %s}", instanceName, instanceZone), Reason: "vm instance is not yet in stopped state"}
}
return nil
})
}
// WaitForVMInstanceUp will wait for the VM instance to attain the RUNNING status
func WaitForVMInstanceUp(computeService *compute.Service, timeout int, delay int, instanceName string, gcpProjectID string, instanceZone string) error {
log.Infof("[Status]: Checking %s VM instance status", instanceName)
return retry.
Times(uint(timeout / delay)).
Wait(time.Duration(delay) * time.Second).
Try(func(attempt uint) error {
instanceState, err := GetVMInstanceStatus(computeService, instanceName, gcpProjectID, instanceZone)
if err != nil {
return stacktrace.Propagate(err, "failed to get the vm instance status")
}
log.Infof("The %s vm instance state is %v", instanceName, instanceState)
if instanceState != "RUNNING" {
return cerrors.Error{ErrorCode: cerrors.ErrorTypeStatusChecks, Target: fmt.Sprintf("{vmName: %s, zone: %s}", instanceName, instanceZone), Reason: "vm instance is not yet in running state"}
}
return nil
})
}
// SetTargetInstance will select the target vm instances which are in RUNNING state and filtered from the given label
func SetTargetInstance(computeService *compute.Service, experimentsDetails *experimentTypes.ExperimentDetails) error {
var (
response *compute.InstanceList
err error
)
if experimentsDetails.InstanceLabel == "" {
return cerrors.Error{ErrorCode: cerrors.ErrorTypeTargetSelection, Target: fmt.Sprintf("{label: %s}", experimentsDetails.InstanceLabel), Reason: "label not found, please provide a valid label"}
}
if strings.Contains(experimentsDetails.InstanceLabel, ":") {
// the label is of format key:value
response, err = computeService.Instances.List(experimentsDetails.GCPProjectID, experimentsDetails.Zones).Filter("labels." + experimentsDetails.InstanceLabel).Do()
} else {
// the label only has key
response, err = computeService.Instances.List(experimentsDetails.GCPProjectID, experimentsDetails.Zones).Filter("labels." + experimentsDetails.InstanceLabel + ":*").Do()
}
if err != nil {
return err
return cerrors.Error{ErrorCode: cerrors.ErrorTypeTargetSelection, Target: fmt.Sprintf("{label: %s, zone: %s}", experimentsDetails.InstanceLabel, experimentsDetails.Zones), Reason: err.Error()}
}
for _, instance := range response.Items {
if instance.Status == "RUNNING" {
experimentsDetails.TargetVMInstanceNameList = append(experimentsDetails.TargetVMInstanceNameList, instance.Name)
}
}
if len(experimentsDetails.TargetVMInstanceNameList) == 0 {
return cerrors.Error{ErrorCode: cerrors.ErrorTypeTargetSelection, Target: fmt.Sprintf("{label: %s, zone: %s}", experimentsDetails.InstanceLabel, experimentsDetails.Zones), Reason: "no running vm instances found with the given label"}
}
log.InfoWithValues("[Info]: Targeting the RUNNING VM instances filtered from instance label", logrus.Fields{
"Number of running instances filtered": len(experimentsDetails.TargetVMInstanceNameList),
})
return nil
}