spurious-server 0.3.1 → 0.4.0
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/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
|