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.
- 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/bin/console +14 -0
- data/bin/setup +8 -0
- data/docker-app.gemspec +36 -0
- data/exe/docker-app +20 -0
- data/lib/docker_app.rb +23 -0
- data/lib/docker_app/builder/packer.rb +105 -0
- data/lib/docker_app/chef/.chef/knife.rb +118 -0
- data/lib/docker_app/chef/chef_build_image.rb +55 -0
- data/lib/docker_app/chef/chef_destroy_container.rb +13 -0
- data/lib/docker_app/chef/chef_destroy_image.rb +17 -0
- data/lib/docker_app/chef/chef_exec_container.rb +16 -0
- data/lib/docker_app/chef/chef_run_container.rb +64 -0
- data/lib/docker_app/chef/install_container_service.rb +14 -0
- data/lib/docker_app/cli.rb +502 -0
- data/lib/docker_app/command.rb +16 -0
- data/lib/docker_app/config.rb +249 -0
- data/lib/docker_app/config/dsl.rb +64 -0
- data/lib/docker_app/config/helpers.rb +99 -0
- data/lib/docker_app/manager_container.rb +376 -0
- data/lib/docker_app/manager_image.rb +119 -0
- data/lib/docker_app/manager_swarm.rb +66 -0
- data/lib/docker_app/provisioner/base.rb +179 -0
- data/lib/docker_app/provisioner/chef.rb +93 -0
- data/lib/docker_app/server_settings.rb +361 -0
- data/lib/docker_app/version.rb +3 -0
- data/lib/templates/example-chef/.chef/knife.rb +5 -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 +853 -0
- data/readme_developers.md +54 -0
- metadata +129 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
module DockerApp
|
2
|
+
class ManagerImage
|
3
|
+
|
4
|
+
###
|
5
|
+
def self.build_image(server_name, settings=nil)
|
6
|
+
puts "building image for #{server_name}..."
|
7
|
+
#puts "settings: #{settings}"
|
8
|
+
#puts "debug: #{settings['properties']}"
|
9
|
+
|
10
|
+
#settings = load_settings(server_name)
|
11
|
+
|
12
|
+
t = settings['build']['build_type']
|
13
|
+
if t=='' || t=='none'
|
14
|
+
#
|
15
|
+
puts "no build needed..."
|
16
|
+
|
17
|
+
elsif t.downcase=='dockerfile'
|
18
|
+
return build_image_with_dockerfile(settings)
|
19
|
+
elsif t.downcase=='github'
|
20
|
+
return build_image_with_dockerfile_github(settings)
|
21
|
+
|
22
|
+
elsif t=='chef'
|
23
|
+
return build_image_with_chef(settings)
|
24
|
+
elsif t=='packer'
|
25
|
+
return build_image_with_packer(settings)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.build_image_with_dockerfile(settings)
|
30
|
+
puts "build image with Dockerfile"
|
31
|
+
|
32
|
+
#cmd %Q(cd #{name} && docker build -t #{settings.image_name} . )
|
33
|
+
cmd %Q(docker build -t #{settings.image_name} #{settings.dir_server_root} )
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.build_image_with_dockerfile_github(settings)
|
38
|
+
puts "build image with Dockerfile from github"
|
39
|
+
|
40
|
+
cmd %Q(docker build -t #{settings.image_name} #{settings.properties['build']['base_image']['repository']} )
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def self.build_image_with_chef(settings)
|
46
|
+
puts "build image with chef"
|
47
|
+
|
48
|
+
# config json
|
49
|
+
save_chef_config(settings)
|
50
|
+
|
51
|
+
# check node
|
52
|
+
cmd %Q(cd #{Config.root_path} && chef exec knife node show #{settings.chef_node_name} -c #{chef_config_knife_path})
|
53
|
+
|
54
|
+
|
55
|
+
#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')} )
|
56
|
+
res_recipe = run_chef_recipe(settings, 'chef_build_image.rb')
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def self.build_image_with_packer(settings)
|
61
|
+
require_relative '../../lib/docker_app/builder/packer'
|
62
|
+
|
63
|
+
puts "build image with packer"
|
64
|
+
|
65
|
+
builder = DockerApp::Builder::Packer.new(settings)
|
66
|
+
builder.build
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def self.destroy_image(server_name, settings={})
|
71
|
+
puts "destroying image for server #{server_name}"
|
72
|
+
|
73
|
+
cmd %Q(docker rmi #{settings.image_name} )
|
74
|
+
cmd %Q(docker rm -f chef.converge.#{settings.image_name} )
|
75
|
+
|
76
|
+
# delete chef data
|
77
|
+
if settings['build']['build_type']=='chef'
|
78
|
+
return destroy_image_chef(settings)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def self.destroy_image_chef(settings)
|
84
|
+
puts "destroying image with chef..."
|
85
|
+
|
86
|
+
# config json
|
87
|
+
save_chef_config(settings)
|
88
|
+
|
89
|
+
# destroy temp container
|
90
|
+
cmd %Q(docker rm -f chef-converge.#{settings.image_name} )
|
91
|
+
|
92
|
+
#
|
93
|
+
cmd %Q(cd #{Config.root_path} && chef exec knife node delete #{settings.chef_node_name} -y -c #{chef_config_knife_path})
|
94
|
+
|
95
|
+
res_recipe = run_chef_recipe(settings, 'chef_destroy_image.rb')
|
96
|
+
|
97
|
+
chef_remove_data(settings)
|
98
|
+
|
99
|
+
# work - before 2016-nov-19
|
100
|
+
#cmd %Q(cd #{Config.root_path} && chef exec knife node delete #{settings.chef_node_name} -y -c #{chef_config_knife_path})
|
101
|
+
|
102
|
+
# clean chef client, node
|
103
|
+
#cmd %Q(cd #{Config.root_path} && rm -f #{settings.filename_chef_node_json} )
|
104
|
+
#cmd %Q(cd #{Config.root_path} && rm -f #{settings.filename_chef_client_json} )
|
105
|
+
end
|
106
|
+
|
107
|
+
###
|
108
|
+
|
109
|
+
def self.image_exist?(settings)
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
###
|
114
|
+
def self.cmd(s)
|
115
|
+
Command.cmd(s)
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module DockerApp
|
2
|
+
class ManagerSwarm
|
3
|
+
|
4
|
+
def self.destroy_service(server_name, settings)
|
5
|
+
puts "destroying service #{server_name}..."
|
6
|
+
|
7
|
+
#
|
8
|
+
cmd %Q(docker service rm #{settings.service_name} )
|
9
|
+
|
10
|
+
#
|
11
|
+
return true
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def self.create_service(server_name, settings={})
|
16
|
+
puts "create swarm service.."
|
17
|
+
|
18
|
+
# destroy
|
19
|
+
destroy_service(server_name, settings)
|
20
|
+
|
21
|
+
|
22
|
+
# prepare
|
23
|
+
create_volumes_dirs(settings)
|
24
|
+
|
25
|
+
# create service
|
26
|
+
docker_opts = settings.properties['docker']
|
27
|
+
|
28
|
+
run_opts = []
|
29
|
+
run_opts << "--network #{docker_opts['swarm_network']}" if docker_opts['swarm_network']
|
30
|
+
run_opts << settings.docker_ports_string
|
31
|
+
run_opts << settings.run_env_variables_string
|
32
|
+
|
33
|
+
# volumes
|
34
|
+
#--mount type=bind,source=/path/on/host,destination=/path/in/container
|
35
|
+
run_opts << settings.docker_volumes.map{|r| "--mount type=bind,source=#{r[0]},destination=#{r[1]}" }.join(' ')
|
36
|
+
|
37
|
+
#
|
38
|
+
run_opts << docker_opts['swarm_options']
|
39
|
+
|
40
|
+
cmd %Q(docker service create \
|
41
|
+
--name #{settings.service_name} \
|
42
|
+
#{run_opts.join(' ')} \
|
43
|
+
#{settings.image_name} #{settings['docker']['command']}
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# volumes
|
49
|
+
def self.create_volumes_dirs(settings)
|
50
|
+
settings.docker_volumes.each do |r|
|
51
|
+
dirpath = "#{r[0]}"
|
52
|
+
if !Dir.exists?(dirpath)
|
53
|
+
FileUtils.mkdir_p(dirpath) rescue nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# helpers
|
59
|
+
|
60
|
+
def self.cmd(s)
|
61
|
+
Command.cmd(s)
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module DockerApp
|
2
|
+
module Provisioner
|
3
|
+
class Base
|
4
|
+
|
5
|
+
def self.run_provision_scripts_setup(settings)
|
6
|
+
#
|
7
|
+
setup_scripts = (settings['provision']['setup'] rescue [])
|
8
|
+
if setup_scripts
|
9
|
+
setup_scripts.each do |script|
|
10
|
+
_run_setup_script(settings, script)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def self.run_provision_scripts_bootstrap(settings)
|
18
|
+
#
|
19
|
+
bootstrap_scripts = (settings['provision']['bootstrap'] rescue [])
|
20
|
+
if bootstrap_scripts
|
21
|
+
bootstrap_scripts.each do |script|
|
22
|
+
_run_bootstrap_script(settings, script)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
=begin
|
28
|
+
# commented - 2017-02-22
|
29
|
+
|
30
|
+
#
|
31
|
+
install_node_script_type = (settings['install']['node']['script_type'] rescue nil)
|
32
|
+
install_bootstrap_script = (settings['install']['bootstrap']['script'] rescue nil)
|
33
|
+
|
34
|
+
if install_node_script_type && install_node_script_type=='chef_recipe'
|
35
|
+
# run container and provision with chef
|
36
|
+
#_run_container_chef(settings)
|
37
|
+
|
38
|
+
# ???
|
39
|
+
#_provision_container_chef_recipe(settings)
|
40
|
+
|
41
|
+
elsif install_node_script_type && install_node_script_type=='shell'
|
42
|
+
# docker run
|
43
|
+
#create_and_run_container(settings)
|
44
|
+
|
45
|
+
# provision with shell script
|
46
|
+
run_shell_script_in_container(settings, "install.sh")
|
47
|
+
|
48
|
+
else
|
49
|
+
# no script for provision
|
50
|
+
#_run_container_docker(settings)
|
51
|
+
|
52
|
+
# docker run
|
53
|
+
#create_and_run_container(settings)
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
# bootstrap
|
58
|
+
if install_bootstrap_script
|
59
|
+
#script = settings['install']['bootstrap']['script'] || '/opt/bootstrap/bootstrap.sh'
|
60
|
+
|
61
|
+
# bootstsrap with shell script
|
62
|
+
run_bootstrap_shell_script_in_container(settings, install_bootstrap_script)
|
63
|
+
end
|
64
|
+
=end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
### provision - setup
|
72
|
+
|
73
|
+
def self._run_setup_script(settings, script)
|
74
|
+
puts "run script #{script}"
|
75
|
+
|
76
|
+
if script['type']=='shell'
|
77
|
+
return _run_setup_script_on_host_shell(settings, script)
|
78
|
+
elsif script['type']=='chef'
|
79
|
+
return _run_setup_script_on_host_chef(settings, script)
|
80
|
+
end
|
81
|
+
|
82
|
+
return nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def self._run_setup_script_on_host_shell(settings, script)
|
86
|
+
cmd %Q(cd #{settings.dir_server_root} && #{script['script']} )
|
87
|
+
end
|
88
|
+
|
89
|
+
def self._run_setup_script_on_host_chef(settings, script)
|
90
|
+
raise 'NOT implemented'
|
91
|
+
|
92
|
+
# run script on host machine
|
93
|
+
script_name = settings['install']['host']['script'] || 'install_host'
|
94
|
+
|
95
|
+
# check script exists
|
96
|
+
#script_path = "#{settings.name}/cookbooks/#{settings.name}/recipes/#{script_name}.rb"
|
97
|
+
#f = File.expand_path('.', script_path)
|
98
|
+
|
99
|
+
#if !File.exists?(f)
|
100
|
+
# puts "script not found: #{f}. Skipping"
|
101
|
+
# return false
|
102
|
+
#end
|
103
|
+
|
104
|
+
#puts "pwd= #{Dir.pwd}"
|
105
|
+
#puts "root = #{Config.root_path}"
|
106
|
+
#exit
|
107
|
+
|
108
|
+
#
|
109
|
+
|
110
|
+
return true
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
### provision - bootstrap
|
117
|
+
|
118
|
+
def self._run_bootstrap_script(settings, script)
|
119
|
+
puts "run BS script #{script}"
|
120
|
+
|
121
|
+
if script['type']=='shell' && script['run_from']=='host'
|
122
|
+
return _run_bootstrap_script_on_host_shell(settings, script)
|
123
|
+
elsif script['type']=='shell' && (script['run_from'].nil? || script['run_from']=='')
|
124
|
+
_run_bootstrap_script_in_container_shell(settings, script)
|
125
|
+
elsif script['type']=='chef'
|
126
|
+
_run_bootstrap_script_in_container_chef(settings, script)
|
127
|
+
end
|
128
|
+
|
129
|
+
return nil
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
def self._run_bootstrap_script_on_host_shell(settings, script)
|
134
|
+
cmd %Q(cd #{settings.dir_server_root} && #{script['script']} )
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
def self._run_bootstrap_script_in_container_shell(settings, script)
|
140
|
+
script_path = script['script']
|
141
|
+
|
142
|
+
# exec
|
143
|
+
cmd %Q(docker exec #{settings.container_name} #{script_path} )
|
144
|
+
end
|
145
|
+
|
146
|
+
def self._run_bootstrap_script_in_container_chef(settings, script)
|
147
|
+
req = DockerApp::Provisioner::Chef.new(settings)
|
148
|
+
return req.run_recipe_in_container script['dir_base'], script['recipe_name']
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
### helpers - shell
|
154
|
+
|
155
|
+
def self.run_script_in_container_shell(settings, script_name)
|
156
|
+
script_path = settings.make_path_full("scripts/#{script_name}")
|
157
|
+
|
158
|
+
# copy
|
159
|
+
cmd %Q(cd #{Config.root_path} && docker cp #{script_path} #{settings.container_name}:/tmp/#{script_name} )
|
160
|
+
|
161
|
+
# exec
|
162
|
+
cmd %Q(docker exec #{settings.container_name} chmod +x /tmp/#{script_name} )
|
163
|
+
cmd %Q(docker exec #{settings.container_name} /tmp/#{script_name} )
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
###
|
171
|
+
def self.cmd(s)
|
172
|
+
Command.cmd(s)
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module DockerApp
|
2
|
+
module Provisioner
|
3
|
+
class Chef
|
4
|
+
|
5
|
+
attr_accessor :server
|
6
|
+
|
7
|
+
def server=(v)
|
8
|
+
@server = v
|
9
|
+
@server
|
10
|
+
end
|
11
|
+
|
12
|
+
def server
|
13
|
+
@server
|
14
|
+
end
|
15
|
+
|
16
|
+
def settings
|
17
|
+
server
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def initialize(_settings)
|
22
|
+
self.server = _settings
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
###
|
27
|
+
|
28
|
+
def copy_config_file
|
29
|
+
# config json
|
30
|
+
save_config
|
31
|
+
|
32
|
+
# copy to container
|
33
|
+
DockerApp::Command.cmd %Q(docker cp #{filename_config} #{settings.container_name}:#{docker_filename_config})
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def save_config
|
38
|
+
require 'json'
|
39
|
+
filename = filename_config
|
40
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
41
|
+
File.open(filename,"w+") do |f|
|
42
|
+
f.write(build_config.to_json)
|
43
|
+
end
|
44
|
+
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
def filename_config
|
49
|
+
File.join(Config.root_path, 'temp', "bootstrap-#{settings.name}.json")
|
50
|
+
end
|
51
|
+
|
52
|
+
def docker_filename_config
|
53
|
+
"/opt/bootstrap/config.json"
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_config
|
57
|
+
res = {}
|
58
|
+
|
59
|
+
attr = settings.properties['attributes']
|
60
|
+
res = attr
|
61
|
+
|
62
|
+
#res = settings.all_attributes
|
63
|
+
|
64
|
+
res
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
### run recipes
|
69
|
+
def run_recipe_in_container(dir_base, recipe_name)
|
70
|
+
|
71
|
+
recipe_name ||= "server::bootstrap"
|
72
|
+
|
73
|
+
# generate config
|
74
|
+
copy_config_file
|
75
|
+
|
76
|
+
|
77
|
+
#
|
78
|
+
q = %Q(cd #{dir_base} && chef-client -z -j #{docker_filename_config} --override-runlist "recipe[#{recipe_name}]" )
|
79
|
+
|
80
|
+
# exec
|
81
|
+
docker_run_cmd q
|
82
|
+
end
|
83
|
+
|
84
|
+
###
|
85
|
+
def docker_run_cmd(s)
|
86
|
+
DockerApp::Command.cmd %Q(docker exec #{settings.container_name} bash -c '#{s}')
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|