docker-builder 0.1.5
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 +11 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/Rakefile +140 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docker-builder.gemspec +36 -0
- data/examples/example-apps-php/.chef/knife.rb +6 -0
- data/examples/example-apps-php/config.rb +19 -0
- data/examples/example-apps-php/servers/apps-php/.chef/knife.rb +2 -0
- data/examples/example-apps-php/servers/apps-php/config.rb +69 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/README.md +1 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/metadata.rb +9 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/recipes/build.rb +43 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/recipes/install.rb +55 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/recipes/install_app.rb +27 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/recipes/install_host.rb +9 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/templates/index.html.erb +4 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/templates/nginx-sites/app.conf.erb +55 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/templates/nginx-sites/app.conf.erb.1 +55 -0
- data/examples/example-apps-php/servers/apps-php/cookbooks/apps-php/templates/nginx-sites/default.conf.erb +45 -0
- data/examples/example-apps-php/servers/apps-php/readme.md +0 -0
- data/examples/example-nginx/config.rb +19 -0
- data/examples/example-nginx/servers/nginx/.chef/knife.rb +8 -0
- data/examples/example-nginx/servers/nginx/config.rb +54 -0
- data/examples/example-nginx/servers/nginx/cookbooks/nginx/README.md +1 -0
- data/examples/example-nginx/servers/nginx/cookbooks/nginx/metadata.rb +9 -0
- data/examples/example-nginx/servers/nginx/cookbooks/nginx/recipes/build.rb +10 -0
- data/examples/example-nginx/servers/nginx/cookbooks/nginx/recipes/install.rb +28 -0
- data/examples/example-nginx/servers/nginx/cookbooks/nginx/recipes/install_host.rb +9 -0
- data/examples/example-nginx/servers/nginx/cookbooks/nginx/templates/index.html.erb +4 -0
- data/examples/example-nginx/servers/nginx/cookbooks/nginx/templates/nginx-sites/default.conf.erb +45 -0
- data/examples/example-nginx/servers/nginx/readme.md +0 -0
- data/examples/example-nginx/temp/ex_nginx.json +20 -0
- data/examples/example-nginx/temp/nginx.json +1 -0
- data/exe/docker-builder +20 -0
- data/install_local.sh +2 -0
- data/lib/docker_builder.rb +18 -0
- data/lib/docker_builder/chef/.chef/knife.rb +115 -0
- data/lib/docker_builder/chef/chef_build_image.copy0.rb +60 -0
- data/lib/docker_builder/chef/chef_destroy_image.copy0.rb +35 -0
- data/lib/docker_builder/cli.rb +346 -0
- data/lib/docker_builder/config.rb +199 -0
- data/lib/docker_builder/config/dsl.rb +48 -0
- data/lib/docker_builder/config/helpers.rb +99 -0
- data/lib/docker_builder/manager.rb +364 -0
- data/lib/docker_builder/server_settings.rb +286 -0
- data/lib/docker_builder/version.rb +3 -0
- data/lib/templates/example-chef/config.rb.erb +18 -0
- data/lib/templates/example-chef/servers/server1/.chef/knife.rb +8 -0
- data/lib/templates/example-chef/servers/server1/config.rb.erb +54 -0
- data/lib/templates/example-chef/servers/server1/cookbooks/server1/README.md +1 -0
- data/lib/templates/example-chef/servers/server1/cookbooks/server1/metadata.rb.erb +8 -0
- data/lib/templates/example-chef/servers/server1/cookbooks/server1/recipes/build.rb +10 -0
- data/lib/templates/example-chef/servers/server1/cookbooks/server1/recipes/install.rb +36 -0
- data/lib/templates/example-chef/servers/server1/cookbooks/server1/recipes/install_host.rb +9 -0
- data/lib/templates/example-chef/servers/server1/cookbooks/server1/templates/index.html.erb +5 -0
- data/lib/templates/example-chef/servers/server1/cookbooks/server1/templates/nginx-sites/default.conf.erb +45 -0
- data/readme.md +233 -0
- data/readme_developers.md +54 -0
- data/temp.sh +21 -0
- data/temp/app-php.json +1 -0
- data/temp/build.sh +29 -0
- data/temp/chef_build_image.rb +37 -0
- data/temp/chef_destroy_image.rb +16 -0
- data/temp/cookbooks/temp1/README.md +1 -0
- data/temp/cookbooks/temp1/metadata.rb +9 -0
- data/temp/cookbooks/temp1/recipes/build.rb +42 -0
- data/temp/run.sh +2 -0
- metadata +157 -0
@@ -0,0 +1,199 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'docker_builder/config/dsl'
|
3
|
+
require 'docker_builder/config/helpers'
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
module DockerBuilder
|
8
|
+
module Config
|
9
|
+
#class Error < DockerBuilder::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 :server, :root_path, :config_file, :tmp_path, :options
|
20
|
+
|
21
|
+
|
22
|
+
# Define on self, since it's a class method
|
23
|
+
def method_missing(method_sym, *arguments, &block)
|
24
|
+
# the first argument is a Symbol, so you need to_s it if you want to pattern match
|
25
|
+
if options.has_key?(method_sym)
|
26
|
+
return options[method_sym]
|
27
|
+
else
|
28
|
+
super
|
29
|
+
end
|
30
|
+
#if method_sym.to_s =~ /^find_by_(.*)$/
|
31
|
+
# find($1.to_sym => arguments.first)
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
# Loads the user's +config.rb+ and all model files.
|
38
|
+
def load(opts = {})
|
39
|
+
update(opts) # from the command line
|
40
|
+
|
41
|
+
unless File.exist?(config_file)
|
42
|
+
#raise Error, "Could not find configuration file: '#{config_file}'."
|
43
|
+
raise "Could not find configuration file: '#{config_file}'."
|
44
|
+
end
|
45
|
+
|
46
|
+
config = File.read(config_file)
|
47
|
+
|
48
|
+
#version = DockerBuilder::VERSION.split('.').first
|
49
|
+
#unless config =~ /^# Backup v#{ version }\.x Configuration$/
|
50
|
+
# raise Error, <<-EOS
|
51
|
+
# Invalid Configuration File
|
52
|
+
# EOS
|
53
|
+
#end
|
54
|
+
|
55
|
+
dsl = DSL.new
|
56
|
+
dsl.instance_eval(config, config_file)
|
57
|
+
|
58
|
+
update(dsl._config_options) # from config.rb
|
59
|
+
update(opts) # command line takes precedence
|
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
|
+
load_servers(opts)
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def dir_gem_root
|
72
|
+
return @dir_gem_root unless @dir_gem_root.nil?
|
73
|
+
|
74
|
+
#
|
75
|
+
spec = Gem::Specification.find_by_name("docker-builder")
|
76
|
+
@dir_gem_root = spec.gem_dir
|
77
|
+
|
78
|
+
@dir_gem_root
|
79
|
+
end
|
80
|
+
|
81
|
+
def options
|
82
|
+
return @options unless @options.nil?
|
83
|
+
|
84
|
+
@options = {}
|
85
|
+
@options
|
86
|
+
end
|
87
|
+
|
88
|
+
def servers
|
89
|
+
options[:servers]
|
90
|
+
end
|
91
|
+
|
92
|
+
def load_servers(opts)
|
93
|
+
# Identify all servers
|
94
|
+
if opts[:server]
|
95
|
+
options[:servers] = {opts[:server]=>{}}
|
96
|
+
else
|
97
|
+
# get from config
|
98
|
+
#options[:servers] = options[:servers]
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
# If :root_path is set in the options, all paths will be updated.
|
108
|
+
# Otherwise, only the paths given will be updated.
|
109
|
+
def update(opts = {})
|
110
|
+
#puts "update. opts=#{opts}"
|
111
|
+
|
112
|
+
# root_path
|
113
|
+
root_path = opts[:root_path].to_s.strip
|
114
|
+
|
115
|
+
#puts "root from opts = #{root_path}"
|
116
|
+
|
117
|
+
if root_path.empty?
|
118
|
+
#puts " set default"
|
119
|
+
root_path = File.path(Dir.getwd)
|
120
|
+
#puts "default root = #{root_path}"
|
121
|
+
end
|
122
|
+
|
123
|
+
new_root = root_path.empty? ? false : set_root_path(root_path)
|
124
|
+
|
125
|
+
puts "FINAL root= #{@root_path}"
|
126
|
+
#exit
|
127
|
+
|
128
|
+
DEFAULTS.each do |name, ending|
|
129
|
+
set_path_variable(name, options[name], ending, new_root)
|
130
|
+
end
|
131
|
+
|
132
|
+
# options
|
133
|
+
opts.each do |name, v|
|
134
|
+
set_variable(name, v)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Sets the @root_path to the given +path+ and returns it.
|
139
|
+
# Raises an error if the given +path+ does not exist.
|
140
|
+
def set_root_path(path)
|
141
|
+
#puts "set path = #{path}"
|
142
|
+
|
143
|
+
# allows #reset! to set the default @root_path,
|
144
|
+
# then use #update to set all other paths,
|
145
|
+
# without requiring that @root_path exist.
|
146
|
+
return @root_path if path == @root_path
|
147
|
+
|
148
|
+
path = File.expand_path(path)
|
149
|
+
|
150
|
+
#puts " res root path=#{path}"
|
151
|
+
|
152
|
+
unless File.directory?(path)
|
153
|
+
raise Error, <<-EOS
|
154
|
+
Root Path Not Found
|
155
|
+
When specifying a --root-path, the path must exist.
|
156
|
+
Path was: #{ path }
|
157
|
+
EOS
|
158
|
+
end
|
159
|
+
@root_path = path
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
|
164
|
+
def set_variable(name, v)
|
165
|
+
#instance_variable_set(:"@#{name}", v) if v
|
166
|
+
options[name] = v
|
167
|
+
end
|
168
|
+
|
169
|
+
def set_path_variable(name, path, ending, root_path)
|
170
|
+
# strip any trailing '/' in case the user supplied this as part of
|
171
|
+
# an absolute path, so we can match it against File.expand_path()
|
172
|
+
path = path.to_s.sub(/\/\s*$/, '').lstrip
|
173
|
+
new_path = false
|
174
|
+
# If no path is given, the variable will not be set/updated
|
175
|
+
# unless a root_path was given. In which case the value will
|
176
|
+
# be updated with our default ending.
|
177
|
+
if path.empty?
|
178
|
+
new_path = File.join(root_path, ending) if root_path
|
179
|
+
else
|
180
|
+
# When a path is given, the variable will be set/updated.
|
181
|
+
# If the path is relative, it will be joined with root_path (if given),
|
182
|
+
# or expanded relative to PWD.
|
183
|
+
new_path = File.expand_path(path)
|
184
|
+
unless path == new_path
|
185
|
+
new_path = File.join(root_path, path) if root_path
|
186
|
+
end
|
187
|
+
end
|
188
|
+
instance_variable_set(:"@#{name}", new_path) if new_path
|
189
|
+
end
|
190
|
+
|
191
|
+
#def reset!
|
192
|
+
# @root_path = File.join(File.expand_path(ENV['HOME'] || ''), 'DockerBuilder')
|
193
|
+
# update(:root_path => @root_path)
|
194
|
+
#end
|
195
|
+
end
|
196
|
+
|
197
|
+
#reset! # set defaults on load
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module DockerBuilder
|
4
|
+
module Config
|
5
|
+
# Context for loading user config.rb and model files.
|
6
|
+
class DSL
|
7
|
+
#class Error < Backup::Error; end
|
8
|
+
#Server = DockerBuilder::Server
|
9
|
+
|
10
|
+
attr_reader :_config_options
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@_config_options = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
# Allow users to set command line path options in config.rb
|
17
|
+
[:root_path, :tmp_path].each do |name|
|
18
|
+
define_method name, lambda {|path| _config_options[name] = path }
|
19
|
+
end
|
20
|
+
|
21
|
+
# allowed options
|
22
|
+
[:servers, :common, :base].each do |name|
|
23
|
+
define_method name, lambda {|v| _config_options[name] = v }
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
# Allows users to create preconfigured models.
|
29
|
+
=begin
|
30
|
+
def preconfigure(name, &block)
|
31
|
+
unless name.is_a?(String) && name =~ /^[A-Z]/
|
32
|
+
raise Error, "Preconfigured model names must be given as a string " +
|
33
|
+
"and start with a capital letter."
|
34
|
+
end
|
35
|
+
|
36
|
+
if DSL.const_defined?(name)
|
37
|
+
raise Error, "'#{ name }' is already in use " +
|
38
|
+
"and can not be used for a preconfigured model."
|
39
|
+
end
|
40
|
+
|
41
|
+
DSL.const_set(name, Class.new(Model))
|
42
|
+
DSL.const_get(name).preconfigure(&block)
|
43
|
+
end
|
44
|
+
=end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module DockerBuilder
|
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,364 @@
|
|
1
|
+
module DockerBuilder
|
2
|
+
class Manager
|
3
|
+
|
4
|
+
|
5
|
+
def self.load_settings(server_name, opts={})
|
6
|
+
settings = Settings.load_settings_for_server(server_name, opts)
|
7
|
+
|
8
|
+
settings.set 'name', server_name
|
9
|
+
|
10
|
+
settings
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.save_chef_config(settings)
|
14
|
+
require 'json'
|
15
|
+
filename = settings.filename_chef_config
|
16
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
17
|
+
File.open(filename,"w+") do |f|
|
18
|
+
f.write(settings.all_attributes.to_json)
|
19
|
+
end
|
20
|
+
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
###
|
26
|
+
def self.build_image(server_name, settings=nil)
|
27
|
+
puts "building image for #{server_name}..."
|
28
|
+
#puts "settings: #{settings}"
|
29
|
+
#puts "debug: #{settings['attributes']}"
|
30
|
+
|
31
|
+
#settings = load_settings(server_name)
|
32
|
+
|
33
|
+
if settings['build']['build_type']=='dockerfile'
|
34
|
+
return build_image_with_dockerfile(settings)
|
35
|
+
elsif settings['build']['build_type']=='chef'
|
36
|
+
return build_image_with_chef(settings)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.build_image_with_dockerfile(settings)
|
41
|
+
puts "build image with Dockerfile. Image: #{settings.image_name}"
|
42
|
+
|
43
|
+
name = settings['name']
|
44
|
+
|
45
|
+
cmd %Q(cd #{name} && docker build -t #{settings.image_name} . )
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.build_image_with_chef(settings)
|
50
|
+
puts "build image with chef"
|
51
|
+
|
52
|
+
# config json
|
53
|
+
save_chef_config(settings)
|
54
|
+
|
55
|
+
# check node
|
56
|
+
cmd %Q(cd #{Config.root_path} && chef exec knife node show #{settings.chef_node_name} -c #{chef_config_knife_path})
|
57
|
+
|
58
|
+
|
59
|
+
#cmd %Q(SERVER_NAME=#{settings.name} SERVER_PATH=#{settings.dir_server_root} chef exec chef-client -z -N #{settings.image_name} -j #{settings.filename_config_json} -c #{chef_config_knife_path} #{chef_recipe_path('chef_build_image.rb')} )
|
60
|
+
res_recipe = run_chef_recipe(settings, 'chef_build_image.rb')
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
### run
|
67
|
+
|
68
|
+
def self.run_container(server_name, settings={})
|
69
|
+
puts "creating and running container.."
|
70
|
+
#settings = load_settings(server_name)
|
71
|
+
|
72
|
+
# provision host before running container
|
73
|
+
res_install = _install_container_provision_host(settings)
|
74
|
+
|
75
|
+
# run container
|
76
|
+
res_run = _run_container(settings)
|
77
|
+
|
78
|
+
|
79
|
+
# TODO: systemd service
|
80
|
+
#res_service = _install_service_container(settings)
|
81
|
+
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
def self._install_container_provision_host(settings)
|
86
|
+
script_type = (settings['install']['host']['script_type'] rescue nil)
|
87
|
+
return true unless script_type
|
88
|
+
|
89
|
+
# run provision script on the host machine
|
90
|
+
if script_type=='chef_recipe'
|
91
|
+
return _install_container_provision_host_chef_recipe(settings)
|
92
|
+
else
|
93
|
+
# do nothing
|
94
|
+
end
|
95
|
+
|
96
|
+
true
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
#
|
101
|
+
def self._install_container_provision_host_chef_recipe(settings)
|
102
|
+
# run script on host machine
|
103
|
+
script_name = settings['install']['host']['script'] || 'install_host'
|
104
|
+
|
105
|
+
# check script exists
|
106
|
+
#script_path = "#{settings.name}/cookbooks/#{settings.name}/recipes/#{script_name}.rb"
|
107
|
+
#f = File.expand_path('.', script_path)
|
108
|
+
|
109
|
+
#if !File.exists?(f)
|
110
|
+
# puts "script not found: #{f}. Skipping"
|
111
|
+
# return false
|
112
|
+
#end
|
113
|
+
|
114
|
+
#puts "pwd= #{Dir.pwd}"
|
115
|
+
#puts "root = #{Config.root_path}"
|
116
|
+
#exit
|
117
|
+
|
118
|
+
#
|
119
|
+
res_chef = run_chef_recipe_server_recipe(settings, script_name)
|
120
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} --override-runlist 'recipe[#{settings.name}::#{script_name}]' )
|
121
|
+
|
122
|
+
return true
|
123
|
+
end
|
124
|
+
|
125
|
+
# run
|
126
|
+
def self._run_container(settings)
|
127
|
+
puts "run container ..."
|
128
|
+
|
129
|
+
script_type = (settings['install']['node']['script_type'] rescue nil)
|
130
|
+
|
131
|
+
if script_type && script_type=='chef_recipe'
|
132
|
+
# run container and provision with chef
|
133
|
+
_run_container_chef(settings)
|
134
|
+
|
135
|
+
# ???
|
136
|
+
#_provision_container_chef_recipe(settings)
|
137
|
+
else
|
138
|
+
#_run_container_docker(settings)
|
139
|
+
|
140
|
+
# docker run
|
141
|
+
cmd %Q(docker run -d --name #{settings.container_name} #{settings.docker_ports_string} #{settings.docker_volumes_string} #{settings.docker_volumes_from_string} #{settings.docker_links_string} #{settings.run_env_variables_string} #{settings.image_name} #{settings['docker']['command']} #{settings['docker']['run_options']})
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
# fix hosts
|
147
|
+
#puts "adding hosts..."
|
148
|
+
#puts "a= #{settings.attributes}"
|
149
|
+
|
150
|
+
container_hosts = settings.node['hosts'] || []
|
151
|
+
container_hosts.each do |r|
|
152
|
+
cmd %Q(docker exec #{settings.container_name} bash -c 'echo "#{r[0]} #{r[1]}" >> /etc/hosts')
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
true
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
### systemd service
|
161
|
+
|
162
|
+
def self._install_service_container(settings)
|
163
|
+
# not work
|
164
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} install_container_service.rb )
|
165
|
+
|
166
|
+
# work
|
167
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} -j config_run_install_container_service.json )
|
168
|
+
|
169
|
+
# work
|
170
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} --override-runlist 'recipe[server-api::install_container_service]' )
|
171
|
+
|
172
|
+
#
|
173
|
+
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]' )
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
def self._remove_service_container(settings)
|
178
|
+
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]' )
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
### provision
|
183
|
+
|
184
|
+
def self._provision_container_chef_recipe(settings)
|
185
|
+
puts "provisioning container #{settings.container_name}"
|
186
|
+
|
187
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} #{settings.name}/cookbooks/#{settings.name}/ )
|
188
|
+
end
|
189
|
+
|
190
|
+
=begin
|
191
|
+
|
192
|
+
def self._run_container_docker(settings)
|
193
|
+
|
194
|
+
end
|
195
|
+
=end
|
196
|
+
|
197
|
+
def self._run_container_chef(settings)
|
198
|
+
# generate json config for chef
|
199
|
+
save_chef_config(settings)
|
200
|
+
|
201
|
+
# run chef
|
202
|
+
#s_run = %Q(cd #{settings.name} && chef-client -z -j config.json -c ../.chef/knife.rb -N #{settings.name} ../lib/chef_container_run.rb)
|
203
|
+
#s_run = %Q(cd #{settings.name} && SERVER_NAME=#{settings.name} chef-client -z -j config.common.json -N #{settings.name} ../container.rb)
|
204
|
+
#s_run = %Q(cd #{settings.name} && SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} ../container.rb)
|
205
|
+
|
206
|
+
# good - 2016-nov-19
|
207
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} chef_run_container.rb)
|
208
|
+
|
209
|
+
#
|
210
|
+
res_chef = run_chef_recipe(settings, 'chef_run_container.rb')
|
211
|
+
|
212
|
+
res_chef
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
def self.destroy_image(server_name, settings={})
|
217
|
+
cmd %Q(docker rmi #{settings.image_name} )
|
218
|
+
cmd %Q(docker rm -f chef.converge.#{settings.image_name} )
|
219
|
+
|
220
|
+
# delete chef data
|
221
|
+
if settings['build']['build_type']=='chef'
|
222
|
+
return destroy_image_chef(settings)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
def self.destroy_image_chef(settings)
|
228
|
+
puts "destroying image with chef..."
|
229
|
+
|
230
|
+
# config json
|
231
|
+
save_chef_config(settings)
|
232
|
+
|
233
|
+
# destroy temp container
|
234
|
+
cmd %Q(docker rm -f chef-converge.#{settings.image_name} )
|
235
|
+
|
236
|
+
#
|
237
|
+
cmd %Q(cd #{Config.root_path} && chef exec knife node delete #{settings.chef_node_name} -y -c #{chef_config_knife_path})
|
238
|
+
|
239
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} chef_destroy_image.rb)
|
240
|
+
#cmd %Q(SERVER_NAME=#{settings.name} SERVER_PATH=#{settings.dir_server_root} chef exec chef-client -z -N #{settings.image_name} -j #{settings.filename_config_json} -c #{chef_config_knife_path} #{chef_recipe_path('chef_destroy_image.rb')} )
|
241
|
+
|
242
|
+
res_recipe = run_chef_recipe(settings, 'chef_destroy_image.rb')
|
243
|
+
|
244
|
+
chef_remove_data(settings)
|
245
|
+
|
246
|
+
# work - before 2016-nov-19
|
247
|
+
#cmd %Q(cd #{Config.root_path} && chef exec knife node delete #{settings.chef_node_name} -y -c #{chef_config_knife_path})
|
248
|
+
|
249
|
+
# clean chef client, node
|
250
|
+
#cmd %Q(cd #{Config.root_path} && rm -f #{settings.filename_chef_node_json} )
|
251
|
+
#cmd %Q(cd #{Config.root_path} && rm -f #{settings.filename_chef_client_json} )
|
252
|
+
end
|
253
|
+
|
254
|
+
###
|
255
|
+
|
256
|
+
|
257
|
+
def self.destroy_container(server_name, settings)
|
258
|
+
puts "destroying container #{server_name}..."
|
259
|
+
|
260
|
+
# TODO: stop, remove systemd service
|
261
|
+
#res_service = _remove_service_container(settings)
|
262
|
+
|
263
|
+
#
|
264
|
+
cmd %Q(docker rm -f #{settings.container_name} )
|
265
|
+
|
266
|
+
|
267
|
+
|
268
|
+
# if chef
|
269
|
+
if settings['build']['build_type']=='chef'
|
270
|
+
return destroy_container_chef(settings)
|
271
|
+
end
|
272
|
+
|
273
|
+
#
|
274
|
+
return true
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
def self.destroy_container_chef(settings)
|
279
|
+
#
|
280
|
+
res_chef = run_chef_recipe(settings, 'chef_destroy_container.rb')
|
281
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} chef_destroy_container.rb)
|
282
|
+
|
283
|
+
#
|
284
|
+
chef_remove_data(settings)
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
def self.start_container(server_name)
|
290
|
+
settings = load_settings(server_name)
|
291
|
+
|
292
|
+
#
|
293
|
+
cmd %Q(docker start #{settings.container_name} )
|
294
|
+
|
295
|
+
return true
|
296
|
+
end
|
297
|
+
|
298
|
+
### run task on running container
|
299
|
+
def self.exec_task(server_name, recipe_name)
|
300
|
+
#raise 'not implemented'
|
301
|
+
|
302
|
+
settings = load_settings(server_name)
|
303
|
+
|
304
|
+
# check script exists
|
305
|
+
script_path = "#{settings.name}/cookbooks/#{settings.name}/recipes/#{recipe_name}.rb"
|
306
|
+
f = File.expand_path('.', script_path)
|
307
|
+
|
308
|
+
if !File.exists?(f)
|
309
|
+
puts "script not found: #{f}. Skipping"
|
310
|
+
return false
|
311
|
+
end
|
312
|
+
|
313
|
+
#
|
314
|
+
cmd %Q(SERVER_NAME=#{settings.name} chef-client -z --override-runlist 'recipe[server-api::exec_container]' )
|
315
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} --override-runlist 'recipe[#{settings.name}::#{recipe_name}]' )
|
316
|
+
#cmd %Q(SERVER_NAME=#{settings.name} chef-client -z -N #{settings.name} chef_exec_container.rb )
|
317
|
+
|
318
|
+
return true
|
319
|
+
end
|
320
|
+
|
321
|
+
###
|
322
|
+
|
323
|
+
def self.cmd(s)
|
324
|
+
puts "running: #{s}"
|
325
|
+
|
326
|
+
res = nil
|
327
|
+
Bundler.with_clean_env do
|
328
|
+
res = `#{s}`
|
329
|
+
end
|
330
|
+
|
331
|
+
puts "#{res}"
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
### helpers - chef
|
336
|
+
|
337
|
+
def self.run_chef_recipe(settings, recipe_rb)
|
338
|
+
cmd %Q(cd #{Config.root_path} && SERVER_NAME=#{settings.name} SERVER_PATH=#{settings.dir_server_root} chef exec chef-client -z -N #{settings.image_name} -j #{settings.filename_config_json} -c #{chef_config_knife_path} #{chef_recipe_path(recipe_rb)} )
|
339
|
+
end
|
340
|
+
|
341
|
+
def self.run_chef_recipe_server_recipe(settings, server_recipe)
|
342
|
+
cmd %Q(cd #{Config.root_path} && SERVER_NAME=#{settings.name} SERVER_PATH=#{settings.dir_server_root} chef exec chef-client -z -N #{settings.image_name} -c #{chef_config_knife_path} --override-runlist 'recipe[#{settings.name}::#{server_recipe}]' )
|
343
|
+
end
|
344
|
+
|
345
|
+
|
346
|
+
def self.chef_config_knife_path
|
347
|
+
"#{Config.dir_gem_root}/lib/docker_builder/chef/.chef/knife.rb"
|
348
|
+
end
|
349
|
+
|
350
|
+
def self.chef_recipe_path(p)
|
351
|
+
"#{Config.dir_gem_root}/lib/docker_builder/chef/#{p}"
|
352
|
+
end
|
353
|
+
|
354
|
+
|
355
|
+
def self.chef_remove_data(settings)
|
356
|
+
#
|
357
|
+
cmd %Q(cd #{Config.root_path} && chef exec knife node delete #{settings.chef_node_name} -y -c #{chef_config_knife_path})
|
358
|
+
|
359
|
+
# clean chef client, node
|
360
|
+
cmd %Q(cd #{Config.root_path} && rm -f #{settings.filename_chef_node_json} )
|
361
|
+
cmd %Q(cd #{Config.root_path} && rm -f #{settings.filename_chef_client_json} )
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|