Skip to content

Commit 1c30eba

Browse files
committed
refacoring destroy func
1 parent 7ebf7f2 commit 1c30eba

File tree

5 files changed

+55
-68
lines changed

5 files changed

+55
-68
lines changed

cmd/arduino-app-cli/app/destroy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/spf13/cobra"
2323

2424
"github.com/arduino/arduino-app-cli/cmd/arduino-app-cli/completion"
25+
"github.com/arduino/arduino-app-cli/cmd/arduino-app-cli/internal/servicelocator"
2526
"github.com/arduino/arduino-app-cli/cmd/feedback"
2627
"github.com/arduino/arduino-app-cli/internal/orchestrator"
2728
"github.com/arduino/arduino-app-cli/internal/orchestrator/app"
@@ -52,7 +53,7 @@ func newDestroyCmd(cfg config.Configuration) *cobra.Command {
5253
func destroyHandler(ctx context.Context, app app.ArduinoApp) error {
5354
out, _, getResult := feedback.OutputStreams()
5455

55-
for message := range orchestrator.DestroyAndCleanApp(ctx, app) {
56+
for message := range orchestrator.StopAndDestroyApp(ctx, servicelocator.GetDockerClient(), app) {
5657
switch message.GetType() {
5758
case orchestrator.ProgressType:
5859
fmt.Fprintf(out, "Progress[%s]: %.0f%%\n", message.GetProgress().Name, message.GetProgress().Progress)

internal/api/docs/openapi.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,7 @@ components:
16861686
- stopping
16871687
- stopped
16881688
- failed
1689+
- uninitialized
16891690
type: string
16901691
uniqueItems: true
16911692
UpdateCheckResult:

internal/e2e/client/client.gen.go

Lines changed: 6 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/e2e/daemon/app_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func TestCreateAndVerifyAppDetails(t *testing.T) {
204204

205205
require.False(t, *retrievedApp.Example, "A new app should not be an 'example'")
206206
require.False(t, *retrievedApp.Default, "A new app should not be 'default'")
207-
require.Equal(t, client.Stopped, retrievedApp.Status, "The initial status of a new app should be 'stopped'")
207+
require.Equal(t, client.Uninitialized, retrievedApp.Status, "The initial status of a new app should be 'initialized'")
208208
require.Empty(t, retrievedApp.Bricks, "A new app should not have 'bricks'")
209209
require.NotEmpty(t, retrievedApp.Path, "The app path should not be empty")
210210
}
@@ -764,7 +764,7 @@ func TestAppDetails(t *testing.T) {
764764
)
765765
require.False(t, *detailsResp.JSON200.Example)
766766
require.False(t, *detailsResp.JSON200.Default)
767-
require.Equal(t, client.Stopped, detailsResp.JSON200.Status)
767+
require.Equal(t, client.Uninitialized, detailsResp.JSON200.Status)
768768
require.NotEmpty(t, detailsResp.JSON200.Path)
769769
})
770770
}

internal/orchestrator/orchestrator.go

Lines changed: 44 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -384,12 +384,27 @@ func getVideoDevices() map[int]string {
384384
return deviceMap
385385
}
386386

387-
func stopAppWithCmd(ctx context.Context, docker command.Cli, app app.ArduinoApp, cmd string) iter.Seq[StreamMessage] {
387+
type StopOptions struct {
388+
Command string
389+
RequireRunning bool
390+
RemoveVolumes bool
391+
RemoveOrphans bool
392+
}
393+
394+
func stopAppWithCmd(ctx context.Context, docker command.Cli, app app.ArduinoApp, opts StopOptions) iter.Seq[StreamMessage] {
388395
return func(yield func(StreamMessage) bool) {
389396
ctx, cancel := context.WithCancel(ctx)
390397
defer cancel()
391398

392-
if !yield(StreamMessage{data: fmt.Sprintf("Stopping app %q", app.Name)}) {
399+
var message string
400+
switch opts.Command {
401+
case "stop":
402+
message = fmt.Sprintf("Stopping app %q", app.Name)
403+
case "down":
404+
message = fmt.Sprintf("destroying app %q", app.Name)
405+
}
406+
407+
if !yield(StreamMessage{data: message}) {
393408
return
394409
}
395410
if err := setStatusLeds(LedTriggerDefault); err != nil {
@@ -410,7 +425,7 @@ func stopAppWithCmd(ctx context.Context, docker command.Cli, app app.ArduinoApp,
410425
yield(StreamMessage{error: err})
411426
return
412427
}
413-
if appStatus.Status != StatusStarting && appStatus.Status != StatusRunning {
428+
if opts.RequireRunning && appStatus.Status != StatusStarting && appStatus.Status != StatusRunning {
414429
yield(StreamMessage{data: fmt.Sprintf("app %q is not running", app.Name)})
415430
return
416431
}
@@ -425,11 +440,26 @@ func stopAppWithCmd(ctx context.Context, docker command.Cli, app app.ArduinoApp,
425440
mainCompose := app.AppComposeFilePath()
426441
// In case the app was never started
427442
if mainCompose.Exist() {
428-
process, err := paths.NewProcess(nil, "docker", "compose", "-f", mainCompose.String(), cmd, fmt.Sprintf("--timeout=%d", DefaultDockerStopTimeoutSeconds))
443+
cmd := "docker"
444+
args := []string{
445+
"compose",
446+
"-f", mainCompose.String(),
447+
opts.Command,
448+
fmt.Sprintf("--timeout=%d", DefaultDockerStopTimeoutSeconds),
449+
}
450+
if opts.RemoveVolumes {
451+
args = append(args, "--volumes")
452+
}
453+
if opts.RemoveOrphans {
454+
args = append(args, "--remove-orphans")
455+
}
456+
fullCommand := append([]string{cmd}, args...)
457+
process, err := paths.NewProcess(nil, fullCommand...)
429458
if err != nil {
430459
yield(StreamMessage{error: err})
431460
return
432461
}
462+
433463
process.RedirectStderrTo(callbackWriter)
434464
process.RedirectStdoutTo(callbackWriter)
435465
if err := process.RunWithinContext(ctx); err != nil {
@@ -443,17 +473,20 @@ func stopAppWithCmd(ctx context.Context, docker command.Cli, app app.ArduinoApp,
443473
}
444474

445475
func StopApp(ctx context.Context, dockerClient command.Cli, app app.ArduinoApp) iter.Seq[StreamMessage] {
446-
return stopAppWithCmd(ctx, dockerClient, app, "stop")
476+
return stopAppWithCmd(ctx, dockerClient, app, StopOptions{
477+
Command: "stop",
478+
RequireRunning: true,
479+
})
447480
}
448481

449482
func StopAndDestroyApp(ctx context.Context, dockerClient command.Cli, app app.ArduinoApp) iter.Seq[StreamMessage] {
450-
return stopAppWithCmd(ctx, dockerClient, app, "down")
451-
}
452-
453-
func DestroyAndCleanApp(ctx context.Context, app app.ArduinoApp) iter.Seq[StreamMessage] {
454483
return func(yield func(StreamMessage) bool) {
455-
456-
for msg := range destroyAppContainers(ctx, app) {
484+
for msg := range stopAppWithCmd(ctx, dockerClient, app, StopOptions{
485+
Command: "down",
486+
RemoveVolumes: true,
487+
RemoveOrphans: true,
488+
RequireRunning: false,
489+
}) {
457490
if !yield(msg) {
458491
return
459492
}
@@ -466,55 +499,6 @@ func DestroyAndCleanApp(ctx context.Context, app app.ArduinoApp) iter.Seq[Stream
466499
}
467500
}
468501

469-
func destroyAppContainers(ctx context.Context, app app.ArduinoApp) iter.Seq[StreamMessage] {
470-
return func(yield func(StreamMessage) bool) {
471-
ctx, cancel := context.WithCancel(ctx)
472-
defer cancel()
473-
474-
if !yield(StreamMessage{data: fmt.Sprintf("Destroying app %q containers and data...", app.Name)}) {
475-
return
476-
}
477-
callbackWriter := NewCallbackWriter(func(line string) {
478-
if !yield(StreamMessage{data: line}) {
479-
cancel()
480-
return
481-
}
482-
})
483-
if _, ok := app.GetSketchPath(); ok {
484-
if err := micro.Disable(); err != nil {
485-
slog.Debug("unable to disable micro (might be already stopped)", slog.String("error", err.Error()))
486-
}
487-
}
488-
if app.MainPythonFile != nil {
489-
mainCompose := app.AppComposeFilePath()
490-
if mainCompose.Exist() {
491-
process, err := paths.NewProcess(
492-
nil,
493-
"docker", "compose",
494-
"-f", mainCompose.String(),
495-
"down",
496-
"--volumes",
497-
"--remove-orphans",
498-
fmt.Sprintf("--timeout=%d", DefaultDockerStopTimeoutSeconds),
499-
)
500-
501-
if err != nil {
502-
yield(StreamMessage{error: err})
503-
return
504-
}
505-
506-
process.RedirectStderrTo(callbackWriter)
507-
process.RedirectStdoutTo(callbackWriter)
508-
if err := process.RunWithinContext(ctx); err != nil {
509-
yield(StreamMessage{error: fmt.Errorf("failed to destroy containers: %w", err)})
510-
return
511-
}
512-
}
513-
}
514-
yield(StreamMessage{data: "App containers and volumes removed."})
515-
}
516-
}
517-
518502
func cleanAppCacheFiles(app app.ArduinoApp) iter.Seq[StreamMessage] {
519503
return func(yield func(StreamMessage) bool) {
520504
cachePath := app.FullPath.Join(".cache")

0 commit comments

Comments
 (0)