Skip to content

Commit 10cbcd1

Browse files
committed
Store Lima version in the instance directory
That way future Lima releases can make decisions about default settings based on the Lima version that created the instance instead of the current instance, and settings for existing instances will not change just because the user updated Lima. Signed-off-by: Jan Dubois <[email protected]>
1 parent f3dc6ed commit 10cbcd1

File tree

5 files changed

+61
-0
lines changed

5 files changed

+61
-0
lines changed

cmd/limactl/start.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/lima-vm/lima/pkg/store/filenames"
2424
"github.com/lima-vm/lima/pkg/templatestore"
2525
"github.com/lima-vm/lima/pkg/uiutil"
26+
"github.com/lima-vm/lima/pkg/version"
2627
"github.com/lima-vm/lima/pkg/yqutil"
2728
"github.com/sirupsen/logrus"
2829
"github.com/spf13/cobra"
@@ -332,6 +333,9 @@ func createInstance(ctx context.Context, st *creatorState, saveBrokenEditorBuffe
332333
if err := os.WriteFile(filePath, st.yBytes, 0o644); err != nil {
333334
return nil, err
334335
}
336+
if err := os.WriteFile(filepath.Join(instDir, filenames.LimaVersion), []byte(version.Version), 0o444); err != nil {
337+
return nil, err
338+
}
335339

336340
inst, err := store.Inspect(st.instName)
337341
if err != nil {

pkg/store/filenames/filenames.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const (
2727

2828
const (
2929
LimaYAML = "lima.yaml"
30+
LimaVersion = "lima-version" // Lima version used to create instance
3031
CIDataISO = "cidata.iso"
3132
CIDataISODir = "cidata"
3233
BaseDisk = "basedisk"

pkg/store/instance.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ import (
1616
"text/template"
1717
"time"
1818

19+
"github.com/coreos/go-semver/semver"
1920
"github.com/docker/go-units"
2021
hostagentclient "github.com/lima-vm/lima/pkg/hostagent/api/client"
2122
"github.com/lima-vm/lima/pkg/limayaml"
2223
"github.com/lima-vm/lima/pkg/store/dirnames"
2324
"github.com/lima-vm/lima/pkg/store/filenames"
2425
"github.com/lima-vm/lima/pkg/textutil"
26+
"github.com/sirupsen/logrus"
2527
)
2628

2729
type Status = string
@@ -56,6 +58,7 @@ type Instance struct {
5658
Config *limayaml.LimaYAML `json:"config,omitempty"`
5759
SSHAddress string `json:"sshAddress,omitempty"`
5860
Protected bool `json:"protected"`
61+
LimaVersion string `json:"limaVersion"`
5962
}
6063

6164
func (inst *Instance) LoadYAML() (*limayaml.LimaYAML, error) {
@@ -167,6 +170,16 @@ func Inspect(instName string) (*Instance, error) {
167170
}
168171
}
169172
}
173+
174+
limaVersionFile := filepath.Join(instDir, filenames.LimaVersion)
175+
if version, err := os.ReadFile(limaVersionFile); err == nil {
176+
inst.LimaVersion = strings.TrimSpace(string(version))
177+
if _, err = parseLimaVersion(inst.LimaVersion); err != nil {
178+
logrus.Warnf("treating lima version %q from %q as very latest release", inst.LimaVersion, limaVersionFile)
179+
}
180+
} else if !errors.Is(err, os.ErrNotExist) {
181+
inst.Errors = append(inst.Errors, err)
182+
}
170183
return inst, nil
171184
}
172185

@@ -423,3 +436,36 @@ func (inst *Instance) Unprotect() error {
423436
inst.Protected = false
424437
return nil
425438
}
439+
440+
// parseLimaVersion parses a Lima version string by removing the leading "v" character and
441+
// stripping everything from the first "-" forward (which are `git describe` artifacts and
442+
// not semver pre-release markers). So "v0.19.1-16-gf3dc6ed.m" will be parsed as "0.19.1".
443+
func parseLimaVersion(version string) (*semver.Version, error) {
444+
version = strings.TrimPrefix(version, "v")
445+
version, _, _ = strings.Cut(version, "-")
446+
return semver.NewVersion(version)
447+
}
448+
449+
// LimaVersionGreaterThan returns true if the Lima version used to create an instance is greater
450+
// than a specific older version. Always returns false if the Lima version is the empty string.
451+
// Unparsable lima versions (like SHA1 commit ids) are treated as the latest version and return true.
452+
// limaVersion is a `github describe` string, not a semantic version. So "0.19.1-16-gf3dc6ed.m"
453+
// will be considered greater than "0.19.1".
454+
func LimaVersionGreaterThan(limaVersion, oldVersion string) bool {
455+
if limaVersion == "" {
456+
return false
457+
}
458+
version, err := parseLimaVersion(limaVersion)
459+
if err != nil {
460+
return true
461+
}
462+
switch version.Compare(*semver.New(oldVersion)) {
463+
case -1:
464+
return false
465+
case +1:
466+
return true
467+
case 0:
468+
return strings.Contains(limaVersion, "-")
469+
}
470+
panic("unreachable")
471+
}

pkg/store/instance_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,12 @@ func TestPrintInstanceTableTwo(t *testing.T) {
155155
assert.NilError(t, err)
156156
assert.Equal(t, tableTwo, buf.String())
157157
}
158+
159+
func TestLimaVersionGreaterThan(t *testing.T) {
160+
assert.Equal(t, LimaVersionGreaterThan("", "0.1.0"), false)
161+
assert.Equal(t, LimaVersionGreaterThan("0.0.1", "0.1.0"), false)
162+
assert.Equal(t, LimaVersionGreaterThan("0.1.0", "0.1.0"), false)
163+
assert.Equal(t, LimaVersionGreaterThan("0.1.0-2", "0.1.0"), true)
164+
assert.Equal(t, LimaVersionGreaterThan("0.2.0", "0.1.0"), true)
165+
assert.Equal(t, LimaVersionGreaterThan("abacab", "0.1.0"), true)
166+
}

website/content/en/docs/dev/Internals/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ having to specify an identity explicitly.
3030
An instance directory contains the following files:
3131

3232
Metadata:
33+
- `lima-version`: the Lima version used to create this instance
3334
- `lima.yaml`: the YAML
3435
- `protected`: empty file, used by `limactl protect`
3536

0 commit comments

Comments
 (0)