diff --git a/cmd/limactl/copy.go b/cmd/limactl/copy.go index 3d4ec4a77e9..038f0b395b8 100644 --- a/cmd/limactl/copy.go +++ b/cmd/limactl/copy.go @@ -48,10 +48,7 @@ func copyAction(cmd *cobra.Command, args []string) error { if err != nil { return err } - u, err := osutil.LimaUser(false) - if err != nil { - return err - } + instDirs := make(map[string]string) scpFlags := []string{} scpArgs := []string{} @@ -86,6 +83,10 @@ func copyAction(cmd *cobra.Command, args []string) error { if inst.Status == store.StatusStopped { return fmt.Errorf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName) } + u, err := osutil.LimaUser(false, inst.LimaVersion) + if err != nil { + return err + } if legacySSH { scpFlags = append(scpFlags, "-P", fmt.Sprintf("%d", inst.SSHLocalPort)) scpArgs = append(scpArgs, fmt.Sprintf("%s@127.0.0.1:%s", u.Username, path[1])) diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index 71096c1de76..27ab1e60f30 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -25,6 +25,7 @@ import ( "github.com/lima-vm/lima/pkg/sshutil" "github.com/lima-vm/lima/pkg/store/filenames" "github.com/lima-vm/lima/pkg/usrlocalsharelima" + "github.com/lima-vm/lima/pkg/version" "github.com/sirupsen/logrus" ) @@ -115,7 +116,7 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort if err := limayaml.Validate(y, false); err != nil { return err } - u, err := osutil.LimaUser(true) + u, err := osutil.LimaUser(true, version.Version) if err != nil { return err } diff --git a/pkg/limayaml/defaults.go b/pkg/limayaml/defaults.go index 8ac8c26c7bd..98fc6a82b4b 100644 --- a/pkg/limayaml/defaults.go +++ b/pkg/limayaml/defaults.go @@ -27,6 +27,7 @@ import ( "github.com/lima-vm/lima/pkg/ptr" "github.com/lima-vm/lima/pkg/store/dirnames" "github.com/lima-vm/lima/pkg/store/filenames" + "github.com/lima-vm/lima/pkg/version/versionutil" ) const ( @@ -753,8 +754,10 @@ func fixUpForPlainMode(y *LimaYAML) { func executeGuestTemplate(format, instDir string, param map[string]string) (bytes.Buffer, error) { tmpl, err := template.New("").Parse(format) + limaVersion := ReadInstLimaVersion(instDir) + if err == nil { - user, _ := osutil.LimaUser(false) + user, _ := osutil.LimaUser(false, limaVersion) data := map[string]interface{}{ "Home": fmt.Sprintf("/home/%s.linux", user.Username), "Name": filepath.Base(instDir), @@ -771,9 +774,11 @@ func executeGuestTemplate(format, instDir string, param map[string]string) (byte } func executeHostTemplate(format, instDir string, param map[string]string) (bytes.Buffer, error) { + limaVersion := ReadInstLimaVersion(instDir) + tmpl, err := template.New("").Parse(format) if err == nil { - user, _ := osutil.LimaUser(false) + user, _ := osutil.LimaUser(false, limaVersion) home, _ := os.UserHomeDir() limaHome, _ := dirnames.LimaDir() data := map[string]interface{}{ @@ -1074,3 +1079,15 @@ func unique(s []string) []string { } return list } + +func ReadInstLimaVersion(instDir string) string { + limaVersionFile := filepath.Join(instDir, filenames.LimaVersion) + limaVersion := "" + if version, err := os.ReadFile(limaVersionFile); err == nil { + limaVersion = strings.TrimSpace(string(version)) + if _, err = versionutil.Parse(limaVersion); err != nil { + logrus.Warnf("treating lima version %q from %q as very latest release", limaVersion, limaVersionFile) + } + } + return limaVersion +} diff --git a/pkg/limayaml/defaults_test.go b/pkg/limayaml/defaults_test.go index 7571baa2c2f..aeaa725cade 100644 --- a/pkg/limayaml/defaults_test.go +++ b/pkg/limayaml/defaults_test.go @@ -14,6 +14,7 @@ import ( "github.com/lima-vm/lima/pkg/ptr" "github.com/lima-vm/lima/pkg/store/dirnames" "github.com/lima-vm/lima/pkg/store/filenames" + "github.com/lima-vm/lima/pkg/version" "github.com/sirupsen/logrus" "gotest.tools/v3/assert" ) @@ -53,7 +54,7 @@ func TestFillDefault(t *testing.T) { assert.NilError(t, err) limaHome, err := dirnames.LimaDir() assert.NilError(t, err) - user, err := osutil.LimaUser(false) + user, err := osutil.LimaUser(false, version.Version) assert.NilError(t, err) guestHome := fmt.Sprintf("/home/%s.linux", user.Username) diff --git a/pkg/limayaml/validate.go b/pkg/limayaml/validate.go index 8eb719ede32..ceadec34f16 100644 --- a/pkg/limayaml/validate.go +++ b/pkg/limayaml/validate.go @@ -15,6 +15,7 @@ import ( "github.com/lima-vm/lima/pkg/localpathutil" "github.com/lima-vm/lima/pkg/networks" "github.com/lima-vm/lima/pkg/osutil" + "github.com/lima-vm/lima/pkg/version" "github.com/sirupsen/logrus" ) @@ -117,7 +118,7 @@ func Validate(y *LimaYAML, warn bool) error { return fmt.Errorf("field `memory` has an invalid value: %w", err) } - u, err := osutil.LimaUser(false) + u, err := osutil.LimaUser(false, version.Version) if err != nil { return fmt.Errorf("internal error (not an error of YAML): %w", err) } diff --git a/pkg/osutil/user.go b/pkg/osutil/user.go index 7474296bca3..4abc6114023 100644 --- a/pkg/osutil/user.go +++ b/pkg/osutil/user.go @@ -11,6 +11,7 @@ import ( "strings" "sync" + "github.com/lima-vm/lima/pkg/version/versionutil" "github.com/sirupsen/logrus" ) @@ -109,17 +110,23 @@ func call(args []string) (string, error) { return strings.TrimSpace(string(out)), nil } -func LimaUser(warn bool) (*user.User, error) { +func LimaUser(warn bool, limaVersion string) (*user.User, error) { cache.warnings = []string{} cache.Do(func() { cache.u, cache.err = user.Current() if cache.err == nil { - if notAllowedUsernameRegex.MatchString(cache.u.Username) { - warning := fmt.Sprintf("local user %q is not a allowed (must not match %q); using %q username instead", - cache.u.Username, notAllowedUsernameRegex.String(), fallbackUser) - cache.warnings = append(cache.warnings, warning) - cache.u.Username = fallbackUser - } else if !regexUsername.MatchString(cache.u.Username) { + + // check if the username is blocked + if versionutil.GreaterThan(limaVersion, "0.23.2") { + if notAllowedUsernameRegex.MatchString(cache.u.Username) { + warning := fmt.Sprintf("local user %q is not a allowed (must not match %q); using %q username instead", + cache.u.Username, notAllowedUsernameRegex.String(), fallbackUser) + cache.warnings = append(cache.warnings, warning) + cache.u.Username = fallbackUser + } + } + + if !regexUsername.MatchString(cache.u.Username) { warning := fmt.Sprintf("local user %q is not a valid Linux username (must match %q); using %q username instead", cache.u.Username, regexUsername.String(), fallbackUser) cache.warnings = append(cache.warnings, warning) diff --git a/pkg/osutil/user_test.go b/pkg/osutil/user_test.go index 860f0a71db2..cd5df682558 100644 --- a/pkg/osutil/user_test.go +++ b/pkg/osutil/user_test.go @@ -9,7 +9,7 @@ import ( ) func TestLimaUserWarn(t *testing.T) { - _, err := LimaUser(true) + _, err := LimaUser(true, "") assert.NilError(t, err) } @@ -18,28 +18,35 @@ func validUsername(username string) bool { } func TestLimaUsername(t *testing.T) { - user, err := LimaUser(false) + user, err := LimaUser(false, "") assert.NilError(t, err) // check for reasonable unix user name assert.Assert(t, validUsername(user.Username), user.Username) } func TestLimaUserUid(t *testing.T) { - user, err := LimaUser(false) + user, err := LimaUser(false, "") assert.NilError(t, err) _, err = strconv.Atoi(user.Uid) assert.NilError(t, err) } func TestLimaUserGid(t *testing.T) { - user, err := LimaUser(false) + user, err := LimaUser(false, "") assert.NilError(t, err) _, err = strconv.Atoi(user.Gid) assert.NilError(t, err) } func TestLimaHomeDir(t *testing.T) { - user, err := LimaUser(false) + user, err := LimaUser(false, "") + assert.NilError(t, err) + // check for absolute unix path (/home) + assert.Assert(t, path.IsAbs(user.HomeDir), user.HomeDir) +} + +func TestLimaAdminUser(t *testing.T) { + user, err := LimaUser(false, "") assert.NilError(t, err) // check for absolute unix path (/home) assert.Assert(t, path.IsAbs(user.HomeDir), user.HomeDir) diff --git a/pkg/sshutil/sshutil.go b/pkg/sshutil/sshutil.go index 302ebfdb794..6156e416a8a 100644 --- a/pkg/sshutil/sshutil.go +++ b/pkg/sshutil/sshutil.go @@ -19,8 +19,10 @@ import ( "github.com/lima-vm/lima/pkg/ioutilx" "github.com/lima-vm/lima/pkg/lockutil" "github.com/lima-vm/lima/pkg/osutil" + "github.com/lima-vm/lima/pkg/store" "github.com/lima-vm/lima/pkg/store/dirnames" "github.com/lima-vm/lima/pkg/store/filenames" + "github.com/lima-vm/lima/pkg/version" "github.com/sirupsen/logrus" "golang.org/x/sys/cpu" ) @@ -228,7 +230,13 @@ func SSHOpts(instDir string, useDotSSH, forwardAgent, forwardX11, forwardX11Trus if len(controlSock) >= osutil.UnixPathMax { return nil, fmt.Errorf("socket path %q is too long: >= UNIX_PATH_MAX=%d", controlSock, osutil.UnixPathMax) } - u, err := osutil.LimaUser(false) + instName := filepath.Base(instDir) + inst, err := store.Inspect(instName) + limaVersion := version.Version + if err == nil { + limaVersion = inst.LimaVersion + } + u, err := osutil.LimaUser(false, limaVersion) if err != nil { return nil, err }