Skip to content

Commit

Permalink
k8s: implement the local registry discovery protocol. Fixes #3435
Browse files Browse the repository at this point in the history
  • Loading branch information
nicks committed Jun 12, 2020
1 parent 71fcb58 commit 776ebc9
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 10 deletions.
53 changes: 43 additions & 10 deletions internal/k8s/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"net"
"sync"

_ "github.com/tilt-dev/localregistry-go"
"github.com/tilt-dev/localregistry-go"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
apiv1 "k8s.io/client-go/kubernetes/typed/core/v1"
Expand Down Expand Up @@ -144,8 +144,35 @@ func (r *registryAsync) inferRegistryFromNodeAnnotations(ctx context.Context) co
return container.Registry{}
}

// Implements the local registry discovery standard.
func (r *registryAsync) inferRegistryFromConfigMap(ctx context.Context) (registry container.Registry, help string) {
hosting, err := localregistry.Discover(ctx, r.core)
if err != nil {
logger.Get(ctx).Warnf("Local registry discovery error: %v", err)
return container.Registry{}, ""
}

if hosting.Host == "" {
return container.Registry{}, hosting.Help
}

registry, err = container.NewRegistryWithHostFromCluster(
hosting.Host, hosting.HostFromContainerRuntime)
if err != nil {
logger.Get(ctx).Warnf("Local registry discovery error: %v", err)
return container.Registry{}, hosting.Help
}
return registry, hosting.Help
}

func (r *registryAsync) Registry(ctx context.Context) container.Registry {
r.once.Do(func() {
reg, help := r.inferRegistryFromConfigMap(ctx)
if !reg.Empty() {
r.registry = reg
return
}

// Auto-infer the microk8s local registry.
if r.env == EnvMicroK8s {
reg := r.inferRegistryFromMicrok8s(ctx)
Expand All @@ -155,19 +182,25 @@ func (r *registryAsync) Registry(ctx context.Context) container.Registry {
}
}

reg := r.inferRegistryFromNodeAnnotations(ctx)
reg = r.inferRegistryFromNodeAnnotations(ctx)
if !reg.Empty() {
r.registry = reg
}

if r.env == EnvKIND6 && r.registry.Empty() {
logger.Get(ctx).Warnf("You are running Kind without a local image registry.\n" +
"Tilt can use the local registry to speed up builds.\n" +
"Instructions: https://github.com/tilt-dev/kind-local")
} else if r.env == EnvK3D && r.registry.Empty() {
logger.Get(ctx).Warnf("You are running K3D without a local image registry.\n" +
"Tilt can use the local registry to speed up builds.\n" +
"Instructions: https://github.com/tilt-dev/k3d-local-registry")
if r.registry.Empty() {
if help != "" {
logger.Get(ctx).Warnf("You are running without a local image registry.\n"+
"Tilt can use the local registry to speed up builds.\n"+
"Instructions: %s", help)
} else if r.env == EnvKIND6 {
logger.Get(ctx).Warnf("You are running Kind without a local image registry.\n" +
"Tilt can use the local registry to speed up builds.\n" +
"Instructions: https://github.com/tilt-dev/kind-local")
} else if r.env == EnvK3D {
logger.Get(ctx).Warnf("You are running K3D without a local image registry.\n" +
"Tilt can use the local registry to speed up builds.\n" +
"Instructions: https://github.com/tilt-dev/k3d-local-registry")
}
}
})
return r.registry
Expand Down
61 changes: 61 additions & 0 deletions internal/k8s/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/tilt-dev/tilt/pkg/logger"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
Expand Down Expand Up @@ -89,6 +90,57 @@ func TestRegistryFoundInKindAnnotations(t *testing.T) {
assert.Equal(t, "localhost:5000", registry.Host)
}

func TestLocalRegistryDiscoveryHelp(t *testing.T) {
cs := &fake.Clientset{}
tracker := ktesting.NewObjectTracker(scheme.Scheme, scheme.Codecs.UniversalDecoder())
cs.AddReactor("*", "*", ktesting.ObjectReaction(tracker))
err := addConfigMap(tracker, `
apiVersion: v1
kind: ConfigMap
metadata:
name: local-registry-hosting
namespace: kube-public
data:
localRegistryHosting.v1: |
help: "https://fake-domain.tilt.dev/local-registry-help"
`)
require.NoError(t, err)

core := cs.CoreV1()
registryAsync := newRegistryAsync(EnvKIND6, core, NewNaiveRuntimeSource(container.RuntimeContainerd))

out := bytes.NewBuffer(nil)
registry := registryAsync.Registry(newLoggerCtx(out))
assert.True(t, registry.Empty())
assert.Contains(t, out.String(), "https://fake-domain.tilt.dev/local-registry-help")
}

func TestLocalRegistryDiscoveryHost(t *testing.T) {
cs := &fake.Clientset{}
tracker := ktesting.NewObjectTracker(scheme.Scheme, scheme.Codecs.UniversalDecoder())
cs.AddReactor("*", "*", ktesting.ObjectReaction(tracker))
err := addConfigMap(tracker, `
apiVersion: v1
kind: ConfigMap
metadata:
name: local-registry-hosting
namespace: kube-public
data:
localRegistryHosting.v1: |
host: "localhost:5000"
hostFromContainerRuntime: "registry:5000"
help: "https://fake-domain.tilt.dev/local-registry-help"
`)
require.NoError(t, err)

core := cs.CoreV1()
registryAsync := newRegistryAsync(EnvKIND6, core, NewNaiveRuntimeSource(container.RuntimeContainerd))

registry := registryAsync.Registry(newLoggerCtx(os.Stdout))
assert.Equal(t, "localhost:5000", registry.Host)
assert.Equal(t, "registry:5000", registry.HostFromCluster())
}

func TestKINDWarning(t *testing.T) {
cs := &fake.Clientset{}
core := cs.CoreV1()
Expand Down Expand Up @@ -156,3 +208,12 @@ func newLoggerCtx(w io.Writer) context.Context {
ctx := logger.WithLogger(context.Background(), l)
return ctx
}

func addConfigMap(tracker ktesting.ObjectTracker, configMap string) error {
obj, _, err :=
scheme.Codecs.UniversalDeserializer().Decode([]byte(configMap), nil, nil)
if err != nil {
return err
}
return tracker.Add(obj)
}

0 comments on commit 776ebc9

Please sign in to comment.