houcho 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjRkYjFlODg2OGNmOTY1ZWY1NzIzMGM0NDZiOTJlZDIyNThiMjcwYQ==
5
+ data.tar.gz: !binary |-
6
+ YzYzNDQ0NzI2MmViN2QzNThkMDk5NmMwYjIzOTVkYTBiYjg3OTgzZg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NTQwOGM5YWY2MjM0NmYxNDM1ZGY5YmFjNTI5OTlmOTI0ZjBkMzdhNzdhNDAx
10
+ NDg5Yzk3NzA2M2RlZDU4MmZjYWEwZjBkNjUwZjFkMWI5ZTkwMzg2NGMzNGZi
11
+ MzU3Y2E5OTI1ZGFkMGY4MTE1Y2U3MjYyZGRlMzZhMTc2MTNhODY=
12
+ data.tar.gz: !binary |-
13
+ ODNlM2NiYTBmZTUxZmIyMjI4ZTA3M2Q4OWNiYmJiMWZiNzg5ZGZhOTAzZjMy
14
+ ZGZjMWFjZTBhMjAwY2QzNjRhMjZjZTFiZmJjZWYyZjQwMzRkODA3OTIwY2Jl
15
+ MGQ0ZjUxMTJlMDliZmNiMWVjNTRkMjQ4NWViOTE5OWIzMWIzNDE=
@@ -0,0 +1,8 @@
1
+ *.swp
2
+ pkg
3
+ coverage
4
+ coverage.data
5
+ rdoc
6
+ .yardoc
7
+ .bundle
8
+
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rainbow'
4
+ gem 'parallel_tests'
5
+ gem 'systemu'
6
+ gem 'serverspec'
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 studio3104
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,187 @@
1
+ # Houcho
2
+ - wrapping to execute serverspec
3
+
4
+ ## Install and Initialize
5
+ - git cloneして、bin/にPATHを通します。
6
+
7
+ ```sh
8
+ $ git clone git://github.com/studio3104/houcho.git
9
+ $ echo PATH=`pwd`'/houcho/bin:$PATH' >> ~/.bachrc
10
+ ```
11
+
12
+ - 作業ディレクトリを作成し、イニシャライズします。
13
+ - このディレクトリ配下にrole情報やspecなどが蓄積されます。
14
+ - `houcho init`すると`git init`されます。
15
+
16
+ ```sh
17
+ $ mkdir houcho-repo
18
+ $ cd houcho-repo
19
+ $ houcho init
20
+ ```
21
+
22
+ ## Simple Usage
23
+ - もっともシンプルな使い方の例。
24
+
25
+ ```sh
26
+ $ houcho spec exec --specs houcho_sample --hosts test.studio3104.com
27
+ ```
28
+
29
+ - `test.studio3104.com`に`houcho_sample_spec.rb`を実行します。
30
+ - `--specs`,`--hosts`の引数は、スペース区切りで複数指定が可能です。
31
+ - `--specs`の引数は、作業ディレクトリの`spec/`からの相対パスで、`_spec.rb`を除いて指定します。
32
+
33
+ ## Create Role, Run Role
34
+ よく使う組み合わせをroleとして定義しておくことが出来ます。
35
+
36
+ - まずはroleの作成。
37
+
38
+ - role名はフリーワードでokです。
39
+
40
+ ```sh
41
+ $ houcho role create studio3104::www
42
+ ```
43
+
44
+ - 作成したroleにホストをattachします。
45
+ - TODO: 複数指定出来るようにする。
46
+
47
+ ```sh
48
+ $ houcho host attach www01.studio3104.com studio3104::www
49
+ $ houcho host attach www02.studio3104.com studio3104::www
50
+ ```
51
+
52
+ - specをattachします。
53
+ - TODO: 複数指定出来るようにする。
54
+ - simple usageと同じように、作業ディレクトリの`spec/`からの相対パスで、`_spec.rb`を除いて指定します。
55
+
56
+ ```sh
57
+ $ houcho spec attach houcho_sample studio3104::www
58
+ ```
59
+
60
+ - 作成したroleの内容を確認します。
61
+
62
+ ```sh
63
+ $ houcho role details studio3104::www
64
+ studio3104::www
65
+
66
+ [host]
67
+ ├─ www01.studio3104.com
68
+ └─ www02.studio3104.com
69
+
70
+ [spec]
71
+ └─ houcho_sample
72
+ ```
73
+
74
+ - roleを実行します。
75
+ - 複数指定が可能です。
76
+
77
+ ```sh
78
+ $ houcho spec exec --roles studio3104::www
79
+ ```
80
+
81
+ - 正規表現を使うことも出来ます。
82
+
83
+ ```sh
84
+ $ houcho spec exec --roles studio3104.+
85
+ ```
86
+
87
+
88
+ ## Include CloudForecast's yaml file
89
+ cloudoforecastのyamlを読み込み、定義済みのオリジナルroleにattach出来ます。
90
+
91
+ - cloudforecastのyamlを、`role/cloudforecast/`に設置します。
92
+ - 拡張子を`yaml`にしておく必要があります。
93
+
94
+ - cloudforecastのyamlを読み込みます。(例では`role/cloudforecast/houcho_sample.yaml`を読み込んでいます。)
95
+ - yamlを置き換えるたびに実行してください。毎回実行する必要はありません。
96
+
97
+ ```sh
98
+ $ houcho cfrole configure
99
+ $ houcho cfrole show
100
+ houcho::author::studio3104
101
+ $ houcho cfrole details houcho::author::studio3104
102
+ [host(s)]
103
+ studio3104.test
104
+ studio3105.test
105
+ studio3106.test
106
+ studio3107.test
107
+ studio3108.test
108
+ studio3109.test
109
+ studio3110.test
110
+ ```
111
+
112
+ - cloudforecastから読み込んだroleを、定義済みのオリジナルroleにattachします。
113
+ - TODO: 複数指定出来るようにする。
114
+
115
+ ```sh
116
+ $ houcho cfrole attach houcho::author::studio3104 studio3104::www
117
+ $ houcho role details studio3104::www
118
+ studio3104::www
119
+
120
+ [host]
121
+ ├─ www01.studio3104.com
122
+ └─ www02.studio3104.com
123
+
124
+ [spec]
125
+ └─ houcho_sample
126
+
127
+ [cloudforecast's]
128
+ houcho::author::studio3104
129
+ [host]
130
+ ├─ studio3104.test
131
+ ├─ studio3105.test
132
+ ├─ studio3106.test
133
+ ├─ studio3107.test
134
+ ├─ studio3108.test
135
+ ├─ studio3109.test
136
+ └─ studio3110.test
137
+ ```
138
+
139
+ ## Applied Usage
140
+ - specを修正したときに、該当のspecが関連付けられているホストを適当にサンプリングして実行する。
141
+ - 複数指定可能。
142
+ - `--sample-host-count`でサンプル数を指定。(default: 5)
143
+ - simple usageと同じように、作業ディレクトリの`spec/`からの相対パスで、`_spec.rb`を除いて指定します。
144
+
145
+ ```sh
146
+ $ houcho spec check houcho_sample hogehogechan
147
+ 7 examples, 7 failures studio3109.test, spec/houcho_sample_spec.rb
148
+ 7 examples, 7 failures studio3110.test, spec/houcho_sample_spec.rb
149
+ 7 examples, 7 failures www02.studio3104.com, spec/houcho_sample_spec.rb
150
+ 7 examples, 7 failures studio3105.test, spec/houcho_sample_spec.rb
151
+ 7 examples, 7 failures studio3104.test, spec/houcho_sample_spec.rb
152
+ hogehogechan has not attached to any roles
153
+ ```
154
+
155
+ - cloudforecastのroleに含まれている一部のホストを実行対象から外す。
156
+
157
+ ```sh
158
+ $ houcho host ignore studio3109.test
159
+ $ houcho role details studio3104::www
160
+ studio3104::www
161
+
162
+ [host]
163
+ ├─ www01.studio3104.com
164
+ └─ www02.studio3104.com
165
+
166
+ [spec]
167
+ └─ houcho_sample
168
+
169
+ [cloudforecast's]
170
+ houcho::author::studio3104
171
+ [host]
172
+ ├─ <ignored>studio3109.test</ignored>
173
+ ├─ studio3104.test
174
+ ├─ studio3105.test
175
+ ├─ studio3106.test
176
+ ├─ studio3107.test
177
+ ├─ studio3108.test
178
+ └─ studio3110.test
179
+ ```
180
+
181
+ ## TODO
182
+ - testがない
183
+ - attach|detachの引数を複数取れるようにする
184
+ - host ignore|disignoreはなにやら変なので他のやりかた考える
185
+ - 引数を複数取れるようにもする
186
+ - disignoreって英語として変
187
+ - include|excludeにすれば実装はそのままでいいかな・・・
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ app_dir = File.expand_path("#{File.dirname(__FILE__)}/..")
5
+ require 'rubygems'
6
+ require 'thor'
7
+ require app_dir + '/lib/Conductor'
8
+
9
+ def conduct
10
+ Conductor.new
11
+ end
12
+
13
+ class Thor::MyHelper < Thor
14
+ class_option :help, :type => :boolean, :aliases => '-h', :desc => 'Help message.'
15
+
16
+ no_tasks do
17
+ def invoke_task(task, *args)
18
+ if options[:help] && task.name != 'help'
19
+ self.class.task_help(shell, task.name)
20
+ else
21
+ super
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.banner(task, namespace = false, subcommand = true)
27
+ super
28
+ end
29
+ end
30
+
31
+
32
+ class Spec < Thor::MyHelper
33
+ namespace :spec
34
+
35
+ desc 'details [spec]', 'show details about a spec'
36
+ def details(spec)
37
+ conduct.show_spec_details(spec)
38
+ end
39
+
40
+ desc 'show', 'show all of specs'
41
+ def show
42
+ conduct.show_all_specs
43
+ end
44
+
45
+ desc 'attach [spec] [role]', 'attach a spec to a role'
46
+ def attach(spec, role)
47
+ conduct.attach_spec_to_role(spec, role)
48
+ end
49
+
50
+ desc 'detach [spec] [role]', 'detach a spec from a role'
51
+ def detach(spec, role)
52
+ conduct.detach_spec_from_role(spec, role)
53
+ end
54
+
55
+ desc 'check [options]', '指定specを、関連付けられているhostを適当に選んで実行させる'
56
+ option :sample_host_count, :type => :numeric, :default => 5, :desc => 'サンプルホスト数'
57
+ def check(*args)
58
+ if args.empty?
59
+ self.class.task_help(shell, __method__)
60
+ exit
61
+ end
62
+ conduct.check_specs(options[:sample_host_count], args)
63
+ end
64
+
65
+ desc 'exec [options]', 'run serverspec'
66
+ option :hosts, :type => :array, :desc => 'hosts that run specs (required: --specs)'
67
+ option :specs, :type => :array, :desc => 'run specs (requied: --hosts)'
68
+ option :roles, :type => :array, :desc => 'runspecs by role'
69
+ option :ukigumo, :type => :boolean, :desc => 'post results to UkigumoServer'
70
+ option :ikachan, :type => :boolean, :desc => 'post fail results to Ikachan'
71
+ option :dry_run, :type => :boolean, :desc => 'show commands that may exexute'
72
+ def exec
73
+ hosts, specs, roles =
74
+ (options[:hosts]||[]), (options[:specs]||[]), (options[:roles]||[])
75
+
76
+ if (hosts + specs + roles).empty? || (hosts.empty? && ! specs.empty?) || (! hosts.empty? && specs.empty?)
77
+ self.class.task_help(shell, __method__)
78
+ exit
79
+ end
80
+
81
+ conduct.runspec_prepare(
82
+ roles, hosts, specs,
83
+ {
84
+ ukigumo: options[:ukigumo],
85
+ ikachan: options[:ikachan],
86
+ },
87
+ options[:dry_run],
88
+ )
89
+ end
90
+ end
91
+
92
+
93
+ class Host < Thor::MyHelper
94
+ namespace :host
95
+
96
+ desc 'details [host]', 'show details about a host'
97
+ def details(host)
98
+ conduct.show_host_details(host)
99
+ end
100
+
101
+ desc 'show', 'show all of hosts'
102
+ def show
103
+ conduct.show_all_hosts
104
+ end
105
+
106
+ desc 'attach [host] [role]', 'attach a host to a role'
107
+ def attach(host, role)
108
+ conduct.attach_host_to_role(host, role)
109
+ end
110
+
111
+ desc 'detach [host] [role]', 'detach a host from a role'
112
+ def detach(host, role)
113
+ conduct.detach_host_from_role(host, role)
114
+ end
115
+
116
+ desc "ignore [host]", "add host to ignore list"
117
+ def ignore(host)
118
+ conduct.ignore_host(host)
119
+ end
120
+
121
+ desc "disignore [host]", "delete host from ignore list"
122
+ def disignore(host)
123
+ conduct.disignore_host(host)
124
+ end
125
+ end
126
+
127
+
128
+ class Role < Thor::MyHelper
129
+ namespace :role
130
+
131
+ desc 'create [role]', 'cretate a role'
132
+ def create(role)
133
+ conduct.create_role(role)
134
+ end
135
+
136
+ desc 'delete [role]', 'delete a role'
137
+ def delete(role)
138
+ conduct.delete_role(role)
139
+ end
140
+
141
+ desc 'rename [exist role] [name]', 'rename a role'
142
+ def rename(role, rename)
143
+ conduct.rename_role(role, rename)
144
+ end
145
+
146
+ desc 'details [role]', 'show details about a role'
147
+ def details(role)
148
+ conduct.show_role_details(role)
149
+ end
150
+
151
+ desc 'show', 'show all of roles'
152
+ def show
153
+ conduct.show_all_roles
154
+ end
155
+ end
156
+
157
+
158
+ class CloudForecast < Thor::MyHelper
159
+ namespace :cfrole
160
+
161
+ desc "details [cfrole]", "show details about a cf's role"
162
+ def details(cf_role)
163
+ conduct.show_cf_role_details(cf_role)
164
+ end
165
+
166
+ desc 'show', "show all of cf's roles"
167
+ def show
168
+ conduct.show_all_cf_roles
169
+ end
170
+
171
+ desc 'attach [cfrole] [role]', 'attach a cf role to a role'
172
+ def attach(cf_role, role)
173
+ conduct.attach_cfrole_to_role(cf_role, role)
174
+ end
175
+
176
+ desc 'detach [cfrole] [role]', 'detach a cf role from a role'
177
+ def detach(cf_role, role)
178
+ conduct.detach_cfrole_from_role(cf_role, role)
179
+ end
180
+
181
+ desc 'configure', '(re)loading yamls of cloudforecast'
182
+ def configure
183
+ conduct.configure_houcho
184
+ end
185
+
186
+ end
187
+
188
+
189
+ class Runlist < Thor::MyHelper
190
+ namespace :runlist
191
+
192
+ desc 'create [runlist]', 'cretate a runlist'
193
+ def create(runlist)
194
+ conduct.create_runlist(runlist)
195
+ end
196
+
197
+ desc 'delete [runlist]', 'delete a runlist'
198
+ def delete(runlist)
199
+ conduct.delete_runlist(runlist)
200
+ end
201
+
202
+ desc 'include [role] [runlist]', 'include a role among a runlist'
203
+ def include(role, runlist)
204
+ conduct.include_role_among_runlist(role, runlist)
205
+ end
206
+
207
+ desc 'exclude [role] [runlist]', 'exclude a role from a runlist'
208
+ def exclude(role, runlist)
209
+ conduct.exclude_role_from_runlist(role, runlist)
210
+ end
211
+
212
+ desc 'rename [exist runlist] [name]', 'rename a runlist'
213
+ def rename(runlist, rename)
214
+ conduct.rename_runlist(runlist, rename)
215
+ end
216
+
217
+ desc 'details [runlist]', 'show details about a runlist'
218
+ def details(runlist)
219
+ conduct.show_runlist_details(runlist)
220
+ end
221
+
222
+ desc 'show', 'show all of runlists'
223
+ def show
224
+ conduct.show_all_runlists
225
+ end
226
+ end
227
+
228
+
229
+ class Houcho < Thor
230
+ register(CloudForecast, 'cfrole', 'cfrole [attach|detach|show|details|configure]', 'cloudforecastをのyamlから情報を読み込んで操作します')
231
+ register(Role, 'role', 'role [create|delete|rename|details|show]', 'roleを追加したり情報を表示したり')
232
+ register(Host, 'host', 'host [attach|detach|show|details|ignore|disignore]', 'hostを追加したり情報を表示したり')
233
+ register(Spec, 'spec', 'spec [attach|detach|show|details|exec|check]', 'specを追加したり情報を表示したり')
234
+
235
+ class_option :help, :type => :boolean, :aliases => '-h', :desc => 'Help message.'
236
+ no_tasks do
237
+ def invoke_task(task, *args)
238
+ if options[:help] && ! %w{role host spec exec cf help}.include?(task.name)
239
+ Houcho.task_help(shell, task.name)
240
+ else
241
+ super
242
+ end
243
+ end
244
+ end
245
+
246
+ desc 'init', 'set houcho repository on current directory'
247
+ def init
248
+ conduct.initialize_houcho
249
+ end
250
+
251
+ end
252
+
253
+ Houcho.start
254
+ exit! if $fail_runspec