Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/cmd/limactl/prune.go
1645 views
1
// SPDX-FileCopyrightText: Copyright The Lima Authors
2
// SPDX-License-Identifier: Apache-2.0
3
4
package main
5
6
import (
7
"context"
8
"fmt"
9
"maps"
10
"os"
11
12
"github.com/sirupsen/logrus"
13
"github.com/spf13/cobra"
14
15
"github.com/lima-vm/lima/v2/pkg/downloader"
16
"github.com/lima-vm/lima/v2/pkg/driverutil"
17
"github.com/lima-vm/lima/v2/pkg/limatype"
18
"github.com/lima-vm/lima/v2/pkg/limayaml"
19
"github.com/lima-vm/lima/v2/pkg/store"
20
"github.com/lima-vm/lima/v2/pkg/templatestore"
21
)
22
23
func newPruneCommand() *cobra.Command {
24
pruneCommand := &cobra.Command{
25
Use: "prune",
26
Short: "Prune garbage objects",
27
Args: WrapArgsError(cobra.NoArgs),
28
RunE: pruneAction,
29
ValidArgsFunction: cobra.NoFileCompletions,
30
GroupID: advancedCommand,
31
}
32
pruneCommand.Flags().Bool("keep-referred", false, "Keep objects that are referred by some instances or templates")
33
return pruneCommand
34
}
35
36
func pruneAction(cmd *cobra.Command, _ []string) error {
37
ctx := cmd.Context()
38
keepReferred, err := cmd.Flags().GetBool("keep-referred")
39
if err != nil {
40
return err
41
}
42
opt := downloader.WithCache()
43
if !keepReferred {
44
return downloader.RemoveAllCacheDir(opt)
45
}
46
47
// Prune downloads that are not used by any instances or templates
48
cacheEntries, err := downloader.CacheEntries(opt)
49
if err != nil {
50
return err
51
}
52
knownLocations, err := knownLocations(ctx)
53
if err != nil {
54
return err
55
}
56
for cacheKey, cachePath := range cacheEntries {
57
if file, exists := knownLocations[cacheKey]; exists {
58
logrus.Debugf("Keep %q caching %q", cacheKey, file.Location)
59
} else {
60
logrus.Debug("Deleting ", cacheKey)
61
if err := os.RemoveAll(cachePath); err != nil {
62
logrus.Warnf("Failed to delete %q: %v", cacheKey, err)
63
return err
64
}
65
}
66
}
67
return nil
68
}
69
70
func knownLocations(ctx context.Context) (map[string]limatype.File, error) {
71
locations := make(map[string]limatype.File)
72
73
// Collect locations from instances
74
instances, err := store.Instances()
75
if err != nil {
76
return nil, err
77
}
78
for _, instanceName := range instances {
79
instance, err := store.Inspect(ctx, instanceName)
80
if err != nil {
81
return nil, err
82
}
83
maps.Copy(locations, locationsFromLimaYAML(instance.Config))
84
}
85
86
// Collect locations from templates
87
templates, err := templatestore.Templates()
88
if err != nil {
89
return nil, err
90
}
91
for _, t := range templates {
92
b, err := templatestore.Read(t.Name)
93
if err != nil {
94
return nil, err
95
}
96
y, err := limayaml.Load(ctx, b, t.Name)
97
if err != nil {
98
return nil, err
99
}
100
if err := driverutil.ResolveVMType(ctx, y, t.Name); err != nil {
101
return nil, fmt.Errorf("failed to resolve vm for %q: %w", t.Name, err)
102
}
103
maps.Copy(locations, locationsFromLimaYAML(y))
104
}
105
return locations, nil
106
}
107
108
func locationsFromLimaYAML(y *limatype.LimaYAML) map[string]limatype.File {
109
locations := make(map[string]limatype.File)
110
for _, f := range y.Images {
111
locations[downloader.CacheKey(f.Location)] = f.File
112
if f.Kernel != nil {
113
locations[downloader.CacheKey(f.Kernel.Location)] = f.Kernel.File
114
}
115
if f.Initrd != nil {
116
locations[downloader.CacheKey(f.Initrd.Location)] = *f.Initrd
117
}
118
}
119
for _, f := range y.Containerd.Archives {
120
locations[downloader.CacheKey(f.Location)] = f
121
}
122
for _, f := range y.Firmware.Images {
123
locations[downloader.CacheKey(f.Location)] = f.File
124
}
125
return locations
126
}
127
128