Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/cmd/limactl/snapshot.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
"errors"
8
"fmt"
9
"strings"
10
11
"github.com/sirupsen/logrus"
12
"github.com/spf13/cobra"
13
14
"github.com/lima-vm/lima/v2/pkg/snapshot"
15
"github.com/lima-vm/lima/v2/pkg/store"
16
)
17
18
func newSnapshotCommand() *cobra.Command {
19
snapshotCmd := &cobra.Command{
20
Use: "snapshot",
21
Short: "Manage instance snapshots",
22
PersistentPreRun: func(*cobra.Command, []string) {
23
logrus.Warn("`limactl snapshot` is experimental")
24
},
25
GroupID: advancedCommand,
26
}
27
snapshotCmd.AddCommand(newSnapshotApplyCommand())
28
snapshotCmd.AddCommand(newSnapshotCreateCommand())
29
snapshotCmd.AddCommand(newSnapshotDeleteCommand())
30
snapshotCmd.AddCommand(newSnapshotListCommand())
31
32
return snapshotCmd
33
}
34
35
func newSnapshotCreateCommand() *cobra.Command {
36
createCmd := &cobra.Command{
37
Use: "create INSTANCE",
38
Aliases: []string{"save"},
39
Short: "Create (save) a snapshot",
40
Args: cobra.MinimumNArgs(1),
41
RunE: snapshotCreateAction,
42
ValidArgsFunction: snapshotBashComplete,
43
}
44
createCmd.Flags().String("tag", "", "Name of the snapshot")
45
46
return createCmd
47
}
48
49
func snapshotCreateAction(cmd *cobra.Command, args []string) error {
50
ctx := cmd.Context()
51
instName := args[0]
52
53
inst, err := store.Inspect(ctx, instName)
54
if err != nil {
55
return err
56
}
57
58
tag, err := cmd.Flags().GetString("tag")
59
if err != nil {
60
return err
61
}
62
63
if tag == "" {
64
return errors.New("expected tag")
65
}
66
67
return snapshot.Save(ctx, inst, tag)
68
}
69
70
func newSnapshotDeleteCommand() *cobra.Command {
71
deleteCmd := &cobra.Command{
72
Use: "delete INSTANCE",
73
Aliases: []string{"del"},
74
Short: "Delete (del) a snapshot",
75
Args: cobra.MinimumNArgs(1),
76
RunE: snapshotDeleteAction,
77
ValidArgsFunction: snapshotBashComplete,
78
}
79
deleteCmd.Flags().String("tag", "", "Name of the snapshot")
80
81
return deleteCmd
82
}
83
84
func snapshotDeleteAction(cmd *cobra.Command, args []string) error {
85
ctx := cmd.Context()
86
instName := args[0]
87
88
inst, err := store.Inspect(ctx, instName)
89
if err != nil {
90
return err
91
}
92
93
tag, err := cmd.Flags().GetString("tag")
94
if err != nil {
95
return err
96
}
97
98
if tag == "" {
99
return errors.New("expected tag")
100
}
101
102
return snapshot.Del(ctx, inst, tag)
103
}
104
105
func newSnapshotApplyCommand() *cobra.Command {
106
applyCmd := &cobra.Command{
107
Use: "apply INSTANCE",
108
Aliases: []string{"load"},
109
Short: "Apply (load) a snapshot",
110
Args: cobra.MinimumNArgs(1),
111
RunE: snapshotApplyAction,
112
ValidArgsFunction: snapshotBashComplete,
113
}
114
applyCmd.Flags().String("tag", "", "Name of the snapshot")
115
116
return applyCmd
117
}
118
119
func snapshotApplyAction(cmd *cobra.Command, args []string) error {
120
ctx := cmd.Context()
121
instName := args[0]
122
123
inst, err := store.Inspect(ctx, instName)
124
if err != nil {
125
return err
126
}
127
128
tag, err := cmd.Flags().GetString("tag")
129
if err != nil {
130
return err
131
}
132
133
if tag == "" {
134
return errors.New("expected tag")
135
}
136
137
return snapshot.Load(ctx, inst, tag)
138
}
139
140
func newSnapshotListCommand() *cobra.Command {
141
listCmd := &cobra.Command{
142
Use: "list INSTANCE",
143
Aliases: []string{"ls"},
144
Short: "List existing snapshots",
145
Args: cobra.MinimumNArgs(1),
146
RunE: snapshotListAction,
147
ValidArgsFunction: snapshotBashComplete,
148
}
149
listCmd.Flags().BoolP("quiet", "q", false, "Only show tags")
150
151
return listCmd
152
}
153
154
func snapshotListAction(cmd *cobra.Command, args []string) error {
155
ctx := cmd.Context()
156
instName := args[0]
157
158
inst, err := store.Inspect(ctx, instName)
159
if err != nil {
160
return err
161
}
162
163
quiet, err := cmd.Flags().GetBool("quiet")
164
if err != nil {
165
return err
166
}
167
out, err := snapshot.List(ctx, inst)
168
if err != nil {
169
return err
170
}
171
if quiet {
172
for i, line := range strings.Split(out, "\n") {
173
// "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT"
174
fields := strings.Fields(line)
175
if i == 0 && len(fields) > 1 && fields[1] != "TAG" {
176
// make sure that output matches the expected
177
return fmt.Errorf("unknown header: %s", line)
178
}
179
if i == 0 || line == "" {
180
// skip header and empty line after using split
181
continue
182
}
183
tag := fields[1]
184
fmt.Fprintf(cmd.OutOrStdout(), "%s\n", tag)
185
}
186
return nil
187
}
188
fmt.Fprint(cmd.OutOrStdout(), out)
189
return nil
190
}
191
192
func snapshotBashComplete(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
193
return bashCompleteInstanceNames(cmd)
194
}
195
196