Skip to content

Commit 6e048e8

Browse files
Jancisazuenko
andcommitted
Merge pull request #17 from axeora/use-file-config
Co-authored-by: Anton Zuenko <[email protected]> Use rclone.conf - like configuration, in addition to cmd arguments
2 parents d728b51 + 8a37645 commit 6e048e8

File tree

8 files changed

+90
-16
lines changed

8 files changed

+90
-16
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@ stringData:
3737
s3-secret-access-key: "SECRET_ACCESS_KEY"
3838
```
3939

40+
Alternatively, you may specify rclone configuration file directly in the secret under `configData` field.
41+
42+
```
43+
apiVersion: v1
44+
kind: Secret
45+
metadata:
46+
name: rclone-secret
47+
type: Opaque
48+
stringData:
49+
remote: "my-s3"
50+
remotePath: "projectname"
51+
configData: |
52+
[my-s3]
53+
type = s3
54+
provider = Minio
55+
access_key_id = ACCESS_KEY_ID
56+
secret_access_key = SECRET_ACCESS_KEY
57+
endpoint = http://minio-release.default:9000
58+
```
59+
4060
Deploy example secret
4161
> `kubectl apply -f example/kubernetes/rclone-secret-example.yaml --namespace kube-system`
4262

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v1.3.0
1+
v1.3.1

deploy/kubernetes/1.13/csi-controller-rclone.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ spec:
4444
- name: socket-dir
4545
mountPath: /csi
4646
- name: rclone
47-
image: wunderio/csi-rclone:v1.3.0
47+
image: wunderio/csi-rclone:v1.3.1
4848
args :
4949
- "/bin/csi-rclone-plugin"
5050
- "--nodeid=$(NODE_ID)"

deploy/kubernetes/1.13/csi-nodeplugin-rclone.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ spec:
4444
capabilities:
4545
add: ["SYS_ADMIN"]
4646
allowPrivilegeEscalation: true
47-
image: wunderio/csi-rclone:v1.3.0
47+
image: wunderio/csi-rclone:v1.3.1
4848
args:
4949
- "/bin/csi-rclone-plugin"
5050
- "--nodeid=$(NODE_ID)"

deploy/kubernetes/1.19/csi-controller-rclone.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ spec:
3333
- name: socket-dir
3434
mountPath: /csi
3535
- name: rclone
36-
image: wunderio/csi-rclone:v1.3.0
36+
image: wunderio/csi-rclone:v1.3.1
3737
args :
3838
- "/bin/csi-rclone-plugin"
3939
- "--nodeid=$(NODE_ID)"

deploy/kubernetes/1.19/csi-nodeplugin-rclone.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ spec:
4444
capabilities:
4545
add: ["SYS_ADMIN"]
4646
allowPrivilegeEscalation: true
47-
image: wunderio/csi-rclone:v1.3.0
47+
image: wunderio/csi-rclone:v1.3.1
4848
args:
4949
- "/bin/csi-rclone-plugin"
5050
- "--nodeid=$(NODE_ID)"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: v1
2+
kind: Secret
3+
metadata:
4+
name: rclone-secret
5+
namespace: csi-rclone
6+
type: Opaque
7+
stringData:
8+
remote: "my-s3"
9+
remotePath: "projectname"
10+
configData: |
11+
[my-s3]
12+
type = s3
13+
provider = Minio
14+
access_key_id = ACCESS_KEY_ID
15+
secret_access_key = SECRET_ACCESS_KEY
16+
endpoint = http://minio-release.default:9000

pkg/rclone/nodeserver.go

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

140147
func (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

Comments
 (0)