Skip to content

Rclone and Google Drive

P3DROVFX edited this page Oct 12, 2026 · 1 revision

Rclone and Google Drive

An automatic backup of the folders you choose to your own Google Drive, run by rclone on a schedule you set, with live progress, per-run history, a storage chart and notifications — all inside Settings → Accounts & Backup. It is a backup, not a two-way sync: your machine is the source of truth, and Drive receives a copy (optionally with old versions kept aside).

Nothing runs until you set it up: the feature is off by default, rclone is an optional dependency (its absence is a status message, never a crash and never an automatic install), and the first upload only happens after you add a folder, authorize Drive and switch it on.

folders you pick ──▶ scripts/gdrive/sync.sh ──▶ rclone copy/sync ──▶ Drive:<you>_<distro>_backups/<folder>
                         ▲   progress as JSON events           └─▶ Drive:…/.versions/<timestamp>/<folder>  (old copies)
              GoogleDriveService.qml (schedule, metered/network checks, history, notifications)

Quick start

  1. Install rclone — it is the optional google-drive feature (ii-p3drovfx deps add google-drive, see Installer and CLI). If it is missing, the top of the Google Drive section shows a copyable command for your distribution — Fedora/RHEL, Arch family, Debian/Ubuntu family, NixOS, openSUSE, Alpine, Gentoo, Void or Solus — or the official installer script for anything else. You run it; the shell never installs packages by itself.
  2. Google credentials. Drive uses the same OAuth client as Gmail, Tasks and Calendar — create it once with Google Cloud Setup and enable the Google Drive API in that project.
  3. Authorize. Settings → Accounts & Backup → Google Drive → authorize. The browser opens (rclone authorize drive), you approve, and an rclone remote named ii-gdrive is created. A cancelled or failed browser flow leaves any existing, working remote untouched.
  4. Add folders with the folder button (a zenity chooser, kdialog as fallback), review the exclusions, and turn the main switch on. Back up now runs it immediately.

The Welcome app has the same walkthrough as the Set up Google Drive backup tutorial.


What the section shows

Separate cards, each answering one question:

  • Status — Setup required / Connected / Syncing, the rclone version, the last result, and (after an interrupted run) Previous sync interrupted · run again.
  • Destination — the top-level Drive folder. The default is per machine, <username>_<distro>_backups, so two computers never overwrite each other; an empty setting or the old ii-backup value both resolve to it, and a custom name is kept as typed (letters, digits, dots, underscores, dashes and nested a/b folders only).
  • Authorization — connect, or Reauthorize if Google revoked the token (shown in the error container colour).
  • Activity — a bento grid: a daily transfer trend (periods without transfers stay visible as gaps), a storage semi-donut (the backup against your Drive quota), a month heatmap of backup days, health and performance cards (volume and timing tabs), the recent run history and retention.
  • Folders — the list of backed-up folders, Schedule, Exclusions.
  • Advanced (the subpage): remote folder name, bandwidth limit, metered-connection and network behaviour, versions kept, orphan policy, notifications, and Backup only files modified since last backup.

Settings (googleDrive)

These live in the shell's durable state, not in the preset-controlled config, because a backup destination is a fact about this machine; presets never touch them (Customization).

Option Default Meaning
enabled off Master switch
syncInterval 3d 1h, 4h, 1d, 2d or 3d (an older 24h becomes 1d; anything else becomes 3d)
syncOnBoot on Run at login when the last backup is older than the interval
syncOnNetworkChange off Run shortly after the network comes back
pauseOnMeteredConnection on Skip while the connection is metered
bandwidthLimitKbps 0 --bwlimit; 0 means unlimited
backupFolders [] Absolute paths
excludePatterns *.tmp, *.swp, *.lock, node_modules/, .git/, __pycache__/ rclone filter globs
driveBasePath "" Remote folder (empty = automatic)
keepVersions 3 Old versions kept (0 = none)
deleteRemoteOrphans off Remove from Drive what you deleted locally
onlyModifiedSinceLastSync off --max-age <last sync time>
notifyOnComplete, notifyOnError on Notifications

The last-run numbers, the 366 most recent run events, and the cached quota / backup-size telemetry are persisted so the page is meaningful before the first refresh.


How a backup runs

For each folder, sync.sh runs:

  • rclone copy <folder> ii-gdrive:<base>/<folder-name> — or rclone sync only when Delete from Drive (orphans) is on. copy never deletes anything on Drive.
  • --exclude-from your patterns, --bwlimit when set, --max-age for "only modified since last backup".
  • With keepVersions > 0, --backup-dir ii-gdrive:<base>/.versions/<timestamp>/<folder>: files that would be overwritten or deleted are moved there instead. After a successful copy the script prunes the oldest version directories beyond the limit, with a 20-second timeout — rclone lsf on Drive can hang indefinitely even after the copy hit 100 %, and the backup must still count as done.
  • Progress is read from rclone's stats lines at --stats 2s (not --progress, which redraws on every file and floods the shell), converted to JSON events (start, stats, file, maintenance, warning, done, complete), and logged to ~/.local/state/illogical-impulse/gdrive/sync-<timestamp>.log.
  • A final rclone size (30-second timeout) fills in the real folder contents, so a run that transferred nothing does not read as "0 files / 0 MB".

Every argument is validated before use (the base path must match [A-Za-z0-9][A-Za-z0-9._/-]* with no .., numbers must be non-negative integers), and the script forwards HUP/INT/TERM to rclone and its parser, so cancelling, closing Settings or hot-reloading the shell can never leave an orphaned upload running.

Scheduling

GoogleDriveService is a boot singleton, so the schedule runs without Settings open. Rules that keep it honest:

  • A timer fires every syncInterval, but the decision uses the persisted time of the last completed backup, so a shell restart cannot turn a three-day schedule into an immediate second upload.
  • Back up at boot is evaluated once per start; a run left marked running by a crash or reload is retried only after it has been stale for 30 minutes.
  • No network → No network connection; metered and pauseOnMeteredConnection → Sync paused on a metered connection; no folders → Add a backup folder first. These are shown, not retried in a loop.
  • With Sync when network connects, a reconnect starts a run after a short settling delay.

From the command line

qs -c ii ipc call googleDriveBackup sync                 # start now
qs -c ii ipc call googleDriveBackup cancel
qs -c ii ipc call googleDriveBackup status               # JSON: configured, syncing, progress, folder, files, bytes, error
qs -c ii ipc call googleDriveBackup setBandwidthLimit 500   # KB/s, 0 removes the limit

Standalone: bash scripts/gdrive/sync.sh --base-path me_fedora_backups --keep-versions 3 --delete-orphans false --exclude-file ex.txt --folder ~/Documents prints the same JSON events.


Security notes

  • Same client as everything else. setup_rclone.py runs rclone authorize drive <client_id> <client_secret> with GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET from ii/.env, and creates the remote with that same pair. OAuth tokens are bound to the client that requested them; mixing rclone's built-in client with your own would fail every refresh with unauthorized_client. Error messages from the helper are scrubbed of the client id, secret and token.
  • Scope. The remote is created with the drive scope (full access to your Drive) because rclone needs to list and manage the backup tree; the app only ever touches <base>/…, but the token could do more. If that is not acceptable, use your own, narrower rclone remote and point the service at it by naming it ii-gdrive.
  • The token lives in rclone's normal config (~/.config/rclone/rclone.conf), not in the shell's files, and is not part of the settings backup.
  • Not encrypted. Files land in Drive as ordinary files under your account. If you need client-side encryption, set up an rclone crypt remote yourself; the shell does not manage one.
  • The destination folder name cannot contain shell metacharacters, and exclusion patterns are written to a temp file (never put on a command line).

Used by other features

  • Backup and Restore — the settings zip can ride along: Keep a copy in Google Drive just adds the backup folder to backupFolders; there is no second uploader.
  • Notes — Keep a copy in Google Drive adds the notes folder to the same list, with a Sync now button.

Troubleshooting

Symptom Cause / fix
rclone is not installed Run the install command shown in the section, then reopen the section (it checks again)
Authorize Google Drive before syncing No ii-gdrive remote: authorize first
Authorization fails with unauthorized_client or invalid_client The remote was created with another client than the one in .env; reauthorize so both match
Google Drive API has not been used in project … Enable the Drive API in the same Google Cloud project
Token expires weekly The OAuth app is in Testing; publish it ([[Google Cloud Setup
Progress sits at 100 % for a while The version-pruning step; it times out after 20 s and keeps your backup
Nothing happens at boot Interval not yet elapsed, or the last run was marked running less than 30 minutes ago
A folder is skipped with backup folder is not a directory The path no longer exists or is a file

Under the hood

Piece Role
services/GoogleDriveService.qml The singleton: rclone/remote checks, scheduling, history, quota, notifications, IPC
scripts/gdrive/sync.sh Argument validation, rclone copy/sync, versions, JSON events, signal forwarding
scripts/gdrive/setup_rclone.py Authorize + create/update the ii-gdrive remote
scripts/gdrive/drive_info.py Drive quota and backup size (rclone about/size, 20 s timeouts)
scripts/gdrive/check_rclone.sh Installed? Remote configured? Version
modules/settings/configs/TasksAccountsConfig.qml, widgets/GoogleDriveBackupConfig.qml, widgets/AdvancedDriveConfig.qml The settings UI
modules/ii/usage/UsageSemiDonut.qml, UsageColumnChart.qml, UsageActivityHeatmap.qml Charts, shared with the Usage app

Related pages

← Back to Home

Clone this wiki locally