This repository has been archived by the owner on Oct 24, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 522
/
persistentvolumeclaims.go
139 lines (124 loc) · 3.93 KB
/
persistentvolumeclaims.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
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
package persistentvolumeclaims
import (
"context"
"encoding/json"
"fmt"
"log"
"os/exec"
"time"
"github.com/Azure/aks-engine/test/e2e/kubernetes/util"
"github.com/pkg/errors"
)
const commandTimeout = 1 * time.Minute
// PersistentVolumeClaims is used to parse data from kubectl get pvc
type PersistentVolumeClaims struct {
Metadata Metadata `json:"metadata"`
Spec Spec `json:"spec"`
Status Status `json:"status"`
}
// Metadata holds information like name, create time, and namespace
type Metadata struct {
CreatedAt time.Time `json:"creationTimestamp"`
Name string `json:"name"`
NameSpace string `json:"namespace"`
}
// Spec holds information like storageClassName, volumeName
type Spec struct {
StorageClassName string `json:"storageClassName"`
VolumeName string `json:"volumeName"`
}
// Status holds information like phase
type Status struct {
Phase string `json:"phase"`
}
// CreatePersistentVolumeClaimsFromFile will create a StorageClass from file with a name
func CreatePersistentVolumeClaimsFromFile(filename, name, namespace string) (*PersistentVolumeClaims, error) {
cmd := exec.Command("k", "apply", "-f", filename)
util.PrintCommand(cmd)
out, err := cmd.CombinedOutput()
if err != nil {
log.Printf("Error trying to create PersistentVolumeClaims %s in namespace %s:%s\n", name, namespace, string(out))
return nil, err
}
pvc, err := Get(name, namespace)
if err != nil {
log.Printf("Error while trying to fetch PersistentVolumeClaims %s in namespace %s:%s\n", name, namespace, err)
return nil, err
}
return pvc, nil
}
// Get will return a PersistentVolumeClaims with a given name and namespace
func Get(pvcName, namespace string) (*PersistentVolumeClaims, error) {
cmd := exec.Command("k", "get", "pvc", pvcName, "-n", namespace, "-o", "json")
util.PrintCommand(cmd)
out, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}
pvc := PersistentVolumeClaims{}
err = json.Unmarshal(out, &pvc)
if err != nil {
log.Printf("Error unmarshalling PersistentVolumeClaims json:%s\n", err)
return nil, err
}
return &pvc, nil
}
// Describe gets the description for the given pvc and namespace.
func Describe(pvcName, namespace string) error {
cmd := exec.Command("k", "describe", "pvc", pvcName, "-n", namespace)
util.PrintCommand(cmd)
out, err := cmd.CombinedOutput()
if err != nil {
return err
}
fmt.Printf("\n%s\n", string(out))
return nil
}
// Delete will delete a PersistentVolumeClaims in a given namespace
func (pvc *PersistentVolumeClaims) Delete(retries int) error {
var kubectlOutput []byte
var kubectlError error
for i := 0; i < retries; i++ {
cmd := exec.Command("k", "delete", "pvc", "-n", pvc.Metadata.NameSpace, pvc.Metadata.Name)
kubectlOutput, kubectlError = util.RunAndLogCommand(cmd, commandTimeout)
if kubectlError != nil {
log.Printf("Error while trying to delete PVC %s in namespace %s:%s\n", pvc.Metadata.Name, pvc.Metadata.NameSpace, string(kubectlOutput))
continue
}
break
}
return kubectlError
}
// WaitOnReady will block until PersistentVolumeClaims is available
func (pvc *PersistentVolumeClaims) WaitOnReady(namespace string, sleep, duration time.Duration) (bool, error) {
readyCh := make(chan bool, 1)
errCh := make(chan error)
ctx, cancel := context.WithTimeout(context.Background(), duration)
defer cancel()
go func() {
for {
select {
case <-ctx.Done():
errCh <- errors.Errorf("Timeout exceeded (%s) while waiting for PersistentVolumeClaims (%s) to become ready", duration.String(), pvc.Metadata.Name)
default:
query, _ := Get(pvc.Metadata.Name, namespace)
if query != nil && query.Status.Phase == "Bound" {
readyCh <- true
} else {
Describe(pvc.Metadata.Name, namespace)
time.Sleep(sleep)
}
}
}
}()
for {
select {
case err := <-errCh:
return false, err
case ready := <-readyCh:
return ready, nil
}
}
}