forked from puppetlabs/puppetlabs-docker
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathruby.rb
117 lines (98 loc) · 4.11 KB
/
ruby.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# frozen_string_literal: true
require 'deep_merge'
Puppet::Type.type(:docker_compose).provide(:ruby) do
desc 'Support for Puppet running Docker Compose'
mk_resource_methods
commands dockercompose: 'docker-compose'
commands dockercmd: 'docker'
has_command(:docker, command(:dockercmd)) do
environment(HOME: '/root')
end
has_command(:docker_compose, command(:dockercompose)) do
environment(HOME: '/root')
end
def set_tmpdir
return unless resource[:tmpdir]
# Check if the the tmpdir target exists
Puppet.warning("#{resource[:tmpdir]} (defined as docker_compose tmpdir) does not exist") unless Dir.exist?(resource[:tmpdir])
# Set TMPDIR environment variable only if defined among resources and exists
ENV['TMPDIR'] = resource[:tmpdir] if Dir.exist?(resource[:tmpdir])
end
def exists?
Puppet.info("Checking for compose project #{name}")
compose_services = {}
compose_containers = []
set_tmpdir
# get merged config using docker-compose config
args = [compose_files, '-p', name, 'config'].insert(3, resource[:options]).compact
compose_output = YAML.safe_load(execute([command(:dockercompose)] + args, combine: false))
# rubocop:disable Style/StringLiterals
containers = docker([
'ps',
'--format',
"{{.Label \"com.docker.compose.service\"}}-{{.Image}}",
'--filter',
"label=com.docker.compose.project=#{name}",
]).split("\n")
compose_containers.push(*containers)
compose_services = compose_output['services']
if compose_services.count != compose_containers.uniq.count
return false
end
counts = Hash[*compose_services.each.map { |key, array|
image = (array['image']) ? array['image'] : get_image(key, compose_services)
Puppet.info("Checking for compose service #{key} #{image}")
[key, compose_containers.count("#{key}-#{image}")]
}.flatten]
# No containers found for the project
if counts.empty? ||
# Containers described in the compose file are not running
counts.any? { |_k, v| v.zero? } ||
# The scaling factors in the resource do not match the number of running containers
resource[:scale] && counts.merge(resource[:scale]) != counts
false
else
true
end
end
def get_image(service_name, compose_services)
image = compose_services[service_name]['image']
unless image
if compose_services[service_name]['extends']
image = get_image(compose_services[service_name]['extends'], compose_services)
elsif compose_services[service_name]['build']
image = "#{name}_#{service_name}"
end
end
image
end
def create
Puppet.info("Running compose project #{name}")
args = [compose_files, '-p', name, 'up', '-d', '--remove-orphans'].insert(3, resource[:options]).insert(5, resource[:up_args]).compact
dockercompose(args)
return unless resource[:scale]
instructions = resource[:scale].map { |k, v| "#{k}=#{v}" }
Puppet.info("Scaling compose project #{name}: #{instructions.join(' ')}")
args = [compose_files, '-p', name, 'scale'].insert(3, resource[:options]).compact + instructions
dockercompose(args)
end
def destroy
Puppet.info("Removing all containers for compose project #{name}")
kill_args = [compose_files, '-p', name, 'kill'].insert(3, resource[:options]).compact
dockercompose(kill_args)
rm_args = [compose_files, '-p', name, 'rm', '--force', '-v'].insert(3, resource[:options]).compact
dockercompose(rm_args)
end
def restart
return unless exists?
Puppet.info("Rebuilding and Restarting all containers for compose project #{name}")
kill_args = [compose_files, '-p', name, 'kill'].insert(3, resource[:options]).compact
dockercompose(kill_args)
build_args = [compose_files, '-p', name, 'build'].insert(3, resource[:options]).compact
dockercompose(build_args)
create
end
def compose_files
resource[:compose_files].map { |x| ['-f', x] }.flatten
end
end