Cinnamon - simple deploy tool

Preview:

DESCRIPTION

 

Citation preview

Cinnamonsimple deploy tool

@shiba_yu362013/02/23 Kansai.pm

自己紹介

shiba_yu36 shibayu36

or etc...

&

http://blog.hatena.ne.jp/shiba_yu36

•株式会社はてな

•アプリケーションエンジニア

•はてなブログ

•外部API、課金などの基盤周り

Work

Perl•perlbrew.el•DBIx::DataFactory•Kyoto.pm•Cinnamon •-> 今日のお話

アジェンダ•デプロイツールとは?

•自作ツールのCinnamonのご紹介

• Demo

•技術的Tips

デプロイツールとは?•デプロイツール知っている人?

•使っている人?

• capistrano使っている人?

デプロイツールとは?•サーバへのデプロイを支援

•面倒な手順をまとめる

•複数台への一括デプロイ

•単純化すると、サーバへのコマンド実行

デプロイツールとは?• Capistrano (Ruby製)

•よく使われてる

• Archer (Perl製)

• etc...

Capistranoへの不満• Railsに紐付きすぎている

•中の実装が多く複雑 -> はまる

Capistranoへの不満•複数サーバにコマンド発行するだけ

• DSLで簡単に設定したい

• Perl !!!!!!!!

Cinnamon

Cinnamonとは?• perl製デプロイツール

• perlでDSLっぽく設定を書ける

•ネーミングは弊社会長犬から

Cinnamonの思想•Minimum

•Role x Task

Minimum• Cinnamon側ではサーバへのコマンド実行のみ

•デプロイの方法は利用者に

Role x Task

環境とタスクの組み合わせ

•サーバ群をroleとして定義

•実行したいものをtaskとして定義

• roleとtaskを組み合わせて実行

•例)「本番appサーバ」に「コードの反映」を実行

Role x Task

cpanm Cinnamon

How to Use

Synopsisuse Cinnamon::DSL;

set user => 'johndoe'; # requiredset application => 'My-App'; # custom value

role production => 'production.host'; # declare server

task update => sub { my ($host, @args) = @_; my $deploy_to = get('deploy_to'); remote { run "cd $deploy_to && git pull"; } $host;};

use Cinnamon::DSL;

set user => 'johndoe'; # requiredset application => 'My-App'; # custom value

role production => 'production.host'; # declare server

task update => sub { my ($host, @args) = @_; my $deploy_to = get('deploy_to'); remote { run "cd $deploy_to && git pull"; } $host;};

•config/deploy.pl•useしてDSLを書けるように

use Cinnamon::DSL;

set user => 'johndoe'; # requiredset application => 'My-App'; # custom value

role production => 'production.host'; # declare server

task update => sub { my ($host, @args) = @_; my $deploy_to = get('deploy_to'); remote { run "cd $deploy_to && git pull"; } $host;};

•ログインユーザ名をset

use Cinnamon::DSL;

set user => 'johndoe'; # requiredset application => 'My-App'; # custom value

role production => 'production.host'; # declare server

task update => sub { my ($host, @args) = @_; my $deploy_to = get('deploy_to'); remote { run "cd $deploy_to && git pull"; } $host;};

•roleでサーバ群を定義

•配列で複数サーバ渡せる

use Cinnamon::DSL;

set user => 'johndoe'; # requiredset application => 'My-App'; # custom value

role production => 'production.host'; # declare server

task update => sub { my ($host, @args) = @_; my $deploy_to = get('deploy_to'); remote { run "cd $deploy_to && git pull"; } $host;};

•taskで実行コマンドを定義

•remote + runでサーバに実行

•runの代わりにsudo

use Cinnamon::DSL;

set user => 'johndoe'; # requiredset application => 'My-App'; # custom value

role production => 'production.host'; # declare server

task update => sub { my ($host, @args) = @_; my $deploy_to = get('deploy_to'); remote { run "cd $deploy_to && git pull"; } $host;};•set/getを使ってユーザ定義値

•遅延評価することも可能

実行• cinnamon (role) (task)

• cinnamon production update

Use Case

サーバ群を別の管理ツールから決めたい

•別にサーバ管理ツールがある

• HTTPのAPIみたいなのがある

•そこから動的にサーバを決めたい

サーバ群を別の管理ツールから決めたい

role production => sub { my $res = LWP::UserAgent->get( 'http://servers.example.com/api/hosts', ); my $hosts = decode_json $res->content; $hosts;};

callbackで動的にサーバを決める遅延ロードする

開発環境は違うブランチ

•本番はmasterを反映

•開発環境はdevelopment

• etc...

開発環境は違うブランチrole production => ['production.host'], { branch => "master",};role development => ['development.host'], { branch => "development",};

task update => sub { my $branch = get('branch'); # ...};

roleで変数の上書きが出来る

How to Make

How to Make• サーバへのコマンド実行部

• Net::OpenSSH• DSL部

サーバへのコマンド実行• Net::OpenSSHが便利

•コマンド実行 + 結果の取得

• system, capture2, open3

サーバへのコマンド実行

my $ssh = Net::OpenSSH->new( 'shiba.host', user => 'shibayu36',);

$ssh->system('ls /home');my ($out, $err) = $ssh->capture2("ls /home");my ($in, $out, $err, $pid) = $ssh->open3("cpanm --installdeps .");

サーバへのコマンド実行

my $ssh = Net::OpenSSH->new( 'shiba.host', user => 'shibayu36',);

$ssh->system('ls /home');my ($out, $err) = $ssh->capture2("ls /home");my ($in, $out, $err, $pid) = $ssh->open3("cpanm --installdeps .");

ホスト名とユーザ名を入れてnew

サーバへのコマンド実行

my $ssh = Net::OpenSSH->new( 'shiba.host', user => 'shibayu36',);

$ssh->system('ls /home');my ($out, $err) = $ssh->capture2("ls /home");my ($in, $out, $err, $pid) = $ssh->open3("cpanm --installdeps .");

systemでコマンドの実行のみ

サーバへのコマンド実行

my $ssh = Net::OpenSSH->new( 'shiba.host', user => 'shibayu36',);

$ssh->system('ls /home');my ($out, $err) = $ssh->capture2("ls /home");my ($in, $out, $err, $pid) = $ssh->open3("cpanm --installdeps .");

capture2で標準出力などを変数に

サーバへのコマンド実行

my $ssh = Net::OpenSSH->new( 'shiba.host', user => 'shibayu36',);

$ssh->system('ls /home');my ($out, $err) = $ssh->capture2("ls /home");my ($in, $out, $err, $pid) = $ssh->open3("cpanm --installdeps .");

open3使うとファイルハンドラがもらえる

使いどころ•サーバと連携するツールの開発に便利

• CinnamonではAnyEvent::Handlerと一緒に使って、出力をしている

DSL•単なる関数export

• Exporter::Lite

DSLの簡単な例package Cinnamon::DSL;use Exporter::Lite;our @EXPORT = qw(role);

sub role ($$;$) { my ($name, $hosts, $params) = @_; # ...}

DSLの応用的な実装• Plack::Builderが参考になる

• builderブロックの中でしかenableが使えない

DSLの応用的な実装sub enable { $_add->(@_) }sub builder(&) { my $block = shift; my $self = __PACKAGE__->new;

# ... local $_add = sub { $self->add_middleware(@_); }; # ...}

まとめ•デプロイツールのお話

•シンプルなツールのCinnamonの紹介

• pull requestお待ちしております!!!

ご清聴ありがとうございました