Skip to content

Commit 9e632b4

Browse files
authored
Merge pull request #3707 from tonistiigi/k8s-trim
kubernetes: trim client-go dependency surface
2 parents bb48188 + 7c47036 commit 9e632b4

1,989 files changed

Lines changed: 6374 additions & 562524 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

driver/kubernetes/driver.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/docker/buildx/driver"
1313
"github.com/docker/buildx/driver/kubernetes/execconn"
14+
"github.com/docker/buildx/driver/kubernetes/kubeclient"
1415
"github.com/docker/buildx/driver/kubernetes/manifest"
1516
"github.com/docker/buildx/driver/kubernetes/podchooser"
1617
"github.com/docker/buildx/store"
@@ -24,9 +25,6 @@ import (
2425
corev1 "k8s.io/api/core/v1"
2526
apierrors "k8s.io/apimachinery/pkg/api/errors"
2627
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27-
"k8s.io/client-go/kubernetes"
28-
clientappsv1 "k8s.io/client-go/kubernetes/typed/apps/v1"
29-
clientcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
3028
)
3129

3230
const (
@@ -49,10 +47,9 @@ type Driver struct {
4947
minReplicas int
5048
deployment *appsv1.Deployment
5149
configMaps []*corev1.ConfigMap
52-
clientset *kubernetes.Clientset
53-
deploymentClient clientappsv1.DeploymentInterface
54-
podClient clientcorev1.PodInterface
55-
configMapClient clientcorev1.ConfigMapInterface
50+
deploymentClient kubeclient.DeploymentClient
51+
podClient kubeclient.PodClient
52+
configMapClient kubeclient.ConfigMapClient
5653
podChooser podchooser.PodChooser
5754
defaultLoad bool
5855
timeout time.Duration
@@ -201,7 +198,6 @@ func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error {
201198
}
202199

203200
func (d *Driver) Dial(ctx context.Context) (net.Conn, error) {
204-
restClient := d.clientset.CoreV1().RESTClient()
205201
restClientConfig, err := d.clientConfig.ClientConfig()
206202
if err != nil {
207203
return nil, err
@@ -221,7 +217,7 @@ func (d *Driver) Dial(ctx context.Context) (net.Conn, error) {
221217
var conn net.Conn
222218
err = tryWithBackoff(ctx, pod.Name, func() error {
223219
var err error
224-
conn, err = execconn.ExecConn(ctx, restClient, restClientConfig, pod.Namespace, pod.Name, containerName, cmd)
220+
conn, err = execconn.ExecConn(ctx, d.podClient.RESTClient(), restClientConfig, pod.Namespace, pod.Name, containerName, cmd)
225221
return err
226222
})
227223
return conn, err

driver/kubernetes/execconn/execconn.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88
"sync"
99
"time"
1010

11+
"github.com/docker/buildx/driver/kubernetes/kubeclient"
1112
"github.com/sirupsen/logrus"
1213
corev1 "k8s.io/api/core/v1"
13-
"k8s.io/client-go/kubernetes/scheme"
1414
"k8s.io/client-go/rest"
1515
"k8s.io/client-go/tools/remotecommand"
1616
)
@@ -29,7 +29,7 @@ func ExecConn(ctx context.Context, restClient rest.Interface, restConfig *rest.C
2929
Stdout: true,
3030
Stderr: true,
3131
TTY: false,
32-
}, scheme.ParameterCodec)
32+
}, kubeclient.ParameterCodec())
3333
exec, err := remotecommand.NewSPDYExecutor(restConfig, "POST", req.URL())
3434
if err != nil {
3535
return nil, err

driver/kubernetes/factory.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import (
1010
"github.com/docker/buildx/driver"
1111
"github.com/docker/buildx/driver/bkimage"
1212
ctxkube "github.com/docker/buildx/driver/kubernetes/context"
13+
"github.com/docker/buildx/driver/kubernetes/kubeclient"
1314
"github.com/docker/buildx/driver/kubernetes/manifest"
1415
"github.com/docker/buildx/driver/kubernetes/podchooser"
1516
dockerclient "github.com/moby/moby/client"
1617
"github.com/pkg/errors"
1718
"github.com/sirupsen/logrus"
1819
corev1 "k8s.io/api/core/v1"
19-
"k8s.io/client-go/kubernetes"
2020
"k8s.io/client-go/rest"
2121
)
2222

@@ -116,16 +116,11 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
116116
if err != nil {
117117
return nil, err
118118
}
119-
clientset, err := kubernetes.NewForConfig(restClientConfig)
120-
if err != nil {
121-
return nil, err
122-
}
123119

124120
d := &Driver{
125121
factory: f,
126122
clientConfig: cc,
127123
InitConfig: cfg,
128-
clientset: clientset,
129124
}
130125

131126
deploymentOpt, loadbalance, namespace, defaultLoad, timeout, err := f.processDriverOpts(deploymentName, namespace, cfg)
@@ -143,9 +138,13 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
143138

144139
d.minReplicas = int(deploymentOpt.Replicas)
145140

146-
d.deploymentClient = clientset.AppsV1().Deployments(namespace)
147-
d.podClient = clientset.CoreV1().Pods(namespace)
148-
d.configMapClient = clientset.CoreV1().ConfigMaps(namespace)
141+
clients, err := kubeclient.New(restClientConfig, namespace)
142+
if err != nil {
143+
return nil, err
144+
}
145+
d.deploymentClient = clients.Deployments
146+
d.podClient = clients.Pods
147+
d.configMapClient = clients.ConfigMaps
149148

150149
switch loadbalance {
151150
case LoadbalanceSticky:
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package kubeclient
2+
3+
import (
4+
"context"
5+
"net/http"
6+
7+
appsv1 "k8s.io/api/apps/v1"
8+
corev1 "k8s.io/api/core/v1"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/runtime/schema"
11+
"k8s.io/client-go/rest"
12+
)
13+
14+
type DeploymentClient interface {
15+
Get(ctx context.Context, name string, opts metav1.GetOptions) (*appsv1.Deployment, error)
16+
Create(ctx context.Context, deployment *appsv1.Deployment, opts metav1.CreateOptions) (*appsv1.Deployment, error)
17+
Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
18+
}
19+
20+
type ConfigMapClient interface {
21+
Create(ctx context.Context, configMap *corev1.ConfigMap, opts metav1.CreateOptions) (*corev1.ConfigMap, error)
22+
Update(ctx context.Context, configMap *corev1.ConfigMap, opts metav1.UpdateOptions) (*corev1.ConfigMap, error)
23+
Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
24+
}
25+
26+
type PodClient interface {
27+
List(ctx context.Context, opts metav1.ListOptions) (*corev1.PodList, error)
28+
RESTClient() rest.Interface
29+
}
30+
31+
type Clients struct {
32+
Deployments DeploymentClient
33+
ConfigMaps ConfigMapClient
34+
Pods PodClient
35+
}
36+
37+
func New(config *rest.Config, namespace string) (*Clients, error) {
38+
httpClient, err := rest.HTTPClientFor(config)
39+
if err != nil {
40+
return nil, err
41+
}
42+
43+
appsClient, err := newRESTClient(config, httpClient, appsv1.SchemeGroupVersion, "/apis")
44+
if err != nil {
45+
return nil, err
46+
}
47+
48+
coreClient, err := newRESTClient(config, httpClient, corev1.SchemeGroupVersion, "/api")
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
return &Clients{
54+
Deployments: &deploymentClient{client: appsClient, namespace: namespace},
55+
ConfigMaps: &configMapClient{client: coreClient, namespace: namespace},
56+
Pods: &podClient{client: coreClient, namespace: namespace},
57+
}, nil
58+
}
59+
60+
func newRESTClient(config *rest.Config, httpClient *http.Client, gv schema.GroupVersion, apiPath string) (rest.Interface, error) {
61+
cfg := *config
62+
cfg.GroupVersion = &gv
63+
cfg.APIPath = apiPath
64+
cfg.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(Scheme(), Codecs()).WithoutConversion()
65+
if cfg.UserAgent == "" {
66+
cfg.UserAgent = rest.DefaultKubernetesUserAgent()
67+
}
68+
return rest.RESTClientForConfigAndClient(&cfg, httpClient)
69+
}
70+
71+
type deploymentClient struct {
72+
client rest.Interface
73+
namespace string
74+
}
75+
76+
func (c *deploymentClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*appsv1.Deployment, error) {
77+
result := &appsv1.Deployment{}
78+
err := c.client.Get().
79+
UseProtobufAsDefault().
80+
Namespace(c.namespace).
81+
Resource("deployments").
82+
Name(name).
83+
VersionedParams(&opts, ParameterCodec()).
84+
Do(ctx).
85+
Into(result)
86+
return result, err
87+
}
88+
89+
func (c *deploymentClient) Create(ctx context.Context, deployment *appsv1.Deployment, opts metav1.CreateOptions) (*appsv1.Deployment, error) {
90+
result := &appsv1.Deployment{}
91+
err := c.client.Post().
92+
UseProtobufAsDefault().
93+
Namespace(c.namespace).
94+
Resource("deployments").
95+
VersionedParams(&opts, ParameterCodec()).
96+
Body(deployment).
97+
Do(ctx).
98+
Into(result)
99+
return result, err
100+
}
101+
102+
func (c *deploymentClient) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
103+
return c.client.Delete().
104+
UseProtobufAsDefault().
105+
Namespace(c.namespace).
106+
Resource("deployments").
107+
Name(name).
108+
Body(&opts).
109+
Do(ctx).
110+
Error()
111+
}
112+
113+
type configMapClient struct {
114+
client rest.Interface
115+
namespace string
116+
}
117+
118+
func (c *configMapClient) Create(ctx context.Context, configMap *corev1.ConfigMap, opts metav1.CreateOptions) (*corev1.ConfigMap, error) {
119+
result := &corev1.ConfigMap{}
120+
err := c.client.Post().
121+
UseProtobufAsDefault().
122+
Namespace(c.namespace).
123+
Resource("configmaps").
124+
VersionedParams(&opts, ParameterCodec()).
125+
Body(configMap).
126+
Do(ctx).
127+
Into(result)
128+
return result, err
129+
}
130+
131+
func (c *configMapClient) Update(ctx context.Context, configMap *corev1.ConfigMap, opts metav1.UpdateOptions) (*corev1.ConfigMap, error) {
132+
result := &corev1.ConfigMap{}
133+
err := c.client.Put().
134+
UseProtobufAsDefault().
135+
Namespace(c.namespace).
136+
Resource("configmaps").
137+
Name(configMap.Name).
138+
VersionedParams(&opts, ParameterCodec()).
139+
Body(configMap).
140+
Do(ctx).
141+
Into(result)
142+
return result, err
143+
}
144+
145+
func (c *configMapClient) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
146+
return c.client.Delete().
147+
UseProtobufAsDefault().
148+
Namespace(c.namespace).
149+
Resource("configmaps").
150+
Name(name).
151+
Body(&opts).
152+
Do(ctx).
153+
Error()
154+
}
155+
156+
type podClient struct {
157+
client rest.Interface
158+
namespace string
159+
}
160+
161+
func (c *podClient) List(ctx context.Context, opts metav1.ListOptions) (*corev1.PodList, error) {
162+
result := &corev1.PodList{}
163+
err := c.client.Get().
164+
UseProtobufAsDefault().
165+
Namespace(c.namespace).
166+
Resource("pods").
167+
VersionedParams(&opts, ParameterCodec()).
168+
Do(ctx).
169+
Into(result)
170+
return result, err
171+
}
172+
173+
func (c *podClient) RESTClient() rest.Interface {
174+
return c.client
175+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package kubeclient
2+
3+
import (
4+
"sync"
5+
6+
appsv1 "k8s.io/api/apps/v1"
7+
corev1 "k8s.io/api/core/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
"k8s.io/apimachinery/pkg/runtime"
10+
"k8s.io/apimachinery/pkg/runtime/schema"
11+
"k8s.io/apimachinery/pkg/runtime/serializer"
12+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
13+
)
14+
15+
type schemeData struct {
16+
scheme *runtime.Scheme
17+
codecs serializer.CodecFactory
18+
parameterCodec runtime.ParameterCodec
19+
}
20+
21+
var loadSchemeData = sync.OnceValue(func() schemeData {
22+
s := runtime.NewScheme()
23+
metav1.AddToGroupVersion(s, schema.GroupVersion{Version: "v1"})
24+
utilruntime.Must(corev1.AddToScheme(s))
25+
utilruntime.Must(appsv1.AddToScheme(s))
26+
27+
return schemeData{
28+
scheme: s,
29+
codecs: serializer.NewCodecFactory(s),
30+
parameterCodec: runtime.NewParameterCodec(s),
31+
}
32+
})
33+
34+
func Scheme() *runtime.Scheme {
35+
return loadSchemeData().scheme
36+
}
37+
38+
func Codecs() serializer.CodecFactory {
39+
return loadSchemeData().codecs
40+
}
41+
42+
func ParameterCodec() runtime.ParameterCodec {
43+
return loadSchemeData().parameterCodec
44+
}

driver/kubernetes/podchooser/podchooser.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import (
66
"sort"
77
"time"
88

9+
"github.com/docker/buildx/driver/kubernetes/kubeclient"
910
"github.com/pkg/errors"
1011
"github.com/serialx/hashring"
1112
"github.com/sirupsen/logrus"
1213
appsv1 "k8s.io/api/apps/v1"
1314
corev1 "k8s.io/api/core/v1"
1415
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15-
clientcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
1616
)
1717

1818
type PodChooser interface {
@@ -21,7 +21,7 @@ type PodChooser interface {
2121

2222
type RandomPodChooser struct {
2323
RandSource rand.Source
24-
PodClient clientcorev1.PodInterface
24+
PodClient kubeclient.PodClient
2525
Deployment *appsv1.Deployment
2626
}
2727

@@ -45,7 +45,7 @@ func (pc *RandomPodChooser) ChoosePod(ctx context.Context) (*corev1.Pod, error)
4545

4646
type StickyPodChooser struct {
4747
Key string
48-
PodClient clientcorev1.PodInterface
48+
PodClient kubeclient.PodClient
4949
Deployment *appsv1.Deployment
5050
}
5151

@@ -74,7 +74,7 @@ func (pc *StickyPodChooser) ChoosePod(ctx context.Context) (*corev1.Pod, error)
7474
return podMap[chosen], nil
7575
}
7676

77-
func ListRunningPods(ctx context.Context, client clientcorev1.PodInterface, depl *appsv1.Deployment) ([]*corev1.Pod, error) {
77+
func ListRunningPods(ctx context.Context, client kubeclient.PodClient, depl *appsv1.Deployment) ([]*corev1.Pod, error) {
7878
selector, err := metav1.LabelSelectorAsSelector(depl.Spec.Selector)
7979
if err != nil {
8080
return nil, err

0 commit comments

Comments
 (0)