Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
7cf21b4
wip: local registry
lizardruss Sep 16, 2022
786240c
wip: implement should rebuild
lizardruss Sep 19, 2022
039cd74
wip: alternative implementation
lizardruss Sep 20, 2022
659e239
test: test for local registry kubectl manifest substitution
lizardruss Sep 20, 2022
5001c7e
fix: implement workaround for not being able to push using docker daemon
lizardruss Sep 22, 2022
06203e9
test: remove test duplication
lizardruss Sep 22, 2022
89f0a7f
test: fix builder local registry compatibility check
lizardruss Sep 22, 2022
2c13aef
fix: support buildkit for local registries
lizardruss Sep 22, 2022
5787f49
test: fix assertion for local registry images
lizardruss Sep 22, 2022
349d390
test: fix failing tests
lizardruss Sep 22, 2022
2cfd3a1
test: fix error hook expectations
lizardruss Sep 22, 2022
5c55b64
fix: adjusting skip push / local registry logic
lizardruss Sep 22, 2022
68e2ae1
test: turn off local registry for certain tests
lizardruss Sep 23, 2022
a35847e
test: test local registry with storage
lizardruss Sep 23, 2022
06c487c
test: check that devImage uses local registry image
lizardruss Sep 23, 2022
6b525e8
refactor: make local registry config top-level
lizardruss Sep 23, 2022
c4f7154
feat: add local registry push progress bar
lizardruss Sep 26, 2022
230a364
fix: use correct image for ShouldRebuild() checks
lizardruss Sep 26, 2022
4a12963
feat: add 'devspace cleanup local-registry' command
lizardruss Sep 26, 2022
b47232f
feat: add flag to prefer local registry over 'kind load'
lizardruss Sep 26, 2022
5404017
refactor: local registry progress output with logger
lizardruss Sep 27, 2022
5e05d34
fix: prevent using local registry when switching to/from a KinD cluster
lizardruss Sep 27, 2022
ad8bfd1
refactor: remove --prefer-local-registry flag
lizardruss Sep 27, 2022
e9c45a2
test: revert expectation changes
lizardruss Sep 27, 2022
58c7e12
chore: remove unused code
lizardruss Sep 27, 2022
b9c6bb4
feat: apply registry configuration changes
lizardruss Sep 27, 2022
6515353
chore: revert unnecessary change
lizardruss Sep 28, 2022
2bceafd
refactor: minor code clean up
lizardruss Sep 28, 2022
31158b0
fix: not all hooks reflect the local registry image
lizardruss Sep 29, 2022
561234f
refactor: use io.Writer instead of logger for local registry progress…
lizardruss Sep 29, 2022
bcd2546
refactor: use server side apply and detect available registry before …
lizardruss Sep 29, 2022
012cb89
refactor: use optional enabled flag to enable/disable local registry
lizardruss Sep 29, 2022
65c6346
chore: clean up logic
lizardruss Sep 29, 2022
eb1398f
feat: add localRegistry config to devspace init output
lizardruss Oct 12, 2022
6d20cdf
fix: skip push with local kubernetes with devspace build
lizardruss Oct 12, 2022
69985d5
fix: skip local registry when using minikube
lizardruss Oct 12, 2022
5e850f7
fix: add logging prefix for local registry
lizardruss Oct 12, 2022
0b325af
fix: 'devspace cleanup local-regitry' check for local registry before…
lizardruss Oct 12, 2022
4066218
fix: use resolved image in errors / log messages
lizardruss Oct 12, 2022
35682f1
fix: add enabled flag to localRegistry init output
lizardruss Oct 13, 2022
724d8d4
fix: log a warning when the local registry is skipped due to Minikube
lizardruss Oct 13, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 4 additions & 3 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import (
// NewBuildCmd creates a new devspace build command
func NewBuildCmd(f factory.Factory, globalFlags *flags.GlobalFlags, rawConfig *RawConfig) *cobra.Command {
cmd := &RunPipelineCmd{
GlobalFlags: globalFlags,
Pipeline: "build",
ForceBuild: true,
GlobalFlags: globalFlags,
Pipeline: "build",
ForceBuild: true,
SkipPushLocalKubernetes: true,
Comment thread
lizardruss marked this conversation as resolved.
}

var pipeline *latest.Pipeline
Expand Down
1 change: 1 addition & 0 deletions cmd/cleanup/cleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func NewCleanupCmd(f factory.Factory, globalFlags *flags.GlobalFlags, plugins []
}

cleanupCmd.AddCommand(newImagesCmd(f, globalFlags))
cleanupCmd.AddCommand(newLocalRegistryCmd(f, globalFlags))

// Add plugin commands
plugin.AddPluginCommands(cleanupCmd, plugins, "cleanup")
Expand Down
171 changes: 171 additions & 0 deletions cmd/cleanup/local_registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package cleanup

import (
"context"

"github.com/loft-sh/devspace/cmd/flags"
"github.com/loft-sh/devspace/pkg/devspace/build/registry"
"github.com/loft-sh/devspace/pkg/devspace/kubectl"
"github.com/loft-sh/devspace/pkg/util/factory"
"github.com/loft-sh/devspace/pkg/util/message"
"github.com/loft-sh/devspace/pkg/util/survey"
"github.com/sirupsen/logrus"
kerrors "k8s.io/apimachinery/pkg/api/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/pkg/errors"
"github.com/spf13/cobra"
)

type localRegistryCmd struct {
*flags.GlobalFlags
}

func newLocalRegistryCmd(f factory.Factory, globalFlags *flags.GlobalFlags) *cobra.Command {
cmd := &localRegistryCmd{GlobalFlags: globalFlags}

localRegistryCmd := &cobra.Command{
Use: "local-registry",
Short: "Deletes the local image registry",
Long: `
#######################################################
######### devspace cleanup local-registry #############
#######################################################
Deletes the local image registry
#######################################################
`,
Args: cobra.NoArgs,
RunE: func(cobraCmd *cobra.Command, args []string) error {
return cmd.RunCleanupLocalRegistry(f, cobraCmd, args)
}}

return localRegistryCmd
}

// RunCleanupLocalRegistry executes the cleanup local-registry command logic
func (cmd *localRegistryCmd) RunCleanupLocalRegistry(f factory.Factory, cobraCmd *cobra.Command, args []string) error {
ctx := context.Background()
log := f.GetLog()

// set config root
configLoader, err := f.NewConfigLoader(cmd.ConfigPath)
if err != nil {
return err
}
configExists, err := configLoader.SetDevSpaceRoot(log)
if err != nil {
return err
} else if !configExists {
return errors.New(message.ConfigNotFound)
}

// create kubectl client
client, err := f.NewKubeClientFromContext(cmd.KubeContext, cmd.Namespace)
if err != nil {
log.Warnf("Unable to create new kubectl client: %v", err)
log.WriteString(logrus.WarnLevel, "\n")
client = nil
}

// load generated config
localCache, err := configLoader.LoadLocalCache()
if err != nil {
return errors.Errorf("error loading local cache: %v", err)
}

if client != nil {
// If the current kube context or namespace is different than old,
// show warnings and reset kube client if necessary
client, err = kubectl.CheckKubeContext(client, localCache, cmd.NoWarn, cmd.SwitchContext, false, log)
if err != nil {
return err
}
}

// load config
configInterface, err := configLoader.LoadWithCache(ctx, localCache, client, cmd.ToConfigOptions(), log)
if err != nil {
return err
}

// clean up registry according to options
config := configInterface.Config()
options := registry.NewDefaultOptions().
WithNamespace(client.Namespace()).
WithLocalRegistryConfig(config.LocalRegistry)

hasStatefulSet := true
_, err = client.KubeClient().AppsV1().StatefulSets(options.Namespace).Get(ctx, options.Name, v1.GetOptions{})
if err != nil {
if kerrors.IsNotFound(err) {
hasStatefulSet = false
} else {
return errors.Wrap(err, "clean up statefulset")
}
}

hasDeployment := true
_, err = client.KubeClient().AppsV1().Deployments(options.Namespace).Get(ctx, options.Name, v1.GetOptions{})
if err != nil {
if kerrors.IsNotFound(err) {
hasDeployment = false
} else {
return errors.Wrap(err, "clean up statefulset")
}
}

hasService := true
_, err = client.KubeClient().CoreV1().Services(options.Namespace).Get(ctx, options.Name, v1.GetOptions{})
if err != nil {
if kerrors.IsNotFound(err) {
hasService = false
} else {
return errors.Wrap(err, "clean up statefulset")
}
}

if !hasStatefulSet && !hasDeployment && !hasService {
log.Donef("No local registry found.")
return nil
}

// prompt user since this is a destructive action
cleanupAnswer, err := log.Question(&survey.QuestionOptions{
Question: "This will delete your local registry and all the images it contains. Do you wish to continue?",
Options: []string{
"Yes",
"No",
},
})
if err != nil {
return err
}

if cleanupAnswer == "No" {
return nil
}

if hasStatefulSet {
err = client.KubeClient().AppsV1().StatefulSets(options.Namespace).Delete(ctx, options.Name, v1.DeleteOptions{})
if err != nil && !kerrors.IsNotFound(err) {
return errors.Wrap(err, "clean up statefulset")
}
}

if hasDeployment {
err = client.KubeClient().AppsV1().Deployments(options.Namespace).Delete(ctx, options.Name, v1.DeleteOptions{})
if err != nil && !kerrors.IsNotFound(err) {
return errors.Wrap(err, "clean up deployment")
}
}

if hasService {
err = client.KubeClient().CoreV1().Services(options.Namespace).Delete(ctx, options.Name, v1.DeleteOptions{})
if err != nil && !kerrors.IsNotFound(err) {
return errors.Wrap(err, "clean up service")
}
}

log.Donef("Successfully cleaned up local registry")
return nil
}
13 changes: 13 additions & 0 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,19 @@ func annotateConfig(configPath string) error {
# tag: v1.0.0
# ui:
# path: ./ui # Path-based dependencies (for monorepos)
`)...)

annotatedConfig = append(annotatedConfig, []byte(`
# Customize local registry settings
# localRegistry:
# enabled: true # Always use local registry, remove to only use the local registry when required
# name: registry
# namespace: ${devspace.namespace} # Uses the current kube context's namespace (can be removed)
# image: registry:2.8.1
# port: 5000
# persistence:
# enabled: false
# size: 5Gi
`)...)

err = ioutil.WriteFile(configPath, annotatedConfig, os.ModePerm)
Expand Down
1 change: 1 addition & 0 deletions e2e/e2e_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
_ "github.com/loft-sh/devspace/e2e/tests/hooks"
_ "github.com/loft-sh/devspace/e2e/tests/imports"
_ "github.com/loft-sh/devspace/e2e/tests/init"
_ "github.com/loft-sh/devspace/e2e/tests/localregistry"
_ "github.com/loft-sh/devspace/e2e/tests/pipelines"
_ "github.com/loft-sh/devspace/e2e/tests/portforward"
_ "github.com/loft-sh/devspace/e2e/tests/proxycommands"
Expand Down
9 changes: 7 additions & 2 deletions e2e/tests/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package config
import (
"bytes"
"fmt"
"github.com/loft-sh/devspace/pkg/devspace/config/constants"
"io/ioutil"
"os"
"path/filepath"

"github.com/loft-sh/devspace/pkg/devspace/config/constants"

"github.com/loft-sh/devspace/pkg/devspace/config/loader"
"github.com/loft-sh/devspace/pkg/devspace/config/loader/variable"
"github.com/loft-sh/devspace/pkg/devspace/config/localcache"
Expand Down Expand Up @@ -106,8 +108,11 @@ var _ = DevSpaceDescribe("config", func() {
// read the generated.yaml
config, err := localcache.NewCacheLoader().Load(constants.DefaultConfigPath)
framework.ExpectNoError(err)

ic, _ := config.GetImageCache("app-test")
framework.ExpectLocalFileContentsImmediately(filepath.Join(tempDir, "out0.txt"), "my-docker-username/helloworld2:"+ic.Tag)
out, err := ioutil.ReadFile(filepath.Join(tempDir, "out0.txt"))
framework.ExpectNoError(err)
gomega.Expect(string(out)).To(gomega.MatchRegexp("my-docker-username/helloworld2:" + ic.Tag))
})

ginkgo.It("should load multiple profiles in order via --profile", func() {
Expand Down
8 changes: 8 additions & 0 deletions e2e/tests/localregistry/framework.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package localregistry

import "github.com/onsi/ginkgo"

// DevSpaceDescribe annotates the test with the label.
func DevSpaceDescribe(text string, body func()) bool {
return ginkgo.Describe("[localregistry] "+text, body)
}
Loading