Skip to content

Commit

Permalink
Merge pull request #2827 from jandubois/username
Browse files Browse the repository at this point in the history
Make guest username, uid, home directory configurable
  • Loading branch information
AkihiroSuda authored Nov 2, 2024
2 parents 5329fd4 + c77bfa2 commit 9c21e15
Show file tree
Hide file tree
Showing 27 changed files with 347 additions and 199 deletions.
3 changes: 3 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ linters-settings:
- name: context-keys-type
- name: deep-exit
- name: dot-imports
arguments:
- allowedPackages:
- github.com/lima-vm/lima/pkg/must
- name: empty-block
- name: error-naming
- name: error-return
Expand Down
21 changes: 8 additions & 13 deletions cmd/limactl/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strings"

"github.com/coreos/go-semver/semver"
"github.com/lima-vm/lima/pkg/osutil"
"github.com/lima-vm/lima/pkg/sshutil"
"github.com/lima-vm/lima/pkg/store"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -48,11 +47,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)
instances := make(map[string]*store.Instance)
scpFlags := []string{}
scpArgs := []string{}
debug, err := cmd.Flags().GetBool("debug")
Expand Down Expand Up @@ -85,28 +80,28 @@ func copyAction(cmd *cobra.Command, args []string) error {
}
if legacySSH {
scpFlags = append(scpFlags, "-P", fmt.Sprintf("%d", inst.SSHLocalPort))
scpArgs = append(scpArgs, fmt.Sprintf("%[email protected]:%s", u.Username, path[1]))
scpArgs = append(scpArgs, fmt.Sprintf("%[email protected]:%s", *inst.Config.User.Name, path[1]))
} else {
scpArgs = append(scpArgs, fmt.Sprintf("scp://%[email protected]:%d/%s", u.Username, inst.SSHLocalPort, path[1]))
scpArgs = append(scpArgs, fmt.Sprintf("scp://%[email protected]:%d/%s", *inst.Config.User.Name, inst.SSHLocalPort, path[1]))
}
instDirs[instName] = inst.Dir
instances[instName] = inst
default:
return fmt.Errorf("path %q contains multiple colons", arg)
}
}
if legacySSH && len(instDirs) > 1 {
if legacySSH && len(instances) > 1 {
return fmt.Errorf("more than one (instance) host is involved in this command, this is only supported for openSSH v8.0 or higher")
}
scpFlags = append(scpFlags, "-3", "--")
scpArgs = append(scpFlags, scpArgs...)

var sshOpts []string
if len(instDirs) == 1 {
if len(instances) == 1 {
// Only one (instance) host is involved; we can use the instance-specific
// arguments such as ControlPath. This is preferred as we can multiplex
// sessions without re-authenticating (MaxSessions permitting).
for _, instDir := range instDirs {
sshOpts, err = sshutil.SSHOpts(instDir, false, false, false, false)
for _, inst := range instances {
sshOpts, err = sshutil.SSHOpts(inst.Dir, *inst.Config.User.Name, false, false, false, false)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/limactl/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func editAction(cmd *cobra.Command, args []string) error {
logrus.Info("Aborting, no changes made to the instance")
return nil
}
y, err := limayaml.Load(yBytes, filePath)
y, err := limayaml.LoadWithWarnings(yBytes, filePath)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions cmd/limactl/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ func shellAction(cmd *cobra.Command, args []string) error {

sshOpts, err := sshutil.SSHOpts(
inst.Dir,
*inst.Config.User.Name,
*inst.Config.SSH.LoadDotSSHPubKeys,
*inst.Config.SSH.ForwardAgent,
*inst.Config.SSH.ForwardX11,
Expand Down
1 change: 1 addition & 0 deletions cmd/limactl/show-ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func showSSHAction(cmd *cobra.Command, args []string) error {
filepath.Join(inst.Dir, filenames.SSHConfig), inst.Hostname)
opts, err := sshutil.SSHOpts(
inst.Dir,
*inst.Config.User.Name,
*inst.Config.SSH.LoadDotSSHPubKeys,
*inst.Config.SSH.ForwardAgent,
*inst.Config.SSH.ForwardX11,
Expand Down
1 change: 1 addition & 0 deletions cmd/limactl/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func tunnelAction(cmd *cobra.Command, args []string) error {

sshOpts, err := sshutil.SSHOpts(
inst.Dir,
*inst.Config.User.Name,
*inst.Config.SSH.LoadDotSSHPubKeys,
*inst.Config.SSH.ForwardAgent,
*inst.Config.SSH.ForwardX11,
Expand Down
7 changes: 7 additions & 0 deletions hack/test-templates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ declare -A CHECKS=(
["mount-path-with-spaces"]=""
["provision-ansible"]=""
["param-env-variables"]=""
["set-user"]=""
)

case "$NAME" in
Expand All @@ -63,6 +64,7 @@ case "$NAME" in
CHECKS["mount-path-with-spaces"]="1"
CHECKS["provision-ansible"]="1"
CHECKS["param-env-variables"]="1"
CHECKS["set-user"]="1"
;;
"docker")
CONTAINER_ENGINE="docker"
Expand Down Expand Up @@ -172,6 +174,11 @@ if [[ -n ${CHECKS["param-env-variables"]} ]]; then
limactl shell "$NAME" test -e /tmp/param-user
fi

if [[ -n ${CHECKS["set-user"]} ]]; then
INFO 'Testing that user settings can be provided by lima.yaml'
limactl shell "$NAME" grep "^john:x:4711:4711:John Doe:/home/john-john" /etc/passwd
fi

INFO "Testing proxy settings are imported"
got=$(limactl shell "$NAME" env | grep FTP_PROXY)
# Expected: FTP_PROXY is set in addition to ftp_proxy, localhost is replaced
Expand Down
6 changes: 6 additions & 0 deletions hack/test-templates/test-misc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,9 @@ probes:
# $ limactl disk create data --size 10G
additionalDisks:
- "data"

user:
name: john
comment: John Doe
home: "/home/{{.User}}-{{.User}}"
uid: 4711
2 changes: 1 addition & 1 deletion pkg/cidata/cidata.TEMPLATE.d/boot/02-wsl2-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[ "$LIMA_CIDATA_VMTYPE" = "wsl2" ] || exit 0

# create user
sudo useradd -u "${LIMA_CIDATA_UID}" "${LIMA_CIDATA_USER}" -c "${LIMA_CIDATA_GECOS}" -d "${LIMA_CIDATA_HOME}"
sudo useradd -u "${LIMA_CIDATA_UID}" "${LIMA_CIDATA_USER}" -c "${LIMA_CIDATA_COMMENT}" -d "${LIMA_CIDATA_HOME}"
sudo mkdir "${LIMA_CIDATA_HOME}"/.ssh/
sudo cp "${LIMA_CIDATA_MNT}"/ssh_authorized_keys "${LIMA_CIDATA_HOME}"/.ssh/authorized_keys
sudo chown "${LIMA_CIDATA_USER}" "${LIMA_CIDATA_HOME}"/.ssh/authorized_keys
Expand Down
2 changes: 1 addition & 1 deletion pkg/cidata/cidata.TEMPLATE.d/lima.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ LIMA_CIDATA_DEBUG={{ .Debug }}
LIMA_CIDATA_NAME={{ .Name }}
LIMA_CIDATA_USER={{ .User }}
LIMA_CIDATA_UID={{ .UID }}
LIMA_CIDATA_GECOS={{ .GECOS }}
LIMA_CIDATA_COMMENT={{ .Comment }}
LIMA_CIDATA_HOME={{ .Home}}
LIMA_CIDATA_HOSTHOME_MOUNTPOINT={{ .HostHomeMountPoint }}
LIMA_CIDATA_MOUNTS={{ len .Mounts }}
Expand Down
4 changes: 2 additions & 2 deletions pkg/cidata/cidata.TEMPLATE.d/user-data
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ timezone: {{.TimeZone}}
users:
- name: "{{.User}}"
uid: "{{.UID}}"
{{- if .GECOS }}
gecos: {{ printf "%q" .GECOS }}
{{- if .Comment }}
gecos: {{ printf "%q" .Comment }}
{{- end }}
homedir: "{{.Home}}"
shell: /bin/bash
Expand Down
18 changes: 5 additions & 13 deletions pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"path"
"path/filepath"
"slices"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -117,23 +116,15 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L
if err := limayaml.Validate(instConfig, false); err != nil {
return nil, err
}
u, err := osutil.LimaUser(true)
if err != nil {
return nil, err
}
uid, err := strconv.Atoi(u.Uid)
if err != nil {
return nil, err
}
args := TemplateArgs{
Debug: debugutil.Debug,
BootScripts: bootScripts,
Name: name,
Hostname: identifierutil.HostnameFromInstName(name), // TODO: support customization
User: u.Username,
UID: uid,
GECOS: u.Name,
Home: fmt.Sprintf("/home/%s.linux", u.Username),
User: *instConfig.User.Name,
Comment: *instConfig.User.Comment,
Home: *instConfig.User.Home,
UID: *instConfig.User.UID,
GuestInstallPrefix: *instConfig.GuestInstallPrefix,
UpgradePackages: *instConfig.UpgradePackages,
Containerd: Containerd{System: *instConfig.Containerd.System, User: *instConfig.Containerd.User},
Expand All @@ -151,6 +142,7 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L

firstUsernetIndex := limayaml.FirstUsernetIndex(instConfig)
var subnet net.IP
var err error

if firstUsernetIndex != -1 {
usernetName := instConfig.Networks[firstUsernetIndex].Lima
Expand Down
10 changes: 4 additions & 6 deletions pkg/cidata/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/lima-vm/lima/pkg/iso9660util"

"github.com/containerd/containerd/identifiers"
"github.com/lima-vm/lima/pkg/osutil"
"github.com/lima-vm/lima/pkg/textutil"
)

Expand Down Expand Up @@ -59,9 +58,9 @@ type TemplateArgs struct {
Hostname string // instance hostname
IID string // instance id
User string // user name
GECOS string // user information
Comment string // user information
Home string // home directory
UID int
UID uint32
SSHPubKeys []string
Mounts []Mount
MountType string
Expand Down Expand Up @@ -97,9 +96,8 @@ func ValidateTemplateArgs(args *TemplateArgs) error {
if err := identifiers.Validate(args.Name); err != nil {
return err
}
if !osutil.ValidateUsername(args.User) {
return errors.New("field User must be valid linux username")
}
// args.User is intentionally not validated here; the user can override with any name they want
// limayaml.FillDefault will validate the default (local) username, but not an explicit setting
if args.User == "root" {
return errors.New("field User must not be \"root\"")
}
Expand Down
20 changes: 10 additions & 10 deletions pkg/cidata/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ var defaultRemoveDefaults = false

func TestConfig(t *testing.T) {
args := &TemplateArgs{
Name: "default",
User: "foo",
UID: 501,
GECOS: "Foo",
Home: "/home/foo.linux",
Name: "default",
User: "foo",
UID: 501,
Comment: "Foo",
Home: "/home/foo.linux",
SSHPubKeys: []string{
"ssh-rsa dummy [email protected]",
},
Expand All @@ -30,11 +30,11 @@ func TestConfig(t *testing.T) {

func TestConfigCACerts(t *testing.T) {
args := &TemplateArgs{
Name: "default",
User: "foo",
UID: 501,
GECOS: "Foo",
Home: "/home/foo.linux",
Name: "default",
User: "foo",
UID: 501,
Comment: "Foo",
Home: "/home/foo.linux",
SSHPubKeys: []string{
"ssh-rsa dummy [email protected]",
},
Expand Down
5 changes: 3 additions & 2 deletions pkg/hostagent/hostagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt

sshOpts, err := sshutil.SSHOpts(
inst.Dir,
*inst.Config.User.Name,
*inst.Config.SSH.LoadDotSSHPubKeys,
*inst.Config.SSH.ForwardAgent,
*inst.Config.SSH.ForwardX11,
Expand Down Expand Up @@ -182,13 +183,13 @@ func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt
// Block ports 22 and sshLocalPort on all IPs
for _, port := range []int{sshGuestPort, sshLocalPort} {
rule := limayaml.PortForward{GuestIP: net.IPv4zero, GuestPort: port, Ignore: true}
limayaml.FillPortForwardDefaults(&rule, inst.Dir, inst.Param)
limayaml.FillPortForwardDefaults(&rule, inst.Dir, inst.Config.User, inst.Param)
rules = append(rules, rule)
}
rules = append(rules, inst.Config.PortForwards...)
// Default forwards for all non-privileged ports from "127.0.0.1" and "::1"
rule := limayaml.PortForward{}
limayaml.FillPortForwardDefaults(&rule, inst.Dir, inst.Param)
limayaml.FillPortForwardDefaults(&rule, inst.Dir, inst.Config.User, inst.Param)
rules = append(rules, rule)

limaDriver := driverutil.CreateTargetDriverInstance(&driver.BaseDriver{
Expand Down
2 changes: 1 addition & 1 deletion pkg/instance/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func Create(ctx context.Context, instName string, instConfig []byte, saveBrokenY
}
// limayaml.Load() needs to pass the store file path to limayaml.FillDefault() to calculate default MAC addresses
filePath := filepath.Join(instDir, filenames.LimaYAML)
loadedInstConfig, err := limayaml.Load(instConfig, filePath)
loadedInstConfig, err := limayaml.LoadWithWarnings(instConfig, filePath)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 9c21e15

Please sign in to comment.