Skip to content

Commit

Permalink
Merge pull request #2107 from rancher-sandbox/lima-version
Browse files Browse the repository at this point in the history
Store Lima version in the instance directory
  • Loading branch information
AkihiroSuda authored Jan 12, 2024
2 parents c12d475 + 10cbcd1 commit a00bd52
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cmd/limactl/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/lima-vm/lima/pkg/store/filenames"
"github.com/lima-vm/lima/pkg/templatestore"
"github.com/lima-vm/lima/pkg/uiutil"
"github.com/lima-vm/lima/pkg/version"
"github.com/lima-vm/lima/pkg/yqutil"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -332,6 +333,9 @@ func createInstance(ctx context.Context, st *creatorState, saveBrokenEditorBuffe
if err := os.WriteFile(filePath, st.yBytes, 0o644); err != nil {
return nil, err
}
if err := os.WriteFile(filepath.Join(instDir, filenames.LimaVersion), []byte(version.Version), 0o444); err != nil {
return nil, err
}

inst, err := store.Inspect(st.instName)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/store/filenames/filenames.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (

const (
LimaYAML = "lima.yaml"
LimaVersion = "lima-version" // Lima version used to create instance
CIDataISO = "cidata.iso"
CIDataISODir = "cidata"
BaseDisk = "basedisk"
Expand Down
46 changes: 46 additions & 0 deletions pkg/store/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import (
"text/template"
"time"

"github.com/coreos/go-semver/semver"
"github.com/docker/go-units"
hostagentclient "github.com/lima-vm/lima/pkg/hostagent/api/client"
"github.com/lima-vm/lima/pkg/limayaml"
"github.com/lima-vm/lima/pkg/store/dirnames"
"github.com/lima-vm/lima/pkg/store/filenames"
"github.com/lima-vm/lima/pkg/textutil"
"github.com/sirupsen/logrus"
)

type Status = string
Expand Down Expand Up @@ -56,6 +58,7 @@ type Instance struct {
Config *limayaml.LimaYAML `json:"config,omitempty"`
SSHAddress string `json:"sshAddress,omitempty"`
Protected bool `json:"protected"`
LimaVersion string `json:"limaVersion"`
}

func (inst *Instance) LoadYAML() (*limayaml.LimaYAML, error) {
Expand Down Expand Up @@ -167,6 +170,16 @@ func Inspect(instName string) (*Instance, error) {
}
}
}

limaVersionFile := filepath.Join(instDir, filenames.LimaVersion)
if version, err := os.ReadFile(limaVersionFile); err == nil {
inst.LimaVersion = strings.TrimSpace(string(version))
if _, err = parseLimaVersion(inst.LimaVersion); err != nil {
logrus.Warnf("treating lima version %q from %q as very latest release", inst.LimaVersion, limaVersionFile)
}
} else if !errors.Is(err, os.ErrNotExist) {
inst.Errors = append(inst.Errors, err)
}
return inst, nil
}

Expand Down Expand Up @@ -423,3 +436,36 @@ func (inst *Instance) Unprotect() error {
inst.Protected = false
return nil
}

// parseLimaVersion parses a Lima version string by removing the leading "v" character and
// stripping everything from the first "-" forward (which are `git describe` artifacts and
// not semver pre-release markers). So "v0.19.1-16-gf3dc6ed.m" will be parsed as "0.19.1".
func parseLimaVersion(version string) (*semver.Version, error) {
version = strings.TrimPrefix(version, "v")
version, _, _ = strings.Cut(version, "-")
return semver.NewVersion(version)
}

// LimaVersionGreaterThan returns true if the Lima version used to create an instance is greater
// than a specific older version. Always returns false if the Lima version is the empty string.
// Unparsable lima versions (like SHA1 commit ids) are treated as the latest version and return true.
// limaVersion is a `github describe` string, not a semantic version. So "0.19.1-16-gf3dc6ed.m"
// will be considered greater than "0.19.1".
func LimaVersionGreaterThan(limaVersion, oldVersion string) bool {
if limaVersion == "" {
return false
}
version, err := parseLimaVersion(limaVersion)
if err != nil {
return true
}
switch version.Compare(*semver.New(oldVersion)) {
case -1:
return false
case +1:
return true
case 0:
return strings.Contains(limaVersion, "-")
}
panic("unreachable")
}
9 changes: 9 additions & 0 deletions pkg/store/instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,12 @@ func TestPrintInstanceTableTwo(t *testing.T) {
assert.NilError(t, err)
assert.Equal(t, tableTwo, buf.String())
}

func TestLimaVersionGreaterThan(t *testing.T) {
assert.Equal(t, LimaVersionGreaterThan("", "0.1.0"), false)
assert.Equal(t, LimaVersionGreaterThan("0.0.1", "0.1.0"), false)
assert.Equal(t, LimaVersionGreaterThan("0.1.0", "0.1.0"), false)
assert.Equal(t, LimaVersionGreaterThan("0.1.0-2", "0.1.0"), true)
assert.Equal(t, LimaVersionGreaterThan("0.2.0", "0.1.0"), true)
assert.Equal(t, LimaVersionGreaterThan("abacab", "0.1.0"), true)
}
1 change: 1 addition & 0 deletions website/content/en/docs/dev/Internals/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ having to specify an identity explicitly.
An instance directory contains the following files:

Metadata:
- `lima-version`: the Lima version used to create this instance
- `lima.yaml`: the YAML
- `protected`: empty file, used by `limactl protect`

Expand Down

0 comments on commit a00bd52

Please sign in to comment.