This repository has been archived by the owner on Nov 20, 2021. It is now read-only.
/
cluster.go
147 lines (137 loc) · 3.75 KB
/
cluster.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
141
142
143
144
145
146
147
package cluster
import (
"fmt"
"os"
"os/exec"
"github.com/pkg/errors"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"sigs.k8s.io/kind/pkg/cluster"
kindcmd "sigs.k8s.io/kind/pkg/cmd"
kindexec "sigs.k8s.io/kind/pkg/exec"
"sigs.k8s.io/kind/pkg/log"
"github.com/criticalstack/crit/pkg/kubeconfig"
)
func ListNodes(clusterName string) ([]*Node, error) {
logger := kindcmd.NewLogger()
provider := cluster.NewProvider(
cluster.ProviderWithLogger(logger),
GetDefault(logger),
)
nodeList, err := provider.ListNodes(clusterName)
if err != nil {
return nil, err
}
nodes := make([]*Node, 0)
for _, node := range nodeList {
nodes = append(nodes, NewNode(node))
}
return nodes, nil
}
func GetKubeConfig(clusterName string) (*clientcmdapi.Config, error) {
nodes, err := ListNodes(clusterName)
if err != nil {
return nil, err
}
for _, node := range nodes {
if node.String() == clusterName {
data, err := node.ReadFile("/etc/kubernetes/admin.conf")
if err != nil {
return nil, err
}
kc, err := clientcmd.Load(data)
if err != nil {
return nil, err
}
n, err := getPublishedPort(clusterName)
if err != nil {
return nil, errors.Wrapf(err, "cannot get published port for cluster %q", clusterName)
}
for _, cluster := range kc.Clusters {
cluster.Server = fmt.Sprintf("https://127.0.0.1:%d", n)
}
return kc, nil
}
}
return nil, errors.Errorf("cannot find cluster %q", clusterName)
}
func ExportKubeConfig(clusterName string, kubeconfigPath string) error {
kc, err := GetKubeConfig(clusterName)
if err != nil {
return err
}
return kubeconfig.MergeConfigToFile(kc, kubeconfigPath)
}
// DeleteNodes is part of the providers.Provider interface
func DeleteNodes(n []*Node) error {
if len(n) == 0 {
return nil
}
providerName := "docker"
if v, ok := os.LookupEnv("KIND_EXPERIMENTAL_PROVIDER"); ok {
providerName = v
}
args := make([]string, 0, len(n)+3) // allocate once
args = append(args,
"rm",
"-f", // force the container to be delete now
"-v", // delete volumes
)
for _, node := range n {
args = append(args, node.String())
}
if err := exec.Command(providerName, args...).Run(); err != nil {
return errors.Wrap(err, "failed to delete nodes")
}
return nil
}
// GetDefault selected the default runtime from the environment override
func GetDefault(logger log.Logger) cluster.ProviderOption {
switch p := os.Getenv("KIND_EXPERIMENTAL_PROVIDER"); p {
case "":
return nil
case "podman":
logger.Warn("using podman due to KIND_EXPERIMENTAL_PROVIDER")
return cluster.ProviderWithPodman()
case "docker":
logger.Warn("using docker due to KIND_EXPERIMENTAL_PROVIDER")
return cluster.ProviderWithDocker()
default:
logger.Warnf("ignoring unknown value %q for KIND_EXPERIMENTAL_PROVIDER", p)
return nil
}
}
// ImageID return the Id of the container image
func ImageID(containerNameOrID string) (string, error) {
providerName := "docker"
if v, ok := os.LookupEnv("KIND_EXPERIMENTAL_PROVIDER"); ok {
providerName = v
}
cmd := kindexec.Command(providerName, "image", "inspect",
"-f", "{{ .Id }}",
containerNameOrID, // ... against the container
)
lines, err := kindexec.CombinedOutputLines(cmd)
if err != nil {
return "", err
}
if len(lines) != 1 {
return "", errors.Errorf("Docker image ID should only be one line, got %d lines", len(lines))
}
return lines[0], nil
}
func PullImage(image string) error {
providerName := "docker"
if v, ok := os.LookupEnv("KIND_EXPERIMENTAL_PROVIDER"); ok {
providerName = v
}
args := []string{
"pull",
image,
}
if data, err := exec.Command(providerName, args...).CombinedOutput(); err != nil {
fmt.Printf("cannot pull image: %s\n", data)
return errors.Wrapf(err, "failed to pull image: %v", image)
}
return nil
}