Skip to content

Commit

Permalink
Make guest username, uid, home directory configurable
Browse files Browse the repository at this point in the history
Also disallows the "admin" username by default (because it is a builtin
user in Ubuntu), but can be overridden by setting it explicitly in lima.yaml.

Signed-off-by: Jan Dubois <[email protected]>
  • Loading branch information
jandubois committed Nov 1, 2024
1 parent 9fe06aa commit 19025ad
Show file tree
Hide file tree
Showing 22 changed files with 317 additions and 178 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.Username, 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.Username, 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.Username, 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.Username,
*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.Username,
*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.Username,
*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:/tmp/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
fullName: John Doe
home: "/tmp/{{.User}}"
uid: 4711
12 changes: 4 additions & 8 deletions pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,7 @@ 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)
uid, err := strconv.Atoi(*instConfig.User.UID)
if err != nil {
return nil, err
}
Expand All @@ -130,10 +126,10 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L
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),
GECOS: *instConfig.User.FullName,
User: *instConfig.User.Username,
Home: *instConfig.User.Home,
GuestInstallPrefix: *instConfig.GuestInstallPrefix,
UpgradePackages: *instConfig.UpgradePackages,
Containerd: Containerd{System: *instConfig.Containerd.System, User: *instConfig.Containerd.User},
Expand Down
6 changes: 2 additions & 4 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 @@ -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
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.Username,
*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 19025ad

Please sign in to comment.