機能 #14
完了GitBucket 2.1のRPMを作成する
100%
説明
GitBucket 2.1のRPMを作成します。
GitBucketの入手先(GitHub)は次のURLです。
https://github.com/takezoe/gitbucket
このリポジトリのcontribには、Red Hat Enterprise Linux用のRPM作成に使うSPECファイル、サービス起動のinitファイル、設定ファイルが登録されていますが、rootユーザーで動く仕様となっています。
そこで、Jenkinsのようにrootではなく特定のユーザー権限で動くようにRPMを作成します。
高橋 徹 さんがほぼ11年前に更新
- ステータス を 新規 から 進行中 に変更
- 進捗率 を 0 から 50 に変更
まずは、GitHubリポジトリより次のファイルを入手します。
- gitbucket.war (Javaバイトコード)
- gitbucket-2.1.tar.gz (ソースファイル)
- gitbucket.spec (RPMビルド用定義ファイル)
- gitbucket.conf (GitBucket実行時の設定ファイル)
- gitbucket.init (GitBucketをservice起動するためのスクリプトファイル)
それぞれRPMビルド用に配置します。
$HOME/rpm +-- SPECS | +-- gitbucket.spec +-- SOURCES +-- gitbucket.war +-- gitbucket-2.1.tar.gz +-- gitbucket.conf +-- gitbucket.ini
GitBucketのcontribをほぼそのままでRPM作成(rootユーザー実行)¶
--- gitbucket.spec 2014-07-20 21:23:47.303501900 +0900
+++ rpm/SPECS/gitbucket.spec 2014-07-20 21:27:18.326450470 +0900
@@ -1,6 +1,6 @@
Name: gitbucket
Summary: GitHub clone written with Scala.
-Version: 1.7
+Version: 2.1
Release: 1%{?dist}
License: Apache
URL: https://github.com/takezoe/gitbucket
@@ -40,6 +40,9 @@
%changelog
+* Sun Jul 20 2014 Toru Takahashi <torutk at gmail.com>
+- Version bump to v2.1.
+
* Mon Oct 28 2013 Jiri Tyr <jiri_DOT_tyr at gmail.com>
- Version bump to v1.7.
RPMビルドを実行します。
~$ rpmbuild -ba rpm/SPECS/gitbucket.spec :
RPMおよびSRPMが生成されます。
$HOME/rpm +-- RPMS | +-- noarch | +-- gitbucket-2.1-1.el6.noarch.rpm +-- SRPMS +-- gitbucket-2.1-1.el6.src.rpm
生成されたRPMをインストールします。
~$ sudo rpm -Uvh rpm/RPMS/noarch/gitbucket-2.1-1.el6.noarch.rpm 準備中... ########################################### [100%] 1:gitbucket ########################################### [100%] ~$
次のファイルがインストールされました。
~$ rpm -ql gitbucket /etc/init.d/gitbucket /etc/sysconfig/gitbucket /usr/share/gitbucket/lib/gitbucket.war /var/log/gitbucket/run.log ~$
手動でgitbucketを実行します。
~$ sudo service gitbucket start
gitbucketのログは、/var/log/gitbucket/run.log に生成されます。
gitbucketのプロセスIDは、/var/run/gitbucket.pid に生成されます。
gitbucketのデータは、/var/lib/gitbucket/ に生成されます。data.h2.db, data.lock.db, version といったファイルが見受けられます。
高橋 徹 さんがほぼ11年前に更新
gitbucketをrootユーザーではなくgitbucketユーザーで動かすために必要なことを調べる¶
Jenkinsが同じくwarファイルをjavaで実行するタイプですが、rootユーザーではなくjenkinsユーザーで実現しているので、Jenkinsの起動スクリプトを参考にします。
https://github.com/jenkinsci/jenkins/blob/master/rpm/SOURCES/jenkins.init.in
rootで動くgitbucketをインストールした後、これをgitbucketユーザーで動かすために必要な修正をしていきます。
修正が完了した時点でgitbucket.specファイルほかを修正していきます。
gitbucketユーザー/グループの作成
~$ sudo groupadd -r gitbucket ~$ sudo useradd -g gitbucket -s /bin/false -r -c "GitBucket SCM Server" -d /var/lib/gitbucket gitbucket
- jenkinsの設定に倣ってユーザーのシェルを/bin/falseにしたけど、su gitbucket -c "コマンド"がスカって起動しません。調べると、
- /bin/false はシェルを通じて一切の操作ができない偽シェル(su <ユーザー> -c "コマンド"も操作できない模様)。daemonで起動する場合はシェルを通じないかも(jenkinsのinitスクリプトではdaemon関数でコマンドを実行していた)。
gitbucketのログディレクトリ/ファイルの所有者変更
~$ sudo chown -R gitbucket.gitbucket /var/log/gitbucketgitbucket起動スクリプト(/etc/init.d/gitbucket)でコマンドをgitbucketユーザーで実行する変更
@@ -41,7 +41,7 @@
fi
# Run the Java process
- daemon --user gitbucket --pidfile ${PID_FILE} "GITBUCKET_HOME=${GITBUCKET_HOME} java $GITBUCKET_JVM_OPTS -jar $GITBUCKET_WAR_FILE $START_OPTS >>$LOG_FILE 2>&1 &"
+ GITBUCKET_HOME="${GITBUCKET_HOME}" java $GITBUCKET_JVM_OPTS -jar $GITBUCKET_WAR_FILE $START_OPTS >>$LOG_FILE 2>&1 &
RETVAL=$?
# Store PID of the Java process into a file
- 最初 su gitbucket -c "..." で実行しようとしましたが、gitbucketユーザーのシェルが偽シェル(/sbin/false)だと駄目だったのでdaemon関数で実行してみました。
起動しましたが、serviceからstopができません。PIDファイルが空です。
gitbucket起動スクリプト(/etc/init.d/gitbucket)でdaemon関数で起動したjavaプロセスのPIDを取得する変更
@@ -46,6 +46,13 @@
# Store PID of the Java process into a file
echo $! > $PID_FILE
+ /bin/ps hww -u gitbucket -o sess,ppid,pid,cmd | \
+ while read sess ppid pid cmd; do
+ [ "$ppid" = 1 ] || continue
+ echo "$cmd" | grep $GITBUCKET_WAR_FILE > /dev/null
+ [ $? = 0 ] || continue
+ echo $pid > "$PID_FILE"
+ done
if [ $RETVAL -eq 0 ] ; then
success "GitBucket startup"
gitbucketのデータは、/var/lib/gitbucketの下に作成されます。ここの所有権をgitbucketユーザーに変更します。
~$ sudo chown -R gitbucket.gitbucket /var/lib/gitbucket
高橋 徹 さんがほぼ11年前に更新
実効ユーザーを変更したRPMを作成するための修正¶
SPECファイルにgitbucketユーザー・グループ作成とファイルのパーミッション指定を追加
@@ -1,7 +1,7 @@
Name: gitbucket
Summary: GitHub clone written with Scala.
Version: 2.1
-Release: 1%{?dist}
+Release: 2%{?dist}
License: Apache
URL: https://github.com/takezoe/gitbucket
Group: System/Servers
@@ -26,6 +26,25 @@
%{__install} -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
touch %{buildroot}%{_localstatedir}/log/%{name}/run.log
+%pre
+/usr/sbin/groupadd -r gitbucket &> /dev/null || :
+/usr/sbin/useradd -g gitbucket -s /bin/false -r -c "GitBucket GitHub clone" -d %{_sharedstatedir}/%{name} gitbucket &> /dev/null || :
+
+%post
+/sbin/chkconfig --add gitbucket
+
+%preun
+if [ "$1" = 0 ]; then
+ /sbin/service gitbucket stop > /dev/null 2>&1
+ /sbin/chkconfig --del gitbucket
+fi
+exit 0
+
+%postun
+if [ "$1" -ge 1 ]; then
+ /sbin/service gitbucket restart > /dev/null 2>&1
+fi
+exit 0
%clean
[ "%{buildroot}" != / ] && %{__rm} -rf "%{buildroot}"
@@ -34,12 +53,16 @@
%files
%defattr(-,root,root,-)
%{_datarootdir}/%{name}/lib/%{name}.war
-%{_sysconfdir}/init.d/%{name}
-%config %{_sysconfdir}/sysconfig/%{name}
-%{_localstatedir}/log/%{name}/run.log
+%config %{_sysconfdir}/init.d/%{name}
+%config(noreplace) %{_sysconfdir}/sysconfig/%{name}
+%attr(0755,gitbucket,gitbucket) %{_sharedstatedir}/%{name}
+%attr(0750,gitbucket,gitbucket) %{_localstatedir}/log/%{name}
%changelog
+* Mon Jul 21 2014 Toru Takahashi <torutk at gmail.com>
+- execute as gitbucket user
+
* Sun Jul 20 2014 Toru Takahashi <torutk at gmail.com>
- Version bump to v2.1.
高橋 徹 さんが10年以上前に更新
Gitbucket 2.4.1がリリースされたので、RPMパッケージを作成しました。
- https://github.com/takezoe/gitbucket/releases からソースコードとwarをダウンロードし、~/rpm/SOURCESにコピー
- 2.1のSPECファイルをバージョンを2.4.1に修正
- ソースコードを作業ディレクトリに展開し、contrib/gitbucket.{conf,init}を取り出し~/rpm/SOURCESにkピー
- rpmbuild実行
- 出来たRPMをインストール
- サービス実行
~$ sudo service gitbucket start ~$
あれ、なにもメッセージが出ません。おかしい。/etc/init.d/gitbucketを直接実行~$ cd /etc/init.d inti.d$ sudo ./gitbucket start init.d$
同じく。gitbucketに片っ端からecho文を埋めてみると、13 set -e 14 15 [ -f /etc/rc.d/init.d/functions ] && source /etc/rc.d/init.d/functions # RedHat
15行目より後に入れたecho文が出ない。
→ set -e について調べてみた
set -e での動作を想定していないライブラリを . (ドット) コマンド や source コマンドで読み込んだときに使えない。
http://qa.atmarkit.co.jp/q/2813
とあった。set -eを削除するとメッセージが出るようになった。
現状はjavaプロセスがrootで実行される。gitbucketユーザーで実行するために、/etc/rc.d/init.d/functionsで定義されるdaemonファンクションを使用してみました。
GITBUCKET_HOME="${GITBUCKET_HOME}" daemon --user=gitbucket java $GITBUCKET_JVM_OPTS -jar $GITBUCKET_WAR_FILE $START_OPTS >>$LOG_FILE 2>&1 &
/var/lib/gitbucketのパーミッションがrootだと動かないのでgitbucketに変更したら動きました。
高橋 徹 さんが10年以上前に更新
service gitbucket stopで停止しない¶
/etc/init.d/gitbucket の起動部分を抜粋
60 GITBUCKET_HOME="${GITBUCKET_HOME}" daemon --user=gitbucket java $GITBUCKET _JVM_OPTS -jar $GITBUCKET_WAR_FILE $START_OPTS >>$LOG_FILE 2>&1 & 61 RETVAL=$? 62 63 echo $! > $PID_FILE
起動するプロセスをps aux
から抜粋
~$ ps aux|grep gitbucket root 1194 /bin/bash /etc/rc3.d/S60gitbucket start root 1203 runuser -s /bin/bash gitbucket -c ulimit -S -c 0 >/dev/null 2>&1 ; java -Dmail.smtp.starttls.enable=true -jar /usr/share/gitbucket/lib/gitbucket.war --port=8080 --host=0.0.0.0 496 1205 bash -c ulimit -S -c 0 >/dev/null 2>&1 ; java -Dmail.smtp.starttls.enable=true -jar /usr/share/gitbucket/lib/gitbucket.war --port=8080 --host=0.0.0.0 496 1206 java -Dmail.smtp.starttls.enable=true -jar /usr/share/gitbucket/lib/gitbucket.war --port=8080 --host=0.0.0.0
このとき、/var/run/gitbucket
の中は、1194 となっていた。これはgitbucketプロセスではなく、gitbucketプロセスを起動するシェルスクリプトのPIDとなっている。
daemon functionに渡す--pidfileオプションは参照用でそのファイルを生成してPIDを書き込んではくれない!
@@ -60,8 +60,6 @@
GITBUCKET_HOME="${GITBUCKET_HOME}" daemon --user=gitbucket java $GITBUCKET_JVM_OPTS -jar $GITBUCKET_WAR_FILE $START_OPTS >>$LOG_FILE 2>&1 &
RETVAL=$?
- echo $! > $PID_FILE
-
if [ $RETVAL -eq 0 ] ; then
success "Success"
else
@@ -77,11 +75,10 @@
echo -n $"Stopping GitBucket server: "
# Run the Java process
- kill $(cat $PID_FILE 2>/dev/null) >>$LOG_FILE 2>&1
+ pkill -f $GITBUCKET_WAR_FILE >>$LOG_FILE 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ] ; then
- rm -f $PID_FILE
success "GitBucket stopping"
else
failure "GitBucket stopping"
高橋 徹 さんが10年以上前に更新
GitBucketの起動制御スクリプトの再構築¶
CentOS 6でGitBucketの起動制御スクリプトを使えるようにするため、リポジトリの元ネタから再度修正を開始します。
https://github.com/takezoe/gitbucket/blob/master/contrib/gitbucket.init
これをCentOS 6で動かすと次の行でエラーとなりました。
if [ `isMac` ]; then
CentOS 6にはisMacというコマンドがないためです。gitbucket.initはこのスクリプトは、RedHat/Ubuntu/Mac OS X共用になっています。ファイル先頭のコメント部分を抜き出します。
# RedHat: /etc/rc.d/init.d/gitbucket # Ubuntu: /etc/init.d/gitbucket # Mac OS/X: /Library/StartupItems/GitBucket
しかし、スクリプト中にif文で切り分けを入れる作りでは、3つの環境を持っていてすべてで確認しながら修正作業をする必要があります。すべての環境を持っていることは稀で、持っていたとしても甚だ手間がかかります。実際、上述のようにRedHat系のCentOSにはないコマンドを実行するコードが入ってしまっています。スクリプトは環境ごとに分けるべきでしょう。
ということで、まずRedHat系専用のスクリプトにします。gitbucketのリポジトリを見ると
gitbuckt +-- contrib : +-- linux : | +-- redhat : | +-- gitbucket.spec : +-- macosx : | +-- makePlist : +-- README.md : +-- gitbucket.conf : +-- gitbucket.init : +-- install
となっているので、RedHat専用にする起動制御スクリプトは、contrib/linux/redhat/に置くのが好ましいでしょう。そこで、contrib/gitbucket.init を、contrib/linux/redhat/gitbucket.init にコピーしこれを変更していきます。
- Ubuntu/MacOS用コードの削除
-# Ubuntu: /etc/init.d/gitbucket -# Mac OS/X: /Library/StartupItems/GitBucket : -[ -f /etc/rc.common ] && source /etc/rc.common # Mac OS/X : -## MacOS proxies for System V service hooks: -StartService() { - start -} -StopService() { - stop -} - -RestartService() { - restart -} - - -if [ `isMac` ]; then - RunService "$1" -else : -fi
- set -eの削除(前に述べたsource /etc/rc.d/init.d/functions を機能させるための修正)
-set -e -
- gitbucketユーザーで実行(前に述べた修正)
- GITBUCKET_HOME="${GITBUCKET_HOME}" java $GITBUCKET_JVM_OPTS -jar $GITBUCKET_WAR_FILE $START_OPTS >>$LOG_FILE 2>&1 & + GITBUCKET_HOME="${GITBUCKET_HOME}" daemon --user=gitbucket java $GITBUCKET_JVM_OPTS -jar $GITBUCKET_WAR_FILE $START_OPTS >>$LOG_FILE 2>&1 &
- pidファイルによるサービス(プロセス)終了の制御ができないため代替方法
-PID_FILE=/var/run/gitbucket.pid : - echo $! > $PID_FILE - : - kill $(cat $PID_FILE 2>/dev/null) >>$LOG_FILE 2>&1 + pkill -f gitbucket.war >>$LOG_FILE 2>&1 : - rm -f $PID_FILE : status) - status -p $PID_FILE java + pgrep -f gitbucket.war >> $LOG_FILE 2>&1 RETVAL=$? + if [ $RETVAL -eq 0 ]; then + echo $"GitBucket is running...." + else + echo $"GitBucket is stopped" ;;
ここまでの修正でサービス起動制御スクリプトを実行すると次のようになります。
~$ sudo service gitbucket status which: no success in (/sbin:/usr/sbin:/bin:/usr/bin) which: no failure in (/sbin:/usr/sbin:/bin:/usr/bin) GitBucket is stopped
これは、次のスクリプト記述が原因です。
if [ -z "$(which success)" ]; then function success { printf "%b\n" "$GREEN $* $OFF" } fi if [ -z "$(which failure)" ]; then function failure { printf "%b\n" "$RED $* $OFF" } fi
successとfailureは、/etc/rc.d/init.d/functionsスクリプトで定義されるシェル関数です。whichコマンドでパスを取得することができません。しかし、このスクリプト記述はsuccessとfailureがコマンドである想定で書かれています。RedHat系専用スクリプトでは、ばっさり削除してしまいます。
-if [ -z "$(which success)" ]; then
- function success {
- printf "%b\n" "$GREEN $* $OFF"
- }
-fi
-if [ -z "$(which failure)" ]; then
- function failure {
- printf "%b\n" "$RED $* $OFF"
- }
-fi
起動に失敗しても、スクリプト上は成功として表示されてしまいます。次のスクリプト部分が課題です。
GITBUCKET_HOME="${GITBUCKET_HOME}" daemon --user=gitbucket java $GITBUCKET \ _JVM_OPTS -jar $GITBUCKET_WAR_FILE $START_OPTS >>$LOG_FILE 2>&1 & RETVAL=$? if [ $RETVAL -eq 0 ] ; then success "Success" else failure "Exit code $RETVAL" fi
バックグラウンド実行(末尾に'&'をつけて実行)した場合、コマンド実行結果('$?')は常に0(成功)となります。
そこで、daemonでバックグラウンド実行後、一定時間経過待ち1してからpgrepでプロセスを探して結果を判定することにします。
GITBUCKET_HOME="${GITBUCKET_HOME}" daemon --user=gitbucket java $GITBUCKET _JVM_OPTS -jar $GITBUCKET_WAR_FILE $START_OPTS >>$LOG_FILE 2>&1 &
+ sleep 3
+ pgrep -f $GITBUCKET_WAR_FILE >> $LOG_FILE 2>&1
RETVAL=$?
1 本当はプロセスが立ち上がったことを確認したかったのですが、うまいやり方が見つからずsleepにしてしまいました。
高橋 徹 さんが約10年前に更新
- ステータス を 解決 から 終了 に変更
- 進捗率 を 80 から 100 に変更
【棚卸し】この修正を、gitbucketのgithubリポジトリからフォークを作成して、ブランチにコミット
https://github.com/torutk/gitbucket/commit/676670e9e3a1666404bedb4cccf54de2773ad0b9
プルリクエストを発行して、その後取り込んでいただきました。