6
6
"encoding/json"
7
7
"errors"
8
8
"flag"
9
+ "fmt"
10
+ "os"
9
11
10
12
"github.com/djdv/go-filesystem-utils/internal/command"
11
13
"github.com/djdv/go-filesystem-utils/internal/filesystem"
@@ -16,11 +18,24 @@ import (
16
18
)
17
19
18
20
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
22
31
)
23
32
33
+ const nfsServerFlagName = "server"
34
+
35
+ func (ns nfsGuestSettings ) marshal (string ) ([]byte , error ) {
36
+ return json .Marshal (ns .Guest )
37
+ }
38
+
24
39
func makeNFSCommand () command.Command {
25
40
return makeMountSubcommand (
26
41
nfs .HostID ,
@@ -73,3 +88,121 @@ func unmarshalNFS() (filesystem.Host, decodeFunc) {
73
88
return "" , errors .New ("NFS host address was not present in the mountpoint data" )
74
89
}
75
90
}
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
+ }
0 commit comments