mirror of
https://github.com/abraunegg/onedrive
synced 2024-06-28 18:30:09 +02:00
Update PR from Master
* Update PR from Master
This commit is contained in:
commit
4df9b000aa
2
.github/FUNDING.yml
vendored
Normal file
2
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
github: abraunegg
|
61
.github/ISSUE_TEMPLATE/bug_report.md
vendored
61
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,61 +0,0 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
**Note:** Before submitting a bug report, please ensure you are running the latest 'onedrive' client as built from 'master' and by using the latest available DMD compiler. Refer to the readme on building the client for your system.
|
||||
|
||||
### Bug Report Details ###
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Application and Operating System Details:**
|
||||
* Provide your OS & version (CentOS 6.x, Ubuntu 18.x etc) and the output of: `uname -a`
|
||||
* Are you using a headless system (no gui) or with a gui installed?
|
||||
* OneDrive Account Type
|
||||
* Did you build from source or install from a package?
|
||||
* If you installed from source, what is your DMD or LDC compiler version: `dmd --version` or `ldmd2 --version`
|
||||
* OneDrive Application Version: Output of `onedrive --version`
|
||||
* OneDrive Application Configuration: Output of `onedrive --display-config`
|
||||
* Provide the version of curl you are using: Output of `curl --version`
|
||||
* Is your configured 'sync_dir' a local directory or a network mount point?
|
||||
* If *not* local, provide all the mountpoints in your system: Output of: `mount`
|
||||
* What partition format type does your configured 'sync_dir' reside on? Output of: `lsblk -f`
|
||||
* Explain your entire configuration setup - is the OneDrive folder shared with any other system, shared with any other platform at the same time, is the OneDrive account you use shared across multiple systems / platforms / Operating Systems and in use at the same time
|
||||
|
||||
**Note:** Please generate a full debug log whilst reproducing the issue as per [https://github.com/abraunegg/onedrive/wiki/Generate-debug-log-for-support](https://github.com/abraunegg/onedrive/wiki/Generate-debug-log-for-support) and email to support@mynas.com.au
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior if not causing an application crash:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
If issue is replicated by a specific 'file' or 'path' please archive the file and path tree & email to support@mynas.com.au
|
||||
|
||||
**Complete Verbose Log Output**
|
||||
A clear and full log of the problem when running the application in the following manner (ie, not in monitor mode):
|
||||
```bash
|
||||
onedrive --synchronize --verbose <any of your other needed options>
|
||||
```
|
||||
|
||||
Run the application in a separate terminal window or SSH session and provide the entire application output including the error & crash. When posing the logs, Please format log output to make it easier to read. See [https://guides.github.com/features/mastering-markdown/](https://guides.github.com/features/mastering-markdown/) for more details.
|
||||
|
||||
Application Log Output:
|
||||
```bash
|
||||
Verbose console log output goes here
|
||||
```
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
### Bug Report Checklist ###
|
||||
* [] Detailed description
|
||||
* [] Application and Operating System Details provided in full
|
||||
* [] Reproduction steps (if applicable)
|
||||
* [] Verbose Log Output from your error
|
||||
* [] Debug Log generated and submitted
|
176
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
176
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
name: "Bug Report"
|
||||
description: Create a Bug Report to help us fix your issue
|
||||
title: "Bug: "
|
||||
labels: ["Bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Note:** Before submitting a bug report, please ensure you are running the latest 'onedrive' client as built from 'master' and compile by using the latest available DMD or LDC compiler. Refer to the the [INSTALL](https://github.com/abraunegg/onedrive/blob/master/docs/INSTALL.md) document on how to build the client for your system.
|
||||
|
||||
- type: textarea
|
||||
id: bugDescription
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: |
|
||||
Add a clear and concise description of what you think the bug is.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: operatingSystemDetails
|
||||
attributes:
|
||||
label: Operating System Details
|
||||
description: |
|
||||
* What is your Operating System (`uname -a`)
|
||||
* Output of: (`cat /etc/redhat-release`) or (`lsb_release -a`)
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: installMethod
|
||||
attributes:
|
||||
label: Client Installation Method
|
||||
description: |
|
||||
How did you install the client?
|
||||
multiple: false
|
||||
options:
|
||||
- From Source
|
||||
- From Distribution Package
|
||||
- From 3rd Party Source (PPA, OpenSuSE Build Service etc)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: accountType
|
||||
attributes:
|
||||
label: OneDrive Account Type
|
||||
description: |
|
||||
What is your OneDrive Account Type?
|
||||
multiple: false
|
||||
options:
|
||||
- Personal
|
||||
- Business | Office365
|
||||
- SharePoint
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: applicationVersion
|
||||
attributes:
|
||||
label: What is your OneDrive Application Version
|
||||
description: |
|
||||
* What is your 'onedrive' client version (`onedrive --version`)?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: applicationConfig
|
||||
attributes:
|
||||
label: What is your OneDrive Application Configuration
|
||||
description: |
|
||||
* What is your Application Configuration (`onedrive --display-config`)?
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: curlVersion
|
||||
attributes:
|
||||
label: What is your 'curl' version
|
||||
description: |
|
||||
* What is your output of (`curl --version`)?
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: syncdirLocation
|
||||
attributes:
|
||||
label: Where is your 'sync_dir' located
|
||||
description: |
|
||||
Is your 'sync_dir' a local directory or on a network mount point?
|
||||
multiple: false
|
||||
options:
|
||||
- Local
|
||||
- Network
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: mountPoints
|
||||
attributes:
|
||||
label: What are all your system 'mount points'
|
||||
description: |
|
||||
* What is your output of (`mount`)?
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: partitionTypes
|
||||
attributes:
|
||||
label: What are all your local file system partition types
|
||||
description: |
|
||||
* What is your output of (`lsblk -f`)?
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: usageDetails
|
||||
attributes:
|
||||
label: How do you use 'onedrive'
|
||||
description: |
|
||||
Explain your entire configuration setup - is the OneDrive folder shared with any other system, shared with any other platform at the same time, is the OneDrive account you use shared across multiple systems / platforms / Operating Systems and in use at the same time
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: howToReproduce
|
||||
attributes:
|
||||
label: Steps to reproduce the behaviour
|
||||
description: |
|
||||
List all the steps required to reproduce the issue.
|
||||
|
||||
If issue is replicated by a specific 'file' or 'path' please archive the file and path tree & email to support@mynas.com.au
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: applicationVerboseLog
|
||||
attributes:
|
||||
label: Complete Verbose Log Output
|
||||
description: |
|
||||
A clear and full log of the problem when running the application in the following manner (ie, not in monitor mode): (`onedrive --synchronize --verbose <any of your other needed options>`)
|
||||
|
||||
Run the application in a separate terminal window or SSH session and provide the entire application output including the error & crash.
|
||||
|
||||
Please also generate a full debug log whilst reproducing the issue as per [https://github.com/abraunegg/onedrive/wiki/Generate-debug-log-for-support](https://github.com/abraunegg/onedrive/wiki/Generate-debug-log-for-support) and email to support@mynas.com.au
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: |
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
- type: textarea
|
||||
id: otherLogs
|
||||
attributes:
|
||||
label: Other Log Information or Details
|
||||
description: |
|
||||
If applicable, add the relevant output from `dmesg` or similar.
|
||||
render: shell
|
||||
|
||||
- type: textarea
|
||||
id: additionalContext
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: |
|
||||
Add any other relevant additional context for the problem.
|
||||
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: "Have a question?"
|
||||
url: https://github.com/abraunegg/onedrive/discussions
|
||||
about: "Please do not raise a GitHub issue for asking questions - please post your question under GitHub Discussions. When opening a new discussion, please include all relevant details such as including your application version and how you installed the client. Thanks in advance for helping us keep the issue tracker clean!"
|
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when ...
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
45
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
45
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
name: "Feature Request"
|
||||
description: Suggest an idea for this project
|
||||
title: "Feature Request: "
|
||||
labels: ["Feature Request"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Suggest an idea for this project
|
||||
|
||||
- type: textarea
|
||||
id: featureProblem
|
||||
attributes:
|
||||
label: Is your feature request related to a problem? Please describe.
|
||||
description: |
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when ...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: featureSolution
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: |
|
||||
A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: featureAlternatives
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: |
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: additionalContext
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: |
|
||||
Add any other context or information about the feature request here.
|
||||
validations:
|
||||
required: false
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,3 +8,4 @@ config.log
|
|||
config.status
|
||||
autom4te.cache/
|
||||
contrib/pacman/PKGBUILD
|
||||
contrib/spec/onedrive.spec
|
||||
|
|
85
CHANGELOG.md
85
CHANGELOG.md
|
@ -2,6 +2,91 @@
|
|||
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.17 - 2022-04-30
|
||||
### Fixed
|
||||
* Fix docker build, by add missing git package for Fedora builds
|
||||
* Fix application crash when attempting to sync a broken symbolic link
|
||||
* Fix Internet connect disruption retry handling and logging output
|
||||
* Fix local folder creation timestamp with timestamp from OneDrive
|
||||
* Fix logging output when download failed
|
||||
|
||||
### Added
|
||||
* Add additional logging specifically for delete event to denote in log output the source of a deletion event when running in --monitor mode
|
||||
|
||||
### Changed
|
||||
* Improve when the local database integrity check is performed and on what frequency the database integrity check is performed
|
||||
|
||||
### Updated
|
||||
* Remove application output ambiguity on how to access 'help' for the client
|
||||
* Update logging output when running in --monitor --verbose mode in regards to the inotify events
|
||||
* Updated documentation (various)
|
||||
|
||||
## 2.4.16 - 2022-03-10
|
||||
### Fixed
|
||||
* Update application file logging error handling
|
||||
* Explicitly set libcurl options
|
||||
* Fix that when a sync_list exclusion is matched, the item needs to be excluded when using --resync
|
||||
* Fix so that application can be compiled correctly on Android hosts
|
||||
* Fix the handling of 429 and 5xx responses when they are generated by OneDrive in a self-referencing circular pattern
|
||||
* Fix applying permissions to volume directories when running in rootless podman
|
||||
* Fix unhandled errors from OneDrive when initialising subscriptions fail
|
||||
|
||||
### Added
|
||||
* Enable GitHub Sponsors
|
||||
* Implement --resync-auth to enable CLI passing in of --rsync approval
|
||||
* Add function to check client version vs latest GitHub release
|
||||
* Add --reauth to allow easy re-authentication of the client
|
||||
* Implement --modified-by to display who last modified a file and when the modification was done
|
||||
* Implement feature request to mark partially-downloaded files as .partial during download
|
||||
* Add documentation for Podman support
|
||||
|
||||
### Changed
|
||||
* Document risk regarding using --resync and force user acceptance of usage risk to proceed
|
||||
* Use YAML for Bug Reports and Feature Requests
|
||||
* Update Dockerfiles to use more modern base Linux distribution
|
||||
|
||||
### Updated
|
||||
* Updated documentation (various)
|
||||
|
||||
## 2.4.15 - 2021-12-31
|
||||
### Fixed
|
||||
* Fix unable to upload to OneDrive Business Shared Folders due to OneDrive API restricting quota information
|
||||
* Update fixing edge case with OneDrive Personal Shared Folders and --resync --upload-only
|
||||
|
||||
### Added
|
||||
* Add SystemD hardening
|
||||
* Add --operation-timeout argument
|
||||
|
||||
### Changed
|
||||
* Updated minimum compiler versions to dmd-2.087.0 and ldc-1.17.0
|
||||
|
||||
### Updated
|
||||
* Updated Dockerfile-alpine to use Apline 3.14
|
||||
* Updated documentation (various)
|
||||
|
||||
## 2.4.14 - 2021-11-24
|
||||
### Fixed
|
||||
* Support DMD 2.097.0 as compiler for Docker Builds
|
||||
* Fix getPathDetailsByDriveId query when using --dry-run and a nested path with --single-directory
|
||||
* Fix edge case when syncing OneDrive Personal Shared Folders
|
||||
* Catch unhandled API response errors when querying OneDrive Business Shared Folders
|
||||
* Catch unhandled API response errors when listing OneDrive Business Shared Folders
|
||||
* Fix error 'Key not found: remaining' with Business Shared Folders (OneDrive API change)
|
||||
* Fix overwriting local files with older versions from OneDrive when items.sqlite3 does not exist and --resync is not used
|
||||
|
||||
### Added
|
||||
* Added operation_timeout as a new configuration to assist in cases where operations take longer that 1h to complete
|
||||
* Add Real-Time syncing of remote updates via webhooks
|
||||
* Add --auth-response option and expose through entrypoint.sh for Docker
|
||||
* Add --disable-download-validation
|
||||
|
||||
### Changed
|
||||
* Always prompt for credentials for authentication rather than re-using cached browser details
|
||||
* Do not re-auth on --logout
|
||||
|
||||
### Updated
|
||||
* Updated documentation (various)
|
||||
|
||||
## 2.4.13 - 2021-7-14
|
||||
### Fixed
|
||||
* Support DMD 2.097.0 as compiler
|
||||
|
|
|
@ -78,7 +78,8 @@ SOURCES = \
|
|||
src/sync.d \
|
||||
src/upload.d \
|
||||
src/util.d \
|
||||
src/progress.d
|
||||
src/progress.d \
|
||||
src/arsd/cgi.d
|
||||
|
||||
ifeq ($(NOTIFICATIONS),yes)
|
||||
SOURCES += src/notifications/notify.d src/notifications/dnotify.d
|
||||
|
@ -106,7 +107,7 @@ onedrive: $(SOURCES)
|
|||
|
||||
install: all
|
||||
$(INSTALL) -D onedrive $(DESTDIR)$(bindir)/onedrive
|
||||
$(INSTALL) -D onedrive.1 $(DESTDIR)$(mandir)/man1/onedrive.1
|
||||
$(INSTALL) -D -m 644 onedrive.1 $(DESTDIR)$(mandir)/man1/onedrive.1
|
||||
$(INSTALL) -D -m 644 contrib/logrotate/onedrive.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/onedrive
|
||||
mkdir -p $(DESTDIR)$(docdir)
|
||||
$(INSTALL) -D -m 644 $(DOCFILES) $(DESTDIR)$(docdir)
|
||||
|
|
18
README.md
18
README.md
|
@ -9,11 +9,12 @@ A free Microsoft OneDrive Client which supports OneDrive Personal, OneDrive for
|
|||
|
||||
This powerful and highly configurable client can run on all major Linux distributions, FreeBSD, or as a Docker container. It supports one-way and two-way sync capabilities and securely connects to Microsoft OneDrive services.
|
||||
|
||||
This client is a 'fork' of the [skilion](https://github.com/skilion/onedrive) client which was abandoned in 2018.
|
||||
This client is a 'fork' of the [skilion](https://github.com/skilion/onedrive) client, which the developer has confirmed he has no desire to maintain or support the client ([reference](https://github.com/skilion/onedrive/issues/518#issuecomment-717604726)). This fork has been in active development since mid 2018.
|
||||
|
||||
## Features
|
||||
* State caching
|
||||
* Real-Time file monitoring with Inotify
|
||||
* Real-Time local file monitoring with inotify
|
||||
* Real-Time syncing of remote updates via webhooks
|
||||
* File upload / download validation to ensure data integrity
|
||||
* Resumable uploads
|
||||
* Support OneDrive for Business (part of Office 365)
|
||||
|
@ -23,12 +24,17 @@ This client is a 'fork' of the [skilion](https://github.com/skilion/onedrive) cl
|
|||
* Dry-run capability to test configuration changes
|
||||
* Prevent major OneDrive accidental data deletion after configuration change
|
||||
* Support for National cloud deployments (Microsoft Cloud for US Government, Microsoft Cloud Germany, Azure and Office 365 operated by 21Vianet in China)
|
||||
* Supports single & multi-tenanted applications
|
||||
* Supports rate limiting of traffic
|
||||
|
||||
## What's missing
|
||||
* While local changes are uploaded right away, remote changes are delayed until next automated sync cycle when using --monitor
|
||||
* Ability to encrypt/decrypt files on-the-fly when uploading/downloading files from OneDrive
|
||||
* Support for Windows 'On-Demand' functionality so file is only downloaded when accessed locally
|
||||
* A GUI for configuration management
|
||||
|
||||
## External Enhancements
|
||||
* A GUI for configuration management: [OneDrive Client for Linux GUI](https://github.com/bpozdena/OneDriveGUI)
|
||||
* 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)
|
||||
|
||||
## Frequently Asked Questions
|
||||
Refer to [Frequently Asked Questions](https://github.com/abraunegg/onedrive/wiki/Frequently-Asked-Questions)
|
||||
|
@ -69,3 +75,7 @@ Refer to [docs/national-cloud-deployments.md](https://github.com/abraunegg/onedr
|
|||
|
||||
### Docker support
|
||||
Refer to [docs/Docker.md](https://github.com/abraunegg/onedrive/blob/master/docs/Docker.md)
|
||||
|
||||
### Podman support
|
||||
Refer to [docs/Podman.md](https://github.com/abraunegg/onedrive/blob/master/docs/Podman.md)
|
||||
|
||||
|
|
10
config
10
config
|
@ -27,7 +27,7 @@
|
|||
# dry_run = "false"
|
||||
# min_notify_changes = "5"
|
||||
# monitor_log_frequency = "5"
|
||||
# monitor_fullscan_frequency = "10"
|
||||
# monitor_fullscan_frequency = "12"
|
||||
# sync_root_files = "false"
|
||||
# classify_as_big_delete = "1000"
|
||||
# user_agent = ""
|
||||
|
@ -35,6 +35,7 @@
|
|||
# skip_dir_strict_match = "false"
|
||||
# application_id = ""
|
||||
# resync = "false"
|
||||
# resync_auth = "false"
|
||||
# bypass_data_preservation = "false"
|
||||
# azure_ad_endpoint = ""
|
||||
# azure_tenant_id = "common"
|
||||
|
@ -42,3 +43,10 @@
|
|||
# sync_dir_permissions = "700"
|
||||
# sync_file_permissions = "600"
|
||||
# rate_limit = "131072"
|
||||
# operation_timeout = "3600"
|
||||
# webhook_enabled = "false"
|
||||
# webhook_public_url = ""
|
||||
# webhook_listening_host = ""
|
||||
# webhook_listening_port = "8888"
|
||||
# webhook_expiration_interval = "86400"
|
||||
# webhook_renewal_interval = "43200"
|
||||
|
|
24
configure
vendored
24
configure
vendored
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for onedrive v2.4.13.
|
||||
# Generated by GNU Autoconf 2.69 for onedrive v2.4.18-dev.
|
||||
#
|
||||
# Report bugs to <https://github.com/abraunegg/onedrive>.
|
||||
#
|
||||
|
@ -579,8 +579,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='onedrive'
|
||||
PACKAGE_TARNAME='onedrive'
|
||||
PACKAGE_VERSION='v2.4.13'
|
||||
PACKAGE_STRING='onedrive v2.4.13'
|
||||
PACKAGE_VERSION='v2.4.18-dev'
|
||||
PACKAGE_STRING='onedrive v2.4.18-dev'
|
||||
PACKAGE_BUGREPORT='https://github.com/abraunegg/onedrive'
|
||||
PACKAGE_URL=''
|
||||
|
||||
|
@ -1219,7 +1219,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures onedrive v2.4.13 to adapt to many kinds of systems.
|
||||
\`configure' configures onedrive v2.4.18-dev to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -1280,7 +1280,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of onedrive v2.4.13:";;
|
||||
short | recursive ) echo "Configuration of onedrive v2.4.18-dev:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -1393,7 +1393,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
onedrive configure v2.4.13
|
||||
onedrive configure v2.4.18-dev
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
|
@ -1410,7 +1410,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by onedrive $as_me v2.4.13, which was
|
||||
It was created by onedrive $as_me v2.4.18-dev, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -2133,7 +2133,7 @@ case $(basename $DC) in
|
|||
# remove everthing after ):
|
||||
VERSION=${VERSION%%):*}
|
||||
# now version should be something like L.M.N
|
||||
MINVERSION=1.12.0
|
||||
MINVERSION=1.17.0
|
||||
;;
|
||||
dmd)
|
||||
# DMD64 D Compiler v2.085.1\n...
|
||||
|
@ -2141,7 +2141,7 @@ case $(basename $DC) in
|
|||
VERSION=${VERSION#*Compiler v}
|
||||
VERSION=${VERSION%% *}
|
||||
# now version should be something like L.M.N
|
||||
MINVERSION=2.083.1
|
||||
MINVERSION=2.087.0
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -2162,7 +2162,7 @@ fi
|
|||
|
||||
|
||||
|
||||
PACKAGE_DATE="July 2021"
|
||||
PACKAGE_DATE="May 2022"
|
||||
|
||||
|
||||
|
||||
|
@ -3159,7 +3159,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by onedrive $as_me v2.4.13, which was
|
||||
This file was extended by onedrive $as_me v2.4.18-dev, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -3212,7 +3212,7 @@ _ACEOF
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
onedrive config.status v2.4.13
|
||||
onedrive config.status v2.4.18-dev
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
|
@ -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.13], [https://github.com/abraunegg/onedrive], [onedrive])
|
||||
AC_INIT([onedrive],[v2.4.18-dev], [https://github.com/abraunegg/onedrive], [onedrive])
|
||||
AC_CONFIG_SRCDIR([src/main.d])
|
||||
|
||||
|
||||
|
@ -104,7 +104,7 @@ case $(basename $DC) in
|
|||
# remove everthing after ):
|
||||
VERSION=${VERSION%%):*}
|
||||
# now version should be something like L.M.N
|
||||
MINVERSION=1.12.0
|
||||
MINVERSION=1.17.0
|
||||
;;
|
||||
dmd)
|
||||
# DMD64 D Compiler v2.085.1\n...
|
||||
|
@ -112,7 +112,7 @@ case $(basename $DC) in
|
|||
VERSION=${VERSION#*Compiler v}
|
||||
VERSION=${VERSION%% *}
|
||||
# now version should be something like L.M.N
|
||||
MINVERSION=2.083.1
|
||||
MINVERSION=2.087.0
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ _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 --resync --skip-dot-files --skip-symlinks --synchronize --upload-only -v --verbose --version -h --help'
|
||||
argopts='--create-directory --get-O365-drive-id --remove-directory --single-directory --source-directory'
|
||||
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'
|
||||
argopts='--create-directory --get-O365-drive-id --operation-timeout --remove-directory --single-directory --source-directory'
|
||||
|
||||
# Loop on the arguments to manage conflicting options
|
||||
for (( i=0; i < ${#COMP_WORDS[@]}-1; i++ )); do
|
||||
|
@ -27,7 +27,7 @@ _onedrive()
|
|||
_filedir
|
||||
return 0
|
||||
;;
|
||||
--create-directory|--get-O365-drive-id|--remove-directory|--single-directory|--source-directory)
|
||||
--create-directory|--get-O365-drive-id|--operation-timeout|--remove-directory|--single-directory|--source-directory)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
|
|
|
@ -22,8 +22,10 @@ complete -c onedrive -l local-first -d 'Synchronize from the local directory sou
|
|||
complete -c onedrive -l logout -d 'Logout the current user.'
|
||||
complete -c onedrive -n "not __fish_seen_subcommand_from --synchronize" -a "-m --monitor" -d 'Keep monitoring for local and remote changes.'
|
||||
complete -c onedrive -l no-remote-delete -d 'Do not delete local file deletes from OneDrive when using --upload-only.'
|
||||
complete -c onedrive -l operation-timeout -d 'Specify the maximum amount of time (in seconds) an operation is allowed to take.'
|
||||
complete -c onedrive -l print-token -d 'Print the access token, useful for debugging.'
|
||||
complete -c onedrive -l remote-directory -d 'Remove a directory on OneDrive - no sync will be performed.'
|
||||
complete -c onedrive -l reauth -d 'Reauthenticate the client with OneDrive.'
|
||||
complete -c onedrive -l resync -d 'Forget the last saved state, perform a full sync.'
|
||||
complete -c onedrive -l single-directory -d 'Specify a single local directory within the OneDrive root to sync.'
|
||||
complete -c onedrive -l skip-dot-files -d 'Skip dot files and folders from syncing.'
|
||||
|
|
|
@ -26,7 +26,9 @@ all_opts=(
|
|||
'--logout[Logout the current user]'
|
||||
'(-m --monitor)'{-m,--monitor}'[Keep monitoring for local and remote changes]'
|
||||
'--no-remote-delete[Do not delete local file deletes from OneDrive when using --upload-only]'
|
||||
'--operation-timeout[Specify the maximum amount of time (in seconds) an operation is allowed to take.]:seconds:'
|
||||
'--print-token[Print the access token, useful for debugging]'
|
||||
'--reauth[Reauthenticate the client with OneDrive]'
|
||||
'--resync[Forget the last saved state, perform a full sync]'
|
||||
'--remove-directory[Remove a directory on OneDrive - no sync will be performed.]:directory name:'
|
||||
'--single-directory[Specify a single local directory within the OneDrive root to sync.]:source directory:_files -/'
|
||||
|
|
|
@ -1,26 +1,38 @@
|
|||
FROM centos:7
|
||||
ENV GOSU_VERSION=1.11
|
||||
# -*-Dockerfile-*-
|
||||
|
||||
ARG FEDORA_VERSION=35
|
||||
ARG DEBIAN_VERSION=bullseye
|
||||
ARG GO_VERSION=1.17
|
||||
ARG GOSU_VERSION=1.14
|
||||
|
||||
FROM golang:${GO_VERSION}-${DEBIAN_VERSION} AS builder-gosu
|
||||
ARG GOSU_VERSION
|
||||
RUN go install -ldflags "-s -w" github.com/tianon/gosu@${GOSU_VERSION}
|
||||
|
||||
FROM fedora:${FEDORA_VERSION} AS builder-onedrive
|
||||
|
||||
RUN dnf install -y ldc pkgconf libcurl-devel sqlite-devel git
|
||||
|
||||
ENV PKG_CONFIG=/usr/bin/pkgconf
|
||||
|
||||
RUN yum install -y make git gcc libcurl-devel sqlite-devel pkg-config && \
|
||||
yum install -y http://downloads.dlang.org/releases/2.x/2.092.1/dmd-2.092.1-0.fedora.x86_64.rpm && \
|
||||
rm -rf /var/cache/yum/ && \
|
||||
# gosu installation
|
||||
gpg --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
|
||||
&& curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64" \
|
||||
&& curl -o /usr/local/bin/gosu.asc -SL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64.asc" \
|
||||
&& gpg --verify /usr/local/bin/gosu.asc \
|
||||
&& rm /usr/local/bin/gosu.asc \
|
||||
&& rm -r /root/.gnupg/ \
|
||||
&& chmod +x /usr/local/bin/gosu \
|
||||
&& gosu nobody true
|
||||
RUN mkdir -p /onedrive/conf /onedrive/data
|
||||
COPY . /usr/src/onedrive
|
||||
WORKDIR /usr/src/onedrive
|
||||
RUN ./configure && \
|
||||
make clean && \
|
||||
make && \
|
||||
make install
|
||||
COPY contrib/docker/entrypoint.sh /entrypoint.sh
|
||||
VOLUME ["/onedrive/conf"]
|
||||
|
||||
RUN ./configure \
|
||||
&& make clean \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
FROM fedora:${FEDORA_VERSION}
|
||||
|
||||
RUN dnf install -y libcurl sqlite ldc-libs \
|
||||
&& dnf clean all \
|
||||
&& mkdir -p /onedrive/conf /onedrive/data
|
||||
|
||||
COPY --from=builder-gosu /go/bin/gosu /usr/local/bin/
|
||||
COPY --from=builder-onedrive /usr/local/bin/onedrive /usr/local/bin/
|
||||
|
||||
COPY contrib/docker/entrypoint.sh /
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
# -*-Dockerfile-*-
|
||||
FROM debian:stretch
|
||||
RUN apt update && \
|
||||
apt install -y build-essential curl libcurl4-openssl-dev libsqlite3-dev pkg-config wget git
|
||||
RUN wget https://github.com/ldc-developers/ldc/releases/download/v1.16.0/ldc2-1.16.0-linux-aarch64.tar.xz && \
|
||||
tar -xvf ldc2-1.16.0-linux-aarch64.tar.xz
|
||||
COPY . /usr/src/onedrive
|
||||
RUN cd /usr/src/onedrive/ && \
|
||||
./configure DC=/ldc2-1.16.0-linux-aarch64/bin/ldmd2 && \
|
||||
make clean && \
|
||||
make && \
|
||||
make install
|
||||
|
||||
FROM debian:stretch-slim
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
RUN apt update && \
|
||||
apt install -y gosu libcurl3 libsqlite3-0 && \
|
||||
rm -rf /var/*/apt && \
|
||||
mkdir -p /onedrive/conf /onedrive/data
|
||||
COPY contrib/docker/entrypoint.sh /
|
||||
COPY --from=0 /usr/local/bin/onedrive /usr/local/bin/
|
|
@ -1,21 +1,35 @@
|
|||
# -*-Dockerfile-*-
|
||||
FROM alpine:3.13
|
||||
RUN apk add \
|
||||
alpine-sdk gnupg xz curl-dev sqlite-dev binutils-gold \
|
||||
autoconf automake ldc go
|
||||
RUN go get github.com/tianon/gosu
|
||||
COPY . /usr/src/onedrive
|
||||
RUN cd /usr/src/onedrive/ && \
|
||||
autoreconf -fiv && \
|
||||
./configure && \
|
||||
make clean && \
|
||||
make && \
|
||||
make install
|
||||
|
||||
FROM alpine:3.13
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
RUN apk add --no-cache \
|
||||
bash libcurl libgcc shadow sqlite-libs ldc-runtime && \
|
||||
mkdir -p /onedrive/conf /onedrive/data
|
||||
ARG ALPINE_VERSION=3.15
|
||||
ARG GO_VERSION=1.17
|
||||
ARG GOSU_VERSION=1.14
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS builder-gosu
|
||||
ARG GOSU_VERSION
|
||||
RUN go install -ldflags "-s -w" github.com/tianon/gosu@${GOSU_VERSION}
|
||||
|
||||
FROM alpine:${ALPINE_VERSION} AS builder-onedrive
|
||||
|
||||
RUN apk add --update --no-cache alpine-sdk gnupg xz curl-dev sqlite-dev binutils-gold autoconf automake ldc
|
||||
|
||||
COPY . /usr/src/onedrive
|
||||
WORKDIR /usr/src/onedrive
|
||||
|
||||
RUN autoreconf -fiv \
|
||||
&& ./configure \
|
||||
&& make clean \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
FROM alpine:${ALPINE_VERSION}
|
||||
|
||||
RUN apk add --update --no-cache bash libcurl libgcc shadow sqlite-libs ldc-runtime \
|
||||
&& mkdir -p /onedrive/conf /onedrive/data
|
||||
|
||||
COPY --from=builder-gosu /go/bin/gosu /usr/local/bin/
|
||||
COPY --from=builder-onedrive /usr/local/bin/onedrive /usr/local/bin/
|
||||
|
||||
COPY contrib/docker/entrypoint.sh /
|
||||
COPY --from=0 /root/go/bin/gosu /usr/local/bin/onedrive /usr/local/bin/
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
|
54
contrib/docker/Dockerfile-debian
Normal file
54
contrib/docker/Dockerfile-debian
Normal file
|
@ -0,0 +1,54 @@
|
|||
# -*-Dockerfile-*-
|
||||
|
||||
ARG DEBIAN_VERSION=bullseye
|
||||
ARG LDC_VERSION_MAIN=1.28.1
|
||||
|
||||
FROM debian:${DEBIAN_VERSION} AS builder-onedrive
|
||||
ARG LDC_VERSION_MAIN
|
||||
|
||||
RUN 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 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN ARCH="$(dpkg --print-architecture)" \
|
||||
&& case "${ARCH}" in \
|
||||
aarch64|arm64) \
|
||||
BINARY_URL="https://github.com/ldc-developers/ldc/releases/download/v${LDC_VERSION_MAIN}/ldc2-${LDC_VERSION_MAIN}-linux-aarch64.tar.xz"; \
|
||||
;; \
|
||||
amd64|x86-64) \
|
||||
BINARY_URL="https://github.com/ldc-developers/ldc/releases/download/v${LDC_VERSION_MAIN}/ldc2-${LDC_VERSION_MAIN}-linux-x86_64.tar.xz"; \
|
||||
;; \
|
||||
*) \
|
||||
echo "Unsupported arch: ${ARCH}"; \
|
||||
exit 1; \
|
||||
;; \
|
||||
esac \
|
||||
&& echo ${BINARY_URL} \
|
||||
&& curl -k -LfsSo /tmp/ldc.tar.xz ${BINARY_URL} \
|
||||
&& mkdir -p /opt/ldc \
|
||||
&& tar -xvf /tmp/ldc.tar.xz -C /opt/ldc --strip-components=1 \
|
||||
&& rm -rf /tmp/ldc.tar.xz
|
||||
|
||||
COPY . /usr/src/onedrive
|
||||
WORKDIR /usr/src/onedrive
|
||||
|
||||
RUN ./configure DC=/opt/ldc/bin/ldmd2 \
|
||||
&& make clean \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
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 \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
# Fix bug with ssl on armhf: https://serverfault.com/a/1045189
|
||||
&& /usr/bin/c_rehash \
|
||||
&& mkdir -p /onedrive/conf /onedrive/data
|
||||
|
||||
COPY --from=builder-onedrive /usr/local/bin/onedrive /usr/local/bin/
|
||||
|
||||
COPY contrib/docker/entrypoint.sh /
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
|
@ -1,21 +1,51 @@
|
|||
# -*-Dockerfile-*-
|
||||
FROM debian:stretch
|
||||
RUN apt update && \
|
||||
apt install -y build-essential curl libcurl4-openssl-dev libsqlite3-dev pkg-config wget git
|
||||
RUN wget https://github.com/ldc-developers/ldc/releases/download/v1.16.0/ldc2-1.16.0-linux-armhf.tar.xz && \
|
||||
tar -xvf ldc2-1.16.0-linux-armhf.tar.xz
|
||||
COPY . /usr/src/onedrive
|
||||
RUN cd /usr/src/onedrive/ && \
|
||||
./configure DC=/ldc2-1.16.0-linux-armhf/bin/ldmd2 && \
|
||||
make clean && \
|
||||
make && \
|
||||
make install
|
||||
|
||||
FROM debian:stretch-slim
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
RUN apt update && \
|
||||
apt install -y gosu libcurl3 libsqlite3-0 && \
|
||||
rm -rf /var/*/apt && \
|
||||
mkdir -p /onedrive/conf /onedrive/data
|
||||
ARG DEBIAN_VERSION=buster
|
||||
ARG LDC_VERSION_MAIN=1.17.0
|
||||
|
||||
FROM debian:${DEBIAN_VERSION} AS builder-onedrive
|
||||
ARG LDC_VERSION_MAIN
|
||||
|
||||
RUN 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 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN ARCH="$(dpkg --print-architecture)" \
|
||||
&& case "${ARCH}" in \
|
||||
armhf|arm) \
|
||||
BINARY_URL="https://github.com/ldc-developers/ldc/releases/download/v${LDC_VERSION_MAIN}/ldc2-${LDC_VERSION_MAIN}-linux-aarch64.tar.xz"; \
|
||||
;; \
|
||||
*) \
|
||||
echo "Unsupported arch: ${ARCH}"; \
|
||||
exit 1; \
|
||||
;; \
|
||||
esac \
|
||||
&& echo ${BINARY_URL} \
|
||||
&& curl -k -LfsSo /tmp/ldc.tar.xz ${BINARY_URL} \
|
||||
&& mkdir -p /opt/ldc \
|
||||
&& tar -xvf /tmp/ldc.tar.xz -C /opt/ldc --strip-components=1 \
|
||||
&& rm -rf /tmp/ldc.tar.xz
|
||||
|
||||
COPY . /usr/src/onedrive
|
||||
WORKDIR /usr/src/onedrive
|
||||
|
||||
RUN ./configure DC=/opt/ldc/bin/ldmd2 \
|
||||
&& make clean \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
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 \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
# Fix bug with ssl on armhf: https://serverfault.com/a/1045189
|
||||
&& /usr/bin/c_rehash \
|
||||
&& mkdir -p /onedrive/conf /onedrive/data
|
||||
|
||||
COPY --from=builder-onedrive /usr/local/bin/onedrive /usr/local/bin/
|
||||
|
||||
COPY contrib/docker/entrypoint.sh /
|
||||
COPY --from=0 /usr/local/bin/onedrive /usr/local/bin/
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
# -*-Dockerfile-*-
|
||||
FROM debian:stretch
|
||||
RUN apt update && \
|
||||
apt install -y build-essential curl libcurl4-openssl-dev libsqlite3-dev pkg-config git wget
|
||||
RUN wget http://downloads.dlang.org/releases/2.x/2.092.1/dmd_2.092.1-0_amd64.deb -O /tmp/dmd_amd64.deb && \
|
||||
dpkg -i /tmp/dmd_amd64.deb
|
||||
RUN rm -f /tmp/dmd_amd64.deb
|
||||
|
||||
COPY . /usr/src/onedrive
|
||||
RUN cd /usr/src/onedrive/ && \
|
||||
./configure && \
|
||||
make clean && \
|
||||
make && \
|
||||
make install
|
||||
|
||||
FROM debian:stretch-slim
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
RUN apt update && \
|
||||
apt install -y gosu libcurl3 libsqlite3-0 && \
|
||||
rm -rf /var/*/apt && \
|
||||
mkdir -p /onedrive/conf /onedrive/data
|
||||
COPY contrib/docker/entrypoint.sh /
|
||||
COPY --from=0 /usr/local/bin/onedrive /usr/local/bin/
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
set +H -xeuo pipefail
|
||||
set +H -euo pipefail
|
||||
|
||||
: ${ONEDRIVE_UID:=$(stat /onedrive/data -c '%u')}
|
||||
: ${ONEDRIVE_GID:=$(stat /onedrive/data -c '%g')}
|
||||
|
@ -23,50 +23,82 @@ else
|
|||
grep -qv root <( groups "${oduser}" ) || { echo 'ROOT level privileges prohibited!'; exit 1; }
|
||||
fi
|
||||
|
||||
chown "${oduser}:${odgroup}" /onedrive/ /onedrive/conf
|
||||
|
||||
# Default parameters
|
||||
ARGS=(--monitor --confdir /onedrive/conf --syncdir /onedrive/data)
|
||||
echo "Base Args: ${ARGS}"
|
||||
|
||||
# Make Verbose output optional, based on an environment variable
|
||||
if [ "${ONEDRIVE_VERBOSE:=0}" == "1" ]; then
|
||||
echo "# We are being verbose"
|
||||
echo "# Adding --verbose"
|
||||
ARGS=(--verbose ${ARGS[@]})
|
||||
fi
|
||||
|
||||
# Tell client to perform debug output, based on an environment variable
|
||||
if [ "${ONEDRIVE_DEBUG:=0}" == "1" ]; then
|
||||
echo "# We are performing debug output"
|
||||
echo "# Adding --verbose --verbose"
|
||||
ARGS=(--verbose --verbose ${ARGS[@]})
|
||||
fi
|
||||
|
||||
# Tell client to perform HTTPS debug output, based on an environment variable
|
||||
if [ "${ONEDRIVE_DEBUG_HTTPS:=0}" == "1" ]; then
|
||||
echo "# We are performing HTTPS debug output"
|
||||
echo "# Adding --debug-https"
|
||||
ARGS=(--debug-https ${ARGS[@]})
|
||||
fi
|
||||
|
||||
# Tell client to perform a resync based on environment variable
|
||||
if [ "${ONEDRIVE_RESYNC:=0}" == "1" ]; then
|
||||
echo "# We are performing a --resync"
|
||||
ARGS=(--resync ${ARGS[@]})
|
||||
echo "# Adding --resync --resync-auth"
|
||||
ARGS=(--resync --resync-auth ${ARGS[@]})
|
||||
fi
|
||||
|
||||
# Tell client to sync in download-only mode based on environment variable
|
||||
if [ "${ONEDRIVE_DOWNLOADONLY:=0}" == "1" ]; then
|
||||
echo "# We are synchronizing in download-only mode"
|
||||
echo "# Adding --download-only"
|
||||
ARGS=(--download-only ${ARGS[@]})
|
||||
fi
|
||||
|
||||
# Tell client to logout based on environment variable
|
||||
if [ "${ONEDRIVE_LOGOUT:=0}" == "1" ]; then
|
||||
echo "# We are logging out to perform a reauthentication"
|
||||
echo "# We are logging out"
|
||||
echo "# Adding --logout"
|
||||
ARGS=(--logout ${ARGS[@]})
|
||||
fi
|
||||
|
||||
# Tell client to re-authenticate based on environment variable
|
||||
if [ "${ONEDRIVE_REAUTH:=0}" == "1" ]; then
|
||||
echo "# We are logging out to perform a reauthentication"
|
||||
echo "# Adding --reauth"
|
||||
ARGS=(--reauth ${ARGS[@]})
|
||||
fi
|
||||
|
||||
# Tell client to utilize auth files at the provided locations based on environment variable
|
||||
if [ -n "${ONEDRIVE_AUTHFILES:=""}" ]; then
|
||||
echo "# We are using auth files to perform authentication"
|
||||
echo "# Adding --auth-files ARG"
|
||||
ARGS=(--auth-files ${ONEDRIVE_AUTHFILES} ${ARGS[@]})
|
||||
fi
|
||||
|
||||
# Tell client to utilize provided auth reponse based on environment variable
|
||||
if [ -n "${ONEDRIVE_AUTHRESPONSE:=""}" ]; then
|
||||
echo "# We are providing the auth response directly to perform authentication"
|
||||
echo "# Adding --auth-response ARG"
|
||||
ARGS=(--auth-response \"${ONEDRIVE_AUTHRESPONSE}\" ${ARGS[@]})
|
||||
fi
|
||||
|
||||
if [ ${#} -gt 0 ]; then
|
||||
ARGS=("${@}")
|
||||
fi
|
||||
|
||||
echo "# Launching onedrive"
|
||||
# Only switch user if not running as target uid (ie. Docker)
|
||||
if [ "$ONEDRIVE_UID" = "$(id -u)" ]; then
|
||||
/usr/local/bin/onedrive "${ARGS[@]}"
|
||||
else
|
||||
chown "${oduser}:${odgroup}" /onedrive/data /onedrive/conf
|
||||
exec gosu "${oduser}" /usr/local/bin/onedrive "${ARGS[@]}"
|
||||
fi
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
%endif
|
||||
|
||||
Name: onedrive
|
||||
Version: 2.4.13
|
||||
Version: 2.4.17
|
||||
Release: 1%{?dist}
|
||||
Summary: Microsoft OneDrive Client
|
||||
Group: System Environment/Network
|
||||
|
@ -15,7 +15,7 @@ URL: https://github.com/abraunegg/onedrive
|
|||
Source0: v%{version}.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
BuildRequires: dmd >= 2.083.0
|
||||
BuildRequires: dmd >= 2.087.0
|
||||
BuildRequires: sqlite-devel >= 3.7.15
|
||||
BuildRequires: libcurl-devel
|
||||
Requires: sqlite >= 3.7.15
|
||||
|
|
|
@ -5,6 +5,17 @@ After=network-online.target
|
|||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
# Commented out hardenings are disabled because they don't work out of the box.
|
||||
# If you know what you are doing please try to enable them.
|
||||
ProtectSystem=full
|
||||
#PrivateDevices=true
|
||||
ProtectHostname=true
|
||||
#ProtectClock=true
|
||||
ProtectKernelTunables=true
|
||||
#ProtectKernelModules=true
|
||||
#ProtectKernelLogs=true
|
||||
ProtectControlGroups=true
|
||||
RestrictRealtime=true
|
||||
ExecStart=@prefix@/bin/onedrive --monitor
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
|
|
|
@ -5,6 +5,17 @@ After=network-online.target
|
|||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
# Commented out hardenings are disabled because they don't work out of the box.
|
||||
# If you know what you are doing please try to enable them.
|
||||
ProtectSystem=full
|
||||
#PrivateDevices=true
|
||||
ProtectHostname=true
|
||||
#ProtectClock=true
|
||||
ProtectKernelTunables=true
|
||||
#ProtectKernelModules=true
|
||||
#ProtectKernelLogs=true
|
||||
ProtectControlGroups=true
|
||||
RestrictRealtime=true
|
||||
ExecStart=@prefix@/bin/onedrive --monitor --confdir=/home/%i/.config/onedrive
|
||||
User=%i
|
||||
Group=users
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# 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:
|
||||
1. Container based on CentOS 7 - Docker Tag: latest
|
||||
2. Container based on Debian Stretch - Docker Tag: stretch
|
||||
1. Container based on Fedora 35 - Docker Tag: latest
|
||||
2. Container based on Debian 11 - Docker Tag: debian
|
||||
3. Container based on Alpine Linux - Docker Tag: alpine
|
||||
|
||||
These containers offer a simple monitoring-mode service for the OneDrive Client for Linux.
|
||||
|
@ -10,8 +10,7 @@ The instructions below have been validated on:
|
|||
* Red Hat Enterprise Linux 8.x
|
||||
* Ubuntu Server 20.04
|
||||
|
||||
The instructions below will utilise the 'latest' tag, however this can be substituted for 'stretch' or 'alpine' if desired.
|
||||
|
||||
The instructions below will utilise the 'latest' tag, however this can be substituted for 'debian' or 'alpine' if desired.
|
||||
|
||||
## Basic Setup
|
||||
### 0. Install docker using your distribution platform's instructions
|
||||
|
@ -59,18 +58,29 @@ Run the docker image with the commands below and make sure to change `ONEDRIVE_D
|
|||
```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
|
||||
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
|
||||
```
|
||||
**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.
|
||||
|
||||
**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:**
|
||||
```
|
||||
docker run -it --name onedrive -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" -e "ONEDRIVE_UID:1000" -e "ONEDRIVE_GID:1000" driveone/onedrive:latest
|
||||
```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
|
||||
```
|
||||
|
||||
When the Docker container successfully starts:
|
||||
|
@ -162,13 +172,15 @@ docker run -it --restart unless-stopped --name onedrive_Work -v onedrive_conf_Wo
|
|||
If you are experienced with docker and onedrive, you can use the following script:
|
||||
|
||||
```bash
|
||||
# Update ONEDRIVE_DATA_DIR with correct existing OneDrive directory path
|
||||
# Update ONEDRIVE_DATA_DIR with correct OneDrive directory path
|
||||
ONEDRIVE_DATA_DIR="${HOME}/OneDrive"
|
||||
# Create directory if non-existant
|
||||
mkdir -p ${ONEDRIVE_DATA_DIR}
|
||||
|
||||
firstRun='-d'
|
||||
docker pull driveone/onedrive:latest
|
||||
docker inspect onedrive_conf > /dev/null || { docker volume create onedrive_conf; firstRun='-it'; }
|
||||
docker inspect onedrive > /dev/null && docker rm -f onedrive
|
||||
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
|
||||
```
|
||||
|
||||
|
@ -184,6 +196,9 @@ 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_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) |
|
||||
|
||||
### Usage Examples
|
||||
**Verbose Output:**
|
||||
|
@ -238,14 +253,14 @@ docker build . -t local-onedrive -f contrib/docker/Dockerfile
|
|||
```
|
||||
|
||||
There are alternate, smaller images available by building
|
||||
Dockerfile-stretch or Dockerfile-alpine. These [multi-stage builder
|
||||
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 Stretch
|
||||
#### How to build and run a custom Docker image based on Debian
|
||||
``` bash
|
||||
docker build . -t local-ondrive-stretch -f contrib/docker/Dockerfile-stretch
|
||||
docker container run -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/onedrive/data" local-ondrive-stretch:latest
|
||||
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
|
||||
|
@ -268,6 +283,6 @@ docker container run -v onedrive_conf:/onedrive/conf -v "${ONEDRIVE_DATA_DIR}:/o
|
|||
|
||||
#### How to build and run a custom Docker image for AARCH64 Platforms
|
||||
``` bash
|
||||
docker build . -t local-onedrive-aarch64 -f contrib/docker/Dockerfile-aarch64
|
||||
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
|
||||
```
|
||||
|
|
|
@ -1,31 +1,33 @@
|
|||
# Installing from Distribution Packages or Building the OneDrive Client for Linux from source
|
||||
# Installing or Upgrading using Distribution Packages or Building the OneDrive Client for Linux from source
|
||||
|
||||
## Installing from Distribution Packages
|
||||
## Installing or Upgrading using Distribution Packages
|
||||
This project has been packaged for the following Linux distributions as per below. The current client release is: [![Version](https://img.shields.io/github/v/release/abraunegg/onedrive)](https://github.com/abraunegg/onedrive/releases)
|
||||
|
||||
Only the current release version or greater is supported.
|
||||
Only the current release version or greater is supported. Earlier versions are not supported and should not be installed or used.
|
||||
|
||||
#### Important Note:
|
||||
Distribution packages may be of an older release when compared to the latest release that is [available](https://github.com/abraunegg/onedrive/releases). If a package is out of date, please contact the package maintainer for resolution.
|
||||
Distribution packages may be of an older release when compared to the latest release that is [available](https://github.com/abraunegg/onedrive/releases). If any package version indicator below is ![#f03c15](https://via.placeholder.com/15/f03c15/000000?text=+) for your distribution, it is recommended that you build from source. Do not install the software from the available distribution package. If a package is out of date, please contact the package maintainer for resolution.
|
||||
|
||||
| Distribution | Package Name & Package Link | PKG_Version | i686 | x86_64 | ARMHF | AARCH64 | Extra Details |
|
||||
|---------------------------------|------------------------------------------------------------------------------|:---------------:|:----:|:------:|:-----:|:-------:|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 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>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/> | |
|
||||
| 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>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/> | 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_testing/onedrive.svg?header=" alt="Debian Testing package" width="46" height="20"></a>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>| |
|
||||
| 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>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>| |
|
||||
| Gentoo | [onedrive](https://gpo.zugaina.org/net-misc/onedrive) | No API Available |<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>| |
|
||||
| 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>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>| 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>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>| |
|
||||
| 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>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>| |
|
||||
| Slackware | [onedrive](https://slackbuilds.org/repository/14.2/network/onedrive/) |<a href="https://slackbuilds.org/repository/14.2/network/onedrive/"><img src="https://repology.org/badge/version-for-repo/slackbuilds/onedrive.svg?header=" alt="SlackBuilds package" width="46" height="20"></a>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>| |
|
||||
| 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>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>| |
|
||||
| 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>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>| |
|
||||
| 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>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>| |
|
||||
| Ubuntu 20.10 | [onedrive](https://packages.ubuntu.com/groovy/onedrive) |<a href="https://packages.ubuntu.com/groovy/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_20_10/onedrive.svg?header=" alt="Ubuntu 20.10 package" width="46" height="20"></a>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>| |
|
||||
| Ubuntu 21.04 | [onedrive](https://packages.ubuntu.com/hirsute/onedrive) |<a href="https://packages.ubuntu.com/hirsute/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_21_04/onedrive.svg?header=" alt="Ubuntu 21.04 package" width="46" height="20"></a>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>| |
|
||||
| Ubuntu PPA | [onedrive](https://launchpad.net/~yann1ck/+archive/ubuntu/onedrive) |<a href="https://launchpad.net/~yann1ck/+archive/ubuntu/onedrive"><img src="https://repology.org/badge/version-for-repo/debian_testing/onedrive.svg?header=" alt="Ubuntu PPA package" width="46" height="20"></a> |<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>| Install via the Ubuntu PPA Archive:<br><br>`sudo add-apt-repository ppa:yann1ck/onedrive`<br>`sudo apt-get update`<br>`sudo apt install onedrive`|
|
||||
| Void Linux | [onedrive](https://voidlinux.org/packages/) |<a href="https://voidlinux.org/packages/"><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>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/tick.gif" alt="supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>|<img src="./images/cross.gif" alt="not_supported" width="39" height="39"/>| |
|
||||
| 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>|✔|✔|✔|✔| It is recommended that for Debian 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> |❌|✔|❌|❌| |
|
||||
| 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 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:** You must compile from source for Raspbian |
|
||||
| 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>Install from OpenSuSE Build Service using the Ubuntu Package Install [Instructions](ubuntu-package-install.md) |
|
||||
| Ubuntu 21.04 | [onedrive](https://packages.ubuntu.com/hirsute/onedrive) |<a href="https://packages.ubuntu.com/hirsute/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_21_04/onedrive.svg?header=" alt="Ubuntu 21.04 package" width="46" height="20"></a> |❌|✔|✔|✔| **Note:** Do not install from Ubuntu Universe<br><br>Install from OpenSuSE Build Service using the Ubuntu Package Install [Instructions](ubuntu-package-install.md) |
|
||||
| Ubuntu 21.10 | [onedrive](https://packages.ubuntu.com/impish/onedrive) |<a href="https://packages.ubuntu.com/impish/onedrive"><img src="https://repology.org/badge/version-for-repo/ubuntu_21_10/onedrive.svg?header=" alt="Ubuntu 21.10 package" width="46" height="20"></a> |❌|✔|✔|✔| **Note:** Do not install from Ubuntu Universe<br><br>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>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:
|
||||
This information is specifically for the following platforms and distributions:
|
||||
|
@ -35,9 +37,9 @@ This information is specifically for the following platforms and distributions:
|
|||
* POP OS
|
||||
* Peppermint OS
|
||||
|
||||
Whilst there are [onedrive](https://packages.ubuntu.com/search?keywords=onedrive&searchon=names&suite=all§ion=all) packages available for Ubuntu, do not install 'onedrive' from these packages via `apt install onedrive` without using the above PPA. The default Ubuntu Universe packages are out-of-date and should not be used. If you wish to use a package, it is highly recommended that you utilise the Ubuntu PPA listed above. If the Ubuntu PPA does not support your distribution or version, your only option is to compile from source using the relevant Ubuntu instructions below.
|
||||
Whilst there are [onedrive](https://packages.ubuntu.com/search?keywords=onedrive&searchon=names&suite=all§ion=all) Universe packages available for Ubuntu, do not install 'onedrive' from these Universe packages. The default Universe packages are out-of-date and are not supported and should not be used. If you wish to use a package, it is highly recommended that you utilise the [OpenSuSE Build Service](ubuntu-package-install.md) to install packages for these platforms. If the OpenSuSE Build Service does not cater for your version, your only option is to build from source.
|
||||
|
||||
If you wish to change this situation so that you can just use 'apt install onedrive', consider becoming the Ubuntu package maintainer and contribute back to the community.
|
||||
If you wish to change this situation so that you can just use the Universe packages via 'apt install onedrive', consider becoming the Ubuntu package maintainer and contribute back to your community.
|
||||
|
||||
## Building from Source - High Level Requirements
|
||||
* Build environment must have at least 1GB of memory & 1GB swap space
|
||||
|
@ -46,7 +48,7 @@ If you wish to change this situation so that you can just use 'apt install onedr
|
|||
* [SQLite 3](https://www.sqlite.org/) >= 3.7.15
|
||||
* [Digital Mars D Compiler (DMD)](http://dlang.org/download.html) or [LDC – the LLVM-based D Compiler](https://github.com/ldc-developers/ldc)
|
||||
|
||||
**Note:** DMD version >= 2.083.1 or LDC version >= 1.12.0 is required to compile this application
|
||||
**Note:** DMD version >= 2.087.0 or LDC version >= 1.17.0 is required to compile this application
|
||||
|
||||
### Example for installing DMD Compiler
|
||||
```text
|
||||
|
@ -114,7 +116,7 @@ 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 19.x, Ubuntu 20.x / Debian 9, Debian 10 - x86_64
|
||||
### Dependencies: Ubuntu 18.x -> Ubuntu 22.x / Debian 9 -> Debian 11 - x86_64
|
||||
These dependencies are also applicable for all Ubuntu based distributions such as:
|
||||
* Lubuntu
|
||||
* Linux Mint
|
||||
|
@ -267,13 +269,13 @@ sudo zypper install libnotify-devel
|
|||
### Building using DMD Reference Compiler
|
||||
Before cloning and compiling, if you have installed DMD via curl for your OS, you will need to activate DMD as per example below:
|
||||
```text
|
||||
Run `source ~/dlang/dmd-2.081.1/activate` in your shell to use dmd-2.081.1.
|
||||
Run `source ~/dlang/dmd-2.087.0/activate` in your shell to use dmd-2.087.0.
|
||||
This will setup PATH, LIBRARY_PATH, LD_LIBRARY_PATH, DMD, DC, and PS1.
|
||||
Run `deactivate` later on to restore your environment.
|
||||
```
|
||||
Without performing this step, the compilation process will fail.
|
||||
|
||||
**Note:** Depending on your DMD version, substitute `2.081.1` above with your DMD version that is installed.
|
||||
**Note:** Depending on your DMD version, substitute `2.087.0` above with your DMD version that is installed.
|
||||
|
||||
```text
|
||||
git clone https://github.com/abraunegg/onedrive.git
|
||||
|
@ -323,15 +325,28 @@ make clean; make
|
|||
sudo make install
|
||||
```
|
||||
|
||||
## Uninstall
|
||||
## Uninstalling the client
|
||||
From within your GitHub repository clone, perform the following to remove the 'onedrive' binary:
|
||||
```text
|
||||
sudo make uninstall
|
||||
# delete the application state
|
||||
```
|
||||
|
||||
If you are not upgrading your client, to remove your application state and configuration, perform the following additional step:
|
||||
```
|
||||
rm -rf ~/.config/onedrive
|
||||
```
|
||||
If you are using the `--confdir option`, substitute `~/.config/onedrive` above for that directory.
|
||||
**Note:** If you are using the `--confdir option`, substitute `~/.config/onedrive` above for that directory.
|
||||
|
||||
If you want to just delete the application key, but keep the items database:
|
||||
```text
|
||||
rm -f ~/.config/onedrive/refresh_token
|
||||
```
|
||||
|
||||
## Upgrading the client
|
||||
If you have installed the client from a distribution package, the client will be updated when the distribution package is updated by the package maintainer and will be updated to the new application version when you perform your package update.
|
||||
|
||||
If you have built the client from source, to upgrade your client, you must first uninstall your existing 'onedrive' binary (see above), then re-install the client by re-cloning, re-compiling and re-installing the client again to install the new version.
|
||||
|
||||
To confirm you have the new version installed, use `onedrive --version` to determine the version that is now installed.
|
||||
|
||||
|
||||
|
|
272
docs/Podman.md
Normal file
272
docs/Podman.md
Normal file
|
@ -0,0 +1,272 @@
|
|||
# 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 35 - Docker Tag: latest
|
||||
2. Container based on Debian 11 - Docker Tag: debian
|
||||
3. Container based on Alpine Linux - Docker Tag: alpine
|
||||
|
||||
These containers offer a simple monitoring-mode service for the OneDrive Client for Linux.
|
||||
|
||||
The instructions below have been validated on:
|
||||
* Fedora 35
|
||||
|
||||
The instructions below will utilise the 'latest' tag, however this can be substituted for 'stretch' 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.
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
**NOTE:** SELinux context needs to be configured or disabled for Podman to be able to write to OneDrive host directory.
|
||||
|
||||
### 1.1 Prepare data volume
|
||||
The container requries 2 Podman volumes:
|
||||
* 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 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
|
||||
|
||||
**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 Podman container will fail to start with the following error message:
|
||||
```bash
|
||||
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.
|
||||
|
||||
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 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`).
|
||||
|
||||
```bash
|
||||
export ONEDRIVE_DATA_DIR="${HOME}/OneDrive"
|
||||
export ONEDRIVE_UID=1000
|
||||
export ONEDRIVE_GID=1000
|
||||
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
|
||||
```
|
||||
**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.**
|
||||
|
||||
The run command would look instead look like as follows:
|
||||
```
|
||||
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" \
|
||||
-e PODMAN=1 \
|
||||
--label "io.containers.autoupdate=image"
|
||||
driveone/onedrive:latest
|
||||
```
|
||||
|
||||
When the Podman container successfully starts:
|
||||
* You will be asked to open a specific link using your web browser
|
||||
* Login to your Microsoft Account and give the application the permission
|
||||
* After giving the permission, you will be redirected to a blank page
|
||||
* Copy the URI of the blank page into the application prompt to authorise the application
|
||||
|
||||
Once the 'onedrive' application is authorised, the client will automatically start monitoring your `ONEDRIVE_DATA_DIR` for data changes to be uploaded to OneDrive. Files stored on OneDrive will be downloaded to this location.
|
||||
|
||||
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
|
||||
|
||||
```bash
|
||||
podman ps -f name=onedrive
|
||||
```
|
||||
|
||||
Show monitor run logs
|
||||
|
||||
```bash
|
||||
podman logs onedrive
|
||||
```
|
||||
|
||||
Stop running monitor
|
||||
|
||||
```bash
|
||||
podman stop onedrive
|
||||
```
|
||||
|
||||
Resume monitor
|
||||
|
||||
```bash
|
||||
podman start onedrive
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
cd /tmp
|
||||
podman generate systemd --new --restart-policy on-failure --name -f onedrive
|
||||
/tmp/container-onedrive.service
|
||||
|
||||
# copy the generated systemd unit file to the systemd path and reload the daemon
|
||||
|
||||
cp -Z ~/container-onedrive.service /usr/lib/systemd/system
|
||||
systemctl daemon-reload
|
||||
|
||||
#optionally enable it to startup on boot
|
||||
|
||||
systemctl enable container-onedrive.service
|
||||
|
||||
#check status
|
||||
|
||||
systemctl status container-onedrive
|
||||
|
||||
#start/stop/restart container as a systemd service
|
||||
|
||||
systemctl stop container-onedrive
|
||||
systemctl start container-onedrive
|
||||
```
|
||||
|
||||
To update the image using podman (Ad-hoc)
|
||||
```
|
||||
podman auto-update
|
||||
```
|
||||
|
||||
To update the image using systemd (Automatic/Scheduled)
|
||||
```
|
||||
# Enable the podman-auto-update.timer service at system start:
|
||||
|
||||
systemctl enable podman-auto-update.timer
|
||||
|
||||
# Start the service
|
||||
|
||||
systemctl start podman-auto-update.timer
|
||||
|
||||
# Containers with the autoupdate label will be updated on the next scheduled timer
|
||||
|
||||
systemctl list-timers --all
|
||||
```
|
||||
|
||||
### 6. Edit the config
|
||||
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:
|
||||
|
||||
```bash
|
||||
podman volume inspect onedrive_conf
|
||||
```
|
||||
Or you can map your own config folder to the config volume. Make sure to copy all files from the volume into your mapped folder first.
|
||||
|
||||
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):
|
||||
```
|
||||
export ONEDRIVE_DATA_DIR_WORK="/home/abraunegg/OneDriveWork"
|
||||
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
|
||||
```
|
||||
|
||||
## 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 |
|
||||
| <B>ONEDRIVE_DEBUG</B> | Controls "--verbose --verbose" switch on onedrive sync. Default is 0 | 1 |
|
||||
| <B>ONEDRIVE_DEBUG_HTTPS</B> | Controls "--debug-https" switch on onedrive sync. Default is 0 | 1 |
|
||||
| <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_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) |
|
||||
|
||||
### 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
|
||||
```
|
||||
**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
|
||||
```
|
||||
**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
|
||||
```
|
||||
**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
|
||||
```
|
||||
**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
|
||||
```
|
||||
|
||||
## Build instructions
|
||||
|
||||
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
|
||||
podman build . -t local-onedrive -f contrib/docker/Dockerfile
|
||||
```
|
||||
|
||||
There are alternate, smaller images available by building
|
||||
Dockerfile-stretch or Dockerfile-alpine. These [multi-stage builder
|
||||
pattern](https://docs.docker.com/develop/develop-images/multistage-build/)
|
||||
|
||||
#### How to build and run a custom Docker image based on Debian Stretch
|
||||
``` bash
|
||||
podman build . -t local-ondrive-stretch -f contrib/docker/Dockerfile-stretch
|
||||
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" local-ondrive-stretch:latest
|
||||
```
|
||||
|
||||
#### How to build and run a custom Docker 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
|
||||
```
|
||||
|
||||
#### How to build and run a custom Docker image for ARMHF (Raspberry Pi)
|
||||
Compatible with:
|
||||
* Raspberry Pi
|
||||
* Raspberry Pi 2
|
||||
* Raspberry Pi Zero
|
||||
* Raspberry Pi 3
|
||||
* Raspberry Pi 4
|
||||
``` bash
|
||||
podman build . -t local-onedrive-rpi -f contrib/docker/Dockerfile-rpi
|
||||
podman run -v onedrive_conf:/onedrive/conf:U,Z -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" local-ondrive-rpi:latest
|
||||
```
|
||||
|
||||
#### How to build and run a custom Docker image for AARCH64 Platforms
|
||||
``` bash
|
||||
podman build . -t local-onedrive-aarch64 -f contrib/docker/Dockerfile-aarch64
|
||||
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
|
||||
```
|
367
docs/USAGE.md
367
docs/USAGE.md
|
@ -23,10 +23,14 @@
|
|||
+ [skip_dir](#skip_dir)
|
||||
+ [skip_file](#skip_file)
|
||||
+ [skip_dotfiles](#skip_dotfiles)
|
||||
+ [skip_symlinks](#skip_symlinks)
|
||||
+ [monitor_interval](#monitor_interval)
|
||||
+ [monitor_fullscan_frequency](#monitor_fullscan_frequency)
|
||||
+ [min_notify_changes](#min_notify_changes)
|
||||
+ [Selective sync via 'sync_list' file](#selective-sync-via-sync_list-file)
|
||||
+ [operation_timeout](#operation_timeout)
|
||||
* [Performing a --resync](#performing-a---resync)
|
||||
* [Performing a --force-sync without a --resync or changing your configuration](#performing-a---force-sync-without-a---resync-or-changing-your-configuration)
|
||||
* [Handling Symbolic Links](#handling-symbolic-links)
|
||||
* [Selective sync via 'sync_list' file](#selective-sync-via-sync_list-file)
|
||||
* [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)
|
||||
* [How to 'skip' directories from syncing?](#how-to-skip-directories-from-syncing)
|
||||
|
@ -35,14 +39,19 @@
|
|||
* [Shared folders (OneDrive Business or Office 365)](#shared-folders-onedrive-business-or-office-365)
|
||||
* [SharePoint / Office 365 Shared Libraries](#sharepoint--office-365-shared-libraries)
|
||||
- [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)
|
||||
+ [webhook_listening_host and webhook_listening_port](#webhook_listening_host-and-webhook_listening_port)
|
||||
+ [webhook_expiration_interval and webhook_renewal_interval](#webhook_expiration_interval-and-webhook_renewal_interval)
|
||||
- [Running 'onedrive' as a system service](#running-onedrive-as-a-system-service)
|
||||
* [OneDrive service running as root user via init.d](#onedrive-service-running-as-root-user-via-initd)
|
||||
* [OneDrive service running as root user via systemd (Arch, Ubuntu, Debian, OpenSuSE, Fedora)](#onedrive-service-running-as-root-user-via-systemd-arch-ubuntu-debian-opensuse-fedora)
|
||||
* [OneDrive service running as root user via systemd (Red Hat Enterprise Linux, CentOS Linux)](#onedrive-service-running-as-root-user-via-systemd-red-hat-enterprise-linux-centos-linux)
|
||||
* [OneDrive service running as a non-root user via systemd (All Linux Distributions)](#onedrive-service-running-as-a-non-root-user-via-systemd-all-linux-distributions)
|
||||
* [OneDrive service running as a non-root user via systemd (with notifications enabled) (Arch, Ubuntu, Debian, OpenSuSE, Fedora)](#onedrive-service-running-as-a-non-root-user-via-systemd-with-notifications-enabled-arch-ubuntu-debian-opensuse-fedora)
|
||||
* [OneDrive service running as a non-root user via runit (antiX, Devuan, Artix, Void)](#onedrive-service-running-as-a-non-root-user-via-runit-antix-devuan-artix-void)
|
||||
- [Additional Configuration](#additional-configuration)
|
||||
* [Using multiple OneDrive accounts](#using-multiple-onedrive-accounts)
|
||||
* [Advanced Configuration of the OneDrive Free Client](#advanced-configuration-of-the-onedrive-free-client)
|
||||
* [Access OneDrive service through a proxy](#access-onedrive-service-through-a-proxy)
|
||||
* [Setup selinux for a sync folder outside of the home folder](#setup-selinux-for-a-sync-folder-outside-of-the-home-folder)
|
||||
- [All available commands](#all-available-commands)
|
||||
|
@ -80,6 +89,8 @@ If your system utilises curl >= 7.62.0 curl defaults to prefer HTTP/2 over HTTP/
|
|||
### Authorize the application with your OneDrive Account
|
||||
After installing the application you must authorize the application with your OneDrive Account. This is done by running the application without any additional command switches.
|
||||
|
||||
Note that some companies require to explicitly add this app in [Microsoft MyApps portal](https://myapps.microsoft.com/). To add an (approved) app to your apps, click on the ellipsis in the top-right corner and choose "Request new apps". On the next page you can add this app. If its not listed, you should request through your IT department.
|
||||
|
||||
You will be asked to open a specific URL by using your web browser where you will have to login into your Microsoft Account and give the application the permission to access your files. After giving permission to the application, you will be redirected to a blank page. Copy the URI of the blank page into the application.
|
||||
```text
|
||||
[user@hostname ~]$ onedrive
|
||||
|
@ -103,7 +114,7 @@ Enter the response uri: https://login.microsoftonline.com/common/oauth2/nativecl
|
|||
|
||||
Application has been successfully authorised, however no additional command switches were provided.
|
||||
|
||||
Please use --help for further assistance in regards to running this application.
|
||||
Please use 'onedrive --help' for further assistance in regards to running this application.
|
||||
```
|
||||
|
||||
### Show your configuration
|
||||
|
@ -111,7 +122,7 @@ To validate your configuration the application will use, utilize the following:
|
|||
```text
|
||||
onedrive --display-config
|
||||
```
|
||||
This will display all the pertinent runtime interpretation of the options and configuration you are using. This is helpful to validate the client will perform the operations your asking without performing a sync. Example output is as follows:
|
||||
This will display all the pertinent runtime interpretation of the options and configuration you are using. Example output is as follows:
|
||||
```text
|
||||
onedrive version = vX.Y.Z-A-bcdefghi
|
||||
Config path = /home/alex/.config/onedrive
|
||||
|
@ -217,13 +228,26 @@ The requested client activity log will instead be located in the users home dire
|
|||
|
||||
On many systems this can be achieved by
|
||||
```text
|
||||
mkdir /var/log/onedrive
|
||||
chown root.users /var/log/onedrive
|
||||
chmod 0775 /var/log/onedrive
|
||||
sudo mkdir /var/log/onedrive
|
||||
sudo chown root.users /var/log/onedrive
|
||||
sudo chmod 0775 /var/log/onedrive
|
||||
```
|
||||
|
||||
All log files will be in the format of `%username%.onedrive.log`, where `%username%` represents the user who ran the client.
|
||||
|
||||
Additionally, you need to ensure that your user account is part of the 'users' group:
|
||||
```
|
||||
cat /etc/group | grep users
|
||||
```
|
||||
|
||||
If your user is not part of this group, then you need to add your user to this group:
|
||||
```
|
||||
sudo usermod -a -G users <your-user-name>
|
||||
```
|
||||
|
||||
You then need to 'logout' of all sessions / SSH sessions to login again to have the new group access applied.
|
||||
|
||||
|
||||
**Note:**
|
||||
To use a different log directory rather than the default above, add the following as a configuration option to `~/.config/onedrive/config`:
|
||||
```text
|
||||
|
@ -279,7 +303,7 @@ ERROR: OneDrive returned a 'HTTP 401 Unauthorized' - Cannot Initialize Sync Engi
|
|||
```
|
||||
To re-authorise the client, follow the steps below:
|
||||
1. If running the client as a service (init.d or systemd), stop the service
|
||||
2. Run the command `onedrive --logout`. This will clean up the previous authorisation, and will prompt you to re-authorise as per initial configuration.
|
||||
2. Run the command `onedrive --reauth`. This will clean up the previous authorisation, and will prompt you to re-authorise the client as per initial configuration.
|
||||
3. Restart the client if running as a service or perform a manual sync
|
||||
|
||||
The application will now sync with OneDrive with the new credentials.
|
||||
|
@ -297,12 +321,12 @@ If you want to change the defaults, you can copy and edit the included config fi
|
|||
**Example:**
|
||||
```text
|
||||
mkdir -p ~/.config/onedrive
|
||||
cp ./config ~/.config/onedrive/config
|
||||
wget https://raw.githubusercontent.com/abraunegg/onedrive/master/config -O ~/.config/onedrive/config
|
||||
nano ~/.config/onedrive/config
|
||||
```
|
||||
This file does not get created by default, and should only be created if you want to change the 'default' operational parameters.
|
||||
|
||||
See the [config](https://raw.githubusercontent.com/abraunegg/onedrive/master/config) file for the full list of options, and [All available commands](https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md#all-available-commands) for all possible keys and there default values.
|
||||
See the [config](https://raw.githubusercontent.com/abraunegg/onedrive/master/config) file for the full list of options, and [All available commands](https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md#all-available-commands) for all possible keys and their default values.
|
||||
|
||||
### The default configuration file is listed below:
|
||||
```text
|
||||
|
@ -335,7 +359,7 @@ See the [config](https://raw.githubusercontent.com/abraunegg/onedrive/master/con
|
|||
# dry_run = "false"
|
||||
# min_notify_changes = "5"
|
||||
# monitor_log_frequency = "5"
|
||||
# monitor_fullscan_frequency = "10"
|
||||
# monitor_fullscan_frequency = "12"
|
||||
# sync_root_files = "false"
|
||||
# classify_as_big_delete = "1000"
|
||||
# user_agent = ""
|
||||
|
@ -343,6 +367,7 @@ See the [config](https://raw.githubusercontent.com/abraunegg/onedrive/master/con
|
|||
# skip_dir_strict_match = "false"
|
||||
# application_id = ""
|
||||
# resync = "false"
|
||||
# resync_auth = "false"
|
||||
# bypass_data_preservation = "false"
|
||||
# azure_ad_endpoint = ""
|
||||
# azure_tenant_id = "common"
|
||||
|
@ -350,13 +375,21 @@ 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 = ""
|
||||
# webhook_listening_port = "8888"
|
||||
# webhook_expiration_interval = "86400"
|
||||
# webhook_renewal_interval = "43200"
|
||||
```
|
||||
|
||||
|
||||
### 'config' file configuration examples:
|
||||
The below are 'config' file examples to assist with configuration of the 'config' file:
|
||||
|
||||
#### sync_dir
|
||||
Configure your local sync directory location.
|
||||
|
||||
Example:
|
||||
```text
|
||||
# When changing a config option below, remove the '#' from the start of the line
|
||||
|
@ -382,7 +415,7 @@ The following are directory and file default permissions for any new directory o
|
|||
* Directories: 700 - This provides the following permissions: `drwx------`
|
||||
* Files: 600 - This provides the following permissions: `-rw-------`
|
||||
|
||||
To change the default permissions, update the following 2 configuration options with the required permissions. Utilise [Unix Permissions Calculator](http://permissions-calculator.org/) to assist in determining the required permissions.
|
||||
To change the default permissions, update the following 2 configuration options with the required permissions. Utilise the [Unix Permissions Calculator](https://chmod-calculator.com/) to assist in determining the required permissions.
|
||||
|
||||
```text
|
||||
# When changing a config option below, remove the '#' from the start of the line
|
||||
|
@ -398,6 +431,12 @@ sync_file_permissions = "600"
|
|||
**Important:** Special permission bits (setuid, setgid, sticky bit) are not supported. Valid permission values are from `000` to `777` only.
|
||||
|
||||
#### skip_dir
|
||||
This option is used to 'skip' certain directories and supports pattern matching.
|
||||
|
||||
Patterns are case insensitive. `*` and `?` [wildcards characters](https://technet.microsoft.com/en-us/library/bb490639.aspx) are supported. Use `|` to separate multiple patterns.
|
||||
|
||||
**Important:** Entries under `skip_dir` are relative to your `sync_dir` path.
|
||||
|
||||
Example:
|
||||
```text
|
||||
# When changing a config option below, remove the '#' from the start of the line
|
||||
|
@ -409,9 +448,6 @@ Example:
|
|||
skip_dir = "Desktop|Documents/IISExpress|Documents/SQL Server Management Studio|Documents/Visual Studio*|Documents/WindowsPowerShell"
|
||||
# log_dir = "/var/log/onedrive/"
|
||||
```
|
||||
Patterns are case insensitive. `*` and `?` [wildcards characters](https://technet.microsoft.com/en-us/library/bb490639.aspx) are supported. Use `|` to separate multiple patterns.
|
||||
|
||||
**Important:** Entries under `skip_dir` are relative to your `sync_dir` path.
|
||||
|
||||
**Note:** The `skip_dir` can be specified multiple times, for example:
|
||||
```text
|
||||
|
@ -427,17 +463,8 @@ skip_dir = "SomeDir|OtherDir|ThisDir|ThatDir|/Path/To/A/Directory|/Another/Path/
|
|||
**Note:** After changing `skip_dir`, you must perform a full re-synchronization by adding `--resync` to your existing command line - for example: `onedrive --synchronize --resync`
|
||||
|
||||
#### skip_file
|
||||
Example:
|
||||
```text
|
||||
# When changing a config option below, remove the '#' from the start of the line
|
||||
# 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"
|
||||
# monitor_interval = "300"
|
||||
# skip_dir = ""
|
||||
# log_dir = "/var/log/onedrive/"
|
||||
```
|
||||
This option is used to 'skip' certain files and supports pattern matching.
|
||||
|
||||
Patterns are case insensitive. `*` and `?` [wildcards characters](https://technet.microsoft.com/en-us/library/bb490639.aspx) are supported. Use `|` to separate multiple patterns.
|
||||
|
||||
Files can be skipped in the following fashion:
|
||||
|
@ -452,6 +479,18 @@ By default, the following files will be skipped:
|
|||
|
||||
**Important:** Do not use a skip_file entry of `.*` as this will prevent correct searching of local changes to process.
|
||||
|
||||
Example:
|
||||
```text
|
||||
# When changing a config option below, remove the '#' from the start of the line
|
||||
# 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"
|
||||
# monitor_interval = "300"
|
||||
# skip_dir = ""
|
||||
# log_dir = "/var/log/onedrive/"
|
||||
```
|
||||
|
||||
**Note:** The `skip_file` can be specified multiple times, for example:
|
||||
```text
|
||||
skip_file = "~*|.~*|*.tmp|*.swp"
|
||||
|
@ -466,6 +505,8 @@ skip_file = "~*|.~*|*.tmp|*.swp|*.blah|never_sync.file"
|
|||
**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`
|
||||
|
||||
#### skip_dotfiles
|
||||
Setting this to `"true"` will skip all .files and .folders while syncing.
|
||||
|
||||
Example:
|
||||
```text
|
||||
# skip_symlinks = "false"
|
||||
|
@ -474,20 +515,12 @@ skip_dotfiles = "true"
|
|||
# dry_run = "false"
|
||||
# monitor_interval = "300"
|
||||
```
|
||||
Setting this to `"true"` will skip all .files and .folders while syncing.
|
||||
|
||||
#### skip_symlinks
|
||||
Example:
|
||||
```text
|
||||
# local_first = "false"
|
||||
# no_remote_delete = "false"
|
||||
skip_symlinks = "true"
|
||||
# debug_https = "false"
|
||||
# skip_dotfiles = "false"
|
||||
```
|
||||
Setting this to `"true"` will skip all symlinks while syncing.
|
||||
|
||||
#### monitor_interval
|
||||
The monitor interval is defined as the wait time 'between' sync's when running in monitor mode. When this interval expires, the client will check OneDrive for changes online, performing data integrity checks and scanning the local 'sync_dir' for new content.
|
||||
|
||||
By default without configuration, 'monitor_interval' is set to 300 seconds. Setting this value to 600 will run the sync process every 10 minutes.
|
||||
|
||||
Example:
|
||||
```text
|
||||
# skip_dotfiles = "false"
|
||||
|
@ -496,20 +529,116 @@ monitor_interval = "600"
|
|||
# min_notify_changes = "5"
|
||||
# monitor_log_frequency = "5"
|
||||
```
|
||||
The monitor interval is defined as the wait time 'between' sync's when running in monitor mode. By default without configuration, the monitor_interval is set to 300 seconds. Setting this value to 600 will run the sync process every 10 minutes.
|
||||
|
||||
#### 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.
|
||||
|
||||
By default without configuration, 'monitor_fullscan_frequency' is set to 12. In this default state, this means that a full scan is performed every 'monitor_interval' x 'monitor_fullscan_frequency' = 3600 seconds. This is only applicable when running in --monitor mode.
|
||||
|
||||
Setting this value to 24 means that the full scan of OneDrive and checking the integrity of the data stored locally will occur every 2 hours (assuming 'monitor_interval' is set to 300 seconds):
|
||||
|
||||
Example:
|
||||
```text
|
||||
# min_notify_changes = "5"
|
||||
# monitor_log_frequency = "5"
|
||||
monitor_fullscan_frequency = "24"
|
||||
# sync_root_files = "false"
|
||||
# classify_as_big_delete = "1000"
|
||||
```
|
||||
|
||||
**Note:** When running in --monitor mode, at application start-up, a full scan will be performed to ensure data integrity. This option has zero effect when running the application in --synchronize mode and a full scan will always be performed.
|
||||
|
||||
#### min_notify_changes
|
||||
This option defines the minimum number of pending incoming changes necessary to trigger a desktop notification. This allows controlling the frequency of notifications.
|
||||
|
||||
Example:
|
||||
```text
|
||||
# dry_run = "false"
|
||||
# monitor_interval = "300"
|
||||
min_notify_changes = "50"
|
||||
# monitor_log_frequency = "5"
|
||||
# monitor_fullscan_frequency = "10"
|
||||
# monitor_fullscan_frequency = "12"
|
||||
```
|
||||
This option defines the minimum number of pending incoming changes necessary to trigger a desktop notification. This allows controlling the frequency of notifications.
|
||||
|
||||
#### Selective sync via 'sync_list' file
|
||||
#### operation_timeout
|
||||
Operation Timeout is the maximum amount of time (seconds) a file operation is allowed to take. This includes DNS resolution, connecting, data transfer, etc.
|
||||
|
||||
Example:
|
||||
```text
|
||||
# sync_file_permissions = "600"
|
||||
# rate_limit = "131072"
|
||||
operation_timeout = "3600"
|
||||
```
|
||||
|
||||
### Performing a --resync
|
||||
If you modify any of the following configuration items, you will be required to perform a `--resync` to ensure your client is syncing your data with the updated configuration:
|
||||
* sync_dir
|
||||
* skip_dir
|
||||
* skip_file
|
||||
* drive_id
|
||||
* Modifying sync_list
|
||||
* Modifying business_shared_folders
|
||||
|
||||
Additionally, you may choose to perform a `--resync` if you feel that this action needs to be taken to ensure your data is in sync. If you are using this switch simply because you dont know the sync status, you can query the actual sync status using `--display-sync-status`.
|
||||
|
||||
When using `--resync`, the following warning and advice will be presented:
|
||||
```text
|
||||
The use of --resync will remove your local 'onedrive' client state, thus no record will exist regarding your current 'sync status'
|
||||
This has the potential to overwrite local versions of files with potentially older versions downloaded from OneDrive which can lead to data loss
|
||||
If in-doubt, backup your local data first before proceeding with --resync
|
||||
|
||||
Are you sure you wish to proceed with --resync? [Y/N]
|
||||
```
|
||||
|
||||
To proceed with using `--resync`, you must type 'y' or 'Y' to allow the application to continue.
|
||||
|
||||
**Note:** It is highly recommended to only use `--resync` if the application advises you to use it. Do not just blindly set the application to start with `--resync` as the default option.
|
||||
|
||||
**Note:** In some automated environments (and it is 100% assumed you *know* what you are doing because of automation), in order to avoid this 'proceed with acknowledgement' requirement, add `--resync-auth` to automatically acknowledge the prompt.
|
||||
|
||||
### Performing a --force-sync without a --resync or changing your configuration
|
||||
In some cases and situations, you may have configured the application to skip certain files and folders using 'skip_file' and 'skip_dir' configuration. You then may have a requirement to actually sync one of these items, but do not wish to modify your configuration, nor perform an entire `--resync` twice.
|
||||
|
||||
The `--force-sync` option allows you to sync a specific directory, ignoring your 'skip_file' and 'skip_dir' configuration and negating the requirement to perform a `--resync`
|
||||
|
||||
In order to use this option, you must run the application manually in the following manner:
|
||||
```text
|
||||
onedrive --synchronize --single-directory '<directory_to_sync>' --force-sync <add any other options needed or required>
|
||||
```
|
||||
|
||||
When using `--force-sync`, the following warning and advice will be presented:
|
||||
```text
|
||||
WARNING: Overriding application configuration to use application defaults for skip_dir and skip_file due to --synchronize --single-directory --force-sync being used
|
||||
|
||||
The use of --force-sync will reconfigure the application to use defaults. This may have untold and unknown future impacts.
|
||||
By proceeding in using this option you accept any impacts including any data loss that may occur as a result of using --force-sync.
|
||||
|
||||
Are you sure you wish to proceed with --force-sync [Y/N]
|
||||
```
|
||||
|
||||
To proceed with using `--force-sync`, you must type 'y' or 'Y' to allow the application to continue.
|
||||
|
||||
### Handling Symbolic Links
|
||||
Microsoft OneDrive has zero concept or understanding of symbolic links, and attempting to upload a symbolic link to Microsoft OneDrive generates a platform API error. All data (files and folders) that are uploaded to OneDrive must be whole files or actual directories.
|
||||
|
||||
As such, there are only two methods to support symbolic links with this client:
|
||||
1. Follow the Linux symbolic link and upload what ever the link is pointing at to OneDrive. This is the default behaviour.
|
||||
2. Skip symbolic links by configuring the application to do so. In skipping, no data, no link, no reference is uploaded to OneDrive.
|
||||
|
||||
To skip symbolic links, edit your configuration as per below:
|
||||
|
||||
```text
|
||||
# local_first = "false"
|
||||
# no_remote_delete = "false"
|
||||
skip_symlinks = "true"
|
||||
# debug_https = "false"
|
||||
# skip_dotfiles = "false"
|
||||
```
|
||||
Setting this to `"true"` will configure the client to skip all symbolic links while syncing.
|
||||
|
||||
The default setting is `"false"` which will sync the whole folder structure referenced by the symbolic link, duplicating the contents on OneDrive in the place where the symbolic link is.
|
||||
|
||||
### 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 `~/.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.
|
||||
|
@ -594,7 +723,7 @@ application_id = "22c49a0d-d21c-4792-aed1-8f163c982546"
|
|||
```
|
||||
**Note:** The application will now use the older 'skilion' client identifier, however this may increase your chances of getting a OneDrive 429 error.
|
||||
|
||||
**Note:** After changing the 'application_id' you will need to restart any 'onedrive' process you have running, and potentially issue a `--logout` to re-auth the client with this updated application ID.
|
||||
**Note:** After changing the 'application_id' you will need to restart any 'onedrive' process you have running, and potentially issue a `--reauth` to re-authenticate the client with this updated application ID.
|
||||
|
||||
|
||||
### How to 'skip' directories from syncing?
|
||||
|
@ -670,10 +799,64 @@ sudo sysctl fs.inotify.max_user_watches=<new_value>
|
|||
|
||||
To make these changes permanent, refer to your OS reference documentation.
|
||||
|
||||
### Use webhook to subscribe to remote updates in 'monitor' mode
|
||||
|
||||
A webhook can be optionally enabled in the monitor mode to allow the onedrive process to subscribe to remote updates. Remote changes can be synced to your local file system as soon as possible, without waiting for the next sync cycle.
|
||||
|
||||
To enable this feature, you need to configure the following options in the config file:
|
||||
|
||||
```
|
||||
webhook_enabled = "true"
|
||||
webhook_public_url = "<public-facing url to reach your webhook>"
|
||||
```
|
||||
|
||||
Setting `webhook_enabled` to `true` enables the webhook in 'monitor' mode. The onedrive process will listen for incoming updates at a configurable endpoint, which defaults to `0.0.0.0:8888`. The `webhook_public_url` must be set to an public-facing url for Microsoft to send updates to your webhook. If your host is directly exposed to the Internet, the `webhook_public_url` can be set to `http://<your_host_ip>:8888/` to match the default endpoint. However, the recommended approach is to configure a reverse proxy like nginx.
|
||||
|
||||
**Note:** A valid HTTPS certificate is required for your public-facing URL if using nginx.
|
||||
|
||||
For example, below is a nginx config snippet to proxy traffic into the webhook:
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
location /webhooks/onedrive {
|
||||
proxy_pass http://127.0.0.1:8888;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With nginx running, you can configure `webhook_public_url` to `https://<your_host>/webhooks/onedrive`.
|
||||
|
||||
### More webhook configuration options
|
||||
|
||||
Below options can be optionally configured. The default is usually good enough.
|
||||
|
||||
#### webhook_listening_host and webhook_listening_port
|
||||
|
||||
Set `webhook_listening_host` and `webhook_listening_port` to change the webhook listening endpoint. If `webhook_listening_host` is left empty, which is the default, the webhook will bind to `0.0.0.0`. The default `webhook_listening_port` is `8888`.
|
||||
|
||||
```
|
||||
webhook_listening_host = ""
|
||||
webhook_listening_port = "8888"
|
||||
```
|
||||
|
||||
#### webhook_expiration_interval and webhook_renewal_interval
|
||||
|
||||
Set `webhook_expiration_interval` and `webhook_renewal_interval` to change the frequency of subscription renewal. By default, the webhook asks Microsoft to keep subscriptions alive for 24 hours, and it renews subscriptions when it is less than 12 hours before their expiration.
|
||||
|
||||
```
|
||||
# Default expiration interval is 24 hours
|
||||
webhook_expiration_interval = "86400"
|
||||
|
||||
# Default renewal interval is 12 hours
|
||||
webhook_renewal_interval = "43200"
|
||||
```
|
||||
|
||||
## Running 'onedrive' as a system service
|
||||
There are two ways that onedrive can be used as a service
|
||||
There are a few ways to use onedrive as a service
|
||||
* via init.d
|
||||
* via systemd
|
||||
* via runit
|
||||
|
||||
**Note:** If using the service files, you may need to increase the `fs.inotify.max_user_watches` value on your system to handle the number of files in the directory you are monitoring as the initial value may be too low.
|
||||
|
||||
|
@ -689,6 +872,7 @@ tail -f /var/log/onedrive/<username>.onedrive.log
|
|||
To change what 'user' the client runs under (by default root), manually edit the init.d service file and modify `daemon --user root onedrive_service.sh` for the correct user.
|
||||
|
||||
### OneDrive service running as root user via systemd (Arch, Ubuntu, Debian, OpenSuSE, Fedora)
|
||||
First, su to root using `su - root`, then enable the systemd service:
|
||||
```text
|
||||
systemctl --user enable onedrive
|
||||
systemctl --user start onedrive
|
||||
|
@ -782,8 +966,81 @@ journalctl --user-unit=onedrive -f
|
|||
|
||||
**Note:** `systemctl --user` directive is not applicable for Red Hat Enterprise Linux (RHEL) or CentOS Linux platforms
|
||||
|
||||
### OneDrive service running as a non-root user via runit (antiX, Devuan, Artix, Void)
|
||||
|
||||
1. Create the following folder if not present already `/etc/sv/runsvdir-<username>`
|
||||
|
||||
- where `<username>` is the `USER` targeted for the service
|
||||
- _e.g_ `# mkdir /etc/sv/runsvdir-nolan`
|
||||
|
||||
2. Create a file called `run` under the previously created folder with
|
||||
executable permissions
|
||||
|
||||
- `# touch /etc/sv/runsvdir-<username>/run`
|
||||
- `# chmod 0755 /etc/sv/runsvdir-<username>/run`
|
||||
|
||||
3. Edit the `run` file with the following contents (priviledges needed)
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
export USER="<username>"
|
||||
export HOME="/home/<username>"
|
||||
|
||||
groups="$(id -Gn "${USER}" | tr ' ' ':')"
|
||||
svdir="${HOME}/service"
|
||||
|
||||
exec chpst -u "${USER}:${groups}" runsvdir "${svdir}"
|
||||
```
|
||||
|
||||
- do not forget to correct the `<username>` according to the `USER` set on
|
||||
step #1
|
||||
|
||||
4. Enable the previously created folder as a service
|
||||
|
||||
- `# ln -fs /etc/sv/runsvdir-<username> /var/service/`
|
||||
|
||||
5. Create a subfolder on the `USER`'s `HOME` directory to store the services
|
||||
(or symlinks)
|
||||
|
||||
- `$ mkdir ~/service`
|
||||
|
||||
6. Create a subfolder for OneDrive specifically
|
||||
|
||||
- `$ mkdir ~/service/onedrive/`
|
||||
|
||||
7. Create a file called `run` under the previously created folder with
|
||||
executable permissions
|
||||
|
||||
- `$ touch ~/service/onedrive/run`
|
||||
- `$ chmod 0755 ~/service/onedrive/run`
|
||||
|
||||
8. Append the following contents to the `run` file
|
||||
|
||||
```sh
|
||||
#!/usr/bin/env sh
|
||||
exec /usr/bin/onedrive --monitor
|
||||
```
|
||||
|
||||
- in some scenario the path for the `onedrive` binary might differ, you can
|
||||
obtain it regardless by running `$ command -v onedrive`
|
||||
|
||||
9. Reboot to apply changes
|
||||
|
||||
10. Check status of user-defined services
|
||||
|
||||
- `$ sv status ~/service/*`
|
||||
|
||||
You may refer to Void's documentation regarding
|
||||
[Per-User Services](https://docs.voidlinux.org/config/services/user-services.html)
|
||||
for extra details.
|
||||
|
||||
## Additional Configuration
|
||||
### Using multiple OneDrive accounts
|
||||
### 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
|
||||
|
||||
Refer to [./advanced-usage.md](advanced-usage.md) for configuration assistance.
|
||||
|
||||
### Access OneDrive service through a proxy
|
||||
|
@ -847,6 +1104,8 @@ Options:
|
|||
Perform authorization via two files passed in as ARG in the format `authUrl:responseUrl`
|
||||
The authorization URL is written to the `authUrl`, then onedrive waits for the file `responseUrl`
|
||||
to be present, and reads the response from that file.
|
||||
--auth-response ARG
|
||||
Perform authentication not via interactive dialog but via providing the reponse url directly.
|
||||
--check-for-nomount
|
||||
Check for the presence of .nosync in the syncdir root. If found, do not perform sync.
|
||||
--check-for-nosync
|
||||
|
@ -863,6 +1122,8 @@ Options:
|
|||
Debug OneDrive HTTPS communication.
|
||||
--destination-directory ARG
|
||||
Destination directory for renamed or move on OneDrive - no sync will be performed.
|
||||
--disable-download-validation
|
||||
Disable download validation when downloading from OneDrive
|
||||
--disable-notifications
|
||||
Do not use desktop notifications in monitor mode.
|
||||
--disable-upload-validation
|
||||
|
@ -879,10 +1140,10 @@ Options:
|
|||
Enable client activity to a separate log file
|
||||
--force
|
||||
Force the deletion of data when a 'big delete' is detected
|
||||
--force-http-1.1
|
||||
Force the use of HTTP/1.1 for all operations (DEPRECIATED)
|
||||
--force-http-2
|
||||
Force the use of HTTP/2 for all operations where applicable
|
||||
--force-sync
|
||||
Force a synchronization of a specific folder, only when using --single-directory and ignoring all non-default skip_dir and skip_file rules
|
||||
--get-O365-drive-id ARG
|
||||
Query and return the Office 365 Drive ID for a given Office 365 SharePoint Shared Library
|
||||
--get-file-link ARG
|
||||
|
@ -899,6 +1160,8 @@ Options:
|
|||
Logout the current user
|
||||
--min-notify-changes ARG
|
||||
Minimum number of pending incoming changes necessary to trigger a desktop notification
|
||||
--modified-by ARG
|
||||
Display the last modified by details of a given path
|
||||
--monitor -m
|
||||
Keep monitoring for local and remote changes
|
||||
--monitor-fullscan-frequency ARG
|
||||
|
@ -909,14 +1172,20 @@ Options:
|
|||
Frequency of logging in monitor mode
|
||||
--no-remote-delete
|
||||
Do not delete local file 'deletes' from OneDrive when using --upload-only
|
||||
--operation-timeout
|
||||
Maximum amount of time (in seconds) an operation is allowed to take
|
||||
--print-token
|
||||
Print the access token, useful for debugging
|
||||
--reauth
|
||||
Reauthenticate the client with OneDrive
|
||||
--remove-directory ARG
|
||||
Remove a directory on OneDrive - no sync will be performed.
|
||||
--remove-source-files
|
||||
Remove source file after successful transfer to OneDrive when using --upload-only
|
||||
--resync
|
||||
Forget the last saved state, perform a full sync
|
||||
--resync-auth
|
||||
Approve the use of performing a --resync action
|
||||
--single-directory ARG
|
||||
Specify a single local directory within the OneDrive root to sync.
|
||||
--skip-dir ARG
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
# Advanced Configuration of the OneDrive Free Client
|
||||
This document covers the following scenarios:
|
||||
* Configuring the client to use mulitple OneDrive accounts / configurations
|
||||
* Configuring the client to use multiple 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
|
||||
## Configuring the client to use multiple OneDrive accounts / configurations
|
||||
Essentially, each OneDrive account or SharePoint Shared Library which you require to be synced needs to have its own and unique configuration, local sync directory and service files. To do this, the following steps are needed:
|
||||
1. Create a unique configuration folder for each onedrive client configuration that you need
|
||||
2. Copy to this folder a copy of the default configuration file
|
||||
|
@ -137,3 +139,57 @@ After unchecking the option and clicking "OK", the Windows OneDrive client shoul
|
|||
| OneDrive Personal | Onedrive Business<br>SharePoint |
|
||||
|---|---|
|
||||
| ![Uncheck-Personal](./images/personal-files-on-demand.png) | ![Uncheck-Business](./images/business-files-on-demand.png) |
|
||||
|
||||
## Configuring the client for use when 'sync_dir' is a mounted directory
|
||||
In some environments, your setup might be that your configured 'sync_dir' is pointing to another mounted file system - a NFS|CIFS location, an external drive (USB stuc, eSATA etc). As such, you configure your 'sync_dir' as follows:
|
||||
```text
|
||||
sync_dir = "/path/to/mountpoint/OneDrive"
|
||||
```
|
||||
|
||||
The issue here is - how does the client react if the mount point gets removed - network loss, device removal?
|
||||
|
||||
The client has zero knowledge of any event that causes a mountpoint to become unavailable, thus, the client (if you are running as a service) will assume that you deleted the files, thus, will go ahead and delete all your files on OneDrive. This is most certainly an undesirable action.
|
||||
|
||||
There are a few options here which you can configure in your 'config' file to assist you to prevent this sort of item from occuring:
|
||||
1. classify_as_big_delete
|
||||
2. check_nomount
|
||||
3. check_nosync
|
||||
|
||||
**Note:** Before making any change to your configuration, stop any sync process & stop any onedrive systemd service from running.
|
||||
|
||||
### classify_as_big_delete
|
||||
By default, this uses a value of 1000 files|folders. An undesirable unmount if you have more than 1000 files, this default level will prevent the client from executing the online delete. Modify this value up or down as desired
|
||||
|
||||
### check_nomount & check_nosync
|
||||
These two options are really the right safe guards to use.
|
||||
|
||||
In your 'mount point', *before* you mount your external folder|device, create empty `.nosync` file, so that this is the *only* file present in the mount location before you mount your data to your mount point. When you mount your data, this '.nosync' file will not be visible, but, if the device you are mounting goes away - this '.nosync' file is the only file visible.
|
||||
|
||||
Next, in your 'config' file, configure the following options: `check_nomount = "true"` and `check_nosync = "true"`
|
||||
|
||||
What this will do is tell the client, if at *any* point you see this file - stop syncing - thus, protecting your online data from being deleted by the mounted device being suddenly unavailable.
|
||||
|
||||
After making this sort of change - test with `--dry-run` so you can see the impacts of your mount point being unavailable, and how the client is now reacting. Once you are happy with how the system will react, restart your sync processes.
|
||||
|
||||
|
||||
## Upload data from the local ~/OneDrive folder to a specific location on OneDrive
|
||||
In some environments, you may not want your local ~/OneDrive folder to be uploaded directly to the root of your OneDrive account online.
|
||||
|
||||
Unfortunatly, the OneDrive API lacks any facility to perform a re-direction of data during upload.
|
||||
|
||||
The workaround for this is to structure your local filesystem and reconfigure your client to achieve the desired goal.
|
||||
|
||||
### High level steps:
|
||||
1. Create a new folder, for example `/opt/OneDrive`
|
||||
2. Configure your application config 'sync_dir' to look at this folder
|
||||
3. Inside `/opt/OneDrive` create the folder you wish to sync the data online to, for example: `/opt/OneDrive/RemoteOnlineDestination`
|
||||
4. Configure the application to only sync `/opt/OneDrive/RemoteDestination` via 'sync_list'
|
||||
5. Symbolically link `~/OneDrive` -> `/opt/OneDrive/RemoteOnlineDestination`
|
||||
|
||||
### Outcome:
|
||||
* Your `~/OneDrive` will look / feel as per normal
|
||||
* The data will be stored online under `/RemoteOnlineDestination`
|
||||
|
||||
### Testing:
|
||||
* Validate your configuration with `onedrive --display-config`
|
||||
* Test your configuration with `onedrive --dry-run`
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
# RPM Package Build Process
|
||||
The instuctions below have been tested on the following systems:
|
||||
* CentOS 6 x86_64
|
||||
* CentOS 7 x86_64
|
||||
* CentOS 8 x86_64
|
||||
|
||||
These instructions should also be applicable for RedHat & Fedora platforms, or any other RedHat RPM based distribution.
|
||||
|
||||
## Prepare Package Development Environment (CentOS 6, 7, 8)
|
||||
## Prepare Package Development Environment (CentOS 7, 8)
|
||||
Install the following dependencies on your build system:
|
||||
```text
|
||||
sudo yum groupinstall -y 'Development Tools'
|
||||
|
@ -14,28 +13,14 @@ sudo yum install -y libcurl-devel
|
|||
sudo yum install -y sqlite-devel
|
||||
sudo yum install -y libnotify-devel
|
||||
sudo yum install -y wget
|
||||
sudo yum install -y http://downloads.dlang.org/releases/2.x/2.091.0/dmd-2.091.0-0.fedora.x86_64.rpm
|
||||
sudo yum install -y http://downloads.dlang.org/releases/2.x/2.087.0/dmd-2.087.0-0.fedora.x86_64.rpm
|
||||
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
|
||||
```
|
||||
|
||||
### CentOS 6 Only
|
||||
In addition to the above requirements, the `sqlite` version used on CentOS 6.x / RHEL 6.x needs to be upgraded. Use the following instructions to update your version of `sqlite` so that it can support this client:
|
||||
```text
|
||||
sudo yum -y install epel-release
|
||||
sudo yum -y install mock
|
||||
wget https://kojipkgs.fedoraproject.org//packages/sqlite/3.7.15.2/2.fc19/src/sqlite-3.7.15.2-2.fc19.src.rpm -O ~/rpmbuild/SRPMS/sqlite-3.7.15.2-2.fc19.src.rpm
|
||||
mock -r epel-6-x86_64 --rebuild ~/rpmbuild/SRPMS/sqlite-3.7.15.2-2.fc19.src.rpm
|
||||
mock -r epel-6-i386 --rebuild ~/rpmbuild/SRPMS/sqlite-3.7.15.2-2.fc19.src.rpm
|
||||
mkdir ~/sqlite-upgrade
|
||||
mv /var/lib/mock/epel-6-x86_64/result/sqlite-*.rpm ~/sqlite-upgrade/
|
||||
mv /var/lib/mock/epel-6-i386/result/sqlite-*.i686.rpm ~/sqlite-upgrade/
|
||||
sudo yum -y upgrade ~/sqlite-upgrade/sqlite-*
|
||||
```
|
||||
|
||||
## Build RPM from spec file
|
||||
Build the RPM from the provided spec file:
|
||||
```text
|
||||
wget https://github.com/abraunegg/onedrive/archive/v2.4.0.tar.gz -O ~/rpmbuild/SOURCES/v2.4.0.tar.gz
|
||||
wget https://github.com/abraunegg/onedrive/archive/refs/tags/v2.4.15.tar.gz -O ~/rpmbuild/SOURCES/v2.4.15.tar.gz
|
||||
wget https://raw.githubusercontent.com/abraunegg/onedrive/master/contrib/spec/onedrive.spec.in -O ~/rpmbuild/SPECS/onedrive.spec
|
||||
rpmbuild -ba ~/rpmbuild/SPECS/onedrive.spec
|
||||
```
|
||||
|
@ -43,197 +28,25 @@ rpmbuild -ba ~/rpmbuild/SPECS/onedrive.spec
|
|||
## RPM Build Results
|
||||
Below are output results of building, installing and running the RPM package on the respective platforms:
|
||||
|
||||
### CentOS 6
|
||||
```text
|
||||
[alex@localhost ~]$ rpmbuild -ba ~/rpmbuild/SPECS/onedrive.spec
|
||||
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.Ve7WYf
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ LANG=C
|
||||
+ export LANG
|
||||
+ unset DISPLAY
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ rm -rf onedrive-2.4.0
|
||||
+ /bin/tar -xf -
|
||||
+ /usr/bin/gzip -dc /home/alex/rpmbuild/SOURCES/v2.4.0.tar.gz
|
||||
+ STATUS=0
|
||||
+ '[' 0 -ne 0 ']'
|
||||
+ cd onedrive-2.4.0
|
||||
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
|
||||
+ exit 0
|
||||
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.iB40rK
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd onedrive-2.4.0
|
||||
+ LANG=C
|
||||
+ export LANG
|
||||
+ unset DISPLAY
|
||||
+ CFLAGS='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
|
||||
+ export CFLAGS
|
||||
+ CXXFLAGS='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
|
||||
+ export CXXFLAGS
|
||||
+ FFLAGS='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -I/usr/lib64/gfortran/modules'
|
||||
+ export FFLAGS
|
||||
+ ./configure --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu --target=x86_64-redhat-linux-gnu --program-prefix= --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info
|
||||
checking for a BSD-compatible install... /usr/bin/install -c
|
||||
checking for x86_64-redhat-linux-gnu-pkg-config... no
|
||||
checking for pkg-config... /usr/bin/pkg-config
|
||||
checking pkg-config is at least version 0.9.0... yes
|
||||
checking for dmd... dmd
|
||||
checking version of D compiler... 2.091.0
|
||||
checking for curl... yes
|
||||
checking for sqlite... yes
|
||||
configure: creating ./config.status
|
||||
config.status: creating Makefile
|
||||
config.status: creating contrib/pacman/PKGBUILD
|
||||
config.status: creating contrib/spec/onedrive.spec
|
||||
config.status: creating onedrive.1
|
||||
config.status: creating contrib/systemd/onedrive.service
|
||||
config.status: creating contrib/systemd/onedrive@.service
|
||||
+ make
|
||||
if [ -f .git/HEAD ] ; then \
|
||||
git describe --tags > version ; \
|
||||
else \
|
||||
echo v2.4.0 > version ; \
|
||||
fi
|
||||
dmd -w -g -O -J. -L-lcurl -L-lsqlite3 -L-ldl src/config.d src/itemdb.d src/log.d src/main.d src/monitor.d src/onedrive.d src/qxor.d src/selective.d src/sqlite.d src/sync.d src/upload.d src/util.d src/progress.d -ofonedrive
|
||||
+ exit 0
|
||||
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.VP7LUb
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ '[' /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64 '!=' / ']'
|
||||
+ rm -rf /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64
|
||||
++ dirname /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64
|
||||
+ mkdir -p /home/alex/rpmbuild/BUILDROOT
|
||||
+ mkdir /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64
|
||||
+ cd onedrive-2.4.0
|
||||
+ LANG=C
|
||||
+ export LANG
|
||||
+ unset DISPLAY
|
||||
+ make install DESTDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64 PREFIX=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64
|
||||
/usr/bin/install -c -D onedrive /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/usr/bin/onedrive
|
||||
/usr/bin/install -c -D onedrive.1 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/usr/share/man/man1/onedrive.1
|
||||
/usr/bin/install -c -D -m 644 contrib/logrotate/onedrive.logrotate /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/etc/logrotate.d/onedrive
|
||||
mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/usr/share/doc/onedrive
|
||||
/usr/bin/install -c -D -m 644 README.md config LICENSE CHANGELOG.md docs/Docker.md docs/INSTALL.md docs/SharePoint-Shared-Libraries.md docs/USAGE.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/usr/share/doc/onedrive
|
||||
install -D contrib/init.d/onedrive.init /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/etc/init.d/onedrive
|
||||
install -D contrib/init.d/onedrive_service.sh /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/usr/bin/onedrive_service.sh
|
||||
+ /usr/lib/rpm/check-buildroot
|
||||
+ /usr/lib/rpm/redhat/brp-compress
|
||||
+ /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
|
||||
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
|
||||
+ /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
|
||||
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python
|
||||
+ /usr/lib/rpm/redhat/brp-python-hardlink
|
||||
+ /usr/lib/rpm/redhat/brp-java-repack-jars
|
||||
Processing files: onedrive-2.4.0-1.el6.x86_64
|
||||
Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.6wsc3O
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd onedrive-2.4.0
|
||||
+ DOCDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/usr/share/doc/onedrive-2.4.0
|
||||
+ export DOCDIR
|
||||
+ rm -rf /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/usr/share/doc/onedrive-2.4.0
|
||||
+ /bin/mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/usr/share/doc/onedrive-2.4.0
|
||||
+ cp -pr README.md LICENSE CHANGELOG.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64/usr/share/doc/onedrive-2.4.0
|
||||
+ exit 0
|
||||
Provides: config(onedrive) = 2.4.0-1.el6
|
||||
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
|
||||
Requires(post): chkconfig
|
||||
Requires(preun): chkconfig initscripts
|
||||
Requires(postun): initscripts
|
||||
Requires: /bin/bash /bin/sh ld-linux-x86-64.so.2()(64bit) ld-linux-x86-64.so.2(GLIBC_2.3)(64bit) libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3.2)(64bit) libc.so.6(GLIBC_2.4)(64bit) libc.so.6(GLIBC_2.6)(64bit) libcurl.so.4()(64bit) libdl.so.2()(64bit) libdl.so.2(GLIBC_2.2.5)(64bit) libgcc_s.so.1()(64bit) libgcc_s.so.1(GCC_3.0)(64bit) libgcc_s.so.1(GCC_4.2.0)(64bit) libm.so.6()(64bit) libm.so.6(GLIBC_2.2.5)(64bit) libpthread.so.0()(64bit) libpthread.so.0(GLIBC_2.2.5)(64bit) libpthread.so.0(GLIBC_2.3.2)(64bit) libpthread.so.0(GLIBC_2.3.3)(64bit) libpthread.so.0(GLIBC_2.3.4)(64bit) librt.so.1()(64bit) librt.so.1(GLIBC_2.2.5)(64bit) libsqlite3.so.0()(64bit) rtld(GNU_HASH)
|
||||
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el6.x86_64
|
||||
Wrote: /home/alex/rpmbuild/SRPMS/onedrive-2.4.0-1.el6.src.rpm
|
||||
Wrote: /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el6.x86_64.rpm
|
||||
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.MuVJDP
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd onedrive-2.4.0
|
||||
+ exit 0
|
||||
[alex@localhost ~]$ sudo yum -y install /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el6.x86_64.rpm
|
||||
Loaded plugins: fastestmirror
|
||||
Setting up Install Process
|
||||
Examining /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el6.x86_64.rpm: onedrive-2.4.0-1.el6.x86_64
|
||||
Marking /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el6.x86_64.rpm to be installed
|
||||
Loading mirror speeds from cached hostfile
|
||||
* base: mirror.internode.on.net
|
||||
* epel: fedora.mirror.serversaustralia.com.au
|
||||
* extras: mirror.internode.on.net
|
||||
* updates: mirror.colocity.com
|
||||
Resolving Dependencies
|
||||
--> Running transaction check
|
||||
---> Package onedrive.x86_64 0:2.4.0-1.el6 will be installed
|
||||
--> Finished Dependency Resolution
|
||||
|
||||
Dependencies Resolved
|
||||
|
||||
==============================================================================================================================================================================================
|
||||
Package Arch Version Repository Size
|
||||
==============================================================================================================================================================================================
|
||||
Installing:
|
||||
onedrive x86_64 2.4.0-1.el6 /onedrive-2.4.0-1.el6.x86_64 5.8 M
|
||||
|
||||
Transaction Summary
|
||||
==============================================================================================================================================================================================
|
||||
Install 1 Package(s)
|
||||
|
||||
Total size: 5.8 M
|
||||
Installed size: 5.8 M
|
||||
Downloading Packages:
|
||||
Running rpm_check_debug
|
||||
Running Transaction Test
|
||||
Transaction Test Succeeded
|
||||
Running Transaction
|
||||
Installing : onedrive-2.4.0-1.el6.x86_64 1/1
|
||||
Verifying : onedrive-2.4.0-1.el6.x86_64 1/1
|
||||
|
||||
Installed:
|
||||
onedrive.x86_64 0:2.4.0-1.el6
|
||||
|
||||
Complete!
|
||||
[alex@localhost ~]$ which onedrive
|
||||
/usr/bin/onedrive
|
||||
[alex@localhost ~]$ onedrive --version
|
||||
onedrive v2.4.0
|
||||
[alex@localhost ~]$ onedrive --display-config
|
||||
onedrive version = v2.4.0
|
||||
Config path = /home/alex/.config/onedrive
|
||||
Config file found in config path = false
|
||||
Config option 'check_nosync' = false
|
||||
Config option 'sync_dir' = /home/alex/OneDrive
|
||||
Config option 'skip_dir' =
|
||||
Config option 'skip_file' = ~*|.~*|*.tmp
|
||||
Config option 'skip_dotfiles' = false
|
||||
Config option 'skip_symlinks' = false
|
||||
Config option 'monitor_interval' = 45
|
||||
Config option 'min_notify_changes' = 5
|
||||
Config option 'log_dir' = /var/log/onedrive/
|
||||
Config option 'classify_as_big_delete' = 1000
|
||||
Config option 'sync_root_files' = false
|
||||
Selective sync configured = false
|
||||
[alex@localhost ~]$
|
||||
```
|
||||
|
||||
### CentOS 7
|
||||
```text
|
||||
[alex@localhost ~]$ rpmbuild -ba ~/rpmbuild/SPECS/onedrive.spec
|
||||
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.BEprc0
|
||||
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.wi6Tdz
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ rm -rf onedrive-2.4.0
|
||||
+ /usr/bin/gzip -dc /home/alex/rpmbuild/SOURCES/v2.4.0.tar.gz
|
||||
+ rm -rf onedrive-2.4.15
|
||||
+ /usr/bin/tar -xf -
|
||||
+ /usr/bin/gzip -dc /home/alex/rpmbuild/SOURCES/v2.4.15.tar.gz
|
||||
+ STATUS=0
|
||||
+ '[' 0 -ne 0 ']'
|
||||
+ cd onedrive-2.4.0
|
||||
+ cd onedrive-2.4.15
|
||||
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
|
||||
+ exit 0
|
||||
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.CSy74N
|
||||
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.dyeEuM
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd onedrive-2.4.0
|
||||
+ cd onedrive-2.4.15
|
||||
+ CFLAGS='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic'
|
||||
+ export CFLAGS
|
||||
+ CXXFLAGS='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic'
|
||||
|
@ -254,7 +67,7 @@ checking for x86_64-redhat-linux-gnu-pkg-config... no
|
|||
checking for pkg-config... /usr/bin/pkg-config
|
||||
checking pkg-config is at least version 0.9.0... yes
|
||||
checking for dmd... dmd
|
||||
checking version of D compiler... 2.091.0
|
||||
checking version of D compiler... 2.087.0
|
||||
checking for curl... yes
|
||||
checking for sqlite... yes
|
||||
configure: creating ./config.status
|
||||
|
@ -269,28 +82,28 @@ configure: WARNING: unrecognized options: --disable-dependency-tracking
|
|||
if [ -f .git/HEAD ] ; then \
|
||||
git describe --tags > version ; \
|
||||
else \
|
||||
echo v2.4.0 > version ; \
|
||||
echo v2.4.15 > version ; \
|
||||
fi
|
||||
dmd -w -g -O -J. -L-lcurl -L-lsqlite3 -L-ldl src/config.d src/itemdb.d src/log.d src/main.d src/monitor.d src/onedrive.d src/qxor.d src/selective.d src/sqlite.d src/sync.d src/upload.d src/util.d src/progress.d -ofonedrive
|
||||
dmd -w -g -O -J. -L-lcurl -L-lsqlite3 -L-ldl src/config.d src/itemdb.d src/log.d src/main.d src/monitor.d src/onedrive.d src/qxor.d src/selective.d src/sqlite.d src/sync.d src/upload.d src/util.d src/progress.d src/arsd/cgi.d -ofonedrive
|
||||
+ exit 0
|
||||
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.Ffintx
|
||||
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.L3JbHy
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ '[' /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64 '!=' / ']'
|
||||
+ rm -rf /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64
|
||||
++ dirname /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64
|
||||
+ '[' /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64 '!=' / ']'
|
||||
+ rm -rf /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64
|
||||
++ dirname /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64
|
||||
+ mkdir -p /home/alex/rpmbuild/BUILDROOT
|
||||
+ mkdir /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64
|
||||
+ cd onedrive-2.4.0
|
||||
+ /usr/bin/make install DESTDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64 PREFIX=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64
|
||||
/usr/bin/install -c -D onedrive /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/bin/onedrive
|
||||
/usr/bin/install -c -D onedrive.1 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/share/man/man1/onedrive.1
|
||||
/usr/bin/install -c -D -m 644 contrib/logrotate/onedrive.logrotate /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/etc/logrotate.d/onedrive
|
||||
mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/share/doc/onedrive
|
||||
/usr/bin/install -c -D -m 644 README.md config LICENSE CHANGELOG.md docs/Docker.md docs/INSTALL.md docs/SharePoint-Shared-Libraries.md docs/USAGE.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/share/doc/onedrive
|
||||
/usr/bin/install -c -d -m 0755 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/lib/systemd/user /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/lib/systemd/system
|
||||
/usr/bin/install -c -m 0644 contrib/systemd/onedrive@.service /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/lib/systemd/system
|
||||
/usr/bin/install -c -m 0644 contrib/systemd/onedrive.service /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/lib/systemd/system
|
||||
+ mkdir /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64
|
||||
+ cd onedrive-2.4.15
|
||||
+ /usr/bin/make install DESTDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64 PREFIX=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64
|
||||
/usr/bin/install -c -D onedrive /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/bin/onedrive
|
||||
/usr/bin/install -c -D onedrive.1 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/share/man/man1/onedrive.1
|
||||
/usr/bin/install -c -D -m 644 contrib/logrotate/onedrive.logrotate /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/etc/logrotate.d/onedrive
|
||||
mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/share/doc/onedrive
|
||||
/usr/bin/install -c -D -m 644 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 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/share/doc/onedrive
|
||||
/usr/bin/install -c -d -m 0755 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/lib/systemd/user /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/lib/systemd/system
|
||||
/usr/bin/install -c -m 0644 contrib/systemd/onedrive@.service /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/lib/systemd/system
|
||||
/usr/bin/install -c -m 0644 contrib/systemd/onedrive.service /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/lib/systemd/system
|
||||
+ /usr/lib/rpm/check-buildroot
|
||||
+ /usr/lib/rpm/redhat/brp-compress
|
||||
+ /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
|
||||
|
@ -299,39 +112,39 @@ mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/share/doc
|
|||
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
|
||||
+ /usr/lib/rpm/redhat/brp-python-hardlink
|
||||
+ /usr/lib/rpm/redhat/brp-java-repack-jars
|
||||
Processing files: onedrive-2.4.0-1.el7.x86_64
|
||||
Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.EB5XJj
|
||||
Processing files: onedrive-2.4.15-1.el7.x86_64
|
||||
Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.cpSXho
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd onedrive-2.4.0
|
||||
+ DOCDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/share/doc/onedrive-2.4.0
|
||||
+ cd onedrive-2.4.15
|
||||
+ DOCDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/share/doc/onedrive-2.4.15
|
||||
+ export DOCDIR
|
||||
+ /usr/bin/mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/share/doc/onedrive-2.4.0
|
||||
+ cp -pr README.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/share/doc/onedrive-2.4.0
|
||||
+ cp -pr LICENSE /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/share/doc/onedrive-2.4.0
|
||||
+ cp -pr CHANGELOG.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64/usr/share/doc/onedrive-2.4.0
|
||||
+ /usr/bin/mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/share/doc/onedrive-2.4.15
|
||||
+ cp -pr README.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/share/doc/onedrive-2.4.15
|
||||
+ cp -pr LICENSE /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/share/doc/onedrive-2.4.15
|
||||
+ cp -pr CHANGELOG.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64/usr/share/doc/onedrive-2.4.15
|
||||
+ exit 0
|
||||
Provides: config(onedrive) = 2.4.0-1.el7 onedrive = 2.4.0-1.el7 onedrive(x86-64) = 2.4.0-1.el7
|
||||
Provides: config(onedrive) = 2.4.15-1.el7 onedrive = 2.4.15-1.el7 onedrive(x86-64) = 2.4.15-1.el7
|
||||
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
|
||||
Requires(post): systemd
|
||||
Requires(preun): systemd
|
||||
Requires(postun): systemd
|
||||
Requires: ld-linux-x86-64.so.2()(64bit) ld-linux-x86-64.so.2(GLIBC_2.3)(64bit) libc.so.6()(64bit) libc.so.6(GLIBC_2.14)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3.2)(64bit) libc.so.6(GLIBC_2.4)(64bit) libc.so.6(GLIBC_2.6)(64bit) libcurl.so.4()(64bit) libdl.so.2()(64bit) libdl.so.2(GLIBC_2.2.5)(64bit) libgcc_s.so.1()(64bit) libgcc_s.so.1(GCC_3.0)(64bit) libgcc_s.so.1(GCC_4.2.0)(64bit) libm.so.6()(64bit) libm.so.6(GLIBC_2.2.5)(64bit) libpthread.so.0()(64bit) libpthread.so.0(GLIBC_2.2.5)(64bit) libpthread.so.0(GLIBC_2.3.2)(64bit) libpthread.so.0(GLIBC_2.3.3)(64bit) libpthread.so.0(GLIBC_2.3.4)(64bit) librt.so.1()(64bit) librt.so.1(GLIBC_2.2.5)(64bit) libsqlite3.so.0()(64bit) rtld(GNU_HASH)
|
||||
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el7.x86_64
|
||||
Wrote: /home/alex/rpmbuild/SRPMS/onedrive-2.4.0-1.el7.src.rpm
|
||||
Wrote: /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el7.x86_64.rpm
|
||||
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.2VzBVJ
|
||||
Requires: ld-linux-x86-64.so.2()(64bit) ld-linux-x86-64.so.2(GLIBC_2.3)(64bit) libc.so.6()(64bit) libc.so.6(GLIBC_2.14)(64bit) libc.so.6(GLIBC_2.15)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3.2)(64bit) libc.so.6(GLIBC_2.3.4)(64bit) libc.so.6(GLIBC_2.4)(64bit) libc.so.6(GLIBC_2.6)(64bit) libc.so.6(GLIBC_2.8)(64bit) libc.so.6(GLIBC_2.9)(64bit) libcurl.so.4()(64bit) libdl.so.2()(64bit) libdl.so.2(GLIBC_2.2.5)(64bit) libgcc_s.so.1()(64bit) libgcc_s.so.1(GCC_3.0)(64bit) libgcc_s.so.1(GCC_4.2.0)(64bit) libm.so.6()(64bit) libm.so.6(GLIBC_2.2.5)(64bit) libpthread.so.0()(64bit) libpthread.so.0(GLIBC_2.2.5)(64bit) libpthread.so.0(GLIBC_2.3.2)(64bit) libpthread.so.0(GLIBC_2.3.4)(64bit) librt.so.1()(64bit) librt.so.1(GLIBC_2.2.5)(64bit) libsqlite3.so.0()(64bit) rtld(GNU_HASH)
|
||||
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el7.x86_64
|
||||
Wrote: /home/alex/rpmbuild/SRPMS/onedrive-2.4.15-1.el7.src.rpm
|
||||
Wrote: /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.15-1.el7.x86_64.rpm
|
||||
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.nWoW33
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd onedrive-2.4.0
|
||||
+ cd onedrive-2.4.15
|
||||
+ exit 0
|
||||
[alex@localhost ~]$ sudo yum -y install /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el7.x86_64.rpm
|
||||
[alex@localhost ~]$ sudo yum -y install /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.15-1.el7.x86_64.rpm
|
||||
Loaded plugins: fastestmirror
|
||||
Examining /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el7.x86_64.rpm: onedrive-2.4.0-1.el7.x86_64
|
||||
Marking /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el7.x86_64.rpm to be installed
|
||||
Examining /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.15-1.el7.x86_64.rpm: onedrive-2.4.15-1.el7.x86_64
|
||||
Marking /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.15-1.el7.x86_64.rpm to be installed
|
||||
Resolving Dependencies
|
||||
--> Running transaction check
|
||||
---> Package onedrive.x86_64 0:2.4.0-1.el7 will be installed
|
||||
---> Package onedrive.x86_64 0:2.4.15-1.el7 will be installed
|
||||
--> Finished Dependency Resolution
|
||||
|
||||
Dependencies Resolved
|
||||
|
@ -340,32 +153,32 @@ Dependencies Resolved
|
|||
Package Arch Version Repository Size
|
||||
==============================================================================================================================================================================================
|
||||
Installing:
|
||||
onedrive x86_64 2.4.0-1.el7 /onedrive-2.4.0-1.el7.x86_64 5.8 M
|
||||
onedrive x86_64 2.4.15-1.el7 /onedrive-2.4.15-1.el7.x86_64 7.2 M
|
||||
|
||||
Transaction Summary
|
||||
==============================================================================================================================================================================================
|
||||
Install 1 Package
|
||||
|
||||
Total size: 5.8 M
|
||||
Installed size: 5.8 M
|
||||
Total size: 7.2 M
|
||||
Installed size: 7.2 M
|
||||
Downloading packages:
|
||||
Running transaction check
|
||||
Running transaction test
|
||||
Transaction test succeeded
|
||||
Running transaction
|
||||
Installing : onedrive-2.4.0-1.el7.x86_64 1/1
|
||||
Verifying : onedrive-2.4.0-1.el7.x86_64 1/1
|
||||
Installing : onedrive-2.4.15-1.el7.x86_64 1/1
|
||||
Verifying : onedrive-2.4.15-1.el7.x86_64 1/1
|
||||
|
||||
Installed:
|
||||
onedrive.x86_64 0:2.4.0-1.el7
|
||||
onedrive.x86_64 0:2.4.15-1.el7
|
||||
|
||||
Complete!
|
||||
[alex@localhost ~]$ which onedrive
|
||||
/usr/bin/onedrive
|
||||
[alex@localhost ~]$ onedrive --version
|
||||
onedrive v2.4.0
|
||||
onedrive v2.4.15
|
||||
[alex@localhost ~]$ onedrive --display-config
|
||||
onedrive version = v2.4.0
|
||||
onedrive version = v2.4.15
|
||||
Config path = /home/alex/.config/onedrive
|
||||
Config file found in config path = false
|
||||
Config option 'check_nosync' = false
|
||||
|
@ -374,34 +187,38 @@ Config option 'skip_dir' =
|
|||
Config option 'skip_file' = ~*|.~*|*.tmp
|
||||
Config option 'skip_dotfiles' = false
|
||||
Config option 'skip_symlinks' = false
|
||||
Config option 'monitor_interval' = 45
|
||||
Config option 'monitor_interval' = 300
|
||||
Config option 'min_notify_changes' = 5
|
||||
Config option 'log_dir' = /var/log/onedrive/
|
||||
Config option 'classify_as_big_delete' = 1000
|
||||
Config option 'upload_only' = false
|
||||
Config option 'no_remote_delete' = false
|
||||
Config option 'remove_source_files' = false
|
||||
Config option 'sync_root_files' = false
|
||||
Selective sync configured = false
|
||||
Selective sync 'sync_list' configured = false
|
||||
Business Shared Folders configured = false
|
||||
[alex@localhost ~]$
|
||||
```
|
||||
|
||||
### CentOS 8
|
||||
```text
|
||||
[alex@localhost ~]$ rpmbuild -ba ~/rpmbuild/SPECS/onedrive.spec
|
||||
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.5LOfYv
|
||||
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.UINFyE
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ rm -rf onedrive-2.4.0
|
||||
+ /usr/bin/gzip -dc /home/alex/rpmbuild/SOURCES/v2.4.0.tar.gz
|
||||
+ rm -rf onedrive-2.4.15
|
||||
+ /usr/bin/gzip -dc /home/alex/rpmbuild/SOURCES/v2.4.15.tar.gz
|
||||
+ /usr/bin/tar -xof -
|
||||
+ STATUS=0
|
||||
+ '[' 0 -ne 0 ']'
|
||||
+ cd onedrive-2.4.0
|
||||
+ cd onedrive-2.4.15
|
||||
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
|
||||
+ exit 0
|
||||
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.HRIOjX
|
||||
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.cX1WQa
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd onedrive-2.4.0
|
||||
+ cd onedrive-2.4.15
|
||||
+ CFLAGS='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
|
||||
+ export CFLAGS
|
||||
+ CXXFLAGS='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
|
||||
|
@ -424,7 +241,7 @@ checking for a BSD-compatible install... /usr/bin/install -c
|
|||
checking for x86_64-redhat-linux-gnu-pkg-config... /usr/bin/x86_64-redhat-linux-gnu-pkg-config
|
||||
checking pkg-config is at least version 0.9.0... yes
|
||||
checking for dmd... dmd
|
||||
checking version of D compiler... 2.091.0
|
||||
checking version of D compiler... 2.087.0
|
||||
checking for curl... yes
|
||||
checking for sqlite... yes
|
||||
configure: creating ./config.status
|
||||
|
@ -439,31 +256,31 @@ configure: WARNING: unrecognized options: --disable-dependency-tracking
|
|||
if [ -f .git/HEAD ] ; then \
|
||||
git describe --tags > version ; \
|
||||
else \
|
||||
echo v2.4.0 > version ; \
|
||||
echo v2.4.15 > version ; \
|
||||
fi
|
||||
dmd -w -g -O -J. -L-lcurl -L-lsqlite3 -L-ldl src/config.d src/itemdb.d src/log.d src/main.d src/monitor.d src/onedrive.d src/qxor.d src/selective.d src/sqlite.d src/sync.d src/upload.d src/util.d src/progress.d -ofonedrive
|
||||
dmd -w -g -O -J. -L-lcurl -L-lsqlite3 -L-ldl src/config.d src/itemdb.d src/log.d src/main.d src/monitor.d src/onedrive.d src/qxor.d src/selective.d src/sqlite.d src/sync.d src/upload.d src/util.d src/progress.d src/arsd/cgi.d -ofonedrive
|
||||
+ exit 0
|
||||
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.u9F8Hd
|
||||
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.dNFPdx
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ '[' /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64 '!=' / ']'
|
||||
+ rm -rf /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64
|
||||
++ dirname /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64
|
||||
+ '[' /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64 '!=' / ']'
|
||||
+ rm -rf /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64
|
||||
++ dirname /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64
|
||||
+ mkdir -p /home/alex/rpmbuild/BUILDROOT
|
||||
+ mkdir /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64
|
||||
+ cd onedrive-2.4.0
|
||||
+ /usr/bin/make install DESTDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64 'INSTALL=/usr/bin/install -p' PREFIX=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64
|
||||
/usr/bin/install -p -D onedrive /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/bin/onedrive
|
||||
/usr/bin/install -p -D onedrive.1 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/share/man/man1/onedrive.1
|
||||
/usr/bin/install -p -D -m 644 contrib/logrotate/onedrive.logrotate /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/etc/logrotate.d/onedrive
|
||||
mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/share/doc/onedrive
|
||||
/usr/bin/install -p -D -m 644 README.md config LICENSE CHANGELOG.md docs/Docker.md docs/INSTALL.md docs/SharePoint-Shared-Libraries.md docs/USAGE.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/share/doc/onedrive
|
||||
/usr/bin/install -p -d -m 0755 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/lib/systemd/user /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/lib/systemd/system
|
||||
/usr/bin/install -p -m 0644 contrib/systemd/onedrive@.service /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/lib/systemd/system
|
||||
/usr/bin/install -p -m 0644 contrib/systemd/onedrive.service /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/lib/systemd/system
|
||||
+ mkdir /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64
|
||||
+ cd onedrive-2.4.15
|
||||
+ /usr/bin/make install DESTDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64 'INSTALL=/usr/bin/install -p' PREFIX=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64
|
||||
/usr/bin/install -p -D onedrive /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/bin/onedrive
|
||||
/usr/bin/install -p -D onedrive.1 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/share/man/man1/onedrive.1
|
||||
/usr/bin/install -p -D -m 644 contrib/logrotate/onedrive.logrotate /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/etc/logrotate.d/onedrive
|
||||
mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/share/doc/onedrive
|
||||
/usr/bin/install -p -D -m 644 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 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/share/doc/onedrive
|
||||
/usr/bin/install -p -d -m 0755 /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/lib/systemd/user /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/lib/systemd/system
|
||||
/usr/bin/install -p -m 0644 contrib/systemd/onedrive@.service /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/lib/systemd/system
|
||||
/usr/bin/install -p -m 0644 contrib/systemd/onedrive.service /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/lib/systemd/system
|
||||
+ /usr/lib/rpm/check-buildroot
|
||||
+ /usr/lib/rpm/redhat/brp-ldconfig
|
||||
/sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/etc/ld.so.conf: No such file or directory
|
||||
/sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/etc/ld.so.conf: No such file or directory
|
||||
+ /usr/lib/rpm/brp-compress
|
||||
+ /usr/lib/rpm/brp-strip /usr/bin/strip
|
||||
+ /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
|
||||
|
@ -472,53 +289,53 @@ mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/share/doc
|
|||
+ /usr/lib/rpm/brp-python-hardlink
|
||||
+ PYTHON3=/usr/libexec/platform-python
|
||||
+ /usr/lib/rpm/redhat/brp-mangle-shebangs
|
||||
Processing files: onedrive-2.4.0-1.el8.x86_64
|
||||
Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.zi889w
|
||||
Processing files: onedrive-2.4.15-1.el8.x86_64
|
||||
Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.TnFKbZ
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd onedrive-2.4.0
|
||||
+ DOCDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ cd onedrive-2.4.15
|
||||
+ DOCDIR=/home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ export LC_ALL=C
|
||||
+ LC_ALL=C
|
||||
+ export DOCDIR
|
||||
+ /usr/bin/mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ cp -pr README.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ cp -pr LICENSE /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ cp -pr CHANGELOG.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ /usr/bin/mkdir -p /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ cp -pr README.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ cp -pr LICENSE /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ cp -pr CHANGELOG.md /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64/usr/share/doc/onedrive
|
||||
+ exit 0
|
||||
warning: File listed twice: /usr/share/doc/onedrive
|
||||
warning: File listed twice: /usr/share/doc/onedrive/CHANGELOG.md
|
||||
warning: File listed twice: /usr/share/doc/onedrive/LICENSE
|
||||
warning: File listed twice: /usr/share/doc/onedrive/README.md
|
||||
Provides: config(onedrive) = 2.4.0-1.el8 onedrive = 2.4.0-1.el8 onedrive(x86-64) = 2.4.0-1.el8
|
||||
Provides: config(onedrive) = 2.4.15-1.el8 onedrive = 2.4.15-1.el8 onedrive(x86-64) = 2.4.15-1.el8
|
||||
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
|
||||
Requires(post): systemd
|
||||
Requires(preun): systemd
|
||||
Requires(postun): systemd
|
||||
Requires: ld-linux-x86-64.so.2()(64bit) ld-linux-x86-64.so.2(GLIBC_2.3)(64bit) libc.so.6()(64bit) libc.so.6(GLIBC_2.14)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3.2)(64bit) libc.so.6(GLIBC_2.4)(64bit) libc.so.6(GLIBC_2.6)(64bit) libcurl.so.4()(64bit) libdl.so.2()(64bit) libdl.so.2(GLIBC_2.2.5)(64bit) libgcc_s.so.1()(64bit) libgcc_s.so.1(GCC_3.0)(64bit) libgcc_s.so.1(GCC_4.2.0)(64bit) libm.so.6()(64bit) libm.so.6(GLIBC_2.2.5)(64bit) libpthread.so.0()(64bit) libpthread.so.0(GLIBC_2.2.5)(64bit) libpthread.so.0(GLIBC_2.3.2)(64bit) libpthread.so.0(GLIBC_2.3.3)(64bit) libpthread.so.0(GLIBC_2.3.4)(64bit) librt.so.1()(64bit) librt.so.1(GLIBC_2.2.5)(64bit) libsqlite3.so.0()(64bit) rtld(GNU_HASH)
|
||||
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.0-1.el8.x86_64
|
||||
Wrote: /home/alex/rpmbuild/SRPMS/onedrive-2.4.0-1.el8.src.rpm
|
||||
Wrote: /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el8.x86_64.rpm
|
||||
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.XEoFDV
|
||||
Requires: ld-linux-x86-64.so.2()(64bit) ld-linux-x86-64.so.2(GLIBC_2.3)(64bit) libc.so.6()(64bit) libc.so.6(GLIBC_2.14)(64bit) libc.so.6(GLIBC_2.15)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3.2)(64bit) libc.so.6(GLIBC_2.3.4)(64bit) libc.so.6(GLIBC_2.4)(64bit) libc.so.6(GLIBC_2.6)(64bit) libc.so.6(GLIBC_2.8)(64bit) libc.so.6(GLIBC_2.9)(64bit) libcurl.so.4()(64bit) libdl.so.2()(64bit) libdl.so.2(GLIBC_2.2.5)(64bit) libgcc_s.so.1()(64bit) libgcc_s.so.1(GCC_3.0)(64bit) libgcc_s.so.1(GCC_4.2.0)(64bit) libm.so.6()(64bit) libm.so.6(GLIBC_2.2.5)(64bit) libpthread.so.0()(64bit) libpthread.so.0(GLIBC_2.2.5)(64bit) libpthread.so.0(GLIBC_2.3.2)(64bit) libpthread.so.0(GLIBC_2.3.4)(64bit) librt.so.1()(64bit) librt.so.1(GLIBC_2.2.5)(64bit) libsqlite3.so.0()(64bit) rtld(GNU_HASH)
|
||||
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/alex/rpmbuild/BUILDROOT/onedrive-2.4.15-1.el8.x86_64
|
||||
Wrote: /home/alex/rpmbuild/SRPMS/onedrive-2.4.15-1.el8.src.rpm
|
||||
Wrote: /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.15-1.el8.x86_64.rpm
|
||||
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.FAMTFz
|
||||
+ umask 022
|
||||
+ cd /home/alex/rpmbuild/BUILD
|
||||
+ cd onedrive-2.4.0
|
||||
+ cd onedrive-2.4.15
|
||||
+ exit 0
|
||||
[alex@localhost ~]$ sudo yum -y install /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.0-1.el8.x86_64.rpm
|
||||
Last metadata expiration check: 0:34:12 ago on Fri 17 Apr 2020 18:11:23 EDT.
|
||||
[alex@localhost ~]$ sudo yum -y install /home/alex/rpmbuild/RPMS/x86_64/onedrive-2.4.15-1.el8.x86_64.rpm
|
||||
Last metadata expiration check: 0:04:07 ago on Fri 14 Jan 2022 14:22:13 EST.
|
||||
Dependencies resolved.
|
||||
==============================================================================================================================================================================================
|
||||
Package Architecture Version Repository Size
|
||||
==============================================================================================================================================================================================
|
||||
Installing:
|
||||
onedrive x86_64 2.4.0-1.el8 @commandline 1.2 M
|
||||
onedrive x86_64 2.4.15-1.el8 @commandline 1.5 M
|
||||
|
||||
Transaction Summary
|
||||
==============================================================================================================================================================================================
|
||||
Install 1 Package
|
||||
|
||||
Total size: 1.2 M
|
||||
Installed size: 5.7 M
|
||||
Total size: 1.5 M
|
||||
Installed size: 7.1 M
|
||||
Downloading Packages:
|
||||
Running transaction check
|
||||
Transaction check succeeded.
|
||||
|
@ -526,20 +343,20 @@ Running transaction test
|
|||
Transaction test succeeded.
|
||||
Running transaction
|
||||
Preparing : 1/1
|
||||
Installing : onedrive-2.4.0-1.el8.x86_64 1/1
|
||||
Running scriptlet: onedrive-2.4.0-1.el8.x86_64 1/1
|
||||
Verifying : onedrive-2.4.0-1.el8.x86_64 1/1
|
||||
Installing : onedrive-2.4.15-1.el8.x86_64 1/1
|
||||
Running scriptlet: onedrive-2.4.15-1.el8.x86_64 1/1
|
||||
Verifying : onedrive-2.4.15-1.el8.x86_64 1/1
|
||||
|
||||
Installed:
|
||||
onedrive-2.4.0-1.el8.x86_64
|
||||
onedrive-2.4.15-1.el8.x86_64
|
||||
|
||||
Complete!
|
||||
[alex@localhost ~]$ which onedrive
|
||||
/usr/bin/onedrive
|
||||
[alex@localhost ~]$ onedrive --version
|
||||
onedrive v2.4.0
|
||||
onedrive v2.4.15
|
||||
[alex@localhost ~]$ onedrive --display-config
|
||||
onedrive version = v2.4.0
|
||||
onedrive version = v2.4.15
|
||||
Config path = /home/alex/.config/onedrive
|
||||
Config file found in config path = false
|
||||
Config option 'check_nosync' = false
|
||||
|
@ -548,11 +365,15 @@ Config option 'skip_dir' =
|
|||
Config option 'skip_file' = ~*|.~*|*.tmp
|
||||
Config option 'skip_dotfiles' = false
|
||||
Config option 'skip_symlinks' = false
|
||||
Config option 'monitor_interval' = 45
|
||||
Config option 'monitor_interval' = 300
|
||||
Config option 'min_notify_changes' = 5
|
||||
Config option 'log_dir' = /var/log/onedrive/
|
||||
Config option 'classify_as_big_delete' = 1000
|
||||
Config option 'upload_only' = false
|
||||
Config option 'no_remote_delete' = false
|
||||
Config option 'remove_source_files' = false
|
||||
Config option 'sync_root_files' = false
|
||||
Selective sync configured = false
|
||||
Selective sync 'sync_list' configured = false
|
||||
Business Shared Folders configured = false
|
||||
[alex@localhost ~]$
|
||||
```
|
Binary file not shown.
Before Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.4 KiB |
325
docs/ubuntu-package-install.md
Normal file
325
docs/ubuntu-package-install.md
Normal file
|
@ -0,0 +1,325 @@
|
|||
# Installation of 'onedrive' package on Debian and Ubuntu
|
||||
|
||||
This document covers the appropriate steps to install the 'onedrive' client using the provided packages for Debian and Ubuntu.
|
||||
|
||||
#### Important information for all Ubuntu and Ubuntu based distribution users:
|
||||
This information is specifically for the following platforms and distributions:
|
||||
* Ubuntu
|
||||
* Lubuntu
|
||||
* Linux Mint
|
||||
* POP OS
|
||||
* Peppermint OS
|
||||
|
||||
Whilst there are [onedrive](https://packages.ubuntu.com/search?keywords=onedrive&searchon=names&suite=all§ion=all) Universe packages available for Ubuntu, do not install 'onedrive' from these Universe packages. The default Ubuntu Universe packages are out-of-date and are not supported and should not be used.
|
||||
|
||||
## 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.
|
||||
|
||||
To remove the PPA repository and the older client, perform the following actions:
|
||||
```text
|
||||
sudo apt remove onedrive
|
||||
sudo add-apt-repository --remove ppa:yann1ck/onedrive
|
||||
```
|
||||
|
||||
### Step 2: Ensure your system is up-to-date
|
||||
Use a script, similar to the following to ensure your system is updated correctly:
|
||||
```text
|
||||
#!/bin/bash
|
||||
rm -rf /var/lib/dpkg/lock-frontend
|
||||
rm -rf /var/lib/dpkg/lock
|
||||
apt-get update
|
||||
apt-get upgrade -y
|
||||
apt-get dist-upgrade -y
|
||||
apt-get autoremove -y
|
||||
apt-get autoclean -y
|
||||
```
|
||||
|
||||
Run this script as 'root' by using `su -` to elevate to 'root'. Example below:
|
||||
```text
|
||||
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-48-generic x86_64)
|
||||
|
||||
* Documentation: https://help.ubuntu.com
|
||||
* Management: https://landscape.canonical.com
|
||||
* Support: https://ubuntu.com/advantage
|
||||
|
||||
425 updates can be installed immediately.
|
||||
208 of these updates are security updates.
|
||||
To see these additional updates run: apt list --upgradable
|
||||
|
||||
Your Hardware Enablement Stack (HWE) is supported until April 2025.
|
||||
Last login: Thu Jan 20 14:21:48 2022 from my.ip.address
|
||||
alex@ubuntu-20-LTS:~$ su -
|
||||
Password:
|
||||
root@ubuntu-20-LTS:~# ls -la
|
||||
total 28
|
||||
drwx------ 3 root root 4096 Oct 10 2020 .
|
||||
drwxr-xr-x 20 root root 4096 Oct 10 2020 ..
|
||||
-rw------- 1 root root 175 Jan 20 14:23 .bash_history
|
||||
-rw-r--r-- 1 root root 3106 Dec 6 2019 .bashrc
|
||||
drwx------ 2 root root 4096 Apr 23 2020 .cache
|
||||
-rw-r--r-- 1 root root 161 Dec 6 2019 .profile
|
||||
-rwxr-xr-x 1 root root 174 Oct 10 2020 update-os.sh
|
||||
root@ubuntu-20-LTS:~# cat update-os.sh
|
||||
#!/bin/bash
|
||||
rm -rf /var/lib/dpkg/lock-frontend
|
||||
rm -rf /var/lib/dpkg/lock
|
||||
apt-get update
|
||||
apt-get upgrade -y
|
||||
apt-get dist-upgrade -y
|
||||
apt-get autoremove -y
|
||||
apt-get autoclean -y
|
||||
root@ubuntu-20-LTS:~# ./update-os.sh
|
||||
Hit:1 http://au.archive.ubuntu.com/ubuntu focal InRelease
|
||||
Hit:2 http://au.archive.ubuntu.com/ubuntu focal-updates InRelease
|
||||
Hit:3 http://au.archive.ubuntu.com/ubuntu focal-backports InRelease
|
||||
Hit:4 http://security.ubuntu.com/ubuntu focal-security InRelease
|
||||
Reading package lists... 96%
|
||||
...
|
||||
Sourcing file `/etc/default/grub'
|
||||
Sourcing file `/etc/default/grub.d/init-select.cfg'
|
||||
Generating grub configuration file ...
|
||||
Found linux image: /boot/vmlinuz-5.13.0-27-generic
|
||||
Found initrd image: /boot/initrd.img-5.13.0-27-generic
|
||||
Found linux image: /boot/vmlinuz-5.4.0-48-generic
|
||||
Found initrd image: /boot/initrd.img-5.4.0-48-generic
|
||||
Found memtest86+ image: /boot/memtest86+.elf
|
||||
Found memtest86+ image: /boot/memtest86+.bin
|
||||
done
|
||||
Removing linux-modules-5.4.0-26-generic (5.4.0-26.30) ...
|
||||
Processing triggers for libc-bin (2.31-0ubuntu9.2) ...
|
||||
Reading package lists... Done
|
||||
Building dependency tree
|
||||
Reading state information... Done
|
||||
root@ubuntu-20-LTS:~#
|
||||
```
|
||||
|
||||
Reboot your system after running this process before continuing with Step 2.
|
||||
```text
|
||||
reboot
|
||||
```
|
||||
|
||||
|
||||
### Step 3: Determine what your OS is based on
|
||||
Determine what your OS is based on. To do this, run the following command:
|
||||
```text
|
||||
lsb_release -a
|
||||
```
|
||||
|
||||
### Step 4: Pick the correct instructions to use
|
||||
If required, review the table below based on your 'lsb_release' information to pick the appropriate instructions to use:
|
||||
|
||||
| Release & Codename | Instructions to use |
|
||||
|--------------------|---------------------|
|
||||
| Ubuntu 18.x / bionic | You must build from source or upgrade your Operating System Ubuntu 22.x |
|
||||
| Linux Mint 19.x / tina | You must build from source or upgrade your Operating System Linux Mint 20.x |
|
||||
| Linux Mint 20.x / ulyana | Use [Ubuntu 20.04](#distribution-ubuntu-2004) instructions below |
|
||||
| Debian 10 | Use [Debian 10](#distribution-debian-10) instructions below |
|
||||
| Debian 11 | Use [Debian 11](#distribution-debian-11) instructions below |
|
||||
| Ubuntu 20.04 | Use [Ubuntu 20.04](#distribution-ubuntu-2004) instructions below |
|
||||
| Ubuntu 21.04 | Use [Ubuntu 21.04](#distribution-ubuntu-2104) instructions below |
|
||||
| Ubuntu 21.10 | Use [Ubuntu 21.10](#distribution-ubuntu-2110) instructions below |
|
||||
| Ubuntu 22.04 | Use [Ubuntu 22.04](#distribution-ubuntu-2204) instructions below |
|
||||
|
||||
## Distribution Package Install Instructions
|
||||
|
||||
### Distribution: Debian 10
|
||||
The packages support the following platform architectures:
|
||||
| i686 | 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_10/Release.key | sudo apt-key add -
|
||||
```
|
||||
|
||||
#### Step 2: Add the OpenSuSE Build Service repository
|
||||
Add the OpenSuSE Build Service repository using the following command:
|
||||
```text
|
||||
echo 'deb https://download.opensuse.org/repositories/home:/npreining:/debian-ubuntu-onedrive/Debian_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 onedrive`
|
||||
|
||||
#### Step 5: Read 'Known Issues' with these packages
|
||||
Read and understand the known issues with these packages below, taking any action that is needed.
|
||||
|
||||
### Distribution: Debian 11
|
||||
The packages support the following platform architectures:
|
||||
| i686 | 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_11/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_11/ ./" | 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 onedrive`
|
||||
|
||||
#### Step 5: Read 'Known Issues' with these packages
|
||||
Read and understand the known issues with these packages below, taking any action that is needed.
|
||||
|
||||
### Distribution: Ubuntu 20.04
|
||||
The packages support the following platform architectures:
|
||||
| i686 | 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_20.04/Release.key | sudo apt-key add -
|
||||
```
|
||||
|
||||
#### Step 2: Add the OpenSuSE Build Service repository
|
||||
Add the OpenSuSE Build Service repository using the following command:
|
||||
```text
|
||||
echo 'deb https://download.opensuse.org/repositories/home:/npreining:/debian-ubuntu-onedrive/xUbuntu_20.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 onedrive`
|
||||
|
||||
#### Step 5: Read 'Known Issues' with these packages
|
||||
Read and understand the known issues with these packages below, taking any action that is needed.
|
||||
|
||||
### Distribution: Ubuntu 21.04
|
||||
The packages support the following platform architectures:
|
||||
| i686 | 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_21.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_21.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 onedrive`
|
||||
|
||||
#### Step 5: Read 'Known Issues' with these packages
|
||||
Read and understand the known issues with these packages below, taking any action that is needed.
|
||||
|
||||
### Distribution: Ubuntu 21.10
|
||||
The packages support the following platform architectures:
|
||||
| i686 | 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_21.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_21.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 onedrive`
|
||||
|
||||
#### Step 5: Read 'Known Issues' with these packages
|
||||
Read and understand the known issues with these packages below, taking any action that is needed.
|
||||
|
||||
### Distribution: Ubuntu 22.04
|
||||
The packages support the following platform architectures:
|
||||
| i686 | 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_22.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_22.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 onedrive`
|
||||
|
||||
#### Step 5: Read 'Known Issues' with these packages
|
||||
Read and understand the known issues with these packages below, taking any action that is needed.
|
||||
|
||||
## Known Issues with Installing from the above packages
|
||||
|
||||
### 1. The 'onedrive' client will automatically startup post 'authentication' without any further actions.
|
||||
The 'onedrive' client will automatically startup post 'authentication' without any further actions. In some circumstances this may be highly undesirable and can also lead to data loss.
|
||||
|
||||
This is because, when the package is installed, the following symbolic link is created:
|
||||
```text
|
||||
Created symlink /etc/systemd/user/default.target.wants/onedrive.service → /usr/lib/systemd/user/onedrive.service.
|
||||
```
|
||||
|
||||
To resolve this, so that the client is *not* automatically started, without 'enabling' the client yourself, you need to remove this symbolic link:
|
||||
```
|
||||
sudo rm /etc/systemd/user/default.target.wants/onedrive.service
|
||||
```
|
||||
|
||||
This issue is being tracked by: [#1274](https://github.com/abraunegg/onedrive/issues/1274)
|
||||
|
||||
**Important:** It is highly advisable that you remove this symbolic link before you configure or authenticate your client. If you do not remove this symbolic link before you configure or authenticate your client this will be a major contributor to why the following error message will be generated:
|
||||
```
|
||||
ERROR: onedrive application is already running - check system process list for active application instances
|
||||
```
|
||||
|
||||
**Important:** Do not rely on this symbolic link for your systemd configuration to automatically start your onedrive client - refer to [Running 'onedrive' as a system service](https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md#running-onedrive-as-a-system-service) on how to configure this correctly.
|
||||
|
||||
### 2. The client will segfault | core-dump when exiting
|
||||
When the client is being run in `--monitor` mode manually, or when using the systemd service, the client will segfault on exit.
|
||||
|
||||
This issue is caused by the way the Ubuntu 'onedrive' packages are built using the Ubuntu LDC package & compiler options which is the root cause for this issue. Refer to: https://bugs.launchpad.net/ubuntu/+source/ldc/+bug/1895969
|
||||
|
||||
**Additional references:**
|
||||
* https://github.com/abraunegg/onedrive/issues/1053
|
||||
* https://github.com/abraunegg/onedrive/issues/1609
|
||||
|
||||
**Resolution Options:**
|
||||
* Uninstall the package and build client from source
|
||||
|
|
@ -23,6 +23,9 @@ Perform authorization via two files passed in as \fBARG\fP in the format \fBauth
|
|||
The authorization URL is written to the \fBauthUrl\fP, then \fBonedrive\fP waits for
|
||||
the file \fBresponseUrl\fP to be present, and reads the response from that file.
|
||||
.TP
|
||||
\fB\-\-auth\-response\fP ARG
|
||||
Perform authentication not via interactive dialog but via providing the reponse url directly.
|
||||
.TP
|
||||
\fB\-\-check\-for\-nomount\fP
|
||||
Check for the presence of .nosync in the syncdir root. If found, do not perform sync.
|
||||
.br
|
||||
|
@ -55,6 +58,11 @@ Configuration file key: \fBdebug_https\fP (default: \fBfalse\fP)
|
|||
\fB\-\-destination\-directory\fP ARG
|
||||
Destination directory for renamed or move on OneDrive \- no sync will be performed.
|
||||
.TP
|
||||
\fB\-\-disable\-download\-validation\fP
|
||||
Disable download validation when downloading from OneDrive
|
||||
.br
|
||||
Configuration file key: \fBdisable_download_validation\fP (default: \fBfalse\fP)
|
||||
.TP
|
||||
\fB\-\-disable\-notifications\fP
|
||||
Do not use desktop notifications in monitor mode
|
||||
.br
|
||||
|
@ -94,6 +102,11 @@ Force the use of HTTP/2 for all operations where applicable
|
|||
.br
|
||||
Configuration file key: \fBforce_http_2\fP (default: \fBfalse\fP)
|
||||
.TP
|
||||
\fB\-\-force\-sync\fP
|
||||
Force a synchronization of a specific folder, only when using --synchronize --single-directory and ignore
|
||||
.br
|
||||
all non-default skip_dir and skip_file rules
|
||||
.TP
|
||||
\fB\-\-get\-O365\-drive\-id\fP ARG
|
||||
Query and return the Office 365 Drive ID for a given Office 365 SharePoint Shared Library
|
||||
.TP
|
||||
|
@ -116,12 +129,15 @@ defines the directory where logging output is saved to, needs to end with a slas
|
|||
.br
|
||||
Configuration file key: \fBlog_dir\fP (default: \fB/var/log/onedrive/\fP)
|
||||
.TP
|
||||
\fB\-\-min-notify-changes\fP
|
||||
\fB\-\-min\-notify\-changes\fP
|
||||
the minimum number of pending incoming changes necessary to trigger
|
||||
a desktop notification
|
||||
.br
|
||||
Configuration file key: \fBmin_notify_changes\fP (default: \fB5\fP)
|
||||
.TP
|
||||
\fB\-m \-\-modified\-by\fP ARG
|
||||
Display the last modified by details of a given path
|
||||
.TP
|
||||
\fB\-m \-\-monitor\fP
|
||||
Keep monitoring for local and remote changes
|
||||
.TP
|
||||
|
@ -146,11 +162,16 @@ Do not delete local file 'deletes' from OneDrive when using \fB\-\-upload\-only\
|
|||
.br
|
||||
Configuration file key: \fBno_remote_delete\fP (default: \fBfalse\fP)
|
||||
.TP
|
||||
\fB\-\-operation\-timeout\fP ARG
|
||||
Set the maximum amount of time (seconds) a file operation is allowed to take. This includes DNS resolution, connecting, data transfer, etc.
|
||||
.br
|
||||
Configuration file key: \fBoperation_timeout\fP (default: \fB3600\fP)
|
||||
.TP
|
||||
\fB\-\-print\-token\fP
|
||||
Print the access token, useful for debugging
|
||||
.TP
|
||||
\fB\-\-resync\fP
|
||||
Forget the last saved state, perform a full sync
|
||||
\fB\-\-reauth\fP
|
||||
Reauthenticate the client with OneDrive
|
||||
.TP
|
||||
\fB\-\-remove\-directory\fP ARG
|
||||
Remove a directory on OneDrive \- no sync will be performed.
|
||||
|
@ -160,6 +181,12 @@ Remove source file after successful transfer to OneDrive when using \-\-upload-o
|
|||
.br
|
||||
Configuration file key: \fBremove_source_files\fP (default: \fBfalse\fP)
|
||||
.TP
|
||||
\fB\-\-resync\fP
|
||||
Forget the last saved state, perform a full sync
|
||||
.TP
|
||||
\fB\-\-resync\-auth\fP
|
||||
Approve the use of performing a --resync action without needing CLI authorization
|
||||
.TP
|
||||
\fB\-\-single\-directory\fP ARG
|
||||
Specify a single local directory within the OneDrive root to sync.
|
||||
.TP
|
||||
|
|
8
src/arsd/README.md
Normal file
8
src/arsd/README.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
The files in this directory have been obtained form the following places:
|
||||
|
||||
cgi.d
|
||||
https://github.com/adamdruppe/arsd/blob/a870179988b8881b04126856105f0fad2cc0018d/cgi.d
|
||||
License: Boost Software License - Version 1.0
|
||||
|
||||
Copyright 2008-2021, Adam D. Ruppe
|
||||
see https://github.com/adamdruppe/arsd/blob/a870179988b8881b04126856105f0fad2cc0018d/LICENSE
|
10488
src/arsd/cgi.d
Normal file
10488
src/arsd/cgi.d
Normal file
File diff suppressed because it is too large
Load diff
79
src/config.d
79
src/config.d
|
@ -59,6 +59,7 @@ final class Config
|
|||
boolValues["check_nosync"] = false;
|
||||
boolValues["download_only"] = false;
|
||||
boolValues["disable_notifications"] = false;
|
||||
boolValues["disable_download_validation"] = false;
|
||||
boolValues["disable_upload_validation"] = false;
|
||||
boolValues["enable_logging"] = false;
|
||||
boolValues["force_http_2"] = false;
|
||||
|
@ -75,9 +76,10 @@ final class Config
|
|||
longValues["skip_size"] = 0;
|
||||
longValues["min_notify_changes"] = 5;
|
||||
longValues["monitor_log_frequency"] = 5;
|
||||
// Number of n sync runs before performing a full local scan of sync_dir
|
||||
// By default 10 which means every ~7.5 minutes a full disk scan of sync_dir will occur
|
||||
longValues["monitor_fullscan_frequency"] = 10;
|
||||
// Number of N sync runs before performing a full local scan of sync_dir
|
||||
// By default 12 which means every ~60 minutes a full disk scan of sync_dir will occur
|
||||
// 'monitor_interval' * 'monitor_fullscan_frequency' = 3600 = 1 hour
|
||||
longValues["monitor_fullscan_frequency"] = 12;
|
||||
// Number of children in a path that is locally removed which will be classified as a 'big data delete'
|
||||
longValues["classify_as_big_delete"] = 1000;
|
||||
// Delete source after successful transfer
|
||||
|
@ -89,6 +91,8 @@ final class Config
|
|||
stringValues["application_id"] = "";
|
||||
// allow for resync to be set via config file
|
||||
boolValues["resync"] = false;
|
||||
// resync now needs to be acknowledged based on the 'risk' of using it
|
||||
boolValues["resync_auth"] = false;
|
||||
// Ignore data safety checks and overwrite local data rather than preserve & rename
|
||||
// This is a config file option ONLY
|
||||
boolValues["bypass_data_preservation"] = false;
|
||||
|
@ -118,6 +122,17 @@ 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;
|
||||
|
||||
// Webhook options
|
||||
boolValues["webhook_enabled"] = false;
|
||||
stringValues["webhook_public_url"] = "";
|
||||
stringValues["webhook_listening_host"] = "";
|
||||
longValues["webhook_listening_port"] = 8888;
|
||||
longValues["webhook_expiration_interval"] = 3600 * 24;
|
||||
longValues["webhook_renewal_interval"] = 3600 * 12;
|
||||
|
||||
// DEVELOPER OPTIONS
|
||||
// display_memory = true | false
|
||||
|
@ -201,8 +216,8 @@ final class Config
|
|||
}
|
||||
|
||||
// configDirName has a trailing /
|
||||
log.vlog("Using 'user' Config Dir: ", configDirName);
|
||||
log.vlog("Using 'system' Config Dir: ", systemConfigDirName);
|
||||
if (!configDirName.empty) log.vlog("Using 'user' Config Dir: ", configDirName);
|
||||
if (!systemConfigDirName.empty) log.vlog("Using 'system' Config Dir: ", systemConfigDirName);
|
||||
|
||||
// Update application set variables based on configDirName
|
||||
refreshTokenFilePath = buildNormalizedPath(configDirName ~ "/refresh_token");
|
||||
|
@ -272,19 +287,23 @@ final class Config
|
|||
stringValues["create_share_link"] = "";
|
||||
stringValues["destination_directory"] = "";
|
||||
stringValues["get_file_link"] = "";
|
||||
stringValues["modified_by"] = "";
|
||||
stringValues["get_o365_drive_id"] = "";
|
||||
stringValues["remove_directory"] = "";
|
||||
stringValues["single_directory"] = "";
|
||||
stringValues["source_directory"] = "";
|
||||
stringValues["auth_files"] = "";
|
||||
stringValues["auth_response"] = "";
|
||||
boolValues["display_config"] = false;
|
||||
boolValues["display_sync_status"] = false;
|
||||
boolValues["print_token"] = false;
|
||||
boolValues["logout"] = false;
|
||||
boolValues["reauth"] = false;
|
||||
boolValues["monitor"] = false;
|
||||
boolValues["synchronize"] = false;
|
||||
boolValues["force"] = false;
|
||||
boolValues["list_business_shared_folders"] = false;
|
||||
boolValues["force_sync"] = false;
|
||||
|
||||
// Application Startup option validation
|
||||
try {
|
||||
|
@ -300,6 +319,9 @@ final class Config
|
|||
"auth-files",
|
||||
"Perform authentication not via interactive dialog but via files read/writes to these files.",
|
||||
&stringValues["auth_files"],
|
||||
"auth-response",
|
||||
"Perform authentication not via interactive dialog but via providing the reponse url directly.",
|
||||
&stringValues["auth_response"],
|
||||
"check-for-nomount",
|
||||
"Check for the presence of .nosync in the syncdir root. If found, do not perform sync.",
|
||||
&boolValues["check_nomount"],
|
||||
|
@ -324,6 +346,9 @@ final class Config
|
|||
"disable-notifications",
|
||||
"Do not use desktop notifications in monitor mode.",
|
||||
&boolValues["disable_notifications"],
|
||||
"disable-download-validation",
|
||||
"Disable download validation when downloading from OneDrive",
|
||||
&boolValues["disable_download_validation"],
|
||||
"disable-upload-validation",
|
||||
"Disable upload validation when uploading to OneDrive",
|
||||
&boolValues["disable_upload_validation"],
|
||||
|
@ -348,6 +373,9 @@ final class Config
|
|||
"force",
|
||||
"Force the deletion of data when a 'big delete' is detected",
|
||||
&boolValues["force"],
|
||||
"force-sync",
|
||||
"Force a synchronization of a specific folder, only when using --synchronize --single-directory and ignore all non-default skip_dir and skip_file rules",
|
||||
&boolValues["force_sync"],
|
||||
"get-file-link",
|
||||
"Display the file link of a synced file",
|
||||
&stringValues["get_file_link"],
|
||||
|
@ -366,6 +394,9 @@ final class Config
|
|||
"min-notify-changes",
|
||||
"Minimum number of pending incoming changes necessary to trigger a desktop notification",
|
||||
&longValues["min_notify_changes"],
|
||||
"modified-by",
|
||||
"Display the last modified by details of a given path",
|
||||
&stringValues["modified_by"],
|
||||
"monitor|m",
|
||||
"Keep monitoring for local and remote changes",
|
||||
&boolValues["monitor"],
|
||||
|
@ -381,12 +412,21 @@ 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"],
|
||||
"reauth",
|
||||
"Reauthenticate the client with OneDrive",
|
||||
&boolValues["reauth"],
|
||||
"resync",
|
||||
"Forget the last saved state, perform a full sync",
|
||||
&boolValues["resync"],
|
||||
"resync-auth",
|
||||
"Approve the use of performing a --resync action",
|
||||
&boolValues["resync_auth"],
|
||||
"remove-directory",
|
||||
"Remove a directory on OneDrive - no sync will be performed.",
|
||||
&stringValues["remove_directory"],
|
||||
|
@ -513,6 +553,16 @@ final class Config
|
|||
private bool load(string filename)
|
||||
{
|
||||
// configure function variables
|
||||
try {
|
||||
readText(filename);
|
||||
} catch (std.file.FileException e) {
|
||||
// Unable to access required file
|
||||
log.error("ERROR: Unable to access ", e.msg);
|
||||
// Use exit scopes to shutdown API
|
||||
return false;
|
||||
}
|
||||
|
||||
// We were able to readText the config file - so, we should be able to open and read it
|
||||
auto file = File(filename, "r");
|
||||
string lineBuffer;
|
||||
|
||||
|
@ -677,11 +727,27 @@ final class Config
|
|||
}
|
||||
return configuredFilePermissionMode;
|
||||
}
|
||||
|
||||
void resetSkipToDefaults() {
|
||||
// reset skip_file and skip_dir to application defaults
|
||||
// skip_file
|
||||
log.vdebug("original skip_file: ", getValueString("skip_file"));
|
||||
log.vdebug("resetting skip_file");
|
||||
setValueString("skip_file", defaultSkipFile);
|
||||
log.vdebug("reset skip_file: ", getValueString("skip_file"));
|
||||
// skip_dir
|
||||
log.vdebug("original skip_dir: ", getValueString("skip_dir"));
|
||||
log.vdebug("resetting skip_dir");
|
||||
setValueString("skip_dir", defaultSkipDir);
|
||||
log.vdebug("reset skip_dir: ", getValueString("skip_dir"));
|
||||
}
|
||||
}
|
||||
|
||||
void outputLongHelp(Option[] opt)
|
||||
{
|
||||
auto argsNeedingOptions = [
|
||||
"--auth-files",
|
||||
"--auth-response",
|
||||
"--confdir",
|
||||
"--create-directory",
|
||||
"--create-share-link",
|
||||
|
@ -690,12 +756,15 @@ void outputLongHelp(Option[] opt)
|
|||
"--get-O365-drive-id",
|
||||
"--log-dir",
|
||||
"--min-notify-changes",
|
||||
"--modified-by",
|
||||
"--monitor-interval",
|
||||
"--monitor-log-frequency",
|
||||
"--monitor-fullscan-frequency",
|
||||
"--remove-directory",
|
||||
"--single-directory",
|
||||
"--skip-dir",
|
||||
"--skip-file",
|
||||
"--skip-size",
|
||||
"--source-directory",
|
||||
"--syncdir",
|
||||
"--user-agent" ];
|
||||
|
|
12
src/itemdb.d
12
src/itemdb.d
|
@ -51,7 +51,13 @@ final class ItemDatabase
|
|||
dbVersion = db.getVersion();
|
||||
} catch (SqliteException e) {
|
||||
// An error was generated - what was the error?
|
||||
log.error("\nAn internal database error occurred: " ~ e.msg ~ "\n");
|
||||
if (e.msg == "database is locked") {
|
||||
log.error("\nERROR: onedrive application is already running - check system process list for active application instances");
|
||||
log.vlog(" - Use 'sudo ps aufxw | grep onedrive' to potentially determine acive running process");
|
||||
write("\n");
|
||||
} else {
|
||||
log.error("\nERROR: An internal database error occurred: " ~ e.msg ~ "\n");
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -84,6 +90,10 @@ final class ItemDatabase
|
|||
// https://www.sqlite.org/pragma.html#pragma_auto_vacuum
|
||||
// PRAGMA schema.auto_vacuum = 0 | NONE | 1 | FULL | 2 | INCREMENTAL;
|
||||
db.exec("PRAGMA auto_vacuum = FULL");
|
||||
// This pragma sets or queries the database connection locking-mode. The locking-mode is either NORMAL or EXCLUSIVE.
|
||||
// https://www.sqlite.org/pragma.html#pragma_locking_mode
|
||||
// PRAGMA schema.locking_mode = NORMAL | EXCLUSIVE
|
||||
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)
|
||||
|
|
14
src/log.d
14
src/log.d
|
@ -13,6 +13,7 @@ version(Notifications) {
|
|||
// enable verbose logging
|
||||
long verbose;
|
||||
bool writeLogFile = false;
|
||||
bool logFileWriteFailFlag = false;
|
||||
|
||||
private bool doNotifications;
|
||||
|
||||
|
@ -35,7 +36,7 @@ void init(string logDir)
|
|||
// we got an error ..
|
||||
writeln("\nUnable to access ", logFilePath);
|
||||
writeln("Please manually create '",logFilePath, "' and set appropriate permissions to allow write access");
|
||||
writeln("The requested client activity log will instead be located in the users home directory\n");
|
||||
writeln("The requested client activity log will instead be located in your users home directory");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +170,17 @@ private void logfileWriteLine(T...)(T args)
|
|||
// We cannot open the log file in logFilePath location for writing
|
||||
// The user is not part of the standard 'users' group (GID 100)
|
||||
// Change logfile to ~/onedrive.log putting the log file in the users home directory
|
||||
|
||||
if (!logFileWriteFailFlag) {
|
||||
// write out error message that we cant log to the requested file
|
||||
writeln("\nUnable to write activity log to ", logFileName);
|
||||
writeln("Please set appropriate permissions to allow write access to the logging directory for your user account");
|
||||
writeln("The requested client activity log will instead be located in your users home directory\n");
|
||||
|
||||
// set the flag so we dont keep printing this error message
|
||||
logFileWriteFailFlag = true;
|
||||
}
|
||||
|
||||
string homePath = environment.get("HOME");
|
||||
string logFileNameAlternate = homePath ~ "/onedrive.log";
|
||||
logFile = File(logFileNameAlternate, "a");
|
||||
|
|
440
src/main.d
440
src/main.d
|
@ -4,12 +4,14 @@ import std.getopt, std.file, std.path, std.process, std.stdio, std.conv, std.alg
|
|||
import config, itemdb, monitor, onedrive, selective, sync, util;
|
||||
import std.net.curl: CurlException;
|
||||
import core.stdc.signal;
|
||||
import std.traits;
|
||||
import std.traits, std.format;
|
||||
import std.concurrency: receiveTimeout;
|
||||
static import log;
|
||||
|
||||
OneDriveApi oneDrive;
|
||||
ItemDatabase itemDb;
|
||||
|
||||
bool onedriveInitialised = false;
|
||||
const int EXIT_UNAUTHORIZED = 3;
|
||||
|
||||
enum MONITOR_LOG_SILENT = 2;
|
||||
|
@ -48,10 +50,13 @@ int main(string[] args)
|
|||
bool skipDirDifferent = false;
|
||||
bool online = false;
|
||||
bool performSyncOK = false;
|
||||
bool onedriveInitialised = false;
|
||||
bool displayMemoryUsage = false;
|
||||
bool displaySyncOptions = false;
|
||||
|
||||
// hash file permission values
|
||||
string hashPermissionValue = "600";
|
||||
auto convertedPermissionValue = parse!long(hashPermissionValue, 8);
|
||||
|
||||
// Define scopes
|
||||
scope(exit) {
|
||||
// Display memory details
|
||||
|
@ -119,6 +124,7 @@ int main(string[] args)
|
|||
"verbose|v+", "Print more details, useful for debugging (repeat for extra debugging)", &log.verbose,
|
||||
"version", "Print the version and exit", &printVersion
|
||||
);
|
||||
|
||||
// print help and exit
|
||||
if (opt.helpWanted) {
|
||||
args ~= "--help";
|
||||
|
@ -131,12 +137,12 @@ int main(string[] args)
|
|||
} catch (GetOptException e) {
|
||||
// option errors
|
||||
log.error(e.msg);
|
||||
log.error("Try 'onedrive -h' for more information");
|
||||
log.error("Try 'onedrive --help' for more information");
|
||||
return EXIT_FAILURE;
|
||||
} catch (Exception e) {
|
||||
// generic error
|
||||
log.error(e.msg);
|
||||
log.error("Try 'onedrive -h' for more information");
|
||||
log.error("Try 'onedrive --help' for more information");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -148,6 +154,10 @@ int main(string[] args)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// How was this application started - what options were passed in
|
||||
log.vdebug("passed in options: ", args);
|
||||
log.vdebug("note --confdir and --verbose not listed in args");
|
||||
|
||||
// set memory display
|
||||
displayMemoryUsage = cfg.getValueBool("display_memory");
|
||||
|
||||
|
@ -157,6 +167,47 @@ int main(string[] args)
|
|||
// update configuration from command line args
|
||||
cfg.update_from_args(args);
|
||||
|
||||
// --resync should be a 'last resort item' .. the user needs to 'accept' to proceed
|
||||
if ((cfg.getValueBool("resync")) && (!cfg.getValueBool("display_config"))) {
|
||||
// what is the risk acceptance?
|
||||
bool resyncRiskAcceptance = false;
|
||||
|
||||
if (!cfg.getValueBool("resync_auth")) {
|
||||
// need to prompt user
|
||||
char response;
|
||||
// warning message
|
||||
writeln("\nThe use of --resync will remove your local 'onedrive' client state, thus no record will exist regarding your current 'sync status'");
|
||||
writeln("This has the potential to overwrite local versions of files with potentially older versions downloaded from OneDrive which can lead to data loss");
|
||||
writeln("If in-doubt, backup your local data first before proceeding with --resync");
|
||||
write("\nAre you sure you wish to proceed with --resync? [Y/N] ");
|
||||
|
||||
try {
|
||||
// Attempt to read user response
|
||||
readf(" %c\n", &response);
|
||||
} catch (std.format.FormatException e) {
|
||||
// Caught an error
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Evaluate user repsonse
|
||||
if ((to!string(response) == "y") || (to!string(response) == "Y")) {
|
||||
// User has accepted --resync risk to proceed
|
||||
resyncRiskAcceptance = true;
|
||||
// Are you sure you wish .. does not use writeln();
|
||||
write("\n");
|
||||
}
|
||||
} else {
|
||||
// resync_auth is true
|
||||
resyncRiskAcceptance = true;
|
||||
}
|
||||
|
||||
// Action based on response
|
||||
if (!resyncRiskAcceptance){
|
||||
// --resync risk not accepted
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialise normalised file paths
|
||||
configFilePath = buildNormalizedPath(cfg.configDirName ~ "/config");
|
||||
syncListFilePath = buildNormalizedPath(cfg.configDirName ~ "/sync_list");
|
||||
|
@ -176,18 +227,24 @@ int main(string[] args)
|
|||
if ((exists(configFilePath)) && (!exists(configHashFile))) {
|
||||
// Hash of config file needs to be created
|
||||
std.file.write(configHashFile, computeQuickXorHash(configFilePath));
|
||||
// Hash file should only be readable by the user who created it - 0600 permissions needed
|
||||
configHashFile.setAttributes(to!int(convertedPermissionValue));
|
||||
}
|
||||
|
||||
// Does a sync_list file exist with a valid hash file
|
||||
if ((exists(syncListFilePath)) && (!exists(syncListHashFile))) {
|
||||
// Hash of sync_list file needs to be created
|
||||
std.file.write(syncListHashFile, computeQuickXorHash(syncListFilePath));
|
||||
// Hash file should only be readable by the user who created it - 0600 permissions needed
|
||||
syncListHashFile.setAttributes(to!int(convertedPermissionValue));
|
||||
}
|
||||
|
||||
// check if business_shared_folders & business_shared_folders hash exists
|
||||
if ((exists(businessSharedFolderFilePath)) && (!exists(businessSharedFoldersHashFile))) {
|
||||
// Hash of business_shared_folders file needs to be created
|
||||
std.file.write(businessSharedFoldersHashFile, computeQuickXorHash(businessSharedFolderFilePath));
|
||||
// Hash file should only be readable by the user who created it - 0600 permissions needed
|
||||
businessSharedFoldersHashFile.setAttributes(to!int(convertedPermissionValue));
|
||||
}
|
||||
|
||||
// If hash files exist, but config files do not ... remove the hash, but only if --resync was issued as now the application will use 'defaults' which 'may' be different
|
||||
|
@ -214,9 +271,36 @@ int main(string[] args)
|
|||
if (exists(configFilePath)) currentConfigHash = computeQuickXorHash(configFilePath);
|
||||
if (exists(syncListFilePath)) currentSyncListHash = computeQuickXorHash(syncListFilePath);
|
||||
if (exists(businessSharedFolderFilePath)) currentBusinessSharedFoldersHash = computeQuickXorHash(businessSharedFolderFilePath);
|
||||
if (exists(configHashFile)) previousConfigHash = readText(configHashFile);
|
||||
if (exists(syncListHashFile)) previousSyncListHash = readText(syncListHashFile);
|
||||
if (exists(businessSharedFoldersHashFile)) previousBusinessSharedFoldersHash = readText(businessSharedFoldersHashFile);
|
||||
if (exists(configHashFile)) {
|
||||
try {
|
||||
previousConfigHash = readText(configHashFile);
|
||||
} catch (std.file.FileException e) {
|
||||
// Unable to access required file
|
||||
log.error("ERROR: Unable to access ", e.msg);
|
||||
// Use exit scopes to shutdown API
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
if (exists(syncListHashFile)) {
|
||||
try {
|
||||
previousSyncListHash = readText(syncListHashFile);
|
||||
} catch (std.file.FileException e) {
|
||||
// Unable to access required file
|
||||
log.error("ERROR: Unable to access ", e.msg);
|
||||
// Use exit scopes to shutdown API
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
if (exists(businessSharedFoldersHashFile)) {
|
||||
try {
|
||||
previousBusinessSharedFoldersHash = readText(businessSharedFoldersHashFile);
|
||||
} catch (std.file.FileException e) {
|
||||
// Unable to access required file
|
||||
log.error("ERROR: Unable to access ", e.msg);
|
||||
// Use exit scopes to shutdown API
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Was sync_list file updated?
|
||||
if (currentSyncListHash != previousSyncListHash) {
|
||||
|
@ -235,7 +319,10 @@ int main(string[] args)
|
|||
// Was config file updated between last execution ang this execution?
|
||||
if (currentConfigHash != previousConfigHash) {
|
||||
// config file was updated, however we only want to trigger a --resync requirement if sync_dir, skip_dir, skip_file or drive_id was modified
|
||||
if (!cfg.getValueBool("display_config")){
|
||||
// only print this message if we are not using --display-config
|
||||
log.log("config file has been updated, checking if --resync needed");
|
||||
}
|
||||
if (exists(configBackupFile)) {
|
||||
// check backup config what has changed for these configuration options if anything
|
||||
// # sync_dir = "~/OneDrive"
|
||||
|
@ -302,9 +389,13 @@ int main(string[] args)
|
|||
// update config hash
|
||||
log.vdebug("updating config hash as it is out of date");
|
||||
std.file.write(configHashFile, computeQuickXorHash(configFilePath));
|
||||
// Hash file should only be readable by the user who created it - 0600 permissions needed
|
||||
configHashFile.setAttributes(to!int(convertedPermissionValue));
|
||||
// create backup copy of current config file
|
||||
log.vdebug("making backup of config file as it is out of date");
|
||||
std.file.copy(configFilePath, configBackupFile);
|
||||
// File Copy should only be readable by the user who created it - 0600 permissions needed
|
||||
configBackupFile.setAttributes(to!int(convertedPermissionValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,6 +405,8 @@ int main(string[] args)
|
|||
if ((exists(configFilePath)) && (!exists(configBackupFile))) {
|
||||
// create backup copy of current config file
|
||||
std.file.copy(configFilePath, configBackupFile);
|
||||
// File Copy should only be readable by the user who created it - 0600 permissions needed
|
||||
configBackupFile.setAttributes(to!int(convertedPermissionValue));
|
||||
}
|
||||
|
||||
// config file set options can be changed via CLI input, specifically these will impact sync and --resync will be needed:
|
||||
|
@ -370,19 +463,27 @@ int main(string[] args)
|
|||
// update hash
|
||||
log.vdebug("updating config hash as --resync issued");
|
||||
std.file.write(configHashFile, computeQuickXorHash(configFilePath));
|
||||
// Hash file should only be readable by the user who created it - 0600 permissions needed
|
||||
configHashFile.setAttributes(to!int(convertedPermissionValue));
|
||||
// create backup copy of current config file
|
||||
log.vdebug("making backup of config file as --resync issued");
|
||||
std.file.copy(configFilePath, configBackupFile);
|
||||
// File copy should only be readable by the user who created it - 0600 permissions needed
|
||||
configBackupFile.setAttributes(to!int(convertedPermissionValue));
|
||||
}
|
||||
if (exists(syncListFilePath)) {
|
||||
// update sync_list hash
|
||||
log.vdebug("updating sync_list hash as --resync issued");
|
||||
std.file.write(syncListHashFile, computeQuickXorHash(syncListFilePath));
|
||||
// Hash file should only be readable by the user who created it - 0600 permissions needed
|
||||
syncListHashFile.setAttributes(to!int(convertedPermissionValue));
|
||||
}
|
||||
if (exists(businessSharedFolderFilePath)) {
|
||||
// update business_shared_folders hash
|
||||
log.vdebug("updating business_shared_folders hash as --resync issued");
|
||||
std.file.write(businessSharedFoldersHashFile, computeQuickXorHash(businessSharedFolderFilePath));
|
||||
// Hash file should only be readable by the user who created it - 0600 permissions needed
|
||||
businessSharedFoldersHashFile.setAttributes(to!int(convertedPermissionValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -498,20 +599,23 @@ int main(string[] args)
|
|||
cfg.setValueBool("resync", true);
|
||||
}
|
||||
|
||||
// Handle --resync and --logout to remove local files
|
||||
if (cfg.getValueBool("resync") || cfg.getValueBool("logout")) {
|
||||
if (cfg.getValueBool("resync")) log.vdebug("--resync requested");
|
||||
log.vlog("Deleting the saved status ...");
|
||||
if (!cfg.getValueBool("dry_run")) {
|
||||
safeRemove(cfg.databaseFilePath);
|
||||
safeRemove(cfg.deltaLinkFilePath);
|
||||
safeRemove(cfg.uploadStateFilePath);
|
||||
}
|
||||
// Handle --logout as separate item, do not 'resync' on a --logout
|
||||
if (cfg.getValueBool("logout")) {
|
||||
log.vdebug("--logout requested");
|
||||
log.log("Deleting the saved authentication status ...");
|
||||
if (!cfg.getValueBool("dry_run")) {
|
||||
safeRemove(cfg.refreshTokenFilePath);
|
||||
}
|
||||
// Exit
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Handle --reauth to re-authenticate the client
|
||||
if (cfg.getValueBool("reauth")) {
|
||||
log.vdebug("--reauth requested");
|
||||
log.log("Deleting the saved authentication status ... re-authentication requested");
|
||||
if (!cfg.getValueBool("dry_run")) {
|
||||
safeRemove(cfg.refreshTokenFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -524,49 +628,87 @@ int main(string[] args)
|
|||
// Does a config file exist or are we using application defaults
|
||||
writeln("Config file found in config path = ", exists(configFilePath));
|
||||
|
||||
// Config Options
|
||||
writeln("Config option 'check_nosync' = ", cfg.getValueBool("check_nosync"));
|
||||
writeln("Config option 'sync_dir' = ", syncDir);
|
||||
writeln("Config option 'skip_dir' = ", cfg.getValueString("skip_dir"));
|
||||
writeln("Config option 'skip_file' = ", cfg.getValueString("skip_file"));
|
||||
writeln("Config option 'skip_dotfiles' = ", cfg.getValueBool("skip_dotfiles"));
|
||||
writeln("Config option 'skip_symlinks' = ", cfg.getValueBool("skip_symlinks"));
|
||||
writeln("Config option 'monitor_interval' = ", cfg.getValueLong("monitor_interval"));
|
||||
writeln("Config option 'min_notify_changes' = ", cfg.getValueLong("min_notify_changes"));
|
||||
writeln("Config option 'log_dir' = ", cfg.getValueString("log_dir"));
|
||||
writeln("Config option 'classify_as_big_delete' = ", cfg.getValueLong("classify_as_big_delete"));
|
||||
writeln("Config option 'upload_only' = ", cfg.getValueBool("upload_only"));
|
||||
writeln("Config option 'no_remote_delete' = ", cfg.getValueBool("no_remote_delete"));
|
||||
writeln("Config option 'remove_source_files' = ", cfg.getValueBool("remove_source_files"));
|
||||
|
||||
// Is config option drive_id configured?
|
||||
if (cfg.getValueString("drive_id") != ""){
|
||||
writeln("Config option 'drive_id' = ", cfg.getValueString("drive_id"));
|
||||
}
|
||||
|
||||
// Config Options as per 'config' file
|
||||
writeln("Config option 'sync_dir' = ", syncDir);
|
||||
|
||||
// logging and notifications
|
||||
writeln("Config option 'enable_logging' = ", cfg.getValueBool("enable_logging"));
|
||||
writeln("Config option 'log_dir' = ", cfg.getValueString("log_dir"));
|
||||
writeln("Config option 'disable_notifications' = ", cfg.getValueBool("disable_notifications"));
|
||||
writeln("Config option 'min_notify_changes' = ", cfg.getValueLong("min_notify_changes"));
|
||||
|
||||
// skip files and directory and 'matching' policy
|
||||
writeln("Config option 'skip_dir' = ", cfg.getValueString("skip_dir"));
|
||||
writeln("Config option 'skip_dir_strict_match' = ", cfg.getValueBool("skip_dir_strict_match"));
|
||||
writeln("Config option 'skip_file' = ", cfg.getValueString("skip_file"));
|
||||
writeln("Config option 'skip_dotfiles' = ", cfg.getValueBool("skip_dotfiles"));
|
||||
writeln("Config option 'skip_symlinks' = ", cfg.getValueBool("skip_symlinks"));
|
||||
|
||||
// --monitor sync process options
|
||||
writeln("Config option 'monitor_interval' = ", cfg.getValueLong("monitor_interval"));
|
||||
writeln("Config option 'monitor_log_frequency' = ", cfg.getValueLong("monitor_log_frequency"));
|
||||
writeln("Config option 'monitor_fullscan_frequency' = ", cfg.getValueLong("monitor_fullscan_frequency"));
|
||||
|
||||
// sync process and method
|
||||
writeln("Config option 'dry_run' = ", cfg.getValueBool("dry_run"));
|
||||
writeln("Config option 'upload_only' = ", cfg.getValueBool("upload_only"));
|
||||
writeln("Config option 'download_only' = ", cfg.getValueBool("download_only"));
|
||||
writeln("Config option 'local_first' = ", cfg.getValueBool("local_first"));
|
||||
writeln("Config option 'check_nosync' = ", cfg.getValueBool("check_nosync"));
|
||||
writeln("Config option 'check_nomount' = ", cfg.getValueBool("check_nomount"));
|
||||
writeln("Config option 'resync' = ", cfg.getValueBool("resync"));
|
||||
writeln("Config option 'resync_auth' = ", cfg.getValueBool("resync_auth"));
|
||||
|
||||
// data integrity
|
||||
writeln("Config option 'classify_as_big_delete' = ", cfg.getValueLong("classify_as_big_delete"));
|
||||
writeln("Config option 'disable_upload_validation' = ", cfg.getValueBool("disable_upload_validation"));
|
||||
writeln("Config option 'bypass_data_preservation' = ", cfg.getValueBool("bypass_data_preservation"));
|
||||
writeln("Config option 'no_remote_delete' = ", cfg.getValueBool("no_remote_delete"));
|
||||
writeln("Config option 'remove_source_files' = ", cfg.getValueBool("remove_source_files"));
|
||||
writeln("Config option 'sync_dir_permissions' = ", cfg.getValueLong("sync_dir_permissions"));
|
||||
writeln("Config option 'sync_file_permissions' = ", cfg.getValueLong("sync_file_permissions"));
|
||||
|
||||
// curl operations
|
||||
writeln("Config option 'application_id' = ", cfg.getValueString("application_id"));
|
||||
writeln("Config option 'azure_ad_endpoint' = ", cfg.getValueString("azure_ad_endpoint"));
|
||||
writeln("Config option 'azure_tenant_id' = ", cfg.getValueString("azure_tenant_id"));
|
||||
writeln("Config option 'user_agent' = ", cfg.getValueString("user_agent"));
|
||||
writeln("Config option 'force_http_2' = ", cfg.getValueBool("force_http_2"));
|
||||
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"));
|
||||
|
||||
|
||||
// Is sync_list configured ?
|
||||
if (exists(syncListFilePath)){
|
||||
writeln("Config option 'sync_root_files' = ", cfg.getValueBool("sync_root_files"));
|
||||
if (exists(syncListFilePath)){
|
||||
|
||||
writeln("Selective sync 'sync_list' configured = true");
|
||||
writeln("sync_list contents:");
|
||||
// Output the sync_list contents
|
||||
auto syncListFile = File(syncListFilePath);
|
||||
auto syncListFile = File(syncListFilePath, "r");
|
||||
auto range = syncListFile.byLine();
|
||||
foreach (line; range)
|
||||
{
|
||||
writeln(line);
|
||||
}
|
||||
} else {
|
||||
writeln("Config option 'sync_root_files' = ", cfg.getValueBool("sync_root_files"));
|
||||
writeln("Selective sync 'sync_list' configured = false");
|
||||
|
||||
}
|
||||
|
||||
// Is business_shared_folders configured
|
||||
// Is business_shared_folders enabled and configured ?
|
||||
writeln("Config option 'sync_business_shared_folders' = ", cfg.getValueBool("sync_business_shared_folders"));
|
||||
if (exists(businessSharedFolderFilePath)){
|
||||
writeln("Business Shared Folders configured = true");
|
||||
writeln("business_shared_folders contents:");
|
||||
// Output the business_shared_folders contents
|
||||
auto businessSharedFolderFileList = File(businessSharedFolderFilePath);
|
||||
auto businessSharedFolderFileList = File(businessSharedFolderFilePath, "r");
|
||||
auto range = businessSharedFolderFileList.byLine();
|
||||
foreach (line; range)
|
||||
{
|
||||
|
@ -576,10 +718,38 @@ int main(string[] args)
|
|||
writeln("Business Shared Folders configured = false");
|
||||
}
|
||||
|
||||
// Are webhooks enabled?
|
||||
writeln("Config option 'webhook_enabled' = ", cfg.getValueBool("webhook_enabled"));
|
||||
if (cfg.getValueBool("webhook_enabled")) {
|
||||
writeln("Config option 'webhook_public_url' = ", cfg.getValueString("webhook_public_url"));
|
||||
writeln("Config option 'webhook_listening_host' = ", cfg.getValueString("webhook_listening_host"));
|
||||
writeln("Config option 'webhook_listening_port' = ", cfg.getValueLong("webhook_listening_port"));
|
||||
writeln("Config option 'webhook_expiration_interval' = ", cfg.getValueLong("webhook_expiration_interval"));
|
||||
writeln("Config option 'webhook_renewal_interval' = ", cfg.getValueLong("webhook_renewal_interval"));
|
||||
}
|
||||
|
||||
// Exit
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// --upload-only and --download-only are mutually exclusive and cannot be used together
|
||||
if ((cfg.getValueBool("upload_only")) && (cfg.getValueBool("download_only"))) {
|
||||
// both cannot be true at the same time
|
||||
writeln("ERROR: --upload-only and --download-only are mutually exclusive and cannot be used together.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Handle --resync to remove local files
|
||||
if (cfg.getValueBool("resync")) {
|
||||
log.vdebug("--resync requested");
|
||||
log.log("Deleting the saved application sync status ...");
|
||||
if (!cfg.getValueBool("dry_run")) {
|
||||
safeRemove(cfg.databaseFilePath);
|
||||
safeRemove(cfg.deltaLinkFilePath);
|
||||
safeRemove(cfg.uploadStateFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
@ -639,8 +809,12 @@ int main(string[] args)
|
|||
}
|
||||
}
|
||||
|
||||
// Initialize OneDrive, check for authorization
|
||||
// Check application version and Initialize OneDrive API, check for authorization
|
||||
if (online) {
|
||||
// Check Application Version
|
||||
log.vlog("Checking Application Version ...");
|
||||
checkApplicationVersion();
|
||||
|
||||
// we can only initialise if we are online
|
||||
log.vlog("Initializing the OneDrive API ...");
|
||||
oneDrive = new OneDriveApi(cfg);
|
||||
|
@ -661,7 +835,7 @@ int main(string[] args)
|
|||
|
||||
// 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("create_share_link") != "") || (cfg.getValueString("get_o365_drive_id") != "") || cfg.getValueBool("display_sync_status") || cfg.getValueBool("list_business_shared_folders")) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -673,7 +847,7 @@ 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 --help for further assistance in regards to running this application.\n");
|
||||
log.log("Please use 'onedrive --help' for further assistance in regards to running this application.\n");
|
||||
// Use exit scopes to shutdown API
|
||||
return EXIT_SUCCESS;
|
||||
} else {
|
||||
|
@ -683,7 +857,7 @@ int main(string[] args)
|
|||
}
|
||||
} else {
|
||||
// Application was not just authorised
|
||||
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 --help for further assistance.\n");
|
||||
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
|
||||
return EXIT_FAILURE;
|
||||
|
@ -693,7 +867,7 @@ 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("\nERROR: --synchronize and --monitor cannot be used together\n");
|
||||
writeln("Refer to --help to determine which command option you should use.\n");
|
||||
writeln("Please use 'onedrive --help' for further assistance in regards to running this application.\n");
|
||||
// Use exit scopes to shutdown API
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -756,7 +930,7 @@ int main(string[] args)
|
|||
log.vdebug("Loading user configured sync_list file ...");
|
||||
syncListConfigured = true;
|
||||
// list what will be synced
|
||||
auto syncListFile = File(syncListFilePath);
|
||||
auto syncListFile = File(syncListFilePath, "r");
|
||||
auto range = syncListFile.byLine();
|
||||
foreach (line; range)
|
||||
{
|
||||
|
@ -774,7 +948,7 @@ int main(string[] args)
|
|||
if (exists(businessSharedFolderFilePath)){
|
||||
log.vdebug("Loading user configured business_shared_folders file ...");
|
||||
// list what will be synced
|
||||
auto businessSharedFolderFileList = File(businessSharedFolderFilePath);
|
||||
auto businessSharedFolderFileList = File(businessSharedFolderFilePath, "r");
|
||||
auto range = businessSharedFolderFileList.byLine();
|
||||
foreach (line; range)
|
||||
{
|
||||
|
@ -818,6 +992,51 @@ int main(string[] args)
|
|||
log.vdebug("skip_file: ", cfg.getValueString("skip_file"));
|
||||
selectiveSync.setFileMask(cfg.getValueString("skip_file"));
|
||||
|
||||
// Implement https://github.com/abraunegg/onedrive/issues/1129
|
||||
// Force a synchronization of a specific folder, only when using --synchronize --single-directory and ignoring all non-default skip_dir and skip_file rules
|
||||
if ((cfg.getValueBool("synchronize")) && (cfg.getValueString("single_directory") != "") && (cfg.getValueBool("force_sync"))) {
|
||||
log.log("\nWARNING: Overriding application configuration to use application defaults for skip_dir and skip_file due to --synchronize --single-directory --force-sync being used");
|
||||
// performing this action could have undesirable effects .. the user must accept this risk
|
||||
// what is the risk acceptance?
|
||||
bool resyncRiskAcceptance = false;
|
||||
|
||||
// need to prompt user
|
||||
char response;
|
||||
// warning message
|
||||
writeln("\nThe use of --force-sync will reconfigure the application to use defaults. This may have untold and unknown future impacts.");
|
||||
writeln("By proceeding in using this option you accept any impacts including any data loss that may occur as a result of using --force-sync.");
|
||||
write("\nAre you sure you wish to proceed with --force-sync [Y/N] ");
|
||||
|
||||
try {
|
||||
// Attempt to read user response
|
||||
readf(" %c\n", &response);
|
||||
} catch (std.format.FormatException e) {
|
||||
// Caught an error
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Evaluate user repsonse
|
||||
if ((to!string(response) == "y") || (to!string(response) == "Y")) {
|
||||
// User has accepted --force-sync risk to proceed
|
||||
resyncRiskAcceptance = true;
|
||||
// Are you sure you wish .. does not use writeln();
|
||||
write("\n");
|
||||
}
|
||||
|
||||
// Action based on response
|
||||
if (!resyncRiskAcceptance){
|
||||
// --force-sync not accepted
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
// --force-sync risk accepted
|
||||
// reset set config using function to use application defaults
|
||||
cfg.resetSkipToDefaults();
|
||||
// update sync engine regex with reset defaults
|
||||
selectiveSync.setDirMask(cfg.getValueString("skip_dir"));
|
||||
selectiveSync.setFileMask(cfg.getValueString("skip_file"));
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the sync engine
|
||||
auto sync = new SyncEngine(cfg, oneDrive, itemDb, selectiveSync);
|
||||
try {
|
||||
|
@ -865,6 +1084,9 @@ int main(string[] args)
|
|||
// Do we configure to disable the upload validation routine
|
||||
if (cfg.getValueBool("disable_upload_validation")) sync.setDisableUploadValidation();
|
||||
|
||||
// Do we configure to disable the download validation routine
|
||||
if (cfg.getValueBool("disable_download_validation")) sync.setDisableDownloadValidation();
|
||||
|
||||
// Has the user enabled to bypass data preservation of renaming local files when there is a conflict?
|
||||
if (cfg.getValueBool("bypass_data_preservation")) {
|
||||
log.log("WARNING: Application has been configured to bypass local data preservation in the event of file conflict.");
|
||||
|
@ -928,10 +1150,19 @@ int main(string[] args)
|
|||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Are we obtaining the URL path for a synced file?
|
||||
// --get-file-link - Are we obtaining the URL path for a synced file?
|
||||
if (cfg.getValueString("get_file_link") != "") {
|
||||
// Query OneDrive for the file link
|
||||
sync.queryOneDriveForFileURL(cfg.getValueString("get_file_link"), syncDir);
|
||||
sync.queryOneDriveForFileDetails(cfg.getValueString("get_file_link"), syncDir, "URL");
|
||||
// Exit application
|
||||
// Use exit scopes to shutdown API
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// --modified-by - Are we listing the modified-by details of a provided path?
|
||||
if (cfg.getValueString("modified_by") != "") {
|
||||
// Query OneDrive for the file link
|
||||
sync.queryOneDriveForFileDetails(cfg.getValueString("modified_by"), syncDir, "ModifiedBy");
|
||||
// Exit application
|
||||
// Use exit scopes to shutdown API
|
||||
return EXIT_SUCCESS;
|
||||
|
@ -1013,9 +1244,9 @@ int main(string[] args)
|
|||
m.onDirCreated = delegate(string path) {
|
||||
// Handle .folder creation if skip_dotfiles is enabled
|
||||
if ((cfg.getValueBool("skip_dotfiles")) && (selectiveSync.isDotFile(path))) {
|
||||
log.vlog("[M] Skipping watching path - .folder found & --skip-dot-files enabled: ", path);
|
||||
log.vlog("[M] Skipping watching local path - .folder found & --skip-dot-files enabled: ", path);
|
||||
} else {
|
||||
log.vlog("[M] Directory created: ", path);
|
||||
log.vlog("[M] Local directory created: ", path);
|
||||
try {
|
||||
sync.scanForDifferences(path);
|
||||
} catch (CurlException e) {
|
||||
|
@ -1026,7 +1257,7 @@ int main(string[] args)
|
|||
}
|
||||
};
|
||||
m.onFileChanged = delegate(string path) {
|
||||
log.vlog("[M] File changed: ", path);
|
||||
log.vlog("[M] Local file changed: ", path);
|
||||
try {
|
||||
sync.scanForDifferences(path);
|
||||
} catch (CurlException e) {
|
||||
|
@ -1036,7 +1267,8 @@ int main(string[] args)
|
|||
}
|
||||
};
|
||||
m.onDelete = delegate(string path) {
|
||||
log.vlog("[M] Item deleted: ", path);
|
||||
log.log("Received inotify delete event from operating system .. attempting item deletion as requested");
|
||||
log.vlog("[M] Local item deleted: ", path);
|
||||
try {
|
||||
sync.deleteByPath(path);
|
||||
} catch (CurlException e) {
|
||||
|
@ -1052,7 +1284,7 @@ int main(string[] args)
|
|||
}
|
||||
};
|
||||
m.onMove = delegate(string from, string to) {
|
||||
log.vlog("[M] Item moved: ", from, " -> ", to);
|
||||
log.vlog("[M] Local item moved: ", from, " -> ", to);
|
||||
try {
|
||||
// Handle .folder -> folder if skip_dotfiles is enabled
|
||||
if ((cfg.getValueBool("skip_dotfiles")) && (selectiveSync.isDotFile(from))) {
|
||||
|
@ -1085,9 +1317,12 @@ int main(string[] args)
|
|||
bool performMonitor = true;
|
||||
ulong monitorLoopFullCount = 0;
|
||||
immutable auto checkInterval = dur!"seconds"(cfg.getValueLong("monitor_interval"));
|
||||
immutable auto githubCheckInterval = dur!"seconds"(86400);
|
||||
immutable long logInterval = cfg.getValueLong("monitor_log_frequency");
|
||||
immutable long fullScanFrequency = cfg.getValueLong("monitor_fullscan_frequency");
|
||||
MonoTime lastCheckTime = MonoTime.currTime();
|
||||
MonoTime lastGitHubCheckTime = MonoTime.currTime();
|
||||
|
||||
long logMonitorCounter = 0;
|
||||
long fullScanCounter = 0;
|
||||
// set fullScanRequired to true so that at application startup we perform a full walk
|
||||
|
@ -1098,6 +1333,7 @@ int main(string[] args)
|
|||
// sync list is configured
|
||||
syncListConfiguredFullScanOverride = true;
|
||||
}
|
||||
immutable bool webhookEnabled = cfg.getValueBool("webhook_enabled");
|
||||
|
||||
while (performMonitor) {
|
||||
if (!cfg.getValueBool("download_only")) {
|
||||
|
@ -1109,6 +1345,34 @@ int main(string[] args)
|
|||
}
|
||||
}
|
||||
|
||||
// Check for notifications pushed from Microsoft to the webhook
|
||||
bool notificationReceived = false;
|
||||
if (webhookEnabled) {
|
||||
// Create a subscription on the first run, or renew the subscription
|
||||
// on subsequent runs when it is about to expire.
|
||||
oneDrive.createOrRenewSubscription();
|
||||
|
||||
// Process incoming notifications if any.
|
||||
|
||||
// Empirical evidence shows that Microsoft often sends multiple
|
||||
// notifications for one single change, so we need a loop to exhaust
|
||||
// all signals that were queued up by the webhook. The notifications
|
||||
// do not contain any actual changes, and we will always rely do the
|
||||
// delta endpoint to sync to latest. Therefore, only one sync run is
|
||||
// good enough to catch up for multiple notifications.
|
||||
for (int signalCount = 0;; signalCount++) {
|
||||
const auto signalExists = receiveTimeout(dur!"seconds"(-1), (ulong _) {});
|
||||
if (signalExists) {
|
||||
notificationReceived = true;
|
||||
} else {
|
||||
if (notificationReceived) {
|
||||
log.log("Received ", signalCount," refresh signals from the webhook");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto currTime = MonoTime.currTime();
|
||||
// has monitor_interval elapsed or are we at application startup / monitor startup?
|
||||
// in a --resync scenario, if we have not 're-populated' the database, valid changes will get skipped:
|
||||
|
@ -1118,7 +1382,15 @@ int main(string[] args)
|
|||
// Moving random_files/2eVPInOMTFNXzRXeNMEoJch5OR9XpGby to target/2eVPInOMTFNXzRXeNMEoJch5OR9XpGby
|
||||
// Skipping uploading this new file as parent path is not in the database: target/2eVPInOMTFNXzRXeNMEoJch5OR9XpGby
|
||||
// 'target' should be in the DB, it should also exist online, but because of --resync, it does not exist in the database thus parent check fails
|
||||
if ((currTime - lastCheckTime > checkInterval) || (monitorLoopFullCount == 0)) {
|
||||
if (notificationReceived || (currTime - lastCheckTime > checkInterval) || (monitorLoopFullCount == 0)) {
|
||||
// Check Application Version against GitHub once per day
|
||||
if (currTime - lastGitHubCheckTime > githubCheckInterval) {
|
||||
// --monitor GitHub Application Version Check time expired
|
||||
checkApplicationVersion();
|
||||
// update when we have performed this check
|
||||
lastGitHubCheckTime = MonoTime.currTime();
|
||||
}
|
||||
|
||||
// monitor sync loop
|
||||
logOutputMessage = "################################################## NEW LOOP ##################################################";
|
||||
if (displaySyncOptions) {
|
||||
|
@ -1139,19 +1411,18 @@ int main(string[] args)
|
|||
logMonitorCounter = 1;
|
||||
}
|
||||
|
||||
// do we perform a full scan of sync_dir?
|
||||
// do we perform a full scan of sync_dir and database integrity check?
|
||||
fullScanCounter += 1;
|
||||
// fullScanFrequency = 'monitor_fullscan_frequency' from config
|
||||
if (fullScanCounter > fullScanFrequency){
|
||||
// loop counter has exceeded
|
||||
// 'monitor_fullscan_frequency' counter has exceeded
|
||||
fullScanCounter = 1;
|
||||
if (syncListConfigured) {
|
||||
// set fullScanRequired = true due to sync_list being used
|
||||
// set fullScanRequired = true due to 'monitor_fullscan_frequency' counter has been exceeded
|
||||
fullScanRequired = true;
|
||||
// are we using sync_list?
|
||||
if (syncListConfigured) {
|
||||
// sync list is configured
|
||||
syncListConfiguredFullScanOverride = true;
|
||||
} else {
|
||||
// dont set fullScanRequired to true as this is excessive if sync_list is not being used
|
||||
fullScanRequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1175,8 +1446,16 @@ int main(string[] args)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
try {
|
||||
string startMessage = "Starting a sync with OneDrive";
|
||||
string finishMessage = "Sync with OneDrive is complete";
|
||||
// perform a --monitor sync
|
||||
if ((cfg.getValueLong("verbose") > 0) || (logMonitorCounter == logInterval)) log.log("Starting a sync with OneDrive");
|
||||
if ((cfg.getValueLong("verbose") > 0) || (logMonitorCounter == logInterval)) {
|
||||
// log to console and log file if enabled
|
||||
log.log(startMessage);
|
||||
} else {
|
||||
// log file only if enabled so we know when a sync started when not using --verbose
|
||||
log.fileOnly(startMessage);
|
||||
}
|
||||
performSync(sync, cfg.getValueString("single_directory"), cfg.getValueBool("download_only"), cfg.getValueBool("local_first"), cfg.getValueBool("upload_only"), (logMonitorCounter == logInterval ? MONITOR_LOG_QUIET : MONITOR_LOG_SILENT), fullScanRequired, syncListConfiguredFullScanOverride, displaySyncOptions, cfg.getValueBool("monitor"), m);
|
||||
if (!cfg.getValueBool("download_only")) {
|
||||
// discard all events that may have been generated by the sync that have not already been handled
|
||||
|
@ -1187,7 +1466,13 @@ int main(string[] args)
|
|||
log.error("ERROR: The following inotify error was generated: ", e.msg);
|
||||
}
|
||||
}
|
||||
if ((cfg.getValueLong("verbose") > 0) || (logMonitorCounter == logInterval)) log.log("Sync with OneDrive is complete");
|
||||
if ((cfg.getValueLong("verbose") > 0) || (logMonitorCounter == logInterval)) {
|
||||
// log to console and log file if enabled
|
||||
log.log(finishMessage);
|
||||
} else {
|
||||
// log file only if enabled so we know when a sync completed when not using --verbose
|
||||
log.fileOnly(finishMessage);
|
||||
}
|
||||
} catch (CurlException e) {
|
||||
// we already tried three times in the performSync routine
|
||||
// if we still have problems, then the sync handle might have
|
||||
|
@ -1275,7 +1560,7 @@ bool initSyncEngine(SyncEngine sync)
|
|||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 400 || e.httpStatusCode == 401) {
|
||||
// Authorization is invalid
|
||||
log.log("\nAuthorization token invalid, use --logout to authorize the client again\n");
|
||||
log.log("\nAuthorization token invalid, use --reauth to authorize the client again\n");
|
||||
return false;
|
||||
}
|
||||
if (e.httpStatusCode >= 500) {
|
||||
|
@ -1414,11 +1699,27 @@ void performSync(SyncEngine sync, string singleDirectory, bool downloadOnly, boo
|
|||
} else {
|
||||
// --monitor in use
|
||||
// Use individual calls with inotify checks between to avoid a race condition between these 2 functions
|
||||
// Database scan
|
||||
// Database scan integrity check to compare DB data vs actual content on disk to ensure what we think is local, is local
|
||||
// and that the data 'hash' as recorded in the DB equals the hash of the actual content
|
||||
// This process can be extremely expensive time and CPU processing wise
|
||||
//
|
||||
// fullScanRequired is set to TRUE when the application starts up, or the config option 'monitor_fullscan_frequency' count is reached
|
||||
// By default, 'monitor_fullscan_frequency' = 12, and 'monitor_interval' = 300, meaning that by default, a full database consistency check
|
||||
// is done once an hour.
|
||||
//
|
||||
// To change this behaviour adjust 'monitor_interval' and 'monitor_fullscan_frequency' to desired values in the application config file
|
||||
if (fullScanRequired) {
|
||||
log.vlog("Performing Database Consistency Integrity Check .. ");
|
||||
sync.scanForDifferencesDatabaseScan(localPath);
|
||||
// handle any inotify events that occured 'whilst' we were scanning the database
|
||||
m.update(true);
|
||||
} else {
|
||||
log.vdebug("NOT performing Database Integrity Check .. fullScanRequired = FALSE");
|
||||
m.update(true);
|
||||
}
|
||||
|
||||
// Filesystem walk to find new files not uploaded
|
||||
log.vdebug("Searching local filesystem for new data");
|
||||
sync.scanForDifferencesFilesystemScan(localPath);
|
||||
// handle any inotify events that occured 'whilst' we were scanning the local filesystem
|
||||
m.update(true);
|
||||
|
@ -1430,12 +1731,12 @@ void performSync(SyncEngine sync, string singleDirectory, bool downloadOnly, boo
|
|||
// --synchronize & no sync_list : fullScanRequired = false, syncListConfiguredFullScanOverride = false
|
||||
// --synchronize & sync_list in use : fullScanRequired = false, syncListConfiguredFullScanOverride = true
|
||||
|
||||
// --monitor loops around 10 iterations. On the 1st loop, sets fullScanRequired = false, syncListConfiguredFullScanOverride = true if requried
|
||||
// --monitor loops around 12 iterations. On the 1st loop, sets fullScanRequired = true, syncListConfiguredFullScanOverride = true if requried
|
||||
|
||||
// --monitor & no sync_list (loop #1) : fullScanRequired = true, syncListConfiguredFullScanOverride = false
|
||||
// --monitor & no sync_list (loop #2 - #10) : fullScanRequired = false, syncListConfiguredFullScanOverride = false
|
||||
// --monitor & no sync_list (loop #2 - #12) : fullScanRequired = false, syncListConfiguredFullScanOverride = false
|
||||
// --monitor & sync_list in use (loop #1) : fullScanRequired = true, syncListConfiguredFullScanOverride = true
|
||||
// --monitor & sync_list in use (loop #2 - #10) : fullScanRequired = false, syncListConfiguredFullScanOverride = false
|
||||
// --monitor & sync_list in use (loop #2 - #12) : fullScanRequired = false, syncListConfiguredFullScanOverride = false
|
||||
|
||||
// Do not perform a full walk of the OneDrive objects
|
||||
if ((!fullScanRequired) && (!syncListConfiguredFullScanOverride)){
|
||||
|
@ -1527,14 +1828,19 @@ auto assumeNoGC(T) (T t) if (isFunctionPointer!T || isDelegate!T)
|
|||
extern(C) nothrow @nogc @system void exitHandler(int value) {
|
||||
try {
|
||||
assumeNoGC ( () {
|
||||
log.log("Got termination signal, shutting down db connection");
|
||||
log.log("Got termination signal, performing clean up");
|
||||
// if initialised, shut down the HTTP instance
|
||||
if (onedriveInitialised) {
|
||||
log.log("Shutting down the HTTP instance");
|
||||
oneDrive.shutdown();
|
||||
}
|
||||
// was itemDb initialised?
|
||||
if (itemDb !is null) {
|
||||
// Make sure the .wal file is incorporated into the main db before we exit
|
||||
log.log("Shutting down db connection");
|
||||
itemDb.performVacuum();
|
||||
destroy(itemDb);
|
||||
}
|
||||
// Use exit scopes to shutdown OneDrive API
|
||||
})();
|
||||
} catch(Exception e) {}
|
||||
exit(0);
|
||||
|
|
355
src/onedrive.d
355
src/onedrive.d
|
@ -1,14 +1,18 @@
|
|||
import std.net.curl;
|
||||
import etc.c.curl: CurlOption;
|
||||
import std.datetime, std.exception, std.file, std.json, std.path;
|
||||
import std.stdio, std.string, std.uni, std.uri, std.file;
|
||||
import std.datetime, std.datetime.systime, std.exception, std.file, std.json, std.path;
|
||||
import std.stdio, std.string, std.uni, std.uri, std.file, std.uuid;
|
||||
import std.array: split;
|
||||
import core.atomic : atomicOp;
|
||||
import core.stdc.stdlib;
|
||||
import core.thread, std.conv, std.math;
|
||||
import std.algorithm.searching;
|
||||
import std.concurrency;
|
||||
import progress;
|
||||
import config;
|
||||
import util;
|
||||
import arsd.cgi;
|
||||
import std.datetime;
|
||||
static import log;
|
||||
shared bool debugResponse = false;
|
||||
private bool dryRun = false;
|
||||
|
@ -77,6 +81,9 @@ private {
|
|||
// Office 365 / SharePoint Queries
|
||||
string siteSearchUrl = globalGraphEndpoint ~ "/v1.0/sites?search";
|
||||
string siteDriveUrl = globalGraphEndpoint ~ "/v1.0/sites/";
|
||||
|
||||
// Subscriptions
|
||||
string subscriptionUrl = globalGraphEndpoint ~ "/v1.0/subscriptions";
|
||||
}
|
||||
|
||||
class OneDriveException: Exception
|
||||
|
@ -102,12 +109,104 @@ class OneDriveException: Exception
|
|||
}
|
||||
}
|
||||
|
||||
class OneDriveWebhook {
|
||||
// We need OneDriveWebhook.serve to be a static function, otherwise we would hit the member function
|
||||
// "requires a dual-context, which is deprecated" warning. The root cause is described here:
|
||||
// - https://issues.dlang.org/show_bug.cgi?id=5710
|
||||
// - https://forum.dlang.org/post/fkyppfxzegenniyzztos@forum.dlang.org
|
||||
// The problem is deemed a bug and should be fixed in the compilers eventually. The singleton stuff
|
||||
// could be undone when it is fixed.
|
||||
//
|
||||
// Following the singleton pattern described here: https://wiki.dlang.org/Low-Lock_Singleton_Pattern
|
||||
// Cache instantiation flag in thread-local bool
|
||||
// Thread local
|
||||
private static bool instantiated_;
|
||||
|
||||
// Thread global
|
||||
private __gshared OneDriveWebhook instance_;
|
||||
|
||||
private string host;
|
||||
private ushort port;
|
||||
private Tid parentTid;
|
||||
private shared uint count;
|
||||
|
||||
static OneDriveWebhook getOrCreate(string host, ushort port, Tid parentTid) {
|
||||
if (!instantiated_) {
|
||||
synchronized(OneDriveWebhook.classinfo) {
|
||||
if (!instance_) {
|
||||
instance_ = new OneDriveWebhook(host, port, parentTid);
|
||||
}
|
||||
|
||||
instantiated_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
return instance_;
|
||||
}
|
||||
|
||||
private this(string host, ushort port, Tid parentTid) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.parentTid = parentTid;
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
// The static serve() is necessary because spawn() does not like instance methods
|
||||
static serve() {
|
||||
// we won't create the singleton instance if it hasn't been created already
|
||||
// such case is a bug which should crash the program and gets fixed
|
||||
instance_.serveImpl();
|
||||
}
|
||||
|
||||
// The static handle() is necessary to work around the dual-context warning mentioned above
|
||||
private static void handle(Cgi cgi) {
|
||||
// we won't create the singleton instance if it hasn't been created already
|
||||
// such case is a bug which should crash the program and gets fixed
|
||||
instance_.handleImpl(cgi);
|
||||
}
|
||||
|
||||
private void serveImpl() {
|
||||
auto server = new RequestServer(host, port);
|
||||
server.serveEmbeddedHttp!handle();
|
||||
}
|
||||
|
||||
private void handleImpl(Cgi cgi) {
|
||||
if (.debugResponse) {
|
||||
log.log("Webhook request: ", cgi.requestMethod, " ", cgi.requestUri);
|
||||
if (!cgi.postBody.empty) {
|
||||
log.log("Webhook post body: ", cgi.postBody);
|
||||
}
|
||||
}
|
||||
|
||||
cgi.setResponseContentType("text/plain");
|
||||
|
||||
if ("validationToken" in cgi.get) {
|
||||
// For validation requests, respond with the validation token passed in the query string
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/concepts/webhook-receiver-validation-request
|
||||
cgi.write(cgi.get["validationToken"]);
|
||||
log.log("Webhook: handled validation request");
|
||||
} else {
|
||||
// Notifications don't include any information about the changes that triggered them.
|
||||
// Put a refresh signal in the queue and let the main monitor loop process it.
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/concepts/using-webhooks
|
||||
count.atomicOp!"+="(1);
|
||||
send(parentTid, to!ulong(count));
|
||||
cgi.write("OK");
|
||||
log.log("Webhook: sent refresh signal #", count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class OneDriveApi
|
||||
{
|
||||
private Config cfg;
|
||||
private string refreshToken, accessToken;
|
||||
private string refreshToken, accessToken, subscriptionId;
|
||||
private SysTime accessTokenExpiration;
|
||||
private HTTP http;
|
||||
private OneDriveWebhook webhook;
|
||||
private SysTime subscriptionExpiration;
|
||||
private Duration subscriptionExpirationInterval, subscriptionRenewalInterval;
|
||||
private string notificationUrl;
|
||||
|
||||
// If true, every new access token is printed
|
||||
bool printAccessToken;
|
||||
|
@ -125,9 +224,9 @@ final class OneDriveApi
|
|||
this.cfg = cfg;
|
||||
http = HTTP();
|
||||
// Curl Timeout Handling
|
||||
// DNS lookup timeout
|
||||
http.dnsTimeout = (dur!"seconds"(5));
|
||||
// Timeout for connecting
|
||||
// libcurl dns_cache_timeout timeout
|
||||
http.dnsTimeout = (dur!"seconds"(60));
|
||||
// Timeout for HTTPS connections
|
||||
http.connectTimeout = (dur!"seconds"(10));
|
||||
// with the following settings we force
|
||||
// - if there is no data flow for 10min, abort
|
||||
|
@ -142,8 +241,7 @@ final class OneDriveApi
|
|||
http.dataTimeout = (dur!"seconds"(600));
|
||||
// maximum time an operation is allowed to take
|
||||
// This includes dns resolution, connecting, data transfer, etc.
|
||||
http.operationTimeout = (dur!"seconds"(3600));
|
||||
|
||||
http.operationTimeout = (dur!"seconds"(cfg.getValueLong("operation_timeout")));
|
||||
// Specify how many redirects should be allowed
|
||||
http.maxRedirects(5);
|
||||
|
||||
|
@ -209,6 +307,8 @@ final class OneDriveApi
|
|||
// Shared With Me
|
||||
sharedWithMeUrl = usl4GraphEndpoint ~ "/v1.0/me/drive/sharedWithMe";
|
||||
sharepointTenantId = usl4GraphEndpoint ~ "/v1.0/organization";
|
||||
// Subscriptions
|
||||
subscriptionUrl = usl4GraphEndpoint ~ "/v1.0/subscriptions";
|
||||
break;
|
||||
case "USL5":
|
||||
log.log("Configuring Azure AD for US Government Endpoints (DOD)");
|
||||
|
@ -236,6 +336,8 @@ final class OneDriveApi
|
|||
// Shared With Me
|
||||
sharedWithMeUrl = usl5GraphEndpoint ~ "/v1.0/me/drive/sharedWithMe";
|
||||
sharepointTenantId = usl5GraphEndpoint ~ "/v1.0/organization";
|
||||
// Subscriptions
|
||||
subscriptionUrl = usl5GraphEndpoint ~ "/v1.0/subscriptions";
|
||||
break;
|
||||
case "DE":
|
||||
log.log("Configuring Azure AD Germany");
|
||||
|
@ -263,6 +365,8 @@ final class OneDriveApi
|
|||
// Shared With Me
|
||||
sharedWithMeUrl = deGraphEndpoint ~ "/v1.0/me/drive/sharedWithMe";
|
||||
sharepointTenantId = deGraphEndpoint ~ "/v1.0/organization";
|
||||
// Subscriptions
|
||||
subscriptionUrl = deGraphEndpoint ~ "/v1.0/subscriptions";
|
||||
break;
|
||||
case "CN":
|
||||
log.log("Configuring AD China operated by 21Vianet");
|
||||
|
@ -290,6 +394,8 @@ final class OneDriveApi
|
|||
// Shared With Me
|
||||
sharedWithMeUrl = cnGraphEndpoint ~ "/v1.0/me/drive/sharedWithMe";
|
||||
sharepointTenantId = cnGraphEndpoint ~ "/v1.0/organization";
|
||||
// Subscriptions
|
||||
subscriptionUrl = cnGraphEndpoint ~ "/v1.0/subscriptions";
|
||||
break;
|
||||
// Default - all other entries
|
||||
default:
|
||||
|
@ -366,6 +472,17 @@ final class OneDriveApi
|
|||
http.handle.set(CurlOption.max_recv_speed_large,userRateLimit);
|
||||
}
|
||||
|
||||
// Explicitly set libcurl options
|
||||
// https://curl.se/libcurl/c/CURLOPT_NOSIGNAL.html
|
||||
// Ensure that nosignal is set to 0 - Setting CURLOPT_NOSIGNAL to 0 makes libcurl ask the system to ignore SIGPIPE signals
|
||||
http.handle.set(CurlOption.nosignal,0);
|
||||
// https://curl.se/libcurl/c/CURLOPT_TCP_NODELAY.html
|
||||
// Ensure that TCP_NODELAY is set to 0 to ensure that TCP NAGLE is enabled
|
||||
http.handle.set(CurlOption.tcp_nodelay,0);
|
||||
// https://curl.se/libcurl/c/CURLOPT_FORBID_REUSE.html
|
||||
// Ensure that we ARE reusing connections - setting to 0 ensures that we are reusing connections
|
||||
http.handle.set(CurlOption.forbid_reuse,0);
|
||||
|
||||
// Do we set the dryRun handlers?
|
||||
if (cfg.getValueBool("dry_run")) {
|
||||
.dryRun = true;
|
||||
|
@ -373,11 +490,19 @@ final class OneDriveApi
|
|||
.simulateNoRefreshTokenFile = true;
|
||||
}
|
||||
}
|
||||
|
||||
subscriptionExpiration = Clock.currTime(UTC());
|
||||
subscriptionExpirationInterval = dur!"seconds"(cfg.getValueLong("webhook_expiration_interval"));
|
||||
subscriptionRenewalInterval = dur!"seconds"(cfg.getValueLong("webhook_renewal_interval"));
|
||||
notificationUrl = cfg.getValueString("webhook_public_url");
|
||||
}
|
||||
|
||||
// Shutdown OneDrive HTTP construct
|
||||
void shutdown()
|
||||
{
|
||||
// delete subscription if there exists any
|
||||
deleteSubscription();
|
||||
|
||||
// reset any values to defaults, freeing any set objects
|
||||
http.clearRequestHeaders();
|
||||
http.onSend = null;
|
||||
|
@ -439,7 +564,7 @@ final class OneDriveApi
|
|||
}
|
||||
return true;
|
||||
} else {
|
||||
// --dry-run & --logout
|
||||
// --dry-run & --reauth
|
||||
return authorize();
|
||||
}
|
||||
}
|
||||
|
@ -449,14 +574,12 @@ final class OneDriveApi
|
|||
{
|
||||
import std.stdio, std.regex;
|
||||
char[] response;
|
||||
string url = authUrl ~ "?client_id=" ~ clientId ~ "&scope=User.Read%20Files.ReadWrite%20Files.ReadWrite.all%20Sites.Read.All%20Sites.ReadWrite.All%20offline_access&response_type=code&redirect_uri=" ~ redirectUrl;
|
||||
string url = authUrl ~ "?client_id=" ~ clientId ~ "&scope=User.Read%20Files.ReadWrite%20Files.ReadWrite.all%20Sites.Read.All%20Sites.ReadWrite.All%20offline_access&response_type=code&prompt=login&redirect_uri=" ~ redirectUrl;
|
||||
string authFilesString = cfg.getValueString("auth_files");
|
||||
if (authFilesString == "") {
|
||||
log.log("Authorize this app visiting:\n");
|
||||
write(url, "\n\n", "Enter the response uri: ");
|
||||
readln(response);
|
||||
cfg.applicationAuthorizeResponseUri = true;
|
||||
} else {
|
||||
string authResponseString = cfg.getValueString("auth_response");
|
||||
if (authResponseString != "") {
|
||||
response = cast(char[]) authResponseString;
|
||||
} else if (authFilesString != "") {
|
||||
string[] authFiles = authFilesString.split(":");
|
||||
string authUrl = authFiles[0];
|
||||
string responseUrl = authFiles[1];
|
||||
|
@ -484,6 +607,11 @@ final class OneDriveApi
|
|||
log.error("Cannot remove files ", authUrl, " ", responseUrl);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
log.log("Authorize this app visiting:\n");
|
||||
write(url, "\n\n", "Enter the response uri: ");
|
||||
readln(response);
|
||||
cfg.applicationAuthorizeResponseUri = true;
|
||||
}
|
||||
// match the authorization code
|
||||
auto c = matchFirst(response, r"(?:[\?&]code=)([\w\d-.]+)");
|
||||
|
@ -791,14 +919,14 @@ final class OneDriveApi
|
|||
return get(url);
|
||||
}
|
||||
|
||||
// Return the requested details of the specified item id
|
||||
// Return the requested details of the specified id
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get
|
||||
JSONValue getFileDetails(const(char)[] driveId, const(char)[] id)
|
||||
{
|
||||
checkAccessTokenExpired();
|
||||
const(char)[] url;
|
||||
url = driveByIdUrl ~ driveId ~ "/items/" ~ id;
|
||||
url ~= "?select=size,malware,file,webUrl";
|
||||
url ~= "?select=size,malware,file,webUrl,lastModifiedBy,lastModifiedDateTime";
|
||||
return get(url);
|
||||
}
|
||||
|
||||
|
@ -899,6 +1027,100 @@ final class OneDriveApi
|
|||
return get(url);
|
||||
}
|
||||
|
||||
// Create a new subscription or renew the existing subscription
|
||||
void createOrRenewSubscription() {
|
||||
checkAccessTokenExpired();
|
||||
|
||||
// Kick off the webhook server first
|
||||
if (webhook is null) {
|
||||
webhook = OneDriveWebhook.getOrCreate(
|
||||
cfg.getValueString("webhook_listening_host"),
|
||||
to!ushort(cfg.getValueLong("webhook_listening_port")),
|
||||
thisTid
|
||||
);
|
||||
spawn(&OneDriveWebhook.serve);
|
||||
}
|
||||
|
||||
if (!hasValidSubscription()) {
|
||||
createSubscription();
|
||||
} else if (isSubscriptionUpForRenewal()) {
|
||||
try {
|
||||
renewSubscription();
|
||||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 404) {
|
||||
log.log("The subscription is not found on the server. Recreating subscription ...");
|
||||
createSubscription();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool hasValidSubscription() {
|
||||
return !subscriptionId.empty && subscriptionExpiration > Clock.currTime(UTC());
|
||||
}
|
||||
|
||||
private bool isSubscriptionUpForRenewal() {
|
||||
return subscriptionExpiration < Clock.currTime(UTC()) + subscriptionRenewalInterval;
|
||||
}
|
||||
|
||||
private void createSubscription() {
|
||||
log.log("Initializing subscription for updates ...");
|
||||
|
||||
auto expirationDateTime = Clock.currTime(UTC()) + subscriptionExpirationInterval;
|
||||
const(char)[] url;
|
||||
url = subscriptionUrl;
|
||||
const JSONValue request = [
|
||||
"changeType": "updated",
|
||||
"notificationUrl": notificationUrl,
|
||||
"resource": "/me/drive/root",
|
||||
"expirationDateTime": expirationDateTime.toISOExtString(),
|
||||
"clientState": randomUUID().toString()
|
||||
];
|
||||
http.addRequestHeader("Content-Type", "application/json");
|
||||
JSONValue response;
|
||||
|
||||
try {
|
||||
response = post(url, request.toString());
|
||||
} catch (OneDriveException e) {
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
|
||||
// We need to exit here, user needs to fix issue
|
||||
log.error("ERROR: Unable to initialize subscriptions for updates. Please fix this issue.");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Save important subscription metadata including id and expiration
|
||||
subscriptionId = response["id"].str;
|
||||
subscriptionExpiration = SysTime.fromISOExtString(response["expirationDateTime"].str);
|
||||
}
|
||||
|
||||
private void renewSubscription() {
|
||||
log.log("Renewing subscription for updates ...");
|
||||
|
||||
auto expirationDateTime = Clock.currTime(UTC()) + subscriptionExpirationInterval;
|
||||
const(char)[] url;
|
||||
url = subscriptionUrl ~ "/" ~ subscriptionId;
|
||||
const JSONValue request = [
|
||||
"expirationDateTime": expirationDateTime.toISOExtString()
|
||||
];
|
||||
http.addRequestHeader("Content-Type", "application/json");
|
||||
JSONValue response = patch(url, request.toString());
|
||||
|
||||
// Update subscription expiration from the response
|
||||
subscriptionExpiration = SysTime.fromISOExtString(response["expirationDateTime"].str);
|
||||
}
|
||||
|
||||
private void deleteSubscription() {
|
||||
if (!hasValidSubscription()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const(char)[] url;
|
||||
url = subscriptionUrl ~ "/" ~ subscriptionId;
|
||||
del(url);
|
||||
log.log("Deleted subscription");
|
||||
}
|
||||
|
||||
private void redeemToken(const(char)[] authCode)
|
||||
{
|
||||
const(char)[] postData =
|
||||
|
@ -922,6 +1144,7 @@ final class OneDriveApi
|
|||
private void acquireToken(const(char)[] postData)
|
||||
{
|
||||
JSONValue response;
|
||||
|
||||
try {
|
||||
if (!externalTenant) {
|
||||
// use normal token url
|
||||
|
@ -988,9 +1211,9 @@ final class OneDriveApi
|
|||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 400 || e.httpStatusCode == 401) {
|
||||
// flag error and notify
|
||||
log.errorAndNotify("\nERROR: Refresh token invalid, use --logout to authorize the client again.\n");
|
||||
log.errorAndNotify("\nERROR: Refresh token invalid, use --reauth to authorize the client again.\n");
|
||||
// set error message
|
||||
e.msg ~= "\nRefresh token invalid, use --logout to authorize the client again";
|
||||
e.msg ~= "\nRefresh token invalid, use --reauth to authorize the client again";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1044,8 +1267,13 @@ final class OneDriveApi
|
|||
{
|
||||
// Threshold for displaying download bar
|
||||
long thresholdFileSize = 4 * 2^^20; // 4 MiB
|
||||
// open file as write in binary mode
|
||||
auto file = File(filename, "wb");
|
||||
|
||||
// To support marking of partially-downloaded files,
|
||||
string originalFilename = filename;
|
||||
string downloadFilename = filename ~ ".partial";
|
||||
|
||||
// open downloadFilename as write in binary mode
|
||||
auto file = File(downloadFilename, "wb");
|
||||
|
||||
// function scopes
|
||||
scope(exit) {
|
||||
|
@ -1139,6 +1367,9 @@ final class OneDriveApi
|
|||
}
|
||||
}
|
||||
|
||||
// Rename downloaded file
|
||||
rename(downloadFilename, originalFilename);
|
||||
|
||||
// Check the HTTP response code, which, if a 429, will also check response headers
|
||||
checkHttpCode();
|
||||
}
|
||||
|
@ -1254,45 +1485,83 @@ final class OneDriveApi
|
|||
} catch (CurlException e) {
|
||||
// Parse and display error message received from OneDrive
|
||||
log.vdebug("onedrive.perform() Generated a OneDrive CurlException");
|
||||
log.error("ERROR: OneDrive returned an error with the following message:");
|
||||
auto errorArray = splitLines(e.msg);
|
||||
string errorMessage = errorArray[0];
|
||||
string defaultTimeoutErrorMessage = " Error Message: There was a timeout in accessing the Microsoft OneDrive service - Internet connectivity issue?";
|
||||
|
||||
// what is contained in the curl error message?
|
||||
if (canFind(errorMessage, "Couldn't connect to server on handle") || canFind(errorMessage, "Couldn't resolve host name on handle") || canFind(errorMessage, "Timeout was reached on handle")) {
|
||||
// This is a curl timeout
|
||||
log.error(defaultTimeoutErrorMessage);
|
||||
// or 408 request timeout
|
||||
// or is this a 408 request timeout
|
||||
// https://github.com/abraunegg/onedrive/issues/694
|
||||
// Back off & retry with incremental delay
|
||||
int retryCount = 10000;
|
||||
int retryAttempts = 1;
|
||||
int backoffInterval = 1;
|
||||
int retryAttempts = 0;
|
||||
int backoffInterval = 0;
|
||||
int maxBackoffInterval = 3600;
|
||||
int timestampAlign = 0;
|
||||
bool retrySuccess = false;
|
||||
SysTime currentTime;
|
||||
|
||||
// what caused the initial curl exception?
|
||||
if (canFind(errorMessage, "Couldn't connect to server on handle")) log.vdebug("Unable to connect to server - HTTPS access blocked?");
|
||||
if (canFind(errorMessage, "Couldn't resolve host name on handle")) log.vdebug("Unable to resolve server - DNS access blocked?");
|
||||
if (canFind(errorMessage, "Timeout was reached on handle")) log.vdebug("A timeout was triggered - data too slow, no response ... use --debug-https to diagnose further");
|
||||
|
||||
while (!retrySuccess){
|
||||
backoffInterval++;
|
||||
int thisBackOffInterval = retryAttempts*backoffInterval;
|
||||
log.vdebug(" Retry Attempt: ", retryAttempts);
|
||||
if (thisBackOffInterval <= maxBackoffInterval) {
|
||||
log.vdebug(" Retry In (seconds): ", thisBackOffInterval);
|
||||
Thread.sleep(dur!"seconds"(thisBackOffInterval));
|
||||
} else {
|
||||
log.vdebug(" Retry In (seconds): ", maxBackoffInterval);
|
||||
Thread.sleep(dur!"seconds"(maxBackoffInterval));
|
||||
}
|
||||
try {
|
||||
// configure libcurl to perform a fresh connection
|
||||
log.vdebug("Configuring libcurl to use a fresh connection for re-try");
|
||||
http.handle.set(CurlOption.fresh_connect,1);
|
||||
// try the access
|
||||
http.perform();
|
||||
// Check the HTTP Response headers - needed for correct 429 handling
|
||||
checkHTTPResponseHeaders();
|
||||
// no error from http.perform() on re-try
|
||||
log.log("Internet connectivity to Microsoft OneDrive service has been restored");
|
||||
// unset the fresh connect option as this then creates performance issues if left enabled
|
||||
log.vdebug("Unsetting libcurl to use a fresh connection as this causes a performance impact if left enabled");
|
||||
http.handle.set(CurlOption.fresh_connect,0);
|
||||
// connectivity restored
|
||||
retrySuccess = true;
|
||||
} catch (CurlException e) {
|
||||
if (canFind(e.msg, "Couldn't connect to server on handle") || canFind(e.msg, "Couldn't resolve host name on handle") || canFind(errorMessage, "Timeout was reached on handle")) {
|
||||
log.error(defaultTimeoutErrorMessage);
|
||||
// Increment & loop around
|
||||
// when was the exception generated
|
||||
currentTime = Clock.currTime();
|
||||
// Increment retry attempts
|
||||
retryAttempts++;
|
||||
if (canFind(e.msg, "Couldn't connect to server on handle") || canFind(e.msg, "Couldn't resolve host name on handle") || canFind(errorMessage, "Timeout was reached on handle")) {
|
||||
// no access to Internet
|
||||
log.error("\nERROR: There was a timeout in accessing the Microsoft OneDrive service - Internet connectivity issue?");
|
||||
// what is the error reason to assis the user as what to check
|
||||
if (canFind(e.msg, "Couldn't connect to server on handle")) {
|
||||
log.log(" - Check HTTPS access or Firewall Rules");
|
||||
timestampAlign = 9;
|
||||
}
|
||||
if (canFind(e.msg, "Couldn't resolve host name on handle")) {
|
||||
log.log(" - Check DNS resolution or Firewall Rules");
|
||||
timestampAlign = 0;
|
||||
}
|
||||
|
||||
// increment backoff interval
|
||||
backoffInterval++;
|
||||
int thisBackOffInterval = retryAttempts*backoffInterval;
|
||||
|
||||
// display retry information
|
||||
currentTime.fracSecs = Duration.zero;
|
||||
auto timeString = currentTime.toString();
|
||||
log.vlog(" Retry attempt: ", retryAttempts);
|
||||
log.vlog(" This attempt timestamp: ", timeString);
|
||||
if (thisBackOffInterval > maxBackoffInterval) {
|
||||
thisBackOffInterval = maxBackoffInterval;
|
||||
}
|
||||
|
||||
// detail when the next attempt will be tried
|
||||
// factor in the delay for curl to generate the exception - otherwise the next timestamp appears to be 'out' even though technically correct
|
||||
auto nextRetry = currentTime + dur!"seconds"(thisBackOffInterval) + dur!"seconds"(timestampAlign);
|
||||
log.vlog(" Next retry in approx: ", (thisBackOffInterval + timestampAlign), " seconds");
|
||||
log.vlog(" Next retry approx: ", nextRetry);
|
||||
|
||||
// thread sleep
|
||||
Thread.sleep(dur!"seconds"(thisBackOffInterval));
|
||||
}
|
||||
if (retryAttempts == retryCount) {
|
||||
// we have attempted to re-connect X number of times
|
||||
|
@ -1302,10 +1571,12 @@ final class OneDriveApi
|
|||
}
|
||||
}
|
||||
if (retryAttempts >= retryCount) {
|
||||
log.error(" Error Message: Was unable to reconnect to the Microsoft OneDrive service after 10000 attempts lasting over 1.2 years!");
|
||||
log.error(" ERROR: Unable to reconnect to the Microsoft OneDrive service after ", retryCount, " attempts lasting over 1.2 years!");
|
||||
throw new OneDriveException(408, "Request Timeout - HTTP 408 or Internet down?");
|
||||
}
|
||||
} else {
|
||||
// Log that an error was returned
|
||||
log.error("ERROR: OneDrive returned an error with the following message:");
|
||||
// Some other error was returned
|
||||
log.error(" Error Message: ", errorMessage);
|
||||
log.error(" Calling Function: ", getFunctionName!({}));
|
||||
|
|
|
@ -24,6 +24,7 @@ class Progress
|
|||
size_t getTerminalWidth() {
|
||||
size_t column = default_width;
|
||||
version (CRuntime_Musl) {
|
||||
} else version(Android) {
|
||||
} else {
|
||||
winsize ws;
|
||||
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col > 0) {
|
||||
|
|
|
@ -373,6 +373,11 @@ private bool isPathExcluded(string path, string[] allowedPaths)
|
|||
log.vdebug("[F]exclude = ", exclude);
|
||||
log.vdebug("[F]excludeMatched = ", excludeMatched);
|
||||
|
||||
// If exclude or excludeMatched is true, then finalResult has to be true
|
||||
if ((exclude) || (excludeMatched)) {
|
||||
finalResult = true;
|
||||
}
|
||||
|
||||
// results
|
||||
if (finalResult) {
|
||||
log.vdebug("Evaluation against 'sync_list' final result: EXCLUDED");
|
||||
|
|
389
src/sync.d
389
src/sync.d
|
@ -27,6 +27,9 @@ private bool uploadOnly = false;
|
|||
// Do we configure to disable the upload validation routine
|
||||
private bool disableUploadValidation = false;
|
||||
|
||||
// Do we configure to disable the download validation routine
|
||||
private bool disableDownloadValidation = false;
|
||||
|
||||
private bool isItemFolder(const ref JSONValue item)
|
||||
{
|
||||
return ("folder" in item) != null;
|
||||
|
@ -145,8 +148,6 @@ private Item makeItem(const ref JSONValue driveItem)
|
|||
// item exists on account default drive id
|
||||
item.mtime = SysTime.fromISOExtString(driveItem["fileSystemInfo"]["lastModifiedDateTime"].str);
|
||||
}
|
||||
// debug output of what the OneDrive item modified time is
|
||||
log.vdebug("lastModifiedDateTime (OneDrive item): ", item.mtime);
|
||||
}
|
||||
|
||||
if (isItemFile(driveItem)) {
|
||||
|
@ -319,7 +320,7 @@ final class SyncEngine
|
|||
if (e.httpStatusCode == 401) {
|
||||
// HTTP request returned status code 401 (Unauthorized)
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
log.errorAndNotify("\nERROR: Check your configuration as your refresh_token may be empty or invalid. You may need to issue a --logout and re-authorise this client.\n");
|
||||
log.errorAndNotify("\nERROR: Check your configuration as your refresh_token may be empty or invalid. You may need to issue a --reauth and re-authorise this client.\n");
|
||||
// Must exit here
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -358,7 +359,7 @@ final class SyncEngine
|
|||
if (e.httpStatusCode == 401) {
|
||||
// HTTP request returned status code 401 (Unauthorized)
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
log.errorAndNotify("\nERROR: Check your configuration as your refresh_token may be empty or invalid. You may need to issue a --logout and re-authorise this client.\n");
|
||||
log.errorAndNotify("\nERROR: Check your configuration as your refresh_token may be empty or invalid. You may need to issue a --reauth and re-authorise this client.\n");
|
||||
// Must exit here
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -389,7 +390,15 @@ final class SyncEngine
|
|||
accountType = oneDriveDetails["driveType"].str;
|
||||
defaultDriveId = oneDriveDetails["id"].str;
|
||||
defaultRootId = oneDriveRootDetails["id"].str;
|
||||
|
||||
// get the remaining size from OneDrive API
|
||||
if ("remaining" in oneDriveDetails["quota"]){
|
||||
// use the value provided
|
||||
remainingFreeSpace = oneDriveDetails["quota"]["remaining"].integer;
|
||||
} else {
|
||||
// set at zero
|
||||
remainingFreeSpace = 0;
|
||||
}
|
||||
|
||||
// Make sure that defaultDriveId is in our driveIDs array to use when checking if item is in database
|
||||
// Keep the driveIDsArray with unique entries only
|
||||
|
@ -416,9 +425,11 @@ final class SyncEngine
|
|||
// json response was missing a 'remaining' value
|
||||
if (accountType == "personal"){
|
||||
log.error("ERROR: OneDrive quota information is missing. Potentially your OneDrive account currently has zero space available. Please free up some space online.");
|
||||
quotaAvailable = false;
|
||||
} else {
|
||||
// quota details not available
|
||||
log.error("ERROR: OneDrive quota information is being restricted. Please fix by speaking to your OneDrive / Office 365 Administrator.");
|
||||
quotaRestricted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -445,6 +456,7 @@ final class SyncEngine
|
|||
// If account type is documentLibrary - then most likely this is a SharePoint repository
|
||||
// and files 'may' be modified after upload. See: https://github.com/abraunegg/onedrive/issues/205
|
||||
if(accountType == "documentLibrary") {
|
||||
// set this flag for SharePoint regardless of --disable-upload-validation being used
|
||||
setDisableUploadValidation();
|
||||
}
|
||||
|
||||
|
@ -550,6 +562,18 @@ final class SyncEngine
|
|||
log.vdebug("documentLibrary account type - flagging to disable upload validation checks due to Microsoft SharePoint file modification enrichments");
|
||||
}
|
||||
|
||||
// Configure disableDownloadValidation if function is called
|
||||
// By default, disableDownloadValidation = false;
|
||||
// Meaning we will always validate our downloads
|
||||
// However, when downloading files from SharePoint, the OneDrive API will not advise the correct file size
|
||||
// which means that the application thinks the file download has failed as the size is different / hash is different
|
||||
// See: https://github.com/abraunegg/onedrive/discussions/1667
|
||||
void setDisableDownloadValidation()
|
||||
{
|
||||
disableDownloadValidation = true;
|
||||
log.vdebug("Flagging to disable download validation checks due to user request");
|
||||
}
|
||||
|
||||
// Issue #658 Handling
|
||||
// If an existing folder is moved into a sync_list valid path (where it previously was out of scope due to sync_list),
|
||||
// then set this flag to true, so that on the second 'true-up' sync, we force a rescan of the OneDrive path to capture any 'files'
|
||||
|
@ -651,7 +675,32 @@ final class SyncEngine
|
|||
|
||||
// Query OneDrive Business Shared Folders shared with me
|
||||
log.vlog("Attempting to sync OneDrive Business Shared Folders");
|
||||
JSONValue graphQuery = onedrive.getSharedWithMe();
|
||||
JSONValue graphQuery;
|
||||
try {
|
||||
graphQuery = onedrive.getSharedWithMe();
|
||||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 401) {
|
||||
// HTTP request returned status code 401 (Unauthorized)
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
log.errorAndNotify("\nERROR: Check your configuration as your refresh_token may be empty or invalid. You may need to issue a --reauth and re-authorise this client.\n");
|
||||
// Must exit here
|
||||
exit(-1);
|
||||
}
|
||||
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.
|
||||
handleOneDriveThrottleRequest();
|
||||
// Retry original request by calling function again to avoid replicating any further error handling
|
||||
log.vdebug("Retrying original request that generated the OneDrive HTTP 429 Response Code (Too Many Requests) - graphQuery = onedrive.getSharedWithMe();");
|
||||
graphQuery = onedrive.getSharedWithMe();
|
||||
}
|
||||
if (e.httpStatusCode >= 500) {
|
||||
// There was a HTTP 5xx Server Side Error
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
// Must exit here
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (graphQuery.type() == JSONType.object) {
|
||||
string sharedFolderName;
|
||||
bool isExternalTenant = false;
|
||||
|
@ -836,7 +885,32 @@ final class SyncEngine
|
|||
if (syncBusinessFolders){
|
||||
log.vlog("Attempting to sync OneDrive Business Shared Folders");
|
||||
// query OneDrive Business Shared Folders shared with me
|
||||
JSONValue graphQuery = onedrive.getSharedWithMe();
|
||||
JSONValue graphQuery;
|
||||
try {
|
||||
graphQuery = onedrive.getSharedWithMe();
|
||||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 401) {
|
||||
// HTTP request returned status code 401 (Unauthorized)
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
log.errorAndNotify("\nERROR: Check your configuration as your refresh_token may be empty or invalid. You may need to issue a --reauth and re-authorise this client.\n");
|
||||
// Must exit here
|
||||
exit(-1);
|
||||
}
|
||||
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.
|
||||
handleOneDriveThrottleRequest();
|
||||
// Retry original request by calling function again to avoid replicating any further error handling
|
||||
log.vdebug("Retrying original request that generated the OneDrive HTTP 429 Response Code (Too Many Requests) - graphQuery = onedrive.getSharedWithMe();");
|
||||
graphQuery = onedrive.getSharedWithMe();
|
||||
}
|
||||
if (e.httpStatusCode >= 500) {
|
||||
// There was a HTTP 5xx Server Side Error
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
// Must exit here
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (graphQuery.type() == JSONType.object) {
|
||||
// valid response from OneDrive
|
||||
string sharedFolderName;
|
||||
|
@ -1205,11 +1279,14 @@ final class SyncEngine
|
|||
}
|
||||
} else {
|
||||
// quota details returned, but for a drive id that is not ours
|
||||
if ("remaining" in currentDriveQuota["quota"]){
|
||||
// remaining is in the quota JSON response
|
||||
if (currentDriveQuota["quota"]["remaining"].integer <= 0) {
|
||||
// value returned is 0 or less than 0
|
||||
log.vlog("OneDrive quota information is set at zero, as this is not our drive id, ignoring");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No quota details returned
|
||||
if (driveId == defaultDriveId) {
|
||||
|
@ -2479,14 +2556,13 @@ final class SyncEngine
|
|||
// file exists locally but is not in the sqlite database - maybe a failed download?
|
||||
log.vlog("Local item does not exist in local database - replacing with file from OneDrive - failed download?");
|
||||
|
||||
// was --resync issued?
|
||||
if (cfg.getValueBool("resync")) {
|
||||
// in a --resync scenario we have zero way of knowing IF the local file is meant to be the right file
|
||||
|
||||
// in a --resync scenario or if items.sqlite3 was deleted before startup we have zero way of knowing IF the local file is meant to be the right file
|
||||
// we have passed the following checks:
|
||||
// 1. file exists locally
|
||||
// 2. local modified time > remote modified time
|
||||
// 3. id is not in the database
|
||||
// 4. --resync was issued
|
||||
|
||||
auto ext = extension(path);
|
||||
auto newPath = path.chomp(ext) ~ "-" ~ deviceName ~ ext;
|
||||
// has the user configured to IGNORE local data protection rules?
|
||||
|
@ -2495,7 +2571,7 @@ final class SyncEngine
|
|||
log.vlog("WARNING: Local Data Protection has been disabled. You may experience data loss on this file: ", path);
|
||||
} else {
|
||||
// local data protection is configured, renaming local file
|
||||
log.vlog("The local item is out-of-sync with OneDrive, renaming to preserve existing file and prevent data loss due to --resync: ", path, " -> ", newPath);
|
||||
log.vlog("The local item is out-of-sync with OneDrive, renaming to preserve existing file and prevent local data loss: ", path, " -> ", newPath);
|
||||
// perform the rename action of the local file
|
||||
if (!dryRun) {
|
||||
safeRename(path);
|
||||
|
@ -2504,7 +2580,7 @@ final class SyncEngine
|
|||
log.vdebug("DRY-RUN: Skipping local file rename");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
// remote file is newer than local item
|
||||
|
@ -2619,6 +2695,12 @@ final class SyncEngine
|
|||
// Configure the applicable permissions for the folder
|
||||
log.vdebug("Setting directory permissions for: ", path);
|
||||
path.setAttributes(cfg.returnRequiredDirectoryPermisions());
|
||||
// Update the time of the folder to match the last modified time as is provided by OneDrive
|
||||
// If there are any files then downloaded into this folder, the last modified time will get
|
||||
// updated by the local Operating System with the latest timestamp - as this is normal operation
|
||||
// as the directory has been modified
|
||||
log.vdebug("Setting directory lastModifiedDateTime for: ", path , " to ", item.mtime);
|
||||
setTimes(path, item.mtime, item.mtime);
|
||||
}
|
||||
} catch (FileException e) {
|
||||
// display the error message
|
||||
|
@ -2860,6 +2942,11 @@ final class SyncEngine
|
|||
}
|
||||
// file has to have downloaded in order to set the times / data for the file
|
||||
if (exists(path)) {
|
||||
// When downloading some files from SharePoint, the OneDrive API reports one file size, but the SharePoint HTTP Server sends a totally different byte count
|
||||
// for the same file
|
||||
// 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
|
||||
// does the file hash OneDrive reports match what we have locally?
|
||||
string quickXorHash = computeQuickXorHash(path);
|
||||
|
@ -2879,18 +2966,39 @@ final class SyncEngine
|
|||
// size error?
|
||||
if (getSize(path) != fileSize) {
|
||||
// downloaded file size does not match
|
||||
log.vdebug("File size on disk: ", getSize(path));
|
||||
log.vdebug("OneDrive API reported size: ", fileSize);
|
||||
log.error("ERROR: File download size mis-match. Increase logging verbosity to determine why.");
|
||||
}
|
||||
// hash error?
|
||||
if ((OneDriveFileHash != quickXorHash) || (OneDriveFileHash != sha1Hash)) {
|
||||
// downloaded file hash does not match
|
||||
log.vdebug("Actual file hash: ", OneDriveFileHash);
|
||||
log.vdebug("OneDrive API reported hash: ", quickXorHash);
|
||||
log.error("ERROR: File download hash mis-match. Increase logging verbosity to determine why.");
|
||||
}
|
||||
// add some workaround messaging
|
||||
if (accountType == "documentLibrary"){
|
||||
// It has been seen where SharePoint / OneDrive API reports one size via the JSON
|
||||
// but the content length and file size written to disk is totally different - example:
|
||||
// From JSON: "size": 17133
|
||||
// From HTTPS Server: < Content-Length: 19340
|
||||
// with no logical reason for the difference, except for a 302 redirect before file download
|
||||
log.error("INFO: It is most likely that a SharePoint OneDrive API issue is the root cause. Add --disable-download-validation to work around this issue but downloaded data integrity cannot be guaranteed.");
|
||||
} else {
|
||||
// other account types
|
||||
log.error("INFO: Potentially add --disable-download-validation to work around this issue but downloaded data integrity cannot be guaranteed.");
|
||||
}
|
||||
|
||||
// we do not want this local file to remain on the local file system
|
||||
safeRemove(path);
|
||||
downloadFailed = true;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// download checks have been disabled
|
||||
log.vdebug("Downloaded file validation disabled due to --disable-download-validation ");
|
||||
}
|
||||
} else {
|
||||
log.error("ERROR: File failed to download. Increase logging verbosity to determine why.");
|
||||
downloadFailed = true;
|
||||
|
@ -2901,6 +3009,9 @@ final class SyncEngine
|
|||
if (!downloadFailed) {
|
||||
writeln("done.");
|
||||
log.fileOnly("Downloading file ", path, " ... done.");
|
||||
} else {
|
||||
writeln("failed!");
|
||||
log.fileOnly("Downloading file ", path, " ... failed!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3395,6 +3506,8 @@ final class SyncEngine
|
|||
{
|
||||
assert(item.type == ItemType.dir);
|
||||
if (exists(path)) {
|
||||
// Fix https://github.com/abraunegg/onedrive/issues/1915
|
||||
try {
|
||||
if (!isDir(path)) {
|
||||
log.vlog("The item was a directory but now it is a file");
|
||||
uploadDeleteItem(item, path);
|
||||
|
@ -3406,6 +3519,11 @@ final class SyncEngine
|
|||
uploadDifferences(child);
|
||||
}
|
||||
}
|
||||
} catch (FileException e) {
|
||||
// display the error message
|
||||
displayFileSystemErrorMessage(e.msg, getFunctionName!({}));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Directory does not exist locally
|
||||
// If we are in a --dry-run situation - this directory may never have existed as we never downloaded it
|
||||
|
@ -4394,7 +4512,18 @@ final class SyncEngine
|
|||
// parent for 'path' is NOT in the database
|
||||
log.vlog("The parent for this path is not in the local database - need to add parent to local database");
|
||||
parentPath = dirName(path);
|
||||
// add the parent into the database
|
||||
uploadCreateDir(parentPath);
|
||||
// save this child item into the database
|
||||
log.vlog("The parent for this path has been added to the local database - adding requested path (", path ,") to database");
|
||||
if (!dryRun) {
|
||||
// save the live data
|
||||
saveItem(response);
|
||||
} else {
|
||||
// need to fake this data
|
||||
auto fakeResponse = createFakeResponse(path);
|
||||
saveItem(fakeResponse);
|
||||
}
|
||||
} else {
|
||||
// parent is in database
|
||||
log.vlog("The parent for this path is in the local database - adding requested path (", path ,") to database");
|
||||
|
@ -4428,6 +4557,40 @@ final class SyncEngine
|
|||
|
||||
// Is the response a valid JSON object - validation checking done in saveItem
|
||||
saveItem(pathDetails);
|
||||
|
||||
// OneDrive Personal Shared Folder edgecase handling
|
||||
// In a:
|
||||
// --resync --upload-only --single-directory 'dir' scenario, and where the root 'dir' for --single-directory is a 'shared folder'
|
||||
// OR
|
||||
// --resync --upload-only scenario, and where the root 'dir' to upload is a 'shared folder'
|
||||
//
|
||||
// We will not have the 'tie' DB entry created because of --upload-only because we do not download the folder structure from OneDrive
|
||||
// to know what the remoteDriveId actually is
|
||||
if (accountType == "personal"){
|
||||
// are we in a --resync --upload-only scenario ?
|
||||
if ((cfg.getValueBool("resync")) && (cfg.getValueBool("upload_only"))) {
|
||||
// Create a temp item
|
||||
// Takes a JSON input and formats to an item which can be used by the database
|
||||
Item tempItem = makeItem(pathDetails);
|
||||
// New DB Tie item due to edge case
|
||||
Item tieDBItem;
|
||||
// Set the name
|
||||
tieDBItem.name = tempItem.name;
|
||||
// Set the correct item type
|
||||
tieDBItem.type = ItemType.dir;
|
||||
//parent.type = ItemType.remote;
|
||||
if ((tempItem.type == ItemType.remote) && (!tempItem.remoteDriveId.empty)) {
|
||||
// set the right elements
|
||||
tieDBItem.driveId = tempItem.remoteDriveId;
|
||||
tieDBItem.id = tempItem.remoteId;
|
||||
// Set the correct mtime
|
||||
tieDBItem.mtime = tempItem.mtime;
|
||||
// Add tie DB record to the local database
|
||||
log.vdebug("Adding tie DB record to database: ", tieDBItem);
|
||||
itemdb.upsert(tieDBItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// need to fake this data
|
||||
auto fakeResponse = createFakeResponse(path);
|
||||
|
@ -4529,7 +4692,15 @@ final class SyncEngine
|
|||
// Does this 'file' already exist on OneDrive?
|
||||
try {
|
||||
// test if the local path exists on OneDrive
|
||||
// if parent.driveId is invalid, then API call will generate a 'HTTP 400 - Bad Request' - make sure we at least have a valid parent.driveId
|
||||
if (!parent.driveId.empty) {
|
||||
// use configured value for parent.driveId
|
||||
fileDetailsFromOneDrive = onedrive.getPathDetailsByDriveId(parent.driveId, path);
|
||||
} else {
|
||||
// switch to using defaultDriveId
|
||||
log.vdebug("parent.driveId is empty - using defaultDriveId for API call");
|
||||
fileDetailsFromOneDrive = onedrive.getPathDetailsByDriveId(defaultDriveId, path);
|
||||
}
|
||||
} catch (OneDriveException e) {
|
||||
// log that we generated an exception
|
||||
log.vdebug("fileDetailsFromOneDrive = onedrive.getPathDetailsByDriveId(parent.driveId, path); generated a OneDriveException");
|
||||
|
@ -5505,12 +5676,21 @@ final class SyncEngine
|
|||
log.vdebug("Skipping adding to database as --upload-only & --remove-source-files configured");
|
||||
} else {
|
||||
// What is the JSON item we are trying to create a DB record with?
|
||||
log.vdebug("Createing DB item from this JSON: ", jsonItem);
|
||||
log.vdebug("Creating DB item from this JSON: ", jsonItem);
|
||||
// Takes a JSON input and formats to an item which can be used by the database
|
||||
Item item = makeItem(jsonItem);
|
||||
// Add to the local database
|
||||
log.vdebug("Adding to database: ", item);
|
||||
itemdb.upsert(item);
|
||||
|
||||
// If we have a remote drive ID, add this to our list of known drive id's
|
||||
if (!item.remoteDriveId.empty) {
|
||||
// Keep the driveIDsArray with unique entries only
|
||||
if (!canFind(driveIDsArray, item.remoteDriveId)) {
|
||||
// Add this drive id to the array to search with
|
||||
driveIDsArray ~= item.remoteDriveId;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// log error
|
||||
|
@ -5737,7 +5917,7 @@ final class SyncEngine
|
|||
log.error("ERROR: Query of OneDrive for Office 365 Library Name failed");
|
||||
if (e.httpStatusCode == 403) {
|
||||
// Forbidden - most likely authentication scope needs to be updated
|
||||
log.error("ERROR: Authentication scope needs to be updated. Use --logout and re-authenticate client.");
|
||||
log.error("ERROR: Authentication scope needs to be updated. Use --reauth and re-authenticate client.");
|
||||
return;
|
||||
}
|
||||
// HTTP request returned status code 429 (Too Many Requests)
|
||||
|
@ -5968,8 +6148,8 @@ final class SyncEngine
|
|||
}
|
||||
}
|
||||
|
||||
// Query OneDrive for a URL path of a file
|
||||
void queryOneDriveForFileURL(string localFilePath, string syncDir)
|
||||
// Query OneDrive for file details of a given path
|
||||
void queryOneDriveForFileDetails(string localFilePath, string syncDir, string outputType)
|
||||
{
|
||||
// Query if file is valid locally
|
||||
if (exists(localFilePath)) {
|
||||
|
@ -5992,20 +6172,40 @@ final class SyncEngine
|
|||
return;
|
||||
}
|
||||
|
||||
// debug output of response
|
||||
log.vdebug("API Response: ", fileDetails);
|
||||
|
||||
// What sort of response to we generate
|
||||
// --get-file-link response
|
||||
if (outputType == "URL") {
|
||||
if ((fileDetails.type() == JSONType.object) && ("webUrl" in fileDetails)) {
|
||||
// Valid JSON object
|
||||
writeln(fileDetails["webUrl"].str);
|
||||
}
|
||||
}
|
||||
|
||||
// --modified-by response
|
||||
if (outputType == "ModifiedBy") {
|
||||
if ((fileDetails.type() == JSONType.object) && ("lastModifiedBy" in fileDetails)) {
|
||||
// Valid JSON object
|
||||
writeln("Last modified: ", fileDetails["lastModifiedDateTime"].str);
|
||||
writeln("Last modified by: ", fileDetails["lastModifiedBy"]["user"]["displayName"].str);
|
||||
// if 'email' provided, add this to the output
|
||||
if ("email" in fileDetails["lastModifiedBy"]["user"]) {
|
||||
writeln("Email Address: ", fileDetails["lastModifiedBy"]["user"]["email"].str);
|
||||
}
|
||||
// was file found?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// was path found?
|
||||
if (!fileInDB) {
|
||||
// File has not been synced with OneDrive
|
||||
log.error("File has not been synced with OneDrive: ", localFilePath);
|
||||
log.error("Path has not been synced with OneDrive: ", localFilePath);
|
||||
}
|
||||
} else {
|
||||
// File does not exist locally
|
||||
log.error("File not found on local system: ", localFilePath);
|
||||
log.error("Path not found on local system: ", localFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6201,10 +6401,8 @@ final class SyncEngine
|
|||
string fakeRootId = defaultRootId;
|
||||
SysTime mtime = timeLastModified(path).toUTC();
|
||||
|
||||
// If the account type is Business, and if Shared Business Folders are being used
|
||||
// Need to update the 'fakeDriveId' & 'fakeRootId' with elements from the database
|
||||
// Otherwise some calls to validate objects fail as the actual driveId being used is invalid
|
||||
if (accountType == "business") {
|
||||
// Need to update the 'fakeDriveId' & 'fakeRootId' with elements from the --dry-run database
|
||||
// Otherwise some calls to validate objects will fail as the actual driveId being used is invalid
|
||||
string parentPath = dirName(path);
|
||||
Item databaseItem;
|
||||
|
||||
|
@ -6220,7 +6418,6 @@ final class SyncEngine
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// real id / eTag / cTag are different format for personal / business account
|
||||
auto sha1 = new SHA1Digest();
|
||||
|
@ -6499,64 +6696,7 @@ final class SyncEngine
|
|||
|
||||
for (;;) {
|
||||
// query children
|
||||
try {
|
||||
thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink);
|
||||
} catch (OneDriveException e) {
|
||||
// OneDrive threw an error
|
||||
log.vdebug("------------------------------------------------------------------");
|
||||
log.vdebug("Query Error: thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink)");
|
||||
log.vdebug("driveId: ", driveId);
|
||||
log.vdebug("idToQuery: ", idToQuery);
|
||||
log.vdebug("nextLink: ", nextLink);
|
||||
|
||||
// HTTP request returned status code 404 (Not Found)
|
||||
if (e.httpStatusCode == 404) {
|
||||
// Stop application
|
||||
log.log("\n\nOneDrive returned a 'HTTP 404 - Item not found'");
|
||||
log.log("The item id to query was not found on OneDrive");
|
||||
log.log("\nRemove your '", cfg.databaseFilePath, "' file and try to sync again\n");
|
||||
}
|
||||
|
||||
// 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.
|
||||
handleOneDriveThrottleRequest();
|
||||
log.vdebug("Retrying original request that generated the OneDrive HTTP 429 Response Code (Too Many Requests) - attempting to query OneDrive drive children");
|
||||
}
|
||||
|
||||
// HTTP request returned status code 500 (Internal Server Error)
|
||||
if (e.httpStatusCode == 500) {
|
||||
// display what the error is
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
}
|
||||
|
||||
// HTTP request returned status code 504 (Gateway Timeout) or 429 retry
|
||||
if ((e.httpStatusCode == 429) || (e.httpStatusCode == 504)) {
|
||||
// re-try the specific changes queries
|
||||
if (e.httpStatusCode == 504) {
|
||||
log.log("OneDrive returned a 'HTTP 504 - Gateway Timeout' when attempting to query OneDrive drive children - retrying applicable request");
|
||||
log.vdebug("thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink) previously threw an error - retrying");
|
||||
// The server, while acting as a proxy, did not receive a timely response from the upstream server it needed to access in attempting to complete the request.
|
||||
log.vdebug("Thread sleeping for 30 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"(30));
|
||||
}
|
||||
// re-try original request - retried for 429 and 504
|
||||
try {
|
||||
log.vdebug("Retrying Query: thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink)");
|
||||
thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink);
|
||||
log.vdebug("Query 'thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink)' performed successfully on re-try");
|
||||
} catch (OneDriveException e) {
|
||||
// display what the error is
|
||||
log.vdebug("Query Error: thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink) on re-try after delay");
|
||||
// error was not a 504 this time
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
}
|
||||
} else {
|
||||
// Default operation if not 404, 410, 429, 500 or 504 errors
|
||||
// display what the error is
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
}
|
||||
}
|
||||
thisLevelChildren = queryThisLevelChildren(driveId, idToQuery, nextLink);
|
||||
|
||||
// process this level children
|
||||
if (!childParentPath.empty) {
|
||||
|
@ -6601,6 +6741,64 @@ final class SyncEngine
|
|||
return thisLevelChildrenData;
|
||||
}
|
||||
|
||||
// Query from OneDrive the child objects for this element
|
||||
JSONValue queryThisLevelChildren(const(char)[] driveId, const(char)[] idToQuery, string nextLink)
|
||||
{
|
||||
JSONValue thisLevelChildren;
|
||||
|
||||
// query children
|
||||
try {
|
||||
// attempt API call
|
||||
log.vdebug("Attempting Query: thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink)");
|
||||
thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink);
|
||||
log.vdebug("Query 'thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink)' performed successfully");
|
||||
} catch (OneDriveException e) {
|
||||
// OneDrive threw an error
|
||||
log.vdebug("------------------------------------------------------------------");
|
||||
log.vdebug("Query Error: thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink)");
|
||||
log.vdebug("driveId: ", driveId);
|
||||
log.vdebug("idToQuery: ", idToQuery);
|
||||
log.vdebug("nextLink: ", nextLink);
|
||||
|
||||
// HTTP request returned status code 404 (Not Found)
|
||||
if (e.httpStatusCode == 404) {
|
||||
// Stop application
|
||||
log.log("\n\nOneDrive returned a 'HTTP 404 - Item not found'");
|
||||
log.log("The item id to query was not found on OneDrive");
|
||||
log.log("\nRemove your '", cfg.databaseFilePath, "' file and try to sync again\n");
|
||||
}
|
||||
|
||||
// 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.
|
||||
handleOneDriveThrottleRequest();
|
||||
log.vdebug("Retrying original request that generated the OneDrive HTTP 429 Response Code (Too Many Requests) - attempting to query OneDrive drive children");
|
||||
}
|
||||
|
||||
// HTTP request returned status code 504 (Gateway Timeout) or 429 retry
|
||||
if ((e.httpStatusCode == 429) || (e.httpStatusCode == 504)) {
|
||||
// re-try the specific changes queries
|
||||
if (e.httpStatusCode == 504) {
|
||||
// transient error - try again in 30 seconds
|
||||
log.log("OneDrive returned a 'HTTP 504 - Gateway Timeout' when attempting to query OneDrive drive children - retrying applicable request");
|
||||
log.vdebug("thisLevelChildren = onedrive.listChildren(driveId, idToQuery, nextLink) previously threw an error - retrying");
|
||||
// The server, while acting as a proxy, did not receive a timely response from the upstream server it needed to access in attempting to complete the request.
|
||||
log.vdebug("Thread sleeping for 30 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"(30));
|
||||
}
|
||||
// re-try original request - retried for 429 and 504 - but loop back calling this function
|
||||
log.vdebug("Retrying Query: thisLevelChildren = queryThisLevelChildren(driveId, idToQuery, nextLink)");
|
||||
thisLevelChildren = queryThisLevelChildren(driveId, idToQuery, nextLink);
|
||||
} else {
|
||||
// Default operation if not 404, 429 or 504 errors
|
||||
// display what the error is
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
}
|
||||
}
|
||||
// return response
|
||||
return thisLevelChildren;
|
||||
}
|
||||
|
||||
// OneDrive Business Shared Folder support
|
||||
void listOneDriveBusinessSharedFolders()
|
||||
{
|
||||
|
@ -6630,7 +6828,32 @@ final class SyncEngine
|
|||
}
|
||||
|
||||
// Query the GET /me/drive/sharedWithMe API
|
||||
JSONValue graphQuery = onedrive.getSharedWithMe();
|
||||
JSONValue graphQuery;
|
||||
try {
|
||||
graphQuery = onedrive.getSharedWithMe();
|
||||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 401) {
|
||||
// HTTP request returned status code 401 (Unauthorized)
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
log.errorAndNotify("\nERROR: Check your configuration as your refresh_token may be empty or invalid. You may need to issue a --reauth and re-authorise this client.\n");
|
||||
// Must exit here
|
||||
exit(-1);
|
||||
}
|
||||
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.
|
||||
handleOneDriveThrottleRequest();
|
||||
// Retry original request by calling function again to avoid replicating any further error handling
|
||||
log.vdebug("Retrying original request that generated the OneDrive HTTP 429 Response Code (Too Many Requests) - graphQuery = onedrive.getSharedWithMe();");
|
||||
graphQuery = onedrive.getSharedWithMe();
|
||||
}
|
||||
if (e.httpStatusCode >= 500) {
|
||||
// There was a HTTP 5xx Server Side Error
|
||||
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
|
||||
// Must exit here
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (graphQuery.type() == JSONType.object) {
|
||||
if (count(graphQuery["value"].array) == 0) {
|
||||
// no shared folders returned
|
||||
|
|
65
src/util.d
65
src/util.d
|
@ -351,6 +351,71 @@ string getFunctionName(alias func)() {
|
|||
return __traits(identifier, __traits(parent, func)) ~ "()\n";
|
||||
}
|
||||
|
||||
// Get the latest release version from GitHub
|
||||
string getLatestReleaseVersion() {
|
||||
// Import curl just for this function
|
||||
import std.net.curl;
|
||||
char[] content;
|
||||
JSONValue json;
|
||||
string latestTag;
|
||||
|
||||
try {
|
||||
content = get("https://api.github.com/repos/abraunegg/onedrive/releases/latest");
|
||||
} catch (CurlException e) {
|
||||
// curl generated an error - meaning we could not query GitHub
|
||||
log.vdebug("Unable to query GitHub for latest release");
|
||||
}
|
||||
|
||||
try {
|
||||
json = 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("{}");
|
||||
}
|
||||
|
||||
// json has to be a valid JSON object
|
||||
if (json.type() == JSONType.object){
|
||||
if ("tag_name" in json) {
|
||||
// use the provided tag
|
||||
// "tag_name": "vA.B.CC" and strip 'v'
|
||||
latestTag = strip(json["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");
|
||||
latestTag = "0.0.0";
|
||||
}
|
||||
} else {
|
||||
// JSONValue is not an object
|
||||
log.vdebug("Invalid JSON Object. Setting latest GitHub release version to 0.0.0");
|
||||
latestTag = "0.0.0";
|
||||
}
|
||||
|
||||
// return the latest github version
|
||||
return latestTag;
|
||||
}
|
||||
|
||||
// Check the application version versus GitHub latestTag
|
||||
void checkApplicationVersion() {
|
||||
// calculate if the client is current version or not
|
||||
string latestVersion = strip(getLatestReleaseVersion());
|
||||
auto currentVersionArray = strip(strip(import("version"), "v")).split("-");
|
||||
string applicationVersion = currentVersionArray[0];
|
||||
|
||||
// display warning if not current
|
||||
if (applicationVersion != latestVersion) {
|
||||
// is application version is older than available on GitHub
|
||||
if (applicationVersion < latestVersion) {
|
||||
// application version is obsolete and unsupported
|
||||
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);
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unit Tests
|
||||
unittest
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue