Skip to content
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
15 changes: 12 additions & 3 deletions cmd/composectl/cmd/update/complete.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package updatectl

import (
"github.com/foundriesio/composeapp/pkg/compose"
v1 "github.com/foundriesio/composeapp/pkg/compose/v1"
"github.com/foundriesio/composeapp/pkg/update"
"github.com/spf13/cobra"
)

type (
completeOptions struct {
Prune bool
Prune bool
PruneAllImages bool
}
)

Expand All @@ -25,7 +27,10 @@ This will mark the update as successful after checking whether the update apps a
opts := completeOptions{}

completeCmd.Flags().BoolVar(&opts.Prune, "prune", false,
"Uninstall and remove the apps that are not included in the update.")
"Uninstall and remove the apps that are not included in the update and images referenced by those apps")
completeCmd.Flags().BoolVar(&opts.PruneAllImages, "prune-all-images", false,
"Remove all unused images, even those that are not associated with the apps being uninstalled and pruned by the update complete process."+
" This option is only effective when --prune is also specified.")
completeCmd.Run = func(cmd *cobra.Command, args []string) {
completeUpdateCmd(cmd, args, &opts)
}
Expand All @@ -42,7 +47,11 @@ func completeUpdateCmd(cmd *cobra.Command, args []string, opts *completeOptions)

var options []update.CompleteOpt
if opts.Prune {
options = append(options, update.CompleteWithPruning())
imagePruneType := compose.PruneTypeOnlyAppImages
if opts.PruneAllImages {
imagePruneType = compose.PruneTypeAllUnusedImages
}
options = append(options, update.CompleteWithPruning(imagePruneType))
}
err = updateCtl.Complete(cmd.Context(), options...)
ExitIfNotNil(err)
Expand Down
69 changes: 37 additions & 32 deletions pkg/compose/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,47 +41,52 @@ func WithImagePruning(pruneType ...PruneType) UninstallOpt {
}

func UninstallApps(ctx context.Context, cfg *Config, appRefs []string, options ...UninstallOpt) error {
if len(appRefs) == 0 {
return nil
}
opts := &UninstallOpts{}
for _, o := range options {
o(opts)
}
status, err := CheckAppsStatus(ctx, cfg, appRefs)
if err != nil {
return err
}
if status.AreRunning() {
return ErrUninstallRunningApps
if len(appRefs) == 0 && (!opts.Prune || opts.PruneType != PruneTypeAllUnusedImages) {
return nil
}

store, err := cfg.AppStoreFactory()
if err != nil {
return err
}
appInStoreRefs, err := store.ListApps(ctx)
if err != nil {
return err
}
appsInStore := make(map[string]int)
for _, ref := range appInStoreRefs {
appsInStore[ref.Name] += 1
}
for _, app := range status.Apps {
if appsInStore[app.Name()] > 1 {
// Multiple versions of the same app exist in the store.
// If the version being removed is not installed, another version may still be
// installed and using the same compose directory. In that case, keep the app
// compose directory; otherwise we could remove compose files needed by the
// other installed version.
if _, isNotInstalled := status.NotInstalledCompose[app.Ref().Digest]; isNotInstalled {
continue
}
var err error
var status *AppsStatus
if len(appRefs) > 0 {
status, err = CheckAppsStatus(ctx, cfg, appRefs)
if err != nil {
return err
}
if err = os.RemoveAll(cfg.GetAppComposeDir(app.Name())); err != nil {
if status.AreRunning() {
return ErrUninstallRunningApps
}

store, err := cfg.AppStoreFactory()
if err != nil {
return err
}
appInStoreRefs, err := store.ListApps(ctx)
if err != nil {
return err
}
appsInStore := make(map[string]int)
for _, ref := range appInStoreRefs {
appsInStore[ref.Name] += 1
}
for _, app := range status.Apps {
if appsInStore[app.Name()] > 1 {
// Multiple versions of the same app exist in the store.
// If the version being removed is not installed, another version may still be
// installed and using the same compose directory. In that case, keep the app
// compose directory; otherwise we could remove compose files needed by the
// other installed version.
if _, isNotInstalled := status.NotInstalledCompose[app.Ref().Digest]; isNotInstalled {
continue
}
}
if err = os.RemoveAll(cfg.GetAppComposeDir(app.Name())); err != nil {
return err
}
}
}

if opts.Prune {
Expand Down
31 changes: 12 additions & 19 deletions pkg/update/complete.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,28 @@ package update
import (
"context"
"fmt"

"github.com/containerd/containerd/platforms"
"github.com/foundriesio/composeapp/pkg/compose"
v1 "github.com/foundriesio/composeapp/pkg/compose/v1"
)

type (
CompleteOpts struct {
Prune bool
Force bool
KeepApps []string
Prune bool
ImagePruneType compose.PruneType
Force bool
}
CompleteOpt func(*CompleteOpts)
)

func CompleteWithPruning(apps ...string) CompleteOpt {
func CompleteWithPruning(imagePruneType ...compose.PruneType) CompleteOpt {
return func(opts *CompleteOpts) {
opts.Prune = true
opts.KeepApps = apps
opts.ImagePruneType = compose.PruneTypeOnlyAppImages
if len(imagePruneType) > 0 {
opts.ImagePruneType = imagePruneType[0]
}
}
}

Expand Down Expand Up @@ -84,31 +88,20 @@ func (u *runnerImpl) complete(ctx context.Context, options ...CompleteOpt) error
}

if opts.Prune {
isInKeepList := func(appName string) bool {
for _, keepApp := range opts.KeepApps {
if appName == keepApp {
return true
}
}
return false
}
currentApps, err := compose.ListApps(ctx, u.config)
if err != nil {
return err
}
var appsToPrune []string
for _, app := range currentApps {
if isInKeepList(app.Name()) {
continue
}
if _, ok := updateApps[app.Ref().String()]; !ok {
appsToPrune = append(appsToPrune, app.Ref().String())
}
}
if err := compose.UninstallApps(ctx, u.config, appsToPrune, compose.WithImagePruning(opts.ImagePruneType)); err != nil {
return err
}
if len(appsToPrune) > 0 {
if err := compose.UninstallApps(ctx, u.config, appsToPrune, compose.WithImagePruning()); err != nil {
return err
}
if err := compose.RemoveApps(ctx, u.config, appsToPrune, compose.WithCheckStatus(false)); err != nil {
return err
}
Expand Down
Loading