Skip to content

Commit 97e4f19

Browse files
feat: implement app cache deletion (#59)
* feat: implement app cache deletion Introduce a `cache clean <app-id>` command to clean app cache. This implementation also tries to stop the related app if running. In case we do not care about that we can simply rm -rf `.cache/*`. Closes #52 * feature: add `--force` flag Add `--force` flag to forcefully terminate the app in case it's running, and then clean the related cache. * feat: add `clean-cache` under app * feat: apply CR suggestion * Update internal/orchestrator/cache.go Co-authored-by: Luca Rinaldi <to@lucar.in> * Update internal/orchestrator/cache.go Co-authored-by: Luca Rinaldi <to@lucar.in> --------- Co-authored-by: Luca Rinaldi <to@lucar.in>
1 parent 62e5944 commit 97e4f19

File tree

5 files changed

+116
-6
lines changed

5 files changed

+116
-6
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ func NewAppCmd(cfg config.Configuration) *cobra.Command {
3939
appCmd.AddCommand(newLogsCmd(cfg))
4040
appCmd.AddCommand(newListCmd(cfg))
4141
appCmd.AddCommand(newMonitorCmd(cfg))
42+
appCmd.AddCommand(newCacheCleanCmd(cfg))
4243

4344
return appCmd
4445
}

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

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package app
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/spf13/cobra"
8+
9+
"github.com/arduino/arduino-app-cli/cmd/arduino-app-cli/completion"
10+
"github.com/arduino/arduino-app-cli/cmd/arduino-app-cli/internal/servicelocator"
11+
"github.com/arduino/arduino-app-cli/cmd/feedback"
12+
"github.com/arduino/arduino-app-cli/internal/orchestrator"
13+
"github.com/arduino/arduino-app-cli/internal/orchestrator/app"
14+
"github.com/arduino/arduino-app-cli/internal/orchestrator/config"
15+
)
16+
17+
func newCacheCleanCmd(cfg config.Configuration) *cobra.Command {
18+
var forceClean bool
19+
appCmd := &cobra.Command{
20+
Use: "clean-cache <app-id>",
21+
Short: "Delete app cache",
22+
Args: cobra.ExactArgs(1),
23+
RunE: func(cmd *cobra.Command, args []string) error {
24+
app, err := Load(args[0])
25+
if err != nil {
26+
return err
27+
}
28+
return cacheCleanHandler(cmd.Context(), app, forceClean)
29+
},
30+
ValidArgsFunction: completion.ApplicationNames(cfg),
31+
}
32+
appCmd.Flags().BoolVarP(&forceClean, "force", "", false, "Forcefully clean the cache even if the app is running")
33+
34+
return appCmd
35+
}
36+
37+
func cacheCleanHandler(ctx context.Context, app app.ArduinoApp, forceClean bool) error {
38+
err := orchestrator.CleanAppCache(
39+
ctx,
40+
servicelocator.GetDockerClient(),
41+
app,
42+
orchestrator.CleanAppCacheRequest{ForceClean: forceClean},
43+
)
44+
if err != nil {
45+
feedback.Fatal(err.Error(), feedback.ErrGeneric)
46+
}
47+
feedback.PrintResult(cacheCleanResult{
48+
AppName: app.Name,
49+
Path: app.ProvisioningStateDir().String(),
50+
})
51+
return nil
52+
}
53+
54+
type cacheCleanResult struct {
55+
AppName string `json:"appName"`
56+
Path string `json:"path"`
57+
}
58+
59+
func (r cacheCleanResult) String() string {
60+
return fmt.Sprintf("✓ Cache of %q App cleaned", r.AppName)
61+
}
62+
63+
func (r cacheCleanResult) Data() interface{} {
64+
return r
65+
}

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ require (
129129
github.com/fsnotify/fsnotify v1.9.0 // indirect
130130
github.com/fvbommel/sortorder v1.1.0 // indirect
131131
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
132-
github.com/getkin/kin-openapi v0.132.0 // indirect
132+
github.com/getkin/kin-openapi v0.133.0 // indirect
133133
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
134134
github.com/go-git/go-billy/v5 v5.6.2 // indirect
135135
github.com/go-git/go-git/v5 v5.16.2 // indirect
@@ -206,7 +206,7 @@ require (
206206
github.com/morikuni/aec v1.0.0 // indirect
207207
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
208208
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
209-
github.com/oapi-codegen/oapi-codegen/v2 v2.5.0 // indirect
209+
github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 // indirect
210210
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect
211211
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
212212
github.com/opencontainers/go-digest v1.0.0 // indirect
@@ -257,6 +257,7 @@ require (
257257
github.com/ulikunitz/xz v0.5.15 // indirect
258258
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
259259
github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect
260+
github.com/woodsbury/decimal128 v1.3.0 // indirect
260261
github.com/x448/float16 v0.8.4 // indirect
261262
github.com/xanzy/ssh-agent v0.3.3 // indirect
262263
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect

go.sum

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQ
310310
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
311311
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
312312
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
313-
github.com/getkin/kin-openapi v0.132.0 h1:3ISeLMsQzcb5v26yeJrBcdTCEQTag36ZjaGk7MIRUwk=
314-
github.com/getkin/kin-openapi v0.132.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58=
313+
github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ=
314+
github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE=
315315
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
316316
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
317317
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
@@ -676,8 +676,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
676676
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
677677
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
678678
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
679-
github.com/oapi-codegen/oapi-codegen/v2 v2.5.0 h1:iJvF8SdB/3/+eGOXEpsWkD8FQAHj6mqkb6Fnsoc8MFU=
680-
github.com/oapi-codegen/oapi-codegen/v2 v2.5.0/go.mod h1:fwlMxUEMuQK5ih9aymrxKPQqNm2n8bdLk1ppjH+lr9w=
679+
github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc=
680+
github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ=
681681
github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro=
682682
github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
683683
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=
@@ -909,6 +909,8 @@ github.com/warthog618/go-gpiocdev v0.9.1 h1:pwHPaqjJfhCipIQl78V+O3l9OKHivdRDdmgX
909909
github.com/warthog618/go-gpiocdev v0.9.1/go.mod h1:dN3e3t/S2aSNC+hgigGE/dBW8jE1ONk9bDSEYfoPyl8=
910910
github.com/warthog618/go-gpiosim v0.1.1 h1:MRAEv+T+itmw+3GeIGpQJBfanUVyg0l3JCTwHtwdre4=
911911
github.com/warthog618/go-gpiosim v0.1.1/go.mod h1:YXsnB+I9jdCMY4YAlMSRrlts25ltjmuIsrnoUrBLdqU=
912+
github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0=
913+
github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds=
912914
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
913915
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
914916
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=

internal/orchestrator/cache.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package orchestrator
2+
3+
import (
4+
"context"
5+
"errors"
6+
7+
"github.com/docker/cli/cli/command"
8+
9+
"github.com/arduino/arduino-app-cli/internal/orchestrator/app"
10+
)
11+
12+
type CleanAppCacheRequest struct {
13+
ForceClean bool
14+
}
15+
16+
var ErrCleanCacheRunningApp = errors.New("cannot remove cache of a running app")
17+
18+
// CleanAppCache removes the `.cache` folder. If it detects that the app is running
19+
// it tries to stop it first.
20+
func CleanAppCache(
21+
ctx context.Context,
22+
docker command.Cli,
23+
app app.ArduinoApp,
24+
req CleanAppCacheRequest,
25+
) error {
26+
runningApp, err := getRunningApp(ctx, docker.Client())
27+
if err != nil {
28+
return err
29+
}
30+
if runningApp != nil && runningApp.FullPath.EqualsTo(app.FullPath) {
31+
if !req.ForceClean {
32+
return ErrCleanCacheRunningApp
33+
}
34+
// We try to remove docker related resources at best effort
35+
for range StopAndDestroyApp(ctx, app) {
36+
// just consume the iterator
37+
}
38+
}
39+
40+
return app.ProvisioningStateDir().RemoveAll()
41+
}

0 commit comments

Comments
 (0)