-
Notifications
You must be signed in to change notification settings - Fork 321
/
Copy pathruby.rb
94 lines (82 loc) · 2.93 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
# frozen_string_literal: true
require 'deep_merge'
Puppet::Type.type(:docker_stack).provide(:ruby) do
desc 'Support for Puppet running Docker Stacks'
mk_resource_methods
commands dockercmd: 'docker'
has_command(:docker, command(:dockercmd)) do
environment(HOME: '/root')
end
def exists?
Puppet.info("Checking for stack #{name}")
stack_services = {}
stack_containers = []
resource[:compose_files].each do |file|
compose_file = YAML.safe_load(File.read(file), [], [], true)
# rubocop:disable Style/StringLiterals
containers = docker([
'ps',
'--format',
"{{.Label \"com.docker.swarm.service.name\"}}-{{.Image}}",
'--filter',
"label=com.docker.stack.namespace=#{name}",
]).split("\n").each do |c|
c.slice!("#{name}_")
end
stack_containers.push(*containers)
stack_containers.uniq!
# rubocop:enable Style/StringLiterals
case compose_file['version']
when %r{^3(\.[0-7])?$}
stack_services.merge!(compose_file['services'])
else
raise(Puppet::Error, "Unsupported docker compose file syntax version \"#{compose_file['version']}\"!")
end
end
if stack_services.count != stack_containers.count
return false
end
counts = Hash[*stack_services.each.map { |key, array|
image = (array['image']) ? array['image'] : get_image(key, stack_services)
image = "#{image}:latest" unless image.include?(':')
Puppet.info("Checking for compose service #{key} #{image}")
["#{key}-#{image}", stack_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? }
false
else
true
end
end
def get_image(service_name, stack_services)
image = stack_services[service_name]['image']
unless image
if stack_services[service_name]['extends']
image = get_image(stack_services[service_name]['extends'], stack_services)
elsif stack_services[service_name]['build']
image = "#{name}_#{service_name}"
end
end
image
end
def create
Puppet.info("Running stack #{name}")
args = ['stack', 'deploy', compose_files, name].insert(1, bundle_file).insert(4, resource[:up_args]).compact
docker(args)
end
def destroy
Puppet.info("Removing docker stack #{name}")
rm_args = ['stack', 'rm', name]
docker(rm_args)
end
def bundle_file
return resource[:bundle_file].map { |x| ['-c', x] }.flatten unless resource[:bundle_file].nil?
end
def compose_files
resource[:compose_files].map { |x| ['-c', x] }.flatten
end
private
end