Compare commits

...

71 commits

Author SHA1 Message Date
abraunegg 1a88d33be3 Backport v2.5.x documentation changes
* Backport v2.5.x documentation changes for Docker and Podman
2023-11-16 09:15:30 +11:00
abraunegg 6282ec9e3b Update ubuntu-package-install.md
* Update doc to align to v2.5.x version
2023-11-10 04:50:50 +11:00
abraunegg 4a60654e3f
Update USAGE.md
* Fix documentation regarding skip_file example
2023-09-25 08:04:29 +10:00
abraunegg a74ff589f8
Update USAGE.md (#2488)
* Add classify_as_big_delete
2023-09-14 07:06:56 +10:00
abraunegg 651aa16844
Update application-security.md
* Fix spelling error
2023-09-11 10:16:50 +10:00
abraunegg 85f99cb899
Update Security Documents (#2484)
* Update Security Documents
2023-09-11 07:26:14 +10:00
abraunegg d712dd6093
Update USAGE.md
* Add note about minimum value for ''monitor_interval'
2023-08-31 09:55:54 +10:00
abraunegg 43b0bed4cb
Fix debugging log output when reporting file size and hash mismatch (#2473)
* Fix debug logging output with correct hash values as these were switched
* Only calculate local file size post download once and reuse value
2023-08-24 18:08:21 +10:00
Flynn Duniho fc5cbaf2e9
Fix typo in USAGE.md (#2466)
* Fix typo in USAGE.md
2023-08-07 12:44:40 +10:00
abraunegg 50d80d333e
Add Debian 12 to documentation (#2459)
* Add Debian 12 to documentation
2023-07-27 05:32:20 +10:00
Gonçalo Martins 99271a45de
Add --no-remote-delete flag to docker entrypoint (#2453)
* Add --no-remote-delete flag to docker entrypoint

---------

Co-authored-by: Gonçalo Martins <g.martins@revolut.com>
Co-authored-by: abraunegg <alex.braunegg@gmail.com>
2023-07-24 10:41:06 +10:00
abraunegg fb0a5f0796
Fix unhandled exception when authurl path is non-existent (#2456)
* Catch an unhandled exception when the user sets the authurl file to a location that cannot be accessed
2023-07-23 10:13:03 +10:00
abraunegg 94ccb7a6d0 Update webhook example configuration documentation
* Update webhook example configuration based on #2447
2023-07-11 18:09:45 +02:00
abraunegg b2bf6aa475
Release files for 2.4.25 (#2440)
* Release files for 2.4.25
2023-06-21 15:30:40 +10:00
abraunegg 268dcf9120
Fix that zero-byte files do not have a hash as reported by the OneDrive API thus should not generate an error message (#2436)
* The OneDrive API does not present a hash for all files, most notably those that are zero byte in size (this may be fixed by the OneDrive API in the future). Add a wrapper to the existing makeItem function to test the file size before working out if this is a going to be a problem and if it is, then print out an error message if the file size is greater than 0 including either the full filename path or the items id.
2023-06-21 13:21:05 +10:00
abraunegg f5edb8b394
Update Docker files June 2023 (#2438)
* Update Docker Files June 2023 and Documentation
2023-06-21 12:59:46 +10:00
abraunegg 4b32dbf12d
Update testbuild.yaml (#2439)
* Update testbuild.yaml and downgrade to Ubuntu 20.04
2023-06-21 11:15:56 +10:00
abraunegg 628a85dc93
Add Ubuntu 23.04 Instructions (#2437)
* Add Ubuntu 23.04 Instructions
2023-06-21 10:54:07 +10:00
abraunegg 3340fcca6a
Update util.d (#2428)
* Remove running version obsolete flag as this causes a false flagging as obsolete
2023-06-20 11:18:20 +10:00
abraunegg 25cc361277
Release files for 2.4.24 v2 (#2427)
* Release files for 2.4.24 v2 to correct incorrect configure.ac version
2023-06-20 10:48:08 +10:00
abraunegg 32a702eaaf Revert "Release files for 2.4.24 (#2426)"
This reverts commit 30b108027d.
2023-06-20 10:41:25 +10:00
abraunegg 30b108027d
Release files for 2.4.24 (#2426)
* Release files for 2.4.24
2023-06-20 10:38:36 +10:00
abraunegg dfd1d1aa4a
Implement #2414 to allow HTTP session timeout(s) tuning via config (#2425)
* Implement #2414 to allow HTTP session timeout(s) tuning via config (taken from v2.5.x)
2023-06-20 09:28:17 +10:00
abraunegg 06420c9a0a
Remove sha1 use and cleanup defunct remaining crc32 use (#2424)
* Remove sha1 from being used by the client as this is being depreciated by Microsoft in July 2023 - https://devblogs.microsoft.com/microsoft365dev/deprecation-of-sha1hash-on-onedrive-personal/
* Complete the removal of crc32 as this is also no longer present for a long time, but some code elements still existed
* Only compute quickXorHash, not quickXorHash and sha256Hash as computing sha256Hash is CPU expensive
* Update cache database stored items to only store quickXorHash and sha256Hash values (remove crc32 and sha1)
2023-06-20 06:55:00 +10:00
abraunegg c9fe8ad051 Update INSTALL.md
* Fix Readme
2023-06-17 08:48:30 +10:00
abraunegg 8045002c87
Update INSTALL.md (#2421)
* Add Linux Mint so it is clear that for Linux Mint users that the OpenSuSE Repository must be used
2023-06-17 08:19:07 +10:00
abraunegg b0eb9ffcdf Update ubuntu-package-install.md
* Add note to remove erroneous systemd service entry
2023-06-12 09:05:13 +10:00
abraunegg aa294b32f8
Update ubuntu-package-install.md
* Update wording
2023-06-12 08:45:03 +10:00
abraunegg 669a21747b
Update Docker.md (#2409)
* Update Docker document to detail to use 'edge' to align to documentation
2023-06-03 07:36:47 +10:00
abraunegg 3b8d7b3b1a
Update ubuntu-package-install.md (#2405)
* Flag Ubuntu 18.x as EOL
* Add 23.04 details to INSTALL.md
2023-06-01 07:52:51 +10:00
abraunegg 64a3bfb033
Update INSTALL.md (#2403)
* Remove Ubuntu 18.x and Debian 9 as these are now EOL
2023-05-31 17:20:59 +10:00
abraunegg 16b751971f
Fix Unable to perform a database vacuum: out of memory when exiting (#2398)
* Due to many poor Internet sources of how to use this application, may folk still do not add --synchronize or --monitor switches because their documentation source fails to detail this. When this is the case, the itemdb does not get fully initialised, but when we exit, we try and clean up, because we have partially initalised, we cannot perform a vacuum of the database which generates an error. This patch adds a flag for this specific scenario, so that if triggered, we do not try to vacuum the database and not triggering a false error.
2023-05-12 18:41:01 +10:00
abraunegg d960febb18
Update README.md (#2393)
* Add Supported Application Versions to README.md and re-structure some sections
2023-05-01 13:00:56 +10:00
abraunegg 77684452aa
Update Docker gosu version to 1.16 to resolve current vulnerabilities (#2386)
* Update gosu version to 1.16
2023-04-18 14:35:24 +10:00
abraunegg 4e5a32c210
Update to Fedora Docker file to use Fedora 37 to resolve current vulnerabilities (#2383)
* Update to use Docker build to use Fedora 37
* Update golang to 1.20
2023-04-18 12:40:05 +10:00
abraunegg 56149c285c
Update to Alpine Docker file to resolve current vulnerabilities (#2384)
* Update to Alpine Docker file to resolve current vulnerabilities
2023-04-18 08:54:10 +10:00
abraunegg ae33616d0b
Update to Debian Docker file to resolve current vulnerabilities (#2385)
* Update to Debian Docker file to resolve current vulnerabilities
2023-04-18 07:34:48 +10:00
abraunegg 3ef4a27fb7
Update USAGE.md (#2382)
* Update usage document to add skip_dotfiles and example
2023-04-17 13:02:38 +10:00
Marni b6d477b04e
Update USAGE.md (#2374)
Updated the sync_list examples. Made it more clear on how it works.
The reason for this edit is to avoid confusion on how the rules work for newcomers, when they first read the examples.
2023-04-08 10:53:35 +10:00
abraunegg 5945edc060
Update ubuntu-package-install.md
* Remove Linux Mint code names as they change between releases.
2023-04-07 16:51:15 +10:00
abraunegg 3aa191e3e4
Update Docker and Podman documents and clarify i386|i686 support (#2370)
* Update Docker and Podman documents clarifying i386|i686 compatibility
* Add building Linux/386 Docker images given that Debian have a compatible LCD version for i386|i686
2023-04-06 07:45:14 +10:00
abraunegg 6324f915fc
Update Docker.md
* Correct Alpine platform use
2023-04-05 10:49:51 +10:00
abraunegg 8c6bdb984d
Fix deprecation warnings with dmd 2.103.0 (#2364)
* Update cgi.d to commit 680003a - last upstream change before requiring `core.d` dependency requirement
* Fix deprecation warnings with dmd 2.103.0 by find/replace `isVirtualFunction` with `isVirtualMethod` in cgi.d
2023-04-03 07:13:11 +10:00
Kendon Bell d48bb34036
Add warning regarding SharePoint Library use (#2354)
* Add suggested warning
* Update PR wording

---------

Co-authored-by: abraunegg <alex.braunegg@gmail.com>
2023-03-28 06:41:57 +11:00
abraunegg ce9b781c34
Update testbuild.yaml (#2356)
* Update image before attempting to install anything
2023-03-27 17:38:31 +11:00
abraunegg 00ce7eed0e
Fix that folders are renamed despite using --dry-run (#2343)
* Fix that folders are renamed despite using --dry-run
2023-03-27 17:22:48 +11:00
abraunegg 0838651327
Update USAGE.md
* Specifically add example for 'sync_list' for Windows folder 'Pictures/Camera Roll'
2023-03-27 08:58:32 +11:00
abraunegg cfb4933778
Fix that a HTTP 504 - Gateway Timeout causes local files to be deleted when using --download-only & --cleanup-local-files mode (#2342)
* Fix that a HTTP 504 - Gateway Timeout causes local files to be deleted when using --download-only & --cleanup-local-files mode
2023-03-19 09:54:58 +11:00
abraunegg 6607ba537b
Fix webhook subscription creation for SharePoint Libraries (#2339)
* Fix webhook subscription creation for SharePoint Libraries
2023-03-18 10:03:49 +11:00
NigelVanHattum 52b1276282
Fix for extra encoded quotation marks surrounding Docker environment variables (#2319)
* Fix for extra encoded quotation marks surrounding Docker environment variables

---------

Co-authored-by: Hattum van <Nigel.van.Hattum@rabobank.nl>
Co-authored-by: abraunegg <alex.braunegg@gmail.com>
2023-03-18 09:53:58 +11:00
abraunegg 5b14157b09
Update INSTALL.md (#2333)
* Add Debian 12 details to INSTALL.md
2023-03-14 09:16:31 +11:00
abraunegg 00ba377c30
Update USAGE.md (#2331)
* Specifically add reference on how to sync both Personal and Business accounts at the same time
* Specifically add reference on how to sync multiple SharePoint Libraries at the same time
2023-03-11 07:25:35 +11:00
Joseph Helfer 537b4338a6
Add --get-file-link option to shell completions (#2308)
* Add --get-file-link option to bash completion
* Add --get-file-link completions for fish and zsh
* Have --get-file-link completion complete files in sync_dir

---------

Co-authored-by: abraunegg <alex.braunegg@gmail.com>
2023-03-07 08:29:57 +11:00
Dimitrios Makris eaeebbde8c
Update Docker.md (#2321)
Fix typo
2023-02-27 09:36:54 +11:00
abraunegg c92d8470f4
Update Docker documentation to support locales for for double-byte language support (#2317)
* Update Docker documentation to support locales for for double-byte language support
2023-02-27 07:44:07 +11:00
NigelVanHattum b3829c1ef3
Add single directory sync to docker (#2309)
* Add single directory sync to docker

---------

Co-authored-by: Hattum van <Nigel.van.Hattum@rabobank.nl>
Co-authored-by: abraunegg <alex.braunegg@gmail.com>
2023-02-24 06:30:00 +11:00
benediktschlager 3acb6c13d2
Podman: Fix test volume is used (#2297)
Use environment variable instead of test volume
2023-01-30 09:50:03 +11:00
abraunegg c10870abd4
Release 2.5.0 Development Prep (#2281)
* Release 2.5.0 Development Prep
2023-01-06 13:48:30 +11:00
abraunegg b9a239ace1
Release files for 2.4.23 (#2280)
* Release files for 2.4.23
2023-01-06 09:00:45 +11:00
abraunegg d043d5584f
Update handling of --source-directory and --destination-directory if empty (#2278)
* Update handling of --source-directory and --destination-directory if one is empty or missing and if used with --synchronize or --monitor
2023-01-02 09:17:39 +11:00
abraunegg 54e1ab0c16
Update Alpine Dockerfile to use Alpine 3.17 (#2277)
* Update Alpine Dockerfile to use Alpine 3.17
* Update golang version to use Golang 1.19
2022-12-30 12:07:29 +11:00
abraunegg ad20628dbe Update USAGE.md
* Add usage clarification
2022-12-28 10:34:36 +11:00
abraunegg 15233e485f
Update application-security.md
* Fix typo
2022-12-28 08:38:56 +11:00
Moritz 7d5a5d33fd
docs: Fix typos in Docker.md (#2270)
'Apline' should actually read 'Alpine'.
2022-12-21 06:24:55 +11:00
abraunegg 6bf0ea5deb
Update version checks (#2269)
* Update version checks to use current application version release date as part of calculating if the client is obsolete and not supported.
2022-12-20 16:48:15 +11:00
abraunegg 3bca35d345
Update version release notification handling (#2267)
* Update the GitHub version check to also utilise the date a release was done, to allow 1 month grace period before generating obsolete version message.
2022-12-17 06:56:12 +11:00
abraunegg 678add91f8
Update --get-O365-drive-id error handling (#2266)
* Ensure a 'Personal' account type is not being used
* If the /sites?search API cannot be found, display a more appropriate error message
2022-12-16 06:08:46 +11:00
abraunegg 4db2ec02fc
systemd: disable PrivateUsers (#2265)
* systemd: disable PrivateUsers
2022-12-14 06:19:25 +11:00
abraunegg c22010095f Update INSTALL.md
* Update OpenSuSE version badge API call
2022-12-09 08:44:28 +11:00
abraunegg 44937abeb8
Update RHEL7, RHEL8 and RHEL9 Makefile and SPEC file compatibility (#2256)
* Update RHEL7, RHEL8 and RHEL9 Makefile and SPEC file compatibility with /etc/redhat-release
2022-12-08 05:38:38 +11:00
abraunegg b2cea4b1dd
Restore RHEL7 spec file compatibility (#2254)
* Restore RHEL7 spec file compatibility caused by a348750ec6
2022-12-07 09:01:21 +11:00
35 changed files with 2619 additions and 1298 deletions

View file

@ -5,6 +5,7 @@ on:
branches: [ master ]
tags: [ 'v*' ]
pull_request:
# Comment these out to force a test build on a PR
branches:
- master
types: [closed]
@ -14,7 +15,10 @@ env:
jobs:
build:
# Comment this out to force a test build on a PR
if: (!(github.event.action == 'closed' && github.event.pull_request.merged != true))
# Build runs on
runs-on: ubuntu-latest
strategy:
@ -26,7 +30,7 @@ jobs:
platforms: linux/amd64,linux/arm64
- flavor: debian
dockerfile: ./contrib/docker/Dockerfile-debian
platforms: linux/amd64,linux/arm64,linux/arm/v7
platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7
- flavor: alpine
dockerfile: ./contrib/docker/Dockerfile-alpine
platforms: linux/amd64,linux/arm64

View file

@ -9,7 +9,8 @@ on:
jobs:
build:
runs-on: ubuntu-latest
#runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- name: Check out code from GitHub
@ -18,6 +19,11 @@ jobs:
submodules: recursive
fetch-depth: 0
- name: Update Image
run: |
sudo apt-get clean
sudo apt-get update -y
- name: Install build-essential
run: sudo apt install -y build-essential

View file

@ -2,6 +2,57 @@
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## 2.4.25 - 2023-06-21
### Fixed
* Fixed that the application was reporting as v2.2.24 when in fact it was v2.4.24 (release tagging issue)
* Fixed that the running version obsolete flag (due to above issue) was causing a false flag as being obsolete
* Fixed that zero-byte files do not have a hash as reported by the OneDrive API thus should not generate an error message
### Updated
* Update to Debian Docker file to resolve Docker image Operating System reported vulnerabilities
* Update to Alpine Docker file to resolve Docker image Operating System reported vulnerabilities
* Update to Fedora Docker file to resolve Docker image Operating System reported vulnerabilities
* Updated documentation (various)
## 2.4.24 - 2023-06-20
### Fixed
* Fix for extra encoded quotation marks surrounding Docker environment variables
* Fix webhook subscription creation for SharePoint Libraries
* Fix that a HTTP 504 - Gateway Timeout causes local files to be deleted when using --download-only & --cleanup-local-files mode
* Fix that folders are renamed despite using --dry-run
* Fix deprecation warnings with dmd 2.103.0
* Fix error that the application is unable to perform a database vacuum: out of memory when exiting
### Removed
* Remove sha1 from being used by the client as this is being depreciated by Microsoft in July 2023
* Complete the removal of crc32 elements
### Added
* Added ONEDRIVE_SINGLE_DIRECTORY configuration capability to Docker
* Added --get-file-link shell completion
* Added configuration to allow HTTP session timeout(s) tuning via config (taken from v2.5.x)
### Updated
* Update to Debian Docker file to resolve Docker image Operating System reported vulnerabilities
* Update to Alpine Docker file to resolve Docker image Operating System reported vulnerabilities
* Update to Fedora Docker file to resolve Docker image Operating System reported vulnerabilities
* Updated cgi.d to commit 680003a - last upstream change before requiring `core.d` dependency requirement
* Updated documentation (various)
## 2.4.23 - 2023-01-06
### Fixed
* Fixed RHEL7, RHEL8 and RHEL9 Makefile and SPEC file compatibility
### Removed
* Disable systemd 'PrivateUsers' due to issues with systemd running processes when option is enabled, causes local file deletes on RHEL based systems
### Updated
* Update --get-O365-drive-id error handling to display a more a more appropriate error message if the API cannot be found
* Update the GitHub version check to utilise the date a release was done, to allow 1 month grace period before generating obsolete version message
* Update Alpine Dockerfile to use Alpine 3.17 and Golang 1.19
* Update handling of --source-directory and --destination-directory if one is empty or missing and if used with --synchronize or --monitor
* Updated documentation (various)
## 2.4.22 - 2022-12-06
### Fixed
* Fix application crash when local file is changed to a symbolic link with non-existent target

View file

@ -58,7 +58,7 @@ user_unit_files = contrib/systemd/onedrive.service
DOCFILES = README.md config LICENSE CHANGELOG.md docs/Docker.md docs/INSTALL.md docs/SharePoint-Shared-Libraries.md docs/USAGE.md docs/BusinessSharedFolders.md docs/advanced-usage.md docs/application-security.md
ifneq ("$(wildcard /etc/redhat-release)","")
RHEL = $(shell cat /etc/redhat-release | grep -E "(Red Hat Enterprise Linux Server|CentOS)" | wc -l)
RHEL = $(shell cat /etc/redhat-release | grep -E "(Red Hat Enterprise Linux|CentOS)" | wc -l)
RHEL_VERSION = $(shell rpm --eval "%{rhel}")
else
RHEL = 0

View file

@ -36,17 +36,28 @@ This client is a 'fork' of the [skilion](https://github.com/skilion/onedrive) cl
* Colorful log output terminal modification: [OneDrive Client for Linux Colorful log Output](https://github.com/zzzdeb/dotfiles/blob/master/scripts/tools/onedrive_log)
* System Tray Icon: [OneDrive Client for Linux System Tray Icon](https://github.com/DanielBorgesOliveira/onedrive_tray)
## Supported Application Version
Only the current application release version or greater is supported.
The current application release version is: [![Version](https://img.shields.io/github/v/release/abraunegg/onedrive)](https://github.com/abraunegg/onedrive/releases)
Check the version of the application you are using `onedrive --version` and ensure that you are running either the current release or compile the application yourself from master to get the latest version.
If you are not using the above application version or greater, you must upgrade your application to obtain support.
## Have a Question
If you have a question or need something clarified, please raise a new disscussion post [here](https://github.com/abraunegg/onedrive/discussions)
Be sure to review the Frequently Asked Questions as well before raising a new discussion post.
## Frequently Asked Questions
Refer to [Frequently Asked Questions](https://github.com/abraunegg/onedrive/wiki/Frequently-Asked-Questions)
## Have a question
If you have a question or need something clarified, please raise a new disscussion post [here](https://github.com/abraunegg/onedrive/discussions)
## Reporting an Issue or Bug
If you encounter any bugs you can report them here on Github. Before filing an issue be sure to:
If you encounter any bugs you can report them here on GitHub. Before filing an issue be sure to:
1. Check the version of the application you are using `onedrive --version` and ensure that you are running either the latest [release](https://github.com/abraunegg/onedrive/releases) or built from master.
2. Fill in a new bug report using the [issue template](https://github.com/abraunegg/onedrive/issues/new?template=bug_report.md)
1. Check the version of the application you are using `onedrive --version` and ensure that you are running a supported application version. If you are not using a supported application version, you must first upgrade your application to a supported version and then re-test for your issue.
2. If you are using a supported applcation version, fill in a new bug report using the [issue template](https://github.com/abraunegg/onedrive/issues/new?template=bug_report.md)
3. Generate a debug log for support using the following [process](https://github.com/abraunegg/onedrive/wiki/Generate-debug-log-for-support)
* If you are in *any* way concerned regarding the sensitivity of the data contained with in the verbose debug log file, create a new OneDrive account, configure the client to use that, use *dummy* data to simulate your environment and then replicate your original issue
* If you are still concerned, provide an NDA or confidentiality document to sign

6
config
View file

@ -44,7 +44,6 @@
# sync_dir_permissions = "700"
# sync_file_permissions = "600"
# rate_limit = "131072"
# operation_timeout = "3600"
# webhook_enabled = "false"
# webhook_public_url = ""
# webhook_listening_host = ""
@ -55,3 +54,8 @@
# display_running_config = "false"
# read_only_auth_scope = "false"
# cleanup_local_files = "false"
# operation_timeout = "3600"
# dns_timeout = "60"
# connect_timeout = "10"
# data_timeout = "600"
# ip_protocol_version = "0"

1174
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@ dnl - commit the changed files (configure.ac, configure)
dnl - tag the release
AC_PREREQ([2.69])
AC_INIT([onedrive],[v2.4.22], [https://github.com/abraunegg/onedrive], [onedrive])
AC_INIT([onedrive],[v2.4.25], [https://github.com/abraunegg/onedrive], [onedrive])
AC_CONFIG_SRCDIR([src/main.d])

View file

@ -10,7 +10,7 @@ _onedrive()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
options='--check-for-nomount --check-for-nosync --debug-https --disable-notifications --display-config --display-sync-status --download-only --disable-upload-validation --dry-run --enable-logging --force-http-1.1 --force-http-2 --local-first --logout -m --monitor --no-remote-delete --print-token --reauth --resync --skip-dot-files --skip-symlinks --synchronize --upload-only -v --verbose --version -h --help'
options='--check-for-nomount --check-for-nosync --debug-https --disable-notifications --display-config --display-sync-status --download-only --disable-upload-validation --dry-run --enable-logging --force-http-1.1 --force-http-2 --get-file-link --local-first --logout -m --monitor --no-remote-delete --print-token --reauth --resync --skip-dot-files --skip-symlinks --synchronize --upload-only -v --verbose --version -h --help'
argopts='--create-directory --get-O365-drive-id --operation-timeout --remove-directory --single-directory --source-directory'
# Loop on the arguments to manage conflicting options
@ -19,12 +19,21 @@ _onedrive()
[[ ${COMP_WORDS[i]} == '--synchronize' ]] && options=${options/--monitor}
[[ ${COMP_WORDS[i]} == '--monitor' ]] && options=${options/--synchronize}
done
case "$prev" in
--confdir|--syncdir)
_filedir
return 0
;;
--get-file-link)
if command -v sed &> /dev/null; then
pushd "$(onedrive --display-config | sed -n "/sync_dir/s/.*= //p")" &> /dev/null
_filedir
popd &> /dev/null
fi
return 0
;;
--create-directory|--get-O365-drive-id|--operation-timeout|--remove-directory|--single-directory|--source-directory)
return 0
;;
@ -33,7 +42,7 @@ _onedrive()
return 0
;;
esac
# notreached
return 0
}

View file

@ -16,6 +16,7 @@ complete -c onedrive -l dry-run -d 'Perform a trial sync with no changes made.'
complete -c onedrive -l enable-logging -d 'Enable client activity to a separate log file.'
complete -c onedrive -l force-http-1.1 -d 'Force the use of HTTP 1.1 for all operations.'
complete -c onedrive -l force-http-2 -d 'Force the use of HTTP 2 for all operations.'
complete -c onedrive -l get-file-link -d 'Display the file link of a synced file.'
complete -c onedrive -l get-O365-drive-id -d 'Query and return the Office 365 Drive ID for a given Office 365 SharePoint Shared Library.'
complete -c onedrive -s h -l help -d 'Print help information.'
complete -c onedrive -l local-first -d 'Synchronize from the local directory source first, before downloading changes from OneDrive.'

View file

@ -21,6 +21,7 @@ all_opts=(
'--enable-logging[Enable client activity to a separate log file]'
'--force-http-1.1[Force the use of HTTP 1.1 for all operations]'
'--force-http-2[Force the use of HTTP 2 for all operations]'
'--get-file-link[Display the file link of a synced file.]:file name:'
'--get-O365-drive-id[Query and return the Office 365 Drive ID for a given Office 365 SharePoint Shared Library]:'
'--local-first[Synchronize from the local directory source first, before downloading changes from OneDrive.]'
'--logout[Logout the current user]'

View file

@ -1,9 +1,9 @@
# -*-Dockerfile-*-
ARG FEDORA_VERSION=36
ARG FEDORA_VERSION=38
ARG DEBIAN_VERSION=bullseye
ARG GO_VERSION=1.17
ARG GOSU_VERSION=1.14
ARG GO_VERSION=1.20
ARG GOSU_VERSION=1.16
FROM golang:${GO_VERSION}-${DEBIAN_VERSION} AS builder-gosu
ARG GOSU_VERSION
@ -25,6 +25,9 @@ RUN ./configure \
FROM fedora:${FEDORA_VERSION}
RUN dnf clean all \
&& dnf -y update
RUN dnf install -y libcurl sqlite ldc-libs \
&& dnf clean all \
&& mkdir -p /onedrive/conf /onedrive/data

View file

@ -1,8 +1,8 @@
# -*-Dockerfile-*-
ARG ALPINE_VERSION=3.16
ARG GO_VERSION=1.17
ARG GOSU_VERSION=1.14
ARG ALPINE_VERSION=3.18
ARG GO_VERSION=1.20
ARG GOSU_VERSION=1.16
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS builder-gosu
ARG GOSU_VERSION
@ -23,6 +23,9 @@ RUN autoreconf -fiv \
FROM alpine:${ALPINE_VERSION}
RUN apk add --upgrade apk-tools \
&& apk upgrade --available
RUN apk add --update --no-cache bash libcurl libgcc shadow sqlite-libs ldc-runtime \
&& mkdir -p /onedrive/conf /onedrive/data

View file

@ -1,10 +1,11 @@
# -*-Dockerfile-*-
ARG DEBIAN_VERSION=bullseye
ARG DEBIAN_VERSION=stable
FROM debian:${DEBIAN_VERSION} AS builder-onedrive
RUN apt-get update \
RUN apt-get clean \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends build-essential curl ca-certificates libcurl4-openssl-dev libsqlite3-dev libxml2-dev pkg-config git ldc \
&& rm -rf /var/lib/apt/lists/*
@ -18,8 +19,10 @@ RUN ./configure DC=/usr/bin/ldmd2 \
FROM debian:${DEBIAN_VERSION}-slim
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends gosu libcurl4 libsqlite3-0 ca-certificates libphobos2-ldc-shared94 \
RUN apt-get clean \
&& apt-get update \
&& apt-get upgrade -y \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends gosu libcurl4 libsqlite3-0 ca-certificates libphobos2-ldc-shared100 \
&& rm -rf /var/lib/apt/lists/* \
# Fix bug with ssl on armhf: https://serverfault.com/a/1045189
&& /usr/bin/c_rehash \

View file

@ -69,6 +69,13 @@ if [ "${ONEDRIVE_UPLOADONLY:=0}" == "1" ]; then
ARGS=(--upload-only ${ARGS[@]})
fi
# Tell client to sync in no-remote-delete mode based on environment variable
if [ "${ONEDRIVE_NOREMOTEDELETE:=0}" == "1" ]; then
echo "# We are synchronizing in no-remote-delete mode"
echo "# Adding --no-remote-delete"
ARGS=(--no-remote-delete ${ARGS[@]})
fi
# Tell client to logout based on environment variable
if [ "${ONEDRIVE_LOGOUT:=0}" == "1" ]; then
echo "# We are logging out"
@ -104,6 +111,13 @@ if [ "${ONEDRIVE_DISPLAY_CONFIG:=0}" == "1" ]; then
ARGS=(--display-running-config ${ARGS[@]})
fi
# Tell client to use sync single dir option
if [ -n "${ONEDRIVE_SINGLE_DIRECTORY:=""}" ]; then
echo "# We are synchronizing in single-directory mode"
echo "# Adding --single-directory ARG"
ARGS=(--single-directory \"${ONEDRIVE_SINGLE_DIRECTORY}\" ${ARGS[@]})
fi
if [ ${#} -gt 0 ]; then
ARGS=("${@}")
fi

View file

@ -5,8 +5,14 @@
%global with_systemd 0
%endif
%if 0%{?rhel} >= 7
%global rhel_unitdir 1
%else
%global rhel_unitdir 0
%endif
Name: onedrive
Version: 2.4.22
Version: 2.4.25
Release: 1%{?dist}
Summary: Microsoft OneDrive Client
Group: System Environment/Network
@ -15,7 +21,7 @@ URL: https://github.com/abraunegg/onedrive
Source0: v%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: dmd >= 2.087.0
BuildRequires: dmd >= 2.088.0
BuildRequires: sqlite-devel >= 3.7.15
BuildRequires: libcurl-devel
Requires: sqlite >= 3.7.15
@ -59,8 +65,13 @@ make
%{_docdir}/%{name}
%{_bindir}/%{name}
%if 0%{?with_systemd}
%if 0%{?rhel_unitdir}
%{_unitdir}/%{name}.service
%{_unitdir}/%{name}@.service
%else
%{_userunitdir}/%{name}.service
%{_unitdir}/%{name}@.service
%endif
%else
%{_bindir}/onedrive_service.sh
/etc/init.d/onedrive

View file

@ -9,7 +9,7 @@ Wants=network-online.target
# If you know what you are doing please try to enable them.
ProtectSystem=full
PrivateUsers=true
#PrivateUsers=true
#PrivateDevices=true
ProtectHostname=true
#ProtectClock=true

View file

@ -1,96 +1,159 @@
# Run the OneDrive Client for Linux under Docker
This client can be run as a Docker container, with 3 available options for you to choose from:
This client can be run as a Docker container, with 3 available container base options for you to choose from:
| Container Base | Docker Tag | Description | x86_64 | ARMHF | AARCH64 |
|----------------|-------------|----------------------------------------------------------------|:------:|:-----:|:-------:|
| Alpine Linux | edge-alpine | Docker container based on Apline 3.16 using 'master' |✔|❌|✔|
| Alpine Linux | alpine | Docker container based on Apline 3.16 using latest release |✔|❌|✔|
| Debian | debian | Docker container based on Debian Bullseye using latest release |✔|✔|✔|
| Debian | edge | Docker container based on Debian Bullseye using 'master' |✔|✔|✔|
| Debian | edge-debian | Docker container based on Debian Bullseye using 'master' |✔|✔|✔|
| Debian | latest | Docker container based on Debian Bullseye using latest release |✔|✔|✔|
| Fedora | edge-fedora | Docker container based on Fedora 36 using 'master' |✔|❌|✔|
| Fedora | fedora | Docker container based on Fedora 36 using latest release |✔|❌|✔|
| Container Base | Docker Tag | Description | i686 | x86_64 | ARMHF | AARCH64 |
|----------------|-------------|----------------------------------------------------------------|:------:|:------:|:-----:|:-------:|
| Alpine Linux | edge-alpine | Docker container based on Alpine 3.18 using 'master' |❌|✔|❌|✔|
| Alpine Linux | alpine | Docker container based on Alpine 3.18 using latest release |❌|✔|❌|✔|
| Debian | debian | Docker container based on Debian Stable using latest release |✔|✔|✔|✔|
| Debian | edge | Docker container based on Debian Stable using 'master' |✔|✔|✔|✔|
| Debian | edge-debian | Docker container based on Debian Stable using 'master' |✔|✔|✔|✔|
| Debian | latest | Docker container based on Debian Stable using latest release |✔|✔|✔|✔|
| Fedora | edge-fedora | Docker container based on Fedora 38 using 'master' |❌|✔|❌|✔|
| Fedora | fedora | Docker container based on Fedora 38 using latest release |❌|✔|❌|✔|
These containers offer a simple monitoring-mode service for the OneDrive Client for Linux.
The instructions below have been validated on:
* Red Hat Enterprise Linux 8.x
* Ubuntu Server 22.04
* Fedora 38
The instructions below will utilise the 'latest' tag, however this can be substituted for any of the other docker tags from the table above if desired.
The instructions below will utilise the 'edge' tag, however this can be substituted for any of the other docker tags such as 'latest' from the table above if desired.
The 'edge' Docker Container will align closer to all documentation and features, where as 'latest' is the release version from a static point in time. The 'latest' tag however may contain bugs and/or issues that will have been fixed, and those fixes are contained in 'edge'.
Additionally there are specific version release tags for each release. Refer to https://hub.docker.com/r/driveone/onedrive/tags for any other Docker tags you may be interested in.
## Basic Setup
### 0. Install docker using your distribution platform's instructions
1. Ensure that SELinux has been disabled on your system. A reboot may be required to ensure that this is correctly disabled.
2. Install Docker as per requried for your platform. Refer to https://docs.docker.com/engine/install/ for assistance.
3. Obtain your normal, non-root user UID and GID by using the `id` command
4. As your normal, non-root user, ensure that you can run `docker run hello-world` *without* using `sudo`
**Note:** The below instructions for docker has been tested and validated when logging into the system as an unprivileged user (non 'root' user).
Once the above 4 steps are complete and you can successfully run `docker run hello-world` without sudo, only then proceed to 'Pulling and Running the Docker Image'
## High Level Configuration Steps
1. Install 'docker' as per your distribution platform's instructions if not already installed.
2. Configure 'docker' to allow non-privileged users to run Docker commands
3. Disable 'SELinux' as per your distribution platform's instructions
4. Test 'docker' by running a test container without using `sudo`
5. Prepare the required docker volumes to store the configuration and data
6. Run the 'onedrive' container and perform authorisation
7. Running the 'onedrive' container under 'docker'
## Pulling and Running the Docker Image
### 1. Pull the image
```bash
docker pull driveone/onedrive:latest
## Configuration Steps
### 1. Install 'docker' on your platform
Install 'docker' as per your distribution platform's instructions if not already installed.
### 2. Configure 'docker' to allow non-privileged users to run Docker commands
Read https://docs.docker.com/engine/install/linux-postinstall/ to configure the 'docker' user group with your user account to allow your non 'root' user to run 'docker' commands.
### 3. Disable SELinux on your platform
In order to run the Docker container, SELinux must be disabled. Without doing this, when the application is authenticated in the steps below, the following error will be presented:
```text
ERROR: The local file system returned an error with the following message:
Error Message: /onedrive/conf/refresh_token: Permission denied
The database cannot be opened. Please check the permissions of ~/.config/onedrive/items.sqlite3
```
The only known work-around for the above problem at present is to disable SELinux. Please refer to your distribution platform's instructions on how to perform this step.
* Fedora: https://docs.fedoraproject.org/en-US/quick-docs/selinux-changing-states-and-modes/#_disabling_selinux
* Red Hat Enterprise Linux: https://access.redhat.com/solutions/3176
Post disabling SELinux and reboot your system, confirm that `getenforce` returns `Disabled`:
```text
$ getenforce
Disabled
```
**NOTE:** SELinux context needs to be configured or disabled for Docker to be able to write to OneDrive host directory.
If you are still experiencing permission issues despite disabling SELinux, please read https://www.redhat.com/sysadmin/container-permission-denied-errors
### 2. Prepare config volume
The Docker container requries 2 Docker volumes:
### 4. Test 'docker' on your platform
Ensure that 'docker' is running as a system service, and is enabled to be activated on system reboot:
```bash
sudo systemctl enable --now docker
```
Test that 'docker' is operational for your 'non-root' user, as per below:
```bash
[alex@fedora-38-docker-host ~]$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete
Digest: sha256:88ec0acaa3ec199d3b7eaf73588f4518c25f9d34f58ce9a0df68429c5af48e8d
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
[alex@fedora-38-docker-host ~]$
```
### 5. Configure the required docker volumes
The 'onedrive' Docker container requires 2 docker volumes to operate:
* Config Volume
* Data Volume
Create the config volume with the following command:
The first volume is the configuration volume that stores all the applicable application configuration + current runtime state. In a non-containerised environment, this normally resides in `~/.config/onedrive` - in a containerised environment this is stored in the volume tagged as `/onedrive/conf`
The second volume is the data volume, where all your data from Microsoft OneDrive is stored locally. This volume is mapped to an actual directory point on your local filesystem and this is stored in the volume tagged as `/onedrive/data`
#### 5.1 Prepare the 'config' volume
Create the 'config' volume with the following command:
```bash
docker volume create onedrive_conf
```
This will create a docker volume labeled `onedrive_conf`, where all configuration of your onedrive account will be stored. You can add a custom config file and other things later.
This will create a docker volume labeled `onedrive_conf`, where all configuration of your onedrive account will be stored. You can add a custom config file in this location at a later point in time if required.
The second docker volume is for your data folder and is created in the next step. This volume needs to be a path to a directory on your local filesystem, and this is where your data will be stored from OneDrive. Keep in mind that:
#### 5.2 Prepare the 'data' volume
Create the 'data' volume with the following command:
```bash
docker volume create onedrive_data
```
This will create a docker volume labeled `onedrive_data` and will map to a path on your local filesystem. This is where your data from Microsoft OneDrive will be stored. Keep in mind that:
* The owner of this specified folder must not be root
* The owner of this specified folder must have permissions for its parent directory
* Docker will attempt to change the permissions of the volume to the user the container is configured to run as
**NOTE:** Issues occur when this target folder is a mounted folder of an external system (NAS, SMB mount, USB Drive etc) as the 'mount' itself is owned by 'root'. If this is your use case, you *must* ensure your normal user can mount your desired target without having the target mounted by 'root'. If you do not fix this, your Docker container will fail to start with the following error message:
**NOTE:** Issues occur when this target folder is a mounted folder of an external system (NAS, SMB mount, USB Drive etc) as the 'mount' itself is owed by 'root'. If this is your use case, you *must* ensure your normal user can mount your desired target without having the target mounted by 'root'. If you do not fix this, your Docker container will fail to start with the following error message:
```bash
ROOT level privileges prohibited!
```
### 3. First run
The 'onedrive' client within the Docker container needs to be authorized with your Microsoft account. This is achieved by initially running docker in interactive mode.
### 6. First run of Docker container under docker and performing authorisation
The 'onedrive' client within the container first needs to be authorised with your Microsoft account. This is achieved by initially running docker in interactive mode.
Run the docker image with the commands below and make sure to change `ONEDRIVE_DATA_DIR` to the actual onedrive data directory on your filesystem that you wish to use (e.g. `"/home/abraunegg/OneDrive"`).
Run the docker image with the commands below and make sure to change the value of `ONEDRIVE_DATA_DIR` to the actual onedrive data directory on your filesystem that you wish to use (e.g. `export ONEDRIVE_DATA_DIR="/home/abraunegg/OneDrive"`).
**Important:** The 'target' folder of `ONEDRIVE_DATA_DIR` must exist before running the docker container. The script below will create 'ONEDRIVE_DATA_DIR' so that it exists locally for the docker volume mapping to occur.
It is also a requirement that the container be run using a non-root uid and gid, you must insert a non-root UID and GID (e.g.` export ONEDRIVE_UID=1000` and export `ONEDRIVE_GID=1000`). The script below will use `id` to evaluate your system environment to use the correct values.
```bash
export ONEDRIVE_DATA_DIR="${HOME}/OneDrive"
mkdir -p ${ONEDRIVE_DATA_DIR}
docker run -it --name onedrive -v onedrive_conf:/onedrive/conf \
-v "${ONEDRIVE_DATA_DIR}:/onedrive/data" \
-e "ONEDRIVE_UID=${ONEDRIVE_UID}" \
-e "ONEDRIVE_GID=${ONEDRIVE_GID}" \
driveone/onedrive:latest
```
**Important:** The 'target' folder of `ONEDRIVE_DATA_DIR` must exist before running the Docker container, otherwise, Docker will create the target folder, and the folder will be given 'root' permissions, which then causes the Docker container to fail upon startup with the following error message:
```bash
ROOT level privileges prohibited!
```
**NOTE:** It is also highly advisable for you to replace `${ONEDRIVE_UID}` and `${ONEDRIVE_GID}` with your actual UID and GID as specified by your `id` command output to avoid any any potential user or group conflicts.
**Example:**
```bash
export ONEDRIVE_UID=`id -u`
export ONEDRIVE_GID=`id -g`
export ONEDRIVE_DATA_DIR="${HOME}/OneDrive"
mkdir -p ${ONEDRIVE_DATA_DIR}
docker run -it --name onedrive -v onedrive_conf:/onedrive/conf \
-v "${ONEDRIVE_DATA_DIR}:/onedrive/data" \
-e "ONEDRIVE_UID=${ONEDRIVE_UID}" \
-e "ONEDRIVE_GID=${ONEDRIVE_GID}" \
driveone/onedrive:latest
driveone/onedrive:edge
```
When the Docker container successfully starts:
@ -103,48 +166,47 @@ Once the 'onedrive' application is authorised, the client will automatically sta
If the client is working as expected, you can detach from the container with Ctrl+p, Ctrl+q.
### 4. Docker Container Status, stop, and restart
Check if the monitor service is running
### 7. Running the 'onedrive' container under 'docker'
#### 7.1 Check if the monitor service is running
```bash
docker ps -f name=onedrive
```
Show monitor run logs
#### 7.2 Show 'onedrive' runtime logs
```bash
docker logs onedrive
```
Stop running monitor
#### 7.3 Stop running 'onedrive' container
```bash
docker stop onedrive
```
Resume monitor
#### 7.4 Start 'onedrive' container
```bash
docker start onedrive
```
Remove onedrive Docker container
#### 7.5 Remove 'onedrive' container
```bash
docker rm -f onedrive
```
## Advanced Setup
### 5. Docker-compose
Also supports docker-compose schemas > 3.
In the following example it is assumed you have a `ONEDRIVE_DATA_DIR` environment variable and a `onedrive_conf` volume.
However, you can also use bind mounts for the configuration folder, e.g. `export ONEDRIVE_CONF="${HOME}/OneDriveConfig"`.
## Advanced Usage
### How to use Docker-compose
You can utilise `docker-compose` if available on your platform if you are able to use docker compose schemas > 3.
In the following example it is assumed you have a `ONEDRIVE_DATA_DIR` environment variable and have already created the `onedrive_conf` volume.
You can also use docker bind mounts for the configuration folder, e.g. `export ONEDRIVE_CONF="${HOME}/OneDriveConfig"`.
```
version: "3"
services:
onedrive:
image: driveone/onedrive:latest
image: driveone/onedrive:edge
restart: unless-stopped
environment:
- ONEDRIVE_UID=${PUID}
@ -156,7 +218,7 @@ services:
Note that you still have to perform step 3: First Run.
### 6. Edit the config
### Editing the running configuration and using a 'config' file
The 'onedrive' client should run in default configuration, however you can change this default configuration by placing a custom config file in the `onedrive_conf` docker volume. First download the default config from [here](https://raw.githubusercontent.com/abraunegg/onedrive/master/config)
Then put it into your onedrive_conf volume path, which can be found with:
@ -168,17 +230,17 @@ Or you can map your own config folder to the config volume. Make sure to copy al
The detailed document for the config can be found here: [Configuration](https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md#configuration)
### 7. Sync multiple accounts
There are many ways to do this, the easiest is probably to
### Syncing multiple accounts
There are many ways to do this, the easiest is probably to do the following:
1. Create a second docker config volume (replace `Work` with your desired name): `docker volume create onedrive_conf_Work`
2. And start a second docker monitor container (again replace `Work` with your desired name):
```
export ONEDRIVE_DATA_DIR_WORK="/home/abraunegg/OneDriveWork"
mkdir -p ${ONEDRIVE_DATA_DIR_WORK}
docker run -it --restart unless-stopped --name onedrive_Work -v onedrive_conf_Work:/onedrive/conf -v "${ONEDRIVE_DATA_DIR_WORK}:/onedrive/data" driveone/onedrive:latest
docker run -it --restart unless-stopped --name onedrive_Work -v onedrive_conf_Work:/onedrive/conf -v "${ONEDRIVE_DATA_DIR_WORK}:/onedrive/data" driveone/onedrive:edge
```
## Run or update with one script
### Run or update the Docker container with one script
If you are experienced with docker and onedrive, you can use the following script:
```bash
@ -188,16 +250,15 @@ ONEDRIVE_DATA_DIR="${HOME}/OneDrive"
mkdir -p ${ONEDRIVE_DATA_DIR}
firstRun='-d'
docker pull driveone/onedrive:latest
docker pull driveone/onedrive:edge
docker inspect onedrive_conf > /dev/null 2>&1 || { docker volume create onedrive_conf; firstRun='-it'; }
docker inspect onedrive > /dev/null 2>&1 && docker rm -f onedrive
docker run $firstRun --restart unless-stopped --name onedrive -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:latest
docker run $firstRun --restart unless-stopped --name onedrive -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:edge
```
## Environment Variables
| Variable | Purpose | Sample Value |
| ---------------- | --------------------------------------------------- |:-------------:|
## Supported Docker Environment Variables
| Variable | Purpose | Sample Value |
| ---------------- | --------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------:|
| <B>ONEDRIVE_UID</B> | UserID (UID) to run as | 1000 |
| <B>ONEDRIVE_GID</B> | GroupID (GID) to run as | 1000 |
| <B>ONEDRIVE_VERBOSE</B> | Controls "--verbose" switch on onedrive sync. Default is 0 | 1 |
@ -206,41 +267,55 @@ docker run $firstRun --restart unless-stopped --name onedrive -v onedrive_conf:/
| <B>ONEDRIVE_RESYNC</B> | Controls "--resync" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_DOWNLOADONLY</B> | Controls "--download-only" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_UPLOADONLY</B> | Controls "--upload-only" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_NOREMOTEDELETE</B> | Controls "--no-remote-delete" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_LOGOUT</B> | Controls "--logout" switch. Default is 0 | 1 |
| <B>ONEDRIVE_REAUTH</B> | Controls "--reauth" switch. Default is 0 | 1 |
| <B>ONEDRIVE_AUTHFILES</B> | Controls "--auth-files" option. Default is "" | "authUrl:responseUrl" |
| <B>ONEDRIVE_AUTHRESPONSE</B> | Controls "--auth-response" option. Default is "" | See [here](https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md#authorize-the-application-with-your-onedrive-account) |
| <B>ONEDRIVE_DISPLAY_CONFIG</B> | Controls "--display-running-config" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_SINGLE_DIRECTORY</B> | Controls "--single-directory" option. Default = "" | "mydir" |
### Usage Examples
### Environment Variables Usage Examples
**Verbose Output:**
```bash
docker container run -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:latest
docker container run -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:edge
```
**Debug Output:**
```bash
docker container run -e ONEDRIVE_DEBUG=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:latest
docker container run -e ONEDRIVE_DEBUG=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:edge
```
**Perform a --resync:**
```bash
docker container run -e ONEDRIVE_RESYNC=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:latest
docker container run -e ONEDRIVE_RESYNC=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:edge
```
**Perform a --resync and --verbose:**
```bash
docker container run -e ONEDRIVE_RESYNC=1 -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:latest
docker container run -e ONEDRIVE_RESYNC=1 -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:edge
```
**Perform a --logout and re-authenticate:**
```bash
docker container run -it -e ONEDRIVE_LOGOUT=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:latest
docker container run -it -e ONEDRIVE_LOGOUT=1 -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" driveone/onedrive:edge
```
## Build instructions
## Building a custom Docker image
### Build Environment Requirements
* Build environment must have at least 1GB of memory & 2GB swap space
There are 2 ways to validate this requirement:
* Modify the file `/etc/dphys-swapfile` and edit the `CONF_SWAPSIZE`, for example: `CONF_SWAPSIZE=2048`. A reboot is required to make this change effective.
* Dynamically allocate a swapfile for building:
You can validate your build environment memory status with the following command:
```text
cat /proc/meminfo | grep -E 'MemFree|Swap'
```
This should result in the following similar output:
```text
MemFree: 3704644 kB
SwapCached: 0 kB
SwapTotal: 8117244 kB
SwapFree: 8117244 kB
```
If you do not have enough swap space, you can use the following script to dynamically allocate a swapfile for building the Docker container:
```bash
cd /var
sudo fallocate -l 1.5G swapfile
@ -255,31 +330,36 @@ swapon -s
free -h
```
### Building a custom Docker image
If you are running a Raspberry Pi, you will need to edit your system configuration to increase your swapfile:
* Modify the file `/etc/dphys-swapfile` and edit the `CONF_SWAPSIZE`, for example: `CONF_SWAPSIZE=2048`.
A reboot of your Raspberry Pi is required to make this change effective.
### Building and running a custom Docker image
You can also build your own image instead of pulling the one from [hub.docker.com](https://hub.docker.com/r/driveone/onedrive):
```bash
git clone https://github.com/abraunegg/onedrive
cd onedrive
docker build . -t local-onedrive -f contrib/docker/Dockerfile
docker container run -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" local-onedrive:latest
```
There are alternate, smaller images available by building
Dockerfile-debian or Dockerfile-alpine. These [multi-stage builder pattern](https://docs.docker.com/develop/develop-images/multistage-build/)
Dockerfiles require Docker version at least 17.05.
There are alternate, smaller images available by using `Dockerfile-debian` or `Dockerfile-alpine`. These [multi-stage builder pattern](https://docs.docker.com/develop/develop-images/multistage-build/) Dockerfiles require Docker version at least 17.05.
#### How to build and run a custom Docker image based on Debian
### How to build and run a custom Docker image based on Debian
``` bash
docker build . -t local-ondrive-debian -f contrib/docker/Dockerfile-debian
docker container run -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" local-ondrive-debian:latest
```
#### How to build and run a custom Docker image based on Alpine Linux
### How to build and run a custom Docker image based on Alpine Linux
``` bash
docker build . -t local-ondrive-alpine -f contrib/docker/Dockerfile-alpine
docker container run -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" local-ondrive-alpine:latest
```
#### How to build and run a custom Docker image for ARMHF (Raspberry Pi)
### How to build and run a custom Docker image for ARMHF (Raspberry Pi)
Compatible with:
* Raspberry Pi
* Raspberry Pi 2
@ -291,8 +371,26 @@ docker build . -t local-onedrive-armhf -f contrib/docker/Dockerfile-debian
docker container run -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" local-onedrive-armhf:latest
```
#### How to build and run a custom Docker image for AARCH64 Platforms
### How to build and run a custom Docker image for AARCH64 Platforms
``` bash
docker build . -t local-onedrive-aarch64 -f contrib/docker/Dockerfile-debian
docker container run -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" local-onedrive-aarch64:latest
```
### How to support double-byte languages
In some geographic regions, you may need to change and/or update the locale specification of the Docker container to better support the local language used for your local filesystem. To do this, follow the example below:
```
FROM driveone/onedrive
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y locales
RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen ja_JP.UTF-8 && \
dpkg-reconfigure locales && \
/usr/sbin/update-locale LANG=ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
```
The above example changes the Docker container to support Japanese. To support your local language, change `ja_JP.UTF-8` to the required entry.

View file

@ -12,19 +12,22 @@ Distribution packages may be of an older release when compared to the latest rel
|---------------------------------|------------------------------------------------------------------------------|:---------------:|:----:|:------:|:-----:|:-------:|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Alpine Linux | [onedrive](https://pkgs.alpinelinux.org/packages?name=onedrive&branch=edge) |<a href="https://pkgs.alpinelinux.org/packages?name=onedrive&branch=edge"><img src="https://repology.org/badge/version-for-repo/alpine_edge/onedrive.svg?header=" alt="Alpine Linux Edge package" width="46" height="20"></a>|❌|✔|❌|✔ | |
| Arch Linux<br><br>Manjaro Linux | [onedrive-abraunegg](https://aur.archlinux.org/packages/onedrive-abraunegg/) |<a href="https://aur.archlinux.org/packages/onedrive-abraunegg"><img src="https://repology.org/badge/version-for-repo/aur/onedrive-abraunegg.svg?header=" alt="AUR package" width="46" height="20"></a>|✔|✔|✔|✔ | Install via: `pamac build onedrive-abraunegg` from the Arch Linux User Repository (AUR)<br><br>**Note:** If asked regarding a provider for 'd-runtime' and 'd-compiler', select 'liblphobos' and 'ldc'<br><br>**Note:** System must have at least 1GB of memory & 1GB swap space
| Debian | [onedrive](https://packages.debian.org/search?keywords=onedrive) |<a href="https://packages.debian.org/search?keywords=onedrive"><img src="https://repology.org/badge/version-for-repo/debian_11/onedrive.svg?header=" alt="Debian package" width="46" height="20"></a>|✔|✔|✔|✔| **Note:** Do not install from Debian Package Repositories<br><br>It is recommended that for Debian that you install from OpenSuSE Build Service using the Debian Package Install [Instructions](ubuntu-package-install.md) |
| Debian 11 | [onedrive](https://packages.debian.org/bullseye/source/onedrive) |<a href="https://packages.debian.org/bullseye/source/onedrive"><img src="https://repology.org/badge/version-for-repo/debian_11/onedrive.svg?header=" alt="Debian 11 package" width="46" height="20"></a>|✔|✔|✔|✔| **Note:** Do not install from Debian Package Repositories<br><br>It is recommended that for Debian 11 that you install from OpenSuSE Build Service using the Debian Package Install [Instructions](ubuntu-package-install.md) |
| Debian 12 | [onedrive](https://packages.debian.org/bookworm/source/onedrive) |<a href="https://packages.debian.org/bookworm/source/onedrive"><img src="https://repology.org/badge/version-for-repo/debian_12/onedrive.svg?header=" alt="Debian 12 package" width="46" height="20"></a>|✔|✔|✔|✔| **Note:** Do not install from Debian Package Repositories<br><br>It is recommended that for Debian 12 that you install from OpenSuSE Build Service using the Debian Package Install [Instructions](ubuntu-package-install.md) |
| Fedora | [onedrive](https://koji.fedoraproject.org/koji/packageinfo?packageID=26044) |<a href="https://koji.fedoraproject.org/koji/packageinfo?packageID=26044"><img src="https://repology.org/badge/version-for-repo/fedora_rawhide/onedrive.svg?header=" alt="Fedora Rawhide package" width="46" height="20"></a>|✔|✔|✔|✔| |
| Gentoo | [onedrive](https://gpo.zugaina.org/net-misc/onedrive) | No API Available |✔|✔|❌|❌| |
| Homebrew | [onedrive](https://formulae.brew.sh/formula/onedrive) | <a href="https://formulae.brew.sh/formula/onedrive"><img src="https://repology.org/badge/version-for-repo/homebrew/onedrive.svg?header=" alt="Homebrew package" width="46" height="20"></a> |❌|✔|❌|❌| |
| Linux Mint 20.x | [onedrive](https://community.linuxmint.com/software/view/onedrive) |<a href="https://community.linuxmint.com/software/view/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_20_04/onedrive.svg?header=" alt="Ubuntu 20.04 package" width="46" height="20"></a> |❌|✔|✔|✔| **Note:** Do not install from Linux Mint Repositories<br><br>It is recommended that for Linux Mint that you install from OpenSuSE Build Service using the Ubuntu Package Install [Instructions](ubuntu-package-install.md) |
| Linux Mint 21.x | [onedrive](https://community.linuxmint.com/software/view/onedrive) |<a href="https://community.linuxmint.com/software/view/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_22_04/onedrive.svg?header=" alt="Ubuntu 22.04 package" width="46" height="20"></a> |❌|✔|✔|✔| **Note:** Do not install from Linux Mint Repositories<br><br>It is recommended that for Linux Mint that you install from OpenSuSE Build Service using the Ubuntu Package Install [Instructions](ubuntu-package-install.md) |
| NixOS | [onedrive](https://search.nixos.org/packages?channel=20.09&from=0&size=50&sort=relevance&query=onedrive)|<a href="https://search.nixos.org/packages?channel=20.09&from=0&size=50&sort=relevance&query=onedrive"><img src="https://repology.org/badge/version-for-repo/nix_unstable/onedrive.svg?header=" alt="nixpkgs unstable package" width="46" height="20"></a>|❌|✔|❌|❌| Use package `onedrive` either by adding it to `configuration.nix` or by using the command `nix-env -iA <channel name>.onedrive`. This does not install a service. To install a service, use unstable channel (will stabilize in 20.09) and add `services.onedrive.enable=true` in `configuration.nix`. You can also add a custom package using the `services.onedrive.package` option (recommended since package lags upstream). Enabling the service installs a default package too (based on the channel). You can also add multiple onedrive accounts trivially, see [documentation](https://github.com/NixOS/nixpkgs/pull/77734#issuecomment-575874225). |
| OpenSuSE | [onedrive](https://software.opensuse.org/package/onedrive) |<a href="https://software.opensuse.org/package/onedrive"><img src="https://repology.org/badge/version-for-repo/opensuse_tumbleweed/onedrive.svg?header=" alt="openSUSE Tumbleweed package" width="46" height="20"></a>|✔|✔|❌|❌| |
| OpenSuSE | [onedrive](https://software.opensuse.org/package/onedrive) |<a href="https://software.opensuse.org/package/onedrive"><img src="https://repology.org/badge/version-for-repo/opensuse_network_tumbleweed/onedrive.svg?header=" alt="openSUSE Tumbleweed package" width="46" height="20"></a>|✔|✔|❌|❌| |
| OpenSuSE Build Service | [onedrive](https://build.opensuse.org/package/show/home:npreining:debian-ubuntu-onedrive/onedrive) | No API Available |✔|✔|✔|✔| Package Build Service for Debian and Ubuntu |
| Raspbian | [onedrive](https://archive.raspbian.org/raspbian/pool/main/o/onedrive/) |<a href="https://archive.raspbian.org/raspbian/pool/main/o/onedrive/"><img src="https://repology.org/badge/version-for-repo/raspbian_stable/onedrive.svg?header=" alt="Raspbian Stable package" width="46" height="20"></a> |❌|❌|✔|✔| **Note:** Do not install from Raspbian Package Repositories<br><br>It is recommended that for Raspbian that you install from OpenSuSE Build Service using the Debian Package Install [Instructions](ubuntu-package-install.md) |
| Slackware | [onedrive](https://slackbuilds.org/result/?search=onedrive&sv=) |<a href="https://slackbuilds.org/result/?search=onedrive&sv="><img src="https://repology.org/badge/version-for-repo/slackbuilds/onedrive.svg?header=" alt="SlackBuilds package" width="46" height="20"></a>|✔|✔|❌|❌| |
| Solus | [onedrive](https://dev.getsol.us/search/query/FB7PIf1jG9Z9/#R) |<a href="https://dev.getsol.us/search/query/FB7PIf1jG9Z9/#R"><img src="https://repology.org/badge/version-for-repo/solus/onedrive.svg?header=" alt="Solus package" width="46" height="20"></a>|✔|✔|❌|❌| |
| Ubuntu 18.04 | [onedrive](https://packages.ubuntu.com/bionic/onedrive) |<a href="https://packages.ubuntu.com/bionic/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_18_04/onedrive.svg?header=" alt="Ubuntu 18.04 package" width="88" height="20"></a> |✔|✔|✔|❌| **Note:** Do not install from Ubuntu Universe<br><br>You must compile from source for this version of Ubuntu |
| Ubuntu 20.04 | [onedrive](https://packages.ubuntu.com/focal/onedrive) |<a href="https://packages.ubuntu.com/focal/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_20_04/onedrive.svg?header=" alt="Ubuntu 20.04 package" width="46" height="20"></a> |❌|✔|✔|✔| **Note:** Do not install from Ubuntu Universe<br><br>It is recommended that for Ubuntu that you install from OpenSuSE Build Service using the Ubuntu Package Install [Instructions](ubuntu-package-install.md) |
| Ubuntu 22.04 | [onedrive](https://packages.ubuntu.com/jammy/onedrive) |<a href="https://packages.ubuntu.com/jammy/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_22_04/onedrive.svg?header=" alt="Ubuntu 22.04 package" width="46" height="20"></a> |❌|✔|✔|✔| **Note:** Do not install from Ubuntu Universe<br><br>It is recommended that for Ubuntu that you install from OpenSuSE Build Service using the Ubuntu Package Install [Instructions](ubuntu-package-install.md) |
| Ubuntu 23.04 | [onedrive](https://packages.ubuntu.com/lunar/onedrive) |<a href="https://packages.ubuntu.com/lunar/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_23_04/onedrive.svg?header=" alt="Ubuntu 23.04 package" width="46" height="20"></a> |❌|✔|✔|✔| **Note:** Do not install from Ubuntu Universe<br><br>It is recommended that for Ubuntu that you install from OpenSuSE Build Service using the Ubuntu Package Install [Instructions](ubuntu-package-install.md) |
| Void Linux | [onedrive](https://voidlinux.org/packages/?arch=x86_64&q=onedrive) |<a href="https://voidlinux.org/packages/?arch=x86_64&q=onedrive"><img src="https://repology.org/badge/version-for-repo/void_x86_64/onedrive.svg?header=" alt="Void Linux x86_64 package" width="46" height="20"></a>|✔|✔|❌|❌| |
#### Important information for all Ubuntu and Ubuntu based distribution users:
@ -60,57 +63,15 @@ curl -fsS https://dlang.org/install.sh | bash -s ldc
## Distribution Package Dependencies
### Dependencies: Ubuntu 16.x
Ubuntu Linux 16.04 LTS reached the end of its five-year LTS window on April 30th 2021 and is no longer supported.
Ubuntu Linux 16.x LTS reached the end of its five-year LTS window on April 30th 2021 and is no longer supported.
### Dependencies: Ubuntu 18.x / Lubuntu 18.x / Debian 9 - i386 / i686
These dependencies are also applicable for all Ubuntu based distributions such as:
* Lubuntu
* Linux Mint
* POP OS
* Peppermint OS
### Dependencies: Ubuntu 18.x / Lubuntu 18.x
Ubuntu Linux 18.x LTS reached the end of its five-year LTS window on May 31th 2023 and is no longer supported.
**Important:** The DMD compiler cannot be used in its default configuration on Ubuntu 18.x / Lubuntu 18.x / Debian 9 i386 / i686 architectures due to an issue in the Ubuntu / Debian linking process. See [https://issues.dlang.org/show_bug.cgi?id=19116](https://issues.dlang.org/show_bug.cgi?id=19116) for further details.
### Dependencies: Debian 9
Debian 9 reached the end of its five-year support window on June 30th 2022 and is no longer supported.
**Note:** Ubuntu 18.x validated with the DMD compiler on the following Ubuntu i386 / i686 platform:
```text
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
```
**Note:** Lubuntu 18.x validated with the DMD compiler on the following Lubuntu i386 / i686 platform:
```text
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.10
DISTRIB_CODENAME=cosmic
DISTRIB_DESCRIPTION="Ubuntu 18.10"
```
**Note:** Debian 9 validated with the DMD compiler on the following Debian i386 / i686 platform:
```text
cat /etc/debian_version
9.11
```
First install development dependencies as per below:
```text
sudo apt install build-essential
sudo apt install libcurl4-openssl-dev libsqlite3-dev pkg-config git curl
```
For notifications the following is also necessary:
```text
sudo apt install libnotify-dev
```
Second, install the DMD compiler as per below:
```text
curl -fsS https://dlang.org/install.sh | bash -s dmd
```
Thirdly, reconfigure the default linker as per below:
```text
sudo update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.gold" 20
sudo update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.bfd" 10
```
### Dependencies: Ubuntu 18.x -> Ubuntu 22.x / Debian 9 -> Debian 11 - x86_64
### Dependencies: Ubuntu 20.x -> Ubuntu 23.x / Debian 10 -> Debian 12 - x86_64
These dependencies are also applicable for all Ubuntu based distributions such as:
* Lubuntu
* Linux Mint
@ -160,7 +121,7 @@ For notifications the following is also necessary:
sudo pacman -S libnotify
```
### Dependencies: Raspbian (ARMHF) and Ubuntu 22.x / Debian 11 / Raspbian (ARM64)
### Dependencies: Raspbian (ARMHF) and Ubuntu 22.x / Debian 11 / Debian 12 / Raspbian (ARM64)
**Note:** The minimum LDC compiler version required to compile this application is now 1.18.0, which is not available for Debian Buster or distributions based on Debian Buster. You are advised to first upgrade your platform distribution to one that is based on Debian Bullseye (Debian 11) or later.
These instructions were validated using:

View file

@ -1,32 +1,104 @@
# Run the OneDrive Client for Linux under Podman
This client can be run as a Podman container, with 3 available options for you to choose from:
1. Container based on Fedora 36 - Docker Tag: latest
2. Container based on Debian 11 - Docker Tag: debian
3. Container based on Alpine Linux - Docker Tag: alpine
This client can be run as a Podman container, with 3 available container base options for you to choose from:
| Container Base | Docker Tag | Description | i686 | x86_64 | ARMHF | AARCH64 |
|----------------|-------------|----------------------------------------------------------------|:------:|:------:|:-----:|:-------:|
| Alpine Linux | edge-alpine | Podman container based on Alpine 3.18 using 'master' |❌|✔|❌|✔|
| Alpine Linux | alpine | Podman container based on Alpine 3.18 using latest release |❌|✔|❌|✔|
| Debian | debian | Podman container based on Debian Stable using latest release |✔|✔|✔|✔|
| Debian | edge | Podman container based on Debian Stable using 'master' |✔|✔|✔|✔|
| Debian | edge-debian | Podman container based on Debian Stable using 'master' |✔|✔|✔|✔|
| Debian | latest | Podman container based on Debian Stable using latest release |✔|✔|✔|✔|
| Fedora | edge-fedora | Podman container based on Fedora 38 using 'master' |❌|✔|❌|✔|
| Fedora | fedora | Podman container based on Fedora 38 using latest release |❌|✔|❌|✔|
These containers offer a simple monitoring-mode service for the OneDrive Client for Linux.
The instructions below have been validated on:
* Fedora 35
* Fedora 38
The instructions below will utilise the 'latest' tag, however this can be substituted for 'debian' or 'alpine' if desired. The below instructions for podman have only been tested as the root user while running the containers themselves as non-root users.
The instructions below will utilise the 'edge' tag, however this can be substituted for any of the other docker tags such as 'latest' from the table above if desired.
**Note:** If you are using Debian or Ubuntu platforms, it is recommended you use the 'debian' Docker tag rather than 'latest' to ensure maximum compatability with your Debian or Ubuntu ecosystem.
The 'edge' Docker Container will align closer to all documentation and features, where as 'latest' is the release version from a static point in time. The 'latest' tag however may contain bugs and/or issues that will have been fixed, and those fixes are contained in 'edge'.
## Basic Setup
### 0. Install podman using your distribution platform's instructions if not already installed
1. Ensure that SELinux has been disabled on your system. A reboot may be required to ensure that this is correctly disabled.
2. Install Podman as per requried for your platform
3. Obtain your normal, non-root user UID and GID by using the `id` command or select another non-root id to run the container as
Additionally there are specific version release tags for each release. Refer to https://hub.docker.com/r/driveone/onedrive/tags for any other Docker tags you may be interested in.
**NOTE:** SELinux context needs to be configured or disabled for Podman to be able to write to OneDrive host directory.
**Note:** The below instructions for podman has been tested and validated when logging into the system as an unprivileged user (non 'root' user).
### 1.1 Prepare data volume
The container requries 2 Podman volumes:
## High Level Configuration Steps
1. Install 'podman' as per your distribution platform's instructions if not already installed.
2. Disable 'SELinux' as per your distribution platform's instructions
3. Test 'podman' by running a test container
4. Prepare the required podman volumes to store the configuration and data
5. Run the 'onedrive' container and perform authorisation
6. Running the 'onedrive' container under 'podman'
## Configuration Steps
### 1. Install 'podman' on your platform
Install 'podman' as per your distribution platform's instructions if not already installed.
### 2. Disable SELinux on your platform
In order to run the Docker container under 'podman', SELinux must be disabled. Without doing this, when the application is authenticated in the steps below, the following error will be presented:
```text
ERROR: The local file system returned an error with the following message:
Error Message: /onedrive/conf/refresh_token: Permission denied
The database cannot be opened. Please check the permissions of ~/.config/onedrive/items.sqlite3
```
The only known work-around for the above problem at present is to disable SELinux. Please refer to your distribution platform's instructions on how to perform this step.
* Fedora: https://docs.fedoraproject.org/en-US/quick-docs/selinux-changing-states-and-modes/#_disabling_selinux
* Red Hat Enterprise Linux: https://access.redhat.com/solutions/3176
Post disabling SELinux and reboot your system, confirm that `getenforce` returns `Disabled`:
```text
$ getenforce
Disabled
```
If you are still experiencing permission issues despite disabling SELinux, please read https://www.redhat.com/sysadmin/container-permission-denied-errors
### 3. Test 'podman' on your platform
Test that 'podman' is operational for your 'non-root' user, as per below:
```bash
[alex@fedora38-podman ~]$ podman pull fedora
Resolved "fedora" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull registry.fedoraproject.org/fedora:latest...
Getting image source signatures
Copying blob b30887322388 done |
Copying config a1cd3cbf8a done |
Writing manifest to image destination
a1cd3cbf8adaa422629f2fcdc629fd9297138910a467b11c66e5ddb2c2753dff
[alex@fedora38-podman ~]$ podman run fedora /bin/echo "Welcome to the Podman World"
Welcome to the Podman World
[alex@fedora38-podman ~]$
```
### 4. Configure the required podman volumes
The 'onedrive' Docker container requires 2 podman volumes to operate:
* Config Volume
* Data Volume
The first volume is for your data folder and is created in the next step. This volume needs to be a path to a directory on your local filesystem, and this is where your data will be stored from OneDrive. Keep in mind that:
The first volume is the configuration volume that stores all the applicable application configuration + current runtime state. In a non-containerised environment, this normally resides in `~/.config/onedrive` - in a containerised environment this is stored in the volume tagged as `/onedrive/conf`
The second volume is the data volume, where all your data from Microsoft OneDrive is stored locally. This volume is mapped to an actual directory point on your local filesystem and this is stored in the volume tagged as `/onedrive/data`
#### 4.1 Prepare the 'config' volume
Create the 'config' volume with the following command:
```bash
podman volume create onedrive_conf
```
This will create a podman volume labeled `onedrive_conf`, where all configuration of your onedrive account will be stored. You can add a custom config file in this location at a later point in time if required.
#### 4.2 Prepare the 'data' volume
Create the 'data' volume with the following command:
```bash
podman volume create onedrive_data
```
This will create a podman volume labeled `onedrive_data` and will map to a path on your local filesystem. This is where your data from Microsoft OneDrive will be stored. Keep in mind that:
* The owner of this specified folder must not be root
* Podman will attempt to change the permissions of the volume to the user the container is configured to run as
@ -36,47 +108,54 @@ The first volume is for your data folder and is created in the next step. This v
ROOT level privileges prohibited!
```
### 1.2 Prepare config volume
Although not required, you can prepare the config volume before starting the container. Otherwise it will be created automatically during initial startup of the container.
### 5. First run of Docker container under podman and performing authorisation
The 'onedrive' client within the container first needs to be authorised with your Microsoft account. This is achieved by initially running podman in interactive mode.
Create the config volume with the following command:
```bash
podman volume create onedrive_conf
```
Run the podman image with the commands below and make sure to change the value of `ONEDRIVE_DATA_DIR` to the actual onedrive data directory on your filesystem that you wish to use (e.g. `export ONEDRIVE_DATA_DIR="/home/abraunegg/OneDrive"`).
This will create a podman volume labeled `onedrive_conf`, where all configuration of your onedrive account will be stored. You can add a custom config file and other things later.
### 2. First run
The 'onedrive' client within the container needs to be authorized with your Microsoft account. This is achieved by initially running podman in interactive mode.
Run the podman image with the commands below and make sure to change `ONEDRIVE_DATA_DIR` to the actual onedrive data directory on your filesystem that you wish to use (e.g. `"/home/abraunegg/OneDrive"`).
It is a requirement that the container be run using a non-root uid and gid, you must insert a non-root UID and GID (e.g.` export ONEDRIVE_UID=1000` and export `ONEDRIVE_GID=1000`).
**Important:** The 'target' folder of `ONEDRIVE_DATA_DIR` must exist before running the podman container. The script below will create 'ONEDRIVE_DATA_DIR' so that it exists locally for the podman volume mapping to occur.
It is also a requirement that the container be run using a non-root uid and gid, you must insert a non-root UID and GID (e.g.` export ONEDRIVE_UID=1000` and export `ONEDRIVE_GID=1000`). The script below will use `id` to evaluate your system environment to use the correct values.
```bash
export ONEDRIVE_DATA_DIR="${HOME}/OneDrive"
export ONEDRIVE_UID=1000
export ONEDRIVE_GID=1000
export ONEDRIVE_UID=`id -u`
export ONEDRIVE_GID=`id -g`
mkdir -p ${ONEDRIVE_DATA_DIR}
podman run -it --name onedrive --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" \
-v onedrive_conf:/onedrive/conf:U,Z \
-v "onedrive-test-data:/onedrive/data:U,Z" \
driveone/onedrive:latest
-v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" \
driveone/onedrive:edge
```
**Important:** The 'target' folder of `ONEDRIVE_DATA_DIR` must exist before running the podman container
**If you plan to use podmans built in auto-updating of container images described in step 5, you must pass an additional argument to set a label during the first run.**
**Important:** In some scenarios, 'podman' sets the configuration and data directories to a different UID & GID as specified. To resolve this situation, you must run 'podman' with the `--userns=keep-id` flag to ensure 'podman' uses the UID and GID as specified. The updated script example when using `--userns=keep-id` is below:
**Important:** In some scenarios, 'podman' sets the configuration and data directories to a different UID & GID as specified. To resolve this situation, you must run 'podman' with the `--userns=keep-id` flag to ensure 'podman' uses the UID and GID as specified.
The run command would look instead look like as follows:
```
```bash
export ONEDRIVE_DATA_DIR="${HOME}/OneDrive"
export ONEDRIVE_UID=`id -u`
export ONEDRIVE_GID=`id -g`
mkdir -p ${ONEDRIVE_DATA_DIR}
podman run -it --name onedrive --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" \
--userns=keep-id \
-v onedrive_conf:/onedrive/conf:U,Z \
-v "onedrive-test-data:/onedrive/data:U,Z" \
-v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" \
driveone/onedrive:edge
```
**Important:** If you plan to use the 'podman' built in auto-updating of container images described in 'Systemd Service & Auto Updating' below, you must pass an additional argument to set a label during the first run. The updated script example to support auto-updating of container images is below:
```bash
export ONEDRIVE_DATA_DIR="${HOME}/OneDrive"
export ONEDRIVE_UID=`id -u`
export ONEDRIVE_GID=`id -g`
mkdir -p ${ONEDRIVE_DATA_DIR}
podman run -it --name onedrive --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" \
--userns=keep-id \
-v onedrive_conf:/onedrive/conf:U,Z \
-v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" \
-e PODMAN=1 \
--label "io.containers.autoupdate=image"
driveone/onedrive:latest
--label "io.containers.autoupdate=image" \
driveone/onedrive:edge
```
When the Podman container successfully starts:
@ -89,41 +168,39 @@ Once the 'onedrive' application is authorised, the client will automatically sta
If the client is working as expected, you can detach from the container with Ctrl+p, Ctrl+q.
### 4. Podman Container Status, stop, and restart
Check if the monitor service is running
### 6. Running the 'onedrive' container under 'podman'
#### 6.1 Check if the monitor service is running
```bash
podman ps -f name=onedrive
```
Show monitor run logs
#### 6.2 Show 'onedrive' runtime logs
```bash
podman logs onedrive
```
Stop running monitor
#### 6.3 Stop running 'onedrive' container
```bash
podman stop onedrive
```
Resume monitor
#### 6.4 Start 'onedrive' container
```bash
podman start onedrive
```
Remove onedrive container
#### 6.5 Remove 'onedrive' container
```bash
podman rm -f onedrive
```
## Advanced Setup
### 5. Systemd Service & Auto Updating
Podman supports running containers as a systemd service and also auto updating of the container images. Using the existing running container you can generate a systemd unit file to be installed by the **root** user. To have your container image auto-update with podman, it must first be created with the label `"io.containers.autoupdate=image"` mentioned in step 2.
## Advanced Usage
### Systemd Service & Auto Updating
Podman supports running containers as a systemd service and also auto updating of the container images. Using the existing running container you can generate a systemd unit file to be installed by the **root** user. To have your container image auto-update with podman, it must first be created with the label `"io.containers.autoupdate=image"` mentioned in step 5 above.
```
cd /tmp
@ -169,7 +246,7 @@ systemctl start podman-auto-update.timer
systemctl list-timers --all
```
### 6. Edit the config
### Editing the running configuration and using a 'config' file
The 'onedrive' client should run in default configuration, however you can change this default configuration by placing a custom config file in the `onedrive_conf` podman volume. First download the default config from [here](https://raw.githubusercontent.com/abraunegg/onedrive/master/config)
Then put it into your onedrive_conf volume path, which can be found with:
@ -180,22 +257,27 @@ Or you can map your own config folder to the config volume. Make sure to copy al
The detailed document for the config can be found here: [Configuration](https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md#configuration)
### 7. Sync multiple accounts
There are many ways to do this, the easiest is probably to
1. Create a second podman config volume (replace `Work` with your desired name): `podman volume create onedrive_conf_Work`
2. And start a second podman monitor container (again replace `Work` with your desired name):
```
### Syncing multiple accounts
There are many ways to do this, the easiest is probably to do the following:
1. Create a second podman config volume (replace `work` with your desired name): `podman volume create onedrive_conf_work`
2. And start a second podman monitor container (again replace `work` with your desired name):
```bash
export ONEDRIVE_DATA_DIR_WORK="/home/abraunegg/OneDriveWork"
export ONEDRIVE_UID=`id -u`
export ONEDRIVE_GID=`id -g`
mkdir -p ${ONEDRIVE_DATA_DIR_WORK}
podman run -it --restart unless-stopped --name onedrive_work \
-v onedrive_conf_Work:/onedrive/conf \
-v "${ONEDRIVE_DATA_DIR_WORK}:/onedrive/data" \
--user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" \
driveone/onedrive:latest
podman run -it --name onedrive_work --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" \
--userns=keep-id \
-v onedrive_conf_work:/onedrive/conf:U,Z \
-v "${ONEDRIVE_DATA_DIR_WORK}:/onedrive/data:U,Z" \
-e PODMAN=1 \
--label "io.containers.autoupdate=image" \
driveone/onedrive:edge
```
## Environment Variables
| Variable | Purpose | Sample Value |
## Supported Podman Environment Variables
| Variable | Purpose | Sample Value |
| ---------------- | --------------------------------------------------- |:-------------:|
| <B>ONEDRIVE_UID</B> | UserID (UID) to run as | 1000 |
| <B>ONEDRIVE_GID</B> | GroupID (GID) to run as | 1000 |
@ -205,36 +287,37 @@ podman run -it --restart unless-stopped --name onedrive_work \
| <B>ONEDRIVE_RESYNC</B> | Controls "--resync" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_DOWNLOADONLY</B> | Controls "--download-only" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_UPLOADONLY</B> | Controls "--upload-only" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_NOREMOTEDELETE</B> | Controls "--no-remote-delete" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_LOGOUT</B> | Controls "--logout" switch. Default is 0 | 1 |
| <B>ONEDRIVE_REAUTH</B> | Controls "--reauth" switch. Default is 0 | 1 |
| <B>ONEDRIVE_AUTHFILES</B> | Controls "--auth-files" option. Default is "" | "authUrl:responseUrl" |
| <B>ONEDRIVE_AUTHRESPONSE</B> | Controls "--auth-response" option. Default is "" | See [here](https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md#authorize-the-application-with-your-onedrive-account) |
| <B>ONEDRIVE_DISPLAY_CONFIG</B> | Controls "--display-running-config" switch on onedrive sync. Default is 0 | 1 |
| <B>ONEDRIVE_SINGLE_DIRECTORY</B> | Controls "--single-directory" option. Default = "" | "mydir" |
### Usage Examples
### Environment Variables Usage Examples
**Verbose Output:**
```bash
podman run -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:latest
podman run -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:edge
```
**Debug Output:**
```bash
podman run -e ONEDRIVE_DEBUG=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:latest
podman run -e ONEDRIVE_DEBUG=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:edge
```
**Perform a --resync:**
```bash
podman run -e ONEDRIVE_RESYNC=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:latest
podman run -e ONEDRIVE_RESYNC=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:edge
```
**Perform a --resync and --verbose:**
```bash
podman run -e ONEDRIVE_RESYNC=1 -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:latest
podman run -e ONEDRIVE_RESYNC=1 -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:edge
```
**Perform a --logout and re-authenticate:**
```bash
podman run -it -e ONEDRIVE_LOGOUT=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:latest
podman run -it -e ONEDRIVE_LOGOUT=1 -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" driveone/onedrive:edge
```
## Build instructions
### Building a custom Podman image
## Building a custom Podman image
You can also build your own image instead of pulling the one from [hub.docker.com](https://hub.docker.com/r/driveone/onedrive):
```bash
git clone https://github.com/abraunegg/onedrive
@ -246,19 +329,19 @@ There are alternate, smaller images available by building
Dockerfile-debian or Dockerfile-alpine. These [multi-stage builder pattern](https://docs.docker.com/develop/develop-images/multistage-build/)
Dockerfiles require Docker version at least 17.05.
#### How to build and run a custom Podman image based on Debian
### How to build and run a custom Podman image based on Debian
``` bash
podman build . -t local-ondrive-debian -f contrib/docker/Dockerfile-debian
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" local-ondrive-debian:latest
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" --userns=keep-id local-ondrive-debian:latest
```
#### How to build and run a custom Podman image based on Alpine Linux
### How to build and run a custom Podman image based on Alpine Linux
``` bash
podman build . -t local-ondrive-alpine -f contrib/docker/Dockerfile-alpine
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" local-ondrive-alpine:latest
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" --userns=keep-id local-ondrive-alpine:latest
```
#### How to build and run a custom Podman image for ARMHF (Raspberry Pi)
### How to build and run a custom Podman image for ARMHF (Raspberry Pi)
Compatible with:
* Raspberry Pi
* Raspberry Pi 2
@ -267,11 +350,11 @@ Compatible with:
* Raspberry Pi 4
``` bash
podman build . -t local-onedrive-armhf -f contrib/docker/Dockerfile-debian
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" local-onedrive-armhf:latest
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" --userns=keep-id local-onedrive-armhf:latest
```
#### How to build and run a custom Podman image for AARCH64 Platforms
### How to build and run a custom Podman image for AARCH64 Platforms
``` bash
podman build . -t local-onedrive-aarch64 -f contrib/docker/Dockerfile-debian
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" local-onedrive-aarch64:latest
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" --userns=keep-id local-onedrive-aarch64:latest
```

View file

@ -1,4 +1,19 @@
# How to configure OneDrive SharePoint Shared Library sync
**WARNING:** Several users have reported files being overwritten causing data loss as a result of using this client with SharePoint Libraries when running as a systemd service.
When this has been investigated, the following has been noted as potential root causes:
* File indexing application such as Baloo File Indexer or Tracker3 constantly indexing your OneDrive data
* The use of WPS Office and how it 'saves' files by deleting the existing item and replaces it with the saved data
Additionally there could be a yet unknown bug with the client, however all debugging and data provided previously shows that an 'external' process to the 'onedrive' application modifies the files triggering the undesirable upload to occur.
**Possible Preventative Actions:**
* Disable all File Indexing for your SharePoint Library data. It is out of scope to detail on how you should do this.
* Disable using a systemd service for syncing your SharePoint Library data.
* Do not use WPS Office to edit your documents. Use OpenOffice or LibreOffice as these do not exhibit the same 'delete to save' action that WPS Office has.
Additionally, please use caution when using this client with SharePoint.
## Application Version
Before reading this document, please ensure you are running application version [![Version](https://img.shields.io/github/v/release/abraunegg/onedrive)](https://github.com/abraunegg/onedrive/releases) or greater. Use `onedrive --version` to determine what application version you are using and upgrade your client if required.

View file

@ -34,12 +34,15 @@ Before reading this document, please ensure you are running application version
+ [monitor_log_frequency](#monitor_log_frequency)
+ [min_notify_changes](#min_notify_changes)
+ [operation_timeout](#operation_timeout)
+ [ip_protocol_version](#ip_protocol_version)
+ [classify_as_big_delete](#classify_as_big_delete)
* [Configuring the client for 'single tenant application' use](#configuring-the-client-for-single-tenant-application-use)
* [Configuring the client to use older 'skilion' application identifier](#configuring-the-client-to-use-older-skilion-application-identifier)
- [Frequently Asked Configuration Questions](#frequently-asked-configuration-questions)
* [How to sync only specific or single directory?](#how-to-sync-only-specific-or-single-directory)
* [How to 'skip' directories from syncing?](#how-to-skip-directories-from-syncing)
* [How to 'skip' files from syncing?](#how-to-skip-files-from-syncing)
* [How to 'skip' dot files and folders from syncing?](#how-to-skip-dot-files-and-folders-from-syncing)
* [How to 'skip' files larger than a certain size from syncing?](#how-to-skip-files-larger-than-a-certain-size-from-syncing)
* [How to 'rate limit' the application to control bandwidth consumed for upload & download operations?](#how-to-rate-limit-the-application-to-control-bandwidth-consumed-for-upload--download-operations)
* [How to prevent your local disk from filling up?](#how-to-prevent-your-local-disk-from-filling-up)
@ -49,6 +52,8 @@ Before reading this document, please ensure you are running application version
* [How to sync sharePoint / Office 365 Shared Libraries?](#how-to-sync-sharepoint--office-365-shared-libraries)
* [How to run a user systemd service at boot without user login?](#how-to-run-a-user-systemd-service-at-boot-without-user-login)
* [How to create a shareable link?](#how-to-create-a-shareable-link)
* [How to sync both Personal and Business accounts at the same time?](#how-to-sync-both-personal-and-business-accounts-at-the-same-time)
* [How to sync multiple SharePoint Libraries at the same time?](#how-to-sync-multiple-sharepoint-libraries-at-the-same-time)
- [Running 'onedrive' in 'monitor' mode](#running-onedrive-in-monitor-mode)
* [Use webhook to subscribe to remote updates in 'monitor' mode](#use-webhook-to-subscribe-to-remote-updates-in-monitor-mode)
* [More webhook configuration options](#more-webhook-configuration-options)
@ -216,39 +221,68 @@ In some cases it may be desirable to 'upload only' to OneDrive. To do this use t
```text
onedrive --synchronize --upload-only
```
**Note:** If a file or folder is present on OneDrive, that does not exist locally, it will be removed. If the data on OneDrive should be kept, the following should be used:
**Note:** If a file or folder is present on OneDrive, that was previously synced and now does not exist locally, that item it will be removed from OneDrive. If the data on OneDrive should be kept, the following should be used:
```text
onedrive --synchronize --upload-only --no-remote-delete
```
**Note:** The operation of 'upload only' does not request data from OneDrive about what 'other' data exists online. The client only knows about the data that 'this' client uploaded, thus any files or folders created or uploaded outside of this client will remain untouched online.
### Performing a selective sync via 'sync_list' file
Selective sync allows you to sync only specific files and directories.
To enable selective sync create a file named `sync_list` in your application configuration directory (default is `~/.config/onedrive`).
Each line of the file represents a relative path from your `sync_dir`. All files and directories not matching any line of the file will be skipped during all operations.
Important points to understand before using 'sync_list'.
* 'sync_list' excludes _everything_ by default on onedrive.
* 'sync_list' follows an _"exclude overrides include"_ rule, and requires **explicit inclusion**.
* Order exclusions before inclusions, so that anything _specifically included_ is included.
* How and where you place your `/` matters for excludes and includes in sub directories.
Each line of the file represents a relative path from your `sync_dir`. All files and directories not matching any line of the file will be skipped during all operations.
Additionally, the use of `/` is critically important to determine how a rule is interpreted. It is very similar to `**` wildcards, for those that are familiar with globbing patterns.
Here is an example of `sync_list`:
```text
# sync_list supports comments
#
# The ordering of entries is highly recommended - exclusions before inclusions
#
# Exclude temp folders under Documents
# Exclude temp folder(s) or file(s) under Documents folder(s), anywhere in Onedrive
!Documents/temp*
# Exclude my secret data
#
# Exclude secret data folder in root directory only
!/Secret_data/*
#
# Include my Backup folder
# Include everything else in root directory
/*
#
# Include my Backup folder(s) or file(s) anywhere on Onedrive
Backup
# Include Documents folder
#
# Include my Backup folder in root
/Backup/
#
# Include Documents folder(s) anywhere in Onedrive
Documents/
# Include all PDF documents
#
# Include all PDF files in Documents folder(s), anywhere in Onedrive
Documents/*.pdf
# Include this single document
#
# Include this single document in Documents folder(s), anywhere in Onedrive
Documents/latest_report.docx
# Include all Work/Project directories
#
# Include all Work/Project directories or files, inside 'Work' folder(s), anywhere in Onedrive
Work/Project*
#
# Include all "notes.txt" files, anywhere in Onedrive
notes.txt
# Include /Blender in the ~OneDrive root but not if elsewhere
#
# Include /Blender in the ~Onedrive root but not if elsewhere in Onedrive
/Blender
#
# Include these directories(or files) in 'Pictures' folder(s), that have a space in their name
Pictures/Camera Roll
Pictures/Saved Pictures
#
# Include these names if they match any file or folder
Cinema Soc
Codes
@ -259,20 +293,6 @@ The following are supported for pattern matching and exclusion rules:
* Use the `*` to wildcard select any characters to match for the item to be included
* Use either `!` or `-` characters at the start of the line to exclude an otherwise included item
To simplify 'exclusions' and 'inclusions', the following is also possible:
```text
# sync_list supports comments
#
# The ordering of entries is highly recommended - exclusions before inclusions
#
# Exclude temp folders under Documents
!Documents/temp*
# Exclude my secret data
!/Secret_data/*
#
# Include everything else
/*
```
**Note:** When enabling the use of 'sync_list' utilise the `--display-config` option to validate that your configuration will be used by the application, and test your configuration by adding `--dry-run` to ensure the client will operate as per your requirement.
@ -500,7 +520,6 @@ See the [config](https://raw.githubusercontent.com/abraunegg/onedrive/master/con
# sync_dir_permissions = "700"
# sync_file_permissions = "600"
# rate_limit = "131072"
# operation_timeout = "3600"
# webhook_enabled = "false"
# webhook_public_url = ""
# webhook_listening_host = ""
@ -511,6 +530,11 @@ See the [config](https://raw.githubusercontent.com/abraunegg/onedrive/master/con
# display_running_config = "false"
# read_only_auth_scope = "false"
# cleanup_local_files = "false"
# operation_timeout = "3600"
# dns_timeout = "60"
# connect_timeout = "10"
# data_timeout = "600"
# ip_protocol_version = "0"
```
### 'config' file configuration examples:
@ -598,7 +622,7 @@ Patterns are case insensitive. `*` and `?` [wildcards characters](https://techne
Files can be skipped in the following fashion:
* Specify a wildcard, eg: '*.txt' (skip all txt files)
* Explicitly specify the filename and it's full path relative to your sync_dir, eg: 'path/to/file/filename.ext'
* Explicitly specify the filename and it's full path relative to your sync_dir, eg: '/path/to/file/filename.ext'
* Explicitly specify the filename only and skip every instance of this filename, eg: 'filename.ext'
By default, the following files will be skipped:
@ -614,7 +638,7 @@ Example:
# For explanations of all config options below see docs/USAGE.md or the man page.
#
# sync_dir = "~/OneDrive"
skip_file = "~*|Documents/OneNote*|Documents/config.xlaunch|myfile.ext"
skip_file = "~*|/Documents/OneNote*|/Documents/config.xlaunch|myfile.ext|/Documents/keepass.kdbx"
# monitor_interval = "300"
# skip_dir = ""
# log_dir = "/var/log/onedrive/"
@ -625,10 +649,11 @@ skip_file = "~*|Documents/OneNote*|Documents/config.xlaunch|myfile.ext"
skip_file = "~*|.~*|*.tmp|*.swp"
skip_file = "*.blah"
skip_file = "never_sync.file"
skip_file = "/Documents/keepass.kdbx"
```
This will be interpreted the same as:
```text
skip_file = "~*|.~*|*.tmp|*.swp|*.blah|never_sync.file"
skip_file = "~*|.~*|*.tmp|*.swp|*.blah|never_sync.file|/Documents/keepass.kdbx"
```
**Note:** after changing `skip_file`, you must perform a full re-synchronization by adding `--resync` to your existing command line - for example: `onedrive --synchronize --resync`
@ -658,6 +683,7 @@ monitor_interval = "600"
# min_notify_changes = "5"
# monitor_log_frequency = "6"
```
**Note:** It is strongly advised you do not use a value of less than 300 seconds for 'monitor_interval'. Using a value less than 300 means your application will be constantly needlessly checking OneDrive online for changes. Future versions of the application may enforce the checking of this minimum value.
#### monitor_fullscan_frequency
This configuration option controls the number of 'monitor_interval' iterations between when a full scan of your data is performed to ensure data integrity and consistency.
@ -723,6 +749,43 @@ Example:
operation_timeout = "3600"
```
#### ip_protocol_version
By default, the application will use IPv4 and IPv6 to resolve and communicate with Microsoft OneDrive. In some Linux distributions (most notably Ubuntu and those distributions based on Ubuntu) this will cause problems due to how DNS resolution is being performed.
To configure the application to use a specific IP version, configure the following in your config file:
```text
# operation_timeout = "3600"
# dns_timeout = "60"
# connect_timeout = "10"
# data_timeout = "600"
ip_protocol_version = "1"
```
**Note:**
* A value of 0 will mean the client will use IPv4 and IPv6. This is the default.
* A value of 1 will mean the client will use IPv4 only.
* A value of 2 will mean the client will use IPv6 only.
#### classify_as_big_delete
This configuration option will help prevent the online deletion of files and folders online, when the directory that has been deleted contains more items than the specified value.
By default, this value is 1000 which will count files and folders as children of the directory that has been deleted.
To change this value, configure the following in your config file:
```text
# monitor_fullscan_frequency = "12"
# sync_root_files = "false"
classify_as_big_delete = "3000"
# user_agent = ""
# remove_source_files = "false"
```
**Note:**
* This option only looks at Directories. It has zero effect on deleting files located in your 'sync_dir' root
* This option (in v2.4.x and below) only gets activated when using `--monitor`. In `--synchronize` mode it is ignored as it is assumed you performed that desired operation before you started your next manual sync with OneDrive.
* Be sensible with setting this value - do not use a low value such as '1' as this will prevent you from syncing your data each and every time you delete a single file.
#### Configuring the client for 'single tenant application' use
In some instances when using OneDrive Business Accounts, depending on the Azure organisational configuration, it will be necessary to configure the client as a 'single tenant application'.
To configure this, after creating the application on your Azure tenant, update the 'config' file with the tenant name (not the GUID) and the newly created Application ID, then this will be used for the authentication process.
@ -773,12 +836,29 @@ check_nosync = "true"
# download_only = "false"
# disable_notifications = "false"
```
**Default:** False
### How to 'skip' files from syncing?
There are two methods to achieve this:
* Utilise 'skip_file' to configure what files to skip. Refer to above for configuration advice.
* Utilise 'sync_list' to configure what files and directories to sync, and what should be exluded
### How to 'skip' dot files and folders from syncing?
There are three methods to achieve this:
* Utilise 'skip_file' or 'skip_dir' to configure what files or folders to skip. Refer to above for configuration advice.
* Utilise 'sync_list' to configure what files and directories to sync, and what should be exluded
* Utilise 'skip_dotfiles' to skip any dot file (for example: `.Trash-1000` or `.xdg-volume-info`) from syncing to OneDrive.
Example:
```text
# skip_symlinks = "false"
# debug_https = "false"
skip_dotfiles = "true"
# skip_size = "1000"
# dry_run = "false"
```
**Default:** False
### How to 'skip' files larger than a certain size from syncing?
There are two methods to achieve this:
* Use `--skip-size ARG` as part of a CLI command to skip new files larger than this size (in MB)
@ -882,6 +962,16 @@ onedrive --create-share-link <path/to/file> --with-editing-perms
```
**Note:** The ordering of the option file path and option flag is important.
### How to sync both Personal and Business accounts at the same time?
You must configure separate instances of the application configuration for each account.
Refer to [./advanced-usage.md](advanced-usage.md) for configuration assistance.
### How to sync multiple SharePoint Libraries at the same time?
You must configure a separate instances of the application configuration for each SharePoint Library.
Refer to [./advanced-usage.md](advanced-usage.md) for configuration assistance.
## Running 'onedrive' in 'monitor' mode
Monitor mode (`--monitor`) allows the onedrive process to continually monitor your local file system for changes to files.
@ -919,7 +1009,7 @@ A webhook can be optionally enabled in the monitor mode to allow the onedrive pr
To enable this feature, you need to configure the following options in the config file:
```
```text
webhook_enabled = "true"
webhook_public_url = "<public-facing url to reach your webhook>"
```
@ -930,10 +1020,11 @@ Setting `webhook_enabled` to `true` enables the webhook in 'monitor' mode. The o
For example, below is a nginx config snippet to proxy traffic into the webhook:
```
```text
server {
listen 80;
location /webhooks/onedrive {
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:8888;
}
}
@ -941,6 +1032,29 @@ server {
With nginx running, you can configure `webhook_public_url` to `https://<your_host>/webhooks/onedrive`.
If you receive this application error:
```text
Subscription validation request failed. Response must exactly match validationToken query parameter.
```
The most likely cause for this error will be your nginx configuration. To resolve, potentially investigate the following configuration for nginx:
```text
server {
listen 80;
location /webhooks/onedrive {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Original-Request-URI $request_uri;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_buffering off;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:8888;
}
}
```
For any further nginx configuration assistance, please refer to: https://docs.nginx.com/
### More webhook configuration options
Below options can be optionally configured. The default is usually good enough.
@ -1160,11 +1274,13 @@ for extra details.
## Additional Configuration
### Advanced Configuration of the OneDrive Free Client
* Configuring the client to use mulitple OneDrive accounts / configurations
* Configuring the client for use in dual-boot (Windows / Linux) situations
* Configuring the client for use when 'sync_dir' is a mounted directory
* Upload data from the local ~/OneDrive folder to a specific location on OneDrive
* Configuring the client to use mulitple OneDrive accounts / configurations, for example:
* Setup to use onedrive with both Personal and Business accounts
* Setup to use onedrive with multiple SharePoint Libraries
* Configuring the client for use in dual-boot (Windows / Linux) situations
* Configuring the client for use when 'sync_dir' is a mounted directory
* Upload data from the local ~/OneDrive folder to a specific location on OneDrive
Refer to [./advanced-usage.md](advanced-usage.md) for configuration assistance.
### Access OneDrive service through a proxy

View file

@ -1,12 +1,27 @@
# OneDrive Client for Linux Application Security
This document details the application security used, and provides details for users on changing these security options.
This document details the following information:
* Why is this application an 'unverified publisher'?
* Application Security and Permission Scopes
* How to change Permission Scopes
* How to review your existing application access consent
## Why is this application an 'unverified publisher'?
Publisher Verification, as per the Microsoft [process](https://learn.microsoft.com/en-us/azure/active-directory/develop/publisher-verification-overview) has actually been configured, and, actually has been verified!
### Verified Publisher Configuration Evidence
As per the image below, the Azure portal shows that the 'Publisher Domain' has actually been verified:
![confirmed_verified_publisher](./images/confirmed_verified_publisher.jpg)
* The 'Publisher Domain' is: https://abraunegg.github.io/
* The required 'Microsoft Identity Association' is: https://abraunegg.github.io/.well-known/microsoft-identity-association.json
## Application Security and Permission Scopes
There are 2 main components regarding security for this application:
* Azure Application Permissions
* User Authentication Permissions
## Default Application Security
Security options should follow the security principal of 'least privilege':
Keeping this in mind, security options should follow the security principal of 'least privilege':
> The principle that a security architecture should be designed so that each entity
> is granted the minimum system resources and authorizations that the entity needs
> to perform its function.
@ -28,6 +43,8 @@ As such, the following API permissions are used by default:
### Default User Authentication Permissions
When a user authenticates with Microsoft OneDrive, additional account permissions are provided by service to give the user specific access to their data. These are delegated permissions provided by the platform:
| API / Permissions name | Type | Description | Admin consent required |
|---|---|---|---|
| Files.ReadWrite | Delegated | Have full access to user files | No |
@ -35,7 +52,7 @@ As such, the following API permissions are used by default:
| Sites.ReadWrite.All | Delegated | Have full access to all items in all site collections | No |
| offline_access | Delegated | Maintain access to data you have given it access to | No |
When these delegated API permissions are commbined, these provide the effective authentication scope for the OneDrive Client for Linux to access your data. The effective 'default' permissions will be:
When these delegated API permissions are combined, these provide the effective authentication scope for the OneDrive Client for Linux to access your data. The resulting effective 'default' permissions will be:
| API / Permissions name | Type | Description | Admin consent required |
|---|---|---|---|

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

65
docs/privacy-policy.md Normal file
View file

@ -0,0 +1,65 @@
# Privacy Policy
Effective Date: May 16 2018
## Introduction
This Privacy Policy outlines how OneDrive Client for Linux ("we," "our," or "us") collects, uses, and protects information when you use our software ("OneDrive Client for Linux"). We respect your privacy and are committed to ensuring the confidentiality and security of any information you provide while using the Software.
## Information We Do Not Collect
We want to be transparent about the fact that we do not collect any personal data, usage data, or tracking data through the Software. This means:
1. **No Personal Data**: We do not collect any information that can be used to personally identify you, such as your name, email address, phone number, or physical address.
2. **No Usage Data**: We do not collect data about how you use the Software, such as the features you use, the duration of your sessions, or any interactions within the Software.
3. **No Tracking Data**: We do not use cookies or similar tracking technologies to monitor your online behavior or track your activities across websites or apps.
## How We Use Your Information
Since we do not collect any personal, usage, or tracking data, there is no information for us to use for any purpose.
## Third-Party Services
The Software may include links to third-party websites or services, but we do not have control over the privacy practices or content of these third-party services. We encourage you to review the privacy policies of any third-party services you access through the Software.
## Children's Privacy
Since we do not collect any personal, usage, or tracking data, there is no restriction on the use of this application by anyone under the age of 18.
## Information You Choose to Share
While we do not collect personal data, usage data, or tracking data through the Software, there may be instances where you voluntarily choose to share information with us, particularly when submitting bug reports. These bug reports may contain sensitive information such as account details, file names, and directory names. It's important to note that these details are included in the logs and debug logs solely for the purpose of diagnosing and resolving technical issues with the Software.
We want to emphasize that, even in these cases, we do not have access to your actual data. The logs and debug logs provided in bug reports are used exclusively for technical troubleshooting and debugging purposes. We take measures to treat this information with the utmost care, and it is only accessible to our technical support and development teams. We do not use this information for any other purpose, and we have strict security measures in place to protect it.
## Protecting Your Sensitive Data
We are committed to safeguarding your sensitive data and maintaining its confidentiality. To ensure its protection:
1. **Limited Access**: Only authorized personnel within our technical support and development teams have access to the logs and debug logs containing sensitive data, and they are trained in handling this information securely.
2. **Data Encryption**: We use industry-standard encryption protocols to protect the transmission and storage of sensitive data.
3. **Data Retention**: We retain bug report data for a limited time necessary for resolving the reported issue. Once the issue is resolved, we promptly delete or anonymize the data.
4. **Security Measures**: We employ robust security measures to prevent unauthorized access, disclosure, or alteration of sensitive data.
By submitting a bug report, you acknowledge and consent to the inclusion of sensitive information in logs and debug logs for the sole purpose of addressing technical issues with the Software.
## Your Responsibilities
While we take measures to protect your sensitive data, it is essential for you to exercise caution when submitting bug reports. Please refrain from including any sensitive or personally identifiable information that is not directly related to the technical issue you are reporting. You have the option to redact or obfuscate sensitive details in bug reports to further protect your data.
## Changes to this Privacy Policy
We may update this Privacy Policy from time to time to reflect changes in our practices or for other operational, legal, or regulatory reasons. We will notify you of any material changes by posting the updated Privacy Policy on our website or through the Software. We encourage you to review this Privacy Policy periodically.
## Contact Us
If you have any questions or concerns about this Privacy Policy or our privacy practices, please contact us at support@mynas.com.au or via GitHub (https://github.com/abraunegg/onedrive)
## Conclusion
By using the Software, you agree to the terms outlined in this Privacy Policy. If you do not agree with any part of this policy, please discontinue the use of the Software.

54
docs/terms-of-service.md Normal file
View file

@ -0,0 +1,54 @@
# OneDrive Client for Linux - Software Service Terms of Service
## 1. Introduction
These Terms of Service ("Terms") govern your use of the OneDrive Client for Linux ("Application") software and related Microsoft OneDrive services ("Service") provided by Microsoft. By accessing or using the Service, you agree to comply with and be bound by these Terms. If you do not agree to these Terms, please do not use the Service.
## 2. License Compliance
The OneDrive Client for Linux software is licensed under the GNU General Public License, version 3.0 (the "GPLv3"). Your use of the software must comply with the terms and conditions of the GPLv3. A copy of the GPLv3 can be found here: https://www.gnu.org/licenses/gpl-3.0.en.html
## 3. Use of the Service
### 3.1. Access and Accounts
You may need to create an account or provide personal information to access certain features of the Service. You are responsible for maintaining the confidentiality of your account information and are solely responsible for all activities that occur under your account.
### 3.2. Prohibited Activities
You agree not to:
- Use the Service in any way that violates applicable laws or regulations.
- Use the Service to engage in any unlawful, harmful, or fraudulent activity.
- Use the Service in any manner that disrupts, damages, or impairs the Service.
## 4. Intellectual Property
The OneDrive Client for Linux software is subject to the GPLv3, and you must respect all copyrights, trademarks, and other intellectual property rights associated with the software. Any contributions you make to the software must also comply with the GPLv3.
## 5. Disclaimer of Warranties
The OneDrive Client for Linux software is provided "as is" without any warranties, either expressed or implied. We do not guarantee that the use of the Application will be error-free or uninterrupted.
Microsoft is not responsible for OneDrive Client for Linux. Any issues or problems with OneDrive Client for Linux should be raised on GitHub at https://github.com/abraunegg/onedrive or email support@mynas.com.au
OneDrive Client for Linux is not responsible for the Microsoft OneDrive Service or the Microsoft Graph API Service that this Application utilizes. Any issue with either Microsoft OneDrive or Microsoft Graph API should be raised with Microsoft via their support channel in your country.
## 6. Limitation of Liability
To the fullest extent permitted by law, we shall not be liable for any direct, indirect, incidental, special, consequential, or punitive damages, or any loss of profits or revenues, whether incurred directly or indirectly, or any loss of data, use, goodwill, or other intangible losses, resulting from (a) your use or inability to use the Service, or (b) any other matter relating to the Service.
This limitiation of liability explicitly relates to the use of the OneDrive Client for Linux software and does not affect your rights under the GPLv3.
## 7. Changes to Terms
We reserve the right to update or modify these Terms at any time without prior notice. Any changes will be effective immediately upon posting on GitHub. Your continued use of the Service after the posting of changes constitutes your acceptance of such changes. Changes can be reviewed on GitHub.
## 8. Governing Law
These Terms shall be governed by and construed in accordance with the laws of Australia, without regard to its conflict of law principles.
## 9. Contact Us
If you have any questions or concerns about these Terms, please contact us at https://github.com/abraunegg/onedrive or email support@mynas.com.au

View file

@ -17,8 +17,8 @@ Whilst there are [onedrive](https://packages.ubuntu.com/search?keywords=onedrive
## Determine which instructions to use
Ubuntu and its clones are based on various different releases, thus, you must use the correct instructions below, otherwise you may run into package dependancy issues and will be unable to install the client.
### Step 1: Remove any configured PPA and associated 'onedrive' package
Many Internet 'help' pages provide inconsistent details on how to install the OneDrive Client for Linux. A number of these continue to point users to install the client via a PPA repository. As this PPA repository is linked to the Debian packages, it is only updated when the Debian packages are updated. As such, it is not advisable to install from this PPA repository.
### Step 1: Remove any configured PPA and associated 'onedrive' package and systemd service files
Many Internet 'help' pages provide inconsistent details on how to install the OneDrive Client for Linux. A number of these websites continue to point users to install the client via the yann1ck PPA repository however this PPA no longer exists and should not be used.
To remove the PPA repository and the older client, perform the following actions:
```text
@ -26,6 +26,15 @@ sudo apt remove onedrive
sudo add-apt-repository --remove ppa:yann1ck/onedrive
```
Additionally, Ubuntu and its clones have a bad habit of creating a 'default' systemd service file when installing the 'onedrive' package so that the client will automatically run the client post being authenticated. This systemd entry is erroneous and needs to be removed.
```
Created symlink /etc/systemd/user/default.target.wants/onedrive.service → /usr/lib/systemd/user/onedrive.service.
```
To remove this symbolic link, run the following command:
```
sudo rm /etc/systemd/user/default.target.wants/onedrive.service
```
### Step 2: Ensure your system is up-to-date
Use a script, similar to the following to ensure your system is updated correctly:
```text
@ -123,19 +132,26 @@ If required, review the table below based on your 'lsb_release' information to p
| Release & Codename | Instructions to use |
|--------------------|---------------------|
| Ubuntu 18.x / Bionic | You must build from source or upgrade your Operating System to Ubuntu 22.x |
| Linux Mint 19.x / Tina | You must build from source or upgrade your Operating System to Linux Mint 20.x |
| Linux Mint 20.x / Ulyana | Use [Ubuntu 20.04](#distribution-ubuntu-2004) instructions below |
| Linux Mint 21.x / Vanessa | Use [Ubuntu 22.04](#distribution-ubuntu-2204) instructions below |
| Debian 10 | You must build from source or upgrade your Operating System to Debian 11 |
| Debian 11 | Use [Debian 11](#distribution-debian-11) instructions below |
| Raspbian GNU/Linux 10 | You must build from source or upgrade your Operating System to Raspbian GNU/Linux 11 |
| Raspbian GNU/Linux 11 | Use [Debian 11](#distribution-debian-11) instructions below |
| Ubuntu 20.04 / Focal | Use [Ubuntu 20.04](#distribution-ubuntu-2004) instructions below |
| Ubuntu 21.04 / Hirsute | Use [Ubuntu 21.04](#distribution-ubuntu-2104) instructions below |
| Ubuntu 21.10 / Impish | Use [Ubuntu 21.10](#distribution-ubuntu-2110) instructions below |
| Ubuntu 22.04 / Jammy | Use [Ubuntu 22.04](#distribution-ubuntu-2204) instructions below |
| Ubuntu 22.10 / Kinetic | Use [Ubuntu 22.10](#distribution-ubuntu-2210) instructions below |
| Linux Mint 19.x | This platform is End-of-Life (EOL) and no longer supported. You must upgrade to Linux Mint 21.x |
| Linux Mint 20.x | Use [Ubuntu 20.04](#distribution-ubuntu-2004) instructions below |
| Linux Mint 21.x | Use [Ubuntu 22.04](#distribution-ubuntu-2204) instructions below |
| Linux Mint Debian Edition (LMDE) 5 / Elsie | Use [Debian 11](#distribution-debian-11) instructions below |
| Linux Mint Debian Edition (LMDE) 6 / Faye | Use [Debian 12](#distribution-debian-12) instructions below |
| Debian 9 | This platform is End-of-Life (EOL) and no longer supported. You must upgrade to Debian 12 |
| Debian 10 | You must build from source or upgrade your Operating System to Debian 12 |
| Debian 11 | Use [Debian 11](#distribution-debian-11) instructions below |
| Debian 12 | Use [Debian 12](#distribution-debian-12) instructions below |
| Raspbian GNU/Linux 10 | You must build from source or upgrade your Operating System to Raspbian GNU/Linux 12 |
| Raspbian GNU/Linux 11 | Use [Debian 11](#distribution-debian-11) instructions below |
| Raspbian GNU/Linux 12 | Use [Debian 12](#distribution-debian-12) instructions below |
| Ubuntu 18.04 / Bionic | This platform is End-of-Life (EOL) and no longer supported. You must upgrade to Ubuntu 22.04 |
| Ubuntu 20.04 / Focal | Use [Ubuntu 20.04](#distribution-ubuntu-2004) instructions below |
| Ubuntu 21.04 / Hirsute | Use [Ubuntu 21.04](#distribution-ubuntu-2104) instructions below |
| Ubuntu 21.10 / Impish | Use [Ubuntu 21.10](#distribution-ubuntu-2110) instructions below |
| Ubuntu 22.04 / Jammy | Use [Ubuntu 22.04](#distribution-ubuntu-2204) instructions below |
| Ubuntu 22.10 / Kinetic | Use [Ubuntu 22.10](#distribution-ubuntu-2210) instructions below |
| Ubuntu 23.04 / Lunar | Use [Ubuntu 23.04](#distribution-ubuntu-2304) instructions below |
| Ubuntu 23.10 / Mantic | Use [Ubuntu 23.10](#distribution-ubuntu-2310) instructions below |
## Distribution Package Install Instructions
@ -143,7 +159,7 @@ If required, review the table below based on your 'lsb_release' information to p
The packages support the following platform architectures:
| &nbsp;i686&nbsp; | x86_64 | ARMHF | AARCH64 |
|:----:|:------:|:-----:|:-------:|
|✔|✔|✔|✔| |
|✔|✔|✔|✔|
#### Step 1: Add the OpenSuSE Build Service repository release key
Add the OpenSuSE Build Service repository release key using the following command:
@ -166,11 +182,38 @@ Run: `sudo apt install --no-install-recommends --no-install-suggests onedrive`
#### Step 5: Read 'Known Issues' with these packages
Read and understand the [known issues](#known-issues-with-installing-from-the-above-packages) with these packages below, taking any action that is needed.
### Distribution: Debian 12
The packages support the following platform architectures:
| &nbsp;i686&nbsp; | x86_64 | ARMHF | AARCH64 |
|:----:|:------:|:-----:|:-------:|
|✔|✔|✔|✔|
#### Step 1: Add the OpenSuSE Build Service repository release key
Add the OpenSuSE Build Service repository release key using the following command:
```text
wget -qO - https://download.opensuse.org/repositories/home:/npreining:/debian-ubuntu-onedrive/Debian_12/Release.key | gpg --dearmor | sudo tee /usr/share/keyrings/obs-onedrive.gpg > /dev/null
```
#### Step 2: Add the OpenSuSE Build Service repository
Add the OpenSuSE Build Service repository using the following command:
```text
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/obs-onedrive.gpg] https://download.opensuse.org/repositories/home:/npreining:/debian-ubuntu-onedrive/Debian_12/ ./" | sudo tee /etc/apt/sources.list.d/onedrive.list
```
#### Step 3: Update your apt package cache
Run: `sudo apt-get update`
#### Step 4: Install 'onedrive'
Run: `sudo apt install --no-install-recommends --no-install-suggests onedrive`
#### Step 5: Read 'Known Issues' with these packages
Read and understand the [known issues](#known-issues-with-installing-from-the-above-packages) with these packages below, taking any action that is needed.
### Distribution: Ubuntu 20.04
The packages support the following platform architectures:
| &nbsp;i686&nbsp; | x86_64 | ARMHF | AARCH64 |
|:----:|:------:|:-----:|:-------:|
❌|✔|✔|✔| |
|❌|✔|✔|✔|
#### Step 1: Add the OpenSuSE Build Service repository release key
Add the OpenSuSE Build Service repository release key using the following command:
@ -197,7 +240,7 @@ Read and understand the [known issues](#known-issues-with-installing-from-the-ab
The packages support the following platform architectures:
| &nbsp;i686&nbsp; | x86_64 | ARMHF | AARCH64 |
|:----:|:------:|:-----:|:-------:|
❌|✔|✔|✔| |
|❌|✔|✔|✔|
#### Step 1: Add the OpenSuSE Build Service repository release key
Add the OpenSuSE Build Service repository release key using the following command:
@ -224,7 +267,7 @@ Read and understand the [known issues](#known-issues-with-installing-from-the-ab
The packages support the following platform architectures:
| &nbsp;i686&nbsp; | x86_64 | ARMHF | AARCH64 |
|:----:|:------:|:-----:|:-------:|
❌|✔|✔|✔| |
|❌|✔|✔|✔|
#### Step 1: Add the OpenSuSE Build Service repository release key
Add the OpenSuSE Build Service repository release key using the following command:
@ -251,7 +294,7 @@ Read and understand the [known issues](#known-issues-with-installing-from-the-ab
The packages support the following platform architectures:
| &nbsp;i686&nbsp; | x86_64 | ARMHF | AARCH64 |
|:----:|:------:|:-----:|:-------:|
❌|✔|✔|✔| |
|❌|✔|✔|✔|
#### Step 1: Add the OpenSuSE Build Service repository release key
Add the OpenSuSE Build Service repository release key using the following command:
@ -278,7 +321,7 @@ Read and understand the [known issues](#known-issues-with-installing-from-the-ab
The packages support the following platform architectures:
| &nbsp;i686&nbsp; | x86_64 | ARMHF | AARCH64 |
|:----:|:------:|:-----:|:-------:|
❌|✔|✔|✔| |
|❌|✔|✔|✔|
#### Step 1: Add the OpenSuSE Build Service repository release key
Add the OpenSuSE Build Service repository release key using the following command:
@ -301,6 +344,61 @@ Run: `sudo apt install --no-install-recommends --no-install-suggests onedrive`
#### Step 5: Read 'Known Issues' with these packages
Read and understand the [known issues](#known-issues-with-installing-from-the-above-packages) with these packages below, taking any action that is needed.
### Distribution: Ubuntu 23.04
The packages support the following platform architectures:
| &nbsp;i686&nbsp; | x86_64 | ARMHF | AARCH64 |
|:----:|:------:|:-----:|:-------:|
|❌|✔|✔|✔|
#### Step 1: Add the OpenSuSE Build Service repository release key
Add the OpenSuSE Build Service repository release key using the following command:
```text
wget -qO - https://download.opensuse.org/repositories/home:/npreining:/debian-ubuntu-onedrive/xUbuntu_23.04/Release.key | gpg --dearmor | sudo tee /usr/share/keyrings/obs-onedrive.gpg > /dev/null
```
#### Step 2: Add the OpenSuSE Build Service repository
Add the OpenSuSE Build Service repository using the following command:
```text
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/obs-onedrive.gpg] https://download.opensuse.org/repositories/home:/npreining:/debian-ubuntu-onedrive/xUbuntu_23.04/ ./" | sudo tee /etc/apt/sources.list.d/onedrive.list
```
#### Step 3: Update your apt package cache
Run: `sudo apt-get update`
#### Step 4: Install 'onedrive'
Run: `sudo apt install --no-install-recommends --no-install-suggests onedrive`
#### Step 5: Read 'Known Issues' with these packages
Read and understand the [known issues](#known-issues-with-installing-from-the-above-packages) with these packages below, taking any action that is needed.
### Distribution: Ubuntu 23.10
The packages support the following platform architectures:
| &nbsp;i686&nbsp; | x86_64 | ARMHF | AARCH64 |
|:----:|:------:|:-----:|:-------:|
|❌|✔|❌|✔|
#### Step 1: Add the OpenSuSE Build Service repository release key
Add the OpenSuSE Build Service repository release key using the following command:
```text
wget -qO - https://download.opensuse.org/repositories/home:/npreining:/debian-ubuntu-onedrive/xUbuntu_23.10/Release.key | gpg --dearmor | sudo tee /usr/share/keyrings/obs-onedrive.gpg > /dev/null
```
#### Step 2: Add the OpenSuSE Build Service repository
Add the OpenSuSE Build Service repository using the following command:
```text
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/obs-onedrive.gpg] https://download.opensuse.org/repositories/home:/npreining:/debian-ubuntu-onedrive/xUbuntu_23.10/ ./" | sudo tee /etc/apt/sources.list.d/onedrive.list
```
#### Step 3: Update your apt package cache
Run: `sudo apt-get update`
#### Step 4: Install 'onedrive'
Run: `sudo apt install --no-install-recommends --no-install-suggests onedrive`
#### Step 5: Read 'Known Issues' with these packages
Read and understand the [known issues](#known-issues-with-installing-from-the-above-packages) with these packages below, taking any action that is needed.
## Known Issues with Installing from the above packages
### 1. The client may segfault | core-dump when exiting

File diff suppressed because it is too large Load diff

View file

@ -43,6 +43,35 @@ final class Config
// Default file permission mode
public long defaultFilePermissionMode = 600;
public int configuredFilePermissionMode;
// Bring in v2.5.0 config items
// HTTP Struct items, used for configuring HTTP()
// Curl Timeout Handling
// libcurl dns_cache_timeout timeout
immutable int defaultDnsTimeout = 60;
// Connect timeout for HTTP|HTTPS connections
immutable int defaultConnectTimeout = 10;
// With the following settings we force
// - if there is no data flow for 10min, abort
// - if the download time for one item exceeds 1h, abort
//
// Timeout for activity on connection
// this translates into Curl's CURLOPT_LOW_SPEED_TIME
// which says:
// It contains the time in number seconds that the
// transfer speed should be below the CURLOPT_LOW_SPEED_LIMIT
// for the library to consider it too slow and abort.
immutable int defaultDataTimeout = 600;
// Maximum time any operation is allowed to take
// This includes dns resolution, connecting, data transfer, etc.
immutable int defaultOperationTimeout = 3600;
// Specify how many redirects should be allowed
immutable int defaultMaxRedirects = 5;
// Specify what IP protocol version should be used when communicating with OneDrive
immutable int defaultIpProtocol = 0; // 0 = IPv4 + IPv6, 1 = IPv4 Only, 2 = IPv6 Only
this(string confdirOption)
{
@ -122,9 +151,6 @@ final class Config
longValues["sync_file_permissions"] = defaultFilePermissionMode;
// Configure download / upload rate limits
longValues["rate_limit"] = 0;
// maximum time an operation is allowed to take
// This includes dns resolution, connecting, data transfer, etc.
longValues["operation_timeout"] = 3600;
// To ensure we do not fill up the load disk, how much disk space should be reserved by default
longValues["space_reservation"] = 50 * 2^^20; // 50 MB as Bytes
// Webhook options
@ -161,6 +187,19 @@ final class Config
// - Enabling this option will add function processing times to the console output
// - This then enables tracking of where the application is spending most amount of time when processing data when users have questions re performance
boolValues["display_processing_time"] = false;
// HTTPS & CURL Operation Settings
// - Maximum time an operation is allowed to take
// This includes dns resolution, connecting, data transfer, etc.
longValues["operation_timeout"] = defaultOperationTimeout;
// libcurl dns_cache_timeout timeout
longValues["dns_timeout"] = defaultDnsTimeout;
// Timeout for HTTPS connections
longValues["connect_timeout"] = defaultConnectTimeout;
// Timeout for activity on a HTTPS connection
longValues["data_timeout"] = defaultDataTimeout;
// What IP protocol version should be used when communicating with OneDrive
longValues["ip_protocol_version"] = defaultIpProtocol; // 0 = IPv4 + IPv6, 1 = IPv4 Only, 2 = IPv6 Only
// EXPAND USERS HOME DIRECTORY
// Determine the users home directory.
@ -451,9 +490,6 @@ final class Config
"no-remote-delete",
"Do not delete local file 'deletes' from OneDrive when using --upload-only",
&boolValues["no_remote_delete"],
"operation-timeout",
"Maximum amount of time (in seconds) an operation is allowed to take",
&longValues["operation_timeout"],
"print-token",
"Print the access token, useful for debugging",
&boolValues["print_token"],
@ -675,7 +711,13 @@ final class Config
setValueString("skip_dir", configFileSkipDir);
}
}
// --single-directory Strip quotation marks from path
// This is an issue when using ONEDRIVE_SINGLE_DIRECTORY with Docker
if (key == "single_directory") {
// Strip quotation marks from provided path
string configSingleDirectory = strip(to!string(c.front.dup), "\"");
setValueString("single_directory", configSingleDirectory);
}
// Azure AD Configuration
if (key == "azure_ad_endpoint") {
string azureConfigValue = c.front.dup;

View file

@ -23,9 +23,8 @@ struct Item {
string cTag;
SysTime mtime;
string parentId;
string crc32Hash;
string sha1Hash;
string quickXorHash;
string sha256Hash;
string remoteDriveId;
string remoteId;
string syncStatus;
@ -34,7 +33,7 @@ struct Item {
final class ItemDatabase
{
// increment this for every change in the db schema
immutable int itemDatabaseVersion = 10;
immutable int itemDatabaseVersion = 11;
Database db;
string insertItemStmt;
@ -100,12 +99,12 @@ final class ItemDatabase
db.exec("PRAGMA locking_mode = EXCLUSIVE");
insertItemStmt = "
INSERT OR REPLACE INTO item (driveId, id, name, type, eTag, cTag, mtime, parentId, crc32Hash, sha1Hash, quickXorHash, remoteDriveId, remoteId, syncStatus)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)
INSERT OR REPLACE INTO item (driveId, id, name, type, eTag, cTag, mtime, parentId, quickXorHash, sha256Hash, remoteDriveId, remoteId, syncStatus)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)
";
updateItemStmt = "
UPDATE item
SET name = ?3, type = ?4, eTag = ?5, cTag = ?6, mtime = ?7, parentId = ?8, crc32Hash = ?9, sha1Hash = ?10, quickXorHash = ?11, remoteDriveId = ?12, remoteId = ?13, syncStatus = ?14
SET name = ?3, type = ?4, eTag = ?5, cTag = ?6, mtime = ?7, parentId = ?8, quickXorHash = ?9, sha256Hash = ?10, remoteDriveId = ?11, remoteId = ?12, syncStatus = ?13
WHERE driveId = ?1 AND id = ?2
";
selectItemByIdStmt = "
@ -136,9 +135,8 @@ final class ItemDatabase
cTag TEXT,
mtime TEXT NOT NULL,
parentId TEXT,
crc32Hash TEXT,
sha1Hash TEXT,
quickXorHash TEXT,
sha256Hash TEXT,
remoteDriveId TEXT,
remoteId TEXT,
deltaLink TEXT,
@ -321,19 +319,18 @@ final class ItemDatabase
bind(6, cTag);
bind(7, mtime.toISOExtString());
bind(8, parentId);
bind(9, crc32Hash);
bind(10, sha1Hash);
bind(11, quickXorHash);
bind(12, remoteDriveId);
bind(13, remoteId);
bind(14, syncStatus);
bind(9, quickXorHash);
bind(10, sha256Hash);
bind(11, remoteDriveId);
bind(12, remoteId);
bind(13, syncStatus);
}
}
private Item buildItem(Statement.Result result)
{
assert(!result.empty, "The result must not be empty");
assert(result.front.length == 15, "The result must have 15 columns");
assert(result.front.length == 14, "The result must have 14 columns");
Item item = {
driveId: result.front[0].dup,
id: result.front[1].dup,
@ -342,12 +339,11 @@ final class ItemDatabase
cTag: result.front[5].dup,
mtime: SysTime.fromISOExtString(result.front[6]),
parentId: result.front[7].dup,
crc32Hash: result.front[8].dup,
sha1Hash: result.front[9].dup,
quickXorHash: result.front[10].dup,
remoteDriveId: result.front[11].dup,
remoteId: result.front[12].dup,
syncStatus: result.front[14].dup
quickXorHash: result.front[8].dup,
sha256Hash: result.front[9].dup,
remoteDriveId: result.front[10].dup,
remoteId: result.front[11].dup,
syncStatus: result.front[12].dup
};
switch (result.front[3]) {
case "file": item.type = ItemType.file; break;

View file

@ -57,10 +57,12 @@ int main(string[] args)
bool displaySyncOptions = false;
bool cleanupLocalFilesGlobal = false;
bool synchronizeConfigured = false;
bool invalidSyncExit = false;
// start and finish messages
string startMessage = "Starting a sync with OneDrive";
string finishMessage = "Sync with OneDrive is complete";
string helpMessage = "Please use 'onedrive --help' for further assistance in regards to running this application.";
// hash file permission values
string hashPermissionValue = "600";
@ -84,7 +86,9 @@ int main(string[] args)
// was itemDb initialised?
if (itemDb !is null) {
// Make sure the .wal file is incorporated into the main db before we exit
itemDb.performVacuum();
if(!invalidSyncExit) {
itemDb.performVacuum();
}
destroy(itemDb);
}
// cleanup any dry-run data
@ -115,7 +119,9 @@ int main(string[] args)
// was itemDb initialised?
if (itemDb !is null) {
// Make sure the .wal file is incorporated into the main db before we exit
itemDb.performVacuum();
if(!invalidSyncExit) {
itemDb.performVacuum();
}
destroy(itemDb);
}
// cleanup any dry-run data
@ -755,7 +761,10 @@ int main(string[] args)
writeln("Config option 'debug_https' = ", cfg.getValueBool("debug_https"));
writeln("Config option 'rate_limit' = ", cfg.getValueLong("rate_limit"));
writeln("Config option 'operation_timeout' = ", cfg.getValueLong("operation_timeout"));
writeln("Config option 'dns_timeout' = ", cfg.getValueLong("dns_timeout"));
writeln("Config option 'connect_timeout' = ", cfg.getValueLong("connect_timeout"));
writeln("Config option 'data_timeout' = ", cfg.getValueLong("data_timeout"));
writeln("Config option 'ip_protocol_version' = ", cfg.getValueLong("ip_protocol_version"));
// Is sync_list configured ?
writeln("Config option 'sync_root_files' = ", cfg.getValueBool("sync_root_files"));
@ -847,7 +856,7 @@ int main(string[] args)
// Test if OneDrive service can be reached, exit if it cant be reached
log.vdebug("Testing network to ensure network connectivity to Microsoft OneDrive Service");
online = testNetwork();
online = testNetwork(cfg);
if (!online) {
// Cant initialise the API as we are not online
if (!cfg.getValueBool("monitor")) {
@ -879,7 +888,7 @@ int main(string[] args)
Thread.sleep(dur!"seconds"(maxBackoffInterval));
}
// perform the re-rty
online = testNetwork();
online = testNetwork(cfg);
if (online) {
// We are now online
log.log("Internet connectivity to Microsoft OneDrive service has been restored");
@ -927,7 +936,36 @@ int main(string[] args)
performSyncOK = true;
}
// create-directory, remove-directory, source-directory, destination-directory
// --source-directory must only be used with --destination-directory
// neither can (or should) be added individually as they have a no operational impact if they are
if (((cfg.getValueString("source_directory") == "") && (cfg.getValueString("destination_directory") != "")) || ((cfg.getValueString("source_directory") != "") && (cfg.getValueString("destination_directory") == ""))) {
// so either --source-directory or --destination-directory was passed in, without the other required item being passed in
// --source-directory or --destination-directory cannot be used with --synchronize or --monitor
writeln();
if (performSyncOK) {
// log an error
log.error("ERROR: --source-directory or --destination-directory cannot be used with --synchronize or --monitor");
} else {
// display issue with using these options
string emptyParameter;
string dataParameter;
if (cfg.getValueString("source_directory").empty) {
emptyParameter = "--source-directory";
dataParameter = "--destination-directory";
} else {
emptyParameter = "--destination-directory";
dataParameter = "--source-directory";
}
log.error("ERROR: " ~ dataParameter ~ " was passed in without also using " ~ emptyParameter);
}
// Use exit scopes to shutdown API
writeln();
log.error(helpMessage);
writeln();
return EXIT_FAILURE;
}
// --create-directory, --remove-directory, --source-directory, --destination-directory
// these are activities that dont perform a sync, so to not generate an error message for these items either
if (((cfg.getValueString("create_directory") != "") || (cfg.getValueString("remove_directory") != "")) || ((cfg.getValueString("source_directory") != "") && (cfg.getValueString("destination_directory") != "")) || (cfg.getValueString("get_file_link") != "") || (cfg.getValueString("modified_by") != "") || (cfg.getValueString("create_share_link") != "") || (cfg.getValueString("get_o365_drive_id") != "") || cfg.getValueBool("display_sync_status") || cfg.getValueBool("list_business_shared_folders")) {
performSyncOK = true;
@ -941,7 +979,8 @@ int main(string[] args)
if (exists(cfg.refreshTokenFilePath)) {
// OneDrive refresh token exists
log.log("\nApplication has been successfully authorised, however no additional command switches were provided.\n");
log.log("Please use 'onedrive --help' for further assistance in regards to running this application.\n");
log.log(helpMessage);
writeln();
// Use exit scopes to shutdown API
return EXIT_SUCCESS;
} else {
@ -954,6 +993,7 @@ int main(string[] args)
log.log("\n--synchronize or --monitor switches missing from your command line input. Please add one (not both) of these switches to your command line or use 'onedrive --help' for further assistance.\n");
log.log("No OneDrive sync will be performed without one of these two arguments being present.\n");
// Use exit scopes to shutdown API
invalidSyncExit = true;
return EXIT_FAILURE;
}
}
@ -961,9 +1001,9 @@ int main(string[] args)
// if --synchronize && --monitor passed in, exit & display help as these conflict with each other
if (cfg.getValueBool("synchronize") && cfg.getValueBool("monitor")) {
writeln();
writeln("ERROR: --synchronize and --monitor cannot be used together");
log.error("ERROR: --synchronize and --monitor cannot be used together");
writeln();
writeln("Please use 'onedrive --help' for further assistance in regards to running this application.");
log.error(helpMessage);
writeln();
// Use exit scopes to shutdown API
return EXIT_FAILURE;
@ -1339,6 +1379,14 @@ int main(string[] args)
log.error("ERROR: Unsupported account type for syncing OneDrive Business Shared Folders");
}
}
// Ensure that the value stored for cfg.getValueString("single_directory") does not contain any extra quotation marks
if (cfg.getValueString("single_directory") != ""){
string originalSingleDirectoryValue = cfg.getValueString("single_directory");
// Strip quotation marks from provided path to ensure no issues within a Docker environment when using passed in values
string updatedSingleDirectoryValue = strip(originalSingleDirectoryValue, "\"");
cfg.setValueString("single_directory", updatedSingleDirectoryValue);
}
// Are we displaying the sync status of the client?
if (cfg.getValueBool("display_sync_status")) {

View file

@ -214,9 +214,9 @@ final class OneDriveApi
http = HTTP();
// Curl Timeout Handling
// libcurl dns_cache_timeout timeout
http.dnsTimeout = (dur!"seconds"(60));
http.dnsTimeout = (dur!"seconds"(cfg.getValueLong("dns_timeout")));
// Timeout for HTTPS connections
http.connectTimeout = (dur!"seconds"(10));
http.connectTimeout = (dur!"seconds"(cfg.getValueLong("connect_timeout")));
// with the following settings we force
// - if there is no data flow for 10min, abort
// - if the download time for one item exceeds 1h, abort
@ -227,17 +227,27 @@ final class OneDriveApi
// It contains the time in number seconds that the
// transfer speed should be below the CURLOPT_LOW_SPEED_LIMIT
// for the library to consider it too slow and abort.
http.dataTimeout = (dur!"seconds"(600));
http.dataTimeout = (dur!"seconds"(cfg.getValueLong("data_timeout")));
// maximum time an operation is allowed to take
// This includes dns resolution, connecting, data transfer, etc.
http.operationTimeout = (dur!"seconds"(cfg.getValueLong("operation_timeout")));
// What IP protocol version should be used when using Curl - IPv4 & IPv6, IPv4 or IPv6
http.handle.set(CurlOption.ipresolve,cfg.getValueLong("ip_protocol_version")); // 0 = IPv4 + IPv6, 1 = IPv4 Only, 2 = IPv6 Only
// Specify how many redirects should be allowed
http.maxRedirects(5);
http.maxRedirects(cfg.defaultMaxRedirects);
// Do we enable curl debugging?
if (cfg.getValueBool("debug_https")) {
http.verbose = true;
.debugResponse = true;
// Output what options we are using so that in the debug log this can be tracked
log.vdebug("http.dnsTimeout = ", cfg.getValueLong("dns_timeout"));
log.vdebug("http.connectTimeout = ", cfg.getValueLong("connect_timeout"));
log.vdebug("http.dataTimeout = ", cfg.getValueLong("data_timeout"));
log.vdebug("http.operationTimeout = ", cfg.getValueLong("operation_timeout"));
log.vdebug("http.CurlOption.ipresolve = ", cfg.getValueLong("ip_protocol_version"));
log.vdebug("http.maxRedirects = ", cfg.defaultMaxRedirects);
}
// Update clientId if application_id is set in config file
@ -576,9 +586,19 @@ final class OneDriveApi
string[] authFiles = authFilesString.split(":");
string authUrl = authFiles[0];
string responseUrl = authFiles[1];
auto authUrlFile = File(authUrl, "w");
authUrlFile.write(url);
authUrlFile.close();
try {
// Try and write out the auth URL to the nominated file
auto authUrlFile = File(authUrl, "w");
authUrlFile.write(url);
authUrlFile.close();
} catch (std.exception.ErrnoException e) {
// There was a file system error
// display the error message
displayFileSystemErrorMessage(e.msg, getFunctionName!({}));
return false;
}
while (!exists(responseUrl)) {
Thread.sleep(dur!("msecs")(100));
}
@ -616,6 +636,12 @@ final class OneDriveApi
redeemToken(c.front);
return true;
}
string getSiteSearchUrl()
{
// Return the actual siteSearchUrl being used and/or requested when performing 'siteQuery = onedrive.o365SiteSearch(nextLink);' call
return .siteSearchUrl;
}
ulong getRetryAfterValue()
{
@ -1006,10 +1032,19 @@ final class OneDriveApi
auto expirationDateTime = Clock.currTime(UTC()) + subscriptionExpirationInterval;
const(char)[] url;
url = subscriptionUrl;
// Create a resource item based on if we have a driveId
string resourceItem;
if (driveId.length) {
resourceItem = "/drives/" ~ driveId ~ "/root";
} else {
resourceItem = "/me/drive/root";
}
// create JSON request to create webhook subscription
const JSONValue request = [
"changeType": "updated",
"notificationUrl": notificationUrl,
"resource": "/me/drive/root",
"resource": resourceItem,
"expirationDateTime": expirationDateTime.toISOExtString(),
"clientState": randomUUID().toString()
];
@ -1780,7 +1815,7 @@ final class OneDriveApi
case 403:
// OneDrive responded that the user is forbidden
log.vlog("OneDrive returned a 'HTTP 403 - Forbidden' - gracefully handling error");
// Throw this as a specific exception so this is caught when performing sync.o365SiteSearch
// Throw this as a specific exception so this is caught when performing 'siteQuery = onedrive.o365SiteSearch(nextLink);' call
throw new OneDriveException(http.statusLine.code, http.statusLine.reason, response);
// 412 - Precondition Failed

View file

@ -98,9 +98,9 @@ private bool hasQuickXorHash(const ref JSONValue item)
return ("quickXorHash" in item["file"]["hashes"]) != null;
}
private bool hasSha1Hash(const ref JSONValue item)
private bool hasSHA256Hash(const ref JSONValue item)
{
return ("sha1Hash" in item["file"]["hashes"]) != null;
return ("sha256Hash" in item["file"]["hashes"]) != null;
}
private bool isDotFile(const(string) path)
@ -117,7 +117,7 @@ private bool isDotFile(const(string) path)
}
// construct an Item struct from a JSON driveItem
private Item makeItem(const ref JSONValue driveItem)
private Item makeDatabaseItem(const ref JSONValue driveItem)
{
Item item = {
id: driveItem["id"].str,
@ -173,16 +173,19 @@ private Item makeItem(const ref JSONValue driveItem)
// extract the file hash
if (isItemFile(driveItem) && ("hashes" in driveItem["file"])) {
if ("crc32Hash" in driveItem["file"]["hashes"]) {
item.crc32Hash = driveItem["file"]["hashes"]["crc32Hash"].str;
} else if ("sha1Hash" in driveItem["file"]["hashes"]) {
item.sha1Hash = driveItem["file"]["hashes"]["sha1Hash"].str;
} else if ("quickXorHash" in driveItem["file"]["hashes"]) {
// Get quickXorHash
if ("quickXorHash" in driveItem["file"]["hashes"]) {
item.quickXorHash = driveItem["file"]["hashes"]["quickXorHash"].str;
} else {
log.vlog("The file does not have any hash");
log.vdebug("quickXorHash is missing from ", driveItem["id"].str);
}
}
// sha256Hash
if ("sha256Hash" in driveItem["file"]["hashes"]) {
item.sha256Hash = driveItem["file"]["hashes"]["sha256Hash"].str;
} else {
log.vdebug("sha256Hash is missing from ", driveItem["id"].str);
}
}
if (isItemRemote(driveItem)) {
item.remoteDriveId = driveItem["remoteItem"]["parentReference"]["driveId"].str;
@ -201,13 +204,11 @@ private Item makeItem(const ref JSONValue driveItem)
private bool testFileHash(const(string) path, const ref Item item)
{
// Try and compute the file hash
if (item.crc32Hash) {
if (item.crc32Hash == computeCrc32(path)) return true;
} else if (item.sha1Hash) {
if (item.sha1Hash == computeSha1Hash(path)) return true;
} else if (item.quickXorHash) {
// Generate QuickXORHash first before others
if (item.quickXorHash) {
if (item.quickXorHash == computeQuickXorHash(path)) return true;
} else if (item.sha256Hash) {
if (item.sha256Hash == computeSHA256Hash(path)) return true;
}
return false;
}
@ -231,8 +232,10 @@ final class SyncEngine
private string[] skippedItems;
// list of items to delete after the changes has been downloaded
private string[2][] idsToDelete;
// list of items we fake created when running --dry-run
// list of items we fake created when using --dry-run
private string[2][] idsFaked;
// list of directory names changed online, but not changed locally when using --dry-run
private string[] pathsRenamed;
// default drive id
private string defaultDriveId;
// default root id
@ -1798,20 +1801,49 @@ final class SyncEngine
log.vdebug("Retrying Query: changesAvailable = onedrive.viewChangesByItemId(driveId, idToQuery, deltaLinkAvailable)");
changesAvailable = onedrive.viewChangesByItemId(driveId, idToQuery, deltaLinkAvailable);
log.vdebug("Query 'changesAvailable = onedrive.viewChangesByItemId(driveId, idToQuery, deltaLinkAvailable)' performed successfully on re-try");
if (changesAvailable.type() == JSONType.object) {
// are there any delta changes?
if (("value" in changesAvailable) != null) {
deltaChanges = count(changesAvailable["value"].array);
log.vdebug("changesAvailable query reports that there are " , deltaChanges , " changes that need processing on OneDrive");
}
}
} catch (OneDriveException e) {
// display what the error is
log.vdebug("Query Error: changesAvailable = onedrive.viewChangesByItemId(driveId, idToQuery, deltaLinkAvailable) on re-try after delay");
if (e.httpStatusCode == 504) {
log.log("OneDrive returned a 'HTTP 504 - Gateway Timeout' when attempting to query for changes - retrying applicable request");
log.vdebug("changesAvailable = onedrive.viewChangesByItemId(driveId, idToQuery, deltaLinkAvailable) previously threw an error - retrying with empty deltaLinkAvailable");
// Increase delay and wait again before retry
log.vdebug("Thread sleeping for 90 seconds as the server did not receive a timely response from the upstream server it needed to access in attempting to complete the request");
Thread.sleep(dur!"seconds"(90));
log.vdebug("Retrying Query - using a null deltaLinkAvailable after delay");
try {
// try query with empty deltaLinkAvailable value
deltaLinkAvailable = null;
changesAvailable = onedrive.viewChangesByItemId(driveId, idToQuery, deltaLinkAvailable);
log.vdebug("Query 'changesAvailable = onedrive.viewChangesByItemId(driveId, idToQuery, deltaLinkAvailable)' performed successfully on re-try");
if (changesAvailable.type() == JSONType.object) {
// are there any delta changes?
if (("value" in changesAvailable) != null) {
deltaChanges = count(changesAvailable["value"].array);
log.vdebug("changesAvailable query reports that there are " , deltaChanges , " changes that need processing on OneDrive when using a null deltaLink value");
}
}
} catch (OneDriveException e) {
// Tried 3 times, give up
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
// OK .. if this was a 504, and running with --download-only & --cleanup-local-files
// need to exit to preserve local data, otherwise potential files will be deleted that should not be deleted
// leading to undesirable potential data loss scenarios
if ((e.httpStatusCode == 504) && (cleanupLocalFiles)) {
// log why we are exiting
log.log("Exiting application due to OneDrive API Gateway Timeout & --download-only & --cleanup-local-files configured to preserve local data");
// Must exit here
onedrive.shutdown();
exit(-1);
}
return;
}
} else {
@ -2878,20 +2910,32 @@ final class SyncEngine
} else {
// TODO: force remote sync by deleting local item
log.vlog("The destination is occupied, renaming the conflicting file...");
safeRename(newPath);
if (!dryRun) {
safeRename(newPath);
}
}
} else {
// to be overwritten item is not already in the itemdb, so it should
// be synced. Do a safe rename here, too.
// TODO: force remote sync by deleting local item
log.vlog("The destination is occupied by new file, renaming the conflicting file...");
safeRename(newPath);
if (!dryRun) {
safeRename(newPath);
}
}
}
// try and rename path, catch exception
try {
log.vdebug("Calling rename(oldPath, newPath)");
rename(oldPath, newPath);
if (!dryRun) {
// rename physical path on disk
rename(oldPath, newPath);
} else {
// track this as a faked id item
idsFaked ~= [newItem.driveId, newItem.id];
// we also need to track that we did not rename this path
pathsRenamed ~= [oldPath];
}
} catch (FileException e) {
// display the error message
displayFileSystemErrorMessage(e.msg, getFunctionName!({}));
@ -2954,13 +2998,13 @@ final class SyncEngine
}
if (!dryRun) {
ulong fileSize = 0;
ulong onlineFileSize = 0;
string OneDriveFileHash;
// fileDetails should be a valid JSON due to prior check
if (hasFileSize(fileDetails)) {
// Use the configured filesize as reported by OneDrive
fileSize = fileDetails["size"].integer;
// Use the configured onlineFileSize as reported by OneDrive
onlineFileSize = fileDetails["size"].integer;
} else {
// filesize missing
log.vdebug("WARNING: fileDetails['size'] is missing");
@ -2974,12 +3018,13 @@ final class SyncEngine
if (fileDetails["file"]["hashes"]["quickXorHash"].str != "") {
OneDriveFileHash = fileDetails["file"]["hashes"]["quickXorHash"].str;
}
}
// Check for Sha1Hash
if (hasSha1Hash(fileDetails)) {
// Use the configured sha1Hash as reported by OneDrive
if (fileDetails["file"]["hashes"]["sha1Hash"].str != "") {
OneDriveFileHash = fileDetails["file"]["hashes"]["sha1Hash"].str;
} else {
// Check for sha256Hash as quickXorHash did not exist
if (hasSHA256Hash(fileDetails)) {
// Use the configured sha256Hash as reported by OneDrive
if (fileDetails["file"]["hashes"]["sha256Hash"].str != "") {
OneDriveFileHash = fileDetails["file"]["hashes"]["sha256Hash"].str;
}
}
}
} else {
@ -2996,12 +3041,12 @@ final class SyncEngine
// debug output
log.vdebug("Local Disk Space Actual: ", localActualFreeSpace);
log.vdebug("Free Space Reservation: ", freeSpaceReservation);
log.vdebug("File Size to Download: ", fileSize);
log.vdebug("File Size to Download: ", onlineFileSize);
// calculate if we can download file
if ((localActualFreeSpace < freeSpaceReservation) || (fileSize > localActualFreeSpace)) {
if ((localActualFreeSpace < freeSpaceReservation) || (onlineFileSize > localActualFreeSpace)) {
// localActualFreeSpace is less than freeSpaceReservation .. insufficient free space
// fileSize is greater than localActualFreeSpace .. insufficient free space
// onlineFileSize is greater than localActualFreeSpace .. insufficient free space
writeln("failed!");
log.log("Insufficient local disk space to download file");
downloadFailed = true;
@ -3010,9 +3055,9 @@ final class SyncEngine
// Attempt to download the file
try {
onedrive.downloadById(item.driveId, item.id, path, fileSize);
onedrive.downloadById(item.driveId, item.id, path, onlineFileSize);
} catch (OneDriveException e) {
log.vdebug("onedrive.downloadById(item.driveId, item.id, path, fileSize); generated a OneDriveException");
log.vdebug("onedrive.downloadById(item.driveId, item.id, path, onlineFileSize); generated a OneDriveException");
// 408 = Request Time Out
// 429 = Too Many Requests - need to delay
if (e.httpStatusCode == 408) {
@ -3026,11 +3071,11 @@ final class SyncEngine
// retry in 2,4,8,16,32,64,128,256,512,1024 seconds
Thread.sleep(dur!"seconds"(retryAttempts*backoffInterval));
try {
onedrive.downloadById(item.driveId, item.id, path, fileSize);
onedrive.downloadById(item.driveId, item.id, path, onlineFileSize);
// successful download
retryAttempts = retryCount;
} catch (OneDriveException e) {
log.vdebug("onedrive.downloadById(item.driveId, item.id, path, fileSize); generated a OneDriveException");
log.vdebug("onedrive.downloadById(item.driveId, item.id, path, onlineFileSize); generated a OneDriveException");
if ((e.httpStatusCode == 429) || (e.httpStatusCode == 408)) {
// If another 408 ..
if (e.httpStatusCode == 408) {
@ -3061,11 +3106,11 @@ final class SyncEngine
// retry after waiting the timeout value from the 429 HTTP response header Retry-After
handleOneDriveThrottleRequest();
try {
onedrive.downloadById(item.driveId, item.id, path, fileSize);
onedrive.downloadById(item.driveId, item.id, path, onlineFileSize);
// successful download
retryAttempts = retryCount;
} catch (OneDriveException e) {
log.vdebug("onedrive.downloadById(item.driveId, item.id, path, fileSize); generated a OneDriveException");
log.vdebug("onedrive.downloadById(item.driveId, item.id, path, onlineFileSize); generated a OneDriveException");
if ((e.httpStatusCode == 429) || (e.httpStatusCode == 408)) {
// If another 408 ..
if (e.httpStatusCode == 408) {
@ -3106,12 +3151,13 @@ final class SyncEngine
// we have implemented --disable-download-validation to disable these checks
if (!disableDownloadValidation) {
// A 'file' was downloaded - does what we downloaded = reported fileSize or if there is some sort of funky local disk compression going on
// A 'file' was downloaded - does what we downloaded = reported onlineFileSize or if there is some sort of funky local disk compression going on
// does the file hash OneDrive reports match what we have locally?
string quickXorHash = computeQuickXorHash(path);
string sha1Hash = computeSha1Hash(path);
// Compute the local file size
ulong localFileSize = getSize(path);
if ((getSize(path) == fileSize) || (OneDriveFileHash == quickXorHash) || (OneDriveFileHash == sha1Hash)) {
if ((localFileSize == onlineFileSize) || (OneDriveFileHash == quickXorHash)) {
// downloaded matches either size or hash
log.vdebug("Downloaded file matches reported size and or reported file hash");
try {
@ -3123,17 +3169,17 @@ final class SyncEngine
}
} else {
// size error?
if (getSize(path) != fileSize) {
if (localFileSize != onlineFileSize) {
// downloaded file size does not match
log.vdebug("File size on disk: ", getSize(path));
log.vdebug("OneDrive API reported size: ", fileSize);
log.vdebug("Actual file size on disk: ", localFileSize);
log.vdebug("OneDrive API reported size: ", onlineFileSize);
log.error("ERROR: File download size mis-match. Increase logging verbosity to determine why.");
}
// hash error?
if ((OneDriveFileHash != quickXorHash) || (OneDriveFileHash != sha1Hash)) {
if (OneDriveFileHash != quickXorHash) {
// downloaded file hash does not match
log.vdebug("Actual file hash: ", OneDriveFileHash);
log.vdebug("OneDrive API reported hash: ", quickXorHash);
log.vdebug("Actual local file hash: ", quickXorHash);
log.vdebug("OneDrive API reported hash: ", OneDriveFileHash);
log.error("ERROR: File download hash mis-match. Increase logging verbosity to determine why.");
}
// add some workaround messaging
@ -4420,8 +4466,23 @@ final class SyncEngine
log.logAndNotify("Skipping item - invalid name (Microsoft Naming Convention): ", path);
return;
}
// We want to upload this new item
// If we are in a --dry-run scenario, we may have renamed a folder - but it is technically not renamed locally
// Thus, that entire path may be attemtped to be uploaded as new data to OneDrive
if (dryRun) {
// check the pathsRenamed array for this path
// if any match - we need to exclude this path
foreach (thisRenamedPath; pathsRenamed) {
log.vdebug("Renamed Path to evaluate: ", thisRenamedPath);
// Can we find 'thisRenamedPath' in the given 'path'
if (canFind(path, thisRenamedPath)) {
log.vdebug("Renamed Path MATCH - DONT UPLOAD AS NEW");
return;
}
}
}
// We want to upload this new local data
if (isDir(path)) {
Item item;
bool pathFoundInDB = false;
@ -6160,6 +6221,13 @@ final class SyncEngine
string nextLink;
string[] siteSearchResults;
// The account type must not be a personal account type
if (accountType == "personal"){
log.error("ERROR: A OneDrive Personal Account cannot be used with --get-O365-drive-id. Please re-authenticate your client using a OneDrive Business Account.");
return;
}
// What query are we performing?
log.log("Office 365 Library Name Query: ", o365SharedLibraryName);
for (;;) {
@ -6167,11 +6235,24 @@ final class SyncEngine
siteQuery = onedrive.o365SiteSearch(nextLink);
} catch (OneDriveException e) {
log.error("ERROR: Query of OneDrive for Office 365 Library Name failed");
// Forbidden - most likely authentication scope needs to be updated
if (e.httpStatusCode == 403) {
// Forbidden - most likely authentication scope needs to be updated
log.error("ERROR: Authentication scope needs to be updated. Use --reauth and re-authenticate client.");
return;
}
// Requested resource cannot be found
if (e.httpStatusCode == 404) {
string siteSearchUrl;
if (nextLink.empty) {
siteSearchUrl = onedrive.getSiteSearchUrl();
} else {
siteSearchUrl = nextLink;
}
// log the error
log.error("ERROR: Your OneDrive Account and Authentication Scope cannot access this OneDrive API: ", siteSearchUrl);
log.error("ERROR: To resolve, please discuss this issue with whomever supports your OneDrive and SharePoint environment.");
return;
}
// HTTP request returned status code 429 (Too Many Requests)
if (e.httpStatusCode == 429) {
// HTTP request returned status code 429 (Too Many Requests). We need to leverage the response Retry-After HTTP header to ensure minimum delay until the throttle is removed.
@ -6691,16 +6772,16 @@ final class SyncEngine
// real id / eTag / cTag are different format for personal / business account
auto sha1 = new SHA1Digest();
ubyte[] hash1 = sha1.digest(path);
ubyte[] fakedOneDriveItemValues = sha1.digest(path);
JSONValue fakeResponse;
if (isDir(path)) {
// path is a directory
fakeResponse = [
"id": JSONValue(toHexString(hash1)),
"cTag": JSONValue(toHexString(hash1)),
"eTag": JSONValue(toHexString(hash1)),
"id": JSONValue(toHexString(fakedOneDriveItemValues)),
"cTag": JSONValue(toHexString(fakedOneDriveItemValues)),
"eTag": JSONValue(toHexString(fakedOneDriveItemValues)),
"fileSystemInfo": JSONValue([
"createdDateTime": mtime.toISOExtString(),
"lastModifiedDateTime": mtime.toISOExtString()
@ -6719,9 +6800,9 @@ final class SyncEngine
string quickXorHash = computeQuickXorHash(path);
fakeResponse = [
"id": JSONValue(toHexString(hash1)),
"cTag": JSONValue(toHexString(hash1)),
"eTag": JSONValue(toHexString(hash1)),
"id": JSONValue(toHexString(fakedOneDriveItemValues)),
"cTag": JSONValue(toHexString(fakedOneDriveItemValues)),
"eTag": JSONValue(toHexString(fakedOneDriveItemValues)),
"fileSystemInfo": JSONValue([
"createdDateTime": mtime.toISOExtString(),
"lastModifiedDateTime": mtime.toISOExtString()
@ -7186,4 +7267,36 @@ final class SyncEngine
onedrive.shutdown();
exit(-1);
}
// Wrapper function for makeDatabaseItem so we can check if the item, if a file, has any hashes
private Item makeItem(JSONValue onedriveJSONItem)
{
Item newDatabaseItem = makeDatabaseItem(onedriveJSONItem);
// Check for hashes in this DB item
if (newDatabaseItem.type == ItemType.file) {
// Does this file have a size greater than 0 - zero size files will potentially not have a hash
if (hasFileSize(onedriveJSONItem)) {
if (onedriveJSONItem["size"].integer > 0) {
// Does the item have any hashes?
if ((newDatabaseItem.quickXorHash.empty) && (newDatabaseItem.sha256Hash.empty)) {
// Odd .. no hash ......
string apiMessage = "WARNING: OneDrive API inconsistency - this file does not have any hash: ";
// This is computationally expensive .. but we are only doing this if there are no hashses provided:
bool parentInDatabase = itemdb.idInLocalDatabase(newDatabaseItem.driveId, newDatabaseItem.parentId);
if (parentInDatabase) {
// Calculate this item path
string newItemPath = computeItemPath(newDatabaseItem.driveId, newDatabaseItem.parentId) ~ "/" ~ newDatabaseItem.name;
log.log(apiMessage, newItemPath);
} else {
// Use the item ID
log.log(apiMessage, newDatabaseItem.id);
}
}
}
}
}
return newDatabaseItem;
}
}

View file

@ -15,7 +15,9 @@ import std.json;
import std.traits;
import qxor;
import core.stdc.stdlib;
static import log;
import log;
import config;
shared string deviceName;
@ -48,28 +50,6 @@ void safeRemove(const(char)[] path)
if (exists(path)) remove(path);
}
// returns the crc32 hex string of a file
string computeCrc32(string path)
{
CRC32 crc;
auto file = File(path, "rb");
foreach (ubyte[] data; chunks(file, 4096)) {
crc.put(data);
}
return crc.finish().toHexString().dup;
}
// returns the sha1 hash hex string of a file
string computeSha1Hash(string path)
{
SHA1 sha;
auto file = File(path, "rb");
foreach (ubyte[] data; chunks(file, 4096)) {
sha.put(data);
}
return sha.finish().toHexString().dup;
}
// returns the quickXorHash base64 string of a file
string computeQuickXorHash(string path)
{
@ -81,6 +61,16 @@ string computeQuickXorHash(string path)
return Base64.encode(qxor.finish());
}
// returns the SHA256 hex string of a file
string computeSHA256Hash(string path) {
SHA256 sha256;
auto file = File(path, "rb");
foreach (ubyte[] data; chunks(file, 4096)) {
sha256.put(data);
}
return sha256.finish().toHexString().dup;
}
// converts wildcards (*, ?) to regex
Regex!char wild2regex(const(char)[] pattern)
{
@ -126,15 +116,23 @@ Regex!char wild2regex(const(char)[] pattern)
}
// returns true if the network connection is available
bool testNetwork()
bool testNetwork(Config cfg)
{
// Use low level HTTP struct
auto http = HTTP();
http.url = "https://login.microsoftonline.com";
// DNS lookup timeout
http.dnsTimeout = (dur!"seconds"(5));
http.dnsTimeout = (dur!"seconds"(cfg.getValueLong("dns_timeout")));
// Timeout for connecting
http.connectTimeout = (dur!"seconds"(5));
http.connectTimeout = (dur!"seconds"(cfg.getValueLong("connect_timeout")));
// Data Timeout for HTTPS connections
http.dataTimeout = (dur!"seconds"(cfg.getValueLong("data_timeout")));
// maximum time any operation is allowed to take
// This includes dns resolution, connecting, data transfer, etc.
http.operationTimeout = (dur!"seconds"(cfg.getValueLong("operation_timeout")));
// What IP protocol version should be used when using Curl - IPv4 & IPv6, IPv4 or IPv6
http.handle.set(CurlOption.ipresolve,cfg.getValueLong("ip_protocol_version")); // 0 = IPv4 + IPv6, 1 = IPv4 Only, 2 = IPv6 Only
// HTTP connection test method
http.method = HTTP.Method.head;
// Attempt to contact the Microsoft Online Service
@ -361,12 +359,14 @@ string getFunctionName(alias func)() {
}
// Get the latest release version from GitHub
string getLatestReleaseVersion() {
JSONValue getLatestReleaseDetails() {
// Import curl just for this function
import std.net.curl;
char[] content;
JSONValue json;
JSONValue githubLatest;
JSONValue versionDetails;
string latestTag;
string publishedDate;
try {
content = get("https://api.github.com/repos/abraunegg/onedrive/releases/latest");
@ -376,50 +376,181 @@ string getLatestReleaseVersion() {
}
try {
json = content.parseJSON();
githubLatest = content.parseJSON();
} catch (JSONException e) {
// unable to parse the content JSON, set to blank JSON
log.vdebug("Unable to parse GitHub JSON response");
json = parseJSON("{}");
githubLatest = parseJSON("{}");
}
// json has to be a valid JSON object
if (json.type() == JSONType.object){
if ("tag_name" in json) {
// githubLatest has to be a valid JSON object
if (githubLatest.type() == JSONType.object){
// use the returned tag_name
if ("tag_name" in githubLatest) {
// use the provided tag
// "tag_name": "vA.B.CC" and strip 'v'
latestTag = strip(json["tag_name"].str, "v");
latestTag = strip(githubLatest["tag_name"].str, "v");
} else {
// set to latestTag zeros
log.vdebug("'tag_name' unavailable in JSON response. Setting latest GitHub release version to 0.0.0");
log.vdebug("'tag_name' unavailable in JSON response. Setting GitHub 'tag_name' release version to 0.0.0");
latestTag = "0.0.0";
}
// use the returned published_at date
if ("published_at" in githubLatest) {
// use the provided value
publishedDate = githubLatest["published_at"].str;
} else {
// set to v2.0.0 release date
log.vdebug("'published_at' unavailable in JSON response. Setting GitHub 'published_at' date to 2018-07-18T18:00:00Z");
publishedDate = "2018-07-18T18:00:00Z";
}
} else {
// JSONValue is not an object
log.vdebug("Invalid JSON Object. Setting latest GitHub release version to 0.0.0");
log.vdebug("Invalid JSON Object. Setting GitHub 'tag_name' release version to 0.0.0");
latestTag = "0.0.0";
log.vdebug("Invalid JSON Object. Setting GitHub 'published_at' date to 2018-07-18T18:00:00Z");
publishedDate = "2018-07-18T18:00:00Z";
}
// return the latest github version
return latestTag;
// return the latest github version and published date as our own JSON
versionDetails = [
"latestTag": JSONValue(latestTag),
"publishedDate": JSONValue(publishedDate)
];
// return JSON
return versionDetails;
}
// Get the release details from the 'current' running version
JSONValue getCurrentVersionDetails(string thisVersion) {
// Import curl just for this function
import std.net.curl;
char[] content;
JSONValue githubDetails;
JSONValue versionDetails;
string versionTag = "v" ~ thisVersion;
string publishedDate;
try {
content = get("https://api.github.com/repos/abraunegg/onedrive/releases");
} catch (CurlException e) {
// curl generated an error - meaning we could not query GitHub
log.vdebug("Unable to query GitHub for release details");
}
try {
githubDetails = content.parseJSON();
} catch (JSONException e) {
// unable to parse the content JSON, set to blank JSON
log.vdebug("Unable to parse GitHub JSON response");
githubDetails = parseJSON("{}");
}
// githubDetails has to be a valid JSON array
if (githubDetails.type() == JSONType.array){
foreach (searchResult; githubDetails.array) {
// searchResult["tag_name"].str;
if (searchResult["tag_name"].str == versionTag) {
log.vdebug("MATCHED version");
log.vdebug("tag_name: ", searchResult["tag_name"].str);
log.vdebug("published_at: ", searchResult["published_at"].str);
publishedDate = searchResult["published_at"].str;
}
}
if (publishedDate.empty) {
// empty .. no version match ?
// set to v2.0.0 release date
log.vdebug("'published_at' unavailable in JSON response. Setting GitHub 'published_at' date to 2018-07-18T18:00:00Z");
publishedDate = "2018-07-18T18:00:00Z";
}
} else {
// JSONValue is not an Array
log.vdebug("Invalid JSON Array. Setting GitHub 'published_at' date to 2018-07-18T18:00:00Z");
publishedDate = "2018-07-18T18:00:00Z";
}
// return the latest github version and published date as our own JSON
versionDetails = [
"versionTag": JSONValue(thisVersion),
"publishedDate": JSONValue(publishedDate)
];
// return JSON
return versionDetails;
}
// Check the application version versus GitHub latestTag
void checkApplicationVersion() {
// calculate if the client is current version or not
string latestVersion = strip(getLatestReleaseVersion());
// Get the latest details from GitHub
JSONValue latestVersionDetails = getLatestReleaseDetails();
string latestVersion = latestVersionDetails["latestTag"].str;
SysTime publishedDate = SysTime.fromISOExtString(latestVersionDetails["publishedDate"].str).toUTC();
SysTime releaseGracePeriod = publishedDate;
SysTime currentTime = Clock.currTime().toUTC();
// drop fraction seconds
publishedDate.fracSecs = Duration.zero;
currentTime.fracSecs = Duration.zero;
releaseGracePeriod.fracSecs = Duration.zero;
// roll the grace period forward to allow distributions to catch up based on their release cycles
releaseGracePeriod = releaseGracePeriod.add!"months"(1);
// what is this clients version?
auto currentVersionArray = strip(strip(import("version"), "v")).split("-");
string applicationVersion = currentVersionArray[0];
// display warning if not current
// debug output
log.vdebug("applicationVersion: ", applicationVersion);
log.vdebug("latestVersion: ", latestVersion);
log.vdebug("publishedDate: ", publishedDate);
log.vdebug("currentTime: ", currentTime);
log.vdebug("releaseGracePeriod: ", releaseGracePeriod);
// display details if not current
// is application version is older than available on GitHub
if (applicationVersion != latestVersion) {
// is application version is older than available on GitHub
// application version is different
bool displayObsolete = false;
// what warning do we present?
if (applicationVersion < latestVersion) {
// application version is obsolete and unsupported
// go get this running version details
JSONValue thisVersionDetails = getCurrentVersionDetails(applicationVersion);
SysTime thisVersionPublishedDate = SysTime.fromISOExtString(thisVersionDetails["publishedDate"].str).toUTC();
thisVersionPublishedDate.fracSecs = Duration.zero;
log.vdebug("thisVersionPublishedDate: ", thisVersionPublishedDate);
// the running version grace period is its release date + 1 month
SysTime thisVersionReleaseGracePeriod = thisVersionPublishedDate;
thisVersionReleaseGracePeriod = thisVersionReleaseGracePeriod.add!"months"(1);
log.vdebug("thisVersionReleaseGracePeriod: ", thisVersionReleaseGracePeriod);
// is this running version obsolete ?
if (!displayObsolete) {
// if releaseGracePeriod > currentTime
// display an information warning that there is a new release available
if (releaseGracePeriod.toUnixTime() > currentTime.toUnixTime()) {
// inside release grace period ... set flag to false
displayObsolete = false;
} else {
// outside grace period
displayObsolete = true;
}
}
// display version response
writeln();
log.logAndNotify("WARNING: Your onedrive client version is obsolete and unsupported. Please upgrade your client version.");
log.vlog("Application version: ", applicationVersion);
log.vlog("Version available: ", latestVersion);
if (!displayObsolete) {
// display the new version is available message
log.logAndNotify("INFO: A new onedrive client version is available. Please upgrade your client version when possible.");
} else {
// display the obsolete message
log.logAndNotify("WARNING: Your onedrive client version is now obsolete and unsupported. Please upgrade your client version.");
}
log.log("Current Application Version: ", applicationVersion);
log.log("Version Available: ", latestVersion);
writeln();
}
}