Skip to content
This repository has been archived by the owner on Mar 16, 2024. It is now read-only.

add acorn run --update/-u flag to update app if exists #710

Merged
merged 4 commits into from
Nov 18, 2022
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
1 change: 1 addition & 0 deletions docs/docs/100-reference/01-command-line/acorn_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ acorn run [flags] IMAGE|DIRECTORY [acorn args]
-q, --quiet Do not print status
-s, --secret strings Bind an existing secret (format existing:sec-name) (ex: sec-name:app-secret)
--target-namespace string The name of the namespace to be created and deleted for the application resources
-u, --update Update the app if it already exists
-v, --volume stringArray Bind an existing volume (format existing:vol-name,field=value) (ex: pvc-name:app-data)
--wait Wait for app to become ready before command exiting (default true)
```
Expand Down
1 change: 1 addition & 0 deletions docs/docs/100-reference/01-command-line/acorn_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ acorn update [flags] APP_NAME [deploy flags]
--profile strings Profile to assign default values
-p, --publish strings Publish port of application (format [public:]private) (ex 81:80)
-P, --publish-all Publish all (true) or none (false) of the defined ports of application
--replace Toggle replacing update, resetting undefined fields to default values
-s, --secret strings Bind an existing secret (format existing:sec-name) (ex: sec-name:app-secret)
--target-namespace string The name of the namespace to be created and deleted for the application resources
-v, --volume stringArray Bind an existing volume (format existing:vol-name,field=value) (ex: pvc-name:app-data)
Expand Down
38 changes: 38 additions & 0 deletions pkg/cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/acorn-io/acorn/pkg/wait"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/yaml"
)

Expand Down Expand Up @@ -73,6 +74,7 @@ type Run struct {
BidirectionalSync bool `usage:"In interactive mode download changes in addition to uploading" short:"b"`
Wait *bool `usage:"Wait for app to become ready before command exiting (default true)"`
Quiet bool `usage:"Do not print status" short:"q"`
Update bool `usage:"Update the app if it already exists" short:"u"`

out io.Writer
}
Expand Down Expand Up @@ -193,6 +195,26 @@ func (s *Run) Run(cmd *cobra.Command, args []string) error {
return err
}

// Update mode -> early exits on invalid combinations
if s.Update {
if s.Interactive {
return fmt.Errorf("cannot use --update/-u with --dev/-i")
}
if s.Name == "" {
return fmt.Errorf("--name/-n NAME is required when updating an app")
}

// unset update mode if app does not exist
_, err := c.AppGet(cmd.Context(), s.Name)
if err != nil {
if apierrors.IsNotFound(err) {
s.Update = false
} else {
return err
}
}
}

opts, err := s.ToOpts()
if err != nil {
return err
Expand Down Expand Up @@ -237,6 +259,22 @@ func (s *Run) Run(cmd *cobra.Command, args []string) error {
}
}

if s.Update {
u := Update{
Image: image,
RunArgs: s.RunArgs,
out: s.out,
Replace: true,
}
err := u.Run(cmd, append([]string{s.Name}, args...))
if err != nil {
return err
}
if s.Wait == nil || *s.Wait {
return wait.App(cmd.Context(), c, s.Name, s.Quiet)
}
}

if len(args) > 1 {
_, flags, err := deployargs.ToFlagsFromImage(cmd.Context(), c, image)
if err != nil {
Expand Down
6 changes: 5 additions & 1 deletion pkg/cli/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ func NewUpdate(out io.Writer) *cobra.Command {
}

type Update struct {
Image string `json:"image,omitempty"`
Image string `json:"image,omitempty"`
Replace bool `usage:"Toggle replacing update, resetting undefined fields to default values" json:"replace,omitempty"` // Replace sets patchMode to false, resulting in a full update, resetting all undefined fields to their defaults
RunArgs

out io.Writer
Expand Down Expand Up @@ -69,6 +70,9 @@ func (s *Update) Run(cmd *cobra.Command, args []string) error {
opts.Image = image
opts.DeployArgs = deployParams

// Overwrite == true means patchMode == false
opts.Replace = s.Replace

if s.Output != "" {
app, err := client.ToAppUpdate(cmd.Context(), c, name, &opts)
if err != nil {
Expand Down
11 changes: 11 additions & 0 deletions pkg/client/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func (c *client) AppUpdate(ctx context.Context, name string, opts *AppUpdateOpti
}

func ToAppUpdate(ctx context.Context, c Client, name string, opts *AppUpdateOptions) (*apiv1.App, error) {

app, err := c.AppGet(ctx, name)
if err != nil {
return nil, err
Expand All @@ -89,6 +90,16 @@ func ToAppUpdate(ctx context.Context, c Client, name string, opts *AppUpdateOpti
app.Spec.Image = opts.Image
}

// Replace/Reset Mode (Not patch mode)
if opts.Replace {
o := opts.ToRun()
nApp := ToApp(app.Namespace, opts.Image, &o)
nApp.Name = app.Name
nApp.ObjectMeta.UID = app.ObjectMeta.UID
nApp.ObjectMeta.ResourceVersion = app.ObjectMeta.ResourceVersion
return nApp, nil
}

app.Labels = typed.Concat(app.Labels, appScoped(opts.Labels))
app.Annotations = typed.Concat(app.Annotations, appScoped(opts.Annotations))
app.Spec.Volumes = mergeVolumes(app.Spec.Volumes, opts.Volumes)
Expand Down
19 changes: 19 additions & 0 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ type AppUpdateOptions struct {
DevMode *bool
Image string
TargetNamespace string
Replace bool // Replace is used to indicate whether the update should be a patch (replace=false: only change specified fields) or a full update (replace=true: reset unspecified fields to defaults)
}

type LogOptions apiv1.LogOptions
Expand Down Expand Up @@ -140,6 +141,24 @@ func (a AppRunOptions) ToUpdate() AppUpdateOptions {
}
}

func (a AppUpdateOptions) ToRun() AppRunOptions {
return AppRunOptions{
Annotations: a.Annotations,
Labels: a.Labels,
PublishMode: a.PublishMode,
Volumes: a.Volumes,
Secrets: a.Secrets,
Links: a.Links,
Ports: a.Ports,
DeployArgs: a.DeployArgs,
DevMode: a.DevMode,
Profiles: a.Profiles,
Permissions: a.Permissions,
Env: a.Env,
TargetNamespace: a.TargetNamespace,
}
}

type ImageProgress struct {
Total int64 `json:"total,omitempty"`
Complete int64 `json:"complete,omitempty"`
Expand Down