buildbox 0.0.1 → 0.0.2
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/.rspec +3 -0
- data/README.md +9 -11
- data/bin/buildbox +84 -16
- data/lib/buildbox.rb +2 -0
- data/lib/buildbox/api.rb +73 -38
- data/lib/buildbox/auth.rb +37 -0
- data/lib/buildbox/build.rb +7 -8
- data/lib/buildbox/client.rb +22 -8
- data/lib/buildbox/configuration.rb +17 -8
- data/lib/buildbox/pid_file.rb +1 -1
- data/lib/buildbox/response.rb +49 -0
- data/lib/buildbox/version.rb +1 -1
- 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: 50ef87e918e385b0169d8bc601aa29f94c6a7dbf
|
4
|
+
data.tar.gz: 8aeb7524a9a4df2b8f74fb80bcff2d6669d4b380
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c46f041eeb2929692d1f4a90d8a931cc10f9de14dab779b116737e4a2553d9d2f4159e36d71d332253269ee46a4649f6919113529d42fcb750e389c7b9e4de0
|
7
|
+
data.tar.gz: a3903b0189b3907b5ccea550ef619cb2f2ba7a40a27a5975c18c62b395c4f82493dc1ecb7cf372c60f11db344ca95cd13a79aaba01802675f57313533d1d4da2
|
data/.rspec
ADDED
data/README.md
CHANGED
@@ -1,24 +1,22 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
TODO: Write a gem description
|
1
|
+
# Buildbox
|
4
2
|
|
5
3
|
## Installation
|
6
4
|
|
7
|
-
|
5
|
+
Install the gem
|
8
6
|
|
9
|
-
gem
|
7
|
+
$ gem install buildbox
|
10
8
|
|
11
|
-
|
9
|
+
Then authenticate
|
12
10
|
|
13
|
-
$
|
11
|
+
$ buildbox auth:login [apikey]
|
14
12
|
|
15
|
-
|
13
|
+
Then you can start monitoring for builds like so:
|
16
14
|
|
17
|
-
$
|
15
|
+
$ buildbox monitor:start
|
18
16
|
|
19
|
-
|
17
|
+
For more help with the command line interface
|
20
18
|
|
21
|
-
|
19
|
+
$ buildbox --help
|
22
20
|
|
23
21
|
## Contributing
|
24
22
|
|
data/bin/buildbox
CHANGED
@@ -2,30 +2,98 @@
|
|
2
2
|
|
3
3
|
dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
4
|
$LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir)
|
5
|
-
require '
|
5
|
+
require 'buildbox'
|
6
6
|
require 'optparse'
|
7
7
|
|
8
|
-
|
8
|
+
commands = {}
|
9
|
+
options = {}
|
9
10
|
|
10
|
-
|
11
|
-
OptionParser.new do |opts|
|
12
|
-
opts.version = Trigger::VERSION
|
13
|
-
opts.banner = 'Usage: trigger command [options]'
|
11
|
+
help = <<HELP
|
14
12
|
|
15
|
-
|
16
|
-
|
13
|
+
auth # authentication (login, logout)
|
14
|
+
monitor # monitor builds (start, stop)
|
15
|
+
version # display version
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
HELP
|
18
|
+
|
19
|
+
global = OptionParser.new do |opts|
|
20
|
+
opts.version = Buildbox::VERSION
|
21
|
+
opts.banner = 'Usage: buildbox COMMAND [command-specific-actions]'
|
22
|
+
|
23
|
+
opts.separator help
|
24
|
+
end
|
25
|
+
|
26
|
+
commands['auth:login'] = OptionParser.new do |opts|
|
27
|
+
opts.banner = "Usage: buildbox auth:login API_KEY"
|
28
|
+
end
|
21
29
|
|
22
|
-
|
30
|
+
commands['auth:logout'] = OptionParser.new do |opts|
|
31
|
+
opts.banner = "Usage: buildbox auth:logout"
|
23
32
|
end
|
24
33
|
|
25
|
-
|
34
|
+
commands['monitor:start'] = OptionParser.new do |opts|
|
35
|
+
opts.banner = "Usage: buildbox monitor:start"
|
26
36
|
|
27
|
-
|
28
|
-
|
37
|
+
opts.on("-d", "--daemon", "Runs as a daemon") do
|
38
|
+
options[:daemon] = true
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on("--help", "You're looking at it.") do
|
42
|
+
puts commands['monitor:start']
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
commands['monitor:stop'] = OptionParser.new do |opts|
|
48
|
+
opts.banner = "Usage: buildbox monitor:stop"
|
49
|
+
end
|
50
|
+
|
51
|
+
commands['version'] = OptionParser.new do |opts|
|
52
|
+
opts.banner = "Usage: buildbox version"
|
53
|
+
end
|
54
|
+
|
55
|
+
global.order!
|
56
|
+
|
57
|
+
args = ARGV
|
58
|
+
|
59
|
+
if command = args.shift
|
60
|
+
if commands.has_key?(command)
|
61
|
+
commands[command].parse!
|
62
|
+
else
|
63
|
+
puts "`#{command}` is an unknown command"
|
64
|
+
exit 1
|
65
|
+
end
|
66
|
+
|
67
|
+
if command == "version"
|
68
|
+
puts Buildbox::VERSION
|
69
|
+
exit
|
70
|
+
end
|
71
|
+
|
72
|
+
if command =~ /^monitor/
|
73
|
+
client = Buildbox::Client.new(options)
|
74
|
+
if command == "monitor:start"
|
75
|
+
client.start
|
76
|
+
elsif command == "monitor:stop"
|
77
|
+
client.stop
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
if command =~ /^auth/
|
82
|
+
auth = Buildbox::Auth.new
|
83
|
+
|
84
|
+
if command == "auth:login"
|
85
|
+
api_key = args[0]
|
86
|
+
|
87
|
+
unless api_key
|
88
|
+
puts commands['auth:login']
|
89
|
+
exit
|
90
|
+
end
|
91
|
+
|
92
|
+
auth.login(:api_key => args[0])
|
93
|
+
elsif command == "auth:logout"
|
94
|
+
auth.logout
|
95
|
+
end
|
96
|
+
end
|
29
97
|
else
|
30
|
-
|
98
|
+
puts global.help
|
31
99
|
end
|
data/lib/buildbox.rb
CHANGED
data/lib/buildbox/api.rb
CHANGED
@@ -4,24 +4,39 @@ module Buildbox
|
|
4
4
|
require 'openssl'
|
5
5
|
require 'json'
|
6
6
|
|
7
|
-
def
|
8
|
-
|
7
|
+
def initialize(options)
|
8
|
+
@options = options
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
11
|
+
def crash(exception, information = {})
|
12
|
+
payload = {
|
13
|
+
:exception => exception.class.name,
|
14
|
+
:message => exception.message,
|
15
|
+
:backtrace => exception.backtrace,
|
16
|
+
:meta => {}
|
17
|
+
}
|
13
18
|
|
14
|
-
|
15
|
-
|
16
|
-
|
19
|
+
payload[:meta][:worker_uuid] = worker_uuid if worker_uuid
|
20
|
+
payload[:meta][:build_uuid] = information[:build] if information[:build]
|
21
|
+
payload[:meta][:client_version] = Buildbox::VERSION
|
17
22
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
request(:post, "crashes", :crash => payload)
|
24
|
+
end
|
25
|
+
|
26
|
+
def register(payload)
|
27
|
+
request(:post, "workers", :worker => payload)
|
28
|
+
end
|
23
29
|
|
24
|
-
|
30
|
+
def login
|
31
|
+
request(:get, "user")
|
32
|
+
end
|
33
|
+
|
34
|
+
def update(build, payload)
|
35
|
+
request(:put, "workers/#{worker_uuid}/builds/#{build.uuid}", :build => payload)
|
36
|
+
end
|
37
|
+
|
38
|
+
def builds(options = {})
|
39
|
+
request(:get, "workers/#{worker_uuid}/builds")
|
25
40
|
end
|
26
41
|
|
27
42
|
private
|
@@ -33,25 +48,31 @@ module Buildbox
|
|
33
48
|
end
|
34
49
|
end
|
35
50
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
51
|
+
def request(method, path, payload = nil)
|
52
|
+
klass = case method
|
53
|
+
when :get then Net::HTTP::Get
|
54
|
+
when :put then Net::HTTP::Put
|
55
|
+
when :post then Net::HTTP::Post
|
56
|
+
else raise "No request class defined for `#{method}`"
|
57
|
+
end
|
39
58
|
|
40
|
-
|
59
|
+
uri = URI.parse(endpoint(path))
|
60
|
+
request = klass.new(uri.request_uri)
|
41
61
|
|
42
|
-
|
43
|
-
|
62
|
+
if payload.nil?
|
63
|
+
Buildbox.logger.debug "#{method.to_s.upcase} #{uri}"
|
64
|
+
else
|
65
|
+
normalized_payload = normalize_payload(payload)
|
66
|
+
request.set_form_data normalized_payload
|
44
67
|
|
45
|
-
|
46
|
-
|
47
|
-
request = Net::HTTP::Put.new(uri.request_uri)
|
48
|
-
request.set_form_data data
|
68
|
+
Buildbox.logger.debug "#{method.to_s.upcase} #{uri} #{normalized_payload.inspect}"
|
69
|
+
end
|
49
70
|
|
50
|
-
|
71
|
+
Response.new http(uri).request(request)
|
72
|
+
end
|
51
73
|
|
52
|
-
|
53
|
-
|
54
|
-
response
|
74
|
+
def worker_uuid
|
75
|
+
Buildbox.configuration.worker_uuid
|
55
76
|
end
|
56
77
|
|
57
78
|
def endpoint(path)
|
@@ -59,22 +80,36 @@ module Buildbox
|
|
59
80
|
"#{Buildbox.configuration.endpoint}/v#{Buildbox.configuration.api_version}/#{path}"
|
60
81
|
end
|
61
82
|
|
62
|
-
|
63
|
-
|
83
|
+
# { :foo => { :bar => { :bang => "yolo" } } } => { "foo[bar][bang]" => "yolo" }
|
84
|
+
def normalize_payload(params, key=nil)
|
85
|
+
params = flatten_keys(params) if params.is_a?(Hash)
|
86
|
+
result = {}
|
87
|
+
params.each do |k,v|
|
88
|
+
case v
|
89
|
+
when Hash
|
90
|
+
result[k.to_s] = normalize_params(v)
|
91
|
+
when Array
|
92
|
+
v.each_with_index do |val,i|
|
93
|
+
result["#{k.to_s}[#{i}]"] = val.to_s
|
94
|
+
end
|
95
|
+
else
|
96
|
+
result[k.to_s] = v.to_s
|
97
|
+
end
|
98
|
+
end
|
99
|
+
result
|
64
100
|
end
|
65
101
|
|
66
|
-
def
|
67
|
-
hash.
|
68
|
-
|
69
|
-
|
70
|
-
if
|
71
|
-
|
102
|
+
def flatten_keys(hash, newhash={}, keys=nil)
|
103
|
+
hash.each do |k, v|
|
104
|
+
k = k.to_s
|
105
|
+
keys2 = keys ? keys+"[#{k}]" : k
|
106
|
+
if v.is_a?(Hash)
|
107
|
+
flatten_keys(v, newhash, keys2)
|
72
108
|
else
|
73
|
-
|
109
|
+
newhash[keys2] = v
|
74
110
|
end
|
75
|
-
|
76
|
-
target
|
77
111
|
end
|
112
|
+
newhash
|
78
113
|
end
|
79
114
|
end
|
80
115
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Buildbox
|
2
|
+
class Auth
|
3
|
+
def login(options)
|
4
|
+
if Buildbox.configuration.api_key
|
5
|
+
error "You have already authentication. To unauthenticate, run `buildbox auth:logout`"
|
6
|
+
end
|
7
|
+
|
8
|
+
key = options[:api_key]
|
9
|
+
api = Buildbox::API.new(:api_key => key)
|
10
|
+
|
11
|
+
if api.login.success?
|
12
|
+
Buildbox.configuration.update :api_key, key
|
13
|
+
info "Authentication successful"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def logout
|
18
|
+
if Buildbox.configuration.api_key.nil?
|
19
|
+
error "You are currently not logged in. To authenticate, run: `buildbox auth:login`"
|
20
|
+
end
|
21
|
+
|
22
|
+
Buildbox.configuration.update :api_key, nil
|
23
|
+
info "You have successfuly logged out"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def info(message)
|
29
|
+
Buildbox.logger.info message
|
30
|
+
end
|
31
|
+
|
32
|
+
def error(message)
|
33
|
+
Buildbox.logger.error message
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/buildbox/build.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Buildbox
|
2
2
|
class Build
|
3
|
-
attr_reader :uuid
|
3
|
+
attr_reader :uuid
|
4
4
|
|
5
5
|
def initialize(options)
|
6
|
-
@uuid
|
7
|
-
@
|
8
|
-
@commit
|
9
|
-
@
|
10
|
-
@command = options[:command] || "bundle && rspec"
|
6
|
+
@uuid = options[:uuid]
|
7
|
+
@repository = options[:repository]
|
8
|
+
@commit = options[:commit]
|
9
|
+
@command = options[:command] || "bundle && rspec"
|
11
10
|
end
|
12
11
|
|
13
12
|
def start(&block)
|
@@ -25,7 +24,7 @@ module Buildbox
|
|
25
24
|
unless build_path.exist?
|
26
25
|
build_path.mkpath
|
27
26
|
|
28
|
-
command.run! %{git clone "#{@
|
27
|
+
command.run! %{git clone "#{@repository}" .}
|
29
28
|
end
|
30
29
|
end
|
31
30
|
|
@@ -40,7 +39,7 @@ module Buildbox
|
|
40
39
|
end
|
41
40
|
|
42
41
|
def folder_name
|
43
|
-
@
|
42
|
+
@repository.gsub(/[^a-zA-Z0-9]/, '-')
|
44
43
|
end
|
45
44
|
|
46
45
|
def command
|
data/lib/buildbox/client.rb
CHANGED
@@ -10,6 +10,8 @@ module Buildbox
|
|
10
10
|
|
11
11
|
Buildbox.logger.info "Starting client..."
|
12
12
|
|
13
|
+
register_client
|
14
|
+
|
13
15
|
begin
|
14
16
|
daemonize if @options[:daemon]
|
15
17
|
pid_file.save
|
@@ -19,6 +21,8 @@ module Buildbox
|
|
19
21
|
process_build_queue
|
20
22
|
wait_for_interval
|
21
23
|
end
|
24
|
+
rescue => e
|
25
|
+
api.crash(e, :build => @build)
|
22
26
|
ensure
|
23
27
|
pid_file.delete
|
24
28
|
end
|
@@ -36,25 +40,35 @@ module Buildbox
|
|
36
40
|
if @options[:daemon]
|
37
41
|
Process.daemon
|
38
42
|
|
39
|
-
Buildbox.logger = Logger.new(Buildbox.root_path.join("
|
43
|
+
Buildbox.logger = Logger.new(Buildbox.root_path.join("buildbox.log"))
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
47
|
+
def register_client
|
48
|
+
worker_uuid = Buildbox.configuration.worker_uuid
|
49
|
+
response = api.register(:uuid => worker_uuid, :hostname => `hostname`.chomp)
|
43
50
|
|
44
|
-
|
45
|
-
|
51
|
+
Buildbox.configuration.update :worker_uuid, response.payload[:uuid]
|
52
|
+
end
|
46
53
|
|
47
|
-
|
54
|
+
def process_build_queue
|
55
|
+
scheduled = api.builds.payload.first
|
56
|
+
|
57
|
+
if scheduled
|
58
|
+
# store build in an instance variable so we can report on it in
|
59
|
+
# the event of a crash
|
60
|
+
@build = Build.new(scheduled)
|
61
|
+
Buildbox::Worker.new(@build, api).run
|
62
|
+
@build = nil
|
63
|
+
end
|
48
64
|
end
|
49
65
|
|
50
66
|
def reload_configuration
|
51
|
-
Buildbox.logger.info "Reloading configuration"
|
52
|
-
|
53
67
|
Buildbox.configuration.reload
|
54
68
|
end
|
55
69
|
|
56
70
|
def wait_for_interval
|
57
|
-
Buildbox.logger.
|
71
|
+
Buildbox.logger.debug "Sleeping for #{@interval} seconds"
|
58
72
|
|
59
73
|
sleep(@interval)
|
60
74
|
end
|
@@ -68,7 +82,7 @@ module Buildbox
|
|
68
82
|
end
|
69
83
|
|
70
84
|
def api
|
71
|
-
@api ||= Buildbox::API.new
|
85
|
+
@api ||= Buildbox::API.new(:api_key => Buildbox.configuration.api_key)
|
72
86
|
end
|
73
87
|
|
74
88
|
def pid_file
|
@@ -6,22 +6,28 @@ module Buildbox
|
|
6
6
|
|
7
7
|
require 'json'
|
8
8
|
|
9
|
+
attr_accessor :worker_uuid
|
10
|
+
attr_accessor :api_key
|
9
11
|
attr_accessor :endpoint
|
10
12
|
attr_accessor :use_ssl
|
11
13
|
attr_accessor :api_version
|
12
|
-
attr_accessor :repositories
|
13
14
|
|
14
15
|
def initialize
|
15
|
-
@use_ssl =
|
16
|
-
@endpoint = 'api.
|
16
|
+
@use_ssl = false
|
17
|
+
@endpoint = 'api.buildbox.io'
|
17
18
|
@api_version = 1
|
18
|
-
|
19
|
+
end
|
20
|
+
|
21
|
+
def update(key, value)
|
22
|
+
self.public_send("#{key}=", value)
|
23
|
+
save
|
19
24
|
end
|
20
25
|
|
21
26
|
def save
|
22
27
|
File.open(path, 'w+') do |file|
|
23
28
|
file.write(to_json)
|
24
29
|
end
|
30
|
+
Buildbox.logger.debug "Configuration saved to `#{path}`"
|
25
31
|
end
|
26
32
|
|
27
33
|
def reload
|
@@ -39,13 +45,16 @@ module Buildbox
|
|
39
45
|
private
|
40
46
|
|
41
47
|
def to_json
|
42
|
-
JSON.
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
JSON.pretty_generate(:endpoint => endpoint,
|
49
|
+
:use_ssl => use_ssl,
|
50
|
+
:api_version => api_version,
|
51
|
+
:api_key => api_key,
|
52
|
+
:worker_uuid => worker_uuid)
|
46
53
|
end
|
47
54
|
|
48
55
|
def read
|
56
|
+
Buildbox.logger.debug "Reading configuration `#{path}`"
|
57
|
+
|
49
58
|
JSON.parse(path.read)
|
50
59
|
end
|
51
60
|
|
data/lib/buildbox/pid_file.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Buildbox
|
2
|
+
class Response
|
3
|
+
attr_reader :payload
|
4
|
+
|
5
|
+
def initialize(response)
|
6
|
+
@response = response
|
7
|
+
|
8
|
+
unless success?
|
9
|
+
raise "API Error: #{@response.code} #{@response.body}"
|
10
|
+
end
|
11
|
+
|
12
|
+
if json?
|
13
|
+
json = JSON.parse(@response.body)
|
14
|
+
|
15
|
+
if json.kind_of?(Array)
|
16
|
+
@payload = json.map { |item| symbolize_keys(item) }
|
17
|
+
else
|
18
|
+
@payload = symbolize_keys(json)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def success?
|
24
|
+
@response.code.to_i == 200
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def json?
|
30
|
+
@response['content-type'] =~ /json/
|
31
|
+
end
|
32
|
+
|
33
|
+
def symbolize_keys(hash)
|
34
|
+
hash.inject({}) do |result, item|
|
35
|
+
key, value = item
|
36
|
+
new_key = case key
|
37
|
+
when String then key.to_sym
|
38
|
+
else key
|
39
|
+
end
|
40
|
+
new_value = case value
|
41
|
+
when Hash then symbolize_keys(value)
|
42
|
+
else value
|
43
|
+
end
|
44
|
+
result[new_key] = new_value
|
45
|
+
result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/buildbox/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: buildbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keith Pitt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -75,6 +75,7 @@ extensions: []
|
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
77
|
- .gitignore
|
78
|
+
- .rspec
|
78
79
|
- Gemfile
|
79
80
|
- LICENSE.txt
|
80
81
|
- README.md
|
@@ -83,11 +84,13 @@ files:
|
|
83
84
|
- buildbox-ruby.gemspec
|
84
85
|
- lib/buildbox.rb
|
85
86
|
- lib/buildbox/api.rb
|
87
|
+
- lib/buildbox/auth.rb
|
86
88
|
- lib/buildbox/build.rb
|
87
89
|
- lib/buildbox/client.rb
|
88
90
|
- lib/buildbox/command.rb
|
89
91
|
- lib/buildbox/configuration.rb
|
90
92
|
- lib/buildbox/pid_file.rb
|
93
|
+
- lib/buildbox/response.rb
|
91
94
|
- lib/buildbox/result.rb
|
92
95
|
- lib/buildbox/utf8.rb
|
93
96
|
- lib/buildbox/version.rb
|