Skip to content

Commit

Permalink
[installer]: add DropImageRepo functionality to RepoName
Browse files Browse the repository at this point in the history
This moves the ImageName and RepoName functions to the RenderContext
struct.
  • Loading branch information
Simon Emms committed Apr 19, 2022
1 parent 6f7798c commit 29a68b3
Show file tree
Hide file tree
Showing 31 changed files with 220 additions and 141 deletions.
2 changes: 1 addition & 1 deletion install/installer/pkg/common/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func InternalCAContainer(ctx *RenderContext, mod ...func(*corev1.Container)) *co
res := &corev1.Container{
Name: "update-ca-certificates",
// It's not possible to use images based on alpine due to errors running update-ca-certificates
Image: ImageName(ctx.Config.Repository, "ca-updater", ctx.VersionManifest.Components.CAUpdater.Version),
Image: ctx.ImageName(ctx.Config.Repository, "ca-updater", ctx.VersionManifest.Components.CAUpdater.Version),
ImagePullPolicy: corev1.PullIfNotPresent,
Command: []string{
"bash", "-c",
Expand Down
34 changes: 3 additions & 31 deletions install/installer/pkg/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
config "github.com/gitpod-io/gitpod/installer/pkg/config/v1"
"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"

"github.com/docker/distribution/reference"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
Expand Down Expand Up @@ -248,7 +247,7 @@ func DatabaseEnv(cfg *config.Config) (res []corev1.EnvVar) {
func DatabaseWaiterContainer(ctx *RenderContext) *corev1.Container {
return &corev1.Container{
Name: "database-waiter",
Image: ImageName(ctx.Config.Repository, "service-waiter", ctx.VersionManifest.Components.ServiceWaiter.Version),
Image: ctx.ImageName(ctx.Config.Repository, "service-waiter", ctx.VersionManifest.Components.ServiceWaiter.Version),
Args: []string{
"-v",
"database",
Expand All @@ -266,7 +265,7 @@ func DatabaseWaiterContainer(ctx *RenderContext) *corev1.Container {
func MessageBusWaiterContainer(ctx *RenderContext) *corev1.Container {
return &corev1.Container{
Name: "msgbus-waiter",
Image: ImageName(ctx.Config.Repository, "service-waiter", ctx.VersionManifest.Components.ServiceWaiter.Version),
Image: ctx.ImageName(ctx.Config.Repository, "service-waiter", ctx.VersionManifest.Components.ServiceWaiter.Version),
Args: []string{
"-v",
"messagebus",
Expand All @@ -284,7 +283,7 @@ func MessageBusWaiterContainer(ctx *RenderContext) *corev1.Container {
func KubeRBACProxyContainer(ctx *RenderContext) *corev1.Container {
return &corev1.Container{
Name: "kube-rbac-proxy",
Image: ImageName(ThirdPartyContainerRepo(ctx.Config.Repository, KubeRBACProxyRepo), KubeRBACProxyImage, KubeRBACProxyTag),
Image: ctx.ImageName(ThirdPartyContainerRepo(ctx.Config.Repository, KubeRBACProxyRepo), KubeRBACProxyImage, KubeRBACProxyTag),
Args: []string{
"--v=5",
"--logtostderr",
Expand Down Expand Up @@ -339,33 +338,6 @@ func Affinity(orLabels ...string) *corev1.Affinity {
}
}

func RepoName(repo, name string) string {
var ref string
if repo == "" {
ref = name
} else {
ref = fmt.Sprintf("%s/%s", strings.TrimSuffix(repo, "/"), name)
}
pref, err := reference.ParseNormalizedNamed(ref)
if err != nil {
panic(fmt.Sprintf("cannot parse image repo %s: %v", ref, err))
}
return pref.String()
}

func ImageName(repo, name, tag string) string {
ref := fmt.Sprintf("%s:%s", RepoName(repo, name), tag)
pref, err := reference.ParseNamed(ref)
if err != nil {
panic(fmt.Sprintf("cannot parse image ref %s: %v", ref, err))
}
if _, ok := pref.(reference.Tagged); !ok {
panic(fmt.Sprintf("image ref %s has no tag: %v", ref, err))
}

return ref
}

// ObjectHash marshals the objects to YAML and produces a sha256 hash of the output.
// This function is useful for restarting pods when the config changes.
// Takes an error as argument to make calling it more conventient. If that error is not nil,
Expand Down
63 changes: 0 additions & 63 deletions install/installer/pkg/common/common_test.go

This file was deleted.

42 changes: 42 additions & 0 deletions install/installer/pkg/common/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@
package common

import (
"fmt"
"strings"

"github.com/docker/distribution/reference"
"github.com/gitpod-io/gitpod/installer/pkg/config/v1"
"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"
"github.com/gitpod-io/gitpod/installer/pkg/config/versions"

"helm.sh/helm/v3/pkg/cli/values"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"
)

// Renderable turns the config into a set of Kubernetes runtime objects
Expand Down Expand Up @@ -85,6 +90,43 @@ func (r *RenderContext) WithExperimental(mod func(ucfg *experimental.Config) err
return mod(r.experimentalConfig)
}

func (r *RenderContext) RepoName(repo, name string) string {
var ref string
if repo == "" {
ref = name
} else {
ref = fmt.Sprintf("%s/%s", strings.TrimSuffix(repo, "/"), name)
}
pref, err := reference.ParseNormalizedNamed(ref)
if err != nil {
panic(fmt.Sprintf("cannot parse image repo %s: %v", ref, err))
}

if pointer.BoolDeref(r.Config.DropImageRepo, false) {
if r.Config.Repository == GitpodContainerRegistry {
panic(fmt.Errorf("cannot remove image repo whilst using the default repository"))
}

segs := strings.Split(reference.Path(pref), "/")
return fmt.Sprintf("%s/%s", r.Config.Repository, segs[len(segs)-1])
}

return pref.String()
}

func (r *RenderContext) ImageName(repo, name, tag string) string {
ref := fmt.Sprintf("%s:%s", r.RepoName(repo, name), tag)
pref, err := reference.ParseNamed(ref)
if err != nil {
panic(fmt.Sprintf("cannot parse image ref %s: %v", ref, err))
}
if _, ok := pref.(reference.Tagged); !ok {
panic(fmt.Sprintf("image ref %s has no tag: %v", ref, err))
}

return ref
}

// generateValues generates the random values used throughout the context
// todo(sje): find a way of persisting these values for updates
func (r *RenderContext) generateValues() error {
Expand Down
128 changes: 127 additions & 1 deletion install/installer/pkg/common/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
package common

import (
"testing"

"github.com/gitpod-io/gitpod/installer/pkg/config/v1"
"github.com/gitpod-io/gitpod/installer/pkg/config/versions"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime"
"testing"
"k8s.io/utils/pointer"
)

func TestCompositeRenderFunc_NilObjectsNilError(t *testing.T) {
Expand All @@ -24,3 +27,126 @@ func TestCompositeRenderFunc_NilObjectsNilError(t *testing.T) {
require.NoError(t, err)
require.Len(t, objects, 0)
}

func TestRepoName(t *testing.T) {
type Expectation struct {
Result string
Panics bool
}
tests := []struct {
Repo string
Name string
Expectation Expectation
CfgRepo string
DropImageRepo *bool
}{
{
Name: "gitpod-io/workspace-full",
Expectation: Expectation{
Result: "docker.io/gitpod-io/workspace-full",
},
},
{
Repo: "some-repo.com",
Name: "some-image",
Expectation: Expectation{
Result: "some-repo.com/some-image",
},
},
{
Repo: "some-repo",
Name: "not@avalid#image-name",
Expectation: Expectation{
Panics: true,
},
},
{
Repo: "some-repo.com",
Name: "some-image",
Expectation: Expectation{
Panics: true,
},
CfgRepo: GitpodContainerRegistry,
DropImageRepo: pointer.Bool(true),
},
// Drop repo, no namespace
{
Name: "gitpod-io/workspace-full",
Expectation: Expectation{
Result: "some.registry.com/workspace-full",
},
CfgRepo: "some.registry.com",
DropImageRepo: pointer.Bool(true),
},
{
Repo: "some-repo.com",
Name: "some-image",
Expectation: Expectation{
Result: "some.registry.com/some-image",
},
CfgRepo: "some.registry.com",
DropImageRepo: pointer.Bool(true),
},
{
Repo: "some-repo",
Name: "not@avalid#image-name",
Expectation: Expectation{
Panics: true,
},
CfgRepo: "some.registry.com",
DropImageRepo: pointer.Bool(true),
},
// Drop repo, namespace
{
Name: "gitpod-io/workspace-full",
Expectation: Expectation{
Result: "some.registry.com/gitpod/workspace-full",
},
CfgRepo: "some.registry.com/gitpod",
DropImageRepo: pointer.Bool(true),
},
{
Repo: "some-repo.com",
Name: "some-image",
Expectation: Expectation{
Result: "some.registry.com/gitpod/some-image",
},
CfgRepo: "some.registry.com/gitpod",
DropImageRepo: pointer.Bool(true),
},
{
Repo: "some-repo",
Name: "not@avalid#image-name",
Expectation: Expectation{
Panics: true,
},
CfgRepo: "some.registry.com/gitpod",
DropImageRepo: pointer.Bool(true),
},
}

for _, test := range tests {
t.Run(test.Repo+"/"+test.Name, func(t *testing.T) {
var act Expectation
func() {
defer func() {
if recover() != nil {
act.Panics = true
}
}()

ctx, err := NewRenderContext(config.Config{
DropImageRepo: test.DropImageRepo,
Repository: test.CfgRepo,
}, versions.Manifest{}, "test_namespace")
require.NoError(t, err)

act.Result = ctx.RepoName(test.Repo, test.Name)
}()

if diff := cmp.Diff(test.Expectation, act); diff != "" {
t.Errorf("RepoName() mismatch (-want +got):\n%s", diff)
}
})
}
}
2 changes: 1 addition & 1 deletion install/installer/pkg/components/agent-smith/daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func daemonset(ctx *common.RenderContext) ([]runtime.Object, error) {
TerminationGracePeriodSeconds: pointer.Int64(30),
Containers: []corev1.Container{{
Name: Component,
Image: common.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.AgentSmith.Version),
Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.AgentSmith.Version),
ImagePullPolicy: corev1.PullIfNotPresent,
Args: []string{"run", "--config", "/config/config.json"},
Resources: corev1.ResourceRequirements{
Expand Down
4 changes: 2 additions & 2 deletions install/installer/pkg/components/blobserve/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Port: ContainerPort,
Timeout: util.Duration(time.Second * 5),
Repos: map[string]blobserve.Repo{
common.RepoName(ctx.Config.Repository, ide.CodeIDEImage): {
ctx.RepoName(ctx.Config.Repository, ide.CodeIDEImage): {
PrePull: []string{},
Workdir: "/ide",
Replacements: []blobserve.StringReplacement{{
Expand Down Expand Up @@ -88,7 +88,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
Replacement: "${supervisor}",
}},
},
common.RepoName(ctx.Config.Repository, workspace.SupervisorImage): {
ctx.RepoName(ctx.Config.Repository, workspace.SupervisorImage): {
PrePull: []string{},
Workdir: "/.supervisor/frontend",
},
Expand Down
2 changes: 1 addition & 1 deletion install/installer/pkg/components/blobserve/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func deployment(ctx *common.RenderContext) ([]runtime.Object, error) {
Containers: []corev1.Container{{
Name: Component,
Args: []string{"run", "/mnt/config/config.json"},
Image: common.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.Blobserve.Version),
Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.Blobserve.Version),
ImagePullPolicy: corev1.PullIfNotPresent,
Ports: []corev1.ContainerPort{{
Name: ServicePortName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func deployment(ctx *common.RenderContext) ([]runtime.Object, error) {
}},
Containers: []corev1.Container{{
Name: Component,
Image: common.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.ContentService.Version),
Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.ContentService.Version),
ImagePullPolicy: corev1.PullIfNotPresent,
Args: []string{
"run",
Expand Down
Loading

0 comments on commit 29a68b3

Please sign in to comment.