-
Notifications
You must be signed in to change notification settings - Fork 0
Daemon
The Python daemon that performs bidirectional Google Drive synchronization.
The daemon runs on Linux, macOS, and Windows as a background process (or systemd user service on Linux) and handles:
- Watching local directories for changes (via watchdog)
- Polling Google Drive for remote changes
- Planning and executing sync operations (upload, download, delete)
- Detecting and resolving conflicts
- Serving an IPC interface over a Unix domain socket
cloud-drive-sync-daemon [OPTIONS] COMMAND
| Option | Description |
|---|---|
--config PATH |
Path to config.toml (default: ~/.config/cloud-drive-sync/config.toml) |
--log-level LEVEL |
Override log level: debug, info, warning, error
|
Start the sync daemon.
cloud-drive-sync-daemon start # Daemonize (fork to background, Linux/macOS only)
cloud-drive-sync-daemon start --foreground # Run in foreground (for development/systemd)
cloud-drive-sync-daemon start --demo # Run with mock Drive API (no Google account needed)| Flag | Description |
|---|---|
--foreground |
Run in the foreground instead of forking |
--demo |
Use mock Drive client with synthetic test data |
--config PATH |
Path to config file |
Windows note: The daemon always runs in foreground mode on Windows (fork is not supported). The Tauri UI manages the daemon lifecycle as a sidecar process.
Stop a running daemon by sending SIGTERM.
cloud-drive-sync-daemon stopCheck whether the daemon is running.
cloud-drive-sync-daemon status
# Output: "Daemon is running (PID 12345)" or "Daemon is not running."Run the OAuth2 authorization flow interactively.
cloud-drive-sync-daemon auth
# Output: "Authorization successful. Credentials stored and ready to use."The daemon reads configuration from a platform-specific path (or the path specified by --config). All values have sensible defaults.
| Platform | Default config path |
|---|---|
| Linux | ~/.config/cloud-drive-sync/config.toml |
| macOS | ~/Library/Application Support/cloud-drive-sync/config.toml |
| Windows | %APPDATA%\cloud-drive-sync\config.toml |
| Key | Type | Default | Description |
|---|---|---|---|
log_level |
string | "info" |
Logging level: debug, info, warning, error
|
| Key | Type | Default | Description |
|---|---|---|---|
poll_interval |
integer | 30 |
Seconds between remote change polls |
conflict_strategy |
string | "keep_both" |
How to handle conflicts: keep_both, newest_wins, ask_user
|
max_concurrent_transfers |
integer | 4 |
Max simultaneous upload/download operations |
debounce_delay |
float | 1.0 |
Seconds to wait before processing a local change (coalesces rapid edits) |
Each [[sync.pairs]] entry defines a local-to-remote folder mapping.
| Key | Type | Default | Description |
|---|---|---|---|
local_path |
string | (required) | Absolute path to the local directory |
remote_folder_id |
string | "root" |
Google Drive folder ID ("root" = My Drive top level) |
enabled |
boolean | true |
Whether this pair should be synced |
sync_mode |
string | "two_way" |
Sync direction: "two_way", "upload_only", or "download_only"
|
ignore_hidden |
boolean | true |
Whether to exclude hidden files/directories (names starting with .) from sync |
[general]
log_level = "info"
[sync]
poll_interval = 30
conflict_strategy = "keep_both"
max_concurrent_transfers = 4
debounce_delay = 1.0
[[sync.pairs]]
local_path = "/home/user/Documents"
remote_folder_id = "root"
enabled = true
sync_mode = "two_way"
ignore_hidden = true
[[sync.pairs]]
local_path = "/home/user/Pictures"
remote_folder_id = "0A3xRemoteFolderIdHere"
enabled = true
sync_mode = "upload_only"
ignore_hidden = trueDemo mode runs the full daemon with a mock Drive client instead of connecting to Google's API:
cloud-drive-sync-daemon start --foreground --demoWhat demo mode does:
- Creates a temporary local sync directory with sample files
- Simulates remote files and changes
- Processes sync operations (upload/download/conflict) against the mock backend
- Responds to all IPC commands normally
This allows the UI to be fully tested without a Google account or network access.
All providers support headless auth for servers and Docker containers:
# Google Drive (console flow — prints URL, paste authorization code)
cloud-drive-sync account add --provider gdrive --headless
# OneDrive (device code flow — prints code, authorize on another device)
cloud-drive-sync account add --provider onedrive --headless
# Dropbox (prints URL, paste authorization code)
cloud-drive-sync account add --provider dropbox --headless
# Nextcloud (prompts for server URL, username, app password)
cloud-drive-sync account add --provider nextcloud --headless
# Box (prints URL, paste authorization code)
cloud-drive-sync account add --provider box --headlessThe --headless flag disables automatic browser opening. The daemon prints a URL or device code to the console, and you complete authorization on any device with a browser.
The daemon runs headless in Docker with no GUI dependencies.
docker run -d --name cloud-drive-sync \
-v cloud-drive-sync-config:/root/.config/cloud-drive-sync \
-v cloud-drive-sync-data:/root/.local/share/cloud-drive-sync \
-v ~/Documents:/data/Documents \
ghcr.io/ciberkids/cloud-drive-sync:latest
# Add account (interactive — prints auth URL)
docker exec -it cloud-drive-sync \
python -m cloud_drive_sync account add --provider gdrive --headless
# Check status
docker exec cloud-drive-sync python -m cloud_drive_sync statusSee docker/docker-compose.yml for a ready-to-use compose file.
| Mount | Purpose |
|---|---|
/root/.config/cloud-drive-sync |
Config (config.toml) |
/root/.local/share/cloud-drive-sync |
Credentials, database |
/run/cloud-drive-sync |
IPC socket (for CLI from host) |
/data/* |
Sync folder mount points |
| Variable | Default | Description |
|---|---|---|
XDG_RUNTIME_DIR |
/run/cloud-drive-sync |
IPC socket directory |
CDS_GOOGLE_CLIENT_ID |
(embedded) | Override Google OAuth client ID |
CDS_GOOGLE_CLIENT_SECRET |
(embedded) | Override Google OAuth client secret |
cd daemon
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"# With real Drive API
python -m cloud_drive_sync --log-level debug start --foreground
# With demo mode
python -m cloud_drive_sync start --foreground --demopytest -v
pytest --cov=cloud_drive_sync # With coverageruff check src/ tests/The daemon is structured as a set of asyncio components:
Daemon
├── Config (TOML loader)
├── Database (async SQLite via aiosqlite)
├── DriveClient (Google API v3 wrapper)
├── SyncEngine
│ ├── DirectoryWatcher (per pair, watchdog-based)
│ ├── ChangePoller (per pair, Drive Changes API)
│ ├── SyncPlanner (diff + action planning)
│ ├── SyncExecutor (concurrent transfer runner)
│ └── ConflictResolver (strategy dispatch)
└── IpcServer (Unix socket, JSON-RPC 2.0)
└── RequestHandler (method dispatch)
For full architectural details, see the Architecture page.
| Package | Version | Purpose |
|---|---|---|
| google-api-python-client | >=2.100.0 | Google Drive API v3 |
| google-auth-oauthlib | >=1.1.0 | OAuth2 flow |
| google-auth-httplib2 | >=0.2.0 | HTTP transport for Google auth |
| watchdog | >=4.0.0 | Filesystem event monitoring |
| aiosqlite | >=0.19.0 | Async SQLite |
| aiofiles | >=23.2.0 | Async file I/O |
| tomli-w | >=1.0.0 | TOML writing |
| click | >=8.1.0 | CLI framework |
| cryptography | >=41.0.0 | Credential encryption |
| Package | Version | Purpose |
|---|---|---|
| pytest | >=7.4.0 | Test framework |
| pytest-asyncio | >=0.21.0 | Async test support |
| pytest-cov | >=4.1.0 | Coverage reporting |
| ruff | >=0.1.0 | Linter and formatter |
Cloud Drive Sync
Getting Started
Reference
Project