Захотілося простого: підключити Google Drive як звичайну папку в файловій системі, і щоб воно саме піднімалось при вході в систему, без танців з бубном щоразу. Здавалося б, rclone mount — і готово. Виявилось трохи цікавіше.
Крок 1. rclone і конфіг, якого нема
Перша спроба:
rclone mount gdrive: ~/GDrive --daemon
У відповідь:
Failed to create file system for "gdrive:": didn't find section in config file
Логічно — remote gdrive в конфізі просто не існував. Створити порожній файл командою rclone config touch теж не рятує: файл є, секції нема.
Рішення: інтерактивний майстер rclone config. Він сам генерує правильну секцію в ~/.config/rclone/rclone.conf і проводить через OAuth-авторизацію в браузері — 2FA при цьому обробляється звичайним способом, через сам Google, rclone до неї жодного стосунку не має. На машині з GUI (а в мене GNOME) достатньо погодитись на Use auto config? (y) — rclone підійме локальний вебсервер і сам відкриє браузер для логіну.
Крок 2. Автозапуск при логіні — перша перешкода: D-Bus
Щоб не монтувати вручну щоразу, оформив systemd user-юніт:
[Unit]
Description=RClone mount Google Drive
AssertPathIsDirectory=%h/GDrive
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/rclone mount gdrive: %h/GDrive \
--vfs-cache-mode writes \
--config=%h/.config/rclone/rclone.conf
ExecStop=/bin/fusermount -u %h/GDrive
Restart=on-failure
RestartSec=10
[Install]
WantedBy=default.target
І одразу вперся в:
Failed to connect to user scope bus via local transport: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined
Спробував виставити loginctl enable-linger, спробував вручну експортувати змінні — не допомагало. Причина виявилась банальною і трохи соромною: у .bashrc завалявся старий
alias systemctl='sudo systemctl'
А sudo за замовчуванням очищує середовище процесу. Тобто щойно виставлені XDG_RUNTIME_DIR і DBUS_SESSION_BUS_ADDRESS до команди просто не доходили — sudo їх зрізав ще до старту systemctl. Найприкріше, що для керування власними user-юнітами (systemctl --user) права root взагалі не потрібні.
Рішення: викликати бінарник напряму, оминаючи alias:
/usr/bin/systemctl --user daemon-reload
/usr/bin/systemctl --user enable --now rclone-gdrive.service
І заразом не завадить loginctl enable-linger <user> — щоб user-сесія (і user-юніти) піднімались навіть без активного графічного логіну.
Крок 3. Сервіс стартує і одразу падає
Failed to create file system for "gdrive:": didn't find section in config file
Та сама помилка, що й на самому початку — але тепер конфіг точно існував. Загадка розкрилась при прямому запуску команди в терміналі (без --daemon, щоб бачити живий вивід):
/usr/bin/rclone mount gdrive: ~/GDrive --vfs-cache-mode writes --config=/home/olden/.config/rclone/rclone.conf
Та сама помилка. Але варто було спробувати з великої літери:
/usr/bin/rclone mount GDrive: ~/GDrive --vfs-cache-mode writes --config=/home/olden/.config/rclone/rclone.conf
— і диск підключився. rclone чутливий до регістру назви remote, а в конфізі секція виявилась записана як [GDrive], а не [gdrive], як я вважав. Дрібниця, яка коштувала половини вечора.
Виправив у юніті:
sed -i 's/rclone mount gdrive:/rclone mount GDrive:/' ~/.config/systemd/user/rclone-gdrive.service
Крок 4. Порожня папка після, здавалося б, вдалого монтування
Сервіс піднявся, systemctl --user status показував active (running), а ls ~/GDrive — порожньо. При тому ручний запуск хвилиною раніше показував повний список файлів.
Причина — накладені (stale) точки монтування. Я тестував ручний запуск rclone mount просто в терміналі, потім намагався його відмонтувати через fusermount3 -u, але процес до кінця не прибрався. Коли systemd підняв новий rclone mount поверх недомонтованого старого шару, ядро показувало нову, ще порожню точку.
Розібратись допомогла така послідовність:
/usr/bin/systemctl --user stop rclone-gdrive.service
fusermount3 -u ~/GDrive # повторити кілька разів, якщо треба
pkill -f "rclone mount" # добити зомбі-процеси
ps aux | grep rclone # переконатись, що чисто
/usr/bin/systemctl --user start rclone-gdrive.service
Після цього ls ~/GDrive нарешті показав реальні файли.
Підсумок: робочий юніт
[Unit]
Description=RClone mount Google Drive
AssertPathIsDirectory=%h/GDrive
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/rclone mount GDrive: %h/GDrive \
--vfs-cache-mode writes \
--config=%h/.config/rclone/rclone.conf
ExecStop=/bin/fusermount -u %h/GDrive
Restart=on-failure
RestartSec=10
[Install]
WantedBy=default.target
loginctl enable-linger $USER
/usr/bin/systemctl --user daemon-reload
/usr/bin/systemctl --user enable --now rclone-gdrive.service
(Type=notify теж мав шанс спрацювати — версія rclone тут доволі свіжа, — але коли шукаєш причину падіння, простіше тимчасово спростити до Type=simple, щоб виключити зайву змінну з рівняння.)
Висновки на майбутнє
- Alias на
sudo systemctlіsystemctl --user— погана комбінація. Sudo зрізає середовище, а--user-юнітам права root взагалі не потрібні. - rclone чутливий до регістру назв remote.
gdrive:іGDrive:— це два різні (точніше, один існуючий і один неіснуючий) remote. - Перед діагностикою systemd-юніта корисно спершу прогнати ту саму команду вручну в терміналі — так помилка видно одразу, без прошарку journalctl.
- Stale FUSE-монтування — підступна штука:
systemctl statusможе казатиactive (running), а точка монтування при цьому виявиться порожньою, бо накладена на недомонтований попередній шар.pkill -f+ чистийstop/startзнімає це надійно.
Дрібниця на дрібниці, але кожна — окрема пастка, у яку легко провалитись саме тому, що симптом (одна й та сама помилка «not found in config file») мав дві геть різні причини на різних етапах.