Jenkinsのジョブのビルド履歴が消失しているように見える件

以前はちゃんとビルドの内容が表示されていたのですが、ふとある時Jenkinsを見てみると以下の画像の様に定期実行していたジョブが作成直後の状態になっていました。

実際のディレクトリにはジョブのワークスペースやビルドの内容が残っているのでJenkinsから見えなくなっているだけだと思うのですが、原因がよく分からず。さらに、この状態からビルドを実行すると部分的に履歴が復活するという不思議な状況。

解決策としては、とりあえずJenkinsを再起動することです。ビルド履歴は全て復活しました。
このまま放っておいていいのか気になりますが。。(ビルド履歴が見えないだけで定期的なビルドは行われていたようです)

さくらVPSのCentOS6.3にGitLabをインストールした時のメモ

さくらVPSを契約した直後のまっさらな状態からGitLabをインストールした時のメモ書きです。

ググれば色々手順を書いてあるブログがヒットするのですが、GitLabのドキュメント通りにやれば問題なくインストール出来るので、基本的にはそちらを参考にして良いと思います。

https://github.com/gitlabhq/gitlabhq/blob/stable/doc/install/installation.md

予めインストールしておくパッケージ

インストールの前にyumなどで依存するパッケージを入れておくと作業がスムーズに進みます。

yum -y --enablerepo=remi install zlib-devel git openssl-devel perl-devel perl-CPAN libicu-devel mysql-server mysql-devel
  • CPANで入れるもの
    • Time::HiRes
perl -MCPAN -e shell

> install Time::HiRes
> exit
  • wgetしてくるもの
    • libyaml
wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
tar -zxvf yaml-0.1.4.tar.gz
cd yaml-0.1.4
./configure
make && make install
Rubyのインストール

GitLabをインストールするにはRubyが必要ですが、YAMLを扱うライブラリとしてpsychもインストールしておく必要があります。

インストール時に./configureのオプションでlibyamlをインストールしたディレクトリを指定します。

whereis libyaml
>>libyaml: /usr/local/lib/libyaml.so /usr/local/lib/libyaml.a /usr/local/lib/libyaml.la

./configure --with-opt-dir=/usr/local/lib
make && make install
GitLabの起動

インストールドキュメントには起動スクリプトをダウンロードしてきて使用するようになっていますが、試してみたところ起動しませんでした。起動スクリプトは詳しく見てないです。。

service gitlab start
>> Gitlab service started
service gitlab status
>> Gitlab service is not running.

なので、代わりにrailsコマンドを叩いて起動させます。

bundle exec rails s -e production(gitlabユーザで実行)
その他
sudo -u gitlab -H bundle コマンド

とすると実行できなかったので、

su gitlab

でgitlabユーザになって実行したことぐらいでしょうか。

Jenkinsでビルド後の成果物の保存時にStackOverflowErrorになる件の対処法

今朝に続き本日2度目のトラブルシューティング。今度はJenkinsでビルドしてテストは成功しているのに、成果物の保存時にエラーになる件です。

何か無限ループしてメモリ使い切ってるぽい?

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 25.234s
[INFO] Finished at: Sat Feb 23 15:09:04 JST 2013
[INFO] Final Memory: 17M/40M
[INFO] ------------------------------------------------------------------------
テスト結果を保存中
成果物を保存中
FATAL: null
java.lang.StackOverflowError
	at java.io.UnixFileSystem.getBooleanAttributes0(Native Method)
	at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:242)
	at java.io.File.exists(File.java:772)
	at hudson.model.User.getOrCreate(User.java:341)
	at hudson.model.User.get(User.java:331)
	at hudson.model.User.get(User.java:299)
	at hudson.plugins.git.GitChangeSet.findOrCreateUser(GitChangeSet.java:270)
	at hudson.plugins.git.GitChangeSet.getAuthor(GitChangeSet.java:324)
	at hudson.model.AbstractBuild.hasParticipant(AbstractBuild.java:454)
	at hudson.model.AbstractProject.hasParticipant(AbstractProject.java:1530)
	at hudson.model.User.getProjects(User.java:448)
	at hudson.scm.MailAddressResolverImpl.findMailAddressFor(MailAddressResolverImpl.java:19)
	at hudson.tasks.MailAddressResolver.resolve(MailAddressResolver.java:101)
	at hudson.tasks.Mailer$UserProperty.getAddress(Mailer.java:532)
	at hudson.plugins.git.GitChangeSet.isMailerPropertySet(GitChangeSet.java:290)
	at hudson.plugins.git.GitChangeSet.findOrCreateUser(GitChangeSet.java:276)
	at hudson.plugins.git.GitChangeSet.getAuthor(GitChangeSet.java:324)
	at hudson.model.AbstractBuild.hasParticipant(AbstractBuild.java:454)
	at hudson.model.AbstractProject.hasParticipant(AbstractProject.java:1530)
	at hudson.model.User.getProjects(User.java:448)
	at hudson.scm.MailAddressResolverImpl.findMailAddressFor(MailAddressResolverImpl.java:19)
	at hudson.tasks.MailAddressResolver.resolve(MailAddressResolver.java:101)
	at hudson.tasks.Mailer$UserProperty.getAddress(Mailer.java:532)
	at hudson.plugins.git.GitChangeSet.isMailerPropertySet(GitChangeSet.java:290)
	at hudson.plugins.git.GitChangeSet.findOrCreateUser(GitChangeSet.java:276)
	at hudson.plugins.git.GitChangeSet.getAuthor(GitChangeSet.java:324)
	at hudson.model.AbstractBuild.hasParticipant(AbstractBuild.java:454)
	at hudson.model.AbstractProject.hasParticipant(AbstractProject.java:1530)
	at hudson.model.User.getProjects(User.java:448)

思いつくことと言えば、Git Pluginのバージョンを1.1.29に上げたことくらい。

対処法として、Git Pluginのバージョンを1.2に上げたらエラーはなくなりました。

参考:
https://issues.jenkins-ci.org/browse/JENKINS-16849

Mavenを使っていてSpring JDBCにパスが通らなくなってエラーになる件の解決方法

昨晩通っていたビルドが今朝急に通らなくなってびっくりしました。とりあえず解決方法を置いておきますね。

POMにspring-ormを追加します。

参考:
http://stackoverflow.com/questions/15029292/cant-import-org-springframework-jdbc-core-with-maven

あと、mybatis-spring-1.2はmybatis本体への依存関係がなくなってるので、MyBatis使ってる場合はPOMにmybatisの追加も必要な場合も。

ApacheサーバでRewriteしてメンテナンス画面を表示させる

稼働中のWebアプリで一旦メンテナンス画面を表示させて、その間に新しいバージョンをデプロイしたいことがあります。
Apacheだとmod_rewriteを使い全てのリクエストに対してメンテナンス画面のURLに書き換えるか、メンテナンス画面のURLにリダイレクトさせれば良いです。

URLを書き換える単純な例だとこんな感じに。

RewriteEngine on
RewriteRule .* /maintenance.html

こちらはリダイレクトする例。リダイレクトする場合はRewriteRuleのオプションに[R]を指定します。
同一ドメインにリダイレクトする場合、RewriteCondでリダイレクト先のパスを除外しないとリダイレクトループが発生するので注意です。

RewriteEngine on
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule .* /maintenance.html [R]

システムメンテナンスの時はレスポンスコード503を返すようなので、RewriteRuleのオプションに[R=503]を追加してみます。
メンテナンス画面のURLはRewriteRuleではなく、ErrorDocumentで指定します。
この場合もRewriteCondでErrorDocumentで指定したパスを指定しないと、Apacheのデフォルトのエラーページが返ってしまいます

ErrorDocument 503 /maintenance.html

RewriteEngine on
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule .* /anywhere(何でも良い) [R=503]

最後にドキュメントルートとメンテナンス画面のディレクトリが別の場合の例も。
Aliasディレクティブで/maintenance.htmlというパスをドキュメントルートとは別の/var/www/error/maintenance.htmlというパスに対応させます。

ErrorDocument 503 /maintenance.html

Alias /maintenance.html /var/www/error/maintenance.html
RewriteEngine on
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule .* /anywhere(何でも良い) [R=503]

実際に使う場合、上の設定ファイルを/etc/httpd/conf.d/maintenance.conf.no_maintenanceといった名前で作成します。
そして通常時には設定ファイルをApacheに読み込ませない様にしておいて、メンテナンス時には設定ファイル名を変更しApacheを再起動するスクリプトを叩いて設定ファイルを読みこませればOKです。

AngularJSとTestacularのE2EテストではJasmineの.notの代わりに.not()を使う

Jasmineの.notを使って下のようなテストを書くと、

expect(element('[ng-view] div#menu1 table > tbody > tr:first > td:first').text()).
        not.toBe("");

toBeメソッドがないというというエラーが出てテストが成功しません。(scripts/e2e-test.shを実行するとエラーが表示されないので、test/e2e/runner.htmlにアクセスしてテストを実行します)

Object function () {
            return executeStatement.call(self, value, arguments);
          } has no method 'toBe'
TypeError: Object function () {
            return executeStatement.call(self, value, arguments);
          } has no method 'toBe'
    at Object.<anonymous> (http://localhost:8000/test/e2e/scenarios.js:32:13)
    at Object.angular.scenario.SpecRunner.run (http://localhost:8000/test/lib/angular/angular-scenario.js:25188:15)

おかしいなあと思って調べてみると、angular-seedのドキュメントのEnd to end testingの項に「your app and allows you to write your tests with jasmine-like BDD syntax.」って書いてありますね。

Jasmineだと思っていたものはAngularJSがAPIを似せて作ったものだったようです。なので、.notではなくて.not()を使うのが正しいです。

AngularJSとTestacularのE2Eテストで日本語が文字化け

angular-seed付属のtest/e2e/runner.htmlからテストを走らせると日本語が文字化けしてテストが落ちることがあります。

なので、runner.htmlにエンコーディングの指定を追加します。

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>End2end Test Runner</title>
    <script src="../lib/angular/angular-scenario.js" ng-autotest></script>
    <script src="scenarios.js"></script>
  </head>
  <body>
  </body>
</html>