mcrain 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|