Skip to content

Commit

Permalink
Add env property on Registry (#277)
Browse files Browse the repository at this point in the history
* feat: implement env properties on registries

Signed-off-by: Nicolas COLLET <MalibuKoKo@users.noreply.github.com>

* test(ContainerInspect): add & fill up Config prop in mocked function

Signed-off-by: Nicolas COLLET <MalibuKoKo@users.noreply.github.com>

* test(registry_test.go): implement function TestCustomEnv

Signed-off-by: Nicolas COLLET <MalibuKoKo@users.noreply.github.com>

* fix var variable assignment

Signed-off-by: Nicolas COLLET <MalibuKoKo@users.noreply.github.com>

---------

Signed-off-by: Nicolas COLLET <MalibuKoKo@users.noreply.github.com>
  • Loading branch information
MalibuKoKo authored Feb 24, 2023
1 parent de62eb9 commit 319f726
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 1 deletion.
8 changes: 8 additions & 0 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ type Registry struct {
// that are tagged "app: k3d".
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`

// Environment vars to use for registry container (optional).
//
// Can be used to change some parameters likes REGISTRY_HTTP_ADDR, REGISTRY_PROXY_REMOTEURL
Env []string `json:"env,omitempty" yaml:"env,omitempty"`

// Image to use for registry container (optional).
//
// Can be used to provide an alternate image or use a different registry
Expand Down Expand Up @@ -223,6 +228,9 @@ type RegistryStatus struct {
// Labels attached to the running container.
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`

// Env attached to the running container.
Env []string `json:"env,omitempty" yaml:"env,omitempty"`

// Image for the running container.
Image string `json:"image,omitempty" yaml:"image,omitempty"`
}
Expand Down
42 changes: 41 additions & 1 deletion pkg/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"sort"
"strings"
"time"
"regexp"
"reflect"

"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
Expand Down Expand Up @@ -132,6 +134,11 @@ func (c *Controller) List(ctx context.Context, options ListOptions) (*api.Regist
name := strings.TrimPrefix(container.Names[0], "/")
created := time.Unix(container.Created, 0)

inspect, err := c.dockerClient.ContainerInspect(ctx, container.ID)
if err != nil {
return nil, err
}
env := inspect.Config.Env
netSummary := container.NetworkSettings
ipAddress := ""
networks := []string{}
Expand Down Expand Up @@ -163,6 +170,7 @@ func (c *Controller) List(ctx context.Context, options ListOptions) (*api.Regist
State: container.State,
Labels: container.Labels,
Image: container.Image,
Env: env,
},
}

Expand Down Expand Up @@ -218,6 +226,38 @@ func (c *Controller) Apply(ctx context.Context, desired *api.Registry) (*api.Reg
needsDelete = true
}
}

r := regexp.MustCompile("^(?P<key>[^=]+)=(?P<value>.*)")
desiredEnvs := make(map[string]string)
for _, value := range desired.Env {
m := r.FindStringSubmatch(value)
if m != nil {
k := m[r.SubexpIndex("key")]
v := m[r.SubexpIndex("value")]
if k != "PATH" {
desiredEnvs[k] = v
}
}
}
existingEnvs := make(map[string]string)
for _, value := range existing.Status.Env {
m := r.FindStringSubmatch(value)
if m != nil {
k := m[r.SubexpIndex("key")]
v := m[r.SubexpIndex("value")]
if k != "PATH" {
existingEnvs[k] = v
}
}
}
if _, ok := desiredEnvs["REGISTRY_STORAGE_DELETE_ENABLED"]; ! ok {
desiredEnvs["REGISTRY_STORAGE_DELETE_ENABLED"] = "true"
desired.Env = append(desired.Env, "REGISTRY_STORAGE_DELETE_ENABLED=true")
}
if eq := reflect.DeepEqual(desiredEnvs, existingEnvs); ! eq {
needsDelete = true
}

if needsDelete && existing.Name != "" {
err = c.Delete(ctx, existing.Name)
if err != nil {
Expand Down Expand Up @@ -253,7 +293,7 @@ func (c *Controller) Apply(ctx context.Context, desired *api.Registry) (*api.Reg
Image: desired.Image,
ExposedPorts: exposedPorts,
Labels: c.labelConfigs(existing, desired),
Env: []string{"REGISTRY_STORAGE_DELETE_ENABLED=true"},
Env: desired.Env,
},
&container.HostConfig{
RestartPolicy: container.RestartPolicy{Name: "always"},
Expand Down
72 changes: 72 additions & 0 deletions pkg/registry/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ func TestListRegistries(t *testing.T) {
State: "running",
Labels: map[string]string{"dev.tilt.ctlptl.role": "registry"},
Image: "registry:2",
Env: []string{"REGISTRY_STORAGE_DELETE_ENABLED=true","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
},
}, list.Items[0])
assert.Equal(t, api.Registry{
Expand All @@ -155,6 +156,7 @@ func TestListRegistries(t *testing.T) {
State: "running",
Labels: map[string]string{"dev.tilt.ctlptl.role": "registry"},
Image: "fake.tilt.dev/my-registry-image:latest",
Env: []string{"REGISTRY_STORAGE_DELETE_ENABLED=true","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
},
}, list.Items[1])
assert.Equal(t, api.Registry{
Expand All @@ -171,6 +173,7 @@ func TestListRegistries(t *testing.T) {
ContainerID: "d62f2587ff7b03858f144d3cf83c789578a6d6403f8b82a459ab4e317917cd42",
State: "running",
Image: "registry:2",
Env: []string{"REGISTRY_STORAGE_DELETE_ENABLED=true","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
},
}, list.Items[2])
}
Expand Down Expand Up @@ -198,6 +201,7 @@ func TestGetRegistry(t *testing.T) {
State: "running",
Labels: map[string]string{"dev.tilt.ctlptl.role": "registry"},
Image: "registry:2",
Env: []string{"REGISTRY_STORAGE_DELETE_ENABLED=true","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
},
}, registry)
}
Expand Down Expand Up @@ -326,6 +330,47 @@ func TestCustomImage(t *testing.T) {
}
}

func TestCustomEnv(t *testing.T) {
f := newFixture(t)
defer f.TearDown()

// Make sure the previous registry is wiped out
// because it doesn't have the image we want.
f.docker.containers = []types.Container{kindRegistry()}

f.docker.onCreate = func() {
f.docker.containers = []types.Container{kindRegistry()}
}

// ensure stable w/o image change
_, err := f.c.Apply(context.Background(), &api.Registry{
TypeMeta: typeMeta,
Name: "kind-registry",
Image: "registry:2",
})
if assert.NoError(t, err) {
assert.Nil(t, f.docker.lastCreateConfig, "Registry should not have been re-created")
}

// change env, should be (re)created
registry, err := f.c.Apply(context.Background(), &api.Registry{
TypeMeta: typeMeta,
Name: "kind-registry",
Image: "registry:2",
Env: []string{"REGISTRY_STORAGE_DELETE_ENABLED=false"},
})
if assert.NoError(t, err) {
assert.Equal(t, "running", registry.Status.State)
}
config := f.docker.lastCreateConfig
if assert.NotNil(t, config) {
assert.Equal(t, map[string]string{"dev.tilt.ctlptl.role": "registry"}, config.Labels)
assert.Equal(t, "kind-registry", config.Hostname)
assert.Equal(t, "registry:2", config.Image)
assert.Equal(t, []string{"REGISTRY_STORAGE_DELETE_ENABLED=false"}, config.Env)
}
}

type fakeDocker struct {
containers []types.Container
lastRemovedContainer string
Expand Down Expand Up @@ -358,6 +403,33 @@ func (d *fakeDocker) ContainerInspect(ctx context.Context, containerID string) (
Running: c.State == "running",
},
},
Config: &container.Config{
Hostname:"test",
Domainname:"",
User:"",
AttachStdin:false,
AttachStdout:false,
AttachStderr:false,
// ExposedPorts:nat.PortSet{"5000/tcp":struct {}{}},
Tty:false,
OpenStdin:false,
StdinOnce:false,
Env:[]string{"REGISTRY_STORAGE_DELETE_ENABLED=true", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
Cmd:[]string{"/etc/docker/registry/config.yml"},
Healthcheck:(*container.HealthConfig)(nil),
ArgsEscaped:false,
Image:"docker.io/library/registry:2",
Volumes:map[string]struct {}{"/var/lib/registry":struct {}{}},
WorkingDir:"",
Entrypoint:[]string{"/entrypoint.sh"},
NetworkDisabled:false,
MacAddress:"",
OnBuild:[]string(nil),
Labels:map[string]string{"dev.tilt.ctlptl.role":"registry"},
StopSignal:"",
StopTimeout:(*int)(nil),
Shell:[]string(nil),
},
}, nil
}
}
Expand Down

0 comments on commit 319f726

Please sign in to comment.