Skip to content

Commit d0bf1bf

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 d0bf1bf

File tree

5 files changed

+59
-0
lines changed

5 files changed

+59
-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: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ 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"
@@ -56,6 +57,7 @@ type Instance struct {
5657
Config *limayaml.LimaYAML `json:"config,omitempty"`
5758
SSHAddress string `json:"sshAddress,omitempty"`
5859
Protected bool `json:"protected"`
60+
LimaVersion string `json:"limaVersion"`
5961
}
6062

6163
func (inst *Instance) LoadYAML() (*limayaml.LimaYAML, error) {
@@ -167,6 +169,20 @@ func Inspect(instName string) (*Instance, error) {
167169
}
168170
}
169171
}
172+
173+
limaVersionFile := filepath.Join(instDir, filenames.LimaVersion)
174+
if version, err := os.ReadFile(limaVersionFile); err == nil {
175+
limaVersion := strings.TrimSpace(string(version))
176+
// Don't store invalid version strings because later code will not validate again
177+
if _, err := parseLimaVersion(limaVersion); err == nil {
178+
inst.LimaVersion = limaVersion
179+
} else {
180+
err = fmt.Errorf("cannot parse lima version %q from %q: %w", limaVersion, limaVersionFile, err)
181+
inst.Errors = append(inst.Errors, err)
182+
}
183+
} else if !errors.Is(err, os.ErrNotExist) {
184+
inst.Errors = append(inst.Errors, err)
185+
}
170186
return inst, nil
171187
}
172188

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

pkg/store/instance_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,11 @@ 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+
}

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)