mcrain 0.1.4 → 0.2.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/.gitmodules +0 -3
- data/README.md +36 -2
- data/exe/mcrain +2 -1
- data/lib/mcrain/base.rb +29 -96
- data/lib/mcrain/client_provider.rb +32 -0
- data/lib/mcrain/container_controller.rb +64 -0
- data/lib/mcrain/mysql.rb +11 -8
- data/lib/mcrain/rabbitmq.rb +5 -2
- data/lib/mcrain/redis.rb +7 -2
- data/lib/mcrain/riak.rb +102 -90
- data/lib/mcrain/version.rb +1 -1
- data/lib/mcrain.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d07708c123940b6ae6e2fa57fd8aa76590439d36
|
4
|
+
data.tar.gz: b8ef280372ad693c31b52e8f62f38f7dba9cab80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a26b6d8f4dab3aa1a0e6b087df9a3af12dc7a0b0690551e38aa06e6252b61524b59c0a8ddd515e88037683f26a317f5f3b9c7fb26e8eb83207cc7145eb113591
|
7
|
+
data.tar.gz: f67ce63e4b1d2dcc5d6f3020b56cda0a672bbfb946abeb977d60a12da59b94c9488cb12757c2df34aea4ec0714bc77c8d64de467880c2c190327cfadb0298b1c
|
data/.gitmodules
CHANGED
data/README.md
CHANGED
@@ -3,9 +3,43 @@
|
|
3
3
|
Mcrain helps you to use docker container in test cases.
|
4
4
|
It supports redis, rabbitmq and riak (stand alone node or clustering) currently.
|
5
5
|
|
6
|
-
##
|
6
|
+
## Prerequisite
|
7
|
+
|
8
|
+
### With boot2docker
|
9
|
+
|
10
|
+
- [install docker into Mac](https://docs.docker.com/installation/mac/)
|
11
|
+
- [install docker into Windows](https://docs.docker.com/installation/windows/)
|
12
|
+
|
13
|
+
|
14
|
+
### Without boot2docker
|
15
|
+
|
16
|
+
The docker daemon must be started with tcp socket option like `-H tcp://0.0.0.0:2375`.
|
17
|
+
Because mcrain uses [Docker Remote API](https://docs.docker.com/reference/api/docker_remote_api/).
|
18
|
+
|
19
|
+
After [installing docker](https://docs.docker.com/installation/#installation),
|
20
|
+
edit the configuration file `/etc/default/docker` for Debian or Ubuntu,
|
21
|
+
or `/etc/sysconfig/docker` for CentOS.
|
22
|
+
|
23
|
+
And add tcp option to DOCKER_OPTS like this:
|
24
|
+
|
25
|
+
```
|
26
|
+
DOCKER_OPTS="-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375"
|
27
|
+
```
|
28
|
+
|
29
|
+
Then restart the docker daemon.
|
30
|
+
|
31
|
+
|
32
|
+
Set `DOCKER_HOST` environment variable for mcrain.
|
33
|
+
```
|
34
|
+
export DOCKER_HOST='tcp://127.0.0.1:2375'
|
35
|
+
```
|
36
|
+
|
37
|
+
The port num must be equal to the port of tcp option in DOCKER_OPTS.
|
38
|
+
|
39
|
+
See the following documents for more information:
|
40
|
+
- https://docs.docker.com/reference/commandline/daemon/
|
41
|
+
- https://docs.docker.com/articles/networking/
|
7
42
|
|
8
|
-
- [docker](https://docs.docker.com/installation/#installation)
|
9
43
|
|
10
44
|
## Installation
|
11
45
|
|
data/exe/mcrain
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
require "mcrain"
|
5
5
|
|
6
6
|
action, service, *args = *ARGV
|
7
|
+
verbose = ARGV.include?('-V') || ARGV.include?('--verbose')
|
7
8
|
if action.nil? || service.nil?
|
8
|
-
|
9
9
|
$stderr.puts(<<MESSAGE)
|
10
10
|
#{$PROGRAM_NAME} <action> <target> [n] [-v or --verbose]
|
11
11
|
action: start or stop
|
@@ -41,6 +41,7 @@ begin
|
|
41
41
|
end
|
42
42
|
rescue => e
|
43
43
|
$stderr.puts "\e[31m[#{e.class}] #{e.message}\e[0m"
|
44
|
+
$stderr.puts e.backtrace.join("\n ") if verbose
|
44
45
|
exit(1)
|
45
46
|
else
|
46
47
|
$stderr.puts "\e[32mOK\e[0m"
|
data/lib/mcrain/base.rb
CHANGED
@@ -6,63 +6,33 @@ require 'timeout'
|
|
6
6
|
require 'socket'
|
7
7
|
|
8
8
|
require 'logger_pipe'
|
9
|
+
require 'docker'
|
9
10
|
|
10
11
|
module Mcrain
|
11
12
|
class Base
|
13
|
+
include ContainerController
|
14
|
+
include ClientProvider
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
def server_name
|
16
|
-
@server_name ||= self.name.split(/::/).last.underscore.to_sym
|
17
|
-
end
|
18
|
-
|
19
|
-
attr_accessor :container_image, :port
|
16
|
+
def logger
|
17
|
+
Mcrain.logger
|
20
18
|
end
|
21
19
|
|
22
|
-
attr_accessor :
|
20
|
+
attr_accessor :skip_reset_after_teardown
|
23
21
|
def reset
|
24
22
|
instance_variables.each do |var|
|
25
23
|
instance_variable_set(var, nil)
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
def container_image
|
30
|
-
self.class.container_image or raise "No container_image for #{self.class.name}"
|
31
|
-
end
|
32
|
-
|
33
|
-
def container_name
|
34
|
-
"test-#{self.class.server_name}"
|
35
|
-
end
|
36
|
-
|
37
|
-
def host
|
38
|
-
@host ||= URI.parse(ENV["DOCKER_HOST"] || "tcp://localhost").host
|
39
|
-
end
|
40
|
-
|
41
|
-
def find_portno
|
42
|
-
# 未使用のポートをシステムに割り当てさせてすぐ閉じてそれを利用する
|
43
|
-
tmpserv = TCPServer.new(0)
|
44
|
-
portno = tmpserv.local_address.ip_port
|
45
|
-
tmpserv.close
|
46
|
-
portno
|
47
|
-
end
|
48
|
-
|
49
|
-
def port
|
50
|
-
@port ||= find_portno
|
51
|
-
end
|
52
|
-
|
53
|
-
def url
|
54
|
-
@url ||= "#{self.class.server_name}://#{host}:#{port}"
|
55
|
-
end
|
56
|
-
|
57
27
|
def start
|
58
|
-
|
59
|
-
run_container
|
28
|
+
setup
|
60
29
|
if block_given?
|
61
30
|
begin
|
31
|
+
wait_port
|
62
32
|
wait
|
63
33
|
return yield(self)
|
64
34
|
ensure
|
65
|
-
|
35
|
+
teardown
|
66
36
|
end
|
67
37
|
else
|
68
38
|
wait
|
@@ -70,37 +40,22 @@ module Mcrain
|
|
70
40
|
end
|
71
41
|
end
|
72
42
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
def run_container
|
80
|
-
LoggerPipe.run(logger, build_docker_command, timeout: 10)
|
81
|
-
end
|
82
|
-
|
83
|
-
def build_docker_command
|
84
|
-
"docker run #{build_docker_command_options} #{container_image}"
|
85
|
-
end
|
86
|
-
|
87
|
-
def build_docker_command_options
|
88
|
-
r = "-d -p #{port}:#{self.class.port} --name #{container_name}"
|
89
|
-
if ext = docker_extra_options
|
90
|
-
r << ext
|
43
|
+
def setup
|
44
|
+
Timeout.timeout(30) do
|
45
|
+
Boot2docker.setup_docker_options
|
46
|
+
container.start!
|
91
47
|
end
|
92
|
-
|
48
|
+
return container
|
93
49
|
end
|
94
50
|
|
95
|
-
|
96
|
-
|
51
|
+
# ポートがLISTENされるまで待つ
|
52
|
+
def wait_port
|
53
|
+
Mcrain.wait_port_opened(host, port, interval: 0.5, timeout: 30)
|
97
54
|
end
|
98
55
|
|
56
|
+
# ポートはdockerがまずLISTENしておいて、その後コンテナ内のミドルウェアが起動するので、
|
57
|
+
# 実際にそのAPIを叩いてみて例外が起きないことを確認します。
|
99
58
|
def wait
|
100
|
-
# ポートがLISTENされるまで待つ
|
101
|
-
Mcrain.wait_port_opened(host, port, interval: 0.5, timeout: 30)
|
102
|
-
# ポートはdockerがまずLISTENしておいて、その後コンテナ内のredisが起動するので、
|
103
|
-
# 実際にAPIを叩いてみて例外が起きないことを確認します。
|
104
59
|
Timeout.timeout(30) do
|
105
60
|
begin
|
106
61
|
wait_for_ready
|
@@ -116,40 +71,18 @@ module Mcrain
|
|
116
71
|
raise NotImplementedError
|
117
72
|
end
|
118
73
|
|
119
|
-
def
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
def build_client
|
124
|
-
require client_require
|
125
|
-
yield if block_given?
|
126
|
-
client_class.new(*client_init_args)
|
127
|
-
end
|
128
|
-
|
129
|
-
def client_require
|
130
|
-
raise NotImplementedError
|
131
|
-
end
|
132
|
-
|
133
|
-
def client_class
|
134
|
-
raise NotImplementedError
|
74
|
+
def teardown
|
75
|
+
stop_or_kill_and_remove
|
76
|
+
reset unless skip_reset_after_teardown
|
135
77
|
end
|
136
78
|
|
137
|
-
def
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
def stop
|
147
|
-
LoggerPipe.run(logger, "docker kill #{container_name}", timeout: 10)
|
148
|
-
reset unless skip_reset_after_stop
|
149
|
-
end
|
150
|
-
|
151
|
-
def logger
|
152
|
-
Mcrain.logger
|
79
|
+
def stop_or_kill_and_remove
|
80
|
+
begin
|
81
|
+
container.stop!
|
82
|
+
rescue => e
|
83
|
+
container.kill!
|
84
|
+
end
|
85
|
+
container.remove
|
153
86
|
end
|
154
87
|
|
155
88
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Mcrain
|
2
|
+
module ClientProvider
|
3
|
+
|
4
|
+
def client
|
5
|
+
@client ||= build_client
|
6
|
+
end
|
7
|
+
|
8
|
+
def build_client
|
9
|
+
require client_require
|
10
|
+
yield if block_given?
|
11
|
+
client_class.new(*client_init_args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def client_require
|
15
|
+
raise NotImplementedError
|
16
|
+
end
|
17
|
+
|
18
|
+
def client_class
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
def client_init_args
|
23
|
+
raise NotImplementedError
|
24
|
+
end
|
25
|
+
|
26
|
+
def client_script
|
27
|
+
client
|
28
|
+
"#{client_class.name}.new(*#{client_init_args.inspect})"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Mcrain
|
3
|
+
module ContainerController
|
4
|
+
|
5
|
+
def self.included(klass)
|
6
|
+
klass.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
attr_writer :server_name
|
11
|
+
def server_name
|
12
|
+
@server_name ||= self.name.split(/::/).last.underscore.to_sym
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :container_image, :port
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Docker::Container]
|
19
|
+
def container
|
20
|
+
unless @container
|
21
|
+
options = build_docker_options
|
22
|
+
Mcrain.logger.info("#{self.class.name}#container Docker::Container.create(#{options.inspect})")
|
23
|
+
@container = Docker::Container.create(options)
|
24
|
+
end
|
25
|
+
@container
|
26
|
+
end
|
27
|
+
|
28
|
+
def container_image
|
29
|
+
self.class.container_image or raise "No container_image for #{self.class.name}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def host
|
33
|
+
@host ||= URI.parse(ENV["DOCKER_HOST"] || "tcp://localhost").host
|
34
|
+
end
|
35
|
+
|
36
|
+
def find_portno
|
37
|
+
# 未使用のポートをシステムに割り当てさせてすぐ閉じてそれを利用する
|
38
|
+
tmpserv = TCPServer.new(0)
|
39
|
+
portno = tmpserv.local_address.ip_port
|
40
|
+
tmpserv.close
|
41
|
+
portno
|
42
|
+
end
|
43
|
+
|
44
|
+
def port
|
45
|
+
@port ||= find_portno
|
46
|
+
end
|
47
|
+
|
48
|
+
def url
|
49
|
+
@url ||= "#{self.class.server_name}://#{host}:#{port}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def build_docker_options
|
53
|
+
{
|
54
|
+
'Image' => container_image,
|
55
|
+
'HostConfig' => {
|
56
|
+
'PortBindings' => {
|
57
|
+
"#{self.class.port}/tcp" => [{ 'HostPort' => port.to_s }]
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
data/lib/mcrain/mysql.rb
CHANGED
@@ -37,17 +37,20 @@ module Mcrain
|
|
37
37
|
attr_accessor :database
|
38
38
|
attr_accessor :username, :password
|
39
39
|
|
40
|
-
def
|
41
|
-
|
40
|
+
def build_docker_options
|
41
|
+
r = super
|
42
|
+
|
42
43
|
username = self.username || "root" # overwrite locally
|
43
44
|
key_user = (username == "root") ? nil : "MYSQL_USER"
|
44
45
|
key_pw = (username == "root") ? "MYSQL_ROOT_PASSWORD" : "MYSQL_PASSWORD"
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
envs = []
|
47
|
+
envs << (password.blank? ? "MYSQL_ALLOW_EMPTY_PASSWORD=yes" : "#{key_pw}=#{password}")
|
48
|
+
envs << "#{key_user}=#{username}" if key_user
|
49
|
+
envs << "MYSQL_DATABASE=#{database}" if database
|
50
|
+
envs << "#{File.expand_path(db_dir)}:/var/lib/mysql" if db_dir
|
51
|
+
r['Env'] = envs unless envs.empty?
|
52
|
+
return r
|
51
53
|
end
|
54
|
+
|
52
55
|
end
|
53
56
|
end
|
data/lib/mcrain/rabbitmq.rb
CHANGED
@@ -8,9 +8,12 @@ module Mcrain
|
|
8
8
|
self.server_name = :rabbitmq
|
9
9
|
|
10
10
|
self.container_image = "rabbitmq:3.4.4-management"
|
11
|
+
self.port = 15672
|
11
12
|
|
12
|
-
def
|
13
|
-
|
13
|
+
def build_docker_options
|
14
|
+
r = super
|
15
|
+
r['HostConfig']['PortBindings']["5672/tcp"] = [{ 'HostPort' => runtime_port.to_s }]
|
16
|
+
return r
|
14
17
|
end
|
15
18
|
|
16
19
|
def runtime_port
|
data/lib/mcrain/redis.rb
CHANGED
@@ -28,8 +28,13 @@ module Mcrain
|
|
28
28
|
|
29
29
|
attr_accessor :db_dir
|
30
30
|
|
31
|
-
def
|
32
|
-
|
31
|
+
def build_docker_options
|
32
|
+
r = super
|
33
|
+
if db_dir
|
34
|
+
r['Volumes'] ||= {}
|
35
|
+
r['Volumes']["/data"] = File.expand_path(db_dir)
|
36
|
+
end
|
37
|
+
return r
|
33
38
|
end
|
34
39
|
end
|
35
40
|
end
|
data/lib/mcrain/riak.rb
CHANGED
@@ -1,27 +1,84 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
require 'mcrain'
|
2
3
|
|
3
4
|
# require 'riak'
|
5
|
+
require 'net/http'
|
4
6
|
|
5
7
|
module Mcrain
|
6
8
|
class Riak < Base
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
self.server_name = :riak
|
11
|
+
|
12
|
+
self.container_image = "hectcastro/riak"
|
13
|
+
|
14
|
+
attr_accessor :automatic_clustering
|
15
|
+
attr_writer :cluster_size, :backend
|
16
|
+
def cluster_size
|
17
|
+
@cluster_size ||= 1
|
18
|
+
end
|
19
|
+
def backend
|
20
|
+
@backend ||= "bitcask" # "leveldb"
|
11
21
|
end
|
12
22
|
|
13
|
-
|
23
|
+
# docker run -e "DOCKER_RIAK_CLUSTER_SIZE=${DOCKER_RIAK_CLUSTER_SIZE}" \
|
24
|
+
# -e "DOCKER_RIAK_AUTOMATIC_CLUSTERING=${DOCKER_RIAK_AUTOMATIC_CLUSTERING}" \
|
25
|
+
# -e "DOCKER_RIAK_BACKEND=${DOCKER_RIAK_BACKEND}" \
|
26
|
+
# -p $publish_http_port \
|
27
|
+
# -p $publish_pb_port \
|
28
|
+
# --link "riak01:seed" \
|
29
|
+
# --name "riak${index}" \
|
30
|
+
# -d hectcastro/riak > /dev/null 2>&1
|
31
|
+
class Node
|
32
|
+
include ContainerController
|
33
|
+
|
34
|
+
self.container_image = "hectcastro/riak"
|
35
|
+
|
36
|
+
self.port = 8087 # protocol buffer
|
37
|
+
# self.http_port = 8098 # HTTP
|
38
|
+
|
39
|
+
attr_reader :owner
|
40
|
+
attr_accessor :primary_node
|
41
|
+
def initialize(owner)
|
42
|
+
@owner = owner
|
43
|
+
end
|
44
|
+
|
45
|
+
def http_port
|
46
|
+
@http_port ||= find_portno
|
47
|
+
end
|
14
48
|
|
15
|
-
|
16
|
-
|
49
|
+
def build_docker_options
|
50
|
+
r = super
|
51
|
+
r['HostConfig']['PortBindings']["8098/tcp"] = [{ 'HostPort' => http_port.to_s }]
|
52
|
+
envs = []
|
53
|
+
envs << "RIAK_CLUSTER_SIZE=#{owner.cluster_size}"
|
54
|
+
envs << "DOCKER_RIAK_AUTOMATIC_CLUSTERING=#{owner.automatic_clustering ? 1 : 0}"
|
55
|
+
envs << "DOCKER_RIAK_BACKEND=#{owner.backend}"
|
56
|
+
r['Env'] = envs unless envs.empty?
|
57
|
+
if primary_node
|
58
|
+
r['HostConfig']['Links'] = ["#{primary_node.container.name}:seed"]
|
59
|
+
end
|
60
|
+
return r
|
61
|
+
end
|
17
62
|
|
18
|
-
|
19
|
-
|
20
|
-
|
63
|
+
def ping
|
64
|
+
owner.logger.debug("sending a ping http://#{host}:#{http_port}/stats")
|
65
|
+
res = Net::HTTP.start(host, http_port) {|http| http.get('/stats') }
|
66
|
+
r = res.is_a?(Net::HTTPSuccess)
|
67
|
+
owner.logger.debug("#{res.inspect} #=> #{r}")
|
68
|
+
return r
|
69
|
+
rescue => e
|
70
|
+
return false
|
71
|
+
end
|
21
72
|
end
|
22
73
|
|
23
|
-
def
|
24
|
-
|
74
|
+
def nodes
|
75
|
+
unless @nodes
|
76
|
+
@nodes = (cluster_size || 1).times.map{ Node.new(self) }
|
77
|
+
array = @nodes.dup
|
78
|
+
primary_node = array.shift
|
79
|
+
array.each{|node| node.primary_node = primary_node}
|
80
|
+
end
|
81
|
+
@nodes
|
25
82
|
end
|
26
83
|
|
27
84
|
def client_class
|
@@ -29,53 +86,20 @@ module Mcrain
|
|
29
86
|
end
|
30
87
|
|
31
88
|
def client_init_args
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
options[:authentication] = {user: uri.user, password: uri.password}
|
38
|
-
end
|
39
|
-
end
|
40
|
-
[options]
|
89
|
+
return [
|
90
|
+
{
|
91
|
+
nodes: nodes.map{|node| {host: node.host, pb_port: node.port} }
|
92
|
+
}
|
93
|
+
]
|
41
94
|
end
|
42
95
|
|
43
96
|
def client_require
|
44
97
|
'riak'
|
45
98
|
end
|
46
99
|
|
47
|
-
def build_uris
|
48
|
-
# https://github.com/hectcastro/docker-riak/blob/develop/bin/test-cluster.sh#L9
|
49
|
-
|
50
|
-
# http://docs.docker.com/reference/api/docker_remote_api/
|
51
|
-
# https://github.com/boot2docker/boot2docker#ssh-into-vm
|
52
|
-
Boot2docker.setup_docker_options
|
53
|
-
|
54
|
-
uri = URI.parse(ENV["DOCKER_HOST"])
|
55
|
-
@host = (uri.scheme == "unix") ? "localhost" : uri.host
|
56
|
-
list = Docker::Container.all
|
57
|
-
riak_containers = list.select{|r| r.info['Image'] =~ /\Ahectcastro\/riak(\:.+)?\z/}
|
58
|
-
@cids = riak_containers.map(&:id)
|
59
|
-
@pb_ports = riak_containers.map do |r|
|
60
|
-
map = r.info['Ports'].each_with_object({}){|rr,d| d[ rr['PrivatePort'] ] = rr['PublicPort']}
|
61
|
-
map[8087]
|
62
|
-
end
|
63
|
-
@port = @pb_ports.first
|
64
|
-
@admin_uris = @cids.map do |cid|
|
65
|
-
r = Docker::Container.get(cid)
|
66
|
-
host = r.info["NetworkSettings"]["IPAddress"]
|
67
|
-
# login with insecure_key
|
68
|
-
# https://github.com/phusion/baseimage-docker#using-the-insecure-key-for-one-container-only
|
69
|
-
"ssh://root@#{host}:22"
|
70
|
-
end
|
71
|
-
@uris = @pb_ports.map do |port|
|
72
|
-
URI::Generic.build(scheme: "riak", host: @host, port: port)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
100
|
def wait_for_ready
|
77
101
|
c = client
|
78
|
-
logger.debug("sending a ping")
|
102
|
+
logger.debug("sending a ping from client")
|
79
103
|
begin
|
80
104
|
r = c.ping
|
81
105
|
raise "Ping failure with #{c.inspect}" unless r
|
@@ -105,54 +129,42 @@ module Mcrain
|
|
105
129
|
end
|
106
130
|
end
|
107
131
|
|
108
|
-
def clear_old_container
|
109
|
-
end
|
110
|
-
|
111
|
-
attr_reader :host, :cids, :pb_ports, :uris, :admin_uris
|
112
|
-
attr_accessor :automatic_clustering, :cluster_size
|
113
|
-
|
114
132
|
def setup
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
133
|
+
Boot2docker.setup_docker_options
|
134
|
+
nodes.map(&:container).each(&:start!)
|
135
|
+
# http://basho.co.jp/riak-quick-start-with-docker/
|
136
|
+
#
|
137
|
+
# "Please wait approximately 30 seconds for the cluster to stabilize"
|
138
|
+
# from https://gist.github.com/agutow/11133143#file-docker3-sh-L12
|
139
|
+
sleep(30)
|
140
|
+
nodes.each do |node|
|
141
|
+
success = false
|
142
|
+
20.times do
|
143
|
+
success = node.ping
|
144
|
+
break if success
|
145
|
+
sleep(3)
|
146
|
+
end
|
147
|
+
raise "failed to run a riak server" unless success
|
148
|
+
end
|
125
149
|
end
|
126
150
|
|
127
|
-
def
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
# "Please wait approximately 30 seconds for the cluster to stabilize"
|
134
|
-
# from https://gist.github.com/agutow/11133143#file-docker3-sh-L12
|
135
|
-
LoggerPipe.run(logger, "#{@prepare_cmd} #{build_command}")
|
136
|
-
sleep(1)
|
137
|
-
20.times do
|
138
|
-
begin
|
139
|
-
LoggerPipe.run(logger, "#{@prepare_cmd} make test-cluster")
|
140
|
-
sleep(5)
|
141
|
-
return
|
142
|
-
rescue
|
143
|
-
sleep(0.5)
|
144
|
-
retry
|
145
|
-
end
|
151
|
+
def teardown
|
152
|
+
nodes.map(&:container).each do |c|
|
153
|
+
begin
|
154
|
+
c.stop!
|
155
|
+
rescue => e
|
156
|
+
c.kill!
|
146
157
|
end
|
147
|
-
|
158
|
+
c.remove
|
148
159
|
end
|
160
|
+
reset unless skip_reset_after_teardown
|
149
161
|
end
|
150
162
|
|
151
|
-
|
152
|
-
|
153
|
-
|
163
|
+
# ポートがLISTENされるまで待つ
|
164
|
+
def wait_port
|
165
|
+
nodes.each do |node|
|
166
|
+
Mcrain.wait_port_opened(node.host, node.port, interval: 0.5, timeout: 30)
|
154
167
|
end
|
155
|
-
reset unless skip_reset_after_stop
|
156
168
|
end
|
157
169
|
|
158
170
|
end
|
data/lib/mcrain/version.rb
CHANGED
data/lib/mcrain.rb
CHANGED
@@ -77,6 +77,8 @@ module Mcrain
|
|
77
77
|
|
78
78
|
autoload :Base, 'mcrain/base'
|
79
79
|
autoload :Boot2docker, 'mcrain/boot2docker'
|
80
|
+
autoload :ContainerController, 'mcrain/container_controller'
|
81
|
+
autoload :ClientProvider, 'mcrain/client_provider'
|
80
82
|
|
81
83
|
autoload :Riak, 'mcrain/riak'
|
82
84
|
autoload :Redis, 'mcrain/redis'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mcrain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- akm
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06
|
11
|
+
date: 2015-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logger_pipe
|
@@ -122,6 +122,8 @@ files:
|
|
122
122
|
- lib/mcrain.rb
|
123
123
|
- lib/mcrain/base.rb
|
124
124
|
- lib/mcrain/boot2docker.rb
|
125
|
+
- lib/mcrain/client_provider.rb
|
126
|
+
- lib/mcrain/container_controller.rb
|
125
127
|
- lib/mcrain/mysql.rb
|
126
128
|
- lib/mcrain/rabbitmq.rb
|
127
129
|
- lib/mcrain/redis.rb
|