docker_brick 0.0.1
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 +7 -0
- data/.gitignore +22 -0
- data/.project +17 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +24 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/bin/brick +11 -0
- data/docker_brick.gemspec +29 -0
- data/lib/brick/application.rb +35 -0
- data/lib/brick/cli/build.rb +28 -0
- data/lib/brick/cli/core/subcommand_loader.rb +39 -0
- data/lib/brick/cli/help.rb +16 -0
- data/lib/brick/cli/project_new.rb +29 -0
- data/lib/brick/cli/run.rb +113 -0
- data/lib/brick/cli/service_new.rb +44 -0
- data/lib/brick/cli/up.rb +46 -0
- data/lib/brick/cli.rb +230 -0
- data/lib/brick/cli__validator.rb +28 -0
- data/lib/brick/config.rb +9 -0
- data/lib/brick/docker/docker_client.rb +160 -0
- data/lib/brick/generators/new_project_generator/templates/fig.yml +0 -0
- data/lib/brick/generators/new_project_generator.rb +51 -0
- data/lib/brick/generators/new_service_generator.rb +24 -0
- data/lib/brick/generators.rb +10 -0
- data/lib/brick/mixin/aliasing.rb +24 -0
- data/lib/brick/mixin/colors.rb +24 -0
- data/lib/brick/mixin/convert_to_class_name.rb +52 -0
- data/lib/brick/mixin/docker_support.rb +253 -0
- data/lib/brick/mixin/yaml_helper.rb +18 -0
- data/lib/brick/mixin.rb +8 -0
- data/lib/brick/models/project.rb +139 -0
- data/lib/brick/models/service.rb +276 -0
- data/lib/brick/models.rb +13 -0
- data/lib/brick/monkey_patches/cli.rb +24 -0
- data/lib/brick/monkey_patches/connection.rb +15 -0
- data/lib/brick/monkey_patches/docker_container.rb +28 -0
- data/lib/brick/monkey_patches/hash.rb +16 -0
- data/lib/brick/monkey_patches.rb +5 -0
- data/lib/brick/version.rb +4 -0
- data/lib/brick.rb +34 -0
- data/spec/brick_update.sh +7 -0
- data/spec/integration/brick/models/project_spec.rb +70 -0
- data/spec/projects/nc_test/fig.yml +14 -0
- data/spec/projects/nc_test/ncserver/Dockerfile +7 -0
- data/spec/projects/rails/myapp/Dockerfile +7 -0
- data/spec/projects/rails/myapp/Gemfile +2 -0
- data/spec/projects/rails/myapp/fig.yml +13 -0
- data/spec/shell/brick_update.sh +7 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/unit/brick/mixin/docker_support.yml +33 -0
- data/spec/unit/brick/mixin/docker_support_spec.rb +66 -0
- data/spec/unit/brick/models/dockerfile/Dockerfile +7 -0
- data/spec/unit/brick/models/fig_build.yml +3 -0
- data/spec/unit/brick/models/fig_completed.yml +41 -0
- data/spec/unit/brick/models/fig_dependency.yml +19 -0
- data/spec/unit/brick/models/fig_single.yml +6 -0
- data/spec/unit/brick/models/fig_volumes.yml +10 -0
- data/spec/unit/brick/models/fig_volumes_from.yml +19 -0
- data/spec/unit/brick/models/project_spec.rb +70 -0
- data/spec/unit/brick/models/service_spec.rb +80 -0
- metadata +231 -0
@@ -0,0 +1,253 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Brick::Mixin
|
5
|
+
module DockerSupport
|
6
|
+
|
7
|
+
#from yml file to the configuration for creating container
|
8
|
+
def create_config hash
|
9
|
+
hash=transform_docker_hash hash
|
10
|
+
|
11
|
+
create_config_for_port hash
|
12
|
+
|
13
|
+
create_config_for_volumes hash
|
14
|
+
|
15
|
+
hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def start_config hash
|
19
|
+
hash=transform_docker_hash hash
|
20
|
+
|
21
|
+
start_config_for_port hash
|
22
|
+
|
23
|
+
start_config_for_volumes hash
|
24
|
+
|
25
|
+
hash
|
26
|
+
end
|
27
|
+
|
28
|
+
#the format is captalized
|
29
|
+
private
|
30
|
+
def transform_docker_hash hash
|
31
|
+
hash= Hash[hash.map do |k,v|
|
32
|
+
keys=k.split('_')
|
33
|
+
|
34
|
+
keys.map!{|key|key.capitalize}
|
35
|
+
|
36
|
+
[keys.join(''), v]
|
37
|
+
end
|
38
|
+
]
|
39
|
+
|
40
|
+
common_config_for_cmd hash
|
41
|
+
|
42
|
+
common_config_for_env hash
|
43
|
+
|
44
|
+
common_config_for_volumes hash
|
45
|
+
|
46
|
+
hash
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
def common_config_for_cmd hash
|
52
|
+
cmd= hash.delete('Command')
|
53
|
+
|
54
|
+
#hash['Cmd']=cmd.split(' ') unless cmd.nil?
|
55
|
+
|
56
|
+
unless cmd.nil?
|
57
|
+
if cmd.instance_of? Array
|
58
|
+
hash['Cmd'] = cmd
|
59
|
+
else
|
60
|
+
hash['Cmd'] = Shellwords.split(cmd)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
hash
|
65
|
+
end
|
66
|
+
|
67
|
+
#common configuration for environment variable
|
68
|
+
def common_config_for_env hash
|
69
|
+
#Support environment variables
|
70
|
+
env_variables = hash.delete('Environment')
|
71
|
+
|
72
|
+
unless env_variables.nil?
|
73
|
+
if env_variables.instance_of? Array
|
74
|
+
hash['Env'] = env_variables
|
75
|
+
elsif env_variables.instance_of? Hash
|
76
|
+
var_arrays = []
|
77
|
+
env_variables.each {|key, value| var_arrays<<"#{key}=#{value}" }
|
78
|
+
hash['Env'] = var_arrays
|
79
|
+
end
|
80
|
+
end
|
81
|
+
hash
|
82
|
+
end
|
83
|
+
|
84
|
+
def common_config_for_volumes hash
|
85
|
+
#volumes
|
86
|
+
unless hash["Volumes"].nil?
|
87
|
+
volumes = hash["Volumes"]
|
88
|
+
|
89
|
+
if volumes.instance_of? Array
|
90
|
+
volumes.map!{|vo|
|
91
|
+
vo_parts = vo.split(":")
|
92
|
+
|
93
|
+
container_volume = nil
|
94
|
+
|
95
|
+
host_volume = vo_parts[0]
|
96
|
+
|
97
|
+
option = "rw"
|
98
|
+
|
99
|
+
if(Pathname.new(host_volume).relative?)
|
100
|
+
host_volume = File.absolute_path(File.join(::Brick::Config[:project_dir],host_volume))
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
if vo_parts.size==1
|
105
|
+
container_volume = host_volume
|
106
|
+
elsif vo_parts.size>=2
|
107
|
+
container_volume = vo_parts[1]
|
108
|
+
|
109
|
+
if(Pathname.new(container_volume).relative?)
|
110
|
+
container_volume = File.absolute_path(File.join(::Brick::Config[:project_dir],container_volume))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
if vo_parts.size==3
|
115
|
+
option = vo_parts[2]
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
[host_volume, container_volume, option].join(':')
|
120
|
+
}
|
121
|
+
else
|
122
|
+
raise "the value of volumes should be an array"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
hash
|
127
|
+
end
|
128
|
+
|
129
|
+
def create_config_for_volumes hash
|
130
|
+
#create config for volumes
|
131
|
+
unless hash["Volumes"].nil?
|
132
|
+
volumes = hash.delete('Volumes')
|
133
|
+
|
134
|
+
volume_hash={}
|
135
|
+
|
136
|
+
volumes.each{|vo|
|
137
|
+
vo_parts = vo.split(':')
|
138
|
+
|
139
|
+
volume_hash[vo_parts[1]] = {}
|
140
|
+
|
141
|
+
}
|
142
|
+
|
143
|
+
hash['Volumes'] = volume_hash
|
144
|
+
|
145
|
+
hash
|
146
|
+
end
|
147
|
+
hash
|
148
|
+
end
|
149
|
+
|
150
|
+
def start_config_for_volumes hash
|
151
|
+
#start config for volumes
|
152
|
+
#start config for volumes
|
153
|
+
unless hash["Volumes"].nil?
|
154
|
+
binds = hash.delete('Volumes')
|
155
|
+
|
156
|
+
hash["Binds"] = binds
|
157
|
+
end
|
158
|
+
hash
|
159
|
+
end
|
160
|
+
|
161
|
+
#the port configuration for creating container
|
162
|
+
def create_config_for_port hash
|
163
|
+
exposed_ports = []
|
164
|
+
|
165
|
+
|
166
|
+
#add expose ports
|
167
|
+
unless hash["Ports"].nil?
|
168
|
+
ports = hash.delete "Ports"
|
169
|
+
|
170
|
+
ports.each{|port|
|
171
|
+
|
172
|
+
container_port = (port.split(':'))[-1]
|
173
|
+
|
174
|
+
exposed_ports << container_port
|
175
|
+
}
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
#Add expose to exposed ports
|
180
|
+
unless hash["Expose"].nil?
|
181
|
+
exposes = hash.delete "Expose"
|
182
|
+
|
183
|
+
exposes.each{|expose|
|
184
|
+
exposed_ports << expose
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
|
190
|
+
if exposed_ports.size > 0
|
191
|
+
|
192
|
+
proto = 'tcp'
|
193
|
+
|
194
|
+
exposed_port_hash = Hash.new
|
195
|
+
|
196
|
+
exposed_ports.each {|container_port| exposed_port_hash["#{container_port}/#{proto}"]={}}
|
197
|
+
|
198
|
+
hash["ExposedPorts"]=exposed_port_hash
|
199
|
+
end
|
200
|
+
|
201
|
+
hash
|
202
|
+
end
|
203
|
+
|
204
|
+
#the port configuration for starting container
|
205
|
+
def start_config_for_port hash
|
206
|
+
#the setting for start config
|
207
|
+
port_bindings = {}
|
208
|
+
|
209
|
+
unless hash["Ports"].nil?
|
210
|
+
ports = hash.delete "Ports"
|
211
|
+
|
212
|
+
ports.each{|port|
|
213
|
+
|
214
|
+
port_definition = port.split(':')
|
215
|
+
|
216
|
+
proto ="tcp"
|
217
|
+
|
218
|
+
if port_definition.size > 1
|
219
|
+
|
220
|
+
container_port = port_definition[-1]
|
221
|
+
|
222
|
+
host_port = port_definition[-2]
|
223
|
+
|
224
|
+
port_bindings["#{container_port}/#{proto}"] = [{"HostPort"=>host_port}]
|
225
|
+
|
226
|
+
# port_bindings << {"#{container_port}/#{proto}"=>[{"HostPort"=>host_port}]}
|
227
|
+
else
|
228
|
+
port_bindings["#{port}/#{proto}"] = [{"HostPort"=>port}]
|
229
|
+
end
|
230
|
+
}
|
231
|
+
|
232
|
+
hash["PortBindings"]=port_bindings
|
233
|
+
end
|
234
|
+
hash
|
235
|
+
end
|
236
|
+
|
237
|
+
def determine_dockerfile_path dockerfile_path, project_dir
|
238
|
+
|
239
|
+
pathname= Pathname.new(dockerfile_path)
|
240
|
+
|
241
|
+
if pathname.absolute?
|
242
|
+
real_dockerfile_path = dockerfile_path
|
243
|
+
else
|
244
|
+
unless project_dir.nil?
|
245
|
+
real_dockerfile_path = File.absolute_path(File.join(project_dir, dockerfile_path))
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
real_dockerfile_path
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Brick::Mixin
|
4
|
+
module YamlHelper
|
5
|
+
def load_yaml_file(path, expected_type = Hash)
|
6
|
+
raise("Cannot find file `#{path}'") unless File.exists?(path)
|
7
|
+
yaml = YAML::load_file(path)
|
8
|
+
|
9
|
+
if expected_type && !yaml.is_a?(expected_type)
|
10
|
+
raise "Incorrect file format in `#{path}', #{expected_type} expected"
|
11
|
+
end
|
12
|
+
|
13
|
+
yaml
|
14
|
+
rescue SystemCallError => e
|
15
|
+
raise "Cannot load YAML file at `#{path}': #{e}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/brick/mixin.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'brick/mixin/yaml_helper'
|
2
|
+
require 'brick/docker/docker_client'
|
3
|
+
#require 'deepstruct'
|
4
|
+
|
5
|
+
module Brick
|
6
|
+
module Models
|
7
|
+
class Project
|
8
|
+
|
9
|
+
include Brick::Mixin::YamlHelper
|
10
|
+
|
11
|
+
attr_accessor :services, :docker_client, :name, :recreate, :insecure_registry
|
12
|
+
|
13
|
+
def initialize(project_name ,options={},client=nil)
|
14
|
+
|
15
|
+
@name = project_name
|
16
|
+
|
17
|
+
unless options[:config_file].nil?
|
18
|
+
@config_file = options[:config_file]
|
19
|
+
end
|
20
|
+
|
21
|
+
@docker_client = client ? client : Brick::Docker::DockerClient::default
|
22
|
+
|
23
|
+
init_services_from_config(@config_file)
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def get_services(service_name, inlcude_links=false)
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_service(name)
|
33
|
+
|
34
|
+
service = nil
|
35
|
+
|
36
|
+
unless @services.nil?
|
37
|
+
|
38
|
+
service = @services[name]
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
service
|
43
|
+
end
|
44
|
+
|
45
|
+
#initialize the configuration of each service, and put it into services
|
46
|
+
def init_services_from_config(config_file=nil)
|
47
|
+
config_hash = load_yaml_file config_file
|
48
|
+
|
49
|
+
# config = config_hash.to_ostruct
|
50
|
+
|
51
|
+
@services = {}
|
52
|
+
|
53
|
+
config_hash.each_key{|key|
|
54
|
+
# @services << Service.new(key,eval("config.#{key}"))
|
55
|
+
@services[key] =Service.new("#{@name}_#{key}_1",config_hash[key],@docker_client)
|
56
|
+
}
|
57
|
+
|
58
|
+
@services.each_key{|key|
|
59
|
+
service = @services[key]
|
60
|
+
service.update_links @services
|
61
|
+
service.update_volumes_from @services
|
62
|
+
service.update_image_for_building_tag("#{self.name}_#{key}")
|
63
|
+
}
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def up(detach_mode = true, enable_link=true, recreate=false)
|
69
|
+
|
70
|
+
self.services.each_key{|key| service= services[key]
|
71
|
+
|
72
|
+
if service.container_exist?
|
73
|
+
puts "Recreating #{service.name} ..."
|
74
|
+
else
|
75
|
+
puts "Creating #{service.name} ..."
|
76
|
+
end
|
77
|
+
|
78
|
+
if service.can_be_built?
|
79
|
+
unless service.image_exist?
|
80
|
+
# by default, not set cache
|
81
|
+
service.build nil, true, ::Brick::Config[:project_dir]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
service.run enable_link, recreate, detach_mode
|
86
|
+
|
87
|
+
|
88
|
+
}
|
89
|
+
|
90
|
+
Service.wait_for_deamon
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
#create the service according to the service name
|
95
|
+
def run_services(service_name, enable_link=true)
|
96
|
+
|
97
|
+
service = @services[service_name]
|
98
|
+
|
99
|
+
to_build = false
|
100
|
+
|
101
|
+
if service.can_be_built?
|
102
|
+
|
103
|
+
if service.image_exist?
|
104
|
+
if ::Brick::Config[:rebuild]
|
105
|
+
to_build=true
|
106
|
+
else
|
107
|
+
puts "The image #{service.image_name} already exists!"
|
108
|
+
end
|
109
|
+
else
|
110
|
+
to_build = true
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
if to_build
|
116
|
+
service.build nil, true, ::Brick::Config[:project_dir]
|
117
|
+
end
|
118
|
+
|
119
|
+
raise ServicesNotFoundException.new("service #{service_name} is not found in #{@config_file}") if service.nil?
|
120
|
+
service.run enable_link
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
def build_services no_cache=false, project_dir=nil
|
125
|
+
self.services.each_key{|key| service= services[key]
|
126
|
+
|
127
|
+
|
128
|
+
if service.can_be_built?
|
129
|
+
service.build("#{self.name}_#{key}",no_cache,project_dir)
|
130
|
+
else
|
131
|
+
::Brick::CLI::logger.info("uses an image, skipping #{key}")
|
132
|
+
end
|
133
|
+
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,276 @@
|
|
1
|
+
require 'brick/mixin'
|
2
|
+
require 'colorize'
|
3
|
+
|
4
|
+
|
5
|
+
module Brick
|
6
|
+
module Models
|
7
|
+
class Service
|
8
|
+
|
9
|
+
include ::Brick::Mixin::Colors
|
10
|
+
|
11
|
+
@@waiting_pool = []
|
12
|
+
|
13
|
+
attr_accessor :client, :name, :links, :service_config_hash, :container, :volumes_from, :image, :image_name
|
14
|
+
|
15
|
+
def self.wait_for_deamon
|
16
|
+
@@waiting_pool.each{|thr|
|
17
|
+
thr.join
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def initialize(name, config, client)
|
23
|
+
self.name = name
|
24
|
+
self.service_config_hash = config
|
25
|
+
self.client = client
|
26
|
+
#puts "client=#{client}"
|
27
|
+
|
28
|
+
determine_color
|
29
|
+
|
30
|
+
unless config["links"].nil?
|
31
|
+
if config["links"].instance_of?(String)
|
32
|
+
self.links= [config["links"]]
|
33
|
+
else
|
34
|
+
self.links= config["links"].dup
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
unless config["volumes_from"].nil?
|
39
|
+
if config["volumes_from"].instance_of?(String)
|
40
|
+
self.volumes_from= [config["volumes_from"]]
|
41
|
+
else
|
42
|
+
self.volumes_from= config["volumes_from"].dup
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
begin
|
47
|
+
self.container = ::Docker::Container.get(name)
|
48
|
+
rescue
|
49
|
+
self.container = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_volumes_from services
|
55
|
+
|
56
|
+
new_volumes_from_config = []
|
57
|
+
|
58
|
+
new_volumes_from = []
|
59
|
+
|
60
|
+
unless volumes_from.nil?
|
61
|
+
|
62
|
+
volumes_from.each {|vo|
|
63
|
+
#new_volumes_from << services[vo]
|
64
|
+
vo_parts = vo.split(':')
|
65
|
+
|
66
|
+
#only one part
|
67
|
+
if vo_parts.size == 1
|
68
|
+
new_vo = "#{services[vo_parts[0]].name}:rw"
|
69
|
+
else
|
70
|
+
new_vo= "#{services[vo_parts[0]].name}:#{vo_parts[1]}"
|
71
|
+
end
|
72
|
+
|
73
|
+
new_volumes_from<< services[vo_parts[0]]
|
74
|
+
|
75
|
+
new_volumes_from_config << new_vo
|
76
|
+
|
77
|
+
}
|
78
|
+
self.volumes_from = new_volumes_from
|
79
|
+
|
80
|
+
service_config_hash["volumes_from"] = new_volumes_from_config
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
def update_links services
|
86
|
+
|
87
|
+
new_links_config = []
|
88
|
+
|
89
|
+
new_links =[]
|
90
|
+
|
91
|
+
unless links.nil?
|
92
|
+
links.each{|link|
|
93
|
+
|
94
|
+
link_array=link.split(':')
|
95
|
+
|
96
|
+
#It's for getting the real service name
|
97
|
+
service_key = link_array[0]
|
98
|
+
|
99
|
+
alias_name = link_array[-1]
|
100
|
+
|
101
|
+
service_container= services[service_key]
|
102
|
+
|
103
|
+
new_links << service_container
|
104
|
+
|
105
|
+
new_links_config << "#{service_container.name}:#{alias_name}"
|
106
|
+
}
|
107
|
+
|
108
|
+
self.links=new_links
|
109
|
+
|
110
|
+
service_config_hash["links"] = new_links_config
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
def exec cmd_array, options ={}
|
117
|
+
if self.container.nil?
|
118
|
+
raise "no container #{name} running, so we can't execute "
|
119
|
+
end
|
120
|
+
|
121
|
+
self.container.exec(cmd_array, options){|stream, chunk| puts "#{color_generator(name)} | #{chunk}".chomp }
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
#equals to "docker run"
|
126
|
+
def run enable_link=true, recreate=true, detach_mode=false
|
127
|
+
|
128
|
+
if running? and (!recreate or can_be_skipped_this_time?)
|
129
|
+
Brick::CLI::logger.debug "the service #{name} is already running. exited."
|
130
|
+
unless detach_mode
|
131
|
+
attach
|
132
|
+
end
|
133
|
+
|
134
|
+
return
|
135
|
+
end
|
136
|
+
|
137
|
+
unless volumes_from.nil?
|
138
|
+
volumes_from.each{|vo| vo.run enable_link}
|
139
|
+
end
|
140
|
+
|
141
|
+
config_hash = @service_config_hash.dup
|
142
|
+
|
143
|
+
if enable_link and !links.nil?
|
144
|
+
links.each{|linked_service|
|
145
|
+
linked_service.run enable_link
|
146
|
+
|
147
|
+
unless detach_mode
|
148
|
+
linked_service.attach
|
149
|
+
else
|
150
|
+
puts "Service #{linked_service.name} has been started"
|
151
|
+
end
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
if !enable_link
|
156
|
+
config_hash.delete("links")
|
157
|
+
end
|
158
|
+
|
159
|
+
if recreate and !container.nil?
|
160
|
+
#if recreate is true, it will destory the old container, and create a new one
|
161
|
+
if running?
|
162
|
+
container.stop
|
163
|
+
end
|
164
|
+
container.delete(:force => true)
|
165
|
+
self.container=nil
|
166
|
+
skip_next_time
|
167
|
+
end
|
168
|
+
|
169
|
+
if container.nil?
|
170
|
+
self.container = client.run config_hash, name
|
171
|
+
else
|
172
|
+
container.start
|
173
|
+
end
|
174
|
+
|
175
|
+
unless detach_mode
|
176
|
+
attach
|
177
|
+
else
|
178
|
+
puts "Service #{name} has been started"
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
#Check if the container is running
|
184
|
+
def running?
|
185
|
+
is_running = false
|
186
|
+
|
187
|
+
if container.nil?
|
188
|
+
begin
|
189
|
+
self.container = ::Docker::Container.get(name)
|
190
|
+
rescue
|
191
|
+
self.container = nil
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
unless container.nil?
|
196
|
+
is_running = container.is_running?
|
197
|
+
end
|
198
|
+
|
199
|
+
is_running
|
200
|
+
end
|
201
|
+
|
202
|
+
def container_info
|
203
|
+
(client.get_container_by_id(container.id)).info rescue {}
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
def attach
|
208
|
+
|
209
|
+
thr=Thread.new{
|
210
|
+
puts "Attaching to service #{name}"
|
211
|
+
container.attach(:stdin => STDIN, :tty => true){|message|
|
212
|
+
|
213
|
+
if message.length > 0
|
214
|
+
puts "#{color_generator(name)} | #{message}".chomp
|
215
|
+
end
|
216
|
+
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
#thr.join
|
221
|
+
@@waiting_pool << thr
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
def can_be_built?
|
226
|
+
!service_config_hash["build"].nil?
|
227
|
+
end
|
228
|
+
|
229
|
+
def skip_next_time
|
230
|
+
@skip = true
|
231
|
+
end
|
232
|
+
|
233
|
+
def can_be_skipped_this_time?
|
234
|
+
@skip == true
|
235
|
+
end
|
236
|
+
|
237
|
+
def build name=nil, no_cache=false, project_dir=nil
|
238
|
+
|
239
|
+
if name.nil?
|
240
|
+
name = self.image_name
|
241
|
+
end
|
242
|
+
|
243
|
+
puts "Start building #{name}..."
|
244
|
+
|
245
|
+
if can_be_built?
|
246
|
+
self.image = client.build_from_dir({:image_name => name,
|
247
|
+
:no_cache => no_cache,
|
248
|
+
:project_dir=>project_dir,
|
249
|
+
:build_dir=>service_config_hash["build"]})
|
250
|
+
else
|
251
|
+
Brick::CLI::logger.debug "no build defintion for #{image_build},skip it"
|
252
|
+
end
|
253
|
+
self.image
|
254
|
+
end
|
255
|
+
|
256
|
+
def image_exist?
|
257
|
+
::Docker::Image.exist?(image_name)
|
258
|
+
end
|
259
|
+
|
260
|
+
def container_exist?
|
261
|
+
::Docker::Container.exist?(name)
|
262
|
+
end
|
263
|
+
|
264
|
+
#If it's using build tag, will create an actual image name for it.
|
265
|
+
#For example, if project name is test, service name is web, the image name should
|
266
|
+
#be test_web
|
267
|
+
def update_image_for_building_tag name
|
268
|
+
unless service_config_hash["build"].nil?
|
269
|
+
service_config_hash["image"]=name
|
270
|
+
end
|
271
|
+
|
272
|
+
self.image_name = service_config_hash["image"]
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|