Skip to content

Commit 914bcc9

Browse files
committed
commands: mount - add NFS guest support
1 parent 619f0cb commit 914bcc9

File tree

6 files changed

+160
-7
lines changed

6 files changed

+160
-7
lines changed

internal/commands/flag.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"unicode/utf8"
1515
"unsafe"
1616

17+
"github.com/djdv/go-filesystem-utils/internal/filesystem"
1718
"github.com/djdv/go-filesystem-utils/internal/generic"
1819
"github.com/djdv/p9/p9"
1920
"github.com/multiformats/go-multiaddr"
@@ -585,3 +586,7 @@ func parseMultiaddrList(parameter string) ([]multiaddr.Multiaddr, error) {
585586
}
586587
return maddrs, nil
587588
}
589+
590+
func prefixIDFlag(system filesystem.ID) string {
591+
return strings.ToLower(string(system)) + "-"
592+
}

internal/commands/mount.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,9 @@ func makeGuestCommands[
294294
](host filesystem.Host,
295295
) []command.Command {
296296
guests := makeIPFSCommands[HC, HM](host)
297+
if nfsGuest := makeNFSGuestCommand[HC, HM](host); nfsGuest != nil {
298+
guests = append(guests, nfsGuest)
299+
}
297300
sortCommands(guests)
298301
return guests
299302
}

internal/commands/mountpoint.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ func makeMountPointGuests[
143143
) mountPointGuests {
144144
guests := make(mountPointGuests)
145145
makeIPFSGuests[HC](guests, path)
146+
makeNFSGuest[HC](guests, path)
146147
return guests
147148
}
148149

internal/commands/mountpoint_ipfs.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ func guestOverlayText(overlay, overlaid filesystem.ID) string {
7171
return string(overlay) + " is an " + string(overlaid) + " overlay"
7272
}
7373

74-
func prefixIDFlag(system filesystem.ID) string {
75-
return strings.ToLower(string(system)) + "-"
76-
}
77-
7874
func (*ipfsOptions) usage(filesystem.Host) string {
7975
return string(ipfs.IPFSID) + " provides an empty root directory." +
8076
"\nChild paths are forwarded to the IPFS API."

internal/commands/mountpoint_nfs.go

Lines changed: 136 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"encoding/json"
77
"errors"
88
"flag"
9+
"fmt"
10+
"os"
911

1012
"github.com/djdv/go-filesystem-utils/internal/command"
1113
"github.com/djdv/go-filesystem-utils/internal/filesystem"
@@ -16,11 +18,24 @@ import (
1618
)
1719

1820
type (
19-
nfsHostSettings nfs.Host
20-
nfsHostOption func(*nfsHostSettings) error
21-
nfsHostOptions []nfsHostOption
21+
nfsHostSettings nfs.Host
22+
nfsHostOption func(*nfsHostSettings) error
23+
nfsHostOptions []nfsHostOption
24+
nfsGuestSettings struct {
25+
nfs.Guest
26+
defaultUID, defaultGID,
27+
defaultHostname, defaultDirpath bool
28+
}
29+
nfsGuestOption func(*nfsGuestSettings) error
30+
nfsGuestOptions []nfsGuestOption
2231
)
2332

33+
const nfsServerFlagName = "server"
34+
35+
func (ns nfsGuestSettings) marshal(string) ([]byte, error) {
36+
return json.Marshal(ns.Guest)
37+
}
38+
2439
func makeNFSCommand() command.Command {
2540
return makeMountSubcommand(
2641
nfs.HostID,
@@ -73,3 +88,121 @@ func unmarshalNFS() (filesystem.Host, decodeFunc) {
7388
return "", errors.New("NFS host address was not present in the mountpoint data")
7489
}
7590
}
91+
92+
func makeNFSGuestCommand[
93+
HC mountCmdHost[HT, HM],
94+
HM marshaller,
95+
HT any,
96+
](host filesystem.Host,
97+
) command.Command {
98+
return makeMountCommand[HC, HM, nfsGuestOptions, nfsGuestSettings](host, nfs.GuestID)
99+
}
100+
101+
func makeNFSGuest[
102+
HC mountPointHost[T],
103+
T any,
104+
](guests mountPointGuests, path ninePath,
105+
) {
106+
guests[nfs.GuestID] = newMountPointFunc[HC, nfs.Guest](path)
107+
}
108+
109+
func (*nfsGuestOptions) usage(filesystem.Host) string {
110+
return string(nfs.GuestID) + " attaches to an NFS file server"
111+
}
112+
113+
func (no *nfsGuestOptions) BindFlags(flagSet *flag.FlagSet) {
114+
var (
115+
flagPrefix = prefixIDFlag(nfs.GuestID)
116+
srvName = flagPrefix + nfsServerFlagName
117+
)
118+
const srvUsage = "NFS server `maddr`"
119+
flagSetFunc(flagSet, srvName, srvUsage, no,
120+
func(value multiaddr.Multiaddr, settings *nfsGuestSettings) error {
121+
settings.Maddr = value
122+
return nil
123+
})
124+
hostnameName := flagPrefix + "hostname"
125+
const hostnameUsage = "client's `hostname`"
126+
flagSetFunc(flagSet, hostnameName, hostnameUsage, no,
127+
func(value string, settings *nfsGuestSettings) error {
128+
settings.Hostname = value
129+
return nil
130+
})
131+
flagSet.Lookup(hostnameName).
132+
DefValue = "caller's hostname"
133+
dirpathName := flagPrefix + "dirpath"
134+
const dirpathUsage = "`dirpath` used when mounting the server"
135+
flagSetFunc(flagSet, dirpathName, dirpathUsage, no,
136+
func(value string, settings *nfsGuestSettings) error {
137+
settings.Dirpath = value
138+
return nil
139+
})
140+
flagSet.Lookup(dirpathName).
141+
DefValue = "/"
142+
linkSepName := flagPrefix + "link-separator"
143+
const linkSepUsage = "`separator` character to replace with `/` when parsing relative symlinks"
144+
flagSetFunc(flagSet, linkSepName, linkSepUsage, no,
145+
func(value string, settings *nfsGuestSettings) error {
146+
settings.LinkSeparator = value
147+
return nil
148+
})
149+
linkLimitName := flagPrefix + "link-limit"
150+
const linkLimitUsage = "sets the maximum amount of times a symbolic link will be resolved in a link chain"
151+
flagSetFunc(flagSet, linkLimitName, linkLimitUsage, no,
152+
func(value uint, settings *nfsGuestSettings) error {
153+
settings.LinkLimit = value
154+
return nil
155+
})
156+
uidName := flagPrefix + "uid"
157+
const uidUsage = "client's `uid`"
158+
flagSetFunc(flagSet, uidName, uidUsage, no,
159+
func(value uint32, settings *nfsGuestSettings) error {
160+
settings.UID = value
161+
return nil
162+
})
163+
flagSet.Lookup(uidName).
164+
DefValue = "caller's uid"
165+
gidName := flagPrefix + "gid"
166+
const gidUsage = "client's `gid`"
167+
flagSetFunc(flagSet, gidName, gidUsage, no,
168+
func(value uint32, settings *nfsGuestSettings) error {
169+
settings.GID = value
170+
return nil
171+
})
172+
flagSet.Lookup(gidName).
173+
DefValue = "caller's gid"
174+
}
175+
176+
func (no nfsGuestOptions) make() (nfsGuestSettings, error) {
177+
settings, err := makeWithOptions(no...)
178+
if err != nil {
179+
return nfsGuestSettings{}, err
180+
}
181+
if settings.Maddr == nil {
182+
var (
183+
flagPrefix = prefixIDFlag(nfs.GuestID)
184+
srvName = flagPrefix + nfsServerFlagName
185+
)
186+
return nfsGuestSettings{}, fmt.Errorf(
187+
"flag `-%s` must be provided for NFS guests",
188+
srvName,
189+
)
190+
}
191+
if settings.Hostname == "" {
192+
hostname, err := os.Hostname()
193+
if err != nil {
194+
return nfsGuestSettings{}, err
195+
}
196+
settings.Hostname = hostname
197+
}
198+
if settings.defaultUID {
199+
settings.UID = uint32(os.Getuid())
200+
}
201+
if settings.defaultGID {
202+
settings.GID = uint32(os.Getgid())
203+
}
204+
if settings.Dirpath == "" {
205+
settings.Dirpath = "/"
206+
}
207+
return settings, nil
208+
}

internal/commands/mountpoint_nonfs.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,18 @@ func makeNFSHost(ninePath, bool) (filesystem.Host, p9fs.MakeGuestFunc) {
2121
func unmarshalNFS() (filesystem.Host, decodeFunc) {
2222
return nfsHost, nil
2323
}
24+
25+
func makeNFSGuestCommand[
26+
HC mountCmdHost[HT, HM],
27+
HM marshaller,
28+
HT any,
29+
](host filesystem.Host,
30+
) command.Command {
31+
return nil
32+
}
33+
34+
func makeNFSGuest[
35+
HC mountPointHost[T],
36+
T any,
37+
](mountPointGuests, ninePath,
38+
) { /*NOOP*/ }

0 commit comments

Comments
 (0)