Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for command and args in service create #635

Merged
merged 2 commits into from
Feb 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
| Show envFrom when running describe service or revision
| https://github.com/knative/client/pull/630

| 🎁
| Add `--cmd` and `--arg` for customization of container entrypoint
| https://github.com/knative/client/pull/635[#635]

## v0.12.0 (2020-01-29)

[cols="1,10,3", options="header", width="100%"]
Expand Down
2 changes: 2 additions & 0 deletions docs/cmd/kn_service_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ kn service create NAME --image IMAGE [flags]

```
--annotation stringArray Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-).
--arg stringArray Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times.
--async Create service and don't wait for it to become ready.
--autoscale-window string Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s)
--cmd string Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments.
--concurrency-limit int Hard Limit of concurrent requests to be processed by a single replica.
--concurrency-target int Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given.
-e, --env stringArray Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-).
Expand Down
2 changes: 2 additions & 0 deletions docs/cmd/kn_service_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ kn service update NAME [flags]

```
--annotation stringArray Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-).
--arg stringArray Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times.
--async Update service and don't wait for it to become ready.
--autoscale-window string Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s)
--cmd string Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments.
--concurrency-limit int Hard Limit of concurrent requests to be processed by a single replica.
--concurrency-target int Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given.
-e, --env stringArray Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-).
Expand Down
27 changes: 27 additions & 0 deletions pkg/kn/commands/service/configuration_edit_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ type ConfigurationEditFlags struct {
Mount []string
Volume []string

Command string
Arg []string

RequestsFlags, LimitsFlags ResourceFlags
MinScale int
MaxScale int
Expand Down Expand Up @@ -102,6 +105,16 @@ func (p *ConfigurationEditFlags) addSharedFlags(command *cobra.Command) {
"To unset a ConfigMap/Secret reference, append \"-\" to the name, e.g. --volume myvolume-.")
p.markFlagMakesRevision("volume")

command.Flags().StringVarP(&p.Command, "cmd", "", "",
"Specify command to be used as entrypoint instead of default one. "+
"Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments.")
p.markFlagMakesRevision("cmd")
command.Flags().StringArrayVarP(&p.Arg, "arg", "", []string{},
"Add argument to the container command. "+
"Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. "+
"You can use this flag multiple times.")
p.markFlagMakesRevision("arg")

command.Flags().StringVar(&p.RequestsFlags.CPU, "requests-cpu", "", "The requested CPU (e.g., 250m).")
p.markFlagMakesRevision("requests-cpu")
command.Flags().StringVar(&p.RequestsFlags.Memory, "requests-memory", "", "The requested memory (e.g., 64Mi).")
Expand Down Expand Up @@ -281,6 +294,20 @@ func (p *ConfigurationEditFlags) Apply(
return err
}

if cmd.Flags().Changed("cmd") {
err = servinglib.UpdateContainerCommand(template, p.Command)
if err != nil {
return err
}
}

if cmd.Flags().Changed("arg") {
err = servinglib.UpdateContainerArg(template, p.Arg)
if err != nil {
return err
}
}

if cmd.Flags().Changed("port") {
err = servinglib.UpdateContainerPort(template, p.Port)
if err != nil {
Expand Down
26 changes: 26 additions & 0 deletions pkg/kn/commands/service/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"strings"
"testing"

"gotest.tools/assert"

api_errors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/watch"
Expand Down Expand Up @@ -156,6 +158,30 @@ func TestServiceCreateImageSync(t *testing.T) {
}
}

func TestServiceCreateCommand(t *testing.T) {
action, created, _, err := fakeServiceCreate([]string{
"service", "create", "foo", "--image", "gcr.io/foo/bar:baz", "--cmd", "/app/start", "--async"}, false, false)
assert.NilError(t, err)
assert.Assert(t, action.Matches("create", "services"))

template, err := servinglib.RevisionTemplateOfService(created)
assert.NilError(t, err)
assert.DeepEqual(t, template.Spec.Containers[0].Command, []string{"/app/start"})
}

func TestServiceCreateArg(t *testing.T) {
action, created, _, err := fakeServiceCreate([]string{
"service", "create", "foo", "--image", "gcr.io/foo/bar:baz", "--arg", "myArg1", "--arg", "--myArg2", "--arg", "--myArg3=3", "--async"}, false, false)
assert.NilError(t, err)
assert.Assert(t, action.Matches("create", "services"))

expectedArg := []string{"myArg1", "--myArg2", "--myArg3=3"}

template, err := servinglib.RevisionTemplateOfService(created)
assert.NilError(t, err)
assert.DeepEqual(t, template.Spec.Containers[0].Args, expectedArg)
}

func TestServiceCreateEnv(t *testing.T) {
action, created, _, err := fakeServiceCreate([]string{
"service", "create", "foo", "--image", "gcr.io/foo/bar:baz", "-e", "A=DOGS", "--env", "B=WOLVES", "--env=EMPTY", "--async"}, false, false)
Expand Down
38 changes: 38 additions & 0 deletions pkg/kn/commands/service/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,44 @@ func TestServiceUpdateImage(t *testing.T) {
}
}

func TestServiceUpdateCommand(t *testing.T) {
orig := newEmptyService()

origTemplate, err := servinglib.RevisionTemplateOfService(orig)
assert.NilError(t, err)

err = servinglib.UpdateContainerCommand(origTemplate, "./start")
assert.NilError(t, err)

action, updated, _, err := fakeServiceUpdate(orig, []string{
"service", "update", "foo", "--cmd", "/app/start", "--async"}, false)
assert.NilError(t, err)
assert.Assert(t, action.Matches("update", "services"))

updatedTemplate, err := servinglib.RevisionTemplateOfService(updated)
assert.NilError(t, err)
assert.DeepEqual(t, updatedTemplate.Spec.Containers[0].Command, []string{"/app/start"})
}

func TestServiceUpdateArg(t *testing.T) {
orig := newEmptyService()

origTemplate, err := servinglib.RevisionTemplateOfService(orig)
assert.NilError(t, err)

err = servinglib.UpdateContainerArg(origTemplate, []string{"myArg0"})
assert.NilError(t, err)

action, updated, _, err := fakeServiceUpdate(orig, []string{
"service", "update", "foo", "--arg", "myArg1", "--arg", "--myArg2", "--arg", "--myArg3=3", "--async"}, false)
assert.NilError(t, err)
assert.Assert(t, action.Matches("update", "services"))

updatedTemplate, err := servinglib.RevisionTemplateOfService(updated)
assert.NilError(t, err)
assert.DeepEqual(t, updatedTemplate.Spec.Containers[0].Args, []string{"myArg1", "--myArg2", "--myArg3=3"})
}

func TestServiceUpdateRevisionNameExplicit(t *testing.T) {
orig := newEmptyServiceBetaAPIStyle()

Expand Down
20 changes: 20 additions & 0 deletions pkg/serving/config_changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,26 @@ func FreezeImageToDigest(template *servingv1alpha1.RevisionTemplateSpec, baseRev
return nil
}

// UpdateContainerCommand updates container with a given argument
func UpdateContainerCommand(template *servingv1alpha1.RevisionTemplateSpec, command string) error {
container, err := ContainerOfRevisionTemplate(template)
if err != nil {
return err
}
container.Command = []string{command}
return nil
}

// UpdateContainerArg updates container with a given argument
func UpdateContainerArg(template *servingv1alpha1.RevisionTemplateSpec, arg []string) error {
container, err := ContainerOfRevisionTemplate(template)
if err != nil {
return err
}
container.Args = arg
return nil
}

// UpdateContainerPort updates container with a give port
func UpdateContainerPort(template *servingv1alpha1.RevisionTemplateSpec, port int32) error {
container, err := ContainerOfRevisionTemplate(template)
Expand Down
22 changes: 22 additions & 0 deletions pkg/serving/config_changes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,28 @@ func checkContainerImage(t *testing.T, template *servingv1alpha1.RevisionTemplat
}
}

func TestUpdateContainerCommand(t *testing.T) {
template, _ := getV1alpha1RevisionTemplateWithOldFields()
err := UpdateContainerCommand(template, "/app/start")
assert.NilError(t, err)
assert.DeepEqual(t, template.Spec.GetContainer().Command, []string{"/app/start"})

err = UpdateContainerCommand(template, "/app/latest")
assert.NilError(t, err)
assert.DeepEqual(t, template.Spec.GetContainer().Command, []string{"/app/latest"})
}

func TestUpdateContainerArg(t *testing.T) {
template, _ := getV1alpha1RevisionTemplateWithOldFields()
err := UpdateContainerArg(template, []string{"--myArg"})
assert.NilError(t, err)
assert.DeepEqual(t, template.Spec.GetContainer().Args, []string{"--myArg"})

err = UpdateContainerArg(template, []string{"myArg1", "--myArg2"})
assert.NilError(t, err)
assert.DeepEqual(t, template.Spec.GetContainer().Args, []string{"myArg1", "--myArg2"})
}

func TestUpdateContainerPort(t *testing.T) {
template, _ := getV1alpha1Config()
err := UpdateContainerPort(template, 8888)
Expand Down