Skip to content

Commit 4be3908

Browse files
authored
Merge pull request #2423 from lizardruss/fix-kaniko-windows
Building in Kaniko is broken from Windows in devspace 6+
2 parents 2897cad + b42f6ef commit 4be3908

6 files changed

Lines changed: 126 additions & 53 deletions

File tree

e2e/tests/localregistry/localregistry.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ var _ = DevSpaceDescribe("localregistry", func() {
419419
framework.ExpectNoError(err)
420420
})
421421

422-
ginkgo.It("should error when local registry is required and not supported by build type", func() {
422+
ginkgo.It("should not use local registry when not supported by build type", func() {
423423
tempDir, err := framework.CopyToTempDir("tests/localregistry/testdata/local-registry-kaniko")
424424
framework.ExpectNoError(err)
425425
defer framework.CleanupTempDir(initialDir, tempDir)
@@ -438,6 +438,9 @@ var _ = DevSpaceDescribe("localregistry", func() {
438438
gomega.Expect(output.String()).To(
439439
gomega.ContainSubstring("unable to push image my-docker-username/helloworld-kaniko and only docker and buildkit builds support using a local registry"),
440440
)
441+
gomega.Expect(output.String()).To(
442+
gomega.ContainSubstring("UNAUTHORIZED: authentication required"),
443+
)
441444
})
442445

443446
ginkgo.It("should error when local registry is required and disabled by configuration", func() {

pkg/devspace/build/build.go

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import (
1111
"github.com/loft-sh/devspace/pkg/devspace/build/types"
1212
"github.com/loft-sh/devspace/pkg/devspace/config/constants"
1313
devspacecontext "github.com/loft-sh/devspace/pkg/devspace/context"
14+
"github.com/loft-sh/devspace/pkg/util/randutil"
1415
"github.com/loft-sh/devspace/pkg/util/stringutil"
1516

1617
"github.com/loft-sh/devspace/pkg/devspace/config/versions/latest"
1718
"github.com/loft-sh/devspace/pkg/devspace/hook"
18-
"github.com/loft-sh/devspace/pkg/util/randutil"
1919
"github.com/pkg/errors"
2020
)
2121

@@ -87,50 +87,90 @@ func (c *controller) Build(ctx devspacecontext.Context, images []string, options
8787
}
8888

8989
// Determine if we need to use the local registry to build any images.
90-
kubeClient := ctx.KubeClient()
9190
var localRegistry *registry.LocalRegistry
92-
if registry.UseLocalRegistry(kubeClient, conf, options.SkipPush) {
93-
ctx := ctx.WithLogger(ctx.Log().WithPrefix("local-registry: "))
94-
for key, imageConf := range conf.Images {
95-
imageName := imageConf.Image
96-
imageConfigName := key
91+
kubeClient := ctx.KubeClient()
92+
builders := map[string]builder.Interface{}
93+
tags := map[string][]string{}
9794

98-
// Update cache for non-local registry use by default
99-
imageCache, _ := ctx.Config().LocalCache().GetImageCache(imageConfigName)
100-
imageCache.LocalRegistryImageName = ""
95+
for imageConfigName, imageConf := range conf.Images {
96+
imageName := imageConf.Image
97+
98+
// Get image tags
99+
imageTags := []string{}
100+
if len(options.Tags) > 0 {
101+
imageTags = append(imageTags, options.Tags...)
102+
} else if len(imageConf.Tags) > 0 {
103+
imageTags = append(imageTags, imageConf.Tags...)
104+
} else {
105+
imageTags = append(imageTags, randutil.GenerateRandomString(7))
106+
}
101107

102-
// Determine whether the local registry is required / enabled
103-
isLocalReqistryRequired := !registry.HasPushPermission(imageConf)
104-
if isLocalReqistryRequired {
105-
// Not able to deploy a local registry
108+
// replace the # in the tags
109+
for i := range imageTags {
110+
for strings.Contains(imageTags[i], "#") {
111+
imageTags[i] = strings.Replace(imageTags[i], "#", randutil.GenerateRandomString(1), 1)
112+
}
113+
}
114+
115+
// Create new builder
116+
builder, err := c.createBuilder(ctx, imageConfigName, imageConf, imageTags, options)
117+
if err != nil {
118+
return errors.Wrap(err, "create builder")
119+
}
120+
121+
// Update cache for non local registry use by default
122+
imageCache, _ := ctx.Config().LocalCache().GetImageCache(imageConfigName)
123+
imageCache.ImageName = imageName
124+
imageCache.LocalRegistryImageName = ""
125+
126+
if registry.UseLocalRegistry(kubeClient, conf, options.SkipPush) && !registry.HasPushPermission(imageConf) {
127+
if SupportsLocalRegistry(builder) {
128+
// Not able to deploy a local registry without a valid kube context
106129
if kubeClient == nil {
107130
return fmt.Errorf("unable to push image %s and a valid kube context is not available", imageConf.Image)
108131
}
109132

133+
// Create and start a local registry if one isn't already running
110134
if localRegistry == nil {
111135
localRegistry = registry.NewLocalRegistry(
112136
registry.NewDefaultOptions().
113137
WithNamespace(kubeClient.Namespace()).
114138
WithLocalRegistryConfig(conf.LocalRegistry),
115139
)
116140

141+
ctx := ctx.WithLogger(ctx.Log().WithPrefix("local-registry: "))
117142
err := localRegistry.Start(ctx)
118143
if err != nil {
119144
return errors.Wrap(err, "start registry")
120145
}
121146
}
122147

123-
var err error
124-
builtImageName, err := localRegistry.RewriteImage(imageName)
148+
// Update cache for local registry use
149+
imageCache.LocalRegistryImageName, err = localRegistry.RewriteImage(imageName)
125150
if err != nil {
126151
return errors.Wrap(err, "rewrite image")
127152
}
153+
ctx.Config().LocalCache().SetImageCache(imageConfigName, imageCache)
128154

129-
// Update cache for local registry use
130-
imageCache.LocalRegistryImageName = builtImageName
155+
// Reset the builder for local registry usage
156+
// TODO: refactor so this isn't necessary!
157+
builder, err = c.createBuilder(ctx, imageConfigName, imageConf, imageTags, options)
158+
if err != nil {
159+
return errors.Wrap(err, "create builder")
160+
}
161+
} else {
162+
ctx.Log().Warnf("unable to push image %s and only docker and buildkit builds support using a local registry", imageConf.Image)
131163
}
132-
ctx.Config().LocalCache().SetImageCache(imageConfigName, imageCache)
133164
}
165+
166+
// Save image cache
167+
ctx.Config().LocalCache().SetImageCache(imageConfigName, imageCache)
168+
169+
// Save builder for later use
170+
builders[imageConfigName] = builder
171+
172+
// Save image tags
173+
tags[imageConfigName] = imageTags
134174
}
135175

136176
// Execute before images build hook
@@ -152,34 +192,8 @@ func (c *controller) Build(ctx devspacecontext.Context, images []string, options
152192
imageConfigName := key
153193
imageCache, _ := ctx.Config().LocalCache().GetImageCache(imageConfigName)
154194
resolvedImage := imageCache.ResolveImage()
155-
156-
// Get image tags
157-
imageTags := []string{}
158-
if len(options.Tags) > 0 {
159-
imageTags = append(imageTags, options.Tags...)
160-
} else if len(imageConf.Tags) > 0 {
161-
imageTags = append(imageTags, imageConf.Tags...)
162-
} else {
163-
imageTags = append(imageTags, randutil.GenerateRandomString(7))
164-
}
165-
166-
// replace the # in the tags
167-
for i := range imageTags {
168-
for strings.Contains(imageTags[i], "#") {
169-
imageTags[i] = strings.Replace(imageTags[i], "#", randutil.GenerateRandomString(1), 1)
170-
}
171-
}
172-
173-
// Create new builder
174-
builder, err := c.createBuilder(ctx, imageConfigName, &cImageConf, imageTags, options)
175-
if err != nil {
176-
return errors.Wrap(err, "create builder")
177-
}
178-
179-
// Check compatibility with local registry
180-
if imageCache.IsLocalRegistryImage() && !SupportsLocalRegistry(builder) {
181-
return fmt.Errorf("unable to push image %s and only docker and buildkit builds support using a local registry", imageConf.Image)
182-
}
195+
imageTags := tags[imageConfigName]
196+
builder := builders[imageConfigName]
183197

184198
// Execute before images build hook
185199
pluginErr := hook.ExecuteHooks(ctx, map[string]interface{}{

pkg/devspace/build/builder/kaniko/kaniko.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@ package kaniko
22

33
import (
44
"fmt"
5+
"io"
6+
"strings"
7+
58
devspacecontext "github.com/loft-sh/devspace/pkg/devspace/context"
69
"github.com/loft-sh/devspace/pkg/devspace/kubectl/selector"
710
"github.com/loft-sh/devspace/pkg/devspace/services/logs"
811
"github.com/sirupsen/logrus"
9-
"io"
10-
"strings"
1112

1213
"github.com/loft-sh/devspace/pkg/util/interrupt"
1314

1415
"github.com/docker/docker/pkg/archive"
1516
"github.com/docker/docker/pkg/idtools"
1617
kerrors "k8s.io/apimachinery/pkg/api/errors"
1718
"k8s.io/apimachinery/pkg/util/wait"
18-
1919
"k8s.io/client-go/util/exec"
2020

2121
"github.com/loft-sh/devspace/pkg/devspace/build/builder"
@@ -109,6 +109,11 @@ func (b *Builder) ShouldRebuild(ctx devspacecontext.Context, forceRebuild bool)
109109
func (b *Builder) BuildImage(ctx devspacecontext.Context, contextPath, dockerfilePath string, entrypoint []string, cmd []string) error {
110110
var err error
111111

112+
contextPath, err = build.ResolveAndValidateContextPath(contextPath)
113+
if err != nil {
114+
return errors.Wrap(err, "resolve context path")
115+
}
116+
112117
// build options
113118
options := &types.ImageBuildOptions{}
114119
if b.helper.ImageConf.BuildArgs != nil {

pkg/devspace/build/registry/util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func UseLocalRegistry(client kubectl.Client, config *latest.Config, skipPush boo
136136
context := client.CurrentContext()
137137

138138
// Determine if this is a vcluster
139-
isVClusterContext := strings.HasPrefix(context, "vcluster_")
139+
isVClusterContext := strings.Contains(context, "vcluster_")
140140

141141
// Determine if this is a local kubernetes cluster
142142
isLocalKubernetes := kubectl.IsLocalKubernetes(context)

pkg/devspace/build/registry/util_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ func TestUseLocalRegistry(t *testing.T) {
7777
},
7878
expected: false,
7979
},
80+
{
81+
name: "Loft VCluster with KinD Cluster",
82+
client: &kubectltesting.Client{
83+
Context: "loft-vcluster_devspace-kind_vcluster-devspace-kind_kind-kind",
84+
},
85+
config: &latest.Config{
86+
LocalRegistry: nil,
87+
},
88+
expected: false,
89+
},
8090
{
8191
name: "Docker Desktop Cluster",
8292
client: &kubectltesting.Client{
@@ -134,6 +144,16 @@ func TestUseLocalRegistry(t *testing.T) {
134144
},
135145
expected: false,
136146
},
147+
{
148+
name: "Loft VCluster with Docker Desktop Cluster",
149+
client: &kubectltesting.Client{
150+
Context: "loft-vcluster_devspacehelper_deploy-example_docker-desktop",
151+
},
152+
config: &latest.Config{
153+
LocalRegistry: nil,
154+
},
155+
expected: false,
156+
},
137157
{
138158
name: "Minikube Cluster",
139159
client: &kubectltesting.Client{
@@ -191,6 +211,16 @@ func TestUseLocalRegistry(t *testing.T) {
191211
},
192212
expected: false,
193213
},
214+
{
215+
name: "Loft VCluster with Minikube Cluster",
216+
client: &kubectltesting.Client{
217+
Context: "loft-vcluster_devspace-minikube_vcluster-devspace-minikube_minikube",
218+
},
219+
config: &latest.Config{
220+
LocalRegistry: nil,
221+
},
222+
expected: false,
223+
},
194224
{
195225
name: "Remote Cluster",
196226
client: &kubectltesting.Client{
@@ -234,6 +264,16 @@ func TestUseLocalRegistry(t *testing.T) {
234264
},
235265
expected: true,
236266
},
267+
{
268+
name: "Loft VCluster with Remote Cluster",
269+
client: &kubectltesting.Client{
270+
Context: "loft-vcluster_vcluster-eks_vcluster-vcluster-eks_arn:aws:eks:us-west-2:1234567890:cluster/remote-eks",
271+
},
272+
config: &latest.Config{
273+
LocalRegistry: nil,
274+
},
275+
expected: true,
276+
},
237277
{
238278
name: "VCluster with Remote Cluster skip push",
239279
client: &kubectltesting.Client{
@@ -245,6 +285,17 @@ func TestUseLocalRegistry(t *testing.T) {
245285
skipPush: true,
246286
expected: false,
247287
},
288+
{
289+
name: "Loft VCluster with Remote Cluster skip push",
290+
client: &kubectltesting.Client{
291+
Context: "loft-vcluster_vcluster-eks_vcluster-vcluster-eks_arn:aws:eks:us-west-2:1234567890:cluster/remote-eks",
292+
},
293+
config: &latest.Config{
294+
LocalRegistry: nil,
295+
},
296+
skipPush: true,
297+
expected: false,
298+
},
248299
{
249300
name: "Nil KubeClient",
250301
client: nil,

pkg/devspace/kubectl/util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func IsLocalKubernetes(context string) bool {
209209
context == dockerDesktopContext ||
210210
context == dockerForDesktopContext {
211211
return true
212-
} else if strings.HasPrefix(context, "vcluster_") &&
212+
} else if strings.Contains(context, "vcluster_") &&
213213
(strings.HasSuffix(context, minikubeContext) ||
214214
strings.HasSuffix(context, dockerDesktopContext) ||
215215
strings.HasSuffix(context, dockerForDesktopContext) ||

0 commit comments

Comments
 (0)