Skip to content

Commit

Permalink
Allow "." and "_" in instance names, disallow them in hostnames
Browse files Browse the repository at this point in the history
Now `limactl create template://ubuntu-24.10` and
`limactl create ./ubuntu-24.10.yaml` creates an instance named
`ubuntu-24.10` with the hostname `lima-ubuntu-24-10`.

Eventually the hostname should be customizable via the YAML,
but it is beyond the scope of this commit.

Fix issue 2813
Alternative to PR 2815

Signed-off-by: Akihiro Suda <[email protected]>
  • Loading branch information
AkihiroSuda committed Oct 28, 2024
1 parent 6a798c3 commit 88d2bdc
Show file tree
Hide file tree
Showing 15 changed files with 60 additions and 21 deletions.
3 changes: 2 additions & 1 deletion cmd/limactl/guessarg/guessarg.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ func InstNameFromURL(urlStr string) (string, error) {
func InstNameFromYAMLPath(yamlPath string) (string, error) {
s := strings.ToLower(filepath.Base(yamlPath))
s = strings.TrimSuffix(strings.TrimSuffix(s, ".yml"), ".yaml")
s = strings.ReplaceAll(s, ".", "-")
// "." is allowed in instance names, but replaced to "-" for hostnames.
// e.g., yaml: "ubuntu-24.04.yaml" , instance name: "ubuntu-24.04", hostname: "lima-ubuntu-24-04"
if err := identifiers.Validate(s); err != nil {
return "", fmt.Errorf("filename %q is invalid: %w", yamlPath, err)
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/limactl/show-ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ func showSSHAction(cmd *cobra.Command, args []string) error {
}
return err
}
logrus.Warnf("`limactl show-ssh` is deprecated. Instead, use `ssh -F %s lima-%s`.",
filepath.Join(inst.Dir, filenames.SSHConfig), inst.Name)
logrus.Warnf("`limactl show-ssh` is deprecated. Instead, use `ssh -F %s %s`.",
filepath.Join(inst.Dir, filenames.SSHConfig), inst.Hostname)
opts, err := sshutil.SSHOpts(
inst.Dir,
*inst.Config.SSH.LoadDotSSHPubKeys,
Expand Down
2 changes: 1 addition & 1 deletion cmd/limactl/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func tunnelAction(cmd *cobra.Command, args []string) error {
default:
fmt.Fprintf(stdout, "Set `ALL_PROXY=socks5h://127.0.0.1:%d`, etc.\n", port)
}
fmt.Fprintf(stdout, "The instance can be connected from the host as <http://lima-%s.internal> via a web browser.\n", inst.Name)
fmt.Fprintf(stdout, "The instance can be connected from the host as <http://%s.internal> via a web browser.\n", inst.Hostname)

// TODO: show the port in `limactl list --json` ?
// TODO: add `--stop` flag to shut down the tunnel
Expand Down
2 changes: 1 addition & 1 deletion pkg/cidata/cidata.TEMPLATE.d/meta-data
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
instance-id: {{.IID}}
local-hostname: lima-{{.Name}}
local-hostname: {{.Hostname}}
2 changes: 2 additions & 0 deletions pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (

"github.com/docker/go-units"
"github.com/lima-vm/lima/pkg/debugutil"
"github.com/lima-vm/lima/pkg/identifierutil"
"github.com/lima-vm/lima/pkg/iso9660util"
"github.com/lima-vm/lima/pkg/limayaml"
"github.com/lima-vm/lima/pkg/localpathutil"
Expand Down Expand Up @@ -128,6 +129,7 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L
Debug: debugutil.Debug,
BootScripts: bootScripts,
Name: name,
Hostname: identifierutil.HostnameFromInstName(name), // TODO: support customization
User: u.Username,
UID: uid,
Home: fmt.Sprintf("/home/%s.linux", u.Username),
Expand Down
1 change: 1 addition & 0 deletions pkg/cidata/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type Disk struct {
type TemplateArgs struct {
Debug bool
Name string // instance name
Hostname string // instance hostname
IID string // instance id
User string // user name
Home string // home directory
Expand Down
4 changes: 3 additions & 1 deletion pkg/hostagent/hostagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
hostagentapi "github.com/lima-vm/lima/pkg/hostagent/api"
"github.com/lima-vm/lima/pkg/hostagent/dns"
"github.com/lima-vm/lima/pkg/hostagent/events"
"github.com/lima-vm/lima/pkg/identifierutil"
"github.com/lima-vm/lima/pkg/limayaml"
"github.com/lima-vm/lima/pkg/networks"
"github.com/lima-vm/lima/pkg/osutil"
Expand Down Expand Up @@ -288,7 +289,8 @@ func (a *HostAgent) Run(ctx context.Context) error {
if limayaml.FirstUsernetIndex(a.instConfig) == -1 && *a.instConfig.HostResolver.Enabled {
hosts := a.instConfig.HostResolver.Hosts
hosts["host.lima.internal"] = networks.SlirpGateway
hosts[fmt.Sprintf("lima-%s", a.instName)] = networks.SlirpIPAddress
hostname := identifierutil.HostnameFromInstName(a.instName) // TODO: support customization
hosts[hostname] = networks.SlirpIPAddress
srvOpts := dns.ServerOptions{
UDPPort: a.udpDNSLocalPort,
TCPPort: a.tcpDNSLocalPort,
Expand Down
9 changes: 9 additions & 0 deletions pkg/identifierutil/identifierutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package identifierutil

import "strings"

func HostnameFromInstName(instName string) string {
s := strings.ReplaceAll(instName, ".", "-")
s = strings.ReplaceAll(s, "_", "-")
return "lima-" + s
}
13 changes: 13 additions & 0 deletions pkg/identifierutil/identifierutil_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package identifierutil

import (
"testing"

"gotest.tools/v3/assert"
)

func TestHostnameFromInstName(t *testing.T) {
assert.Equal(t, "lima-default", HostnameFromInstName("default"))
assert.Equal(t, "lima-ubuntu-24-04", HostnameFromInstName("ubuntu-24.04"))
assert.Equal(t, "lima-foo-bar-baz", HostnameFromInstName("foo_bar.baz"))
}
2 changes: 1 addition & 1 deletion pkg/instance/ansible.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func runAnsiblePlaybook(ctx context.Context, inst *store.Instance, playbook stri
func createAnsibleInventory(inst *store.Instance) (string, error) {
vars := map[string]interface{}{
"ansible_connection": "ssh",
"ansible_host": "lima-" + inst.Name,
"ansible_host": inst.Hostname,
"ansible_ssh_common_args": "-F " + inst.SSHConfigFile,
}
hosts := map[string]interface{}{
Expand Down
2 changes: 1 addition & 1 deletion pkg/instance/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ func watchHostAgentEvents(ctx context.Context, inst *store.Instance, haStdoutPat
return true
}
if *inst.Config.Plain {
logrus.Infof("READY. Run `ssh -F %q lima-%s` to open the shell.", inst.SSHConfigFile, inst.Name)
logrus.Infof("READY. Run `ssh -F %q %s` to open the shell.", inst.SSHConfigFile, inst.Hostname)
} else {
logrus.Infof("READY. Run `%s` to open the shell.", LimactlShellCmd(inst.Name))
}
Expand Down
20 changes: 12 additions & 8 deletions pkg/limayaml/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/sirupsen/logrus"
"golang.org/x/sys/cpu"

"github.com/lima-vm/lima/pkg/identifierutil"
"github.com/lima-vm/lima/pkg/networks"
"github.com/lima-vm/lima/pkg/osutil"
"github.com/lima-vm/lima/pkg/ptr"
Expand Down Expand Up @@ -814,12 +815,14 @@ func executeGuestTemplate(format, instDir string, param map[string]string) (byte
tmpl, err := template.New("").Parse(format)
if err == nil {
user, _ := osutil.LimaUser(false)
name := filepath.Base(instDir)
data := map[string]interface{}{
"Home": fmt.Sprintf("/home/%s.linux", user.Username),
"Name": filepath.Base(instDir),
"UID": user.Uid,
"User": user.Username,
"Param": param,
"Home": fmt.Sprintf("/home/%s.linux", user.Username),
"Name": name,
"Hostname": identifierutil.HostnameFromInstName(name), // TODO: support customization
"UID": user.Uid,
"User": user.Username,
"Param": param,
}
var out bytes.Buffer
if err := tmpl.Execute(&out, data); err == nil {
Expand All @@ -836,9 +839,10 @@ func executeHostTemplate(format, instDir string, param map[string]string) (bytes
home, _ := os.UserHomeDir()
limaHome, _ := dirnames.LimaDir()
data := map[string]interface{}{
"Dir": instDir,
"Home": home,
"Name": filepath.Base(instDir),
"Dir": instDir,
"Home": home,
"Name": filepath.Base(instDir),
// TODO: add hostname fields for the host and the guest
"UID": user.Uid,
"User": user.Username,
"Param": param,
Expand Down
2 changes: 1 addition & 1 deletion pkg/networks/usernet/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (c *Client) ConfigureDriver(ctx context.Context, driver *driver.BaseDriver)
return err
}
hosts := driver.Instance.Config.HostResolver.Hosts
hosts[fmt.Sprintf("lima-%s.internal", driver.Instance.Name)] = ipAddress
hosts[fmt.Sprintf("%s.internal", driver.Instance.Hostname)] = ipAddress
err = c.AddDNSHosts(hosts)
return err
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/sshutil/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"io"
"strings"

"github.com/lima-vm/lima/pkg/identifierutil"
)

// FormatT specifies the format type.
Expand Down Expand Up @@ -57,7 +59,7 @@ func quoteOption(o string) string {

// Format formats the ssh options.
func Format(w io.Writer, instName string, format FormatT, opts []string) error {
fakeHostname := "lima-" + instName // corresponds to the default guest hostname
fakeHostname := identifierutil.HostnameFromInstName(instName) // TODO: support customization
switch format {
case FormatCmd:
args := []string{"ssh"}
Expand Down
11 changes: 8 additions & 3 deletions pkg/store/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

"github.com/docker/go-units"
hostagentclient "github.com/lima-vm/lima/pkg/hostagent/api/client"
"github.com/lima-vm/lima/pkg/identifierutil"
"github.com/lima-vm/lima/pkg/limayaml"
"github.com/lima-vm/lima/pkg/store/dirnames"
"github.com/lima-vm/lima/pkg/store/filenames"
Expand All @@ -38,7 +39,9 @@ const (
)

type Instance struct {
Name string `json:"name"`
Name string `json:"name"`
// Hostname, not HostName (corresponds to SSH's naming convention)
Hostname string `json:"hostname"`
Status Status `json:"status"`
Dir string `json:"dir"`
VMType limayaml.VMType `json:"vmType"`
Expand Down Expand Up @@ -66,8 +69,10 @@ type Instance struct {
// Other errors are returned as *Instance.Errors.
func Inspect(instName string) (*Instance, error) {
inst := &Instance{
Name: instName,
Status: StatusUnknown,
Name: instName,
// TODO: support customizing hostname
Hostname: identifierutil.HostnameFromInstName(instName),
Status: StatusUnknown,
}
// InstanceDir validates the instName but does not check whether the instance exists
instDir, err := InstanceDir(instName)
Expand Down

0 comments on commit 88d2bdc

Please sign in to comment.