File 8652.patch of Package rclone
From b3d240d9aa3037b4ac53d9a673533923086855e3 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Mon, 30 Jun 2025 17:37:34 +0200
Subject: [PATCH 1/6] Add vendor OpenCloud to webdav backend
OpenCloud is a fork of ownCloud Infinite Scale
---
backend/webdav/tus.go | 1 +
backend/webdav/webdav.go | 5 ++++-
docs/content/webdav.md | 10 ++++++++++
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/backend/webdav/tus.go b/backend/webdav/tus.go
index 3f6a843bbbd73..d88d80b370b4d 100644
--- a/backend/webdav/tus.go
+++ b/backend/webdav/tus.go
@@ -2,6 +2,7 @@ package webdav
/*
Chunked upload based on the tus protocol for ownCloud Infinite Scale
+ and OpenCloud
See https://tus.io/protocols/resumable-upload
*/
diff --git a/backend/webdav/webdav.go b/backend/webdav/webdav.go
index 32d8842579462..74f1527a3da75 100644
--- a/backend/webdav/webdav.go
+++ b/backend/webdav/webdav.go
@@ -90,6 +90,9 @@ func init() {
}, {
Value: "infinitescale",
Help: "ownCloud Infinite Scale",
+ }, {
+ Value: "opencloud",
+ Help: "OpenCloud",
}, {
Value: "sharepoint",
Help: "Sharepoint Online, authenticated by Microsoft account",
@@ -642,7 +645,7 @@ func (f *Fs) setQuirks(ctx context.Context, vendor string) error {
f.propsetMtime = true
f.hasOCMD5 = true
f.hasOCSHA1 = true
- case "infinitescale":
+ case "opencloud", "infinitescale":
f.precision = time.Second
f.useOCMtime = true
f.propsetMtime = true
diff --git a/docs/content/webdav.md b/docs/content/webdav.md
index e30ef76cba9e9..611f5a6de2595 100644
--- a/docs/content/webdav.md
+++ b/docs/content/webdav.md
@@ -391,6 +391,16 @@ settings of the user through a checkbox there.
Infinite Scale works with the chunking [tus](https://tus.io) upload protocol.
The chunk size is currently fixed 10 MB.
+### OpenCloud
+
+The WebDAV URL for OpenCloud can be found in the details panel of
+any space in OpenCloud if the display was enabled in the personal
+settings of the user through a checkbox there.
+
+OpenCloud works with the chunking [tus](https://tus.io) upload protocol.
+The chunk size is currently fixed 10 MB. With that, files of any size
+can be uploaded to the cloud.
+
### Sharepoint Online
Rclone can be used with Sharepoint provided by OneDrive for Business
From ddc290658c032290cb4a6937d5c777ab7c8321b2 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Mon, 30 Jun 2025 17:38:12 +0200
Subject: [PATCH 2/6] test_all: Add test infrastructure for Webdav vendor
OpenCloud
---
backend/webdav/webdav_test.go | 38 ++++++++++++++++++++++++-----------
fstest/fstests/fstests.go | 4 ++--
fstest/test_all/config.yaml | 11 ++++++++++
3 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/backend/webdav/webdav_test.go b/backend/webdav/webdav_test.go
index 1949a41c60fc7..20f3f45766eeb 100644
--- a/backend/webdav/webdav_test.go
+++ b/backend/webdav/webdav_test.go
@@ -22,20 +22,34 @@ func TestIntegration(t *testing.T) {
// TestIntegration runs integration tests against the remote
func TestIntegration2(t *testing.T) {
- if *fstest.RemoteName != "" {
- t.Skip("skipping as -remote is set")
- }
- fstests.Run(t, &fstests.Opt{
- RemoteName: "TestWebdavOwncloud:",
- NilObject: (*Object)(nil),
- ChunkedUpload: fstests.ChunkedUploadConfig{
- Skip: true,
- },
- })
+ if *fstest.RemoteName != "" {
+ t.Skip("skipping as -remote is set")
+ }
+ fstests.Run(t, &fstests.Opt{
+ RemoteName: "TestWebdavOwncloud:",
+ NilObject: (*Object)(nil),
+ ChunkedUpload: fstests.ChunkedUploadConfig{
+ Skip: true,
+ },
+ })
}
-// TestIntegration runs integration tests against the remote
func TestIntegration3(t *testing.T) {
+ if *fstest.RemoteName != "" {
+ t.Skip("skipping as -remote is set")
+ }
+ fstests.Run(t, &fstests.Opt{
+ RemoteName: "TestWebdavOpenCloud:",
+ NilObject: (*Object)(nil),
+ ChunkedUpload: fstests.ChunkedUploadConfig{
+ Skip: true,
+ },
+ })
+}
+
+
+// TestIntegration runs integration tests against the remote
+func TestIntegration4(t *testing.T) {
if *fstest.RemoteName != "" {
t.Skip("skipping as -remote is set")
}
@@ -49,7 +63,7 @@ func TestIntegration3(t *testing.T) {
}
// TestIntegration runs integration tests against the remote
-func TestIntegration4(t *testing.T) {
+func TestIntegration5(t *testing.T) {
if *fstest.RemoteName != "" {
t.Skip("skipping as -remote is set")
}
diff --git a/fstest/fstests/fstests.go b/fstest/fstests/fstests.go
index 5e1105cfc61ef..f005408e7c48d 100644
--- a/fstest/fstests/fstests.go
+++ b/fstest/fstests/fstests.go
@@ -459,11 +459,11 @@ func Run(t *testing.T, opt *Opt) {
t.Logf("Didn't find %q in config file - skipping tests", remoteName)
return
}
- require.NoError(t, err, fmt.Sprintf("unexpected error: %v", err))
+ require.NoError(t, err, fmt.Sprintf(" 1 unexpected error: %v", err))
// Get fsInfo which contains type, etc. of the fs
fsInfo, _, _, _, err := fs.ConfigFs(subRemoteName)
- require.NoError(t, err, fmt.Sprintf("unexpected error: %v", err))
+ require.NoError(t, err, fmt.Sprintf(" 2 unexpected error: %v", err))
// Skip the rest if it failed
skipIfNotOk(t)
diff --git a/fstest/test_all/config.yaml b/fstest/test_all/config.yaml
index f24cc6cc8cc4f..7f03b7ae92e31 100644
--- a/fstest/test_all/config.yaml
+++ b/fstest/test_all/config.yaml
@@ -487,6 +487,17 @@ backends:
ignoretests:
- cmd/bisync
- cmd/gitannex
+ - backend: "webdav"
+ remote: "TestWebdavOpenCloud:"
+ ignore:
+ - TestIntegration/FsMkdir/FsEncoding/punctuation
+ - TestIntegration/FsMkdir/FsEncoding/invalid_UTF-8
+ env:
+ - RCLONE_NO_CHECK_CERTIFICATE=true
+ fastlist: false
+ ignoretests:
+ - cmd/bisync
+ - cmd/gitannex
- backend: "webdav"
remote: "TestWebdavRclone:"
ignore:
From d5e641ff71aad26890b9aac1f29c933dc7b11296 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Wed, 2 Jul 2025 16:32:29 +0200
Subject: [PATCH 3/6] Add OpenCloud testserver start script
---
fstest/testserver/init.d/TestWebdavOpenCloud | 52 ++++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100755 fstest/testserver/init.d/TestWebdavOpenCloud
diff --git a/fstest/testserver/init.d/TestWebdavOpenCloud b/fstest/testserver/init.d/TestWebdavOpenCloud
new file mode 100755
index 0000000000000..ce93de18d39d6
--- /dev/null
+++ b/fstest/testserver/init.d/TestWebdavOpenCloud
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+set -e
+
+NAME=opencloud
+USER=admin
+PASS=admin
+PORT=9200
+
+CONF_DIR=/tmp/opencloud-config
+install -d -m 0777 ${CONF_DIR}
+
+. $(dirname "$0")/docker.bash
+
+start() {
+ echo "*************************** init"
+ docker run --rm --name $NAME \
+ -v ${CONF_DIR}:/etc/opencloud \
+ -e "OC_INSECURE=true" \
+ -e "IDM_ADMIN_PASSWORD=$PASS" \
+ -e "OC_FORCE_CONFIG_OVERWRITE=true" \
+ -e "OC_URL=https://127.0.0.1:$PORT" \
+ opencloudeu/opencloud-rolling \
+ init
+
+ docker run --rm -d --name $NAME \
+ -e "OC_LOG_LEVEL=debug" \
+ -e "OC_LOG_PRETTY=true" \
+ -e "OC_URL=https://127.0.0.1:$PORT" \
+ -e "IDM_ADMIN_PASSWORD=$PASS" \
+ -e "OC_INSECURE=true" \
+ -e "PROXY_ENABLE_BASIC_AUTH=true" \
+ -v ${CONF_DIR}:/etc/opencloud \
+ -p 127.0.0.1:${PORT}:9200 \
+ opencloudeu/opencloud-rolling
+
+ echo type=webdav
+ echo url=https://127.0.0.1:${PORT}/dav/spaces/some-admin-user-id-0000-100000000000
+ echo user=$USER
+ echo pass=$(rclone obscure $PASS)
+ echo vendor=opencloud
+ echo _connect=127.0.0.1:${PORT}
+ echo _connect_delay=5s
+}
+
+stop() {
+ # Clean up the mess
+ docker stop opencloud
+ rm -r ${CONF_DIR}
+}
+
+. $(dirname "$0")/run.bash
From 726c5d4e270116e0bf5e511b22524725b8840629 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Thu, 10 Jul 2025 18:25:08 +0200
Subject: [PATCH 4/6] Fix some startup parameters and retrieve the correct
WebDAV Url
OpenCloud needs a so called storage provider ID (mount id) and
the final WebDAV Url for the test has to be queried
---
fstest/testserver/init.d/TestWebdavOpenCloud | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/fstest/testserver/init.d/TestWebdavOpenCloud b/fstest/testserver/init.d/TestWebdavOpenCloud
index ce93de18d39d6..87c907130f377 100755
--- a/fstest/testserver/init.d/TestWebdavOpenCloud
+++ b/fstest/testserver/init.d/TestWebdavOpenCloud
@@ -20,24 +20,32 @@ start() {
-e "IDM_ADMIN_PASSWORD=$PASS" \
-e "OC_FORCE_CONFIG_OVERWRITE=true" \
-e "OC_URL=https://127.0.0.1:$PORT" \
+ -e "OC_ADMIN_USER_ID=some-admin-user-id-0000-100000000000" \
+ -e "GATEWAY_STORAGE_USERS_MOUNT_ID=storage-users-1" \
+ -e "STORAGE_USERS_MOUNT_ID=storage-users-1" \
opencloudeu/opencloud-rolling \
init
- docker run --rm -d --name $NAME \
+ docker run -d --name $NAME \
-e "OC_LOG_LEVEL=debug" \
-e "OC_LOG_PRETTY=true" \
-e "OC_URL=https://127.0.0.1:$PORT" \
-e "IDM_ADMIN_PASSWORD=$PASS" \
+ -e "OC_ADMIN_USER_ID=some-admin-user-id-0000-100000000000" \
+ -e "GATEWAY_STORAGE_USERS_MOUNT_ID=storage-users-1" \
+ -e "STORAGE_USERS_MOUNT_ID=storage-users-1" \
-e "OC_INSECURE=true" \
-e "PROXY_ENABLE_BASIC_AUTH=true" \
-v ${CONF_DIR}:/etc/opencloud \
-p 127.0.0.1:${PORT}:9200 \
opencloudeu/opencloud-rolling
-
+
+ sleep 10
echo type=webdav
- echo url=https://127.0.0.1:${PORT}/dav/spaces/some-admin-user-id-0000-100000000000
+ url=$(curl -f -s -k -u admin:${PASS} "https://127.0.0.1:${PORT}/graph/v1.0/me/drive" -H 'accept: application/json' | jq -r '.root.webDavUrl' - )
+ echo url=${url}
echo user=$USER
- echo pass=$(rclone obscure $PASS)
+ echo pass=$(/home/kf/git/rclone/rclone obscure $PASS)
echo vendor=opencloud
echo _connect=127.0.0.1:${PORT}
echo _connect_delay=5s
From 8b9a3848c33c820fd38c1370daa9ca8dcef8200b Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Thu, 10 Jul 2025 18:26:48 +0200
Subject: [PATCH 5/6] OpenCloud can not set the modification time via PROPSET
Adjusted the config parameters accordingly
---
backend/webdav/webdav.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/webdav/webdav.go b/backend/webdav/webdav.go
index 74f1527a3da75..e7ea740d5b551 100644
--- a/backend/webdav/webdav.go
+++ b/backend/webdav/webdav.go
@@ -648,7 +648,7 @@ func (f *Fs) setQuirks(ctx context.Context, vendor string) error {
case "opencloud", "infinitescale":
f.precision = time.Second
f.useOCMtime = true
- f.propsetMtime = true
+ f.propsetMtime = false
f.hasOCMD5 = false
f.hasOCSHA1 = true
f.canChunk = false
From 04a979b07daa01fcd237fb93882b870a01601436 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Wed, 10 Sep 2025 10:05:24 +0200
Subject: [PATCH 6/6] Fix formatting, makes linter hopefully happy
---
backend/webdav/webdav_test.go | 41 +++++++++++++++++------------------
1 file changed, 20 insertions(+), 21 deletions(-)
diff --git a/backend/webdav/webdav_test.go b/backend/webdav/webdav_test.go
index 20f3f45766eeb..6f06956537596 100644
--- a/backend/webdav/webdav_test.go
+++ b/backend/webdav/webdav_test.go
@@ -22,32 +22,31 @@ func TestIntegration(t *testing.T) {
// TestIntegration runs integration tests against the remote
func TestIntegration2(t *testing.T) {
- if *fstest.RemoteName != "" {
- t.Skip("skipping as -remote is set")
- }
- fstests.Run(t, &fstests.Opt{
- RemoteName: "TestWebdavOwncloud:",
- NilObject: (*Object)(nil),
- ChunkedUpload: fstests.ChunkedUploadConfig{
- Skip: true,
- },
- })
+ if *fstest.RemoteName != "" {
+ t.Skip("skipping as -remote is set")
+ }
+ fstests.Run(t, &fstests.Opt{
+ RemoteName: "TestWebdavOwncloud:",
+ NilObject: (*Object)(nil),
+ ChunkedUpload: fstests.ChunkedUploadConfig{
+ Skip: true,
+ },
+ })
}
func TestIntegration3(t *testing.T) {
- if *fstest.RemoteName != "" {
- t.Skip("skipping as -remote is set")
- }
- fstests.Run(t, &fstests.Opt{
- RemoteName: "TestWebdavOpenCloud:",
- NilObject: (*Object)(nil),
- ChunkedUpload: fstests.ChunkedUploadConfig{
- Skip: true,
- },
- })
+ if *fstest.RemoteName != "" {
+ t.Skip("skipping as -remote is set")
+ }
+ fstests.Run(t, &fstests.Opt{
+ RemoteName: "TestWebdavOpenCloud:",
+ NilObject: (*Object)(nil),
+ ChunkedUpload: fstests.ChunkedUploadConfig{
+ Skip: true,
+ },
+ })
}
-
// TestIntegration runs integration tests against the remote
func TestIntegration4(t *testing.T) {
if *fstest.RemoteName != "" {