おそらくはそれさえも平凡な日々

R2を同期するr2syncというツールをRustで書いてcrate公開した

https://crates.io/crates/r2sync

コマンドラインツールであり以下でインストールできる。

$ brew install Songmu/tap/r2sync
# or
$ cargo install r2sync

これはローカルディレクトリの中身をCloudflare R2に簡易的に同期するごく単純なツールで以下のように使う。

$ r2sync ./dir r2://your-bucket/path

リモートに同一ファイルが存在する場合にputをスキップするようになっていて、それが欲しくて作った。ちなみに、--public-domain というオプションを付けると、同一ファイルチェックを公開URL経由で行うようになってAPIアクセスを減らせる。

$ r2sync --public-domain files.example.com ./dir r2://your-bucket/path

ファイルの同一性チェックは、Content-LengthとETagを見ている。S3やR2はETagがコンテンツのMD5ハッシュ値なので、それで同一性チェックをしている。この挙動が未来永劫担保されるかわからないが、単にContent-Lengthだけ見るのも嫌だったし、実際にContent-Lengthだけ主に見ている aws s3 sync がたまにハマるという話も聞くのでそうした。

GitHub Actions

カスタムアクションも公開していて、以下のように使える。oss4.funでも導入した。

- uses: Songmu/r2sync@v0
  with:
    r2_account_id: ${{ secrets.R2_ACCOUNT_ID }}
    r2_access_key_id: ${{ secrets.R2_ACCESS_KEY_ID }}
    r2_secret_access_key: ${{ secrets.R2_SECRET_ACCESS_KEY }}
    src: ./audio
    dest: r2://<your-bucket>/audio
    public_domain: files.example.com

作った動機

ポッドキャストの音声ファイルのアップロードをGitHub Actionsでやっているが、ディレクトリ内の全部の音声ファイルを毎回素朴にputしていたので流石に富豪すぎるので解決しようと考えたのが契機。

案外、既存の良いツールが見つけられなかったのと、aws s3 sync を使っても良かったのだけど、前述のETagの話もあったし、せっかくR2はエグレス料金が無料なのだからファイルの同一性チェックを公開URL経由でおこなうアイデアを盛り込んで作った。

Rust

習作がてらちょっとしたものをRustで作ってみたいと思っていたので、ちょうどよい題材だった。strとStringの使い分けとか、unwrapを使いすぎだったりとかまだまだお作法が分からない部分が多いが、とりあえずcrate公開までいけたのは良かった。Resultとかパターンマッチ含めた言語自体の書き味はかなり良い。

思っていたよりクロスビルド周りが難しくて、各プラットフォームにバイナリを提供するのに手こずった。とりあえず、GitHub Actions上で作るのは一旦断念して手元でバイナリをビルドしてGitHub Releasesにghrでアップロードするという一昔前のスタイルでお茶を濁した。

Rustを書き始めるにあたって「Rustの練習帳」が参考になった。Rustの考え方やコマンドラインツール作成について実践を通して学べる点で有益だった。Goでもこういう本があると良さそう(すでにあるかも)、とか思った。

created at
last modified at

2024-10-15T01:37:16+0900

comments powered by Disqus