Skip to content

Commit e237573

Browse files
authored
Merge pull request #804 from AkihiroSuda/sshocker-0.3.0
sshfs: support setting `sftpDriver: "openssh-sftp-server"`
2 parents 30864a1 + ae059f0 commit e237573

File tree

9 files changed

+104
-6
lines changed

9 files changed

+104
-6
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ The current default spec:
250250
## How it works
251251

252252
- Hypervisor: QEMU with HVF accelerator
253-
- Filesystem sharing: [reverse sshfs](https://github.com/lima-vm/sshocker/blob/v0.2.0/pkg/reversesshfs/reversesshfs.go) (likely to be replaced with 9p or Samba in future)
253+
- Filesystem sharing: [Reverse SSHFS (default), or virtio-9p-pci aka virtfs](./docs/mount.md)
254254
- Port forwarding: `ssh -L`, automated by watching `/proc/net/tcp` and `iptables` events in the guest
255255

256256
## Developer guide
@@ -266,6 +266,7 @@ The current default spec:
266266
- Performance optimization
267267
- More guest distros
268268
- Windows hosts
269+
- virtio-fs to replace virtio-9p-pci aka virtfs (work has to be done on QEMU repo)
269270
- [vsock](https://github.com/apple/darwin-xnu/blob/xnu-7195.81.3/bsd/man/man4/vsock.4) to replace SSH (work has to be done on QEMU repo)
270271

271272
## FAQs & Troubleshooting

docs/mount.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Filesystem mounts
2+
3+
Lima supports several methods for mounting the host filesystem into the guest.
4+
5+
The default mount type is shown in the following table:
6+
7+
| Lima Version | Default |
8+
| ---------------- | ----------------------------------- |
9+
| < 0.10 | reverse-sshfs + Builtin SFTP server |
10+
| >= 0.10 | reverse-sshfs + OpenSSH SFTP server |
11+
| >= 1.0 (Planned) | 9p |
12+
13+
## Mount types
14+
15+
### reverse-sshfs
16+
The "reverse-sshfs" mount type exposes the host filesystem by running an SFTP server on the host.
17+
While the host works as an SFTP server, the host does not open any TCP port,
18+
as the host initiates an SSH connection into the guest and let the guest connect to the SFTP server via the stdin.
19+
20+
An example configuration:
21+
```yaml
22+
mountType: "reverse-sshfs"
23+
mounts:
24+
- location: "~"
25+
sshfs:
26+
# Enabling the SSHFS cache will increase performance of the mounted filesystem, at
27+
# the cost of potentially not reflecting changes made on the host in a timely manner.
28+
# Warning: It looks like PHP filesystem access does not work correctly when
29+
# the cache is disabled.
30+
# 🟢 Builtin default: true
31+
cache: null
32+
# SSHFS has an optional flag called 'follow_symlinks'. This allows mounts
33+
# to be properly resolved in the guest os and allow for access to the
34+
# contents of the symlink. As a result, symlinked files & folders on the Host
35+
# system will look and feel like regular files directories in the Guest OS.
36+
# 🟢 Builtin default: false
37+
followSymlinks: null
38+
# SFTP driver, "builtin" or "openssh-sftp-server". "openssh-sftp-server" is recommended.
39+
# 🟢 Builtin default: "openssh-sftp-server" if OpenSSH SFTP Server binary is found, otherwise "builtin"
40+
sftpDriver: null
41+
```
42+
43+
The default value of `sftpDriver` has been set to "openssh-sftp-server" since Lima v0.10, when an OpenSSH SFTP Server binary
44+
such as `/usr/libexec/sftp-server` is detected on the host.
45+
Lima prior to v0.10 had used "builtin" as the SFTP driver.
46+
47+
#### Caveats
48+
- A mount is disabled when the SSH connection was shut down.
49+
- A compromised `sshfs` process in the guest may have an access to unexposed host directories.
50+
51+
### 9p
52+
The "9p" mount type is implemented by using QEMU's virtio-9p-pci devices.
53+
virtio-9p-pci is also known as "virtfs", but note that this is unrelated to [virtio-fs](https://virtio-fs.gitlab.io/).
54+
55+
An example configuration:
56+
```yaml
57+
mountType: "9p"
58+
mounts:
59+
- location: "~"
60+
9p:
61+
# Supported security models are "passthrough", "mapped-xattr", "mapped-file" and "none".
62+
# 🟢 Builtin default: "mapped-xattr"
63+
securityModel: null
64+
# Select 9P protocol version. Valid options are: "9p2000" (legacy), "9p2000.u", "9p2000.L".
65+
# 🟢 Builtin default: "9p2000.L"
66+
protocolVersion: null
67+
# The number of bytes to use for 9p packet payload, where 4KiB is the absolute minimum.
68+
# 🟢 Builtin default: "128KiB"
69+
msize: null
70+
# Specifies a caching policy. Valid options are: "none", "loose", "fscache" and "mmap".
71+
# Try choosing "mmap" or "none" if you see a stability issue with the default "fscache".
72+
# See https://www.kernel.org/doc/Documentation/filesystems/9p.txt
73+
# 🟢 Builtin default: "fscache" for non-writable mounts, "mmap" for writable mounts
74+
cache: null
75+
```
76+
#### Caveats
77+
- The "9p" mount type is known to be incompatible with CentOS, Rocky Linux, and AlmaLinux as their kernel do not support `CONFIG_NET_9P_VIRTIO`.

examples/default.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ mounts:
6161
# system will look and feel like regular files directories in the Guest OS.
6262
# 🟢 Builtin default: false
6363
followSymlinks: null
64+
# SFTP driver, "builtin" or "openssh-sftp-server". "openssh-sftp-server" is recommended.
65+
# 🟢 Builtin default: "openssh-sftp-server" if OpenSSH SFTP Server binary is found, otherwise "builtin"
66+
sftpDriver: null
6467
9p:
6568
# Supported security models are "passthrough", "mapped-xattr", "mapped-file" and "none".
6669
# 🟢 Builtin default: "mapped-xattr"

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ require (
1717
github.com/google/go-cmp v0.5.7
1818
github.com/gorilla/mux v1.8.0
1919
github.com/hashicorp/go-multierror v1.1.1
20-
github.com/lima-vm/sshocker v0.2.3
20+
github.com/lima-vm/sshocker v0.3.0
2121
github.com/mattn/go-isatty v0.0.14
2222
github.com/mattn/go-shellwords v1.0.12
2323
github.com/miekg/dns v1.1.48

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
118118
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
119119
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
120120
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
121-
github.com/lima-vm/sshocker v0.2.3 h1:z4xTGS51Bo03adLHcetl3WjSK4zbJeFe6GT0ChiZI7I=
122-
github.com/lima-vm/sshocker v0.2.3/go.mod h1:tdwxS0o2d2vNfe2CN+QN9J8XF3VPX4y9IUu7fpy2ibc=
121+
github.com/lima-vm/sshocker v0.3.0 h1:4W7AFfwqkhPwBIOtwfnxxggdS3/bs6JkTYT1RfrXwfQ=
122+
github.com/lima-vm/sshocker v0.3.0/go.mod h1:LtQ68MCRh2MPgAczFNyElrOObNR1lsb31YCeFGgeLyc=
123123
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
124124
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
125125
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=

pkg/hostagent/mount.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func (a *HostAgent) setupMount(ctx context.Context, m limayaml.Mount) (*mount, e
5151
}
5252
logrus.Infof("Mounting %q", expanded)
5353
rsf := &reversesshfs.ReverseSSHFS{
54+
Driver: *m.SSHFS.SFTPDriver,
5455
SSHConfig: a.sshConfig,
5556
LocalPath: expanded,
5657
Host: "127.0.0.1",

pkg/limayaml/defaults.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
376376
if mount.SSHFS.FollowSymlinks != nil {
377377
mounts[i].SSHFS.FollowSymlinks = mount.SSHFS.FollowSymlinks
378378
}
379+
if mount.SSHFS.SFTPDriver != nil {
380+
mounts[i].SSHFS.SFTPDriver = mount.SSHFS.SFTPDriver
381+
}
379382
if mount.NineP.SecurityModel != nil {
380383
mounts[i].NineP.SecurityModel = mount.NineP.SecurityModel
381384
}
@@ -406,6 +409,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
406409
if mount.SSHFS.FollowSymlinks == nil {
407410
mount.SSHFS.FollowSymlinks = pointer.Bool(false)
408411
}
412+
if mount.SSHFS.SFTPDriver == nil {
413+
mount.SSHFS.SFTPDriver = pointer.String("")
414+
}
409415
if mount.NineP.SecurityModel == nil {
410416
mounts[i].NineP.SecurityModel = pointer.String(Default9pSecurityModel)
411417
}

pkg/limayaml/defaults_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ func TestFillDefault(t *testing.T) {
146146
expect.Mounts[0].Writable = pointer.Bool(false)
147147
expect.Mounts[0].SSHFS.Cache = pointer.Bool(true)
148148
expect.Mounts[0].SSHFS.FollowSymlinks = pointer.Bool(false)
149+
expect.Mounts[0].SSHFS.SFTPDriver = pointer.String("")
149150
expect.Mounts[0].NineP.SecurityModel = pointer.String(Default9pSecurityModel)
150151
expect.Mounts[0].NineP.ProtocolVersion = pointer.String(Default9pProtocolVersion)
151152
expect.Mounts[0].NineP.Msize = pointer.String(Default9pMsize)
@@ -297,6 +298,7 @@ func TestFillDefault(t *testing.T) {
297298
expect.Containerd.Archives[0].Arch = *d.Arch
298299
expect.Mounts[0].SSHFS.Cache = pointer.Bool(true)
299300
expect.Mounts[0].SSHFS.FollowSymlinks = pointer.Bool(false)
301+
expect.Mounts[0].SSHFS.SFTPDriver = pointer.String("")
300302
expect.Mounts[0].NineP.SecurityModel = pointer.String(Default9pSecurityModel)
301303
expect.Mounts[0].NineP.ProtocolVersion = pointer.String(Default9pProtocolVersion)
302304
expect.Mounts[0].NineP.Msize = pointer.String(Default9pMsize)

pkg/limayaml/limayaml.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,17 @@ type Mount struct {
5757
NineP NineP `yaml:"9p,omitempty" json:"9p,omitempty"`
5858
}
5959

60+
type SFTPDriver = string
61+
62+
const (
63+
SFTPDriverBuiltin = "builtin"
64+
SFTPDriverOpenSSHSFTPServer = "openssh-sftp-server"
65+
)
66+
6067
type SSHFS struct {
61-
Cache *bool `yaml:"cache,omitempty" json:"cache,omitempty"`
62-
FollowSymlinks *bool `yaml:"followSymlinks,omitempty" json:"followSymlinks,omitempty"`
68+
Cache *bool `yaml:"cache,omitempty" json:"cache,omitempty"`
69+
FollowSymlinks *bool `yaml:"followSymlinks,omitempty" json:"followSymlinks,omitempty"`
70+
SFTPDriver *SFTPDriver `yaml:"sftpDriver,omitempty" json:"sftpDriver,omitempty"`
6371
}
6472

6573
type NineP struct {

0 commit comments

Comments
 (0)