@@ -2,8 +2,11 @@ package main
2
2
3
3
import (
4
4
"os"
5
- "path/filepath"
6
5
6
+ "github.com/lima-vm/lima/pkg/downloader"
7
+ "github.com/lima-vm/lima/pkg/limayaml"
8
+ "github.com/lima-vm/lima/pkg/store"
9
+ "github.com/lima-vm/lima/pkg/templatestore"
7
10
"github.com/sirupsen/logrus"
8
11
"github.com/spf13/cobra"
9
12
)
@@ -17,15 +20,98 @@ func newPruneCommand() *cobra.Command {
17
20
ValidArgsFunction : cobra .NoFileCompletions ,
18
21
GroupID : advancedCommand ,
19
22
}
23
+ pruneCommand .Flags ().Bool ("keep-referred" , false , "Keep objects that are referred by some instances or templates" )
20
24
return pruneCommand
21
25
}
22
26
23
- func pruneAction (_ * cobra.Command , _ []string ) error {
24
- ucd , err := os . UserCacheDir ( )
27
+ func pruneAction (cmd * cobra.Command , _ []string ) error {
28
+ keepReferred , err := cmd . Flags (). GetBool ( "keep-referred" )
25
29
if err != nil {
26
30
return err
27
31
}
28
- cacheDir := filepath .Join (ucd , "lima" )
29
- logrus .Infof ("Pruning %q" , cacheDir )
30
- return os .RemoveAll (cacheDir )
32
+ opt := downloader .WithCache ()
33
+ if ! keepReferred {
34
+ return downloader .RemoveAllCacheDir (opt )
35
+ }
36
+
37
+ // Prune downloads that are not used by any instances or templates
38
+ cacheEntries , err := downloader .CacheEntries (opt )
39
+ if err != nil {
40
+ return err
41
+ }
42
+ knownLocations , err := knownLocations ()
43
+ if err != nil {
44
+ return err
45
+ }
46
+ for cacheKey , cachePath := range cacheEntries {
47
+ if file , exists := knownLocations [cacheKey ]; exists {
48
+ logrus .Debugf ("Keep %q caching %q" , cacheKey , file .Location )
49
+ } else {
50
+ logrus .Debug ("Deleting " , cacheKey )
51
+ if err := os .RemoveAll (cachePath ); err != nil {
52
+ logrus .Warnf ("Failed to delete %q: %v" , cacheKey , err )
53
+ return err
54
+ }
55
+ }
56
+ }
57
+ return nil
58
+ }
59
+
60
+ func knownLocations () (map [string ]limayaml.File , error ) {
61
+ locations := make (map [string ]limayaml.File )
62
+
63
+ // Collect locations from instances
64
+ instances , err := store .Instances ()
65
+ if err != nil {
66
+ return nil , err
67
+ }
68
+ for _ , instanceName := range instances {
69
+ instance , err := store .Inspect (instanceName )
70
+ if err != nil {
71
+ return nil , err
72
+ }
73
+ for k , v := range locationsFromLimaYAML (instance .Config ) {
74
+ locations [k ] = v
75
+ }
76
+ }
77
+
78
+ // Collect locations from templates
79
+ templates , err := templatestore .Templates ()
80
+ if err != nil {
81
+ return nil , err
82
+ }
83
+ for _ , t := range templates {
84
+ b , err := templatestore .Read (t .Name )
85
+ if err != nil {
86
+ return nil , err
87
+ }
88
+ y , err := limayaml .Load (b , t .Name )
89
+ if err != nil {
90
+ return nil , err
91
+ }
92
+ for k , v := range locationsFromLimaYAML (y ) {
93
+ locations [k ] = v
94
+ }
95
+ }
96
+ return locations , nil
97
+ }
98
+
99
+ func locationsFromLimaYAML (y * limayaml.LimaYAML ) map [string ]limayaml.File {
100
+ locations := make (map [string ]limayaml.File )
101
+ for _ , f := range y .Images {
102
+ locations [downloader .CacheKey (f .Location )] = f .File
103
+ if f .Kernel != nil {
104
+ locations [downloader .CacheKey (f .Kernel .Location )] = f .Kernel .File
105
+ }
106
+ if f .Initrd != nil {
107
+ locations [downloader .CacheKey (f .Initrd .Location )] = * f .Initrd
108
+ }
109
+ }
110
+ for _ , f := range y .Containerd .Archives {
111
+ locations [downloader .CacheKey (f .Location )] = f
112
+ }
113
+ for _ , f := range y .Firmware .Images {
114
+ locations [downloader .CacheKey (f .Location )] = f .File
115
+ }
116
+ return locations
31
117
}
0 commit comments