# NAME Cinnamon - A minimalistic deploy tool # SYNOPSIS use strict; use warnings; # Exports some commands use Cinnamon::DSL; my $application = 'My::App'; # It's required if you want to login to remote host set user => 'johndoe'; # User defined params to use later set application => $application; set repository => "git://git.example.com/projects/$application"; # Lazily evaluated if passed as a code set lazy_value => sub { #... }; # Roles role development => 'development.example.com', { deploy_to => "/home/app/www/$application-devel", branch => "develop", }; # Lazily evaluated if passed as a code role production => sub { my $res = LWP::UserAgent->get('http://servers.example.com/api/hosts'); my $hosts = decode_json $res->content; $hosts; }, { deploy_to => "/home/app/www/$application", branch => "master", }; # Tasks task update => sub { my ($host) = @_; my $deploy_to = get('deploy_to'); my $branch = 'origin/' . get('branch'); # Executed on localhost run 'some', 'command'; # Executed on remote host remote { run "cd $deploy_to && git fetch origin && git checkout -q $branch && git submodule update --init"; } $host; }; task restart => sub { my ($host) = @_; # ... }; # Nest tasks task server => { setup => sub { my ($host) = @_; # ... }, }; # You can call other tasks task deploy => sub { my ($host) = @_; call "update", $host; call "restart", $host; }; # WARNINGS This software is under the heavy development and considered ALPHA quality. Things might be broken, not all features have been implemented, and APIs will be likely to change. # DESCRIPTION Cinnamon is a minimalistic deploy tool aiming to provide structurization of issues about deployment. It only introduces the most essential feature for deployment and a few utilities. # DSLs This module provides some DSLs for use. I designed them to be kept as simple as possible, and I don't want to add too many commands: ## Structural Commands ### role ( _$role: Str_ => (_$host: String_ | _$hosts: Array\[String\]_ | _$sub: CODE_), _$param: HASHREF_ ) > role production => 'production.example.com'; > > # or > > role production => [ qw(production1.example.com production2.exampl.ecom) ]; > > # or > > role production => sub { > my $res = LWP::UserAgent->get('http://servers.example.com/api/hosts'); > my $hosts = decode_json $res->content; > $hosts; > }; > > # or > > role production => 'production.example.com', { > hoge => 'fuga', > }; > > Relates names (eg. production) to hosts to be deployed. > > If you pass a CODE as the second argument, this method delays the > value to be evaluated till the value is needed at the first time. This > is useful, for instance, when you want to retrieve hosts information > from some external APIs or so. > > If you pass a HASHREF as the third argument, you can get specified > parameters by get DSL. ### task ( _$taskname: Str_ => (_\\%tasks: Hash\[String =_ CODE\]> | _$sub: CODE_) ) task update => sub { my ($host) = @_; my $hoge = get 'hoge'; # parameter set in global or role parameter # ... }; # you can nest tasks task server => { start => sub { my ($host) = @_; # ... }, stop => sub { my ($host) = @_; # ... }, }; Defines some named tasks by CODEs. The arguments which are passed into the CODEs are: - _$host_ The host name where the task is executed. Which is one of the hosts you set by `role` command. ## Utilities ### set ( _$key: String_ => (_$value: Any_ | _$sub: CODE_) ) > set key => 'value'; > > # or > > set key => sub { > # values to be lazily evaluated > }; > > # or > > set key => sub { > my (@args) = @_; > # value to be lazily evaluated with @args > }; > > Sets a value which is related to a key. > > If you pass a CODE as the second argument, this method delays the > value to be evaluated till `get` is called. This is useful when you > want to retrieve hosts information from some external APIs or so. ### get ( _$key: String_ \[, _@args: Array\[Any\]_ \] ): Any > my $value = get 'key'; > > # or > > my $value = get key => qw(foo bar baz); > > Gets a value related to the key. > > If the value is a CODE, you can pass some arguments which can be used > while evaluating. ### run ( _@command: Array_ ): ( _$stdout: String_, _$stderr: String_ ) > my ($stdout, $stdout) = run 'git', 'pull'; > > Executes a command. It returns the result of execution, `$stdout` and > `$stderr`, as strings. ### sudo ( _@command: Array_ ): ( _$stdout: String_, _$stderr: String_ ) > my ($stdout, $stdout) = sudo '/path/to/httpd', 'restart'; > > Executes a command as well, but under _sudo_ environment. ### remote ( _$sub: CODE_ _$host: String_ ): Any > my ($stdout, $stdout) = remote { > run 'git', 'pull'; > sudo '/path/to/httpd', 'restart'; > } $host; Connects to the remote `$host` and executes the `$code` there. Where `run` and `sudo` commands to be executed depends on that context. They are done on the remote host when set in `remote` block, whereas done on localhost without it. Remote login username is retrieved by `get 'user'` or `` `whoami` `` command. Set appropriate username in advance if needed. ### call ( _$task\_name: String_, _$host: String_ ) > task deploy => sub { > my ($host) = @_; > call "update", $host; > call "web:restart", $host; > }; Call other tasks in a task code. ## Configuration Variables Cinnamon configuration is managed by set function. You can customize following variables. ### user user name which is used for login to server. ### concurrency Max number of concurrent execution of tasks. the task which is not specified concurrency, is executed in parallel by all the hosts. > set concurrency => { > restart => 1, > 'server:setup' => 2, > }; # REPOSITORY https://github.com/kentaro/cinnamon # AUTHOR - Kentaro Kuribayashi - Yuki Shibazaki # SEE ALSO - Tutorial (Japanese) [http://d.hatena.ne.jp/naoya/20130118/1358477523](http://d.hatena.ne.jp/naoya/20130118/1358477523) - [capistrano](https://metacpan.org/pod/capistrano) - [Archer](https://metacpan.org/pod/Archer) # LICENSE Copyright (C) Kentaro Kuribayashi This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.