@@ -19,8 +19,11 @@ package cmd
19
19
import (
20
20
"net"
21
21
"os"
22
+ "os/signal"
23
+ "strconv"
22
24
"strings"
23
25
"sync"
26
+ "syscall"
24
27
25
28
"github.com/golang/glog"
26
29
"github.com/spf13/cobra"
@@ -34,16 +37,26 @@ import (
34
37
"k8s.io/minikube/third_party/go9p/ufs"
35
38
)
36
39
40
+ // nineP is the value of --type used for the 9p filesystem.
41
+ const nineP = "9p"
42
+
43
+ // placeholders for flag values
37
44
var mountIP string
38
45
var mountVersion string
46
+ var mountType string
39
47
var isKill bool
40
48
var uid int
41
49
var gid int
42
- var msize int
50
+ var mSize int
51
+ var options []string
52
+ var mode uint
53
+
54
+ // supportedFilesystems is a map of filesystem types to not warn against.
55
+ var supportedFilesystems = map [string ]bool {nineP : true }
43
56
44
57
// mountCmd represents the mount command
45
58
var mountCmd = & cobra.Command {
46
- Use : "mount [flags] MOUNT_DIRECTORY(ex: \" /home \" ) " ,
59
+ Use : "mount [flags] <source directory>:<target directory> " ,
47
60
Short : "Mounts the specified directory into minikube" ,
48
61
Long : `Mounts the specified directory into minikube.` ,
49
62
Run : func (cmd * cobra.Command , args []string ) {
@@ -56,13 +69,12 @@ var mountCmd = &cobra.Command{
56
69
57
70
if len (args ) != 1 {
58
71
exit .Usage (`Please specify the directory to be mounted:
59
- minikube mount HOST_MOUNT_DIRECTORY:VM_MOUNT_DIRECTORY(ex: "/host-home:/vm-home")` )
72
+ minikube mount <source directory>:<target directory> (example: "/host-home:/vm-home")` )
60
73
}
61
74
mountString := args [0 ]
62
75
idx := strings .LastIndex (mountString , ":" )
63
76
if idx == - 1 { // no ":" was present
64
- exit .Usage (`Mount directory must be in the form:
65
- HOST_MOUNT_DIRECTORY:VM_MOUNT_DIRECTORY` )
77
+ exit .Usage (`mount argument %q must be in form: <source directory>:<target directory>` , mountString )
66
78
}
67
79
hostPath := mountString [:idx ]
68
80
vmPath := mountString [idx + 1 :]
@@ -74,7 +86,7 @@ var mountCmd = &cobra.Command{
74
86
}
75
87
}
76
88
if len (vmPath ) == 0 || ! strings .HasPrefix (vmPath , "/" ) {
77
- exit .Usage ("The :VM_MOUNT_DIRECTORY must be an absolute path" )
89
+ exit .Usage ("Target directory %q must be an absolute path" , vmPath )
78
90
}
79
91
var debugVal int
80
92
if glog .V (1 ) {
@@ -104,32 +116,88 @@ var mountCmd = &cobra.Command{
104
116
exit .WithCode (exit .Data , "error parsing the input ip address for mount" )
105
117
}
106
118
}
107
- console .OutStyle ("mounting" , "Mounting %s into %s on the minikube VM" , hostPath , vmPath )
108
- console .OutStyle ("notice" , "This daemon process needs to stay alive for the mount to be accessible ..." )
109
119
port , err := cmdUtil .GetPort ()
110
120
if err != nil {
111
121
exit .WithError ("Error finding port for mount" , err )
112
122
}
123
+
124
+ cfg := & cluster.MountConfig {
125
+ Type : mountType ,
126
+ UID : uid ,
127
+ GID : gid ,
128
+ Version : mountVersion ,
129
+ MSize : mSize ,
130
+ Port : port ,
131
+ Mode : os .FileMode (mode ),
132
+ Options : map [string ]string {},
133
+ }
134
+
135
+ for _ , o := range options {
136
+ if ! strings .Contains (o , "=" ) {
137
+ cfg .Options [o ] = ""
138
+ continue
139
+ }
140
+ parts := strings .Split (o , "=" )
141
+ cfg .Options [parts [0 ]] = parts [1 ]
142
+ }
143
+
144
+ console .OutStyle ("mounting" , "Mounting host path %s into VM as %s ..." , hostPath , vmPath )
145
+ console .OutStyle ("mount-options" , "Mount options:" )
146
+ console .OutStyle ("option" , "Type: %s" , cfg .Type )
147
+ console .OutStyle ("option" , "UID: %d" , cfg .UID )
148
+ console .OutStyle ("option" , "GID: %d" , cfg .GID )
149
+ console .OutStyle ("option" , "Version: %s" , cfg .Version )
150
+ console .OutStyle ("option" , "MSize: %d" , cfg .MSize )
151
+ console .OutStyle ("option" , "Mode: %o (%s)" , cfg .Mode , cfg .Mode )
152
+ console .OutStyle ("option" , "Options: %s" , cfg .Options )
153
+
154
+ // An escape valve to allow future hackers to try NFS, VirtFS, or other FS types.
155
+ if ! supportedFilesystems [cfg .Type ] {
156
+ console .OutLn ("" )
157
+ console .OutStyle ("warning" , "%s is not yet a supported filesystem. We will try anyways!" , cfg .Type )
158
+ }
159
+
113
160
var wg sync.WaitGroup
114
- wg .Add (1 )
161
+ if cfg .Type == nineP {
162
+ wg .Add (1 )
163
+ go func () {
164
+ console .OutStyle ("fileserver" , "Userspace file server: " )
165
+ ufs .StartServer (net .JoinHostPort (ip .String (), strconv .Itoa (port )), debugVal , hostPath )
166
+ wg .Done ()
167
+ }()
168
+ }
169
+
170
+ // Unmount if Ctrl-C or kill request is received.
171
+ c := make (chan os.Signal , 1 )
172
+ signal .Notify (c , os .Interrupt , syscall .SIGTERM )
115
173
go func () {
116
- ufs .StartServer (net .JoinHostPort (ip .String (), port ), debugVal , hostPath )
117
- wg .Done ()
174
+ for sig := range c {
175
+ console .OutStyle ("unmount" , "Unmounting %s ..." , vmPath )
176
+ cluster .Unmount (host , vmPath )
177
+ exit .WithCode (exit .Interrupted , "Exiting due to %s signal" , sig )
178
+ }
118
179
}()
119
- err = cluster .MountHost (api , ip , vmPath , port , mountVersion , uid , gid , msize )
180
+
181
+ err = cluster .Mount (host , ip .String (), vmPath , cfg )
120
182
if err != nil {
121
- exit .WithError ("failed to mount host " , err )
183
+ exit .WithError ("mount failed " , err )
122
184
}
185
+ console .OutStyle ("success" , "Successfully mounted %s to %s" , hostPath , vmPath )
186
+ console .OutLn ("" )
187
+ console .OutStyle ("notice" , "NOTE: This process must stay alive for the mount to be accessible ..." )
123
188
wg .Wait ()
124
189
},
125
190
}
126
191
127
192
func init () {
128
193
mountCmd .Flags ().StringVar (& mountIP , "ip" , "" , "Specify the ip that the mount should be setup on" )
194
+ mountCmd .Flags ().StringVar (& mountType , "type" , nineP , "Specify the mount filesystem type (supported types: 9p)" )
129
195
mountCmd .Flags ().StringVar (& mountVersion , "9p-version" , constants .DefaultMountVersion , "Specify the 9p version that the mount should use" )
130
196
mountCmd .Flags ().BoolVar (& isKill , "kill" , false , "Kill the mount process spawned by minikube start" )
131
197
mountCmd .Flags ().IntVar (& uid , "uid" , 1001 , "Default user id used for the mount" )
132
198
mountCmd .Flags ().IntVar (& gid , "gid" , 1001 , "Default group id used for the mount" )
133
- mountCmd .Flags ().IntVar (& msize , "msize" , constants .DefaultMsize , "The number of bytes to use for 9p packet payload" )
199
+ mountCmd .Flags ().UintVar (& mode , "mode" , 0755 , "File permissions used for the mount" )
200
+ mountCmd .Flags ().StringSliceVar (& options , "options" , []string {}, "Additional mount options, such as cache=fscache" )
201
+ mountCmd .Flags ().IntVar (& mSize , "msize" , constants .DefaultMsize , "The number of bytes to use for 9p packet payload" )
134
202
RootCmd .AddCommand (mountCmd )
135
203
}
0 commit comments