1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dnfやbrewで入れられる自分専用のパッケージリポジトリを用意してみた

1
Posted at

きっかけ

自作のCLIツールやdotfiles用のスクリプトを複数のマシンに配るとき、毎回git cloneしてシンボリックリンクを張るのが面倒になってきた。普段からパッケージはdnfとbrewで管理しているので、自分のツールも同じ仕組みに乗せてしまえば dnf upgrade や brew upgrade のついでに更新される。ということで、自分専用のdnfリポジトリとbrew tapを用意してみた。

brew tap

GitHubに homebrew-tools という名前でリポジトリを作る。homebrew- というプレフィックスが必須で、これがあると brew tap ユーザー名/tools のように短い名前で参照できる。

リポジトリ直下に Formula ディレクトリを作って、rubyのファイルを置くだけでいい。

※USER_NAMEは自分のGitHubユーザ名に置き換えること

class Mytool < Formula
  desc "My personal CLI tool"
  homepage "https://github.com/USER_NAME/mytool"
  url "https://github.com/USER_NAME/mytool/archive/refs/tags/v0.2.0.tar.gz"
  sha256 "ここにtarballのsha256を書く"
  license "MIT"

  def install
    bin.install "mytool"
  end
end

sha256は次のコマンドで取れる。

curl -sL https://github.com/USER_NAME/mytool/archive/refs/tags/v0.2.0.tar.gz | shasum -a 256

使う側はこれだけ。

brew tap USER_NAME/tools
brew install mytool

タグを切るたびにFormulaのurlとsha256を書き換える必要があるけど、それ以外にやることがない。メタデータの生成も署名も不要で、GitHubのリポジトリがそのまま配布チャネルになる。

dnf

こっちはそれなりに手順がある。大まかには、rpmを作る、createrepo_cでメタデータを生成する、httpで公開する、の流れになる。

rpmを作る

まずspecファイルを書く。

Name:           mytool
Version:        0.2.0
Release:        1%{?dist}
Summary:        My personal CLI tool
License:        MIT
URL:            https://github.com/ttakahashi/mytool
Source0:        %{url}/archive/refs/tags/v%{version}.tar.gz

%description
Personal CLI tool for daily tasks.

%prep
%autosetup -n mytool-%{version}

%install
install -Dm755 mytool %{buildroot}%{_bindir}/mytool

%files
%license LICENSE
%{_bindir}/mytool

ビルドはrpmbuildでも良いが、chrootを使用するmockを使った。

mock -r fedora-44-x86_64 --buildsrpm --spec mytool.spec --sources .
mock -r fedora-44-x86_64 --rebuild mytool-0.2.0-1.fc44.src.rpm

リポジトリのメタデータを作る

できたrpmをディレクトリに集めて createrepo_c を実行する。

mkdir -p repo/fedora/44/x86_64
cp result/mytool-0.2.0-1.fc44.x86_64.rpm repo/fedora/44/x86_64/
createrepo_c repo/fedora/44/x86_64

これで repodata ディレクトリが生成されて、dnfが読める形式になる。
rpmを追加したり更新したりしたら、毎回createrepo_cを実行し直す必要がある。
最初これを忘れて、新しいバージョンを置いたのにdnfから見えないとしばらく悩んだ。

公開する

httpで配信できればなんでもいいので、GitHub Pagesに乗せた。repoディレクトリをそのままpagesブランチに置くだけ。

クライアント側には .repo ファイルを置く。

# /etc/yum.repos.d/USER_NAME.repo
[USER_NAME]
name=USER_NAME personal repo
baseurl=https://USER_NAME.github.io/repo/fedora/$releasever/$basearch
enabled=1
gpgcheck=0

これで dnf install mytool が通るようになる。

gpgについて

上の例では gpgcheck=0 にしているけど、自分しか使わないリポジトリでも署名はしておいた方がいい。rpmsignで署名して、公開鍵をリポジトリに置いて gpgkey= で参照させる。手順は長くなるので省くが、署名なし運用だとdnfの設定で警告を黙らせ続けることになって精神衛生に悪い。

ハマったところ

  • createrepo_cの実行を忘れると、rpmを置いてもdnfからは存在しないことになる。リリース用のMakefileに組み込んで忘れないようにした
  • GitHub Pagesのデプロイには少しラグがあるので、pushした直後にdnfを叩くと404になることがある。dnf clean metadata してから再試行すれば直る
  • brewのFormulaはsha256が一致しないとインストールが止まる。タグを打ち直すとtarballのハッシュが変わるので、リリース後にタグを動かすのはやめた方がいい

まとめ

個人ツールの配布なら、macOS向けはbrew tap一択でいいと思う。リポジトリを作ってrubyファイルを1枚置くだけで終わる。

dnfの方はFedoraならCOPRを使う方が実は簡単らしいがそれに気がついたのは一通り終わったあとなので機会があれば試そうと思う。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?