-
Notifications
You must be signed in to change notification settings - Fork 38
/
admin_kind.go
124 lines (104 loc) · 3.48 KB
/
admin_kind.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
package cluster
import (
"context"
"fmt"
"os/exec"
"strings"
"github.com/pkg/errors"
"github.com/tilt-dev/ctlptl/pkg/api"
"github.com/tilt-dev/localregistry-go"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/klog/v2"
)
const kindNetworkName = "kind"
// kindAdmin uses the kind CLI to manipulate a kind cluster,
// once the underlying machine has been setup.
type kindAdmin struct {
iostreams genericclioptions.IOStreams
}
func newKindAdmin(iostreams genericclioptions.IOStreams) *kindAdmin {
return &kindAdmin{
iostreams: iostreams,
}
}
func (a *kindAdmin) EnsureInstalled(ctx context.Context) error {
_, err := exec.LookPath("kind")
if err != nil {
return fmt.Errorf("kind not installed. Please install kind with these instructions: https://kind.sigs.k8s.io/")
}
return nil
}
func (a *kindAdmin) Create(ctx context.Context, desired *api.Cluster, registry *api.Registry) error {
klog.V(3).Infof("Creating cluster with config:\n%+v\n---\n", desired)
if registry != nil {
klog.V(3).Infof("Initializing cluster with registry config:\n%+v\n---\n", registry)
}
clusterName := desired.Name
if !strings.HasPrefix(clusterName, "kind-") {
return fmt.Errorf("all kind clusters must have a name with the prefix kind-*")
}
kindName := strings.TrimPrefix(clusterName, "kind-")
args := []string{"create", "cluster", "--name", kindName}
// TODO(nick): Let the user pass in their own Kind configuration.
in := strings.NewReader("")
if registry != nil {
containerdConfig := fmt.Sprintf(`
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
containerdConfigPatches:
- |-
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:%d"]
endpoint = ["http://%s:%d"]
`, registry.Status.HostPort, registry.Name, registry.Status.ContainerPort)
in = strings.NewReader(containerdConfig)
args = append(args, "--config", "-")
}
cmd := exec.CommandContext(ctx, "kind", args...)
cmd.Stdout = a.iostreams.Out
cmd.Stderr = a.iostreams.ErrOut
cmd.Stdin = in
err := cmd.Run()
if err != nil {
return errors.Wrap(err, "creating kind cluster")
}
if !a.inKindNetwork(registry) {
_, _ = fmt.Fprintf(a.iostreams.ErrOut, " Connecting kind to registry %s\n", registry.Name)
cmd := exec.CommandContext(ctx, "docker", "network", "connect", kindNetworkName, registry.Name)
err := cmd.Run()
if err != nil {
return errors.Wrap(err, "connecting registry")
}
}
return nil
}
func (a *kindAdmin) inKindNetwork(registry *api.Registry) bool {
for _, n := range registry.Status.Networks {
if n == kindNetworkName {
return true
}
}
return false
}
func (a *kindAdmin) LocalRegistryHosting(registry *api.Registry) *localregistry.LocalRegistryHostingV1 {
return &localregistry.LocalRegistryHostingV1{
Host: fmt.Sprintf("localhost:%d", registry.Status.HostPort),
HostFromClusterNetwork: fmt.Sprintf("%s:%d", registry.Name, registry.Status.ContainerPort),
Help: "https://github.com/tilt-dev/ctlptl",
}
}
func (a *kindAdmin) Delete(ctx context.Context, config *api.Cluster) error {
clusterName := config.Name
if !strings.HasPrefix(clusterName, "kind-") {
return fmt.Errorf("all kind clusters must have a name with the prefix kind-*")
}
kindName := strings.TrimPrefix(clusterName, "kind-")
cmd := exec.CommandContext(ctx, "kind", "delete", "cluster", "--name", kindName)
cmd.Stdout = a.iostreams.Out
cmd.Stderr = a.iostreams.ErrOut
cmd.Stdin = a.iostreams.In
err := cmd.Run()
if err != nil {
return errors.Wrap(err, "deleting kind cluster")
}
return nil
}