docker-app 0.2.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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/CODE_OF_CONDUCT.md +49 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/bin/console +14 -0
  7. data/bin/setup +8 -0
  8. data/docker-app.gemspec +36 -0
  9. data/exe/docker-app +20 -0
  10. data/lib/docker_app.rb +23 -0
  11. data/lib/docker_app/builder/packer.rb +105 -0
  12. data/lib/docker_app/chef/.chef/knife.rb +118 -0
  13. data/lib/docker_app/chef/chef_build_image.rb +55 -0
  14. data/lib/docker_app/chef/chef_destroy_container.rb +13 -0
  15. data/lib/docker_app/chef/chef_destroy_image.rb +17 -0
  16. data/lib/docker_app/chef/chef_exec_container.rb +16 -0
  17. data/lib/docker_app/chef/chef_run_container.rb +64 -0
  18. data/lib/docker_app/chef/install_container_service.rb +14 -0
  19. data/lib/docker_app/cli.rb +502 -0
  20. data/lib/docker_app/command.rb +16 -0
  21. data/lib/docker_app/config.rb +249 -0
  22. data/lib/docker_app/config/dsl.rb +64 -0
  23. data/lib/docker_app/config/helpers.rb +99 -0
  24. data/lib/docker_app/manager_container.rb +376 -0
  25. data/lib/docker_app/manager_image.rb +119 -0
  26. data/lib/docker_app/manager_swarm.rb +66 -0
  27. data/lib/docker_app/provisioner/base.rb +179 -0
  28. data/lib/docker_app/provisioner/chef.rb +93 -0
  29. data/lib/docker_app/server_settings.rb +361 -0
  30. data/lib/docker_app/version.rb +3 -0
  31. data/lib/templates/example-chef/.chef/knife.rb +5 -0
  32. data/lib/templates/example-chef/config.rb.erb +18 -0
  33. data/lib/templates/example-chef/servers/server1/.chef/knife.rb +8 -0
  34. data/lib/templates/example-chef/servers/server1/config.rb.erb +54 -0
  35. data/lib/templates/example-chef/servers/server1/cookbooks/server1/README.md +1 -0
  36. data/lib/templates/example-chef/servers/server1/cookbooks/server1/metadata.rb.erb +8 -0
  37. data/lib/templates/example-chef/servers/server1/cookbooks/server1/recipes/build.rb +10 -0
  38. data/lib/templates/example-chef/servers/server1/cookbooks/server1/recipes/install.rb +36 -0
  39. data/lib/templates/example-chef/servers/server1/cookbooks/server1/recipes/install_host.rb +9 -0
  40. data/lib/templates/example-chef/servers/server1/cookbooks/server1/templates/index.html.erb +5 -0
  41. data/lib/templates/example-chef/servers/server1/cookbooks/server1/templates/nginx-sites/default.conf.erb +45 -0
  42. data/readme.md +853 -0
  43. data/readme_developers.md +54 -0
  44. metadata +129 -0
@@ -0,0 +1,16 @@
1
+ module DockerApp
2
+ class Command
3
+
4
+ def self.cmd(s)
5
+ puts "running: #{s}"
6
+
7
+ res = nil
8
+ Bundler.with_clean_env do
9
+ res = `#{s}`
10
+ end
11
+
12
+ puts "#{res}"
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,249 @@
1
+ # encoding: utf-8
2
+ require 'docker_app/config/dsl'
3
+ require 'docker_app/config/helpers'
4
+
5
+
6
+
7
+ module DockerApp
8
+ module Config
9
+ #class Error < DockerApp::Error; end
10
+
11
+ DEFAULTS = {
12
+ :config_file => 'config.rb',
13
+ :tmp_path => 'temp'
14
+ }
15
+
16
+ class << self
17
+ #include Utilities::Helpers
18
+
19
+ attr_reader :servers, :options,
20
+ :root_path, :config_file, :tmp_path
21
+
22
+
23
+ # Define on self, since it's a class method
24
+ def method_missing(method_sym, *arguments, &block)
25
+ # the first argument is a Symbol, so you need to_s it if you want to pattern match
26
+ if options.has_key?(method_sym)
27
+ return options[method_sym]
28
+ else
29
+ super
30
+ end
31
+ #if method_sym.to_s =~ /^find_by_(.*)$/
32
+ # find($1.to_sym => arguments.first)
33
+
34
+ end
35
+
36
+
37
+
38
+ # Loads the user's +config.rb+ and all model files.
39
+ def load(opts = {})
40
+ update(opts) # from the command line
41
+
42
+ #config_file = 'temp_config.rb'
43
+
44
+ puts "config file: #{config_file}"
45
+
46
+ unless File.exist?(config_file)
47
+ #raise Error, "Could not find configuration file: '#{config_file}'."
48
+ raise "Could not find configuration file: '#{config_file}'."
49
+ end
50
+
51
+ text_config = File.read(config_file)
52
+
53
+ dsl = DSL.new
54
+ dsl.instance_eval(text_config, config_file)
55
+
56
+ # set options from dsl object
57
+ update(dsl._config_options) # from config.rb
58
+ # command line takes precedence
59
+ update(opts)
60
+
61
+ #Dir[File.join(File.dirname(config_file), 'models', '*.rb')].each do |model|
62
+ # dsl.instance_eval(File.read(model), model)
63
+ #end
64
+
65
+ # servers
66
+ # Identify all servers
67
+ if @options['server']
68
+ srv_name = @options['server'] || @options[:server]
69
+ # one server
70
+ @servers = {srv_name => dsl._config_servers[srv_name]}
71
+ else
72
+ # all servers
73
+ @servers = dsl._config_servers
74
+ end
75
+
76
+
77
+ @servers.each do |name, sc|
78
+ # from common config
79
+ sc.common_config = self
80
+ sc.properties['name'] ||= name
81
+ #sc.properties['common'] = Config.options[:common]
82
+ end
83
+
84
+
85
+
86
+ end
87
+
88
+
89
+ def dir_gem_root
90
+ return @dir_gem_root unless @dir_gem_root.nil?
91
+
92
+ #
93
+ spec = Gem::Specification.find_by_name("docker-app")
94
+ @dir_gem_root = spec.gem_dir
95
+
96
+ @dir_gem_root
97
+ end
98
+
99
+ def options
100
+ return @options unless @options.nil?
101
+
102
+ @options = {}
103
+ @options
104
+ end
105
+
106
+ #def servers
107
+ #options[:servers]
108
+ #@_servers || []
109
+ #end
110
+
111
+
112
+ ### NOT USED
113
+ ## TODO: refactor
114
+ def self.load_settings_for_server(name, opts={})
115
+ settings = ServerSettings.new
116
+
117
+ settings.set 'name', name
118
+
119
+ # set from main Config
120
+ Config.servers[name].each do |k,v|
121
+ settings.properties[k]=v
122
+ end
123
+
124
+
125
+ #puts "current=#{File.dirname(__FILE__)}"
126
+ #puts "ff=#{file_base_settings}"
127
+
128
+ #
129
+ #t = File.read(file_base_settings) rescue ''
130
+ #eval(t, settings.get_binding)
131
+
132
+
133
+ #
134
+ f = file_settings_for_server(name)
135
+ t = File.read(f) rescue ''
136
+ eval(t, settings.get_binding)
137
+
138
+ #
139
+ settings.properties['name'] ||= name
140
+
141
+ # from common config
142
+ settings.properties['common'] = Config.options[:common]
143
+
144
+ settings
145
+ end
146
+
147
+
148
+ ### helpers
149
+
150
+ def self.file_settings_for_server(name)
151
+ #File.join(File.dirname(__FILE__), '..', 'config', "#{name}.rb")
152
+ File.join(Config.root_path, 'servers', name, 'config.rb')
153
+ end
154
+
155
+ def self.file_server_base_settings
156
+ File.join(File.dirname(__FILE__), '..', 'config' ,'common.rb')
157
+ end
158
+
159
+
160
+ private
161
+
162
+ # If :root_path is set in the options, all paths will be updated.
163
+ # Otherwise, only the paths given will be updated.
164
+ def update(opts = {})
165
+ #puts "update. opts=#{opts}"
166
+
167
+ # root_path
168
+ root_path = opts[:root_path].to_s.strip
169
+
170
+ #puts "root from opts = #{root_path}"
171
+
172
+ if root_path.empty?
173
+ root_path = File.path(Dir.getwd)
174
+ end
175
+
176
+ new_root = root_path.empty? ? false : set_root_path(root_path)
177
+
178
+ DEFAULTS.each do |name, ending|
179
+ set_path_variable(name, options[name], ending, new_root)
180
+ end
181
+
182
+ # options
183
+ opts.each do |name, v|
184
+ set_variable(name, v)
185
+ end
186
+
187
+ # config file
188
+ set_path_variable("config_file", options['config_file'], DEFAULTS['config_file'], new_root)
189
+
190
+ end
191
+
192
+ # Sets the @root_path to the given +path+ and returns it.
193
+ # Raises an error if the given +path+ does not exist.
194
+ def set_root_path(path)
195
+ # allows #reset! to set the default @root_path,
196
+ # then use #update to set all other paths,
197
+ # without requiring that @root_path exist.
198
+ return @root_path if path == @root_path
199
+
200
+ path = File.expand_path(path)
201
+
202
+ unless File.directory?(path)
203
+ raise Error, <<-EOS
204
+ Root Path Not Found
205
+ When specifying a --root-path, the path must exist.
206
+ Path was: #{ path }
207
+ EOS
208
+ end
209
+ @root_path = path
210
+ end
211
+
212
+
213
+
214
+ def set_variable(name, v)
215
+ #instance_variable_set(:"@#{name}", v) if v
216
+ options[name] = v
217
+ end
218
+
219
+ def set_path_variable(name, path, ending, root_path)
220
+ # strip any trailing '/' in case the user supplied this as part of
221
+ # an absolute path, so we can match it against File.expand_path()
222
+ path = path.to_s.sub(/\/\s*$/, '').lstrip
223
+ new_path = false
224
+ # If no path is given, the variable will not be set/updated
225
+ # unless a root_path was given. In which case the value will
226
+ # be updated with our default ending.
227
+ if path.empty?
228
+ new_path = File.join(root_path, ending) if root_path
229
+ else
230
+ # When a path is given, the variable will be set/updated.
231
+ # If the path is relative, it will be joined with root_path (if given),
232
+ # or expanded relative to PWD.
233
+ new_path = File.expand_path(path)
234
+ unless path == new_path
235
+ new_path = File.join(root_path, path) if root_path
236
+ end
237
+ end
238
+ instance_variable_set(:"@#{name}", new_path) if new_path
239
+ end
240
+
241
+ #def reset!
242
+ # @root_path = File.join(File.expand_path(ENV['HOME'] || ''), 'DockerApp')
243
+ # update(:root_path => @root_path)
244
+ #end
245
+ end
246
+
247
+ #reset! # set defaults on load
248
+ end
249
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ module DockerApp
4
+ module Config
5
+ # Context for loading user config.rb and model files.
6
+ class DSL
7
+ #class Error < Backup::Error; end
8
+ #Server = DockerApp::Server
9
+
10
+ attr_reader :_config_options
11
+ attr_reader :_config_servers
12
+
13
+ def initialize
14
+ @_config_options = {}
15
+ @_config_servers = {}
16
+ end
17
+
18
+ # Allow users to set command line path options in config.rb
19
+ [:root_path, :tmp_path].each do |name|
20
+ define_method name, lambda {|path| _config_options[name] = path }
21
+ end
22
+
23
+ # options - common
24
+ [
25
+ :prefix, :image_prefix, :container_prefix, :service_prefix,
26
+ :dir_data
27
+ ].each do |name|
28
+ define_method name, lambda {|path| _config_options[name] = path }
29
+ end
30
+
31
+ # allowed options
32
+ [:common, :base].each do |name|
33
+ define_method name, lambda {|v| _config_options[name] = v }
34
+ end
35
+
36
+
37
+ def server(server_name, &block)
38
+ sc = ServerSettings.new
39
+ block.call(sc)
40
+ #sc.instance_eval(&block)
41
+ _config_servers[server_name] = sc
42
+ end
43
+
44
+ # Allows users to create preconfigured models.
45
+ =begin
46
+ def preconfigure(name, &block)
47
+ unless name.is_a?(String) && name =~ /^[A-Z]/
48
+ raise Error, "Preconfigured model names must be given as a string " +
49
+ "and start with a capital letter."
50
+ end
51
+
52
+ if DSL.const_defined?(name)
53
+ raise Error, "'#{ name }' is already in use " +
54
+ "and can not be used for a preconfigured model."
55
+ end
56
+
57
+ DSL.const_set(name, Class.new(Model))
58
+ DSL.const_get(name).preconfigure(&block)
59
+ end
60
+ =end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,99 @@
1
+ # encoding: utf-8
2
+ require 'ostruct'
3
+
4
+ module DockerApp
5
+ module Config
6
+ module Helpers
7
+
8
+ def self.included(klass)
9
+ klass.extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ def defaults
15
+ @defaults ||= Config::Defaults.new
16
+
17
+ if block_given?
18
+ yield @defaults
19
+ else
20
+ @defaults
21
+ end
22
+ end
23
+
24
+ # Used only within the specs
25
+ def clear_defaults!
26
+ defaults.reset!
27
+ end
28
+
29
+ def deprecations
30
+ @deprecations ||= {}
31
+ end
32
+
33
+ protected
34
+
35
+
36
+
37
+ end # ClassMethods
38
+
39
+ private
40
+
41
+ ##
42
+ # Sets any pre-configured default values.
43
+ # If a default value was set for an invalid accessor,
44
+ # this will raise a NameError.
45
+ def load_defaults!
46
+ self.class.defaults._attributes.each do |name|
47
+ val = self.class.defaults.send(name)
48
+ val = val.dup rescue val
49
+ send(:"#{ name }=", val)
50
+ end
51
+ end
52
+
53
+ ##
54
+ # Check missing methods for deprecated attribute accessors.
55
+ #
56
+ # If a value is set on an accessor that has been deprecated
57
+ # using #attr_deprecate, a warning will be issued and any
58
+ # :action (Proc) specified will be called with a reference to
59
+ # the class instance and the value set on the deprecated accessor.
60
+ # See #attr_deprecate and #log_deprecation_warning
61
+ #
62
+ # Note that OpenStruct (used for setting defaults) does not allow
63
+ # multiple arguments when assigning values for members.
64
+ # So, we won't allow it here either, even though an attr_accessor
65
+ # will accept and convert them into an Array. Therefore, setting
66
+ # an option value using multiple values, whether as a default or
67
+ # directly on the class' accessor, should not be supported.
68
+ # i.e. if an option will accept being set as an Array, then it
69
+ # should be explicitly set as such. e.g. option = [val1, val2]
70
+ #
71
+ def method_missing(name, *args)
72
+ if method = name.to_s.chomp!('=')
73
+ if (len = args.count) != 1
74
+ raise ArgumentError,
75
+ "wrong number of arguments (#{ len } for 1)", caller(1)
76
+ end
77
+ end
78
+
79
+ super
80
+ end
81
+
82
+ end # Helpers
83
+
84
+ # Store for pre-configured defaults.
85
+ class Defaults < OpenStruct
86
+ # Returns an Array of all attribute method names
87
+ # that default values were set for.
88
+ def _attributes
89
+ @table.keys
90
+ end
91
+
92
+ # Used only within the specs
93
+ def reset!
94
+ @table.clear
95
+ end
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,376 @@
1
+ module DockerApp
2
+ class ManagerContainer
3
+
4
+ def self.save_chef_config(settings)
5
+ require 'json'
6
+ filename = settings.filename_chef_config
7
+ FileUtils.mkdir_p(File.dirname(filename))
8
+ File.open(filename,"w+") do |f|
9
+ f.write(settings.all_attributes.to_json)
10
+ end
11
+
12
+ true
13
+ end
14
+
15
+
16
+ def self.save_config_json(settings)
17
+ require 'json'
18
+ filename = settings.filename_config_json
19
+ FileUtils.mkdir_p(File.dirname(filename))
20
+ File.open(filename,"w+") do |f|
21
+ f.write(settings.all_attributes.to_json)
22
+ end
23
+
24
+ true
25
+ end
26
+
27
+
28
+
29
+
30
+ ### run
31
+
32
+ def self.run_container(server_name, settings={})
33
+ puts "creating and running container.."
34
+ #settings = load_settings(server_name)
35
+
36
+ # generate config
37
+ save_config_json(settings)
38
+
39
+
40
+ # destroy
41
+ destroy_container(server_name, settings)
42
+
43
+ # create
44
+ create_container(settings)
45
+
46
+
47
+ # START && run provision after start
48
+ start_container(name, settings)
49
+
50
+
51
+ # TODO: systemd service
52
+ #res_service = _install_service_container(settings)
53
+
54
+
55
+ true
56
+ end
57
+
58
+ def self.create_container(settings)
59
+ # create
60
+ net_options = ""
61
+ networks = settings['docker'].fetch('network', {}).fetch('networks', [])
62
+ if networks && networks[0]
63
+ network = networks[0]
64
+ #puts "network=#{network}"
65
+ net_options << "--net #{network['net']} "
66
+ net_options << "--ip #{network['ip']} " if network['ip']
67
+ net_options << "--mac-address #{network['mac_address']} " if network['mac_address']
68
+ end
69
+
70
+
71
+ cmd %Q(docker create --name #{settings.container_name} #{net_options} #{settings.docker_ports_string} #{settings.docker_volumes_string} #{settings.docker_volumes_from_string} #{settings.docker_links_string} #{settings.run_extra_options_string} #{settings.run_env_variables_string} #{settings.image_name} #{settings['docker']['command']} #{settings['docker']['run_options']})
72
+
73
+ # network
74
+ setup_network(settings)
75
+ end
76
+
77
+
78
+ def self.setup_network(settings)
79
+ container_name = settings.container_name
80
+
81
+ # networks
82
+ networks = settings['docker'].fetch('network', {}).fetch('networks', [])
83
+ if networks
84
+ ind = 0
85
+ networks.each do |net|
86
+ ind = ind + 1
87
+
88
+ #
89
+ next if net['action']=='remove'
90
+
91
+ # skip first network
92
+ next if ind==1
93
+
94
+ # connect
95
+ ip = net['ip']
96
+ s_ip = "--ip #{ip}" if ip
97
+ #puts %Q(docker network connect #{s_ip} #{net['net']} #{settings.container_name})
98
+ cmd %Q(docker network connect #{s_ip} #{net['net']} #{settings.container_name})
99
+ end
100
+
101
+ # remove
102
+ networks.each do |net|
103
+ next unless net['action']=='remove'
104
+ cmd %Q(docker network disconnect #{net['net']} #{settings.container_name})
105
+ end
106
+ end
107
+ end
108
+
109
+
110
+
111
+
112
+ def self.start_container(name, settings)
113
+ ### BEFORE START
114
+ # run setup provision scripts
115
+ DockerApp::Provisioner::Base.run_provision_scripts_setup(settings)
116
+
117
+
118
+ ### start
119
+ cmd %Q(docker start #{settings.container_name})
120
+
121
+ # wait
122
+ wait_until_running(settings.container_name)
123
+
124
+ ### AFTER START
125
+
126
+ # setup
127
+ setup_container_after_start(settings)
128
+
129
+ # provision after start
130
+ # run bootstrap provision scripts
131
+ DockerApp::Provisioner::Base.run_provision_scripts_bootstrap(settings)
132
+
133
+ end
134
+
135
+
136
+ def self.wait_until_running(container_name)
137
+ retries = 10
138
+ until system("docker exec #{container_name} true") || retries < 0
139
+ sleep 1
140
+ retries = retries - 1
141
+ end
142
+
143
+ assert_container_running(container_name)
144
+ end
145
+
146
+ def self.assert_container_running(container_name)
147
+ res = system("docker exec #{container_name} true")
148
+ assert res, "Container #{container_name} is not running"
149
+ end
150
+
151
+
152
+ =begin
153
+ def self._prepare_provision_before_start_chef(settings, script)
154
+ puts "_prepare_provision_before_start_chef"
155
+
156
+ require_relative '../../lib/docker_app/provisioner/provisioner_chef'
157
+
158
+ provisioner = DockerApp::Provisioner::Chef.new(settings)
159
+ provisioner.copy_config_file
160
+
161
+ end
162
+ =end
163
+
164
+ def self.setup_container_after_start(settings)
165
+
166
+ # default gateway
167
+ network = settings['docker']['network']
168
+ if network
169
+ gateway = network['default_gateway']
170
+
171
+ if gateway
172
+ # fix default gateway
173
+ #cmd %Q(docker exec #{settings.container_name} ip route change default via #{gateway} dev eth1)
174
+ cmd %Q(docker exec #{settings.container_name} ip route change default via #{gateway})
175
+ end
176
+ end
177
+
178
+
179
+
180
+ # fix hosts
181
+ container_hosts = settings['docker']['hosts'] || []
182
+ container_hosts.each do |r|
183
+ #cmd %Q(docker exec #{settings.container_name} bash -c 'echo "#{r[0]} #{r[1]}" >> /etc/hosts')
184
+ cmd %Q(docker exec #{settings.container_name} sh -c 'echo "#{r[0]} #{r[1]}" >> /etc/hosts')
185
+ end
186
+ end
187
+
188
+
189
+
190
+
191
+
192
+
193
+ ### systemd service
194
+
195
+ def self._install_service_container(settings)
196
+ # not work
197
+ #cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} install_container_service.rb )
198
+
199
+ # work
200
+ #cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} -j config_run_install_container_service.json )
201
+
202
+ # work
203
+ #cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} --override-runlist 'recipe[server-api::install_container_service]' )
204
+
205
+ #
206
+ cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} -j config/config-#{settings.name}.json --override-runlist 'recipe[server-api::install_container_service]' )
207
+ end
208
+
209
+
210
+ def self._remove_service_container(settings)
211
+ cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} -j config/config-#{settings.name}.json --override-runlist 'recipe[server-api::remove_container_service]' )
212
+ end
213
+
214
+
215
+
216
+ =begin
217
+ def self._run_container_chef(settings)
218
+ # generate json config for chef
219
+ save_chef_config(settings)
220
+
221
+ # run chef
222
+ #s_run = %Q(cd #{settings.name} && chef-client -z -j config.json -c ../.chef/knife.rb -N #{settings.name} ../lib/chef_container_run.rb)
223
+
224
+ # good - 2016-nov-19
225
+ #cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} chef_run_container.rb)
226
+
227
+ #
228
+ res_chef = run_chef_recipe(settings, 'chef_run_container.rb')
229
+
230
+ res_chef
231
+ end
232
+
233
+ =end
234
+
235
+
236
+
237
+
238
+ ###
239
+
240
+ def self.destroy_container(server_name, settings)
241
+ puts "destroying container #{server_name}..."
242
+
243
+ # TODO: stop, remove systemd service
244
+ #res_service = _remove_service_container(settings)
245
+
246
+ #
247
+ cmd %Q(docker rm -f #{settings.container_name} )
248
+
249
+
250
+
251
+ # if chef
252
+ if settings['build']['build_type']=='chef'
253
+ return destroy_container_chef(settings)
254
+ end
255
+
256
+ #
257
+ return true
258
+ end
259
+
260
+
261
+ def self.destroy_container_chef(settings)
262
+ # destroy temp container
263
+ cmd %Q(docker rm -f chef-converge.#{settings.image_name} )
264
+
265
+ #
266
+ res_chef = run_chef_recipe(settings, 'chef_destroy_container.rb')
267
+ #cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} chef_destroy_container.rb)
268
+
269
+ #
270
+ chef_remove_data(settings)
271
+
272
+ end
273
+
274
+
275
+
276
+
277
+ ### stop container
278
+
279
+ def self.stop_container(server_name, settings)
280
+ puts "stopping container #{server_name}..."
281
+
282
+ #
283
+ cmd %Q(docker stop #{settings.container_name} )
284
+
285
+ #
286
+ return true
287
+ end
288
+
289
+
290
+ ### run task on running container
291
+ def self.exec_task(server_name, recipe_name)
292
+ #raise 'not implemented'
293
+
294
+ settings = load_settings(server_name)
295
+
296
+ # check script exists
297
+ script_path = "#{settings.name}/cookbooks/#{settings.name}/recipes/#{recipe_name}.rb"
298
+ f = File.expand_path('.', script_path)
299
+
300
+ if !File.exists?(f)
301
+ puts "script not found: #{f}. Skipping"
302
+ return false
303
+ end
304
+
305
+ #
306
+ cmd %Q(SERVER_NAME=#{settings.name} chef-client -z --override-runlist 'recipe[server-api::exec_container]' )
307
+ #cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} --override-runlist 'recipe[#{settings.name}::#{recipe_name}]' )
308
+ #cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} chef_exec_container.rb )
309
+
310
+ return true
311
+ end
312
+
313
+
314
+ ###
315
+ def self.clear_cache(name, settings)
316
+ # common cache
317
+ cmd("rm -rf ~/.chef/cache")
318
+ cmd("rm -rf ~/.chef/local-mode-cache")
319
+
320
+ # cache for server
321
+ cmd("rm -rf #{settings.dir_server_root}/.chef/local-mode-cache")
322
+ #cmd("rm -rf ~/.chef/package-cache")
323
+
324
+ # cache in gem
325
+ cmd("rm -rf #{Config.dir_gem_root}/lib/docker_app/.chef/local-mode-cache")
326
+
327
+
328
+ end
329
+
330
+ ###
331
+
332
+ def self.cmd(s)
333
+ Command.cmd(s)
334
+ end
335
+
336
+
337
+
338
+ ### helpers - chef
339
+
340
+ def self.run_chef_recipe(settings, recipe_rb)
341
+ cmd %Q(cd #{Config.root_path} && SERVER_NAME=#{settings.name} SERVER_PATH=#{settings.dir_server_root} chef exec chef-client -z -N #{settings.container_name} -j #{settings.filename_config_json} -c #{chef_config_knife_path} #{chef_recipe_path(recipe_rb)} )
342
+ end
343
+
344
+ def self.run_chef_recipe_server_recipe(settings, server_recipe)
345
+ cmd %Q(cd #{Config.root_path} && SERVER_NAME=#{settings.name} SERVER_PATH=#{settings.dir_server_root} chef exec chef-client -z -N #{settings.container_name} -c #{chef_config_knife_path} --override-runlist 'recipe[#{settings.name}::#{server_recipe}]' )
346
+ end
347
+
348
+
349
+ def self.chef_config_knife_path
350
+ "#{Config.dir_gem_root}/lib/docker_app/chef/.chef/knife.rb"
351
+ end
352
+
353
+ def self.chef_recipe_path(p)
354
+ "#{Config.dir_gem_root}/lib/docker_app/chef/#{p}"
355
+ end
356
+
357
+
358
+ def self.chef_remove_data(settings)
359
+ #
360
+ cmd %Q(cd #{Config.root_path} && chef exec knife node delete #{settings.chef_node_name} -y -c #{chef_config_knife_path})
361
+
362
+ # clean chef client, node
363
+ cmd %Q(cd #{Config.root_path} && rm -f #{settings.filename_chef_node_json} )
364
+ cmd %Q(cd #{Config.root_path} && rm -f #{settings.filename_chef_client_json} )
365
+ end
366
+
367
+
368
+ ### common helpers
369
+ def self.assert(expression, string = "Assert failed")
370
+ unless expression
371
+ throw Exception.new string
372
+ end
373
+ end
374
+
375
+ end
376
+ end