ops 0.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.
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +134 -0
- data/LICENSE +7 -0
- data/README.md +81 -0
- data/Rakefile +27 -0
- data/examples/rails3/.gitignore +15 -0
- data/examples/rails3/.rspec +3 -0
- data/examples/rails3/Gemfile +5 -0
- data/examples/rails3/Gemfile.lock +130 -0
- data/examples/rails3/Rakefile +13 -0
- data/examples/rails3/config/application.rb +34 -0
- data/examples/rails3/config/boot.rb +6 -0
- data/examples/rails3/config/environment.rb +5 -0
- data/examples/rails3/config/initializers/secret_token.rb +1 -0
- data/examples/rails3/config/locales/en.yml +5 -0
- data/examples/rails3/config/routes.rb +3 -0
- data/examples/rails3/config.ru +4 -0
- data/examples/rails3/public/404.html +26 -0
- data/examples/rails3/public/422.html +26 -0
- data/examples/rails3/public/500.html +25 -0
- data/examples/rails3/public/favicon.ico +0 -0
- data/examples/rails3/public/index.html +14 -0
- data/examples/rails3/public/robots.txt +5 -0
- data/examples/rails3/script/rails +6 -0
- data/examples/rails3/spec/functional/ops_routes_spec.rb +63 -0
- data/examples/rails3/spec/spec_helper.rb +5 -0
- data/examples/sample_deploys/1234/REVISION +1 -0
- data/examples/sample_deploys/1234/VERSION +1 -0
- data/examples/sample_deploys/2341/REVISION +1 -0
- data/examples/sample_deploys/2341/VERSION +1 -0
- data/examples/sample_deploys/3412/REVISION +1 -0
- data/examples/sample_deploys/3412/VERSION +1 -0
- data/examples/sample_deploys/4123/REVISION +1 -0
- data/examples/sample_deploys/4123/VERSION +1 -0
- data/examples/sinatra/.rspec +3 -0
- data/examples/sinatra/Rakefile +15 -0
- data/examples/sinatra/app.rb +14 -0
- data/examples/sinatra/config.ru +17 -0
- data/examples/sinatra/spec/functional/ops_routes_spec.rb +63 -0
- data/examples/sinatra/spec/spec_helper.rb +3 -0
- data/lib/ops/config.rb +43 -0
- data/lib/ops/heartbeat.rb +41 -0
- data/lib/ops/revision.rb +117 -0
- data/lib/ops/server/helpers.rb +44 -0
- data/lib/ops/server/views/layout.html.slim +22 -0
- data/lib/ops/server/views/version.html.slim +50 -0
- data/lib/ops/server/views/version.json.rabl +9 -0
- data/lib/ops/server.rb +45 -0
- data/lib/ops/version.rb +3 -0
- data/lib/ops.rb +14 -0
- data/ops.gemspec +25 -0
- data/spec/functional/ops_routes_spec.rb +63 -0
- data/spec/ops/config_spec.rb +0 -0
- data/spec/ops/heartbeat_spec.rb +49 -0
- data/spec/ops/revision_spec.rb +41 -0
- data/spec/ops/server_spec.rb +0 -0
- data/spec/ops/version_spec.rb +7 -0
- data/spec/ops_spec.rb +9 -0
- data/spec/spec_helper.rb +15 -0
- metadata +192 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'rack/test'
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
RSpec::Matchers.define :have_content_type do |content_type|
|
7
|
+
CONTENT_HEADER_MATCHER = /^([A-Za-z]+\/[\w\-+\.]+)(;charset=(.*))?/
|
8
|
+
|
9
|
+
chain :with_charset do |charset|
|
10
|
+
@charset = charset
|
11
|
+
end
|
12
|
+
|
13
|
+
match do |response|
|
14
|
+
_, content, _, charset = *content_type_header.match(CONTENT_HEADER_MATCHER).to_a
|
15
|
+
|
16
|
+
if @charset
|
17
|
+
@charset == charset && content == content_type
|
18
|
+
else
|
19
|
+
content == content_type
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
failure_message_for_should do |response|
|
24
|
+
if @charset
|
25
|
+
"Content type #{content_type_header.inspect} should match #{content_type.inspect} with charset #{@charset}"
|
26
|
+
else
|
27
|
+
"Content type #{content_type_header.inspect} should match #{content_type.inspect}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
failure_message_for_should_not do |model|
|
32
|
+
if @charset
|
33
|
+
"Content type #{content_type_header.inspect} should not match #{content_type.inspect} with charset #{@charset}"
|
34
|
+
else
|
35
|
+
"Content type #{content_type_header.inspect} should not match #{content_type.inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def content_type_header
|
40
|
+
last_response.headers['Content-Type']
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'routes', :type => :controller do
|
45
|
+
include Rack::Test::Methods
|
46
|
+
|
47
|
+
it 'renders a version page' do
|
48
|
+
get "/ops/version"
|
49
|
+
last_response.should be_ok
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'renders a json version page' do
|
53
|
+
get "/ops/version.json"
|
54
|
+
last_response.should be_ok
|
55
|
+
last_response.should have_content_type('application/json').with_charset('utf-8')
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'renders a heartbeat page' do
|
59
|
+
get "/ops/heartbeat"
|
60
|
+
last_response.should be_ok
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
1234567890
|
@@ -0,0 +1 @@
|
|
1
|
+
v1.0.0^{}
|
@@ -0,0 +1 @@
|
|
1
|
+
2345678901
|
@@ -0,0 +1 @@
|
|
1
|
+
v1.0.1^{}
|
@@ -0,0 +1 @@
|
|
1
|
+
3456789012
|
@@ -0,0 +1 @@
|
|
1
|
+
v1.1.1^{}
|
@@ -0,0 +1 @@
|
|
1
|
+
4567890123
|
@@ -0,0 +1 @@
|
|
1
|
+
v2.0.0^{}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) unless $LOAD_PATH.include?(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
desc "Start the demo using `rackup`"
|
7
|
+
task :start do
|
8
|
+
exec "rackup config.ru"
|
9
|
+
end
|
10
|
+
|
11
|
+
task default: [:start]
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new('test:ops') do |test|
|
14
|
+
test.pattern = "spec/functional/*_spec.rb"
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'logger'
|
3
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
|
4
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) unless $LOAD_PATH.include?(File.dirname(__FILE__))
|
5
|
+
require 'app'
|
6
|
+
require 'ops'
|
7
|
+
|
8
|
+
use Rack::ShowExceptions
|
9
|
+
|
10
|
+
Ops.setup do |config|
|
11
|
+
config.file_root = '../sample_deploys/4123'
|
12
|
+
config.environment = ENV['RACK_ENV']
|
13
|
+
end
|
14
|
+
|
15
|
+
run Rack::URLMap.new \
|
16
|
+
"/" => Demo::App.new,
|
17
|
+
"/ops" => Ops::Server.new
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'rack/test'
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
RSpec::Matchers.define :have_content_type do |content_type|
|
7
|
+
CONTENT_HEADER_MATCHER = /^([A-Za-z]+\/[\w\-+\.]+)(;charset=(.*))?/
|
8
|
+
|
9
|
+
chain :with_charset do |charset|
|
10
|
+
@charset = charset
|
11
|
+
end
|
12
|
+
|
13
|
+
match do |response|
|
14
|
+
_, content, _, charset = *content_type_header.match(CONTENT_HEADER_MATCHER).to_a
|
15
|
+
|
16
|
+
if @charset
|
17
|
+
@charset == charset && content == content_type
|
18
|
+
else
|
19
|
+
content == content_type
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
failure_message_for_should do |response|
|
24
|
+
if @charset
|
25
|
+
"Content type #{content_type_header.inspect} should match #{content_type.inspect} with charset #{@charset}"
|
26
|
+
else
|
27
|
+
"Content type #{content_type_header.inspect} should match #{content_type.inspect}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
failure_message_for_should_not do |model|
|
32
|
+
if @charset
|
33
|
+
"Content type #{content_type_header.inspect} should not match #{content_type.inspect} with charset #{@charset}"
|
34
|
+
else
|
35
|
+
"Content type #{content_type_header.inspect} should not match #{content_type.inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def content_type_header
|
40
|
+
last_response.headers['Content-Type']
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'routes', :type => :controller do
|
45
|
+
include Rack::Test::Methods
|
46
|
+
|
47
|
+
it 'renders a version page' do
|
48
|
+
get "/ops/version"
|
49
|
+
last_response.should be_ok
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'renders a json version page' do
|
53
|
+
get "/ops/version.json"
|
54
|
+
last_response.should be_ok
|
55
|
+
last_response.should have_content_type('application/json').with_charset('utf-8')
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'renders a heartbeat page' do
|
59
|
+
get "/ops/heartbeat"
|
60
|
+
last_response.should be_ok
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
data/lib/ops/config.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Ops
|
2
|
+
class Config
|
3
|
+
def initialize(data={})
|
4
|
+
@data = {}
|
5
|
+
update!(data)
|
6
|
+
end
|
7
|
+
|
8
|
+
def update!(data)
|
9
|
+
data.each do |key, value|
|
10
|
+
self[key] = value
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](key)
|
15
|
+
@data[key.to_sym]
|
16
|
+
end
|
17
|
+
|
18
|
+
def []=(key, value)
|
19
|
+
if value.class == Hash
|
20
|
+
@data[key.to_sym] = Config.new(value)
|
21
|
+
else
|
22
|
+
@data[key.to_sym] = value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(sym, *args)
|
27
|
+
if sym.to_s =~ /(.+)=$/
|
28
|
+
self[$1] = args.first
|
29
|
+
else
|
30
|
+
self[sym]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class << self
|
36
|
+
attr_accessor :config
|
37
|
+
|
38
|
+
def setup
|
39
|
+
self.config ||= Config.new
|
40
|
+
yield config
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Ops
|
2
|
+
class Heartbeat
|
3
|
+
class << self
|
4
|
+
def add(name, &block)
|
5
|
+
instance.add name, &block
|
6
|
+
end
|
7
|
+
|
8
|
+
def check(name)
|
9
|
+
instance.check(name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def instance
|
13
|
+
@singleton ||= new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def heartbeats
|
18
|
+
@heartbeats ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def add(name, &block)
|
22
|
+
heartbeats[name] = block
|
23
|
+
end
|
24
|
+
|
25
|
+
def check(name)
|
26
|
+
begin
|
27
|
+
return heartbeats[name.to_sym].call
|
28
|
+
rescue Exception => e
|
29
|
+
# print stacktrace for error raised by executing block
|
30
|
+
puts "Exception: #{e}\n#{e.backtrace[2..-1].join("\n")}" unless heartbeats[name.to_sym].nil?
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class << self
|
37
|
+
def add_heartbeat(name, &block)
|
38
|
+
Heartbeat.add name, &block
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/ops/revision.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
module Ops
|
2
|
+
class Revision
|
3
|
+
def initialize(new_headers={}, opts = Ops.config)
|
4
|
+
@file_root = opts.file_root.to_s # convert to string in case they pass us a Pathname
|
5
|
+
@environment = opts.environment
|
6
|
+
@headers = new_headers
|
7
|
+
end
|
8
|
+
|
9
|
+
def version_or_branch
|
10
|
+
@version ||= if version_file?
|
11
|
+
chomp(version_file).gsub('^{}', '')
|
12
|
+
elsif development? && `git branch` =~ /^\* (.*)$/
|
13
|
+
$1
|
14
|
+
else
|
15
|
+
'Unknown (VERSION file is missing)'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def previous_versions
|
20
|
+
@previous_versions ||= get_previous_by_time
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_previous_by_time
|
24
|
+
get_previous_versions.sort { |a, b| a[:time] <=> b[:time] }
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_previous_versions
|
28
|
+
Dir["#{path}/../*"].each_with_object([]) do |dir, array|
|
29
|
+
next if dir =~ /#{current_dir}$/
|
30
|
+
version, revision = File.join(dir, 'VERSION'), File.join(dir, 'REVISION')
|
31
|
+
array << stats_hash(version: version, revision: revision) if File.exists?(version) && File.exists?(revision)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def path
|
36
|
+
File.absolute_path file_root
|
37
|
+
end
|
38
|
+
|
39
|
+
def current_dir
|
40
|
+
file_root.split('/').last
|
41
|
+
end
|
42
|
+
|
43
|
+
def stats_hash(files)
|
44
|
+
{ version: get_version(files[:version]),
|
45
|
+
revision: get_revision(files[:revision]),
|
46
|
+
time: get_time(files[:revision]) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_version(file)
|
50
|
+
chomp(file).gsub('^{}', '')
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_revision(file)
|
54
|
+
chomp file
|
55
|
+
end
|
56
|
+
|
57
|
+
def chomp(file)
|
58
|
+
File.read(file).chomp
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_time(file)
|
62
|
+
File.stat(file).mtime
|
63
|
+
end
|
64
|
+
|
65
|
+
def file_root
|
66
|
+
@file_root
|
67
|
+
end
|
68
|
+
|
69
|
+
def environment
|
70
|
+
@environment
|
71
|
+
end
|
72
|
+
|
73
|
+
def development?
|
74
|
+
environment == 'development'
|
75
|
+
end
|
76
|
+
|
77
|
+
def version_file
|
78
|
+
@version_file ||= File.join(file_root, 'VERSION')
|
79
|
+
end
|
80
|
+
|
81
|
+
def version_file?
|
82
|
+
File.exists? version_file
|
83
|
+
end
|
84
|
+
|
85
|
+
def revision_file
|
86
|
+
@revision_file ||= File.join(file_root, 'REVISION')
|
87
|
+
end
|
88
|
+
|
89
|
+
def revision_file?
|
90
|
+
File.exists? revision_file
|
91
|
+
end
|
92
|
+
|
93
|
+
def deploy_date
|
94
|
+
@deploy_date ||= if version_file?
|
95
|
+
get_time version_file
|
96
|
+
elsif development?
|
97
|
+
'Live'
|
98
|
+
else
|
99
|
+
'Unknown (VERSION file is missing)'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def last_commit
|
104
|
+
@last_commit ||= if revision_file?
|
105
|
+
chomp revision_file
|
106
|
+
elsif development? && `git show` =~ /^commit (.*)$/
|
107
|
+
$1
|
108
|
+
else
|
109
|
+
'Unknown (REVISION file is missing)'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def headers
|
114
|
+
@headers.select{|k,v| k.match(/^[-A-Z_].*$/) }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Ops
|
2
|
+
module Helpers
|
3
|
+
def hostname
|
4
|
+
@hostname ||= `/bin/hostname` || 'Unknown'
|
5
|
+
end
|
6
|
+
|
7
|
+
def app_name
|
8
|
+
@app_name ||= begin
|
9
|
+
dirs = Dir.pwd.split('/')
|
10
|
+
if dirs.last =~ /^\d+$/
|
11
|
+
dirs[-3]
|
12
|
+
else
|
13
|
+
dirs.last
|
14
|
+
end.sub(/\.com$/, '')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def version_link(version)
|
19
|
+
github_link 'tree', version
|
20
|
+
end
|
21
|
+
|
22
|
+
def commit_link(commit)
|
23
|
+
github_link 'commit', commit
|
24
|
+
end
|
25
|
+
|
26
|
+
def github_link(resource, subresource)
|
27
|
+
"https://github.com/primedia/#{app_name}/#{resource}/#{subresource}" unless subresource =~ /^Unknown/
|
28
|
+
end
|
29
|
+
|
30
|
+
def print_detail(object, indent = 0)
|
31
|
+
output = ""
|
32
|
+
if object.kind_of? Hash
|
33
|
+
output << "{\n"
|
34
|
+
output << object.collect { |key, value|
|
35
|
+
" " * indent + " #{print_detail key} => #{print_detail value, indent+1}"
|
36
|
+
}.join(",\n") << "\n"
|
37
|
+
output << " " * indent + "}"
|
38
|
+
else
|
39
|
+
output << object.inspect
|
40
|
+
end
|
41
|
+
output
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
title= app_name
|
5
|
+
css:
|
6
|
+
td {padding: 0 5px; vertical-align: top;}
|
7
|
+
pre {margin: 0}
|
8
|
+
tr.even {background: #dddddd;}
|
9
|
+
.container {font-size: 20px; width: 1000px; padding-bottom: 100px;}
|
10
|
+
.label {float: left; width: 400px; font-weight: bold}
|
11
|
+
.spacer {clear: both; padding: 10px;}
|
12
|
+
.value {float: left; width: 500px; text-align: right;}
|
13
|
+
td {padding: 0 5px}
|
14
|
+
#previous_versions .value {clear: both; width: 1000px; text-align: left;}
|
15
|
+
#previous_versions tr.header td {font-weight: bold}
|
16
|
+
#previous_versions .value tr.even {background: #dddddd;}
|
17
|
+
#headers .value {clear: both; width: 1000px; text-align: left;}
|
18
|
+
#headers .value tr.even {background: #dddddd;}
|
19
|
+
.clear {clear: both;}
|
20
|
+
body
|
21
|
+
==yield
|
22
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
.container
|
2
|
+
.spacer
|
3
|
+
#version
|
4
|
+
.label= "#{app_name} Version"
|
5
|
+
.value
|
6
|
+
a href=version_link(@version.version_or_branch) = @version.version_or_branch
|
7
|
+
.spacer
|
8
|
+
#date
|
9
|
+
.label Date Deployed
|
10
|
+
.value= @version.deploy_date
|
11
|
+
.spacer
|
12
|
+
#commit
|
13
|
+
.label Last Commit
|
14
|
+
.value
|
15
|
+
a href=commit_link(@version.last_commit) = @version.last_commit
|
16
|
+
.spacer
|
17
|
+
#host
|
18
|
+
.label Host
|
19
|
+
.value= hostname
|
20
|
+
.spacer
|
21
|
+
#environment
|
22
|
+
.label Environment
|
23
|
+
.value= @version.environment
|
24
|
+
.spacer
|
25
|
+
#previous_versions
|
26
|
+
.label Previous Versions
|
27
|
+
.value
|
28
|
+
- unless @previous_versions.empty?
|
29
|
+
table
|
30
|
+
tr.header
|
31
|
+
td Time
|
32
|
+
td Version
|
33
|
+
td Commit
|
34
|
+
- @previous_versions.each_with_index do |version, i|
|
35
|
+
tr class=(i%2==0 ? 'even' : nil)
|
36
|
+
td= version[:time].strftime('%x %X')
|
37
|
+
td
|
38
|
+
a href=version_link(version[:version]) = version[:version]
|
39
|
+
td
|
40
|
+
a href=commit_link(version[:revision]) = version[:revision]
|
41
|
+
.spacer
|
42
|
+
#headers
|
43
|
+
.label Headers
|
44
|
+
.value
|
45
|
+
table
|
46
|
+
- @headers.sort_by{ |h| h.first }.each_with_index do |(header, value), i|
|
47
|
+
tr class=(i%2==0 ? 'even' : nil)
|
48
|
+
td= header
|
49
|
+
td= value
|
50
|
+
.clear
|
data/lib/ops/server.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/respond_to'
|
3
|
+
require 'ops/server/helpers'
|
4
|
+
require 'rabl'
|
5
|
+
require 'slim'
|
6
|
+
|
7
|
+
module Ops
|
8
|
+
class Server < Sinatra::Base
|
9
|
+
Rabl.register!
|
10
|
+
Server.register Sinatra::RespondTo
|
11
|
+
dir = File.dirname(File.expand_path(__FILE__))
|
12
|
+
set :views, "#{dir}/server/views"
|
13
|
+
Slim::Engine.set_default_options shortcut: { '#' => 'id', '.' => 'class' }
|
14
|
+
|
15
|
+
helpers Ops::Helpers
|
16
|
+
|
17
|
+
def request_headers
|
18
|
+
env.each_with_object({}) { |(k,v), headers| headers[k] = v }
|
19
|
+
end
|
20
|
+
|
21
|
+
get '/version/?' do
|
22
|
+
@version = Revision.new request_headers
|
23
|
+
@previous_versions = @version.previous_versions
|
24
|
+
@headers = @version.headers
|
25
|
+
respond_to do |wants|
|
26
|
+
wants.html { slim :version }
|
27
|
+
wants.json { render :rabl, :version, format: 'json' }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
get '/heartbeat/?' do
|
32
|
+
'OK'
|
33
|
+
end
|
34
|
+
|
35
|
+
get '/heartbeat/:name/?' do
|
36
|
+
name = params[:name]
|
37
|
+
if Heartbeat.check name
|
38
|
+
"#{name} is OK"
|
39
|
+
else
|
40
|
+
status 503
|
41
|
+
"#{name} does not have a heartbeat"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/ops/version.rb
ADDED
data/lib/ops.rb
ADDED
data/ops.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/ops/version', __FILE__)
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.authors = ["Michael Pelz-Sherman", "Colin Rymer", "Primedia Team"]
|
7
|
+
gem.email = ["mpelzsherman@gmail.com", "colin.rymer@gmail.com"]
|
8
|
+
gem.description = 'This gem provides standardized support for obtaining version and heartbeat information from Sinatra or Rails-based web applications.'
|
9
|
+
gem.summary = "Provide ops info endpoints."
|
10
|
+
gem.date = Date.today.to_s
|
11
|
+
gem.homepage = "http://github.com/primedia/ops"
|
12
|
+
gem.license = 'MIT'
|
13
|
+
gem.executables = []
|
14
|
+
gem.files = `git ls-files | grep -v myapp`.split("\n")
|
15
|
+
gem.test_files = `git ls-files -- test/*`.split("\n")
|
16
|
+
gem.name = "ops"
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
gem.version = Ops::VERSION
|
19
|
+
gem.required_ruby_version = '>= 1.9'
|
20
|
+
gem.add_dependency 'oj', '~> 1.4.5'
|
21
|
+
gem.add_dependency 'rabl', '~> 0.7.6'
|
22
|
+
gem.add_dependency 'slim', '~> 1.3.4'
|
23
|
+
gem.add_dependency 'sinatra', '~> 1.3.3'
|
24
|
+
gem.add_dependency 'sinatra-respond_to', '~> 0.8.0'
|
25
|
+
end
|