Skip to content

Commit 513f68d

Browse files
authored
feat(remove): Introduce drain feature to remove instance services (#2198)
Reviewed-by: Cezar Craciunoiu <cezar.craciunoiu@unikraft.io> Approved-by: Cezar Craciunoiu <cezar.craciunoiu@unikraft.io>
2 parents 2d4976d + bd8ea38 commit 513f68d

File tree

1 file changed

+45
-2
lines changed
  • internal/cli/kraft/cloud/service/remove

1 file changed

+45
-2
lines changed

internal/cli/kraft/cloud/service/remove/remove.go

+45-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type RemoveOptions struct {
2626
All bool `long:"all" short:"a" usage:"Remove all services"`
2727
Auth *config.AuthConfig `noattribute:"true"`
2828
Client kraftcloud.KraftCloud `noattribute:"true"`
29+
Drain bool `long:"drain" short:"D" usage:"Remove all instances within the service"`
2930
Metro string `noattribute:"true"`
3031
Token string `noattribute:"true"`
3132
WaitEmpty bool `long:"wait-empty" usage:"Wait for the service to be empty before removing it"`
@@ -71,6 +72,10 @@ func (opts *RemoveOptions) Pre(cmd *cobra.Command, args []string) error {
7172
return fmt.Errorf("could not populate metro and token: %w", err)
7273
}
7374

75+
if opts.Drain && opts.WaitEmpty {
76+
return fmt.Errorf("draining and waiting for the service to be empty are mutually exclusive")
77+
}
78+
7479
return nil
7580
}
7681

@@ -125,9 +130,45 @@ func Remove(ctx context.Context, opts *RemoveOptions, args ...string) error {
125130
}
126131
}
127132

128-
if opts.WaitEmpty {
129-
var processes []*processtree.ProcessTreeItem
133+
var processes []*processtree.ProcessTreeItem
134+
135+
if opts.Drain {
136+
for _, service := range args {
137+
processes = append(processes,
138+
processtree.NewProcessTreeItem(
139+
fmt.Sprintf("draining %s", service),
140+
"",
141+
func(ctx context.Context) error {
142+
serviceResp, err := opts.Client.Services().WithMetro(opts.Metro).Get(ctx, service)
143+
if err != nil {
144+
return fmt.Errorf("could not get service: %w", err)
145+
}
146+
147+
sg, err := serviceResp.FirstOrErr()
148+
if err != nil && *sg.Error == kcclient.APIHTTPErrorNotFound {
149+
return nil
150+
} else if err != nil {
151+
return err
152+
}
153+
154+
if len(sg.Instances) == 0 {
155+
return nil
156+
}
157+
158+
var instances []string
159+
for _, instance := range sg.Instances {
160+
instances = append(instances, instance.UUID)
161+
}
162+
163+
log.G(ctx).Infof("deleting %d instances...", len(instances))
130164

165+
_, err = opts.Client.Instances().WithMetro(opts.Metro).Delete(ctx, instances...)
166+
return err
167+
},
168+
),
169+
)
170+
}
171+
} else if opts.WaitEmpty {
131172
services := args
132173
args = []string{}
133174

@@ -161,7 +202,9 @@ func Remove(ctx context.Context, opts *RemoveOptions, args ...string) error {
161202
),
162203
)
163204
}
205+
}
164206

207+
if opts.Drain || opts.WaitEmpty {
165208
treemodel, err := processtree.NewProcessTree(
166209
ctx,
167210
[]processtree.ProcessTreeOption{

0 commit comments

Comments
 (0)