Skip to content

Commit

Permalink
feat(issue-24): Refactor Docker Image attributes and add files for kn…
Browse files Browse the repository at this point in the history
…ative templating (#32)

Co-authored-by: Aman Vivek Ramkumar <aman.ramkumar@nearform.com>
  • Loading branch information
zimny and amanvr authored May 23, 2023
1 parent e66b2f4 commit 04e43fe
Show file tree
Hide file tree
Showing 17 changed files with 181 additions and 120 deletions.
13 changes: 0 additions & 13 deletions assets/knative/service.yaml

This file was deleted.

10 changes: 10 additions & 0 deletions assets/knative/service.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: {{ .Name }}
namespace: default
spec:
template:
spec:
containers:
- image: {{ .RemoteTag }}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/a8m/envsubst v1.4.2 // indirect
github.com/blendle/zapdriver v1.3.1 // indirect
github.com/containerd/containerd v1.7.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2y
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/Microsoft/hcsshim v0.10.0-rc.7 h1:HBytQPxcv8Oy4244zbQbe6hnOnx544eL5QPUqhJldz8=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/a8m/envsubst v1.4.2 h1:4yWIHXOLEJHQEFd4UjrWDrYeYlV7ncFWJOCBRLOZHQg=
github.com/a8m/envsubst v1.4.2/go.mod h1:MVUTQNGQ3tsjOOtKCNd+fl8RzhsXcDvvAEzkhGtlsbY=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
Expand Down
17 changes: 4 additions & 13 deletions src/cli/build.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
package cli

import (
"fmt"
"path"

"github.com/nearform/k8s-kurated-addons-cli/src/services/docker"
"github.com/nearform/k8s-kurated-addons-cli/src/utils/logger"
"github.com/urfave/cli/v2"
)

func (c CLI) Build(cCtx *cli.Context) error {
repoName := cCtx.String("repo-name")
dockerFileName := cCtx.String("dockerfile-name")
project := c.newProject(cCtx)
docker, err := docker.New(project, dockerFileName, repoName)
if err != nil {
return fmt.Errorf("Creating docker service: %v", err)
}

logger.PrintInfo("Dockerfile Location: " + path.Join(project.Directory, docker.DockerFileName))
return docker.Build()
func (c *CLI) Build(cCtx *cli.Context) error {
project := c.getProject(cCtx)
logger.PrintInfo("Dockerfile Location: " + path.Join(project.Directory, c.DockerService.DockerFileName))
return c.DockerService.Build()
}

func (c CLI) BuildCMD() *cli.Command {
Expand Down
49 changes: 42 additions & 7 deletions src/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,59 @@ import (

"github.com/nearform/k8s-kurated-addons-cli/src/services/project"

"github.com/nearform/k8s-kurated-addons-cli/src/services/docker"
"github.com/nearform/k8s-kurated-addons-cli/src/utils/defaults"
"github.com/nearform/k8s-kurated-addons-cli/src/utils/logger"

"github.com/urfave/cli/v2"
)

type CLI struct {
Resources embed.FS
CWD string
Resources embed.FS
CWD string
DockerService docker.DockerService
project project.Project
dockerImage docker.DockerImage
}

func (c CLI) newProject(cCtx *cli.Context) project.Project {
return project.New(
cCtx.String("app-name"),
cCtx.String("project-directory"),
func (c *CLI) init(cCtx *cli.Context) {

repoName := cCtx.String("repo-name")
dockerFileName := cCtx.String("dockerfile-name")
appName := cCtx.String("app-name")
version := cCtx.String("app-version")
projectDirectory := cCtx.String("project-directory")

project := project.New(
appName,
projectDirectory,
cCtx.String("runtime-version"),
cCtx.String("app-version"),
version,
c.Resources,
)

dockerImage := docker.DockerImage{
Registry: repoName,
Name: appName,
Directory: projectDirectory,
Tag: version,
}

dockerService, err := docker.New(project, dockerImage, dockerFileName)
if err != nil {
logger.PrintError("Error creating docker service", err)
}

c.DockerService = dockerService
c.dockerImage = dockerImage
c.project = project
}

func (c *CLI) getProject(cCtx *cli.Context) *project.Project {
if (c.project == project.Project{}) {
c.init(cCtx)
}
return &c.project
}

func (c CLI) Run() {
Expand Down
6 changes: 3 additions & 3 deletions src/cli/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"github.com/urfave/cli/v2"
)

func (c CLI) Delete(cCtx *cli.Context) error {
func (c *CLI) Delete(cCtx *cli.Context) error {
config, err := knative.Config(
cCtx.String("endpoint"),
cCtx.String("token"),
Expand All @@ -14,11 +14,11 @@ func (c CLI) Delete(cCtx *cli.Context) error {
if err != nil {
return err
}
project := c.newProject(cCtx)
project := c.getProject(cCtx)
return knative.Clean(config, project)
}

func (c CLI) DeleteCMD() *cli.Command {
func (c *CLI) DeleteCMD() *cli.Command {
return &cli.Command{
Name: "delete",
Usage: "delete the knative service",
Expand Down
6 changes: 3 additions & 3 deletions src/cli/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"github.com/urfave/cli/v2"
)

func (c CLI) Deploy(cCtx *cli.Context) error {
func (c *CLI) Deploy(cCtx *cli.Context) error {
config, err := knative.Config(
cCtx.String("endpoint"),
cCtx.String("token"),
Expand All @@ -15,9 +15,9 @@ func (c CLI) Deploy(cCtx *cli.Context) error {
if err != nil {
return err
}
project := c.newProject(cCtx)
project := c.getProject(cCtx)

return knative.Apply(config, project)
return knative.Apply(config, project, c.dockerImage)
}

func (c CLI) DeployCMD() *cli.Command {
Expand Down
2 changes: 1 addition & 1 deletion src/cli/onmain.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/urfave/cli/v2"
)

func (c CLI) OnMainCMD() *cli.Command {
func (c *CLI) OnMainCMD() *cli.Command {
flags := []cli.Flag{}
flags = append(flags, Flags(Kubernetes)...)
flags = append(flags, Flags(Build)...)
Expand Down
19 changes: 5 additions & 14 deletions src/cli/push.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
package cli

import (
"fmt"

"github.com/docker/docker/api/types"
"github.com/nearform/k8s-kurated-addons-cli/src/services/docker"
"github.com/urfave/cli/v2"
)

func (c CLI) Push(cCtx *cli.Context) error {
repoName := cCtx.String("repo-name")
dockerFileName := cCtx.String("dockerfile-name")
project := c.newProject(cCtx)
docker, err := docker.New(project, dockerFileName, repoName)
if err != nil {
return fmt.Errorf("Creating docker service: %v", err)
}
docker.AuthConfig = types.AuthConfig{
func (c *CLI) Push(cCtx *cli.Context) error {
c.init(cCtx)
c.DockerService.AuthConfig = types.AuthConfig{
Username: cCtx.String("registry-user"),
Password: cCtx.String("registry-password"),
}
return docker.Push()
return c.DockerService.Push()
}

func (c CLI) PushCMD() *cli.Command {
func (c *CLI) PushCMD() *cli.Command {
return &cli.Command{
Name: "push",
Usage: "push the container image to a registry",
Expand Down
6 changes: 3 additions & 3 deletions src/cli/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"github.com/urfave/cli/v2"
)

func (c CLI) template(cCtx *cli.Context) error {
project := c.newProject(cCtx)
func (c *CLI) template(cCtx *cli.Context) error {
project := c.getProject(cCtx)
content, err := project.Dockerfile()
if err != nil {
return fmt.Errorf("Getting docker file %v", err)
Expand All @@ -16,7 +16,7 @@ func (c CLI) template(cCtx *cli.Context) error {
return nil
}

func (c CLI) TemplateCMD() *cli.Command {
func (c *CLI) TemplateCMD() *cli.Command {
return &cli.Command{
Name: "template",
Usage: "output the docker file used for this project",
Expand Down
27 changes: 27 additions & 0 deletions src/services/docker/docker-image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package docker

import (
"fmt"
"github.com/nearform/k8s-kurated-addons-cli/src/utils/defaults"
)

type DockerImage struct {
Registry string
Name string
Directory string
Tag string
}

func (dockerImage DockerImage) RemoteTag() string {
if dockerImage.Directory != defaults.ProjectDirectory {
return fmt.Sprintf("%s/%s/%s:%s", dockerImage.Registry, dockerImage.Name, dockerImage.Directory, dockerImage.Tag)
}
return fmt.Sprintf("%s/%s:%s", dockerImage.Registry, dockerImage.Name, dockerImage.Tag)
}

func (dockerImage DockerImage) LocalTag() string {
if dockerImage.Directory != defaults.ProjectDirectory {
return fmt.Sprintf("%s/%s:%s", dockerImage.Name, dockerImage.Directory, dockerImage.Tag)
}
return fmt.Sprintf("%s:%s", dockerImage.Name, dockerImage.Tag)
}
40 changes: 12 additions & 28 deletions src/services/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,22 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/archive"

"github.com/nearform/k8s-kurated-addons-cli/src/services/project"
"github.com/nearform/k8s-kurated-addons-cli/src/utils/defaults"

"github.com/nearform/k8s-kurated-addons-cli/src/utils/logger"
)

type DockerService struct {
project project.Project
DockerFileName string
ContainerRepo string
Client client.Client
AuthConfig types.AuthConfig
dockerImage DockerImage
}

// Create a new instance of the DockerService
func New(project project.Project, dockerFileName string, containerRepo string) (DockerService, error) {
func New(project project.Project, dockerImage DockerImage, dockerFileName string) (DockerService, error) {
client, err := getClient()
if err != nil {
return DockerService{}, err
Expand All @@ -36,8 +37,8 @@ func New(project project.Project, dockerFileName string, containerRepo string) (
return DockerService{
project: project,
DockerFileName: dockerFileName,
ContainerRepo: containerRepo,
Client: *client,
dockerImage: dockerImage,
}, nil
}

Expand All @@ -51,27 +52,9 @@ func getClient() (*client.Client, error) {
return cli, nil
}

func (ds DockerService) RemoteTag() string {
tag := ds.project.Version
directory := ds.project.Directory
if directory != defaults.ProjectDirectory {
return fmt.Sprintf("%s/%s/%s:%s", ds.ContainerRepo, ds.project.Name, directory, tag)
}
return fmt.Sprintf("%s/%s:%s", ds.ContainerRepo, ds.project.Name, tag)
}

func (ds DockerService) LocalTag() string {
tag := ds.project.Version
directory := ds.project.Directory
if directory != defaults.ProjectDirectory {
return fmt.Sprintf("%s/%s:%s", ds.project.Name, directory, tag)
}
return fmt.Sprintf("%s:%s", ds.project.Name, tag)
}

func (ds DockerService) buildContext() (*bytes.Reader, error) {
// Get the context for the docker build
existingBuildContext, err := archive.TarWithOptions(ds.project.Directory, &archive.TarOptions{})
existingBuildContext, err := archive.TarWithOptions(ds.dockerImage.Directory, &archive.TarOptions{})
if err != nil {
return nil, fmt.Errorf("Failed to create build context %v", err)
}
Expand Down Expand Up @@ -128,7 +111,7 @@ func (ds DockerService) buildContext() (*bytes.Reader, error) {

// Build Docker image
func (ds DockerService) Build() error {
logger.PrintInfo("Building " + ds.LocalTag())
logger.PrintInfo("Building " + ds.dockerImage.LocalTag())

ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5)
defer cancel()
Expand All @@ -142,7 +125,7 @@ func (ds DockerService) Build() error {
buildOptions := types.ImageBuildOptions{
Context: combinedBuildContextReader,
Dockerfile: ds.DockerFileName,
Tags: []string{ds.LocalTag()},
Tags: []string{ds.dockerImage.LocalTag()},
Remove: true,
}

Expand All @@ -155,12 +138,13 @@ func (ds DockerService) Build() error {
defer buildResponse.Body.Close()

logger.PrintStream(buildResponse.Body)

return nil
}

// Push Docker image
func (ds DockerService) Push() error {
logger.PrintInfo("Pushing to " + ds.RemoteTag())
logger.PrintInfo("Pushing to " + ds.dockerImage.RemoteTag())
logger.PrintInfo("User: " + ds.AuthConfig.Username)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*120)
defer cancel()
Expand All @@ -173,12 +157,12 @@ func (ds DockerService) Push() error {
RegistryAuth: base64.URLEncoding.EncodeToString(encodedJSON),
}

err = ds.Client.ImageTag(ctx, ds.LocalTag(), ds.RemoteTag())
err = ds.Client.ImageTag(ctx, ds.dockerImage.LocalTag(), ds.dockerImage.RemoteTag())
if err != nil {
return fmt.Errorf("Tagging local image for remote %v", err)
}

pushResponse, err := ds.Client.ImagePush(ctx, ds.RemoteTag(), ipo)
pushResponse, err := ds.Client.ImagePush(ctx, ds.dockerImage.RemoteTag(), ipo)
defer pushResponse.Close()
if err != nil {
return fmt.Errorf("Failed to push docker image %v", err)
Expand Down
Loading

0 comments on commit 04e43fe

Please sign in to comment.