@@ -17,23 +17,25 @@ limitations under the License.
17
17
package kind
18
18
19
19
import (
20
+ "context"
20
21
"fmt"
21
- "os"
22
22
"os/exec"
23
- "strings"
23
+
24
+ "github.com/docker/docker/api/types/container"
25
+ "github.com/docker/docker/api/types/strslice"
26
+ "github.com/docker/docker/client"
27
+ "sigs.k8s.io/kind/pkg/cluster"
28
+ "sigs.k8s.io/kind/pkg/cluster/nodes"
24
29
)
25
30
26
31
// IsClusterRunning checks if a Kind cluster with the given name is running
27
- func IsClusterRunning (clusterName string ) (bool , error ) {
28
- cmd := exec .Command (Kind , "get" , "clusters" )
29
- output , err := cmd .CombinedOutput ()
32
+ func IsClusterRunning (provider * cluster.Provider , clusterName string ) (bool , error ) {
33
+ clusters , err := provider .List ()
30
34
if err != nil {
31
- return false , fmt .Errorf ("failed to get Kind clusters: %w, output: %s " , err , string ( output ) )
35
+ return false , fmt .Errorf ("failed to list Kind clusters: %w" , err )
32
36
}
33
-
34
- clusters := strings .Split (strings .TrimSpace (string (output )), "\n " )
35
- for _ , cluster := range clusters {
36
- if cluster == clusterName {
37
+ for _ , c := range clusters {
38
+ if c == clusterName {
37
39
return true , nil
38
40
}
39
41
}
@@ -73,61 +75,80 @@ func WithNetworks(networks []string) CreateClusterOption {
73
75
}
74
76
75
77
// CreateCluster creates a Kind cluster with the given name
76
- func CreateCluster (name string , opts ... CreateClusterOption ) error {
78
+ func CreateCluster (ctx context. Context , provider * cluster. Provider , name string , opts ... CreateClusterOption ) error {
77
79
options := & CreateClusterOptions {}
78
80
for _ , opt := range opts {
79
81
opt (options )
80
82
}
81
83
82
- args := []string {"create" , "cluster" , "--name" , name }
84
+ createOpts := []cluster.CreateOption {
85
+ cluster .CreateWithRetain (true ),
86
+ cluster .CreateWithDisplayUsage (true ),
87
+ cluster .CreateWithDisplaySalutation (true ),
88
+ }
83
89
if options .ConfigFile != "" {
84
- args = append (args , "--config" , options .ConfigFile )
90
+ createOpts = append (createOpts , cluster . CreateWithConfigFile ( options .ConfigFile ) )
85
91
}
86
92
if options .K8sVersion != "" {
87
- args = append (args , "--image" , fmt .Sprintf ("kindest/node:%s" , options .K8sVersion ))
93
+ createOpts = append (createOpts , cluster .CreateWithNodeImage (fmt .Sprintf ("kindest/node:%s" , options .K8sVersion )))
94
+ }
95
+ err := provider .Create (name , createOpts ... )
96
+ if err != nil {
97
+ return fmt .Errorf ("kind cluster creation failed: %w" , err )
88
98
}
89
99
90
- cmd := exec .Command (Kind , args ... ) // #nosec
91
- cmd .Dir , _ = os .Getwd ()
92
- output , err := cmd .CombinedOutput ()
100
+ // Initialize Docker client
101
+ cli , err := client .NewClientWithOpts (client .FromEnv , client .WithAPIVersionNegotiation ())
93
102
if err != nil {
94
- return fmt .Errorf ("'kind create cluster' failed : %w, output: %s " , err , string ( output ) )
103
+ return fmt .Errorf ("failed to create Docker client : %w" , err )
95
104
}
96
105
97
106
// Since a cluster can mount additional certificates, we need to make sure they are
98
107
// usable by the nodes in the cluster.
99
- nodes , err := getNodes (name )
108
+ nodeList , err := getNodes (provider , name )
100
109
if err != nil {
101
110
return err
102
111
}
103
- for _ , node := range nodes {
104
- cmd = exec .Command ("docker" , "exec" , node , "update-ca-certificates" ) // #nosec
105
- output , err = cmd .CombinedOutput ()
112
+ for _ , node := range nodeList {
113
+ cmd : = exec .Command ("docker" , "exec" , node . String () , "update-ca-certificates" ) // #nosec
114
+ output , err : = cmd .CombinedOutput ()
106
115
if err != nil {
107
116
return fmt .Errorf ("failed to update CA certificates in node %s: %w, output: %s" , node , err , string (output ))
108
117
}
118
+
119
+ execConfig := container.ExecOptions {
120
+ Cmd : strslice .StrSlice ([]string {"update-ca-certificates" }),
121
+ AttachStdout : true ,
122
+ AttachStderr : true ,
123
+ }
124
+ execID , err := cli .ContainerExecCreate (ctx , node .String (), execConfig )
125
+ if err != nil {
126
+ return fmt .Errorf ("failed to create exec instance in node %s: %w" , node .String (), err )
127
+ }
128
+
129
+ err = cli .ContainerExecStart (ctx , execID .ID , container.ExecStartOptions {})
130
+ if err != nil {
131
+ return fmt .Errorf ("failed to start exec instance in node %s: %w" , node .String (), err )
132
+ }
109
133
}
110
134
111
- for _ , network := range options .Networks {
112
- for _ , node := range nodes {
113
- cmd = exec .Command ("docker" , "network" , "connect" , network , node ) // #nosec
114
- output , err = cmd .CombinedOutput ()
135
+ for _ , netw := range options .Networks {
136
+ for _ , node := range nodeList {
137
+ err := cli .NetworkConnect (ctx , netw , node .String (), nil )
115
138
if err != nil {
116
- return fmt .Errorf ("failed to connect node %s to network %s: %w, output: %s" , node , network , err ,
117
- string (output ))
139
+ return fmt .Errorf ("failed to connect node %s to network %s: %w" , node .String (), netw , err )
118
140
}
119
141
}
120
142
}
121
143
122
144
return nil
123
145
}
124
146
125
- func getNodes (clusterName string ) ([]string , error ) {
126
- cmd := exec .Command (Kind , "get" , "nodes" , "--name" , clusterName )
127
- output , err := cmd .CombinedOutput ()
147
+ func getNodes (provider * cluster.Provider , clusterName string ) ([]nodes.Node , error ) {
148
+ nodeList , err := provider .ListNodes (clusterName )
128
149
if err != nil {
129
- return nil , fmt .Errorf ("failed to get Kind nodes: %w, output: %s " , err , string ( output ) )
150
+ return nil , fmt .Errorf ("failed to get Kind nodes: %w" , err )
130
151
}
131
152
132
- return strings . Split ( strings . TrimSpace ( string ( output )), " \n " ) , nil
153
+ return nodeList , nil
133
154
}
0 commit comments