Skip to content

Commit

Permalink
Support for "push" with "services" (#767)
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo Chico de Guzman <pchico83@gmail.com>
  • Loading branch information
pchico83 committed Mar 17, 2020
1 parent ff393d2 commit 0dc24da
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 134 deletions.
7 changes: 6 additions & 1 deletion cmd/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@ func runDown(dev *model.Dev) error {
return err
}

err = down.Run(dev, "", d, client)
trList, err := deployments.GetTranslations(dev, d, client)
if err != nil {
return err
}

err = down.Run(dev, "", d, trList, client)
if err != nil {
return err
}
Expand Down
58 changes: 46 additions & 12 deletions cmd/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,26 +111,37 @@ func runPush(dev *model.Dev, autoDeploy bool, imageTag, oktetoRegistryURL, progr
if !errors.IsNotFound(err) {
return err
}
if !autoDeploy {
if err := askIfDeploy(dev.Name, dev.Namespace); err != nil {
return err
if len(dev.Services) == 0 {
if !autoDeploy {
if err := askIfDeploy(dev.Name, dev.Namespace); err != nil {
return err
}
}
d = dev.GevSandbox()
create = true
}
}
if create {
if imageTag == "" && oktetoRegistryURL == "" {
return fmt.Errorf("you need to specify the image tag to build with the '-t' argument")
}
d = dev.GevSandbox()
create = true
}

buildKitHost, isOktetoCluster, err := build.GetBuildKitHost()
trList, err := deployments.GetTranslations(dev, d, c)
if err != nil {
return err
}
if create {
if imageTag == "" && !isOktetoCluster {
return fmt.Errorf("you need to specify the image tag to build with the '-t' argument")
}
imageFromDeployment, err := getImageFromDeployment(trList)
if err != nil {
return err
}

imageTag = build.GetImageTag(dev, imageTag, d, oktetoRegistryURL)
buildKitHost, isOktetoCluster, err := build.GetBuildKitHost()
if err != nil {
return err
}

imageTag = build.GetImageTag(dev, imageTag, imageFromDeployment, oktetoRegistryURL)
log.Infof("pushing with image tag %s", imageTag)

var imageDigest string
Expand All @@ -147,11 +158,12 @@ func runPush(dev *model.Dev, autoDeploy bool, imageTag, oktetoRegistryURL, progr
spinner.start()
defer spinner.stop()
if create {
delete(d.Annotations, model.OktetoAutoCreateAnnotation)
if err := createServiceAndDeployment(dev, d, imageTag, c); err != nil {
return err
}
} else {
err = down.Run(dev, imageTag, d, c)
err = down.Run(dev, imageTag, d, trList, c)
if err != nil {
return err
}
Expand All @@ -160,6 +172,28 @@ func runPush(dev *model.Dev, autoDeploy bool, imageTag, oktetoRegistryURL, progr
return nil
}

func getImageFromDeployment(trList map[string]*model.Translation) (string, error) {
imageFromDeployment := ""
for _, tr := range trList {
if tr.Deployment == nil {
continue
}
for _, rule := range tr.Rules {
devContainer := deployments.GetDevContainer(&tr.Deployment.Spec.Template.Spec, rule.Container)
if devContainer == nil {
return "", fmt.Errorf("container '%s' not found in deployment '%s'", rule.Container, tr.Deployment.Name)
}
if imageFromDeployment == "" {
imageFromDeployment = devContainer.Image
}
if devContainer.Image != imageFromDeployment {
return "", fmt.Errorf("cannot push code: deployments referenced by okteto manifest use different images")
}
}
}
return imageFromDeployment, nil
}

func createServiceAndDeployment(dev *model.Dev, d *appsv1.Deployment, imageTag string, c *kubernetes.Clientset) error {
d.Spec.Template.Spec.Containers[0].Image = imageTag
if err := deployments.Deploy(d, true, c); err != nil {
Expand Down
58 changes: 0 additions & 58 deletions pkg/cmd/build/buildkit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,64 +15,6 @@ package build

import "testing"

func Test_GetRepoNameWithoutTag(t *testing.T) {
var tests = []struct {
name string
image string
expected string
}{
{
name: "official-with-tag",
image: "ubuntu:2",
expected: "ubuntu",
},
{
name: "official-without-tag",
image: "ubuntu",
expected: "ubuntu",
},
{
name: "repo-with-tag",
image: "test/ubuntu:2",
expected: "test/ubuntu",
},
{
name: "repo-without-tag",
image: "test/ubuntu",
expected: "test/ubuntu",
},
{
name: "registry-with-tag",
image: "registry/gitlab.com/test/ubuntu:2",
expected: "registry/gitlab.com/test/ubuntu",
},
{
name: "registry-without-tag",
image: "registry/gitlab.com/test/ubuntu",
expected: "registry/gitlab.com/test/ubuntu",
},
{
name: "localhost-with-tag",
image: "localhost:5000/test/ubuntu:2",
expected: "localhost:5000/test/ubuntu",
},
{
name: "registry-without-tag",
image: "localhost:5000/test/ubuntu",
expected: "localhost:5000/test/ubuntu",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := GetRepoNameWithoutTag(tt.image)
if tt.expected != result {
t.Errorf("expected %s got %s in test %s", tt.expected, result, tt.name)
}
})
}

}

func Test_translateCacheHandler(t *testing.T) {
var tests = []struct {
name string
Expand Down
15 changes: 8 additions & 7 deletions pkg/cmd/build/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ import (
"strings"

"github.com/okteto/okteto/pkg/config"
"github.com/okteto/okteto/pkg/k8s/deployments"
"github.com/okteto/okteto/pkg/model"
"github.com/okteto/okteto/pkg/okteto"
appsv1 "k8s.io/api/apps/v1"
)

//GetRepoNameWithoutTag returns the image name without the tag
func GetRepoNameWithoutTag(name string) string {
var domain, remainder string
i := strings.IndexRune(name, '/')
i := strings.IndexRune(name, '@')
if i != -1 {
return name[:i]
}
i = strings.IndexRune(name, '/')
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
domain, remainder = "", name
} else {
Expand All @@ -49,16 +51,15 @@ func GetRepoNameWithoutTag(name string) string {
}

//GetImageTag returns the image taag to build and push
func GetImageTag(dev *model.Dev, imageTag string, d *appsv1.Deployment, oktetoRegistryURL string) string {
func GetImageTag(dev *model.Dev, imageTag, imageFromDeployment, oktetoRegistryURL string) string {
if imageTag != "" {
return imageTag
}
if oktetoRegistryURL != "" {
return fmt.Sprintf("%s/%s/%s:okteto", oktetoRegistryURL, dev.Namespace, dev.Name)
}
devContainer := deployments.GetDevContainer(&d.Spec.Template.Spec, dev.Container)
imageWithoutTag := GetRepoNameWithoutTag(devContainer.Image)
return fmt.Sprintf("%s:%s", imageWithoutTag, string(d.UID))
imageWithoutTag := GetRepoNameWithoutTag(imageFromDeployment)
return fmt.Sprintf("%s:okteto", imageWithoutTag)
}

func getDockerfileWithCacheHandler(filename string) (string, error) {
Expand Down
143 changes: 93 additions & 50 deletions pkg/cmd/build/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,72 +18,115 @@ import (

"github.com/okteto/okteto/pkg/model"
"github.com/okteto/okteto/pkg/okteto"
appsv1 "k8s.io/api/apps/v1"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

func Test_GetRepoNameWithoutTag(t *testing.T) {
var tests = []struct {
name string
image string
expected string
}{
{
name: "official-with-tag",
image: "ubuntu:2",
expected: "ubuntu",
},
{
name: "official-without-tag",
image: "ubuntu",
expected: "ubuntu",
},
{
name: "repo-with-tag",
image: "test/ubuntu:2",
expected: "test/ubuntu",
},
{
name: "repo-without-tag",
image: "test/ubuntu",
expected: "test/ubuntu",
},
{
name: "registry-with-tag",
image: "registry/gitlab.com/test/ubuntu:2",
expected: "registry/gitlab.com/test/ubuntu",
},
{
name: "registry-without-tag",
image: "registry/gitlab.com/test/ubuntu",
expected: "registry/gitlab.com/test/ubuntu",
},
{
name: "localhost-with-tag",
image: "localhost:5000/test/ubuntu:2",
expected: "localhost:5000/test/ubuntu",
},
{
name: "registry-without-tag",
image: "localhost:5000/test/ubuntu",
expected: "localhost:5000/test/ubuntu",
},
{
name: "sha256",
image: "pchico83/test@sha256:e78ad0d316485b7dbffa944a92b29ea4fa26d53c63054605c4fb7a8b787a673c",
expected: "pchico83/test",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := GetRepoNameWithoutTag(tt.image)
if tt.expected != result {
t.Errorf("expected %s got %s in test %s", tt.expected, result, tt.name)
}
})
}
}

func Test_GetImageTag(t *testing.T) {
var tests = []struct {
name string
dev *model.Dev
imageTag string
d *appsv1.Deployment
oktetoRegistryURL string
expected string
name string
dev *model.Dev
imageTag string
imageFromDeployment string
oktetoRegistryURL string
expected string
}{
{
name: "imageTag-not-in-okteto",
dev: &model.Dev{Name: "dev", Namespace: "ns"},
imageTag: "imageTag",
d: &appsv1.Deployment{},
oktetoRegistryURL: "",
expected: "imageTag",
name: "imageTag-not-in-okteto",
dev: &model.Dev{Name: "dev", Namespace: "ns"},
imageTag: "imageTag",
imageFromDeployment: "",
oktetoRegistryURL: "",
expected: "imageTag",
},
{
name: "imageTag-in-okteto",
dev: &model.Dev{Name: "dev", Namespace: "ns"},
imageTag: "imageTag",
d: &appsv1.Deployment{},
oktetoRegistryURL: okteto.CloudRegistryURL,
expected: "imageTag",
name: "imageTag-in-okteto",
dev: &model.Dev{Name: "dev", Namespace: "ns"},
imageTag: "imageTag",
imageFromDeployment: "",
oktetoRegistryURL: okteto.CloudRegistryURL,
expected: "imageTag",
},
{
name: "okteto",
dev: &model.Dev{Name: "dev", Namespace: "ns"},
imageTag: "",
d: &appsv1.Deployment{},
oktetoRegistryURL: okteto.CloudRegistryURL,
expected: "registry.cloud.okteto.net/ns/dev:okteto",
name: "okteto",
dev: &model.Dev{Name: "dev", Namespace: "ns"},
imageTag: "",
imageFromDeployment: "",
oktetoRegistryURL: okteto.CloudRegistryURL,
expected: "registry.cloud.okteto.net/ns/dev:okteto",
},
{
name: "not-in-okteto",
dev: &model.Dev{Name: "dev", Namespace: "ns"},
imageTag: "",
d: &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
UID: types.UID("uuid"),
},
Spec: appsv1.DeploymentSpec{
Template: apiv1.PodTemplateSpec{
Spec: apiv1.PodSpec{
Containers: []apiv1.Container{
{
Image: "okteto/test:2",
},
},
},
},
},
},
oktetoRegistryURL: "",
expected: "okteto/test:uuid",
name: "not-in-okteto",
dev: &model.Dev{Name: "dev", Namespace: "ns"},
imageTag: "",
imageFromDeployment: "okteto/test:2",
oktetoRegistryURL: "",
expected: "okteto/test:okteto",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := GetImageTag(tt.dev, tt.imageTag, tt.d, tt.oktetoRegistryURL)
result := GetImageTag(tt.dev, tt.imageTag, tt.imageFromDeployment, tt.oktetoRegistryURL)
if tt.expected != result {
t.Errorf("expected %s got %s in test %s", tt.expected, result, tt.name)
}
Expand Down

0 comments on commit 0dc24da

Please sign in to comment.