Skip to content

Commit c397481

Browse files
committed
limactl prune: add --keep-referred option to keep objects that are referred by some instances or templates
Signed-off-by: Norio Nomura <[email protected]>
1 parent b3067dc commit c397481

File tree

1 file changed

+107
-2
lines changed

1 file changed

+107
-2
lines changed

cmd/limactl/prune.go

+107-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package main
22

33
import (
4+
"crypto/sha256"
5+
"fmt"
46
"os"
57
"path/filepath"
68

9+
"github.com/lima-vm/lima/pkg/limayaml"
10+
"github.com/lima-vm/lima/pkg/store"
11+
"github.com/lima-vm/lima/pkg/templatestore"
712
"github.com/sirupsen/logrus"
813
"github.com/spf13/cobra"
914
)
@@ -17,15 +22,115 @@ func newPruneCommand() *cobra.Command {
1722
ValidArgsFunction: cobra.NoFileCompletions,
1823
GroupID: advancedCommand,
1924
}
25+
pruneCommand.Flags().Bool("keep-referred", false, "Keep objects that are referred by some instances or templates")
2026
return pruneCommand
2127
}
2228

23-
func pruneAction(_ *cobra.Command, _ []string) error {
29+
func pruneAction(cmd *cobra.Command, _ []string) error {
30+
keepReferred, err := cmd.Flags().GetBool("keep-referred")
31+
if err != nil {
32+
return err
33+
}
2434
ucd, err := os.UserCacheDir()
2535
if err != nil {
2636
return err
2737
}
2838
cacheDir := filepath.Join(ucd, "lima")
2939
logrus.Infof("Pruning %q", cacheDir)
30-
return os.RemoveAll(cacheDir)
40+
if !keepReferred {
41+
return os.RemoveAll(cacheDir)
42+
}
43+
44+
// Prune downloads that are not used by any instances or templates
45+
downloadDir := filepath.Join(cacheDir, "download", "by-url-sha256")
46+
_, err = os.Stat(downloadDir)
47+
if err != nil {
48+
if os.IsNotExist(err) {
49+
return nil
50+
}
51+
return err
52+
}
53+
cacheEntries, err := os.ReadDir(downloadDir)
54+
if err != nil {
55+
return err
56+
}
57+
knownLocations, err := knownLocations()
58+
if err != nil {
59+
return err
60+
}
61+
for _, entry := range cacheEntries {
62+
if file, exists := knownLocations[entry.Name()]; exists {
63+
logrus.Debugf("Keep %q caching %q", entry.Name(), file.Location)
64+
} else {
65+
logrus.Debug("Deleting ", entry.Name())
66+
if err := os.RemoveAll(filepath.Join(downloadDir, entry.Name())); err != nil {
67+
logrus.Warnf("Failed to delete %q: %v", entry.Name(), err)
68+
return err
69+
}
70+
}
71+
}
72+
return nil
73+
}
74+
75+
func knownLocations() (map[string]limayaml.File, error) {
76+
locations := make(map[string]limayaml.File)
77+
78+
// Collect locations from instances
79+
instances, err := store.Instances()
80+
if err != nil {
81+
return nil, err
82+
}
83+
for _, instanceName := range instances {
84+
instance, err := store.Inspect(instanceName)
85+
if err != nil {
86+
return nil, err
87+
}
88+
for k, v := range locationsFromLimaYAML(instance.Config) {
89+
locations[k] = v
90+
}
91+
}
92+
93+
// Collect locations from templates
94+
templates, err := templatestore.Templates()
95+
if err != nil {
96+
return nil, err
97+
}
98+
for _, t := range templates {
99+
b, err := templatestore.Read(t.Name)
100+
if err != nil {
101+
return nil, err
102+
}
103+
y, err := limayaml.Load(b, t.Name)
104+
if err != nil {
105+
return nil, err
106+
}
107+
for k, v := range locationsFromLimaYAML(y) {
108+
locations[k] = v
109+
}
110+
}
111+
return locations, nil
112+
}
113+
114+
func locationsFromLimaYAML(y *limayaml.LimaYAML) map[string]limayaml.File {
115+
locations := make(map[string]limayaml.File)
116+
for _, f := range y.Images {
117+
locations[sha256OfURL(f.Location)] = f.File
118+
if f.Kernel != nil {
119+
locations[sha256OfURL(f.Kernel.Location)] = f.Kernel.File
120+
}
121+
if f.Initrd != nil {
122+
locations[sha256OfURL(f.Initrd.Location)] = *f.Initrd
123+
}
124+
}
125+
for _, f := range y.Containerd.Archives {
126+
locations[sha256OfURL(f.Location)] = f
127+
}
128+
for _, f := range y.Firmware.Images {
129+
locations[sha256OfURL(f.Location)] = f.File
130+
}
131+
return locations
132+
}
133+
134+
func sha256OfURL(url string) string {
135+
return fmt.Sprintf("%x", sha256.Sum256([]byte(url)))
31136
}

0 commit comments

Comments
 (0)