Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions e2e/tests/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"os"
"os/exec"
"strings"

"github.com/docker/docker/api/types"
Expand Down Expand Up @@ -78,6 +79,52 @@ var _ = DevSpaceDescribe("build", func() {
framework.ExpectEqual(found, true, "image not found in cache")
})

ginkgo.It("should build dockerfile with docker and load in kind cluster", func() {
tempDir, err := framework.CopyToTempDir("tests/build/testdata/docker")
framework.ExpectNoError(err)
defer framework.CleanupTempDir(initialDir, tempDir)

// create build command
buildCmd := &cmd.RunPipelineCmd{
GlobalFlags: &flags.GlobalFlags{
NoWarn: true,
},
SkipPush: true,
Pipeline: "build",
}
err = buildCmd.RunDefault(f)
framework.ExpectNoError(err)

// create devspace docker client to access docker APIs
devspaceDockerClient, err := docker.NewClient(context.TODO(), log)
framework.ExpectNoError(err)

dockerClient := devspaceDockerClient.DockerAPIClient()
imageList, err := dockerClient.ImageList(ctx, types.ImageListOptions{})
framework.ExpectNoError(err)

found := false
Outer:
for _, image := range imageList {
for _, tag := range image.RepoTags {
if tag == "my-docker-username/helloworld:latest" {
found = true
break Outer
}
}
}
framework.ExpectEqual(found, true, "image not found in cache")

var stdout, stderr bytes.Buffer
cmd := exec.Command("kind", "load", "docker-image", "my-docker-username/helloworld:latest")
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err = cmd.Run()
framework.ExpectNoError(err)
err = stderrContains(stderr.String(), "found to be already present")
framework.ExpectNoError(err)
})

ginkgo.It("should build dockerfile with docker even when KUBECONFIG is invalid", func() {
tempDir, err := framework.CopyToTempDir("tests/build/testdata/docker")
framework.ExpectNoError(err)
Expand Down Expand Up @@ -135,6 +182,50 @@ var _ = DevSpaceDescribe("build", func() {
_ = os.Unsetenv("KUBECONFIG")
})

ginkgo.It("should build dockerfile with buildkit and load in kind cluster", func() {
tempDir, err := framework.CopyToTempDir("tests/build/testdata/buildkit")
framework.ExpectNoError(err)
defer framework.CleanupTempDir(initialDir, tempDir)

// create build command
buildCmd := &cmd.RunPipelineCmd{
GlobalFlags: &flags.GlobalFlags{
NoWarn: true,
},
SkipPush: true,
Pipeline: "build",
}
err = buildCmd.RunDefault(f)
framework.ExpectNoError(err)

// create devspace docker client to access docker APIs
devspaceDockerClient, err := docker.NewClient(context.TODO(), log)
framework.ExpectNoError(err)

dockerClient := devspaceDockerClient.DockerAPIClient()
imageList, err := dockerClient.ImageList(ctx, types.ImageListOptions{})
framework.ExpectNoError(err)

for _, image := range imageList {
if len(image.RepoTags) > 0 && image.RepoTags[0] == "my-docker-username/helloworld-buildkit:latest" {
err = nil
break
} else {
err = errors.New("image not found")
}
}
framework.ExpectNoError(err)

var stdout, stderr bytes.Buffer
cmd := exec.Command("kind", "load", "docker-image", "my-docker-username/helloworld-buildkit:latest")
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err = cmd.Run()
framework.ExpectNoError(err)
err = stderrContains(stderr.String(), "found to be already present")
framework.ExpectNoError(err)
})

ginkgo.It("should build dockerfile with buildkit", func() {
tempDir, err := framework.CopyToTempDir("tests/build/testdata/buildkit")
framework.ExpectNoError(err)
Expand Down Expand Up @@ -424,3 +515,10 @@ func stdoutContains(stdout, content string) error {
}
return fmt.Errorf("%s found in output", content)
}

func stderrContains(stderr, content string) error {
if strings.Contains(stderr, content) {
return nil
}
return fmt.Errorf("%s found in output", content)
}
1 change: 1 addition & 0 deletions helper/server/chown_unsupported.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build windows
// +build windows

package server
Expand Down
21 changes: 20 additions & 1 deletion pkg/devspace/build/builder/buildkit/buildkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,27 @@ func buildWithCLI(ctx context.Context, dir string, context io.Reader, writer io.
return fmt.Errorf("error retrieving minikube environment with 'minikube docker-env --shell none'. Try setting the option preferMinikube to false: %v", err)
}
}
err = command2.CommandWithEnv(ctx, dir, writer, writer, context, minikubeEnv, command[0], completeArgs...)
if err != nil {
return err
}
//load image if it is a kind-context
if skipPush && kubeClient != nil && kubectl.IsKindContext(kubeClient.CurrentContext()) {
if len(options.Tags) > 0 {
for _, tag := range options.Tags {
command := []string{"kind", "load", "docker-image", tag}
completeArgs := []string{}
completeArgs = append(completeArgs, command[1:]...)
err = command2.CommandWithEnv(ctx, dir, writer, writer, nil, minikubeEnv, command[0], completeArgs...)
if err != nil {
log.Info(errors.Errorf("error during image load to kind cluster: %v", err))
}
log.Info("Image loaded to kind cluster")
}
}
}

return command2.CommandWithEnv(ctx, dir, writer, writer, context, minikubeEnv, command[0], completeArgs...)
return nil
}

type NodeGroup struct {
Expand Down
22 changes: 22 additions & 0 deletions pkg/devspace/build/builder/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
devspacecontext "github.com/loft-sh/devspace/pkg/devspace/context"
"github.com/loft-sh/devspace/pkg/devspace/kubectl"
command2 "github.com/loft-sh/devspace/pkg/util/command"
"github.com/sirupsen/logrus"
"io"
"os"
Expand Down Expand Up @@ -182,6 +183,27 @@ func (b *Builder) BuildImage(ctx devspacecontext.Context, contextPath, dockerfil
}
} else {
ctx.Log().Infof("Skip image push for %s", b.helper.ImageName)
//load image if it is a kind-context
if ctx.KubeClient() != nil && kubectl.IsKindContext(ctx.KubeClient().CurrentContext()) {
for _, tag := range buildOptions.Tags {
command := []string{"kind", "load", "docker-image", tag}
completeArgs := []string{}
completeArgs = append(completeArgs, command[1:]...)
// Determine output writer
var writeCloser io.WriteCloser
if ctx.Log() == logpkg.GetInstance() {
writeCloser = logpkg.WithNopCloser(stdout)
} else {
writeCloser = ctx.Log().Writer(logrus.InfoLevel, false)
}
defer writeCloser.Close()
err = command2.CommandWithEnv(ctx.Context(), ctx.WorkingDir(), writeCloser, writeCloser, nil, nil, command[0], completeArgs...)
if err != nil {
ctx.Log().Info(errors.Errorf("error during image load to kind cluster: %v", err))
}
ctx.Log().Info("Image loaded to kind cluster")
}
}
}

return nil
Expand Down
11 changes: 10 additions & 1 deletion pkg/devspace/kubectl/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
)

const minikubeContext = "minikube"
const kindContext = "kind-kind"
const dockerDesktopContext = "docker-desktop"
const dockerForDesktopContext = "docker-for-desktop"

Expand Down Expand Up @@ -201,11 +202,19 @@ func NewPortForwarder(client Client, pod *corev1.Pod, ports []string, addresses

// IsLocalKubernetes returns true if the context belongs to a local Kubernetes cluster
func IsLocalKubernetes(context string) bool {
if context == minikubeContext || context == dockerDesktopContext || context == dockerForDesktopContext {
if context == minikubeContext ||
context == kindContext ||
context == dockerDesktopContext ||
context == dockerForDesktopContext {
return true
} else if strings.HasPrefix(context, "vcluster_") && (strings.HasSuffix(context, minikubeContext) || strings.HasSuffix(context, dockerDesktopContext) || strings.HasSuffix(context, dockerForDesktopContext)) {
return true
}

return false
}

// IsKindContext returns true if the context is a kind Kubernetes cluster
func IsKindContext(context string) bool {
return context == kindContext
}
1 change: 1 addition & 0 deletions pkg/util/idle/idle_darwin.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build darwin
// +build darwin

package idle
Expand Down
1 change: 1 addition & 0 deletions pkg/util/idle/idle_windows.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build windows
// +build windows

package idle
Expand Down