From 8d691e426317105eeee2cb3c2f56396602259d80 Mon Sep 17 00:00:00 2001 From: Julien Castets Date: Wed, 4 Oct 2023 15:52:31 +0200 Subject: [PATCH] Add flag --privileged to koyeb service, closes #137 --- go.mod | 2 +- go.sum | 4 + pkg/koyeb/services.go | 23 ++++- pkg/koyeb/services_test.go | 178 +++++++++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 pkg/koyeb/services_test.go diff --git a/go.mod b/go.mod index ff1de87a..bfb323e0 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/gofrs/uuid v4.3.0+incompatible github.com/gorilla/websocket v1.5.0 github.com/iancoleman/strcase v0.2.0 - github.com/koyeb/koyeb-api-client-go v0.0.0-20230627102521-e7bd5ffc792b + github.com/koyeb/koyeb-api-client-go v0.0.0-20231004123101-b055bd9e4928 github.com/logrusorgru/aurora v2.0.3+incompatible github.com/manifoldco/promptui v0.9.0 github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index d7b6fe81..d4afa953 100644 --- a/go.sum +++ b/go.sum @@ -165,6 +165,10 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/koyeb/koyeb-api-client-go v0.0.0-20230627102521-e7bd5ffc792b h1:es3LHannGBfAGQQll3XFRDR3Gq0GBsA8R+MhzUS6mLw= github.com/koyeb/koyeb-api-client-go v0.0.0-20230627102521-e7bd5ffc792b/go.mod h1:+oQfFj2WL3gi9Pb+UHbob4D7xaT52mPfKyH1UvWa4PQ= +github.com/koyeb/koyeb-api-client-go v0.0.0-20231004121755-b21e872a5723 h1:+koxDo4E/V11wTqoGSYCNAgX/wYd4hqfZWMeU7pFfn0= +github.com/koyeb/koyeb-api-client-go v0.0.0-20231004121755-b21e872a5723/go.mod h1:+oQfFj2WL3gi9Pb+UHbob4D7xaT52mPfKyH1UvWa4PQ= +github.com/koyeb/koyeb-api-client-go v0.0.0-20231004123101-b055bd9e4928 h1:xFTTl4MmHRZmrZnoi7BvQVPlMroQo98mdFbZuXsVXiA= +github.com/koyeb/koyeb-api-client-go v0.0.0-20231004123101-b055bd9e4928/go.mod h1:+oQfFj2WL3gi9Pb+UHbob4D7xaT52mPfKyH1UvWa4PQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= diff --git a/pkg/koyeb/services.go b/pkg/koyeb/services.go index e3780ff8..4291ecb3 100644 --- a/pkg/koyeb/services.go +++ b/pkg/koyeb/services.go @@ -232,6 +232,7 @@ func addServiceDefinitionFlags(flags *pflag.FlagSet) { flags.Int64("scale", 1, "Set both min-scale and max-scale") flags.Int64("min-scale", 1, "Min scale") flags.Int64("max-scale", 1, "Max scale") + flags.Bool("privileged", false, "Whether the service container should run in privileged mode") // Global flags, only for services with the type "web" (not "worker") flags.StringSlice( @@ -612,12 +613,12 @@ func setSource(definition *koyeb.DeploymentDefinition, flags *pflag.FlagSet) err Solution: "Fix the flags and try again", } } - if hasDockerFlags { + if hasDockerFlags || definition.HasDocker() { docker := definition.GetDocker() source := parseDockerSource(flags, &docker) definition.SetDocker(*source) definition.Git = nil - } else if hasGitFlags { + } else if hasGitFlags || definition.HasGit() { git := definition.GetGit() source, err := parseGitSource(flags, &git) if err != nil { @@ -651,6 +652,10 @@ func parseDockerSource(flags *pflag.FlagSet, source *koyeb.DockerSource) *koyeb. secret, _ := flags.GetString("docker-private-registry-secret") source.SetImageRegistrySecret(secret) } + if flags.Lookup("privileged").Changed { + privileged, _ := flags.GetBool("privileged") + source.SetPrivileged(privileged) + } return source } @@ -697,7 +702,8 @@ func setGitSourceBuilder(flags *pflag.FlagSet, source *koyeb.GitSource) (*koyeb. flags.Lookup("git-docker-command").Changed || flags.Lookup("git-docker-args").Changed || flags.Lookup("git-docker-target").Changed || - (flags.Lookup("git-builder").Changed && builder == "docker") { + (flags.Lookup("git-builder").Changed && builder == "docker") || + source.HasDocker() { // If --git-builder has not been provided, but the current source is a buildpack builder. if !flags.Lookup("git-builder").Changed && source.HasBuildpack() { @@ -722,7 +728,8 @@ func setGitSourceBuilder(flags *pflag.FlagSet, source *koyeb.GitSource) (*koyeb. flags.Lookup("git-build-command").Changed || flags.Lookup("git-buildpack-run-command").Changed || flags.Lookup("git-run-command").Changed || - (flags.Lookup("git-builder").Changed && builder == "buildpack") { + (flags.Lookup("git-builder").Changed && builder == "buildpack") || + source.HasBuildpack() { // If --git-builder has not been provided, but the current source is a buildpack builder. if !flags.Lookup("git-builder").Changed && source.HasDocker() { @@ -791,6 +798,10 @@ func parseGitSourceBuildpackBuilder(flags *pflag.FlagSet, builder koyeb.Buildpac } else if flags.Lookup("git-buildpack-run-command").Changed { builder.SetRunCommand(buildpackRunCommand) } + if flags.Lookup("privileged").Changed { + privileged, _ := flags.GetBool("privileged") + builder.SetPrivileged(privileged) + } return &builder, nil } @@ -816,6 +827,10 @@ func parseGitSourceDockerBuilder(flags *pflag.FlagSet, builder koyeb.DockerBuild target, _ := flags.GetString("git-docker-target") builder.SetTarget(target) } + if flags.Lookup("privileged").Changed { + privileged, _ := flags.GetBool("privileged") + builder.SetPrivileged(privileged) + } return &builder, nil } diff --git a/pkg/koyeb/services_test.go b/pkg/koyeb/services_test.go new file mode 100644 index 00000000..b4db5c55 --- /dev/null +++ b/pkg/koyeb/services_test.go @@ -0,0 +1,178 @@ +package koyeb + +import ( + "testing" + + "github.com/koyeb/koyeb-api-client-go/api/v1/koyeb" + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" +) + +func TestSetGitSourceBuilder(t *testing.T) { + tests := map[string]struct { + args []string + source *koyeb.GitSource + expected *koyeb.GitSource + }{ + "invalid_git_builder": { + args: []string{"--git-builder", "xxx"}, + source: &koyeb.GitSource{}, + expected: nil, + }, + "source_buildpack_no_arg": { + args: []string{}, + source: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{}, + }, + expected: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{}, + }, + }, + "source_docker_no_arg": { + args: []string{}, + source: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{}, + }, + expected: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{}, + }, + }, + "source_buildpack_set_builder_to_buildpack": { + args: []string{"--git-builder", "buildpack"}, + source: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{}, + }, + expected: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{}, + }, + }, + "source_buildpack_set_builder_to_docker": { + args: []string{"--git-builder", "docker"}, + source: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{}, + }, + expected: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{}, + }, + }, + "source_docker_set_builder_to_buildpack": { + args: []string{"--git-builder", "buildpack"}, + source: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{}, + }, + expected: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{}, + }, + }, + "source_docker_set_builder_to_docker": { + args: []string{"--git-builder", "docker"}, + source: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{}, + }, + expected: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{}, + }, + }, + "source_buildpack_set_docker_args": { + args: []string{"--git-docker-dockerfile", "Dockerfile.dev"}, + source: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{}, + }, + expected: nil, + }, + "source_buildpack_set_buildpack_args": { + args: []string{"--git-buildpack-run-command", "run", "--git-buildpack-build-command", "build", "--privileged"}, + source: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{ + Privileged: koyeb.PtrBool(false), + }, + }, + expected: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{ + RunCommand: koyeb.PtrString("run"), + BuildCommand: koyeb.PtrString("build"), + Privileged: koyeb.PtrBool(true), + }, + }, + }, + "source_docker_set_buildpack_args": { + args: []string{"--git-buildpack-run-command", "run", "--git-buildpack-build-command", "build", "--privileged"}, + source: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{}, + }, + expected: nil, + }, + "source_docker_set_docker_args": { + args: []string{ + "--git-docker-command", "cmd", + "--git-docker-args", "arg1", "--git-docker-args", "arg2", + "--git-docker-entrypoint", "entrypoint.sh", "--git-docker-entrypoint", "entrypoint-arg", + "--git-docker-dockerfile", "Dockerfile.dev", + "--git-docker-target", "dev", + "--privileged", + }, + source: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{}, + }, + expected: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{ + Command: koyeb.PtrString("cmd"), + Args: []string{"arg1", "arg2"}, + Entrypoint: []string{"entrypoint.sh", "entrypoint-arg"}, + Dockerfile: koyeb.PtrString("Dockerfile.dev"), + Target: koyeb.PtrString("dev"), + Privileged: koyeb.PtrBool(true), + }, + }, + }, + "source_buildpack_override_privileged_without_other_args": { + args: []string{"--privileged=false"}, + source: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{ + Privileged: koyeb.PtrBool(true), + }, + }, + expected: &koyeb.GitSource{ + Buildpack: &koyeb.BuildpackBuilder{ + Privileged: koyeb.PtrBool(false), + }, + }, + }, + "source_docker_override_privileged_without_other_args": { + args: []string{"--privileged"}, + source: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{ + Privileged: koyeb.PtrBool(false), + }, + }, + expected: &koyeb.GitSource{ + Docker: &koyeb.DockerBuilder{ + Privileged: koyeb.PtrBool(true), + }, + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + cmd := &cobra.Command{} + + addServiceDefinitionFlags(cmd.Flags()) + + cmd.SetArgs(tc.args) + if err := cmd.ParseFlags(tc.args); err != nil { + t.Fatal() + } + + ret, err := setGitSourceBuilder(cmd.Flags(), tc.source) + + if tc.expected != nil { + assert.Nil(t, err) + assert.Equal(t, tc.expected, ret) + } else { + assert.NotNil(t, err) + assert.Nil(t, ret) + } + }) + } +}