Skip to content

Commit c448953

Browse files
Jonathan D.A. Jewellclaude
andcommitted
Add v1.0 enterprise features, desktop integration, and tooling
MUST features: - install.sh: Full installation script with all components - scripts/cloud-sync-status: Health check command with JSON output - systemd/cloud-sync-watchdog.*: Error recovery timer/service SHOULD features: - selinux/: Full SELinux policy module (rclone_t confined domain) - audit/: auditd rules for enterprise compliance logging - overlay-daemon/: Rust daemon for file manager sync status - tray-daemon/: System tray daemon with notifications - nautilus-extension/: Nautilus sync status emblems - dolphin-extension/: Dolphin context menu actions Tooling: - justfile: Comprehensive recipes including cookbooks - config/schema.ncl: Nickel configuration schema - .laminar/: CI integration for laminar - tests/: Ada test runner and SPARK formal verification Documentation: - README.adoc: Updated with v1.0 features section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent e462fd3 commit c448953

24 files changed

Lines changed: 3181 additions & 0 deletions

.laminar/cloud-sync-tuner.run

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
# Laminar CI job for cloud-sync-tuner
4+
# Place in /var/lib/laminar/cfg/jobs/
5+
6+
set -euo pipefail
7+
8+
echo "=== Cloud Sync Tuner CI ==="
9+
echo "Commit: ${GIT_COMMIT:-unknown}"
10+
echo "Branch: ${GIT_BRANCH:-unknown}"
11+
echo ""
12+
13+
# Checkout
14+
cd "$WORKSPACE"
15+
git fetch --all
16+
git checkout "${GIT_COMMIT:-HEAD}"
17+
18+
# Build
19+
echo "=== Building ==="
20+
just build
21+
22+
# Lint
23+
echo "=== Linting ==="
24+
just lint
25+
26+
# Test
27+
echo "=== Testing ==="
28+
just test
29+
30+
# Security scan
31+
echo "=== Security Scan ==="
32+
if command -v cargo-audit &>/dev/null; then
33+
cd overlay-daemon && cargo audit
34+
cd ../tray-daemon && cargo audit
35+
cd ..
36+
fi
37+
38+
# Build SELinux policy (don't fail if selinux-devel missing)
39+
echo "=== SELinux Policy ==="
40+
just build-selinux || echo "SELinux build skipped (missing deps)"
41+
42+
# Package
43+
echo "=== Packaging ==="
44+
VERSION=$(grep -oP 'Version : constant String := "\K[^"]+' src/cloud_sync_tuner.adb)
45+
just release "$VERSION"
46+
47+
echo ""
48+
echo "=== CI Complete ==="
49+
echo "Artifact: dist/cloud-sync-tuner-${VERSION}.tar.gz"

README.adoc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,57 @@ This tool complements https://github.com/hyperpolymath/laminar[laminar] for clou
220220
|Android |- |✓ |✓ |- |No mounts, remote ops only
221221
|===
222222

223+
== v1.0 Features
224+
225+
=== Smart Sync
226+
227+
[cols="1,2"]
228+
|===
229+
|Feature |Description
230+
231+
|Cache size limits |Auto-evict old files when cache exceeds threshold
232+
|Min free space |Emergency eviction when disk runs low
233+
|Write-back buffering |Buffer writes locally before uploading
234+
|Pinned folders |Mark folders for offline access (like native clients)
235+
|Bandwidth scheduling |Time-based bandwidth limits
236+
|Conflict resolution |Configurable strategy (newer/older/larger/path1)
237+
|===
238+
239+
=== Desktop Integration
240+
241+
* **System tray daemon** (`cloud-sync-tray`) - Real-time sync status icon
242+
* **Nautilus extension** - Sync status emblems in GNOME Files
243+
* **Dolphin service menu** - Context menu actions in KDE
244+
* **Desktop notifications** - Alerts for sync events
245+
246+
=== Enterprise Features
247+
248+
* **SELinux policy** - Confined `rclone_t` domain
249+
* **Auditd rules** - File access logging for compliance
250+
* **Health check** - `cloud-sync-status` command for monitoring
251+
* **Watchdog timer** - Automatic service recovery
252+
253+
=== Just Recipes
254+
255+
[source,bash]
256+
----
257+
just cookbook-dropbox-fix # Fix Dropbox rate limiting
258+
just cookbook-offline-setup # Setup offline folders
259+
just cookbook-max-performance # Maximum caching
260+
just cookbook-enterprise # Enable SELinux + audit
261+
----
262+
263+
== Installation (v1.0)
264+
265+
[source,bash]
266+
----
267+
git clone https://github.com/hyperpolymath/cloud-sync-tuner
268+
cd cloud-sync-tuner
269+
just install
270+
----
271+
272+
See `justfile` for all available recipes.
273+
223274
== License
224275

225276
AGPL-3.0-or-later

audit/cloud-sync-tuner.rules

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# SPDX-License-Identifier: AGPL-3.0-or-later
2+
# auditd rules for cloud-sync-tuner
3+
# Enterprise compliance logging for cloud file access
4+
5+
# Rule identification key
6+
-k cloud-sync
7+
8+
########################################
9+
# Monitor rclone binary execution
10+
########################################
11+
-w /home/hyper/.local/bin/rclone -p x -k cloud-sync-exec
12+
-w /usr/bin/rclone -p x -k cloud-sync-exec
13+
14+
########################################
15+
# Monitor configuration changes
16+
########################################
17+
-w /home/hyper/.config/rclone/rclone.conf -p wa -k cloud-sync-config
18+
-w /home/hyper/.config/cloud-sync-tuner/ -p wa -k cloud-sync-config
19+
20+
########################################
21+
# Monitor mount point access
22+
# Note: Excessive logging may occur - tune for your needs
23+
########################################
24+
25+
# Dropbox mount - file modifications only (not reads)
26+
-w /run/media/hyper/eclipse/Cloud/Dropbox -p wa -k cloud-sync-dropbox
27+
28+
# Google Drive mount - file modifications only
29+
-w /run/media/hyper/eclipse/Cloud/GoogleDrive -p wa -k cloud-sync-gdrive
30+
31+
# OneDrive mount - file modifications only
32+
-w /run/media/hyper/eclipse/Cloud/OneDrive -p wa -k cloud-sync-onedrive
33+
34+
########################################
35+
# Monitor cache directory for debugging
36+
# Uncomment for troubleshooting only
37+
########################################
38+
# -w /home/hyper/.cache/rclone -p wa -k cloud-sync-cache
39+
40+
########################################
41+
# Monitor offline sync directory
42+
########################################
43+
-w /home/hyper/Offline -p wa -k cloud-sync-offline
44+
45+
########################################
46+
# Monitor systemd service changes
47+
########################################
48+
-w /home/hyper/.config/systemd/user/rclone-dropbox.service -p wa -k cloud-sync-service
49+
-w /home/hyper/.config/systemd/user/rclone-gdrive.service -p wa -k cloud-sync-service
50+
-w /home/hyper/.config/systemd/user/rclone-onedrive.service -p wa -k cloud-sync-service
51+
52+
########################################
53+
# Monitor credential access
54+
########################################
55+
-w /home/hyper/.config/rclone/rclone.conf -p r -k cloud-sync-cred-access
56+
57+
########################################
58+
# FUSE device access
59+
########################################
60+
-a always,exit -F arch=b64 -S open,openat -F path=/dev/fuse -k cloud-sync-fuse

config/schema.ncl

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# SPDX-License-Identifier: AGPL-3.0-or-later
2+
# Cloud Sync Tuner - Nickel Configuration Schema
3+
# Validates and generates TOML configuration
4+
5+
let CacheMode = [| 'Off, 'Minimal, 'Writes, 'Full |] in
6+
7+
let ConflictStrategy = [| 'None, 'Newer, 'Older, 'Larger, 'Smaller, 'Path1, 'Path2 |] in
8+
9+
let RateLimiting = {
10+
tps_limit | Number | default = 4
11+
| doc "Transactions per second (1-100)",
12+
tps_burst | Number | default = 1
13+
| doc "Burst allowance (1-10)",
14+
chunk_size_mb | Number | default = 32
15+
| doc "Read chunk size in MB (1-512)",
16+
cache_age_hours | Number | default = 72
17+
| doc "Cache entry max age in hours (1-168)",
18+
dir_cache_min | Number | default = 5
19+
| doc "Directory cache time in minutes (1-60)",
20+
} in
21+
22+
let SmartSync = {
23+
cache_max_size_gb | Number | default = 10
24+
| doc "Maximum cache size in GB (0 = unlimited)",
25+
min_free_space_gb | Number | default = 5
26+
| doc "Minimum free disk space in GB",
27+
write_back_sec | Number | default = 5
28+
| doc "Write-back delay in seconds (1-60)",
29+
poll_interval_min | Number | default = 1
30+
| doc "Remote change poll interval in minutes (1-60)",
31+
buffer_size_mb | Number | default = 16
32+
| doc "Buffer size in MB (1-128)",
33+
transfers | Number | default = 4
34+
| doc "Concurrent transfers (1-32)",
35+
checkers | Number | default = 8
36+
| doc "Concurrent checkers (1-64)",
37+
} in
38+
39+
let ScheduleEntry = {
40+
start | Number
41+
| doc "Start hour (0-23)",
42+
end | Number
43+
| doc "End hour (0-23)",
44+
limit_kbps | Number
45+
| doc "Bandwidth limit in KB/s (0 = unlimited)",
46+
} in
47+
48+
let Bandwidth = {
49+
enabled | Bool | default = false
50+
| doc "Enable bandwidth scheduling",
51+
schedule | Array ScheduleEntry | default = []
52+
| doc "Schedule entries",
53+
} in
54+
55+
let Service = {
56+
name | String
57+
| doc "Display name",
58+
remote | String
59+
| doc "rclone remote name (e.g., 'dropbox:')",
60+
mount_point | String
61+
| doc "Local mount path",
62+
service_name | String
63+
| doc "systemd service name",
64+
enabled | Bool | default = true
65+
| doc "Whether service is enabled",
66+
rc_port | Number | optional
67+
| doc "rclone RC port for this service",
68+
69+
# Service-specific overrides
70+
tps_limit | Number | optional,
71+
tps_burst | Number | optional,
72+
chunk_size_mb | Number | optional,
73+
} in
74+
75+
let PinnedFolder = {
76+
service | String
77+
| doc "Service name (dropbox, gdrive, onedrive)",
78+
remote_path | String
79+
| doc "Path on remote (e.g., 'Documents/Important')",
80+
local_path | String
81+
| doc "Local sync path (e.g., '~/Offline/Dropbox/Documents')",
82+
enabled | Bool | default = true
83+
| doc "Whether folder is pinned",
84+
} in
85+
86+
let Config = {
87+
general | {
88+
cache_mode | CacheMode | default = 'Writes
89+
| doc "VFS cache mode",
90+
desktop_notify | Bool | default = true
91+
| doc "Desktop notifications",
92+
tray_icon | Bool | default = true
93+
| doc "System tray icon",
94+
offline_dir | String | default = "~/Offline"
95+
| doc "Offline sync directory",
96+
},
97+
98+
rate_limiting | RateLimiting | default = {},
99+
smart_sync | SmartSync | default = {},
100+
101+
conflict_resolution | {
102+
strategy | ConflictStrategy | default = 'Newer
103+
| doc "Conflict resolution strategy",
104+
} | default = {},
105+
106+
bandwidth | Bandwidth | default = {},
107+
108+
services | Array Service | default = [],
109+
pinned_folders | Array PinnedFolder | default = [],
110+
} in
111+
112+
# Presets
113+
let presets = {
114+
dropbox = {
115+
general.cache_mode = 'Writes,
116+
rate_limiting = {
117+
tps_limit = 4,
118+
tps_burst = 1,
119+
chunk_size_mb = 32,
120+
},
121+
},
122+
123+
gdrive = {
124+
general.cache_mode = 'Writes,
125+
rate_limiting = {
126+
tps_limit = 8,
127+
tps_burst = 2,
128+
chunk_size_mb = 64,
129+
},
130+
},
131+
132+
onedrive = {
133+
general.cache_mode = 'Writes,
134+
rate_limiting = {
135+
tps_limit = 6,
136+
tps_burst = 2,
137+
chunk_size_mb = 32,
138+
},
139+
},
140+
141+
minimal = {
142+
general.cache_mode = 'Writes,
143+
smart_sync = {
144+
cache_max_size_gb = 2,
145+
transfers = 2,
146+
checkers = 4,
147+
buffer_size_mb = 8,
148+
},
149+
},
150+
151+
performance = {
152+
general.cache_mode = 'Full,
153+
smart_sync = {
154+
cache_max_size_gb = 50,
155+
transfers = 8,
156+
checkers = 16,
157+
buffer_size_mb = 64,
158+
},
159+
},
160+
} in
161+
162+
# Export schema and presets
163+
{
164+
Config,
165+
presets,
166+
167+
# Validation function
168+
validate = fun config =>
169+
let valid_tps = config.rate_limiting.tps_limit >= 1
170+
&& config.rate_limiting.tps_limit <= 100 in
171+
let valid_burst = config.rate_limiting.tps_burst >= 1
172+
&& config.rate_limiting.tps_burst <= 10 in
173+
let valid_chunk = config.rate_limiting.chunk_size_mb >= 1
174+
&& config.rate_limiting.chunk_size_mb <= 512 in
175+
valid_tps && valid_burst && valid_chunk,
176+
177+
# Generate TOML output
178+
to_toml = fun config => std.serialize 'Toml config,
179+
}

dolphin-extension/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Dolphin Integration
2+
3+
## Service Menu (Context Menu)
4+
5+
Install the service menu for right-click actions:
6+
7+
```bash
8+
mkdir -p ~/.local/share/kservices5/ServiceMenus/
9+
cp cloud_sync_overlay.desktop ~/.local/share/kservices5/ServiceMenus/
10+
```
11+
12+
## Overlay Icons
13+
14+
Dolphin supports overlay icons via the `fileoverlaysplugin`. The cloud-sync-overlay
15+
daemon exposes status via D-Bus which Dolphin can query.
16+
17+
For KDE Plasma 6+, install the overlay plugin:
18+
19+
```bash
20+
# Fedora
21+
sudo dnf install dolphin-plugins
22+
23+
# The daemon must be running:
24+
systemctl --user start cloud-sync-overlay
25+
```
26+
27+
## Alternative: Using .directory Files
28+
29+
For directories, you can set emblems via `.directory` files:
30+
31+
```ini
32+
[Desktop Entry]
33+
Icon=folder-cloud
34+
```
35+
36+
The daemon can automatically manage these files for cloud directories.

0 commit comments

Comments
 (0)