Skip to content

Commit b48f544

Browse files
committed
Write ~/.lima/<INSTANCE>/ssh.config
```console $ limactl ls --format='{{.SSHConfigFile}}' default /Users/example/.lima/default/ssh.config ``` Signed-off-by: Akihiro Suda <[email protected]>
1 parent 74ee986 commit b48f544

File tree

6 files changed

+48
-0
lines changed

6 files changed

+48
-0
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,20 @@ Use `<INSTANCE>:<FILENAME>` to specify a source or target inside an instance.
225225

226226
`limactl disk list`: list all existing disks
227227

228+
#### `limactl show-ssh`
229+
- `limactl show-ssh --format=cmd <INSTANCE>` (default): Full `ssh` command line
230+
- `limactl show-ssh --format=args <INSTANCE>`: Similar to the `cmd` format but omits `ssh` and the destination address
231+
- `limactl show-ssh --format=options <INSTANCE>`: ssh option key value pairs
232+
- `limactl show-ssh --format=config <INSTANCE>`: `~/.ssh/config` format
233+
234+
The config file is also automatically created inside the instance directory:
235+
```console
236+
$ limactl ls --format='{{.SSHConfigFile}}' default
237+
/Users/example/.lima/default/ssh.config
238+
239+
$ ssh -F /Users/example/.lima/default/ssh.config lima-default
240+
```
241+
228242
#### `limactl completion`
229243
- To enable bash completion, add `source <(limactl completion bash)` to `~/.bash_profile`.
230244

cmd/limactl/show_ssh.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ const showSSHExample = `
3434
User example
3535
Hostname 127.0.0.1
3636
Port 60022
37+
38+
To show the config file path:
39+
$ limactl ls --format='{{.SSHConfigFile}}' default
40+
/Users/example/.lima/default/ssh.config
3741
`
3842

3943
func newShowSSHCommand() *cobra.Command {

docs/internal.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ VZ:
5454

5555
SSH:
5656
- `ssh.sock`: SSH control master socket
57+
- `ssh.config`: SSH config file for `ssh -F`. Not consumed by Lima itself.
5758

5859
Guest agent:
5960
- `ga.sock`: Forwarded to `/run/lima-guestagent.sock` in the guest, via SSH

pkg/hostagent/hostagent.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package hostagent
22

33
import (
4+
"bytes"
45
"context"
56
"encoding/json"
67
"errors"
@@ -111,6 +112,9 @@ func New(instName string, stdout io.Writer, sigintCh chan os.Signal, opts ...Opt
111112
if err != nil {
112113
return nil, err
113114
}
115+
if err = writeSSHConfigFile(inst, sshLocalPort, sshOpts); err != nil {
116+
return nil, err
117+
}
114118
sshConfig := &ssh.SSHConfig{
115119
AdditionalArgs: sshutil.SSHArgsFromOpts(sshOpts),
116120
}
@@ -150,6 +154,28 @@ func New(instName string, stdout io.Writer, sigintCh chan os.Signal, opts ...Opt
150154
return a, nil
151155
}
152156

157+
func writeSSHConfigFile(inst *store.Instance, sshLocalPort int, sshOpts []string) error {
158+
if inst.Dir == "" {
159+
return fmt.Errorf("directory is unknown for the instance %q", inst.Name)
160+
}
161+
var b bytes.Buffer
162+
if _, err := fmt.Fprintf(&b, `# This SSH config file can be passed to 'ssh -F'.
163+
# This file is created by Lima, but not used by Lima itself currently.
164+
# Modifications to this file will be lost on restarting the Lima instance.
165+
`); err != nil {
166+
return err
167+
}
168+
if err := sshutil.Format(&b, inst.Name, sshutil.FormatConfig,
169+
append(sshOpts,
170+
"Hostname=127.0.0.1",
171+
fmt.Sprintf("Port=%d", sshLocalPort),
172+
)); err != nil {
173+
return err
174+
}
175+
fileName := filepath.Join(inst.Dir, filenames.SSHConfig)
176+
return os.WriteFile(fileName, b.Bytes(), 0600)
177+
}
178+
153179
func determineSSHLocalPort(y *limayaml.LimaYAML, instName string) (int, error) {
154180
if *y.SSH.LocalPort > 0 {
155181
return *y.SSH.LocalPort, nil

pkg/store/filenames/filenames.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const (
3737
SerialLog = "serial.log"
3838
SerialSock = "serial.sock"
3939
SSHSock = "ssh.sock"
40+
SSHConfig = "ssh.config"
4041
GuestAgentSock = "ga.sock"
4142
HostAgentPID = "ha.pid"
4243
HostAgentSock = "ha.sock"

pkg/store/instance.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type Instance struct {
4747
AdditionalDisks []limayaml.Disk `json:"additionalDisks,omitempty"`
4848
Networks []limayaml.Network `json:"network,omitempty"`
4949
SSHLocalPort int `json:"sshLocalPort,omitempty"`
50+
SSHConfigFile string `json:"sshConfigFile,omitempty"`
5051
HostAgentPID int `json:"hostAgentPID,omitempty"`
5152
DriverPID int `json:"driverPID,omitempty"`
5253
Errors []error `json:"errors,omitempty"`
@@ -101,6 +102,7 @@ func Inspect(instName string) (*Instance, error) {
101102
inst.AdditionalDisks = y.AdditionalDisks
102103
inst.Networks = y.Networks
103104
inst.SSHLocalPort = *y.SSH.LocalPort // maybe 0
105+
inst.SSHConfigFile = filepath.Join(instDir, filenames.SSHConfig)
104106

105107
inst.HostAgentPID, err = ReadPIDFile(filepath.Join(instDir, filenames.HostAgentPID))
106108
if err != nil {

0 commit comments

Comments
 (0)