-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup-teardown.go
140 lines (121 loc) · 4.44 KB
/
setup-teardown.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
140
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package remote
import (
"fmt"
"os"
"github.com/golang/glog"
compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/util/uuid"
)
// TestContext holds the CSI Client handle to a remotely connected Driver
// as well as a handle to the Instance that the driver is running on
type TestContext struct {
Instance *InstanceInfo
Client *CsiClient
proc *processes
}
// ClientConfig contains all the parameters required to package a new
// driver and run it remotely on a GCE Instance
type ClientConfig struct {
// Absolute path of the package
PkgPath string
// Absolute path of the driver binary to copy remotely
BinPath string
// Path on remote instance workspace
WorkspaceDir string
// Command to run on remote instance to start the driver
RunDriverCmd string
// Port to use as SSH tunnel on both remote and local side.
Port string
}
type processes struct {
sshTunnel int
remoteDriver int
}
// SetupInstance sets up the specified GCE Instance for E2E testing and returns a handle to the instance object for future use.
func SetupInstance(instanceProject, instanceZone, instanceName, instanceServiceAccount string, cs *compute.Service) (*InstanceInfo, error) {
// Create the instance in the requisite zone
instance, err := CreateInstanceInfo(instanceProject, instanceZone, instanceName, cs)
if err != nil {
return nil, err
}
err = instance.CreateOrGetInstance(instanceServiceAccount)
if err != nil {
return nil, err
}
return instance, nil
}
// SetupNewDriverAndClient gets the driver binary, runs it on the provided instance and connects
// a CSI client to it through SHH tunnelling. It returns a TestContext with both a handle to the instance
// that the driver is on and the CSI Client object to make CSI calls to the remote driver.
func SetupNewDriverAndClient(instance *InstanceInfo, config *ClientConfig) (*TestContext, error) {
archiveName := fmt.Sprintf("e2e_driver_binaries_%s.tar.gz", uuid.NewUUID())
archivePath, err := CreateDriverArchive(archiveName, config.PkgPath, config.BinPath)
if err != nil {
return nil, err
}
defer func() {
err = os.Remove(archivePath)
if err != nil {
glog.Warningf("Failed to remove archive file %s: %v", archivePath, err)
}
}()
// Upload archive to instance and run binaries
driverPID, err := instance.UploadAndRun(archivePath, config.WorkspaceDir, config.RunDriverCmd)
if err != nil {
return nil, err
}
// Create an SSH tunnel from port to port
sshPID, err := instance.CreateSSHTunnel(config.Port, config.Port)
if err != nil {
return nil, fmt.Errorf("SSH Tunnel pid %v encountered error: %v", sshPID, err)
}
client := CreateCSIClient(fmt.Sprintf("localhost:%s", config.Port))
err = client.AssertCSIConnection()
if err != nil {
return nil, fmt.Errorf("asserting csi connection failed with: %v", err)
}
return &TestContext{
Instance: instance,
Client: client,
proc: &processes{
sshTunnel: sshPID,
remoteDriver: driverPID,
},
}, nil
}
// TeardownDriverAndClient closes the CSI Client connection, closes the SSH tunnel
// Kills the driver process on the GCE instance, and cleans up the remote driver workspace
func TeardownDriverAndClient(context *TestContext) error {
// Close the client connection
err := context.Client.CloseConn()
if err != nil {
return fmt.Errorf("failed to close CSI Client connection: %v", err)
}
// Close the SSH tunnel
proc, err := os.FindProcess(context.proc.sshTunnel)
if err != nil {
return fmt.Errorf("unable to efind process for ssh tunnel %v: %v", context.proc.sshTunnel, err)
}
if err = proc.Kill(); err != nil {
return fmt.Errorf("failed to kill ssh tunnel process %v: %v", context.proc.sshTunnel, err)
}
// Kill the driver process on remote
cmd := fmt.Sprintf("kill %v", context.proc.remoteDriver)
output, err := context.Instance.SSH(cmd)
if err != nil {
return fmt.Errorf("failed to kill driver on remote instance, got output %s: %v", output, err)
}
return nil
}