docker-app 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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,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
+