Ubuntu 22.04.3 LTSでOneDrive同期を試す

systemdでOneDriveサービスを動かすところでちょっと詰まったので、備忘録を残します。

環境

OS: Ubuntu 22.04.3 LTS
OneDriveクライアント: GitHub - abraunegg/onedrive: OneDrive Client for Linux
※利用したバージョン: onedrive v2.4.25-1+np1

インストール

以下ドキュメントに沿ってインストールします。
onedrive/docs/INSTALL.md at master · abraunegg/onedrive · GitHub

リポジトリの追加

$ 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
$ 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

パッケージアップデート&OneDriveインストール

$ sudo apt update
$ sudo apt install onedrive

初期設定

認証

onedriveコマンドを引数なしで実行すると認証用URLが表示されるので、ブラウザにコピペして認証します。
認証が完了すると空白のページが表示されるので、その空白ページのURLをコピーして"Enter the response uri: "の部分にペースト。

$ onedrive

Authorize this app visiting:

https://..... # このURLをブラウザにコピペして認証

Enter the response uri: # 認証後に表示される空白ページのURLをここにコピペ

onedrive/docs/USAGE.md at master · abraunegg/onedrive · GitHub

コンフィグファイルの準備

コンフィグファイルなしでも動きますが、変更したい場合は以下のようにテンプレートファイルをダウンロードして適宜変更します。

$ mkdir -p ~/.config/onedrive
$ wget https://raw.githubusercontent.com/abraunegg/onedrive/master/config -O ~/.config/onedrive/config
$ vi ~/.config/onedrive/config

onedrive/docs/USAGE.md at master · abraunegg/onedrive · GitHub

なお今回はOneDrive上に同期対象外としたいフォルダがあったため、以下のようにsync_listというファイルを追加で作成しました。

$ vi ~/.config/onedrive/sync_list

"Attachments"と"Exclude_files"というフォルダは同期の対象外とし、それ以外はすべて同期の対象としました。

# sync_list supports comments
#
# The ordering of entries is highly recommended - exclusions before inclusions
#
# Exclude these folders
!Attachments
!Exclude_files
#
# Include everything else
/*

onedrive/docs/USAGE.md at master · abraunegg/onedrive · GitHub

同期

以下コマンドで同期が実行されます。

onedrive --synchronize

onedrive/docs/USAGE.md at master · abraunegg/onedrive · GitHub

デフォルトでは以下パスにファイルが同期されます。

/home/<username>/OneDrive

今回同期対象としたファイル容量は約60GB程度とそんなに大きくないのですが、同期の完了までに6時間ほどかかったようです。*1
動画ファイルのようにまとまった大きなファイルはスムーズにダウンロードできるのですが、写真やログのように細かなファイルが大量にあると一つ一つの処理に時間がかかっているイメージです。

同期のサービス化

ファイルを更新するたびに先程の同期コマンドを実行するのは現実的ではないので、サービスとして登録します。

systemdでのサービス登録(rootユーザ)

まず以下ドキュメントに沿って、systemdでのサービス登録をrootユーザとして試しました。
onedrive/docs/USAGE.md at master · abraunegg/onedrive · GitHub

$ sudo su - root
# systemctl --user enable onedrive
Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user)

エラーが出て止まりました。
書いてある通り、 "$DBUS_SESSION_BUS_ADDRESS"と"$XDG_RUNTIME_DIR"という変数が定義されていないようです。

以下を.bashrcに設定するようドキュメントに記載があったため、rootの.bashrcの末尾に追記しました。

export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"

rootでログインし直して再実行しましたが、以下の通りファイルが無いと言われて止まります。

$ sudo su - root
# systemctl --user enable onedrive
Failed to connect to bus: No such file or directory

このエラーについて、以下URLに解決方法が書かれていました。
systemd: Failed to connect to bus: No such file or directory · abraunegg/onedrive Wiki · GitHub

上記URLに記載の通り設定すると、正しくサービス登録されました。
ただここで気づいたのですが、rootユーザとしてサービス登録すると、同期したすべてのファイルの所有権がrootになってしまいます。

Note: This will run the 'onedrive' process with a UID/GID of '0', thus, any files or folders that are created will be owned by 'root'

これは個人的に不便なので、rootユーザとしてのサービス登録はやめることにしました。

systemdでのサービス登録(一般ユーザ)

以下ドキュメントに沿って、systemdでのサービス登録を一般ユーザ(ramune)として試しました。
onedrive/docs/USAGE.md at master · abraunegg/onedrive · GitHub

まず一般ユーザとして、同期が正しく完了することを確認します。*2

$ onedrive --synchronize --verbose

Using 'user' Config Dir: /home/ramune/.config/onedrive
...
Sync with OneDrive is complete

rootユーザに切り替えて、上記一般ユーザ名を指定してサービス有効化&開始します。

$ sudo su - root
# systemctl enable onedrive@ramune.service
# systemctl start onedrive@ramune.service

ステータスを見ると、エラーで止まっています。

# systemctl status onedrive@ramune.service
● onedrive@ramune.service - OneDrive Free Client for ramune
     Loaded: loaded (/lib/systemd/system/onedrive@.service; enabled; vendor preset: enabled)
     Active: activating (auto-restart) (Result: exit-code) since Sun 2024-01-28 14:38:22 JST; 951ms ago
       Docs: https://github.com/abraunegg/onedrive
    Process: 26504 ExecStart=/usr/bin/onedrive --monitor --confdir=/root/.config/onedrive (code=exited, status=1/FAILURE)
   Main PID: 26504 (code=exited, status=1/FAILURE)
        CPU: 35ms

コンフィグのパスが"/root/.config/onedrive"となっている部分が怪しいので、このパスを一般ユーザのものに書き換えます。

# vi /etc/systemd/system/multi-user.target.wants/onedrive@ramune.service 
# ExecStart=/usr/bin/onedrive --monitor --confdir=/root/.config/onedrive
# ↓以下に書き換え
ExecStart=/usr/bin/onedrive --monitor --confdir=/home/ramune/.config/onedrive

デーモンをリロードしてから、サービス再起動&ステータス確認をします。

# systemctl daemon-reload 
# systemctl restart onedrive@ramune.service
# systemctl status onedrive@ramune.service
● onedrive@ramune.service - OneDrive Free Client for ramune
     Loaded: loaded (/lib/systemd/system/onedrive@.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2024-01-28 14:43:40 JST; 4min 46s ago
       Docs: https://github.com/abraunegg/onedrive
   Main PID: 28095 (onedrive)
      Tasks: 13 (limit: 57428)
     Memory: 47.2M
        CPU: 8.123s
     CGroup: /system.slice/system-onedrive.slice/onedrive@ramune.service
             └─28095 /usr/bin/onedrive --monitor --confdir=/home/ramune/.config/onedrive

エラーが解消し、"active (running)"になりました。

ログは以下のように確認します。

$ journalctl --unit=onedrive@ramune -f
Jan 28 15:46:46 ubuntu onedrive[28095]: Starting a sync with OneDrive
Jan 28 15:46:46 ubuntu onedrive[28095]: Syncing changes and items from OneDrive ...
Jan 28 15:46:48 ubuntu onedrive[28095]: Performing a database consistency and integrity check on locally stored data due to fullscan requirement ...
Jan 28 15:49:14 ubuntu onedrive[28095]: Sync with OneDrive is complete

うまく動いているようです。

試しにUbuntuWindowsでファイルの新規作成や編集を試しましたが、お互いに変更が反映されています。

*1:ルータのトラフィックログから推測しただけなので、多少ずれがあるかもしれないです。

*2:すでに同期済みの場合でも全ての同期対象フォルダについて再度チェックが入るので、同期処理にある程度時間がかかります。