@@ -77,13 +77,13 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
7777 // Load default connection settings from secret
7878 secret , e := getSecret ("rclone-secret" )
7979
80- remote , remotePath , flags , e := extractFlags (req .GetVolumeContext (), secret )
80+ remote , remotePath , configData , flags , e := extractFlags (req .GetVolumeContext (), secret )
8181 if e != nil {
8282 klog .Warningf ("storage parameter error: %s" , e )
8383 return nil , e
8484 }
8585
86- e = Mount (remote , remotePath , targetPath , flags )
86+ e = Mount (remote , remotePath , targetPath , configData , flags )
8787 if e != nil {
8888 if os .IsPermission (e ) {
8989 return nil , status .Error (codes .PermissionDenied , e .Error ())
@@ -97,7 +97,7 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
9797 return & csi.NodePublishVolumeResponse {}, nil
9898}
9999
100- func extractFlags (volumeContext map [string ]string , secret * v1.Secret ) (string , string , map [string ]string , error ) {
100+ func extractFlags (volumeContext map [string ]string , secret * v1.Secret ) (string , string , string , map [string ]string , error ) {
101101
102102 // Empty argument list
103103 flags := make (map [string ]string )
@@ -120,7 +120,7 @@ func extractFlags(volumeContext map[string]string, secret *v1.Secret) (string, s
120120 }
121121
122122 if e := validateFlags (flags ); e != nil {
123- return "" , "" , flags , e
123+ return "" , "" , "" , flags , e
124124 }
125125
126126 remote := flags ["remote" ]
@@ -131,10 +131,17 @@ func extractFlags(volumeContext map[string]string, secret *v1.Secret) (string, s
131131 delete (flags , "remotePathSuffix" )
132132 }
133133
134+ configData := ""
135+ ok := false
136+
137+ if configData , ok = flags ["configData" ]; ok {
138+ delete (flags , "configData" )
139+ }
140+
134141 delete (flags , "remote" )
135142 delete (flags , "remotePath" )
136143
137- return remote , remotePath , flags , nil
144+ return remote , remotePath , configData , flags , nil
138145}
139146
140147func (ns * nodeServer ) NodeUnpublishVolume (ctx context.Context , req * csi.NodeUnpublishVolumeRequest ) (* csi.NodeUnpublishVolumeResponse , error ) {
@@ -221,7 +228,7 @@ func getSecret(secretName string) (*v1.Secret, error) {
221228}
222229
223230// Mount routine.
224- func Mount (remote string , remotePath string , targetPath string , flags map [string ]string ) error {
231+ func Mount (remote string , remotePath string , targetPath string , configData string , flags map [string ]string ) error {
225232 mountCmd := "rclone"
226233 mountArgs := []string {}
227234
@@ -233,16 +240,47 @@ func Mount(remote string, remotePath string, targetPath string, flags map[string
233240 defaultFlags ["allow-non-empty" ] = "true"
234241 defaultFlags ["allow-other" ] = "true"
235242
236- // rclone mount remote:path /path/to/mountpoint [flags]
243+ remoteWithPath := fmt . Sprintf ( ":%s:%s" , remote , remotePath )
237244
245+ if strings .Contains (configData , "[" + remote + "]" ) {
246+ remoteWithPath = fmt .Sprintf ("%s:%s" , remote , remotePath )
247+ klog .Infof ("remote %s found in configData, remoteWithPath set to %s" , remote , remoteWithPath )
248+ }
249+
250+ // rclone mount remote:path /path/to/mountpoint [flags]
238251 mountArgs = append (
239252 mountArgs ,
240253 "mount" ,
241- fmt . Sprintf ( ":%s:%s" , remote , remotePath ) ,
254+ remoteWithPath ,
242255 targetPath ,
243256 "--daemon" ,
244257 )
245258
259+ // If a custom flag configData is defined,
260+ // create a temporary file, fill it with configData content,
261+ // and run rclone with --config <tmpfile> flag
262+ if configData != "" {
263+
264+ configFile , err := ioutil .TempFile ("" , "rclone.conf" )
265+ if err != nil {
266+ return err
267+ }
268+
269+ // Normally, a defer os.Remove(configFile.Name()) should be placed here.
270+ // However, due to a rclone mount --daemon flag, rclone forks and creates a race condition
271+ // with this nodeplugin proceess. As a result, the config file gets deleted
272+ // before it's reread by a forked process.
273+
274+ if _ , err := configFile .Write ([]byte (configData )); err != nil {
275+ return err
276+ }
277+ if err := configFile .Close (); err != nil {
278+ return err
279+ }
280+
281+ mountArgs = append (mountArgs , "--config" , configFile .Name ())
282+ }
283+
246284 // Add default flags
247285 for k , v := range defaultFlags {
248286 // Exclude overriden flags
@@ -262,12 +300,12 @@ func Mount(remote string, remotePath string, targetPath string, flags map[string
262300 return err
263301 }
264302
265- klog .Infof ("executing mount command cmd=%s, remote=:%s:%s , targetpath=%s" , mountCmd , remote , remotePath , targetPath )
303+ klog .Infof ("executing mount command cmd=%s, remote=%s , targetpath=%s" , mountCmd , remoteWithPath , targetPath )
266304
267305 out , err := exec .Command (mountCmd , mountArgs ... ).CombinedOutput ()
268306 if err != nil {
269- return fmt .Errorf ("mounting failed: %v cmd: '%s' remote: ':%s: %s' targetpath: %s output: %q" ,
270- err , mountCmd , remote , remotePath , targetPath , string (out ))
307+ return fmt .Errorf ("mounting failed: %v cmd: '%s' remote: '%s' targetpath: %s output: %q" ,
308+ err , mountCmd , remoteWithPath , targetPath , string (out ))
271309 }
272310
273311 return nil
0 commit comments