etsy-deployinator 1.0.1
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 +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +368 -0
- data/Rakefile +16 -0
- data/bin/deployinator-tailer.rb +78 -0
- data/deployinator.gemspec +31 -0
- data/lib/deployinator.rb +114 -0
- data/lib/deployinator/app.rb +204 -0
- data/lib/deployinator/base.rb +58 -0
- data/lib/deployinator/config.rb +7 -0
- data/lib/deployinator/controller.rb +147 -0
- data/lib/deployinator/helpers.rb +610 -0
- data/lib/deployinator/helpers/deploy.rb +68 -0
- data/lib/deployinator/helpers/dsh.rb +42 -0
- data/lib/deployinator/helpers/git.rb +348 -0
- data/lib/deployinator/helpers/plugin.rb +50 -0
- data/lib/deployinator/helpers/stack-tail.rb +32 -0
- data/lib/deployinator/helpers/version.rb +62 -0
- data/lib/deployinator/helpers/view.rb +67 -0
- data/lib/deployinator/logging.rb +16 -0
- data/lib/deployinator/plugin.rb +7 -0
- data/lib/deployinator/stack-tail.rb +34 -0
- data/lib/deployinator/static/css/diff_style.css +283 -0
- data/lib/deployinator/static/css/highlight.css +235 -0
- data/lib/deployinator/static/css/style.css +1223 -0
- data/lib/deployinator/static/js/flot/jquery.flot.min.js +1 -0
- data/lib/deployinator/static/js/flot/jquery.flot.selection.js +299 -0
- data/lib/deployinator/static/js/jquery-1.8.3.min.js +2 -0
- data/lib/deployinator/static/js/jquery-ui-1.8.24.min.js +5 -0
- data/lib/deployinator/static/js/jquery.timed_bar.js +36 -0
- data/lib/deployinator/tasks/initialize.rake +84 -0
- data/lib/deployinator/tasks/tests.rake +22 -0
- data/lib/deployinator/templates/deploys_status.mustache +42 -0
- data/lib/deployinator/templates/generic_single_push.mustache +64 -0
- data/lib/deployinator/templates/index.mustache +12 -0
- data/lib/deployinator/templates/layout.mustache +604 -0
- data/lib/deployinator/templates/log.mustache +24 -0
- data/lib/deployinator/templates/log_table.mustache +90 -0
- data/lib/deployinator/templates/messageboxes.mustache +29 -0
- data/lib/deployinator/templates/run_logs.mustache +15 -0
- data/lib/deployinator/templates/scroll_control.mustache +8 -0
- data/lib/deployinator/templates/stream.mustache +13 -0
- data/lib/deployinator/version.rb +3 -0
- data/lib/deployinator/views/deploys_status.rb +22 -0
- data/lib/deployinator/views/index.rb +14 -0
- data/lib/deployinator/views/layout.rb +48 -0
- data/lib/deployinator/views/log.rb +12 -0
- data/lib/deployinator/views/log_table.rb +35 -0
- data/lib/deployinator/views/run_logs.rb +32 -0
- data/templates/app.rb.erb +7 -0
- data/templates/config.ru.erb +10 -0
- data/templates/helper.rb.erb +15 -0
- data/templates/stack.rb.erb +17 -0
- data/templates/template.mustache +1 -0
- data/templates/view.rb.erb +7 -0
- data/test/unit/helpers_dsh_test.rb +40 -0
- data/test/unit/helpers_test.rb +77 -0
- data/test/unit/version_test.rb +104 -0
- metadata +245 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
<ol id="log">
|
2
|
+
{{# log_lines }}
|
3
|
+
<li class="{{env}} {{stack}} {{is_prod}}">
|
4
|
+
{{stack}} –
|
5
|
+
<span title="{{time}}" data-timestamp="{{time_secs}}" class="timestamp">{{timestamp}}</span> |
|
6
|
+
<span class="env">{{env}}</span> |
|
7
|
+
{{who}} |
|
8
|
+
{{{msg}}}
|
9
|
+
{{# run_log_url}}
|
10
|
+
<a href="/run_logs/view/{{run_log_url}}">run log</a>
|
11
|
+
{{/ run_log_url}}
|
12
|
+
{{# new}} |
|
13
|
+
{{# diff_url}}
|
14
|
+
<a href="/{{diff_method}}/{{stack}}/{{old}}/{{new}}?time={{time_secs}}" target="_blank">diff</a>
|
15
|
+
{{/ diff_url}}
|
16
|
+
|
17
|
+
{{# dashboards_host }}
|
18
|
+
<a href="http://{{ dashboards_host }}/deploy.php?m=1&time={{ from_timestamp }}&until={{ until_timestamp }}&error_log=_all" target="_blank">dashboard</a>
|
19
|
+
{{/ dashboards_host }}
|
20
|
+
|
21
|
+
{{/ new}}
|
22
|
+
</li>
|
23
|
+
{{/ log_lines }}
|
24
|
+
</ol>
|
@@ -0,0 +1,90 @@
|
|
1
|
+
<table id="log">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th>
|
5
|
+
{{# prev_page }}
|
6
|
+
<a href="?page={{prev_page}}">prev</a>
|
7
|
+
{{/ prev_page }}
|
8
|
+
</th>
|
9
|
+
<th></th>
|
10
|
+
<th></th>
|
11
|
+
<th></th>
|
12
|
+
<th></th>
|
13
|
+
<th></th>
|
14
|
+
<th></th>
|
15
|
+
<th>
|
16
|
+
<a href="?page={{next_page}}">next</a>
|
17
|
+
</th>
|
18
|
+
</tr>
|
19
|
+
<tr>
|
20
|
+
<th>Stack</th>
|
21
|
+
<th>When (UTC)</th>
|
22
|
+
<th>Info</th>
|
23
|
+
<th>Who</th>
|
24
|
+
<th>Message</th>
|
25
|
+
<th>Run Log</th>
|
26
|
+
<th>Diff</th>
|
27
|
+
{{# dashboards? }}
|
28
|
+
<th>Dashboard</th>
|
29
|
+
{{/ dashboards? }}
|
30
|
+
{{# show_counts? }}
|
31
|
+
<th>+/-</th>
|
32
|
+
{{/ show_counts? }}
|
33
|
+
</tr>
|
34
|
+
</thead>
|
35
|
+
<tbody>
|
36
|
+
{{# log_lines }}
|
37
|
+
<tr class="{{env}} {{is_prod}}">
|
38
|
+
<td>{{stack}}</td>
|
39
|
+
<td><span title="{{timestamp}}" class="timestamp" data-timestamp="{{time_secs}}">{{time}}</span></td>
|
40
|
+
<td>{{env}}</td>
|
41
|
+
<td>{{who}}</td>
|
42
|
+
<td>{{{msg}}}</td>
|
43
|
+
<td>
|
44
|
+
{{# run_log_url }}
|
45
|
+
<a href="/run_logs/view/{{run_log_url}}">run log</a>
|
46
|
+
{{/ run_log_url }}
|
47
|
+
</td>
|
48
|
+
<td>
|
49
|
+
{{# new}}
|
50
|
+
<a href="/{{diff_method}}/{{stack}}/{{old}}/{{new}}" target="_blank">diff</a>
|
51
|
+
{{/ new}}
|
52
|
+
</td>
|
53
|
+
{{# dashboards? }}
|
54
|
+
<td>
|
55
|
+
<a href="http://{{ dashboards_host }}/deploy.php?m=1&time={{ from_timestamp }}&until={{ until_timestamp }}&error_log=_all" target="_blank">dashboard</a>
|
56
|
+
</td>
|
57
|
+
{{/ dashboards? }}
|
58
|
+
{{# show_counts? }}
|
59
|
+
<td>
|
60
|
+
{{counts}}
|
61
|
+
</td>
|
62
|
+
{{/ show_counts? }}
|
63
|
+
</tr>
|
64
|
+
{{/ log_lines }}
|
65
|
+
|
66
|
+
<tr>
|
67
|
+
<th>
|
68
|
+
{{# prev_page }}
|
69
|
+
<form action="/log">
|
70
|
+
<input type="hidden" name="page" value="{{prev_page}}" />
|
71
|
+
<button class="button small">Prev</button>
|
72
|
+
</form>
|
73
|
+
{{/ prev_page }}
|
74
|
+
</th>
|
75
|
+
<th></th>
|
76
|
+
<th></th>
|
77
|
+
<th></th>
|
78
|
+
<th></th>
|
79
|
+
<th></th>
|
80
|
+
<th>
|
81
|
+
<form action="/log">
|
82
|
+
<input type="hidden" name="page" value="{{next_page}}" />
|
83
|
+
<button class="button small">Next</button>
|
84
|
+
</form>
|
85
|
+
|
86
|
+
</th>
|
87
|
+
</tr>
|
88
|
+
|
89
|
+
</tbody>
|
90
|
+
</table>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<div id="error_report" class="display-panel">
|
2
|
+
<h1>Error Log</h1>
|
3
|
+
</div>
|
4
|
+
<div id="warning_report" class="display-panel">
|
5
|
+
<h1>Warnings</h1>
|
6
|
+
</div>
|
7
|
+
<div id="info_msg_report" class="display-panel">
|
8
|
+
<h1>Information Log</h1>
|
9
|
+
{{# disabled_override }}
|
10
|
+
<h3>You have chosen to override version checking. Hic sunt dracones.</h3>
|
11
|
+
<p> Stuff known not to work properly without a valid version rev:
|
12
|
+
<ul style="list-style-position: inside">
|
13
|
+
<li> Diff URLs </li>
|
14
|
+
<li> Jenkins build notifications </li>
|
15
|
+
</ul>
|
16
|
+
</p>
|
17
|
+
<script>$('#info_msg_report').show();</script>
|
18
|
+
{{/ disabled_override }}
|
19
|
+
{{^ allowed_to_push_to_prod?}}
|
20
|
+
<div id="not-allowed-to-prod">
|
21
|
+
Oops, looks like you can't push to prod yet. Just ask <span class="channel">#sysops</span> or
|
22
|
+
<span class="channel">#devtools</span>
|
23
|
+
to add you to the <span class="the-group">deploy-prod</span> LDAP group.
|
24
|
+
</div>
|
25
|
+
<script>$('#info_msg_report').show();</script>
|
26
|
+
{{/ allowed_to_push_to_prod?}}
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<ul id="run-log">
|
2
|
+
{{# files}}
|
3
|
+
<li>
|
4
|
+
<span class="timestamp-normal">{{time}}</span>
|
5
|
+
<a href="/run_logs/view/{{name}}">{{name}}</a>
|
6
|
+
</li>
|
7
|
+
{{/ files}}
|
8
|
+
</ul>
|
9
|
+
|
10
|
+
{{#next_page }}
|
11
|
+
<a href="/run_logs?page={{ to_s }}">More run logs</a>
|
12
|
+
{{/next_page}}
|
13
|
+
{{^next_page}}
|
14
|
+
No more run logs
|
15
|
+
{{/next_page}}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<link rel="stylesheet" href="/static/css/style.css?v=10" type="text/css" media="screen">
|
5
|
+
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
|
6
|
+
<style type="text/css" media="screen">
|
7
|
+
body { background:#111 none repeat scroll 0 0; }
|
8
|
+
</style>
|
9
|
+
</head>
|
10
|
+
<body class='code'>
|
11
|
+
{{ yield }}
|
12
|
+
</body>
|
13
|
+
</html>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'deployinator/helpers/deploy'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Deployinator::Views
|
5
|
+
class DeploysStatus < Layout
|
6
|
+
include Deployinator::Helpers::DeployHelpers
|
7
|
+
|
8
|
+
self.template_file = "#{File.dirname(__FILE__)}/../templates/deploys_status.mustache"
|
9
|
+
|
10
|
+
def current_deploys
|
11
|
+
ret = []
|
12
|
+
JSON.parse(get_list_of_deploys.to_json).each do |deploy|
|
13
|
+
ret << { "stack" => deploy['stack'], "stage" => deploy['stage'] }
|
14
|
+
end
|
15
|
+
if (ret.length>0)
|
16
|
+
ret
|
17
|
+
else
|
18
|
+
{ "stack" => "alcohol", "stage" => "consuming" }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Deployinator::Views
|
2
|
+
class Index < Layout
|
3
|
+
|
4
|
+
self.template_file = "#{File.dirname(__FILE__)}/../templates/index.mustache"
|
5
|
+
|
6
|
+
# Public: Gets an array of stacks for use in templating the
|
7
|
+
# index page.
|
8
|
+
#
|
9
|
+
# Retuns an array of non-pinned stacks!
|
10
|
+
def get_other_stack_list
|
11
|
+
Deployinator.get_stacks
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'deployinator/helpers/git'
|
2
|
+
require 'deployinator/helpers/stack-tail'
|
3
|
+
|
4
|
+
module Deployinator
|
5
|
+
module Views
|
6
|
+
class Layout < Mustache
|
7
|
+
include Deployinator::Helpers::GitHelpers,
|
8
|
+
Deployinator::Helpers::StackTailHelpers,
|
9
|
+
Deployinator::Helpers::VersionHelpers
|
10
|
+
|
11
|
+
@@internal_partials = ["log", "log_table", "generic_single_push", "scroll_control", "messageboxes"]
|
12
|
+
|
13
|
+
self.template_file = "#{File.dirname(__FILE__)}/../templates/layout.mustache"
|
14
|
+
|
15
|
+
def self.partial(name)
|
16
|
+
if @@internal_partials.include?(name.to_s)
|
17
|
+
File.read("#{File.dirname(__FILE__)}/../templates/#{name.to_s}.mustache")
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_stack(stack)
|
24
|
+
@stack = stack
|
25
|
+
end
|
26
|
+
|
27
|
+
def disabled_override
|
28
|
+
@disabled_override
|
29
|
+
end
|
30
|
+
|
31
|
+
def additional_bottom_body_html
|
32
|
+
""
|
33
|
+
end
|
34
|
+
|
35
|
+
def additional_top_body_html
|
36
|
+
""
|
37
|
+
end
|
38
|
+
|
39
|
+
def additional_header_html
|
40
|
+
""
|
41
|
+
end
|
42
|
+
|
43
|
+
def tailer_loading_message
|
44
|
+
"Currently connecting to tailer web socket. If this message persists for a long time, please contact your administrator. If you are developing a new stack, try restarting the deployinator-tailer."
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Deployinator::Views
|
2
|
+
class Log < Layout
|
3
|
+
|
4
|
+
self.template_file = "#{File.dirname(__FILE__)}/../templates/log.mustache"
|
5
|
+
|
6
|
+
def log_lines
|
7
|
+
@params = @params.inject({}) {|p,(k,v)| p[k.intern] = v; p }
|
8
|
+
puts @params
|
9
|
+
log_to_hash({:no_limit => true}.merge(@params))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Deployinator::Views
|
2
|
+
class LogTable < Layout
|
3
|
+
|
4
|
+
self.template_file = "#{File.dirname(__FILE__)}/../templates/log_table.mustache"
|
5
|
+
|
6
|
+
def log_lines
|
7
|
+
@params = @params.inject({}) {|p,(k,v)| p[k.intern] = v; p }
|
8
|
+
# this on is called from /log
|
9
|
+
log_to_hash({:no_limit => true, :page => 1}.merge(@params))
|
10
|
+
end
|
11
|
+
|
12
|
+
def dashboards?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def show_counts?
|
17
|
+
@params[:show_counts] == "true"
|
18
|
+
end
|
19
|
+
|
20
|
+
def prev_page
|
21
|
+
return unless @params && @params[:page]
|
22
|
+
page = @params[:page].to_i
|
23
|
+
if page && page > 1
|
24
|
+
page - 1
|
25
|
+
else
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def next_page
|
31
|
+
page = @params[:page] ? @params[:page].to_i : 1
|
32
|
+
page + 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Deployinator::Views
|
2
|
+
class RunLogs < Layout
|
3
|
+
|
4
|
+
self.template_file = "#{File.dirname(__FILE__)}/../templates/run_logs.mustache"
|
5
|
+
|
6
|
+
PER_PAGE = 30
|
7
|
+
|
8
|
+
# Internal: determines what the next page number is.
|
9
|
+
#
|
10
|
+
# Returns the next page number
|
11
|
+
def next_page
|
12
|
+
page = get_page
|
13
|
+
num_run_logs = get_run_logs.count
|
14
|
+
return (page+1)*PER_PAGE < num_run_logs ? page + 1 : false
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# Internal: fetches the run_log files to be displayed in a list view
|
19
|
+
#
|
20
|
+
# Returns an array of hashes with name, time keys
|
21
|
+
def files
|
22
|
+
page = get_page
|
23
|
+
offset = PER_PAGE * page
|
24
|
+
get_run_logs(:limit => PER_PAGE, :offset => offset)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_page
|
28
|
+
@params['page'].to_i || 0
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Deployinator
|
2
|
+
module Helpers
|
3
|
+
module <%= mustache_class %>Helpers
|
4
|
+
def <%= stack %>_production_version
|
5
|
+
# %x{curl http://my-app.com/version.txt}
|
6
|
+
"1234567-abc"
|
7
|
+
end
|
8
|
+
|
9
|
+
def <%= stack %>_head_build
|
10
|
+
# %x{git ls-remote -h http://www.github.com/name/repo.git origin/master | cut -c1-8.chomp
|
11
|
+
"12345678"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'helpers/<%= stack %>'
|
2
|
+
module Deployinator
|
3
|
+
module Stacks
|
4
|
+
class <%= mustache_class %>Deploy < Deployinator::Deploy
|
5
|
+
include Deployinator::Helpers::<%= mustache_class %>Helpers
|
6
|
+
|
7
|
+
def <%= stack %>_production(options={})
|
8
|
+
old_build = environments[0][:current_build].call
|
9
|
+
|
10
|
+
log_and_stream "Fill in the <%= stack %>_production method in stacks/<%= stack %>.rb!<br>"
|
11
|
+
|
12
|
+
# log the deploy
|
13
|
+
log_and_shout :old_build => old_build, :build => environments[0][:next_build].call
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{{< generic_single_push }}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'deployinator'
|
2
|
+
require 'deployinator/helpers'
|
3
|
+
require 'deployinator/helpers/dsh'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'mocha/setup'
|
6
|
+
|
7
|
+
include Deployinator
|
8
|
+
include Deployinator::Helpers
|
9
|
+
include Deployinator::Helpers::DshHelpers
|
10
|
+
|
11
|
+
#
|
12
|
+
# Set of tests for methods in our DshHelpers Module
|
13
|
+
#
|
14
|
+
class DshHelperTest < Test::Unit::TestCase
|
15
|
+
|
16
|
+
def test_hosts_for_ignores_comments
|
17
|
+
DshHelpers.expects(:`).returns("host1\n#host2\nhost3")
|
18
|
+
assert_equal(["host1","host3"], DshHelpers.hosts_for("foo"))
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_hosts_for_ignores_comments_whitespace_before
|
22
|
+
DshHelpers.expects(:`).returns("host1\n #host2\nhost3")
|
23
|
+
assert_equal(["host1","host3"], DshHelpers.hosts_for("hoo"))
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_hosts_for
|
27
|
+
DshHelpers.expects(:`).returns("host1\nhost2\nhost3")
|
28
|
+
assert_equal(["host1","host2","host3"], DshHelpers.hosts_for("bar"))
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_host_for_raises_when_nil
|
32
|
+
DshHelpers.expects(:`).returns("")
|
33
|
+
# $? is the return value of the previous backtick command
|
34
|
+
# we are mocking it
|
35
|
+
$?.expects(:exitstatus).returns(1)
|
36
|
+
assert_raises(RuntimeError) do
|
37
|
+
DshHelpers.hosts_for("baz")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|