houcho 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|