git

2015年03月27日

このエントリーをはてなブックマークに追加

個人作業環境を一撃セットアップ

身近なメンバーに説明する手頃な材料が欲しかったので、本エントリを書いた。

作業ノードを転々としていると、各所に作業環境を構築する回数が多くなる。作業対象が使い捨てである事が増えれば増える程、その傾向が強くなった。構築回数が多いからこそ、整理する機会に恵まれていたとも言う。その結果、今ではログイン後に下記コマンド1行を実行するだけだ。

$ curl -fSkL https://raw.githubusercontent.com/hansode/env-bootstrap/master/build-personal-env.sh | bash

build-personal-env.shの処理を掘り下げて行く。

build-personal-env.sh 処理概要

  1. mkdir -p ${HOME}/repos/git/github.com
  2. hansode/dotfiles${HOME}/repos/git/github.com/に配置
    1. cd ${HOME}/repos/git/github.com/ && make
    2. make 実行により、自分好みのdotfilesが配置・セットアップされる

dotfilesdotfileだけを管理し、env-bootstrapdotfilesをセットアップする。dotfilesにセットアップスクリプトを置いても良いが、役割分担を明確にする為にも別プロジェクトで管理している。今(2015/03/27現在)は、たまたまdotfilesしか扱ってないが、他のプロジェクトを扱いたい場合は、今の様に役割分担してる方が柔軟な管理が可能。かつては別プロジェクトを扱っていた経緯がある。

dotfilesが環境を判定

作業対象は複数あり、プラットフォーム毎に必要なdotfileが異なって来る。

  • Cygwin 1.7 / Windows 8.1
  • MacOS 10.10 (Yosemite)
  • Raspbian 7.6 (Wheezy)
  • Fedora release 20 (Heisenbug)
  • CentOS-6.6/6.5/6.4
  • CentOS-7.0.1406

例えばCygwin環境にはDropboxをインストールしているので、Cygwinのホームディレクトリからアクセスしやすいようにしている。また、CygwinとMacOSでは、Vagrantを扱う事があるので、Vagrant環境を整理している。

自身の${HOME}構造を標準化

build-personal-env.shが配置するdotfileswork/repos/git/github.com/dotfiles配下。これは自分だけのルールであり、第三者に強制されるものではない。長年の経験から程よく管理しやすい構造として辿り着いた構造は、下記の通り。

まとめ

自分が実施して来た手順を整理すると、こうなる。

  1. dotfilesを整理する
  2. dotfilesをセットアップするスクリプトを管理
  3. ${HOME}構造を標準化する
  4. 1〜3を繰り返す

自分は上記順序で整理して来たが、1〜3の順序に根拠や強制力は無い。整理出来そうな所から整理すれば良い。重要なのは、整理する事だ。

関連成果物




編集
@hansode at 19:30|PermalinkComments(0)TrackBack(0)
このエントリーをはてなブックマークに追加

<committer_datetime>git<commit_hash>に辿り着くまで

Wakame-vdcOpenVNetに付与するリリースIDは、Gitのコミット履歴を基にして生成している。具体的には、

  • 20150318183519git1a6d5b4

メタ情報を含めて説明すると、

  • <committer_datetime>git<commit_hash>

この文字列を生成する手順は、下記の通り。

$ commit_hash=$(git log HEAD -n 1 --pretty=format:"%h")
$ committer_datetime=$(date --date="$(git log ${commit_hash} -n 1 --pretty=format:"%cd" --date=iso)" +%Y%m%d%H%M%S)
$ echo ${committer_datetime}git${commit_hash}

本エントリは、何故この様にしたのかを振り返る。

先輩パッケージの幾つかは既にgitのコミット履歴を利用していた

過去に何度かバージョン番号にgit情報らしきものを含んだパッケージを見かけた事があったので、それらを参考にする事にした。CentOS6で調査してみると、RPMにおける%{Release}タグにgitの情報を含んだパッケージが存在する。その一例を列挙する。

$ rpm -qa --qf '%{NAME} %{Release}\n' | awk '$2 ~ "git"'   | sort | sed 's,.el6,,'
deltarpm 0.5.20090913git
dkms 30.git.7c3e7c5
libpcap 6.20091201git117cb5
python-deltarpm 0.5.20090913git
tcpdump 3.20090921gitdf3cb4.2
xz 0.3.beta.20091007git
xz-libs 0.3.beta.20091007git
xz-lzma-compat 0.3.beta.20091007git

これらを整理してみると、3つに分類される。

  1. 数字.<comitter_date>git
    • deltarpm 0.5.20090913git
    • python-deltarpm 0.5.20090913git
    • xz 0.3.beta.20091007git
    • xz-libs 0.3.beta.20091007git
    • xz-lzma-compat 0.3.beta.20091007git
  2. 数字.git.<commit_hash>
    • dkms 30.git.7c3e7c5
  3. 数字.<committer_date>git<commit_hash>
    • libpcap 6.20091201git117cb5
    • tcpdump 3.20090921gitdf3cb4.2

いずれも、先頭の数字の意味が良く分からない。良く分からないので削除。

  1. <comitter_date>git
  2. git.<commit_hash>
  3. <committer_date>git<commit_hash>

これらを吟味。

  1. 【却下】コミットハッシュが含まれていないので追跡し辛い
  2. 【却下】辞書順に並べた時に、新旧を判断できない
  3. 【採用】欲しい情報を含んでいる

3をそのまま採用すると、<committer_date>の場合、1日に複数回ビルドすると、どちらのbuildが古いのか・新しいのかが分かり辛い。そこで<comitter_date>ではなく<comitter_datetime>を使う事にした。

  • <committer_datetime>git<commit_hash>

コミット時刻とコミットハッシュを含んだ理想的なリリースID。

リリースIDを生成・組み立てる

1: <commit_hash>を生成

特定コミットのハッシュを取得する。

$ git log HEAD -n 1 --pretty=format:"%h"
1e1b0ec

なお、HEADの代わりにブランチ名を指定する事も可能である。

$ git log master -n 1 --pretty=format:"%h"
1e1b0ec

これによりコミットハッシュを取得出来る。

2: <committer_datetime>を生成

--date=shortを指定すると、Y-m-dで取得可能だ。

$ git log HEAD -n 1 --pretty=format:"%cd" --date=short
2015-03-25

-はパッケージマネージャの予約文字列である可能性が高いので、-を削除したい。また、Y-m-dだけでなくH:M:Sも取得したい。しかし、この2つの要望を満たす--date=xxxを、git-logがサポートしてなかった。そこで、dateコマンドと組み合せて生成する事にした。

$ date --date="$(git log HEAD -n 1 --pretty=format:"%cd" --date=iso)" +%Y%m%d%H%M%S
20150325193037

コミット時刻を取得出来た。

3: 文字列gitを含める

参考にしたパッケージには、Gitの情報である事を明確化する為に文字列gitが含まれている。そのポリシーを拝借し、1と2を合わせる。

$ echo ${committer_datetime}git${commit_hash}

期待する文字列を生成出来る。

4: 1+2+3

3つをつなぎ合わせる。

$ commit_hash=$(git log HEAD -n 1 --pretty=format:"%h")
$ echo commit_hash=${commit_hash}
commit_hash=1e1b0ec

$ committer_datetime=$(date --date="$(git log ${commit_hash} -n 1 --pretty=format:"%cd" --date=iso)" +%Y%m%d%H%M%S)
$ echo committer_datetime=${committer_datetime}
committer_datetime=20150325193037

$ echo ${committer_datetime}git${commit_hash}
20150325193037git1e1b0ec

これにより、リリースIDを生成出来るようになった。

最後はrpmbuildと組み合せる

rpmbuildを実行する際にリリースIDをオプション指定すれば良い。Wakame-vdcの場合は、こうなる。

$ rpmbuild -bb ./wakame-vdc.spec --define "build_id 20150325193037git1e1b0ec"

build_idは標準マクロではないので、rpmspecファイルを工夫する必要がある。rpmspecの書き方は、本エントリの本題ではないので、別エントリにて。

まとめ

Wakame-vdcは、このリリースIDで約3年運用している。もしも何か不具合が生じた場合には、リリースIDに含まれているコミットハッシュから追跡可能だ。また、コミット時刻も含まれているので、どのコミットをビルドしたのが一目瞭然。今の所、凄く上手く行っている。結構おススメです。




編集
@hansode at 15:30|PermalinkComments(0)TrackBack(0)

2015年03月25日

このエントリーをはてなブックマークに追加

GitリポジトリのツリーをRPMとして手っ取り早くパッケージングしたかった。手順をまとめ、git2rpmとして実装・公開してみた。

主な特徴・制約

  • Gitリポジトリを指定して実行するとRPMが生成される
  • パッケージ名は rpm4<パッケージ名>
  • インストール先は/home/git2rpm/<パッケージ名>
  • コミット履歴をもとにバージョン番号<コミット時刻>git<コミットハッシュ>を生成

使い方

引数にGitリポジトリURIを指定するだけ。

$ git2rpm <git-repo>

git2rpm実行例

試しに https://github.com/hansode/makistrano を一撃でrpm化してみる。

1: Gitリポジトリを指定してgit2rpmを実行
$ ./git2rpm https://github.com/hansode/makistrano.git
+ repouri=https://github.com/hansode/makistrano.git
+ reponame=makistrano.git
+ reponame=makistrano
+ reponame=rpm4makistrano
+ mkdir -p /home/vagrant/rpmbuild/BUILD /home/vagrant/rpmbuild/BUILDROOT /home/vagrant/rpmbuild/RPMS /home/vagrant/rpmbuild/SOURCES /home/vagrant/rpmbuild/SPECS /home/vagrant/rpmbuild/SRPMS
+ [[ -d rpm4makistrano ]]
+ cd rpm4makistrano
+ git pull
Already up-to-date.
++ git log HEAD -n 1 --pretty=format:%h
+ git_version=2add2a4
+++ git log 2add2a4 -n 1 --pretty=format:%cd --date=iso
++ date '--date=2013-11-18 18:07:42 -0800' +%Y%m%d%H%M%S
+ git_datetime=20131119110742
+ build_id=20131119110742git2add2a4
+ cd /home/vagrant/rpmbuild/SPECS
+ cat
+ rpmbuild -bb rpm4makistrano.spec --define 'repouri https://github.com/hansode/makistrano.git' --define 'reponame rpm4makistrano' --define 'build_id 20131119110742git2add2a4'
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.qpo4o6
+ umask 022
+ cd /home/vagrant/rpmbuild/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ '[' -d rpm4makistrano-20131119110742git2add2a4 ']'
+ rm -rf rpm4makistrano-20131119110742git2add2a4
+ git clone https://github.com/hansode/makistrano.git rpm4makistrano-20131119110742git2add2a4
Initialized empty Git repository in /home/vagrant/rpmbuild/BUILD/rpm4makistrano-20131119110742git2add2a4/.git/
remote: Counting objects: 278, done.
remote: Total 278 (delta 0), reused 0 (delta 0), pack-reused 278
Receiving objects: 100% (278/278), 36.30 KiB, done.
Resolving deltas: 100% (106/106), done.
+ cd rpm4makistrano-20131119110742git2add2a4
+ :
+ cd /home/vagrant/rpmbuild/BUILD
+ cd rpm4makistrano-20131119110742git2add2a4
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.pRFBqi
+ umask 022
+ cd /home/vagrant/rpmbuild/BUILD
+ cd rpm4makistrano-20131119110742git2add2a4
+ LANG=C
+ export LANG
+ unset DISPLAY
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.bbDnBu
+ umask 022
+ cd /home/vagrant/rpmbuild/BUILD
+ '[' /home/vagrant/rpmbuild/BUILDROOT/rpm4makistrano-20131119110742git2add2a4-1.el6.x86_64 '!=' / ']'
+ rm -rf /home/vagrant/rpmbuild/BUILDROOT/rpm4makistrano-20131119110742git2add2a4-1.el6.x86_64
++ dirname /home/vagrant/rpmbuild/BUILDROOT/rpm4makistrano-20131119110742git2add2a4-1.el6.x86_64
+ mkdir -p /home/vagrant/rpmbuild/BUILDROOT
+ mkdir /home/vagrant/rpmbuild/BUILDROOT/rpm4makistrano-20131119110742git2add2a4-1.el6.x86_64
+ cd rpm4makistrano-20131119110742git2add2a4
+ LANG=C
+ export LANG
+ unset DISPLAY
+ rm -rf /home/vagrant/rpmbuild/BUILDROOT/rpm4makistrano-20131119110742git2add2a4-1.el6.x86_64
+ mkdir -p /home/vagrant/rpmbuild/BUILDROOT/rpm4makistrano-20131119110742git2add2a4-1.el6.x86_64//home/git2rpm/rpm4makistrano
++ pwd
+ rsync -aHA --exclude=.git '--exclude=.git/*' /home/vagrant/rpmbuild/BUILD/rpm4makistrano-20131119110742git2add2a4/ /home/vagrant/rpmbuild/BUILDROOT/rpm4makistrano-20131119110742git2add2a4-1.el6.x86_64//home/git2rpm/rpm4makistrano/
+ /usr/lib/rpm/find-debuginfo.sh --strict-build-id /home/vagrant/rpmbuild/BUILD/rpm4makistrano-20131119110742git2add2a4
+ /usr/lib/rpm/check-rpaths /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/brp-python-bytecompile
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars
Processing files: rpm4makistrano-20131119110742git2add2a4-1.el6.noarch
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: /bin/bash /bin/sh
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/vagrant/rpmbuild/BUILDROOT/rpm4makistrano-20131119110742git2add2a4-1.el6.x86_64
warning: Could not canonicalize hostname: vagrant-centos6
Wrote: /home/vagrant/rpmbuild/RPMS/noarch/rpm4makistrano-20131119110742git2add2a4-1.el6.noarch.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.xqZHo1
+ umask 022
+ cd /home/vagrant/rpmbuild/BUILD
+ cd rpm4makistrano-20131119110742git2add2a4
+ rm -rf /home/vagrant/rpmbuild/BUILDROOT/rpm4makistrano-20131119110742git2add2a4-1.el6.x86_64
+ exit 0

/home/vagrant/rpmbuild/RPMS/noarch/rpm4makistrano-20131119110742git2add2a4-1.el6.noarch.rpm が生成された。

  • パッケージ名はrpm4makistrano
  • バージョンは20131119110742git2add2a4
2: 生成されたrpmをインストールしてみる
$ sudo yum install --disablerepo='*' /home/vagrant/rpmbuild/RPMS/noarch/rpm4makistrano-20131119110742git2add2a4-1.el6.noarch.rpm                  Loaded plugins: fastestmirror
Setting up Install Process
Examining /home/vagrant/rpmbuild/RPMS/noarch/rpm4makistrano-20131119110742git2add2a4-1.el6.noarch.rpm: rpm4makistrano-20131119110742git2add2a4-1.el6.noarch
Marking /home/vagrant/rpmbuild/RPMS/noarch/rpm4makistrano-20131119110742git2add2a4-1.el6.noarch.rpm to be installed
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package rpm4makistrano.noarch 0:20131119110742git2add2a4-1.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

===================================================================================================================================================================================
 Package                        Arch                   Version                                         Repository                                                             Size
===================================================================================================================================================================================
Installing:
 rpm4makistrano                 noarch                 20131119110742git2add2a4-1.el6                  /rpm4makistrano-20131119110742git2add2a4-1.el6.noarch                  40 k

Transaction Summary
===================================================================================================================================================================================
Install       1 Package(s)

Total size: 40 k
Installed size: 40 k
Is this ok [y/N]: y
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : rpm4makistrano-20131119110742git2add2a4-1.el6.noarch                                                                                                            1/1
  Verifying  : rpm4makistrano-20131119110742git2add2a4-1.el6.noarch                                                                                                            1/1

Installed:
  rpm4makistrano.noarch 0:20131119110742git2add2a4-1.el6

Complete!
3: rpmの情報を確認
$ rpm -qi rpm4makistrano
Name        : rpm4makistrano               Relocations: /home/git2rpm/rpm4makistrano
Version     : 20131119110742git2add2a4          Vendor: (none)
Release     : 1.el6                         Build Date: Mon 16 Mar 2015 06:31:31 PM JST
Install Date: Mon 16 Mar 2015 06:33:05 PM JST      Build Host: vagrant-centos6
Group       : Unspecified                   Source RPM: rpm4makistrano-20131119110742git2add2a4-1.el6.src.rpm
Size        : 41404                            License: BSD
Signature   : (none)
URL         : https://github.com/hansode/makistrano.git
Summary     : git2rpm
Description :
4: ファイルリストを確認
$ rpm -ql rpm4makistrano
/home/git2rpm/rpm4makistrano
/home/git2rpm/rpm4makistrano/.travis.yml
/home/git2rpm/rpm4makistrano/Makefile
/home/git2rpm/rpm4makistrano/README.md
/home/git2rpm/rpm4makistrano/bin
/home/git2rpm/rpm4makistrano/bin/maki
/home/git2rpm/rpm4makistrano/examples
/home/git2rpm/rpm4makistrano/examples/Makifile
/home/git2rpm/rpm4makistrano/functions
/home/git2rpm/rpm4makistrano/functions/makistrano.sh
/home/git2rpm/rpm4makistrano/test
/home/git2rpm/rpm4makistrano/test/Makefile
/home/git2rpm/rpm4makistrano/test/integration
/home/git2rpm/rpm4makistrano/test/integration/Makefile
/home/git2rpm/rpm4makistrano/test/integration/makistrano
/home/git2rpm/rpm4makistrano/test/integration/makistrano/Makefile
/home/git2rpm/rpm4makistrano/test/integration/makistrano/helper_shunit2.sh
/home/git2rpm/rpm4makistrano/test/integration/makistrano/t.makistrano_cli.sh
/home/git2rpm/rpm4makistrano/test/shunit2
/home/git2rpm/rpm4makistrano/test/unit
/home/git2rpm/rpm4makistrano/test/unit/Makefile
/home/git2rpm/rpm4makistrano/test/unit/makistrano
/home/git2rpm/rpm4makistrano/test/unit/makistrano/Makefile
/home/git2rpm/rpm4makistrano/test/unit/makistrano/helper_shunit2.sh
/home/git2rpm/rpm4makistrano/test/unit/makistrano/t.makistrano_cli.sh
/home/git2rpm/rpm4makistrano/test/unit/makistrano/t.makistrano_eval.sh
/home/git2rpm/rpm4makistrano/test/unit/makistrano/t.makistrano_load_config.sh
/home/git2rpm/rpm4makistrano/test/unit/makistrano/t.makistrano_node.sh
/home/git2rpm/rpm4makistrano/test/unit/makistrano/t.makistrano_nodes.sh

/home/git2rpm/rpm4<パッケージ名>にインストールされている事が分かる。

TODO?

機能追加は、機能不足を感じた時など、気が向いた時に。

  • パッケージ名のprefixrpm4を無効化・別名を指定出来るようにする?
  • インストール先を/home/git2rpmではないディレクトリを指定可能にする?
  • 単にファイルツリーをrpm化しているだけなので、make等のbuild手順を定義出来るようにする?
  • masterブランチだけでなく、他のブランチを指定?

機能追加すると使い辛くなりそうなので、使い辛さが残る程度が丁度良いのかも知れない。

まとめ

git2rpmを使う事により、rpmspecファイルを生成せずにrpmを一撃生成出来た。yumリポジトリと連携させると、バージョンを意識したデプロイ・管理をしやすくなるはずである。

あとがき

yumと連携しなければ、下記と大差がない。yumを使わないと意味がない。

$ git clone <git-uri> /home/git2rpm/<name>



編集
@hansode at 11:00|PermalinkComments(0)TrackBack(0)