Skip to content

Commit 0121f55

Browse files
committed
feat(localregistry): exposed resources and annotations
Signed-off-by: Francisco Garcia Florez <francisco@truevoid.dev>
1 parent ec22b1b commit 0121f55

File tree

9 files changed

+439
-263
lines changed

9 files changed

+439
-263
lines changed

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ require (
9999
github.com/emirpasic/gods v1.12.0 // indirect
100100
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
101101
github.com/felixge/httpsnoop v1.0.3 // indirect
102+
github.com/fsnotify/fsnotify v1.4.9 // indirect
102103
github.com/go-errors/errors v1.4.2 // indirect
103104
github.com/go-logr/logr v1.3.0 // indirect
104105
github.com/go-logr/stdr v1.2.2 // indirect
@@ -153,6 +154,8 @@ require (
153154
github.com/morikuni/aec v1.0.0 // indirect
154155
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
155156
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
157+
github.com/nxadm/tail v1.4.8 // indirect
158+
github.com/onsi/ginkgo v1.16.5 // indirect
156159
github.com/opencontainers/go-digest v1.0.0 // indirect
157160
github.com/opencontainers/image-spec v1.1.0 // indirect
158161
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
@@ -196,6 +199,7 @@ require (
196199
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
197200
gopkg.in/inf.v0 v0.9.1 // indirect
198201
gopkg.in/src-d/go-billy.v4 v4.3.2 // indirect
202+
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
199203
gopkg.in/warnings.v0 v0.1.2 // indirect
200204
gopkg.in/yaml.v2 v2.4.0 // indirect
201205
k8s.io/cli-runtime v0.29.0 // indirect

go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPr
413413
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
414414
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
415415
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
416+
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
416417
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
417418
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
418419
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
@@ -729,6 +730,8 @@ github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/
729730
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
730731
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
731732
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
733+
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
734+
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
732735
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
733736
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
734737
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
@@ -744,6 +747,8 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
744747
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
745748
github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ=
746749
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
750+
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
751+
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
747752
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
748753
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
749754
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
@@ -753,6 +758,7 @@ github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
753758
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
754759
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
755760
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
761+
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
756762
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
757763
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
758764
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
@@ -1108,6 +1114,7 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
11081114
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
11091115
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
11101116
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
1117+
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
11111118
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
11121119
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
11131120
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -1206,6 +1213,7 @@ golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7w
12061213
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
12071214
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
12081215
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1216+
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
12091217
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
12101218
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
12111219
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1296,6 +1304,7 @@ golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roY
12961304
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
12971305
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
12981306
golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
1307+
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
12991308
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
13001309
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
13011310
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=

pkg/devspace/build/localregistry/deployment.go

Lines changed: 86 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,17 @@ const BuildKitContainer = "buildkitd"
1919

2020
func (r *LocalRegistry) ensureDeployment(ctx devspacecontext.Context) (*appsv1.Deployment, error) {
2121
// Switching from a persistent registry, delete the statefulset.
22-
_, err := ctx.KubeClient().KubeClient().AppsV1().StatefulSets(r.Namespace).Get(ctx.Context(), r.Name, metav1.GetOptions{})
22+
_, err := ctx.KubeClient().
23+
KubeClient().
24+
AppsV1().
25+
StatefulSets(r.Namespace).
26+
Get(ctx.Context(), r.Name, metav1.GetOptions{})
2327
if err == nil {
24-
err := ctx.KubeClient().KubeClient().AppsV1().StatefulSets(r.Namespace).Delete(ctx.Context(), r.Name, metav1.DeleteOptions{})
28+
err := ctx.KubeClient().
29+
KubeClient().
30+
AppsV1().
31+
StatefulSets(r.Namespace).
32+
Delete(ctx.Context(), r.Name, metav1.DeleteOptions{})
2533
if err != nil && kerrors.IsNotFound(err) {
2634
return nil, err
2735
}
@@ -31,29 +39,41 @@ func (r *LocalRegistry) ensureDeployment(ctx devspacecontext.Context) (*appsv1.D
3139
var existing *appsv1.Deployment
3240
desired := r.getDeployment()
3341
kubeClient := ctx.KubeClient()
34-
err = wait.PollUntilContextTimeout(ctx.Context(), time.Second, 30*time.Second, true, func(ctx context.Context) (bool, error) {
35-
var err error
36-
37-
existing, err = kubeClient.KubeClient().AppsV1().Deployments(r.Namespace).Get(ctx, r.Name, metav1.GetOptions{})
38-
if err == nil {
39-
return true, nil
40-
}
42+
err = wait.PollUntilContextTimeout(
43+
ctx.Context(),
44+
time.Second,
45+
30*time.Second,
46+
true,
47+
func(ctx context.Context) (bool, error) {
48+
var err error
4149

42-
if kerrors.IsNotFound(err) {
43-
existing, err = kubeClient.KubeClient().AppsV1().Deployments(r.Namespace).Create(ctx, desired, metav1.CreateOptions{})
50+
existing, err = kubeClient.KubeClient().
51+
AppsV1().
52+
Deployments(r.Namespace).
53+
Get(ctx, r.Name, metav1.GetOptions{})
4454
if err == nil {
4555
return true, nil
4656
}
4757

48-
if kerrors.IsAlreadyExists(err) {
49-
return false, nil
58+
if kerrors.IsNotFound(err) {
59+
existing, err = kubeClient.KubeClient().
60+
AppsV1().
61+
Deployments(r.Namespace).
62+
Create(ctx, desired, metav1.CreateOptions{})
63+
if err == nil {
64+
return true, nil
65+
}
66+
67+
if kerrors.IsAlreadyExists(err) {
68+
return false, nil
69+
}
70+
71+
return false, err
5072
}
5173

5274
return false, err
53-
}
54-
55-
return false, err
56-
})
75+
},
76+
)
5777
if err != nil {
5878
return nil, err
5979
}
@@ -72,7 +92,8 @@ func (r *LocalRegistry) ensureDeployment(ctx devspacecontext.Context) (*appsv1.D
7292
},
7393
)
7494
if kerrors.IsUnsupportedMediaType(err) {
75-
ctx.Log().Debugf("Server-side apply not available on the server for localRegistry deployment: (%v)", err)
95+
ctx.Log().
96+
Debugf("Server-side apply not available on the server for localRegistry deployment: (%v)", err)
7697
// Unsupport server-side apply, we use existing or created deployment
7798
return existing, nil
7899
}
@@ -96,11 +117,18 @@ func (r *LocalRegistry) getDeployment() *appsv1.Deployment {
96117
Labels: map[string]string{
97118
"app": r.Name,
98119
},
99-
Annotations: getAnnotations(r.LocalBuild),
120+
Annotations: getAnnotations(r.LocalBuild, r.Annotations),
100121
},
101122
Spec: corev1.PodSpec{
102123
EnableServiceLinks: new(bool),
103-
Containers: getContainers(r.RegistryImage, r.BuildKitImage, "registry", int32(r.Port), r.LocalBuild),
124+
Containers: getContainers(
125+
r.RegistryImage,
126+
r.BuildKitImage,
127+
"registry",
128+
int32(r.Port),
129+
r.LocalBuild,
130+
r.Resources,
131+
),
104132
Volumes: []corev1.Volume{
105133
{
106134
VolumeSource: corev1.VolumeSource{
@@ -121,24 +149,42 @@ func (r *LocalRegistry) getDeployment() *appsv1.Deployment {
121149
}
122150
}
123151

124-
func getAnnotations(localbuild bool) map[string]string {
125-
if !localbuild {
126-
return map[string]string{
152+
func getAnnotations(isLocalbuild bool, annotations map[string]string) map[string]string {
153+
if !isLocalbuild {
154+
combined := map[string]string{
127155
"container.apparmor.security.beta.kubernetes.io/buildkitd": "unconfined",
128156
}
157+
158+
for k, v := range annotations {
159+
combined[k] = v
160+
}
161+
162+
return combined
129163
}
130-
return map[string]string{}
164+
165+
return annotations
131166
}
132167

133168
// this returns a different deployment, if we're using a local docker build or not.
134-
func getContainers(registryImage, buildKitImage, volume string, port int32, localbuild bool) []corev1.Container {
135-
buildContainers := getRegistryContainers(registryImage, volume, port)
169+
func getContainers(
170+
registryImage, buildKitImage, volume string,
171+
port int32,
172+
localbuild bool,
173+
registryResources *corev1.ResourceRequirements,
174+
) []corev1.Container {
175+
buildContainers := getRegistryContainers(registryImage, volume, port, registryResources)
136176
if localbuild {
137177
// in case we're using local builds just return the deployment with only the
138178
// registry container inside
139179
return buildContainers
140180
}
141181

182+
resources := corev1.ResourceRequirements{}
183+
184+
if registryResources != nil {
185+
resources = *registryResources
186+
}
187+
142188
buildKitContainer := []corev1.Container{
143189
{
144190
Name: BuildKitContainer,
@@ -185,6 +231,7 @@ func getContainers(registryImage, buildKitImage, volume string, port int32, loca
185231
MountPath: "/home/user/.local/share/buildkit",
186232
},
187233
},
234+
Resources: resources,
188235
},
189236
}
190237

@@ -193,7 +240,18 @@ func getContainers(registryImage, buildKitImage, volume string, port int32, loca
193240
return append(buildKitContainer, buildContainers...)
194241
}
195242

196-
func getRegistryContainers(registryImage, volume string, port int32) []corev1.Container {
243+
func getRegistryContainers(
244+
registryImage, volume string,
245+
port int32,
246+
registryResources *corev1.ResourceRequirements,
247+
) []corev1.Container {
248+
249+
resources := corev1.ResourceRequirements{}
250+
251+
if registryResources != nil {
252+
resources = *registryResources
253+
}
254+
197255
return []corev1.Container{
198256
{
199257
Name: "registry",
@@ -240,6 +298,7 @@ func getRegistryContainers(registryImage, volume string, port int32) []corev1.Co
240298
MountPath: "/var/lib/registry",
241299
},
242300
},
301+
Resources: resources,
243302
},
244303
}
245304
}

pkg/devspace/build/localregistry/local_registry.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ type LocalRegistry struct {
3333
Options
3434
host string
3535
servicePort *corev1.ServicePort
36+
resources *corev1.ResourceRequirements
37+
annotations map[string]string
3638
}
3739

3840
func GetOrCreateLocalRegistry(

pkg/devspace/build/localregistry/options.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package localregistry
22

33
import (
4+
"fmt"
45
"path"
56

67
"github.com/loft-sh/devspace/pkg/devspace/config/versions/latest"
8+
9+
corev1 "k8s.io/api/core/v1"
10+
"k8s.io/apimachinery/pkg/api/resource"
711
)
812

913
var (
@@ -24,6 +28,8 @@ type Options struct {
2428
StorageEnabled bool
2529
StorageSize string
2630
StorageClassName string
31+
Resources *corev1.ResourceRequirements
32+
Annotations map[string]string
2733
}
2834

2935
func getID(o Options) string {
@@ -41,6 +47,8 @@ func NewDefaultOptions() Options {
4147
StorageEnabled: false,
4248
StorageSize: RegistryDefaultStorage,
4349
StorageClassName: "",
50+
Resources: nil,
51+
Annotations: map[string]string{},
4452
}
4553
}
4654

@@ -113,6 +121,52 @@ func (o Options) WithStorageSize(storageSize string) Options {
113121
return newOptions
114122
}
115123

124+
func (o Options) WithResources(resources *latest.PodResources) Options {
125+
if resources == nil {
126+
return o
127+
}
128+
129+
// helper converts a map[string]string -> corev1.ResourceList
130+
toList := func(src map[string]string) (corev1.ResourceList, error) {
131+
if len(src) == 0 {
132+
return nil, nil
133+
}
134+
dst := corev1.ResourceList{}
135+
for k, v := range src {
136+
q, err := resource.ParseQuantity(v)
137+
if err != nil {
138+
return nil, fmt.Errorf("invalid quantity %q for %s: %w", v, k, err)
139+
}
140+
dst[corev1.ResourceName(k)] = q
141+
}
142+
return dst, nil
143+
}
144+
145+
reqs, err := toList(resources.Requests)
146+
if reqs == nil || err != nil {
147+
return o
148+
}
149+
lims, err := toList(resources.Limits)
150+
if lims == nil || err != nil {
151+
return o
152+
}
153+
154+
o.Resources = &corev1.ResourceRequirements{
155+
Requests: reqs,
156+
Limits: lims,
157+
}
158+
159+
return o
160+
}
161+
162+
func (o Options) WithAnnotations(annotations map[string]string) Options {
163+
newOptions := o
164+
if annotations != nil {
165+
newOptions.Annotations = annotations
166+
}
167+
return newOptions
168+
}
169+
116170
func (o Options) WithLocalRegistryConfig(config *latest.LocalRegistryConfig) Options {
117171
newOptions := o
118172
if config != nil {
@@ -122,9 +176,12 @@ func (o Options) WithLocalRegistryConfig(config *latest.LocalRegistryConfig) Opt
122176
WithImage(config.Image).
123177
WithBuildKitImage(config.BuildKitImage).
124178
WithPort(config.Port).
179+
WithResources(config.Resources).
180+
WithAnnotations(config.Annotations).
125181
WithLocalBuild(config.LocalBuild)
126182

127-
if config.Persistence != nil && config.Persistence.Enabled != nil && *config.Persistence.Enabled {
183+
if config.Persistence != nil && config.Persistence.Enabled != nil &&
184+
*config.Persistence.Enabled {
128185
newOptions = newOptions.
129186
EnableStorage().
130187
WithStorageClassName(config.Persistence.StorageClassName).

0 commit comments

Comments
 (0)