spurious-server 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/spurious-server +4 -5
- data/config/images.yaml +3 -0
- data/lib/spurious/server/app.rb +8 -3
- data/lib/spurious/server/options.rb +26 -1
- data/lib/spurious/server/state/base.rb +17 -5
- data/lib/spurious/server/state/delete.rb +34 -10
- data/lib/spurious/server/state/factory.rb +1 -4
- data/lib/spurious/server/state/init.rb +28 -35
- data/lib/spurious/server/state/ports.rb +2 -1
- data/lib/spurious/server/state/start.rb +27 -14
- data/lib/spurious/server/state/stop.rb +22 -7
- data/lib/spurious/server/version.rb +1 -1
- data/spurious-server.gemspec +1 -0
- metadata +16 -3
- data/lib/spurious/server/state/update.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7af8bff11bf2fda45cc441abe270a73dea2a3691
|
4
|
+
data.tar.gz: b2e6b3769c6d72ee57c1e56a45dccc252fa58b6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ffd92f6f4f681176d369506817aa3008bb9613d460532aa864ab212e328480e474bd9d5f412e50f0fa09e26a257fa7ee1e7052e3b646864f05bcbc3a1c89ade8
|
7
|
+
data.tar.gz: a5ba053aea4eab0ce5fb0c8fafeb1b2baaf195da3981e639db37dc8389642aab4efb6099384a7d95accca81fd5c2f5d36ef5b4a466a5414b45cafe0b1be85f82
|
data/bin/spurious-server
CHANGED
@@ -6,13 +6,12 @@ require 'spurious/server'
|
|
6
6
|
require 'spurious/server/version'
|
7
7
|
require 'daemons'
|
8
8
|
require 'eventmachine'
|
9
|
+
require 'em-synchrony'
|
9
10
|
require 'spurious/server/options'
|
10
11
|
|
11
12
|
options = Spurious::Server::Options.new(ENV)
|
13
|
+
ENV['DOCKER_HOST'] = options.ssl_docker_host
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
Daemons.run_proc('Spurious Server', :dir => '/tmp', :log_output => true) do
|
17
|
-
EventMachine.run Spurious::Server.handle(options)
|
15
|
+
Daemons.run_proc('Spurious_Server', :dir => '/tmp', :log_output => true) do
|
16
|
+
EventMachine.synchrony Spurious::Server.handle(options)
|
18
17
|
end
|
data/config/images.yaml
CHANGED
data/lib/spurious/server/app.rb
CHANGED
@@ -16,9 +16,14 @@ module Spurious
|
|
16
16
|
def receive_data data
|
17
17
|
payload = parse_payload data
|
18
18
|
state(payload[:type]).execute!
|
19
|
-
rescue
|
20
|
-
|
21
|
-
|
19
|
+
rescue Excon::Errors::Timeout, Excon::Errors::SocketError => e
|
20
|
+
error('Connection to the docker daemon has failed, please check that docker is running on the host or VM', true)
|
21
|
+
rescue StandardError => e
|
22
|
+
error(e.message, true)
|
23
|
+
end
|
24
|
+
|
25
|
+
def error(message, close = false)
|
26
|
+
send_data "#{JSON.generate({:message_type => 'error', :type => 'error', :response => message, :close => close, :colour => :red})}\n"
|
22
27
|
end
|
23
28
|
|
24
29
|
protected
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spurious
|
2
2
|
module Server
|
3
3
|
class Options
|
4
|
-
attr_reader :docker_full_path, :docker_host, :docker_port, :docker_api, :server_port, :server_ip, :write_timeout, :read_timeout
|
4
|
+
attr_reader :docker_full_path, :docker_host, :docker_port, :docker_api, :server_port, :server_ip, :write_timeout, :read_timeout, :cert_path
|
5
5
|
|
6
6
|
def initialize(env)
|
7
7
|
@docker_host = env['DOCKER_HOST'].nil? ? 'localhost' : env['DOCKER_HOST'][/\/\/([0-9a-z\.]+):/,1]
|
@@ -11,8 +11,33 @@ module Spurious
|
|
11
11
|
@server_ip = env.fetch('SPURIOUS_SERVER_IP', '0.0.0.0')
|
12
12
|
@write_timeout = env.fetch('EXCON_WRITE_TIMEOUT', 30000)
|
13
13
|
@read_timeout = env.fetch('EXCON_READ_TIMEOUT', 30000)
|
14
|
+
@cert_path = env.fetch('DOCKER_CERT_PATH', nil)
|
15
|
+
setup_ssl if @cert_path
|
14
16
|
end
|
15
17
|
|
18
|
+
def ssl_docker_host
|
19
|
+
"https://#{docker_host}:#{docker_port}"
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def setup_ssl
|
25
|
+
Docker.options = {
|
26
|
+
:client_cert => valid_cert_path?('cert.pem'),
|
27
|
+
:client_key => valid_cert_path?('key.pem'),
|
28
|
+
:ssl_ca_file => valid_cert_path?('ca.pem')
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid_cert_path?(cert)
|
33
|
+
File.join(absolute_cert_path, cert).tap do |path|
|
34
|
+
raise "Could not find: #{path}, please check it exists in your DOCKER_CERTS_PATH folder" unless File.exists? path
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def absolute_cert_path
|
39
|
+
@absolute_cert_path ||= File.expand_path cert_path
|
40
|
+
end
|
16
41
|
end
|
17
42
|
end
|
18
43
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'docker'
|
2
2
|
require 'peach'
|
3
3
|
require 'spurious/server'
|
4
|
+
require 'excon'
|
4
5
|
|
5
6
|
module Spurious
|
6
7
|
module Server
|
@@ -9,8 +10,15 @@ module Spurious
|
|
9
10
|
attr_accessor :connection, :config
|
10
11
|
|
11
12
|
def initialize(connection, config)
|
12
|
-
@connection
|
13
|
-
@config
|
13
|
+
@connection = connection
|
14
|
+
@config = config
|
15
|
+
connection_timeouts
|
16
|
+
end
|
17
|
+
|
18
|
+
def connection_timeouts(connect = 1, read = 5, write = 5)
|
19
|
+
Excon.defaults[:write_timeout] = write
|
20
|
+
Excon.defaults[:read_timeout] = read
|
21
|
+
Excon.defaults[:connect_timeout] = connect
|
14
22
|
end
|
15
23
|
|
16
24
|
def execute!
|
@@ -35,18 +43,22 @@ module Spurious
|
|
35
43
|
config.for sanitize(image)
|
36
44
|
end
|
37
45
|
|
38
|
-
def send(data, close = false)
|
39
|
-
connection.send_data "#{JSON.generate({:type => state_identifer, :response => data, :close => close})}\n"
|
46
|
+
def send(data, message_type = 'info', close = false, colour = :white)
|
47
|
+
connection.send_data "#{JSON.generate({:message_type => message_type, :type => state_identifer, :response => data, :close => close, :colour => colour})}\n"
|
40
48
|
end
|
41
49
|
|
42
50
|
def error(message, close = false)
|
43
|
-
connection.
|
51
|
+
connection.error(message, close)
|
44
52
|
end
|
45
53
|
|
46
54
|
def sanitize(name)
|
47
55
|
name.gsub('/', '')
|
48
56
|
end
|
49
57
|
|
58
|
+
def docker_available?
|
59
|
+
|
60
|
+
end
|
61
|
+
|
50
62
|
private
|
51
63
|
|
52
64
|
def state_identifer
|
@@ -7,20 +7,44 @@ module Spurious
|
|
7
7
|
module State
|
8
8
|
class Delete < Base
|
9
9
|
|
10
|
+
def initialize(connection, config)
|
11
|
+
super
|
12
|
+
connection_timeouts 2, 600, 600
|
13
|
+
end
|
14
|
+
|
10
15
|
def execute!
|
11
|
-
containers = spurious_containers.length
|
12
|
-
|
13
|
-
|
14
|
-
container.
|
15
|
-
|
16
|
-
|
16
|
+
containers = spurious_containers.length - 1
|
17
|
+
|
18
|
+
spurious_containers.each_with_index do |container, index|
|
19
|
+
container_name = container.json["Name"].gsub('/', '')
|
20
|
+
container_config = config.for(container_name)
|
21
|
+
container_meta = container.json
|
22
|
+
|
23
|
+
remove_container = Proc.new do
|
24
|
+
send "Removing #{container_name}", :debug
|
25
|
+
container.delete(:force => true)
|
26
|
+
|
27
|
+
unless container_config[:ignore] && container_config[:ignore][:delete]
|
28
|
+
image = container_config[:image]
|
29
|
+
|
30
|
+
Docker::Image.get(container_meta["Image"]).tap do |image|
|
31
|
+
image.remove(:force => true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
index_to_check = index + 1
|
36
|
+
containers == index_to_check
|
17
37
|
end
|
38
|
+
|
39
|
+
EM.defer(remove_container, operation_complete)
|
40
|
+
|
18
41
|
end
|
19
|
-
|
42
|
+
end
|
20
43
|
|
21
|
-
|
22
|
-
|
23
|
-
|
44
|
+
def operation_complete
|
45
|
+
Proc.new do |complete|
|
46
|
+
send("5 containers successfully removed", :info, true, :green) if complete
|
47
|
+
end
|
24
48
|
end
|
25
49
|
end
|
26
50
|
end
|
@@ -2,7 +2,6 @@ require 'spurious/server/state/init'
|
|
2
2
|
require 'spurious/server/state/start'
|
3
3
|
require 'spurious/server/state/stop'
|
4
4
|
require 'spurious/server/state/delete'
|
5
|
-
require 'spurious/server/state/update'
|
6
5
|
require 'spurious/server/state/ports'
|
7
6
|
require 'spurious/server/state/error'
|
8
7
|
|
@@ -11,7 +10,7 @@ module Spurious
|
|
11
10
|
module State
|
12
11
|
module Factory
|
13
12
|
|
14
|
-
def self.create(type, connection, config, options)
|
13
|
+
def self.create(type, connection, config, options = {})
|
15
14
|
case type.to_sym
|
16
15
|
when :init
|
17
16
|
Init.new(connection, config, options.docker_host)
|
@@ -23,8 +22,6 @@ module Spurious
|
|
23
22
|
Ports.new(connection, config, options.docker_host)
|
24
23
|
when :delete
|
25
24
|
Delete.new(connection, config)
|
26
|
-
when :update
|
27
|
-
Update.new(connection, config)
|
28
25
|
when :error
|
29
26
|
Error.new(connection)
|
30
27
|
else
|
@@ -7,69 +7,62 @@ module Spurious
|
|
7
7
|
module Server
|
8
8
|
module State
|
9
9
|
class Init < Base
|
10
|
-
|
11
10
|
attr_accessor :completed_containers, :docker_host
|
12
11
|
|
13
12
|
def initialize(connection, config, docker_host)
|
14
13
|
super(connection, config)
|
14
|
+
connection_timeouts 2, 600, 600
|
15
15
|
@docker_host = docker_host
|
16
16
|
end
|
17
17
|
|
18
18
|
def execute!
|
19
|
-
|
20
|
-
|
19
|
+
|
20
|
+
raise "Containers have already been initilised, please run 'spurious start'" if spurious_containers.length > 0
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
send("Pulling containers from the registry can take some time, please be patient...", :info, false, :blue)
|
25
|
+
|
26
|
+
containers = app_config.length
|
27
|
+
index = 0
|
21
28
|
|
22
29
|
app_config.each do |name, meta|
|
23
|
-
image_meta = {
|
24
|
-
|
30
|
+
image_meta = {}.tap do |h|
|
31
|
+
h['fromImage'] = meta[:image]
|
32
|
+
h['Env'] = meta[:env] unless meta[:env].nil?
|
33
|
+
end
|
25
34
|
container_cmd = []
|
26
35
|
|
27
36
|
if meta[:image] == 'smaj/spurious-s3'
|
28
37
|
container_cmd = ['-h', docker_host]
|
29
38
|
end
|
30
39
|
|
31
|
-
|
32
|
-
|
40
|
+
create_container = Proc.new do
|
33
41
|
begin
|
34
|
-
|
42
|
+
send "Creating #{name} container", :debug
|
35
43
|
Docker::Container.create("name" => name, "Image" => meta[:image], 'Cmd' => container_cmd)
|
36
|
-
rescue
|
37
|
-
|
38
|
-
|
39
|
-
this.error "Container with name: #{name} already exists"
|
40
|
-
else
|
41
|
-
this.error "Error creating container: #{e.message}"
|
42
|
-
end
|
44
|
+
rescue Docker::Error::ArgumentError, Docker::Error::NotFoundError
|
45
|
+
rescue Excon::Errors::Conflict
|
46
|
+
error "#{name} container already exists"
|
43
47
|
end
|
44
|
-
|
48
|
+
index = index + 1
|
49
|
+
operation_complete(containers == index)
|
45
50
|
end
|
46
51
|
|
47
|
-
|
48
|
-
completed_containers = completed_containers + 1
|
49
|
-
this.send("#{config.app.length} containers successfully initialized", true) if completed_containers == app_config.length
|
50
|
-
end
|
51
|
-
|
52
|
-
image_operation = Proc.new do
|
52
|
+
create_image = Proc.new do
|
53
53
|
begin
|
54
|
-
|
54
|
+
send "Pulling latest version of #{name} from registry", :debug
|
55
55
|
Docker::Image.create(image_meta)
|
56
|
-
rescue
|
57
|
-
this.error "Error pulling down image: #{e.message}"
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
image_callback = Proc.new do
|
63
|
-
EM.add_timer(1) do
|
64
|
-
EM.defer(container_operation, container_callback)
|
56
|
+
rescue Docker::Error::ArgumentError, Docker::Error::NotFoundError, Excon::Errors::Timeout, Excon::Errors::SocketError
|
65
57
|
end
|
66
58
|
end
|
67
59
|
|
68
|
-
EM.
|
69
|
-
EM.defer(image_operation, image_callback)
|
70
|
-
end
|
60
|
+
EM.defer(create_image, create_container)
|
71
61
|
end
|
62
|
+
end
|
72
63
|
|
64
|
+
def operation_complete(complete)
|
65
|
+
send("6 containers successfully initialized", :info, true, :green) if complete
|
73
66
|
end
|
74
67
|
|
75
68
|
end
|
@@ -34,11 +34,12 @@ module Spurious
|
|
34
34
|
end
|
35
35
|
|
36
36
|
end
|
37
|
-
send ports, true
|
37
|
+
send ports, :info, true
|
38
38
|
|
39
39
|
connection.unbind
|
40
40
|
rescue Exception => e
|
41
41
|
puts e.message
|
42
|
+
raise('There was a problem connecting to the Docker API (check that docker is running or if not running under linux check the VM hosting docker is running and the API is accesbile')
|
42
43
|
end
|
43
44
|
|
44
45
|
end
|
@@ -9,38 +9,51 @@ module Spurious
|
|
9
9
|
class Start < Base
|
10
10
|
attr_accessor :docker_host
|
11
11
|
|
12
|
-
def initialize(connection, config,
|
12
|
+
def initialize(connection, config, docker_host_ip)
|
13
13
|
super(connection, config)
|
14
|
-
|
14
|
+
connection_timeouts 2, 600, 600
|
15
|
+
@docker_host_ip = docker_host_ip
|
15
16
|
end
|
16
17
|
|
17
18
|
def execute!
|
19
|
+
started_containers = 0
|
20
|
+
|
21
|
+
raise "Containers haven't been initialised, please run 'spurious init' first." if spurious_containers.length == 0
|
22
|
+
|
18
23
|
spurious_containers.each do |container|
|
19
24
|
begin
|
25
|
+
started_containers = started_containers + 1
|
20
26
|
config = container_config(container.json["Name"])
|
21
|
-
send "Starting
|
22
|
-
meta = {
|
23
|
-
|
27
|
+
send "Starting #{container.json["Name"].gsub('/', '')}", :debug
|
28
|
+
meta = {}.tap do |m|
|
29
|
+
m["PublishAllPorts"] = true
|
30
|
+
m["Links"] = config[:link] unless config[:link].nil?
|
31
|
+
end
|
32
|
+
|
24
33
|
container.start meta
|
25
34
|
|
26
35
|
if container.json["Name"] == '/spurious-sqs' then
|
27
36
|
port_setup = Proc.new do
|
28
|
-
|
29
|
-
|
37
|
+
begin
|
38
|
+
port = container.json["NetworkSettings"]["Ports"]['4568/tcp'].first['HostPort']
|
39
|
+
Net::HTTP.get(URI("http://#{docker_host_ip}:#{port}/host-details?host=#{docker_host_ip}&port=#{port}"))
|
40
|
+
rescue StandardError => e
|
41
|
+
end
|
30
42
|
end
|
31
|
-
|
32
43
|
EM.add_timer(5) { EM.defer(port_setup) }
|
33
44
|
end
|
34
45
|
rescue Exception => e
|
35
|
-
|
46
|
+
started_containers = started_containers - 1
|
47
|
+
case e.message
|
48
|
+
when /304 Not Modified/
|
49
|
+
error('Container is already running...')
|
50
|
+
else
|
51
|
+
error(e.message)
|
52
|
+
end
|
36
53
|
end
|
37
54
|
end
|
38
55
|
|
39
|
-
send
|
40
|
-
|
41
|
-
connection.unbind
|
42
|
-
rescue Exception => e
|
43
|
-
puts e.message
|
56
|
+
send("Started #{started_containers} containers", :info, true, :green)
|
44
57
|
end
|
45
58
|
|
46
59
|
end
|
@@ -7,17 +7,32 @@ module Spurious
|
|
7
7
|
module State
|
8
8
|
class Stop < Base
|
9
9
|
|
10
|
+
def initialize(connection, config)
|
11
|
+
super
|
12
|
+
connection_timeouts 2, 600, 600
|
13
|
+
end
|
14
|
+
|
10
15
|
def execute!
|
11
|
-
spurious_containers.
|
12
|
-
|
13
|
-
|
16
|
+
containers = spurious_containers.length - 1
|
17
|
+
|
18
|
+
spurious_containers.each_with_index do |container, index|
|
19
|
+
stop_containers = Proc.new do
|
20
|
+
|
21
|
+
send "Stopping #{container.json["Name"].gsub('/', '')}", :debug
|
22
|
+
container.stop
|
23
|
+
index_to_check = index + 1
|
24
|
+
containers == index_to_check
|
25
|
+
end
|
26
|
+
EM.defer(stop_containers, operation_complete)
|
14
27
|
end
|
15
|
-
|
28
|
+
end
|
16
29
|
|
17
|
-
|
18
|
-
|
19
|
-
|
30
|
+
def operation_complete
|
31
|
+
Proc.new do |complete|
|
32
|
+
send("Stopped 6 containers", :info, true, :green) if complete
|
33
|
+
end
|
20
34
|
end
|
35
|
+
|
21
36
|
end
|
22
37
|
end
|
23
38
|
end
|
data/spurious-server.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rspec"
|
24
24
|
|
25
25
|
spec.add_runtime_dependency "eventmachine"
|
26
|
+
spec.add_runtime_dependency "em-synchrony"
|
26
27
|
spec.add_runtime_dependency "docker-api"
|
27
28
|
spec.add_runtime_dependency "daemons"
|
28
29
|
spec.add_runtime_dependency "peach"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spurious-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Jack
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: em-synchrony
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: docker-api
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,7 +150,6 @@ files:
|
|
136
150
|
- lib/spurious/server/state/ports.rb
|
137
151
|
- lib/spurious/server/state/start.rb
|
138
152
|
- lib/spurious/server/state/stop.rb
|
139
|
-
- lib/spurious/server/state/update.rb
|
140
153
|
- lib/spurious/server/version.rb
|
141
154
|
- spec/app_spec.rb
|
142
155
|
- spec/config_spec.rb
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'docker'
|
2
|
-
require 'peach'
|
3
|
-
require 'json'
|
4
|
-
require 'spurious/server/state/base'
|
5
|
-
|
6
|
-
module Spurious
|
7
|
-
module Server
|
8
|
-
module State
|
9
|
-
class Update < Base
|
10
|
-
|
11
|
-
def execute!
|
12
|
-
['stop', 'delete', 'init', 'up'].each do |state|
|
13
|
-
connection.receive_data(JSON.generate({:type => state}))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|