diff --git a/pkg/cidata/cidata.TEMPLATE.d/lima.env b/pkg/cidata/cidata.TEMPLATE.d/lima.env index b4d00673867d..b1720f0dcada 100644 --- a/pkg/cidata/cidata.TEMPLATE.d/lima.env +++ b/pkg/cidata/cidata.TEMPLATE.d/lima.env @@ -4,6 +4,7 @@ LIMA_CIDATA_USER={{ .User }} LIMA_CIDATA_UID={{ .UID }} LIMA_CIDATA_COMMENT={{ .Comment }} LIMA_CIDATA_HOME={{ .Home}} +LIMA_CIDATA_SHELL={{ .Shell }} LIMA_CIDATA_HOSTHOME_MOUNTPOINT={{ .HostHomeMountPoint }} LIMA_CIDATA_MOUNTS={{ len .Mounts }} {{- range $i, $val := .Mounts}} diff --git a/pkg/cidata/cidata.TEMPLATE.d/user-data b/pkg/cidata/cidata.TEMPLATE.d/user-data index 13a98c78181c..3842f8d46e9e 100644 --- a/pkg/cidata/cidata.TEMPLATE.d/user-data +++ b/pkg/cidata/cidata.TEMPLATE.d/user-data @@ -34,7 +34,7 @@ users: gecos: {{ printf "%q" .Comment }} {{- end }} homedir: "{{.Home}}" - shell: /bin/bash + shell: {{.Shell}} sudo: ALL=(ALL) NOPASSWD:ALL lock_passwd: true ssh-authorized-keys: diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index 2030a9a8e9b1..abd2ccf48062 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -125,6 +125,7 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L User: *instConfig.User.Name, Comment: *instConfig.User.Comment, Home: *instConfig.User.Home, + Shell: *instConfig.User.Shell, UID: *instConfig.User.UID, GuestInstallPrefix: *instConfig.GuestInstallPrefix, UpgradePackages: *instConfig.UpgradePackages, diff --git a/pkg/cidata/template.go b/pkg/cidata/template.go index 92460df1c76c..b2287f6edc01 100644 --- a/pkg/cidata/template.go +++ b/pkg/cidata/template.go @@ -62,6 +62,7 @@ type TemplateArgs struct { User string // user name Comment string // user information Home string // home directory + Shell string // login shell UID uint32 SSHPubKeys []string Mounts []Mount @@ -109,6 +110,9 @@ func ValidateTemplateArgs(args *TemplateArgs) error { if args.Home == "" { return errors.New("field Home must be set") } + if args.Shell == "" { + return errors.New("field Shell must be set") + } if len(args.SSHPubKeys) == 0 { return errors.New("field SSHPubKeys must be set") } diff --git a/pkg/cidata/template_test.go b/pkg/cidata/template_test.go index e05abd3e7e9f..79be8a952122 100644 --- a/pkg/cidata/template_test.go +++ b/pkg/cidata/template_test.go @@ -17,6 +17,7 @@ func TestConfig(t *testing.T) { UID: 501, Comment: "Foo", Home: "/home/foo.linux", + Shell: "/bin/bash", SSHPubKeys: []string{ "ssh-rsa dummy foo@example.com", }, @@ -35,6 +36,7 @@ func TestConfigCACerts(t *testing.T) { UID: 501, Comment: "Foo", Home: "/home/foo.linux", + Shell: "/bin/bash", SSHPubKeys: []string{ "ssh-rsa dummy foo@example.com", }, @@ -51,10 +53,11 @@ func TestConfigCACerts(t *testing.T) { func TestTemplate(t *testing.T) { args := &TemplateArgs{ - Name: "default", - User: "foo", - UID: 501, - Home: "/home/foo.linux", + Name: "default", + User: "foo", + UID: 501, + Home: "/home/foo.linux", + Shell: "/bin/bash", SSHPubKeys: []string{ "ssh-rsa dummy foo@example.com", }, @@ -86,10 +89,11 @@ func TestTemplate(t *testing.T) { func TestTemplate9p(t *testing.T) { args := &TemplateArgs{ - Name: "default", - User: "foo", - UID: 501, - Home: "/home/foo.linux", + Name: "default", + User: "foo", + UID: 501, + Home: "/home/foo.linux", + Shell: "/bin/bash", SSHPubKeys: []string{ "ssh-rsa dummy foo@example.com", }, diff --git a/pkg/limayaml/defaults.go b/pkg/limayaml/defaults.go index dfa88885a677..20a157a054f3 100644 --- a/pkg/limayaml/defaults.go +++ b/pkg/limayaml/defaults.go @@ -209,6 +209,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) { if y.User.Home == nil { y.User.Home = d.User.Home } + if y.User.Shell == nil { + y.User.Shell = d.User.Shell + } if y.User.UID == nil { y.User.UID = d.User.UID } @@ -221,6 +224,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) { if o.User.Home != nil { y.User.Home = o.User.Home } + if o.User.Shell != nil { + y.User.Shell = o.User.Shell + } if o.User.UID != nil { y.User.UID = o.User.UID } @@ -236,6 +242,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) { y.User.Home = ptr.Of(osutil.LimaUser(existingLimaVersion, warn).HomeDir) warn = false } + if y.User.Shell == nil { + y.User.Shell = ptr.Of("/bin/bash") + } if y.User.UID == nil { uidString := osutil.LimaUser(existingLimaVersion, warn).Uid if uid, err := strconv.ParseUint(uidString, 10, 32); err == nil { diff --git a/pkg/limayaml/defaults_test.go b/pkg/limayaml/defaults_test.go index 03b7ff80e9d7..1a2f91b8cd93 100644 --- a/pkg/limayaml/defaults_test.go +++ b/pkg/limayaml/defaults_test.go @@ -117,6 +117,7 @@ func TestFillDefault(t *testing.T) { Name: ptr.Of(user.Username), Comment: ptr.Of(user.Name), Home: ptr.Of(user.HomeDir), + Shell: ptr.Of("/bin/bash"), UID: ptr.Of(uint32(uid)), }, } @@ -441,6 +442,7 @@ func TestFillDefault(t *testing.T) { Name: ptr.Of("xxx"), Comment: ptr.Of("Foo Bar"), Home: ptr.Of("/tmp"), + Shell: ptr.Of("/bin/tcsh"), UID: ptr.Of(uint32(8080)), }, } @@ -664,6 +666,7 @@ func TestFillDefault(t *testing.T) { Name: ptr.Of("foo"), Comment: ptr.Of("foo bar baz"), Home: ptr.Of("/override"), + Shell: ptr.Of("/bin/sh"), UID: ptr.Of(uint32(1122)), }, } diff --git a/pkg/limayaml/limayaml.go b/pkg/limayaml/limayaml.go index 6927fab26ca8..3f4e852006e9 100644 --- a/pkg/limayaml/limayaml.go +++ b/pkg/limayaml/limayaml.go @@ -88,6 +88,7 @@ type User struct { Name *string `yaml:"name,omitempty" json:"name,omitempty" jsonschema:"nullable"` Comment *string `yaml:"comment,omitempty" json:"comment,omitempty" jsonschema:"nullable"` Home *string `yaml:"home,omitempty" json:"home,omitempty" jsonschema:"nullable"` + Shell *string `yaml:"shell,omitempty" json:"shell,omitempty" jsonschema:"nullable"` UID *uint32 `yaml:"uid,omitempty" json:"uid,omitempty" jsonschema:"nullable"` } diff --git a/templates/default.yaml b/templates/default.yaml index 9825d9ee1b86..e8c84cfebe8c 100644 --- a/templates/default.yaml +++ b/templates/default.yaml @@ -294,6 +294,9 @@ user: # It can use the following template variables: {{.Name}}, {{.Hostname}}, {{.UID}}, {{.User}}, and {{.Param.Key}}. # 🟢 Builtin default: "/home/{{.User}}.linux" home: null + # Shell. Needs to be an absolute path. + # 🟢 Builtin default: "/bin/bash" + shell: null vmOpts: qemu: diff --git a/website/content/en/docs/dev/internals.md b/website/content/en/docs/dev/internals.md index bce899a74647..48aa0b08b83c 100644 --- a/website/content/en/docs/dev/internals.md +++ b/website/content/en/docs/dev/internals.md @@ -181,6 +181,7 @@ The volume label is "cidata", as defined by [cloud-init NoCloud](https://docs.cl - `LIMA_CIDATA_UID`: the numeric UID - `LIMA_CIDATA_COMMENT`: the full name or comment string - `LIMA_CIDATA_HOME`: the guest home directory +- `LIMA_CIDATA_SHELL`: the guest login shell - `LIMA_CIDATA_HOSTHOME_MOUNTPOINT`: the mount point of the host home directory, or empty if not mounted - `LIMA_CIDATA_MOUNTS`: the number of the Lima mounts - `LIMA_CIDATA_MOUNTS_%d_MOUNTPOINT`: the N-th mount point of Lima mounts (N=0, 1, ...)