-
Notifications
You must be signed in to change notification settings - Fork 483
Expand file tree
/
Copy pathutil.go
More file actions
250 lines (210 loc) · 7.99 KB
/
util.go
File metadata and controls
250 lines (210 loc) · 7.99 KB
Edit and raw actions
OlderNewer
1
/*
2
Copyright 2017 The Kubernetes Authors.
3
4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7
8
http://www.apache.org/licenses/LICENSE-2.0
9
10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16
17
package framework
18
19
import (
20
"fmt"
21
"strings"
22
"sync"
23
"time"
24
25
"github.com/pborman/uuid"
26
internalapi "k8s.io/kubernetes/pkg/kubelet/apis/cri"
27
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
28
"k8s.io/kubernetes/pkg/kubelet/remote"
29
30
. "github.com/onsi/ginkgo"
31
. "github.com/onsi/gomega"
32
)
33
34
var (
35
//lock for uuid
36
uuidLock sync.Mutex
37
38
// lastUUID record last generated uuid from NewUUID()
39
lastUUID uuid.UUID
40
)
41
42
const (
43
// DefaultUIDPrefix is a default UID prefix of PodSandbox
44
DefaultUIDPrefix string = "cri-test-uid"
45
46
// DefaultNamespacePrefix is a default namespace prefix of PodSandbox
47
DefaultNamespacePrefix string = "cri-test-namespace"
48
49
// DefaultAttempt is a default attempt prefix of PodSandbox or container
50
DefaultAttempt uint32 = 2
51
52
// DefaultContainerImage is the default image for container using
53
DefaultContainerImage string = "busybox:1.28"
54
55
// DefaultStopContainerTimeout is the default timeout for stopping container
56
DefaultStopContainerTimeout int64 = 60
57
)
58
59
// LoadCRIClient creates a InternalAPIClient.
60
func LoadCRIClient() (*InternalAPIClient, error) {
61
rService, err := remote.NewRemoteRuntimeService(TestContext.RuntimeServiceAddr, TestContext.RuntimeServiceTimeout)
62
if err != nil {
63
return nil, err
64
}
65
66
var imageServiceAddr = TestContext.ImageServiceAddr
67
if imageServiceAddr == "" {
68
// Fallback to runtime service endpoint
69
imageServiceAddr = TestContext.RuntimeServiceAddr
70
}
71
iService, err := remote.NewRemoteImageService(imageServiceAddr, TestContext.ImageServiceTimeout)
72
if err != nil {
73
return nil, err
74
}
75
76
return &InternalAPIClient{
77
CRIRuntimeClient: rService,
78
CRIImageClient: iService,
79
}, nil
80
}
81
82
func nowStamp() string {
83
return time.Now().Format(time.StampMilli)
84
}
85
86
func log(level string, format string, args ...interface{}) {
87
fmt.Fprintf(GinkgoWriter, nowStamp()+": "+level+": "+format+"\n", args...)
88
}
89
90
// Logf prints a info message.
91
func Logf(format string, args ...interface{}) {
92
log("INFO", format, args...)
93
}
94
95
// Failf prints an error message.
96
func Failf(format string, args ...interface{}) {
97
msg := fmt.Sprintf(format, args...)
98
log("INFO", msg)
99
Fail(nowStamp()+": "+msg, 1)
100
}
101
102
// ExpectNoError reports error if err is not nil.
103
func ExpectNoError(err error, explain ...interface{}) {
104
if err != nil {
105
Logf("Unexpected error occurred: %v", err)
106
}
107
ExpectWithOffset(1, err).NotTo(HaveOccurred(), explain...)
108
}
109
110
// NewUUID creates a new UUID string.
111
func NewUUID() string {
112
uuidLock.Lock()
113
defer uuidLock.Unlock()
114
result := uuid.NewUUID()
115
// The UUID package is naive and can generate identical UUIDs if the
116
// time interval is quick enough.
117
// The UUID uses 100 ns increments so it's short enough to actively
118
// wait for a new value.
119
for uuid.Equal(lastUUID, result) == true {
120
result = uuid.NewUUID()
121
}
122
lastUUID = result
123
return result.String()
124
}
125
126
// RunDefaultPodSandbox runs a PodSandbox with default options.
127
func RunDefaultPodSandbox(c internalapi.RuntimeService, prefix string) string {
128
podSandboxName := prefix + NewUUID()
129
uid := DefaultUIDPrefix + NewUUID()
130
namespace := DefaultNamespacePrefix + NewUUID()
131
132
config := &runtimeapi.PodSandboxConfig{
133
Metadata: BuildPodSandboxMetadata(podSandboxName, uid, namespace, DefaultAttempt),
134
Linux: &runtimeapi.LinuxPodSandboxConfig{},
135
}
136
return RunPodSandbox(c, config)
137
}
138
139
// BuildPodSandboxMetadata builds PodSandboxMetadata.
140
func BuildPodSandboxMetadata(podSandboxName, uid, namespace string, attempt uint32) *runtimeapi.PodSandboxMetadata {
141
return &runtimeapi.PodSandboxMetadata{
142
Name: podSandboxName,
143
Uid: uid,
144
Namespace: namespace,
145
Attempt: attempt,
146
}
147
}
148
149
// RunPodSandbox runs a PodSandbox.
150
func RunPodSandbox(c internalapi.RuntimeService, config *runtimeapi.PodSandboxConfig) string {
151
podID, err := c.RunPodSandbox(config)
152
ExpectNoError(err, "failed to create PodSandbox: %v", err)
153
return podID
154
}
155
156
// CreatePodSandboxForContainer creates a PodSandbox for creating containers.
157
func CreatePodSandboxForContainer(c internalapi.RuntimeService) (string, *runtimeapi.PodSandboxConfig) {
158
podSandboxName := "create-PodSandbox-for-container-" + NewUUID()
159
uid := DefaultUIDPrefix + NewUUID()
160
namespace := DefaultNamespacePrefix + NewUUID()
161
config := &runtimeapi.PodSandboxConfig{
162
Metadata: BuildPodSandboxMetadata(podSandboxName, uid, namespace, DefaultAttempt),
163
Linux: &runtimeapi.LinuxPodSandboxConfig{},
164
}
165
166
podID := RunPodSandbox(c, config)
167
return podID, config
168
}
169
170
// BuildContainerMetadata builds containerMetadata.
171
func BuildContainerMetadata(containerName string, attempt uint32) *runtimeapi.ContainerMetadata {
172
return &runtimeapi.ContainerMetadata{
173
Name: containerName,
174
Attempt: attempt,
175
}
176
}
177
178
// CreateDefaultContainer creates a default container with default options.
179
func CreateDefaultContainer(rc internalapi.RuntimeService, ic internalapi.ImageManagerService, podID string, podConfig *runtimeapi.PodSandboxConfig, prefix string) string {
180
containerName := prefix + NewUUID()
181
containerConfig := &runtimeapi.ContainerConfig{
182
Metadata: BuildContainerMetadata(containerName, DefaultAttempt),
183
Image: &runtimeapi.ImageSpec{Image: DefaultContainerImage},
184
Command: []string{"top"},
185
Linux: &runtimeapi.LinuxContainerConfig{},
186
}
187
188
return CreateContainer(rc, ic, containerConfig, podID, podConfig)
189
}
190
191
// CreateContainerWithError creates a container but leave error check to caller
192
func CreateContainerWithError(rc internalapi.RuntimeService, ic internalapi.ImageManagerService, config *runtimeapi.ContainerConfig, podID string, podConfig *runtimeapi.PodSandboxConfig) (string, error) {
193
// Pull the image if it does not exist.
194
imageName := config.Image.Image
195
if !strings.Contains(imageName, ":") {
196
imageName = imageName + ":latest"
197
Logf("Use latest as default image tag.")
198
}
199
200
status := ImageStatus(ic, imageName)
201
if status == nil {
202
PullPublicImage(ic, imageName)
203
}
204
205
By("Create container.")
206
containerID, err := rc.CreateContainer(podID, config, podConfig)
207
return containerID, err
208
}
209
210
// CreateContainer creates a container with the prefix of containerName.
211
func CreateContainer(rc internalapi.RuntimeService, ic internalapi.ImageManagerService, config *runtimeapi.ContainerConfig, podID string, podConfig *runtimeapi.PodSandboxConfig) string {
212
containerID, err := CreateContainerWithError(rc, ic, config, podID, podConfig)
213
ExpectNoError(err, "failed to create container: %v", err)
214
Logf("Created container %q\n", containerID)
215
return containerID
216
}
217
218
// ImageStatus gets the status of the image named imageName.
219
func ImageStatus(c internalapi.ImageManagerService, imageName string) *runtimeapi.Image {
220
By("Get image status for image: " + imageName)
221
imageSpec := &runtimeapi.ImageSpec{
222
Image: imageName,
223
}
224
status, err := c.ImageStatus(imageSpec)
225
ExpectNoError(err, "failed to get image status: %v", err)
226
return status
227
}
228
229
// ListImage list the image filtered by the image filter.
230
func ListImage(c internalapi.ImageManagerService, filter *runtimeapi.ImageFilter) []*runtimeapi.Image {
231
images, err := c.ListImages(filter)
232
ExpectNoError(err, "Failed to get image list: %v", err)
233
return images
234
}
235
236
// PullPublicImage pulls the public image named imageName.
237
func PullPublicImage(c internalapi.ImageManagerService, imageName string) string {
238
if !strings.Contains(imageName, ":") {
239
imageName = imageName + ":latest"
240
Logf("Use latest as default image tag.")
241
}
242
243
By("Pull image : " + imageName)
244
imageSpec := &runtimeapi.ImageSpec{
245
Image: imageName,
246
}
247
id, err := c.PullImage(imageSpec, nil)
248
ExpectNoError(err, "failed to pull image: %v", err)
249
return id
250
}