houcho 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +38 -20
- data/lib/houcho.rb +1 -0
- data/lib/houcho/cli.rb +1 -0
- data/lib/houcho/cli/outerrole.rb +2 -0
- data/lib/houcho/config.rb +1 -11
- data/lib/houcho/outerrole/cloudforecast.rb +4 -35
- data/lib/houcho/outerrole/save.rb +50 -0
- data/lib/houcho/outerrole/yabitz.rb +82 -0
- data/lib/houcho/repository.rb +0 -1
- data/lib/houcho/spec/runner.rb +16 -15
- data/lib/houcho/version.rb +1 -1
- data/spec/houcho_spec.rb +8 -7
- data/ukigumo_failurepage.patch +88 -0
- data/ukigumo_tmpl.patch +67 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 861b8e2a9dba584c7491cae19e5b89af5d344b3e
|
4
|
+
data.tar.gz: a002ee817dac79bc4df21a13fbf13e64cea1780a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b7f5057e97c73796f3bad5989ff922896954c64bddef2124e0b80c77893ea38e3dc69504a7e9779331fe945da73ca41c4cca1be6450fc661f08df5a13db609e
|
7
|
+
data.tar.gz: 9baa6c039dd5caeecac4d9198e53979ab017cb9c0248470435aceaae02b23148c2c72df0c1056dc72029a78449e2c7bb3009a76579f5c25732b0e906e8b0c669
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Houcho
|
2
2
|
- wrapping to execute serverspec
|
3
|
-
- depends on ruby 1.9 later(recommended: 2.0 later).
|
3
|
+
- depends on ruby 1.9.3 later(recommended: 2.0.0 later).
|
4
4
|
|
5
5
|
## Install and Initialize
|
6
6
|
- install houcho from ruby gems
|
@@ -9,13 +9,14 @@
|
|
9
9
|
$ gem install houcho
|
10
10
|
```
|
11
11
|
|
12
|
-
-
|
13
|
-
-
|
12
|
+
- initialize working directory.
|
13
|
+
- set houcho repository on directory set environment variable `HOUCHO_ROOT`
|
14
|
+
- default: `/etc/houcho`
|
14
15
|
|
15
16
|
```sh
|
16
|
-
$ mkdir houcho-repo
|
17
|
-
$ cd houcho-repo
|
18
17
|
$ houcho init
|
18
|
+
$ ls /etc/houcho
|
19
|
+
houcho.conf houcho.db log outerrole script spec
|
19
20
|
```
|
20
21
|
|
21
22
|
## Simple Usage
|
@@ -82,15 +83,15 @@ $ houcho role details studio3104::www
|
|
82
83
|
## Include CloudForecast's yaml file
|
83
84
|
Houcho is able to load yaml of CloudForecast, and attach to the role defined.
|
84
85
|
|
85
|
-
- install yaml of CloudForecast to
|
86
|
+
- install yaml of CloudForecast to `${HOUCHO_ROOT}/outerrole/cloudforecast/` under working directory.
|
86
87
|
- extension have to be yaml.
|
87
88
|
|
88
89
|
- load cloudforecast's yaml.
|
89
90
|
- run each time you replace the yaml. do not need to run every time.
|
90
91
|
|
91
92
|
```sh
|
92
|
-
$ houcho
|
93
|
-
$ houcho
|
93
|
+
$ houcho outerrole load
|
94
|
+
$ houcho outerrole list
|
94
95
|
houcho::author::studio3104
|
95
96
|
$ houcho cf details houcho::author::studio3104
|
96
97
|
[houcho::author::studio3104]
|
@@ -102,7 +103,7 @@ $ houcho cf details houcho::author::studio3104
|
|
102
103
|
- attach to the original role defined, the role read from cloudforecast.
|
103
104
|
|
104
105
|
```sh
|
105
|
-
$ houcho
|
106
|
+
$ houcho outerrole attach houcho::author::studio3104 --roles studio3104::www
|
106
107
|
$ houcho role details studio3104::www
|
107
108
|
[studio3104::www]
|
108
109
|
host
|
@@ -113,25 +114,46 @@ $ houcho role details studio3104::www
|
|
113
114
|
├─ houcho_sample
|
114
115
|
└─ houcho_sample2
|
115
116
|
|
116
|
-
|
117
|
+
outer role
|
117
118
|
houcho::author::studio3104
|
118
119
|
host
|
119
120
|
├─ studio3104.test
|
120
121
|
└─ studio3105.test
|
121
122
|
```
|
123
|
+
|
124
|
+
## Setting Attribute to Role, Outer Role, Host
|
125
|
+
- houcho is able to set individual attribute.
|
126
|
+
- For example, you have a spec file like this.
|
127
|
+
|
128
|
+
```
|
129
|
+
require "spec_helper"
|
130
|
+
|
131
|
+
describe file(attr[:httpd_conf]) do
|
132
|
+
it { should contain "SSLCompression\soff" }
|
133
|
+
end
|
134
|
+
```
|
122
135
|
|
136
|
+
- set variable `attr[:httpd_conf]` to be evaluated at runtime.
|
137
|
+
|
138
|
+
```
|
139
|
+
$ houcho attr set --target role:studio3104::www --value httpd_conf:/etc/httpd/conf/httpd.conf
|
140
|
+
```
|
141
|
+
|
142
|
+
- args of `--target`'s key can specify `host`, `role`, `outerrole`
|
143
|
+
|
144
|
+
|
123
145
|
## Applied Usage
|
124
146
|
- at modified specs, run specs by sampling appropriately host.
|
125
|
-
- `--
|
147
|
+
- `--samples` can specifies the number of samples(default: 5)
|
126
148
|
- argument is able to specify exception of `_spec.rb`, and relative path from `spec/` under working directory same as simple usage.
|
127
149
|
|
128
150
|
```sh
|
129
151
|
$ houcho spec check houcho_sample hogehogechan
|
130
|
-
7 examples, 7 failures studio3109.test
|
131
|
-
7 examples, 7 failures studio3110.test
|
132
|
-
7 examples, 7 failures www02.studio3104.com
|
133
|
-
7 examples, 7 failures studio3105.test
|
134
|
-
7 examples, 7 failures studio3104.test
|
152
|
+
7 examples, 7 failures studio3109.test => houcho_sample
|
153
|
+
7 examples, 7 failures studio3110.test => houcho_sample
|
154
|
+
7 examples, 7 failures www02.studio3104.com => houcho_sample
|
155
|
+
7 examples, 7 failures studio3105.test => houcho_sample
|
156
|
+
7 examples, 7 failures studio3104.test => houcho_sample
|
135
157
|
hogehogechan has not attached to any roles
|
136
158
|
```
|
137
159
|
|
@@ -143,7 +165,3 @@ $ houcho role exec studio3104::www --exclude-hosts studio3104.test
|
|
143
165
|
|
144
166
|
## TODO
|
145
167
|
- write more tests
|
146
|
-
- `Houcho::Logger`
|
147
|
-
- LTSV
|
148
|
-
- yaml -> sqlite ?
|
149
|
-
- executable spec from relative path(current directory is any)
|
data/lib/houcho.rb
CHANGED
data/lib/houcho/cli.rb
CHANGED
data/lib/houcho/cli/outerrole.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'houcho/outerrole'
|
3
3
|
require 'houcho/outerrole/cloudforecast'
|
4
|
+
require 'houcho/outerrole/yabitz'
|
4
5
|
|
5
6
|
module Houcho
|
6
7
|
module CLI
|
@@ -47,6 +48,7 @@ module Houcho
|
|
47
48
|
desc 'load', 'load role data from outer system'
|
48
49
|
def load
|
49
50
|
Houcho::OuterRole::CloudForecast.load
|
51
|
+
Houcho::OuterRole::Yabitz.load
|
50
52
|
end
|
51
53
|
end
|
52
54
|
end
|
data/lib/houcho/config.rb
CHANGED
@@ -13,16 +13,6 @@ module Houcho
|
|
13
13
|
LOGDIR = "#{APPROOT}/log"
|
14
14
|
SPECLOG = "#{LOGDIR}/serverspec.log"
|
15
15
|
|
16
|
-
FILE = "#{
|
17
|
-
begin
|
18
|
-
conf = YAML.load_file(FILE)
|
19
|
-
rescue
|
20
|
-
end
|
21
|
-
if conf
|
22
|
-
UKIGUMO = conf["ukigumo"]
|
23
|
-
IKACHAN = conf["ikachan"]
|
24
|
-
GIT = conf["git"]
|
25
|
-
RSPEC = conf["rspec"]
|
26
|
-
end
|
16
|
+
FILE = "#{APPROOT}/houcho.conf"
|
27
17
|
end
|
28
18
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require "houcho/config"
|
2
|
-
require "houcho/
|
2
|
+
require "houcho/outerrole/save"
|
3
3
|
require "yaml"
|
4
4
|
|
5
|
+
include Houcho::OuterRole::Save
|
6
|
+
|
5
7
|
module Houcho
|
6
8
|
|
7
9
|
class OuterRole
|
@@ -16,7 +18,7 @@ class OuterRole
|
|
16
18
|
group = load_group(yaml)
|
17
19
|
cfrole = create_cf_role(yaml, group)
|
18
20
|
|
19
|
-
|
21
|
+
save_outer_role(cfrole, "CloudForecast")
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -55,39 +57,6 @@ class OuterRole
|
|
55
57
|
|
56
58
|
cfrole
|
57
59
|
end
|
58
|
-
|
59
|
-
|
60
|
-
def save_cf_role(cfrole)
|
61
|
-
db = Houcho::Database.new.handle
|
62
|
-
db.transaction do
|
63
|
-
|
64
|
-
cfrole.each do |outerrole, hosts|
|
65
|
-
begin
|
66
|
-
db.execute("INSERT INTO outerrole(name, data_source) VALUES(?,?)", outerrole, "CloudForecast")
|
67
|
-
rescue SQLite3::ConstraintException, "column name is not unique"
|
68
|
-
ensure
|
69
|
-
outerrole_id = db.execute("SELECT id FROM outerrole WHERE name = ?", outerrole).flatten.first
|
70
|
-
end
|
71
|
-
|
72
|
-
hosts.each do |host|
|
73
|
-
begin
|
74
|
-
db.execute("INSERT INTO host(name) VALUES(?)", host)
|
75
|
-
rescue SQLite3::ConstraintException, "column name is not unique"
|
76
|
-
ensure
|
77
|
-
begin
|
78
|
-
db.execute(
|
79
|
-
"INSERT INTO outerrole_host(outerrole_id, host_id) VALUES(?,?)",
|
80
|
-
outerrole_id,
|
81
|
-
db.execute("SELECT id FROM host WHERE name = ?", host).flatten.first
|
82
|
-
)
|
83
|
-
rescue SQLite3::ConstraintException, "column name is not unique"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
end #end of transaction
|
90
|
-
end
|
91
60
|
end
|
92
61
|
end
|
93
62
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "houcho/database"
|
2
|
+
|
3
|
+
module Houcho
|
4
|
+
|
5
|
+
class OuterRole
|
6
|
+
module Save
|
7
|
+
def save_outer_role(outerrole, datasource)
|
8
|
+
db = Houcho::Database.new.handle
|
9
|
+
db.transaction do
|
10
|
+
|
11
|
+
delete_ids = db.execute("SELECT id FROM outerrole WHERE data_source = ?", datasource).flatten
|
12
|
+
|
13
|
+
outerrole.each do |outerrole, hosts|
|
14
|
+
begin
|
15
|
+
db.execute("INSERT INTO outerrole(name, data_source) VALUES(?,?)", outerrole, datasource)
|
16
|
+
rescue SQLite3::ConstraintException, "column name is not unique"
|
17
|
+
ensure
|
18
|
+
outerrole_id = db.execute("SELECT id FROM outerrole WHERE name = ?", outerrole).flatten.first
|
19
|
+
end
|
20
|
+
|
21
|
+
delete_ids.delete(outerrole_id)
|
22
|
+
db.execute("DELETE FROM outerrole_host WHERE outerrole_id = ?", outerrole_id)
|
23
|
+
|
24
|
+
hosts.each do |host|
|
25
|
+
begin
|
26
|
+
db.execute("INSERT INTO host(name) VALUES(?)", host)
|
27
|
+
rescue SQLite3::ConstraintException, "column name is not unique"
|
28
|
+
ensure
|
29
|
+
begin
|
30
|
+
db.execute(
|
31
|
+
"INSERT INTO outerrole_host(outerrole_id, host_id) VALUES(?,?)",
|
32
|
+
outerrole_id,
|
33
|
+
db.execute("SELECT id FROM host WHERE name = ?", host).flatten.first
|
34
|
+
)
|
35
|
+
rescue SQLite3::ConstraintException, "column name is not unique"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
delete_ids.each do |id|
|
42
|
+
db.execute("DELETE FROM outerrole_host WHERE outerrole_id = ?", id)
|
43
|
+
end
|
44
|
+
|
45
|
+
end #end of transaction
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "houcho/config"
|
2
|
+
require "houcho/outerrole/save"
|
3
|
+
require "net/http"
|
4
|
+
require "cgi"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
include Houcho::OuterRole::Save
|
8
|
+
|
9
|
+
module Houcho
|
10
|
+
|
11
|
+
class OuterRole
|
12
|
+
class Yabitz; end
|
13
|
+
class << Yabitz
|
14
|
+
def load
|
15
|
+
begin
|
16
|
+
yabitz = YAML.load_file(Houcho::Config::FILE)["yabitz"]
|
17
|
+
rescue
|
18
|
+
end
|
19
|
+
|
20
|
+
if yabitz
|
21
|
+
yabitzrole = create_yabitz_role(yabitz["host"], yabitz["port"])
|
22
|
+
save_outer_role(yabitzrole, "Yabitz")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
private
|
28
|
+
def http_get(host, port, path, params)
|
29
|
+
Net::HTTP.get(
|
30
|
+
host,
|
31
|
+
"#{path}?".concat(
|
32
|
+
params.collect do |k,v|
|
33
|
+
"#{k}=#{CGI::escape(v.to_s)}"
|
34
|
+
end.join("&")
|
35
|
+
),
|
36
|
+
port
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def download_json(host, port)
|
41
|
+
JSON.load(
|
42
|
+
http_get(
|
43
|
+
host, port, "/ybz/search.json",
|
44
|
+
{
|
45
|
+
andor: "AND",
|
46
|
+
cond0: 0,
|
47
|
+
field0: "os",
|
48
|
+
value0: " ",
|
49
|
+
status: "IN_SERVICE",
|
50
|
+
ex_andor: "AND",
|
51
|
+
ex_cond0: 0,
|
52
|
+
ex_field0: "not_selected",
|
53
|
+
ex_value0: nil,
|
54
|
+
},
|
55
|
+
)
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_yabitz_role(host, port)
|
60
|
+
data = {}
|
61
|
+
|
62
|
+
download_json(host, port).each do |instance|
|
63
|
+
host = instance["display"]
|
64
|
+
type = instance["content"]["type"]
|
65
|
+
hw = instance["content"]["hwinfo"]
|
66
|
+
os = instance["content"]["os"]
|
67
|
+
|
68
|
+
type = type ? type.gsub(/\s+/, "") : "NOTYPEINFO"
|
69
|
+
hw = hw ? hw.gsub(/\s+/, "") : "NOHWINFO"
|
70
|
+
os = os ? os.gsub(/\s+/, "") : "NOOSINFO"
|
71
|
+
|
72
|
+
role = "#{type}::#{hw}::#{os}"
|
73
|
+
data[role] ||= []
|
74
|
+
data[role].concat([instance["display"]]).uniq
|
75
|
+
end
|
76
|
+
|
77
|
+
data
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
data/lib/houcho/repository.rb
CHANGED
@@ -19,7 +19,6 @@ module Houcho
|
|
19
19
|
"ukigumo" => { "host" => "", "port" => "" },
|
20
20
|
"ikachan" => { "host" => "", "port" => "", "channel" => [] },
|
21
21
|
"git" => { "uri" => "" },
|
22
|
-
"rspec" => [],
|
23
22
|
}.to_yaml) unless File.exist?("#{Houcho::Config::FILE}")
|
24
23
|
|
25
24
|
File.write("#{Houcho::Config::SPECDIR}/spec_helper.rb", <<EOD
|
data/lib/houcho/spec/runner.rb
CHANGED
@@ -66,13 +66,11 @@ class Spec
|
|
66
66
|
rv = {}
|
67
67
|
rv["host"] = []
|
68
68
|
rv["spec"] = []
|
69
|
-
rv["outer role"] = []
|
70
69
|
|
71
70
|
rv["spec"].concat(value["spec"]).uniq
|
72
71
|
rv["host"].concat(value["host"]).uniq if value["host"]
|
73
72
|
|
74
73
|
if value["outer role"]
|
75
|
-
rv["outer role"].concat(value["outer role"].keys).uniq
|
76
74
|
value["outer role"].each do |outerrolename, v|
|
77
75
|
rv["host"].concat(v["host"]).uniq if v["host"]
|
78
76
|
end
|
@@ -108,20 +106,23 @@ class Spec
|
|
108
106
|
attr_role = @role.get_attr(role)
|
109
107
|
attr_host = @host.get_attr(host)
|
110
108
|
attr_outerrole = {}
|
109
|
+
outerrole = []
|
110
|
+
|
111
|
+
@host.details(host).each do |h, v|
|
112
|
+
outerrole = outerrole.concat((v["outer role"] || [])).uniq
|
113
|
+
end
|
111
114
|
|
112
|
-
|
113
|
-
|
114
|
-
attr_outerrole.merge!(@outerrole.get_attr(o))
|
115
|
-
end
|
115
|
+
outerrole.each do |o|
|
116
|
+
attr_outerrole.merge!(@outerrole.get_attr(o))
|
116
117
|
end
|
117
118
|
|
118
119
|
attr = attr_role.merge(attr_outerrole)
|
119
120
|
attr = attr.merge(attr_host)
|
120
121
|
|
121
122
|
logmesg = ""
|
122
|
-
if attr != {} && attr_host == {} &&
|
123
|
-
logmsg = "might not be given the appropriate attribute value, because #{host} have no attributes and belongs to more than one outer role - #{
|
124
|
-
@logger.warn(host) {
|
123
|
+
if attr != {} && attr_host == {} && outerrole.size > 1
|
124
|
+
logmsg = "might not be given the appropriate attribute value, because #{host} have no attributes and belongs to more than one outer role - #{outerrole.join(", ")}"
|
125
|
+
@logger.warn(host) { logmsg }
|
125
126
|
logmsg += "\n"
|
126
127
|
end
|
127
128
|
|
@@ -160,24 +161,24 @@ class Spec
|
|
160
161
|
def post_result(result, role, host, spec, command, message)
|
161
162
|
result_status = result[0] == 0 ? 1 : 2
|
162
163
|
|
163
|
-
|
164
|
-
|
165
|
-
|
164
|
+
conf = YAML.load_file(Houcho::Config::FILE)
|
165
|
+
ukigumo = conf["ukigumo"]
|
166
|
+
ikachan = conf["ikachan"]
|
166
167
|
|
167
|
-
if ukigumo["host"] != "" && ukigumo["port"] != ""
|
168
|
+
if ukigumo && ukigumo["host"] != "" && ukigumo["port"] != ""
|
168
169
|
u = CI::UkigumoClient.new(ukigumo["host"], ukigumo["port"])
|
169
170
|
ukigumo_report = u.post({
|
170
171
|
:status => result_status,
|
171
172
|
:project => host.gsub(/\./, "-"),
|
172
173
|
:branch => role,
|
173
|
-
:repo =>
|
174
|
+
:repo => "_",
|
174
175
|
:revision => spec.join(", "),
|
175
176
|
:vc_log => command,
|
176
177
|
:body => ( message || "" ) + result[1],
|
177
178
|
})
|
178
179
|
end
|
179
180
|
|
180
|
-
if ikachan["host"] != "" && ikachan["port"] != "" && result_status != 1
|
181
|
+
if ikachan && ikachan["host"] != "" && ikachan["port"] != "" && result_status != 1
|
181
182
|
message = "[serverspec fail] #{host} => #{spec.join(", ")}"
|
182
183
|
message += " (#{JSON.parse(ukigumo_report)["report"]["url"]})" if ukigumo_report
|
183
184
|
|
data/lib/houcho/version.rb
CHANGED
data/spec/houcho_spec.rb
CHANGED
@@ -36,6 +36,7 @@ YAML
|
|
36
36
|
@role.create(["studio3104", "studio3105"])
|
37
37
|
|
38
38
|
Houcho::OuterRole::CloudForecast.load
|
39
|
+
Houcho::OuterRole::Yabitz.load
|
39
40
|
|
40
41
|
@host.attach("hostA", "studio3104")
|
41
42
|
@outerrole.attach("houcho::rspec::studio3104", "studio3104")
|
@@ -361,16 +362,16 @@ YAML
|
|
361
362
|
context "run role" do
|
362
363
|
it do
|
363
364
|
expect(@specrunner.execute_role("studio3104", [], true)).to eq([
|
364
|
-
"TARGET_HOST=hostA
|
365
|
-
"TARGET_HOST=test1.studio3104.com
|
366
|
-
"TARGET_HOST=test2.studio3104.com
|
365
|
+
"TARGET_HOST=hostA rspec --format documentation #{Houcho::Config::SPECDIR}/specA_spec.rb",
|
366
|
+
"TARGET_HOST=test1.studio3104.com rspec --format documentation #{Houcho::Config::SPECDIR}/specA_spec.rb",
|
367
|
+
"TARGET_HOST=test2.studio3104.com rspec --format documentation #{Houcho::Config::SPECDIR}/specA_spec.rb"
|
367
368
|
])
|
368
369
|
end
|
369
370
|
|
370
371
|
it "with exclude host" do
|
371
372
|
expect(@specrunner.execute_role("studio3104", "test1.studio3104.com", true)).to eq([
|
372
|
-
"TARGET_HOST=hostA
|
373
|
-
"TARGET_HOST=test2.studio3104.com
|
373
|
+
"TARGET_HOST=hostA rspec --format documentation #{Houcho::Config::SPECDIR}/specA_spec.rb",
|
374
|
+
"TARGET_HOST=test2.studio3104.com rspec --format documentation #{Houcho::Config::SPECDIR}/specA_spec.rb"
|
374
375
|
])
|
375
376
|
end
|
376
377
|
end
|
@@ -382,8 +383,8 @@ YAML
|
|
382
383
|
"specA",
|
383
384
|
true
|
384
385
|
)).to eq([
|
385
|
-
"TARGET_HOST=test3.studio3104.com
|
386
|
-
"TARGET_HOST=test4.studio3104.com
|
386
|
+
"TARGET_HOST=test3.studio3104.com rspec --format documentation #{Houcho::Config::SPECDIR}/specA_spec.rb",
|
387
|
+
"TARGET_HOST=test4.studio3104.com rspec --format documentation #{Houcho::Config::SPECDIR}/specA_spec.rb"
|
387
388
|
])
|
388
389
|
end
|
389
390
|
|
@@ -0,0 +1,88 @@
|
|
1
|
+
diff --git a/lib/Ukigumo/Server/Command/Report.pm b/lib/Ukigumo/Server/Command/Report.pm
|
2
|
+
index 831110c..415770a 100644
|
3
|
+
--- a/lib/Ukigumo/Server/Command/Report.pm
|
4
|
+
+++ b/lib/Ukigumo/Server/Command/Report.pm
|
5
|
+
@@ -63,6 +63,39 @@ sub recent_list {
|
6
|
+
return wantarray ? ($reports, $pager) : $reports;
|
7
|
+
}
|
8
|
+
|
9
|
+
+sub failure_list {
|
10
|
+
+ my $class = shift;
|
11
|
+
+ state $rule = Data::Validator->new(
|
12
|
+
+ limit => { isa => 'Int', default => 50 },
|
13
|
+
+ page => { isa => 'Int', default => 1 },
|
14
|
+
+ );
|
15
|
+
+ my $args = $rule->validate(@_);
|
16
|
+
+
|
17
|
+
+ my $reports = c->dbh->selectall_arrayref(
|
18
|
+
+ q{SELECT branch.project, branch.branch, report.report_id, report.revision, report.status, report.ctime
|
19
|
+
+ FROM report INNER JOIN branch ON (branch.branch_id=report.branch_id)
|
20
|
+
+ WHERE NOT report.status = 1
|
21
|
+
+ ORDER BY report_id DESC
|
22
|
+
+ LIMIT } . ($args->{limit} + 1) . " OFFSET " . $args->{limit}*($args->{page}-1),
|
23
|
+
+ { Slice => +{} },
|
24
|
+
+ );
|
25
|
+
+ my $has_next = do {
|
26
|
+
+ if (@$reports == $args->{limit}+1) {
|
27
|
+
+ pop @$reports;
|
28
|
+
+ 1;
|
29
|
+
+ } else {
|
30
|
+
+ 0;
|
31
|
+
+ }
|
32
|
+
+ };
|
33
|
+
+ my $pager = Data::Page::NoTotalEntries->new(
|
34
|
+
+ has_next => $has_next,
|
35
|
+
+ entries_per_page => $args->{limit},
|
36
|
+
+ current_page => $args->{page},
|
37
|
+
+ entries_on_this_page => @$reports,
|
38
|
+
+ );
|
39
|
+
+ return wantarray ? ($reports, $pager) : $reports;
|
40
|
+
+}
|
41
|
+
+
|
42
|
+
sub list {
|
43
|
+
my $class = shift;
|
44
|
+
state $rule = Data::Validator->new(
|
45
|
+
diff --git a/lib/Ukigumo/Server/Web/Dispatcher.pm b/lib/Ukigumo/Server/Web/Dispatcher.pm
|
46
|
+
index dbea5f7..7c0796b 100644
|
47
|
+
--- a/lib/Ukigumo/Server/Web/Dispatcher.pm
|
48
|
+
+++ b/lib/Ukigumo/Server/Web/Dispatcher.pm
|
49
|
+
@@ -70,6 +70,25 @@ get '/recent' => sub {
|
50
|
+
);
|
51
|
+
};
|
52
|
+
|
53
|
+
+get '/failure' => sub {
|
54
|
+
+ my ($c, $args) = @_;
|
55
|
+
+
|
56
|
+
+ my $page = $c->req->param('page') || 1;
|
57
|
+
+ my $limit = 50;
|
58
|
+
+
|
59
|
+
+ my ($reports, $pager) = Ukigumo::Server::Command::Report->failure_list(
|
60
|
+
+ page => $page,
|
61
|
+
+ limit => $limit,
|
62
|
+
+ );
|
63
|
+
+ return $c->render(
|
64
|
+
+ 'recent.tt' => {
|
65
|
+
+ reports => $reports,
|
66
|
+
+ pager => $pager,
|
67
|
+
+ now => time(),
|
68
|
+
+ }
|
69
|
+
+ );
|
70
|
+
+};
|
71
|
+
+
|
72
|
+
get '/project/{project}' => sub {
|
73
|
+
my ($c, $args) = @_;
|
74
|
+
|
75
|
+
diff --git a/tmpl/include/layout.tt b/tmpl/include/layout.tt
|
76
|
+
index be22ba0..78c1246 100644
|
77
|
+
--- a/tmpl/include/layout.tt
|
78
|
+
+++ b/tmpl/include/layout.tt
|
79
|
+
@@ -27,6 +27,9 @@
|
80
|
+
<li>
|
81
|
+
<a href="[% uri_for('/recent') %]">Recent</a>
|
82
|
+
</li>
|
83
|
+
+ <li>
|
84
|
+
+ <a href="[% uri_for('/failure') %]">Failure</a>
|
85
|
+
+ </li>
|
86
|
+
</ul>
|
87
|
+
</div>
|
88
|
+
</div>
|
data/ukigumo_tmpl.patch
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
diff --git a/tmpl/include/layout.tt b/tmpl/include/layout.tt
|
2
|
+
index be22ba0..911c695 100644
|
3
|
+
--- a/tmpl/include/layout.tt
|
4
|
+
+++ b/tmpl/include/layout.tt
|
5
|
+
@@ -2,7 +2,7 @@
|
6
|
+
<html>
|
7
|
+
<head>
|
8
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
9
|
+
- <title>[% IF subtitle %][% subtitle %] - [% END %][% title || l('Ukigumo') %]</title>
|
10
|
+
+ <title>[% IF subtitle %][% subtitle %] - [% END %][% title || l('Houcho') %]</title>
|
11
|
+
<meta http-equiv="Content-Style-Type" content="text/css" />
|
12
|
+
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
13
|
+
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"]]>
|
14
|
+
@@ -22,7 +22,7 @@
|
15
|
+
<div class="topbar">
|
16
|
+
<div class="topbar-inner">
|
17
|
+
<div class="container">
|
18
|
+
- <h3><a href="[% uri_for('/') %]">[% l('Ukigumo') %]</a></h3>
|
19
|
+
+ <h3><a href="[% uri_for('/') %]">[% l('Houcho') %]</a></h3>
|
20
|
+
<ul class="nav">
|
21
|
+
<li>
|
22
|
+
<a href="[% uri_for('/recent') %]">Recent</a>
|
23
|
+
diff --git a/tmpl/include/table/project.tt b/tmpl/include/table/project.tt
|
24
|
+
index 1c94b7d..7e76746 100644
|
25
|
+
--- a/tmpl/include/table/project.tt
|
26
|
+
+++ b/tmpl/include/table/project.tt
|
27
|
+
@@ -1,8 +1,8 @@
|
28
|
+
<h2><a href="[% uri_for('/project/' _ uri(project_name)) %]">[% project_name %]</a></h2>
|
29
|
+
<table>
|
30
|
+
<tr>
|
31
|
+
- <th>[% l('Branch') %]</th>
|
32
|
+
- <th>[% l('Revision') %]</th>
|
33
|
+
+ <th>[% l('Role') %]</th>
|
34
|
+
+ <th>[% l('Spec') %]</th>
|
35
|
+
<th>[% l('Status') %]</th>
|
36
|
+
<th>[% l('Date') %]</th>
|
37
|
+
</tr>
|
38
|
+
diff --git a/tmpl/recent.tt b/tmpl/recent.tt
|
39
|
+
index f856497..6a6c92c 100644
|
40
|
+
--- a/tmpl/recent.tt
|
41
|
+
+++ b/tmpl/recent.tt
|
42
|
+
@@ -9,9 +9,9 @@
|
43
|
+
|
44
|
+
<table>
|
45
|
+
<tr>
|
46
|
+
- <th>[% l('Project') %]</th>
|
47
|
+
- <th>[% l('Branch') %]</th>
|
48
|
+
- <th>[% l('Revision') %]</th>
|
49
|
+
+ <th>[% l('Host') %]</th>
|
50
|
+
+ <th>[% l('Role') %]</th>
|
51
|
+
+ <th>[% l('Spec') %]</th>
|
52
|
+
<th>[% l('Status') %]</th>
|
53
|
+
<th>[% l('Date') %]</th>
|
54
|
+
</tr>
|
55
|
+
diff --git a/tmpl/report_list.tt b/tmpl/report_list.tt
|
56
|
+
index bbdb022..0e3481a 100644
|
57
|
+
--- a/tmpl/report_list.tt
|
58
|
+
+++ b/tmpl/report_list.tt
|
59
|
+
@@ -9,7 +9,7 @@
|
60
|
+
|
61
|
+
<table>
|
62
|
+
<tr>
|
63
|
+
- <th>[% l('Revision') %]</th>
|
64
|
+
+ <th>[% l('Spec') %]</th>
|
65
|
+
<th>[% l('Status') %]</th>
|
66
|
+
<th>[% l('Date') %]</th>
|
67
|
+
</tr>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: houcho
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Satoshi SUZUKI
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -181,6 +181,7 @@ files:
|
|
181
181
|
- lib/houcho/host.rb
|
182
182
|
- lib/houcho/outerrole.rb
|
183
183
|
- lib/houcho/outerrole/cloudforecast.rb
|
184
|
+
- lib/houcho/outerrole/save.rb
|
184
185
|
- lib/houcho/outerrole/yabitz.rb
|
185
186
|
- lib/houcho/repository.rb
|
186
187
|
- lib/houcho/role.rb
|
@@ -188,6 +189,8 @@ files:
|
|
188
189
|
- lib/houcho/spec/runner.rb
|
189
190
|
- lib/houcho/version.rb
|
190
191
|
- spec/houcho_spec.rb
|
192
|
+
- ukigumo_failurepage.patch
|
193
|
+
- ukigumo_tmpl.patch
|
191
194
|
homepage: https://github.com/studio3104/houcho
|
192
195
|
licenses:
|
193
196
|
- MIT
|