Jenkinsをすごいcronとして使う

Jenkinsは継続的デリバリーとか継続的インテグレーションの文脈で語られることが多いので、ソースコードのビルドだったりテストの実行だったりをエンジニアの代わりに実行してくれるツールだと思われていることが多いです。(当たり前のことを長々と何言ってんだって感じですが)

しかしJenkinsの機能を、そういったような開発管理ツールではなく汎用的なバッチツール、要は「すごいcron」として使用できることも分かったのでちょっと試してみました。

Git pluginを入れる

今回はサーバ上で動かすバッチをすべてGithubで管理しようと思いますので、pluginを入れます。 入れるのはjenkins GIT plugin! https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin

いれたらJenkinsからGithubにアクセスする設定を行います。 Jenkinsユーザのホームディレクトリは/var/lib/jenkins以下で次の作業を実行!

 cd /var/lib/jenkins
 sudo -u jenkins mkdir .ssh 
 sudo -u jenkins -H ssh-keygen -t rsa -C jenkins@hiroraba.com
 chmod 744 ../.ssh

できた公開鍵をGithubに登録したらJenkinsからアクセスできるか確認。

 sudo -u jenkins ssh -T git@github.com

コードを書いてjenkinsでバッチを動かす

バッチスクリプトを書いてgithubのレポジトリに登録します。 今回は簡単なHELLOだけprintするスクリプトを書きました。何か画像を収集するスクリプトなどをかければ良かったのですが。

後はJenkinsにjobを登録します。

jobのタイプはフリースタイルで大丈夫です。

job

バッチスクリプトが入っているレポジトリを登録。

job2

ビルドトリガを定期的に実行にしcronを設定。

jenkins

実行するシェルスクリプトを書く。 今回はperlのスクリプトを実行するだけ。

job3

これでjobを保存すれば5分毎にGithubのレポジトリがJenkinsサーバにチェックアウトされ、スクリプトが実行されます!

まとめ

  • cronの設定作業をUIから行うことができて楽。バッチ毎にjobを分ければ更に楽です。
  • 仮に実行に失敗してもJenkinsのWebUIからjob実行ボタンをポチッと押せば再実行可能。サーバに入って細々したコマンドを打つ必要なし。
  • サーバに入る必要がないということはサーバ管理者でなくてもJenkinsのアクセス権限さえもらっていればバッチの再実行が可能。楽。
  • サーバで動くスクリプトがGithubで管理できる。Jenkinsが勝手にGithubからコピーしてくれるから修正後にサーバに反映させる必要がないです。pull requestがマージされたらその次のjobから自動的に変更が反映されます。
  • また一つ便利になりました。

Perl歴1年の自分がMojolicious触ってみた感想2

Perl歴1年の自分がMojolicious触ってみた感想 - She is not Gorilla.

これの続き、実際どういう手順で書いたか。

準備

まずはPlackとMojoiiciousを入れる。

cpanm plack
cpanm Mojoiicious

雛形を作る。

mojo generate app MySyte

mojo generate app <アプリケーション名>で雛形ができる。 ちなみにアプリケーション名はCamelケースじゃないと怒られる。 my_siteの中にできた雛形はこんな感じになっていた。

[my_syte] tree                                                                                                          .
├── lib
│   ├── MySyte
│   │   └── Example.pm
│   └── MySyte.pm
├── log
├── public
│   └── index.html
├── script
│   └── my_syte
├── t
│   └── basic.t
└── templates
    ├── example
    │   └── welcome.html.ep
    └── layouts
        └── default.html.ep

動かす

それぞれのファイルは次で見るとしてまずは立ち上げてみる。

plackup script/my_syte

http://0.0.0.0:5000/ を見るとこんな画面が出ているはず。

aaa

一体何が生成されたのか

ではgenerateコマンドで何が出来たのか、一個一個見ていく。

lib

ロジックを規定しているコードが置かれている。ファイルを見た感じ、lib/MySyte.pmでルーティングを設定するらしい。

$r->get('/')->to('example#welcome');

lib/MySite/Example以下にコントローラがある。あろうことか自分はここにロジックを書きまくってしまったんだけどそんなことはしていけない。ダサいからすぐ直そう。

log

ここにはログが入るらしい。今回は使っていない。

public

index.htmlという静的ファイルが入っていたのでここには静的ファイルが入るんだろうと思ったんだけどどうやらそうみたい。javascriptとかCSSとか、後404.htmlもここに入る。

t

以下のテストを行うテストスクリプトが入ってた。今回はいじっていない。

$t->get_ok('/')->status_is(200)->content_like(qr/Mojolicious/i);

templates

*.html.epってあるからして分かるけどここにはテンプレートが入ってる。

実際書く!

全部の説明をしてしまうと結構長くなってしまうので簡潔にまとめる。 getで何かの値を送るフォームはこんな感じで書いた。

<%= form_for  '/get' => (method => 'get') => begin %>
     <%= text_field 'artist', placeholder => 'input artist you like.' %>
     </br>
     <%= submit_button 'OK', class => 'btn btn-primary' %>
<% end %>

送った値はコントローラーのgetっていうサブルーチン内で受け取る。

sub get {
  my $self = shift;
  artist => $self->param('artist'),

modelでごにょごにょした値はrender関数にハッシュで渡して格納してあげる。

$self->render(tracks => $track_url, artist => $artist);

渡った値はget.html.ep内でデリファレンスしてあげるなりなんなりして展開する。

<p class="lead">They are Based on <%= $artist %></p>

こんなふうに書いていって最終的にはこんな構成になった。 footerとheaderはsharedっていうファイルに入れておのおののtemplate内でincludeするようにした。

├── lib
│   ├── HoundCloud
│   │   └── Index.pm
│   └── HoundCloud.pm
├── public
│   ├── css
│   │   ├── bootstrap
│   │   │   ├── bootstrap-responsive.css
│   │   │   ├── bootstrap-responsive.min.css
│   │   │   ├── bootstrap.css
│   │   │   └── bootstrap.min.css
│   │   └── houndcloud.css
│   └── js
├── script
│   └── hound_cloud
├── t
│   └── basic.t
└── templates
    ├── index
    │   ├── get.html.ep
    │   └── welcome.html.ep
    └── shared
        ├── footer.html.ep
        └── header.html.ep

最後に

  • MojoliciousはRails程ごってりしていないと思った。チュートリアルも簡単だったのでPerlを少しでも触った人には取っ付き易いと思う。
  • 情報の流れが分かりやすいのでMVCを学ぶにも適しているのでは?と思った。

それとこんなブログを見るよりこちらを読みましょう。自分も今から読みます。

Mojolicious最速マスター - Qiita [キータ]

Mojolicious - Liteでないアプリの実用的なディレクトリ構造一例 - Qiita [キータ]

Perl歴1年の自分がMojolicious触ってみた感想

何をやったか

  • 仕事でperlを書き始めて1年たったけどバックエンドしか書いてなかったので、WAFを使ってみたいと思ってちょっと触ってみた

何を作ったのか

  • 音楽が好きなので、普段からLast fm とかSoundCloudのAPIを使ってなにかしたいと思っていた。
  • アーティスト名を検索したら似たアーティストをLast fmから取ってきて、そのアーティストを元にSound Cloudからtrackを持ってくるだけの簡単なものを作った。たぶん3時間くらいでできた。気がする。

何をみながらやったの?

  • 基本的にこれを見るだけでできた。 Home · yuki-kimoto/mojolicious-guides-japanese Wiki · GitHub

  • といっても見たのはルーティングの書き方と、テンプレートへの値の 渡し方だけで、後のロジック部分はいつものように書くだけでだったからすごく簡単だった。

で、具体的にはどうやったの?

lxc + Rex

何をやったか

  • lxcを複数コンテナ立ててRexで管理した。
  • Rexはperlで書けるchefのようなもの。apache2だったら以下のような書き方でインストールできる。
  • 所謂Infrastructure As a Code.

(R)?ex - A simple framework to simplify systemadministration and datacenter automation

gist7988838

インストール方法

echo 'deb http://rex.linux-files.org/ubuntu/ precise rex' >> /etc/apt/sources.list
wget -O - http://rex.linux-files.org/DPKG-GPG-KEY-REXIFY-REPO | apt-key add -
apt-get update
apt-get install rex

ディレクトリ構成

  • Rexfileで実行ユーザとかサーバを書いて、lib中のモジュールで細かい設定を行う。Vagrantとchefの関係にちょっと似ている。
.
├── lib
│   └── mysite.pm
└── Rexfile

Rexfile

set groupsでserverをグルーピングできる。このgroupに対して各々の具体的な処理をlib以下(今回だとmysite)に書くらしい。serverは今回はIP指定だけどwww[0-100]のような書き方も可。

gist7988866

mysite.pm

gist7988975

server1グループにapache2入れてserver2にphp5を入れるだけの処理。chefやpuppetに似ていて既視感がある。install以外にもrunでコマンドを走らせることもできるし、テンプレートも使える。

my $output = run "uptime";
say $output;

実行コマンド

以下のコマンドでmysite内のtaskが走る。

rex mysite:server1 mysite:server2

感想

Perlでchefっぽいものが書けて便利だけど、プロジェクト自体がまだ新しくDocumentがあまり整備されていない様子。 後公式Manualだとrootユーザでログインすることになっていて、それっていいのかなってちょっと思った。

PerlでTDDするためにguardっぽいモジュール書いた

何をやったか

PerlでTDDをしたくなったのだけれど、いちいちテストスクリプトを修正毎に回すのが億劫になってしまったのでファイルを監視して勝手に回すモジュール書いた。perlにguardっぽい挙動をさせるもの。

中でやってることは簡単で、newするときに監視したいプロジェクトのrootディレクトリを指定する。startでFilesys::notify::simpleへの監視が始まる。更新されたファイルが *.t であればそのテストだけ回し、*.pl *.pmだったらワイルドに全部回す。

TDDへの意識の高みが消え失せる前に書かねばというモチベーションの元作ったのですごくシンプルなものになった(なってしまった)

テストについて

基本的にテストはめんどくさい。開発より単調な作業だし時間がかかる、だからこそ開発と平行してやるべきなんだけど、それがなかなかできない。

だとすれば、テスト作成に必要な準備は徹底的にめんどくさくないものにすべきだと思う。今回はモジュールにしてしまったのも本来はスクリプトにすべきだったと思っているしなんならスクリプトを起動する手間だって省きたい。vimを立ち上げたときに自動的監視が始まりテストが動き始めたら尚良い。

このモジュールを書きながら、そんなことをちょっとだけ考えた。

おわりに

このエントリは Qiita Perl Advent Calendarの14日の記事として書きました。

来年はちゃんと準備してテクニカルのことを書きたい。

Perl Advent Calendar 2013 - Qiita [キータ]

 

Dockerを入れるrecipe書いたら翌日に用なしになった

vagrantでdockerを使おうと思って、どうせならchefでいれられるようにしようと思って、こんなrecipeを書いた。

無事に使えるようになったのでやったーと思って寝て起きたらdocker provisionerがリリースされていた。

Vagrant.configure("2") do |config|
  config.vm.provision "docker",
    images: ["ubuntu"]
end

Vagrantfileにたったこれだけ追記するだけで入っちゃうらしい。

Docker - Provisioning - Vagrant Documentation

なんと。