💾

Podman + Quadlet で OneDrive の Linux クライアントを自動起動する(systemd対応)

に公開

背景

  • 自分のPC買い替えのときにせっかくなので podman に切り替えてみた
  • docker だと --restart always を入れれば Docker の起動時に自動でコンテナが立ち上がってくれるが podman はサービス化に一手間必要
  • OneDrive Client for Linux はコンテナイメージでも配布されている。コンテナを自動起動する方法として、ドキュメントでは podman generate systemd で systemd のユニットファイルを生成するやり方が記載されていたが、このコマンドは非推奨になったようなので Quadlet を使うことにした

手順

  1. 設定用の volume を作成

    $ podman volume create onedrive-conf
    
  2. 一度手動でコンテナを起動、認証

    export ONEDRIVE_DATA_DIR="${HOME}/OneDrive"
    export ONEDRIVE_UID=`id -u`
    export ONEDRIVE_GID=`id -g`
    mkdir -p ${ONEDRIVE_DATA_DIR}
    podman run -it --name onedrive --user "${ONEDRIVE_UID}:${ONEDRIVE_GID}" \
     --userns=keep-id \
     -v onedrive-conf:/onedrive/conf:U,Z \
     -v "${ONEDRIVE_DATA_DIR}:/onedrive/data:U,Z" \
     driveone/onedrive:edge
    

    以下の様に出力されるので、ブラウザでURLを開いて認証し、リダイレクトされたURLをコピペする

    Please authorise this application by visiting the following URL:
    
    https://login.microsoftonline.com/...(略)
    
    Paste redirect URI here:
    

    認証に成功すると同期が始まる。

  3. 同期の完了後、 ctrl+c でコンテナを止めてファイルを確認

    $ ls -ln ~/OneDrive
    

    user:group がホストの UID (概ね 1000:1000 ) になっていればOKです

  4. コンテナから Kubernetes yaml 形式の設定ファイルを生成

    $ podman generate kube onedrive -f onedrive.yaml
    $ podman rm onedrive  # コンテナはもう不要なので削除
    
  5. 設定ファイルを使用して起動確認

    $ podman kube play --userns=keep-id onedrive.yaml
    $ podman logs -f CONTAINER_ID
    $ podman kube down onedrive.yaml  # ログが問題なさそうなら終了
    
    • --userns=keep-id は設定ファイルには反映されないようなので、コマンド引数で指定します。
  6. Quadlet 用の .kube ファイルを作成

    Podman Quadlet では systemd generator という、systemd の unit ファイルを動的に生成する仕組みを利用しています。Quadlet で先ほど生成した yaml ファイルを使うためには .kube ファイルを所定の場所に配置する必要があります。今回はログインユーザで動かすサービスなため ~/.config/containers/systemd/ 以下に配置します。

    # ~/.config/containers/systemd/onedrive.kube
    [Unit]
    Description=OneDrive Client
    Wants=network-online.target
    After=network-online.target
    RequiresMountsFor=%t/containers
    
    [Kube]
    UserNS=keep-id
    Yaml=/path/to/onedrive.yaml
    
    [Service]
    Restart=on-failure
    TimeoutStopSec=70
    
    [Install]
    WantedBy=default.target
    
    • Yaml= で生成したファイルを指定します
    • UserNS=podman kube のコマンド引数の --userns と同じ意味です
  7. ファイルを配置したら以下のコマンドで内容のチェック

    $ /usr/lib/systemd/system-generators/podman-system-generator --user --dryrun
    
  8. 問題なければ以下のコマンドで実際にサービスを生成

    $ systemctl --user daemon-reload
    $ systemctl --user list-unit-files  # unit が登録されているか確認
    $ systemctl --user list-dependencies  # unit の依存関係を確認
    
  9. systemctl から起動

    サービスの起動は以下のコマンドで行います

    $ systemctl --user start onedrive
    $ # ちなみに止めるときは
    $ systemctl --user stop onedrive
    

    以下のコマンドでログに Sync with Microsoft OneDrive is complete とでていればOKです

    $ systemctl --user status onedrive
    $ # or
    $ journalctl --user -u onedrive -f
    
  10. 再起動した後、自動でサービスが起動しているか確認

$ systemctl --user status onedrive
  • 起動に時間がかかる場合がある?らしく再起動直後は status が inactive になっていることがあります。動作確認は少し待ってからにしましょう。 [1]
  • Quadlet では通常の systemd の unit と違い、enable を手動で行う必要はありません [2]

TIPS

  • 何らかの原因で設定用の volume が消えてしまった場合、 podman ps でコンテナID を取得し、 $ podman exec -it CONTAINER_ID /bin/bash などでコンテナに入って entrypoint.sh を手動で実行すれば認証情報を入力するプロンプトがでます。

感想

正直な話 podman generate kube だけで完結せず別途 .kube を書く必要があるなら podman generate systemd を使った方が楽だと思うので本格的に generate systemd が使えなくなるまではそっちを利用するのでよさそうに思います。少し調べた範囲だと systemd generator を使っている方がバージョンアップで設定内容を変更する必要が出てきても Quadlet側で対応してくれるなどのメリットはあるみたいですが。

参考

脚注
  1. 私の環境ではほぼ毎回90秒かかるので設定の問題かもしれません ↩︎

  2. https://github.com/containers/podman/discussions/17744 仕様について議論中?な模様 ↩︎

Discussion