Skip to content

Commit

Permalink
feat(compose): Introduce --remove-orphans flag (#1587)
Browse files Browse the repository at this point in the history
Reviewed-by: Alexander Jung <alex@unikraft.io>
Approved-by: Alexander Jung <alex@unikraft.io>
  • Loading branch information
nderjung authored Apr 23, 2024
2 parents 03d12d5 + f0adeae commit 3da3f85
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 5 deletions.
8 changes: 7 additions & 1 deletion compose/v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func (v1 *v1Compose) refreshRunningServices(ctx context.Context, embeddedProject
runningMachines := []metav1.ObjectMeta{}

// Orphaned machines
orphanMachines := []string{}
for _, machine := range embeddedProject.Status.Machines {
isService := false
for _, service := range project.Services {
Expand All @@ -99,12 +100,17 @@ func (v1 *v1Compose) refreshRunningServices(ctx context.Context, embeddedProject
if m.Name == machine.Name {
runningMachines = append(runningMachines, machine)
if !isService && m.Status.State == machineapi.MachineStateRunning {
log.G(ctx).WithField("machine", machine.Name).Warn("found orphan machine")
orphanMachines = append(orphanMachines, machine.Name)
}
}
}
}

if len(orphanMachines) > 0 {
log.G(ctx).WithField("machines", orphanMachines).
Warn("found orphan machines for this project. You can run this command with the --remove-orphans flag to clean it up")
}

// Name collisions
for _, m := range machines.Items {
if m.Status.State != machineapi.MachineStateRunning {
Expand Down
10 changes: 9 additions & 1 deletion internal/cli/kraft/compose/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"kraftkit.sh/cmdfactory"
"kraftkit.sh/compose"
"kraftkit.sh/internal/cli/kraft/build"
"kraftkit.sh/internal/cli/kraft/compose/utils"
netcreate "kraftkit.sh/internal/cli/kraft/net/create"
"kraftkit.sh/internal/cli/kraft/pkg"
"kraftkit.sh/internal/cli/kraft/pkg/pull"
Expand All @@ -39,7 +40,8 @@ import (
)

type CreateOptions struct {
Composefile string `noattribute:"true"`
Composefile string `noattribute:"true"`
RemoveOrphans bool `long:"remove-orphans" usage:"Remove machines for services not defined in the Compose file"`
}

func NewCmd() *cobra.Command {
Expand Down Expand Up @@ -98,6 +100,12 @@ func (opts *CreateOptions) Run(ctx context.Context, args []string) error {
return err
}

if opts.RemoveOrphans {
if err := utils.RemoveOrphans(ctx, project); err != nil {
return err
}
}

composeController, err := compose.NewComposeProjectV1(ctx)
if err != nil {
return err
Expand Down
10 changes: 9 additions & 1 deletion internal/cli/kraft/compose/down/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/spf13/cobra"
"kraftkit.sh/cmdfactory"
"kraftkit.sh/compose"
"kraftkit.sh/internal/cli/kraft/compose/utils"
networkremove "kraftkit.sh/internal/cli/kraft/net/remove"
machineremove "kraftkit.sh/internal/cli/kraft/remove"
"kraftkit.sh/log"
Expand All @@ -27,7 +28,8 @@ import (
)

type DownOptions struct {
composefile string
composefile string
RemoveOrphans bool `long:"remove-orphans" usage:"Remove machines for services not defined in the Compose file."`
}

func NewCmd() *cobra.Command {
Expand Down Expand Up @@ -81,6 +83,12 @@ func (opts *DownOptions) Run(ctx context.Context, args []string) error {
return err
}

if opts.RemoveOrphans {
if err := utils.RemoveOrphans(ctx, project); err != nil {
return err
}
}

machineController, err := mplatform.NewMachineV1alpha1ServiceIterator(ctx)
if err != nil {
return err
Expand Down
13 changes: 13 additions & 0 deletions internal/cli/kraft/compose/ps/ps.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

type PsOptions struct {
Long bool `long:"long" short:"l" usage:"Show more information"`
Orphans bool `long:"orphans" usage:"Include orphaned services (default: true)" default:"true"`
Output string `long:"output" short:"o" usage:"Set output format. Options: table,yaml,json,list" default:"table"`
Quiet bool `long:"quiet" short:"q" usage:"Only display machine IDs"`
ShowAll bool `long:"all" short:"a" usage:"Show all machines (default shows just running)"`
Expand Down Expand Up @@ -111,6 +112,18 @@ func (opts *PsOptions) Run(ctx context.Context, args []string) error {
filteredPsTable := []pslist.PsEntry{}
for _, psEntry := range psTable {
for _, machine := range embeddedProject.Status.Machines {
orphaned := true
for _, service := range project.Services {
if service.Name == machine.Name {
orphaned = false
break
}
}

if orphaned && !opts.Orphans {
continue
}

if psEntry.Name == machine.Name {
filteredPsTable = append(filteredPsTable, psEntry)
}
Expand Down
7 changes: 5 additions & 2 deletions internal/cli/kraft/compose/up/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import (
)

type UpOptions struct {
Detach bool `long:"detach" short:"d" usage:"Run in background"`
RemoveOrphans bool `long:"remove-orphans" usage:"Remove machines for services not defined in the Compose file."`

composefile string
Detach bool `long:"detach" short:"d" usage:"Run in background"`
}

func NewCmd() *cobra.Command {
Expand Down Expand Up @@ -64,7 +66,8 @@ func (opts *UpOptions) Pre(cmd *cobra.Command, _ []string) error {

func (opts *UpOptions) Run(ctx context.Context, _ []string) error {
createOptions := create.CreateOptions{
Composefile: opts.composefile,
Composefile: opts.composefile,
RemoveOrphans: opts.RemoveOrphans,
}

if err := createOptions.Run(ctx, []string{}); err != nil {
Expand Down
75 changes: 75 additions & 0 deletions internal/cli/kraft/compose/utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2024, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file except in compliance with the License.

package utils

import (
"context"

"kraftkit.sh/compose"
"kraftkit.sh/internal/cli/kraft/remove"
"kraftkit.sh/log"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
composeapi "kraftkit.sh/api/compose/v1"
machineapi "kraftkit.sh/api/machine/v1alpha1"
mplatform "kraftkit.sh/machine/platform"
)

func RemoveOrphans(ctx context.Context, project *compose.Project) error {
composeController, err := compose.NewComposeProjectV1(ctx)
if err != nil {
return err
}

embeddedProject, err := composeController.Get(ctx, &composeapi.Compose{
ObjectMeta: metav1.ObjectMeta{
Name: project.Name,
},
})
if err != nil {
return err
}

machineController, err := mplatform.NewMachineV1alpha1ServiceIterator(ctx)
if err != nil {
return err
}

machines, err := machineController.List(ctx, &machineapi.MachineList{})
if err != nil {
return err
}

orphanMachines := []string{}
for _, machine := range embeddedProject.Status.Machines {
isService := false
for _, service := range project.Services {
if service.Name == machine.Name {
isService = true
break
}
}

for _, m := range machines.Items {
if m.Name == machine.Name {
if !isService && m.Status.State == machineapi.MachineStateRunning {
orphanMachines = append(orphanMachines, machine.Name)
}
}
}
}

if len(orphanMachines) == 0 {
return nil
}

log.G(ctx).Info("removing orphan machines...")
removeOptions := remove.RemoveOptions{
Platform: "auto",
}

return removeOptions.Run(ctx, orphanMachines)
}

0 comments on commit 3da3f85

Please sign in to comment.