feat: initial commit
This commit is contained in:
commit
38f495e3f4
457 changed files with 40577 additions and 0 deletions
109
environments/production/thirdparty/docker/lib/puppet/provider/docker_compose/ruby.rb
vendored
Normal file
109
environments/production/thirdparty/docker/lib/puppet/provider/docker_compose/ruby.rb
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
# 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
|
||||
|
||||
has_command(:docker, 'docker')
|
||||
|
||||
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', compose_files, '-p', name, 'config'].insert(3, resource[:options]).compact
|
||||
compose_output = Puppet::Util::Yaml.safe_load(execute([command(:docker)] + args, combine: false), [Symbol])
|
||||
|
||||
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']
|
||||
|
||||
return false if compose_services.count != compose_containers.uniq.count
|
||||
|
||||
counts = Hash[*compose_services.each.map { |key, 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', compose_files, '-p', name, 'up', '-d', '--remove-orphans'].insert(3, resource[:options]).insert(5, resource[:up_args]).compact
|
||||
docker(args)
|
||||
return unless resource[:scale]
|
||||
|
||||
instructions = resource[:scale].map { |k, v| "#{k}=#{v}" }
|
||||
Puppet.info("Scaling compose project #{name}: #{instructions.join(' ')}")
|
||||
args = ['compose', compose_files, '-p', name, 'scale'].insert(3, resource[:options]).compact + instructions
|
||||
docker(args)
|
||||
end
|
||||
|
||||
def destroy
|
||||
Puppet.info("Removing all containers for compose project #{name}")
|
||||
kill_args = ['compose', compose_files, '-p', name, 'kill'].insert(3, resource[:options]).compact
|
||||
docker(kill_args)
|
||||
rm_args = ['compose', compose_files, '-p', name, 'rm', '--force', '-v'].insert(3, resource[:options]).compact
|
||||
docker(rm_args)
|
||||
end
|
||||
|
||||
def restart
|
||||
return unless exists?
|
||||
|
||||
Puppet.info("Rebuilding and Restarting all containers for compose project #{name}")
|
||||
kill_args = ['compose', compose_files, '-p', name, 'kill'].insert(3, resource[:options]).compact
|
||||
docker(kill_args)
|
||||
build_args = ['compose', compose_files, '-p', name, 'build'].insert(3, resource[:options]).compact
|
||||
docker(build_args)
|
||||
create
|
||||
end
|
||||
|
||||
def compose_files
|
||||
resource[:compose_files].map { |x| ['-f', x] }.flatten
|
||||
end
|
||||
end
|
95
environments/production/thirdparty/docker/lib/puppet/provider/docker_network/ruby.rb
vendored
Normal file
95
environments/production/thirdparty/docker/lib/puppet/provider/docker_network/ruby.rb
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'json'
|
||||
|
||||
Puppet::Type.type(:docker_network).provide(:ruby) do
|
||||
desc 'Support for Docker Networking'
|
||||
|
||||
mk_resource_methods
|
||||
|
||||
has_command(:docker, 'docker')
|
||||
|
||||
def network_conf
|
||||
flags = ['network', 'create']
|
||||
multi_flags = ->(values, format) {
|
||||
filtered = [values].flatten.compact
|
||||
filtered.map { |val| format % val }
|
||||
}
|
||||
|
||||
[
|
||||
['--driver=%s', :driver],
|
||||
['--subnet=%s', :subnet],
|
||||
['--gateway=%s', :gateway],
|
||||
['--ip-range=%s', :ip_range],
|
||||
['--ipam-driver=%s', :ipam_driver],
|
||||
['--aux-address=%s', :aux_address],
|
||||
['--opt=%s', :options],
|
||||
].each do |(format, key)|
|
||||
values = resource[key]
|
||||
new_flags = multi_flags.call(values, format)
|
||||
flags.concat(new_flags)
|
||||
end
|
||||
|
||||
if defined?(resource[:additional_flags])
|
||||
additional_flags = []
|
||||
if resource[:additional_flags].is_a?(String)
|
||||
additional_flags = resource[:additional_flags].split
|
||||
elsif resource[:additional_flags].is_a?(Array)
|
||||
additional_flags = resource[:additional_flags]
|
||||
end
|
||||
additional_flags.each do |additional_flag|
|
||||
flags << additional_flag
|
||||
end
|
||||
end
|
||||
|
||||
flags << resource[:name]
|
||||
end
|
||||
|
||||
def self.instances
|
||||
output = docker(['network', 'ls'])
|
||||
lines = output.split("\n")
|
||||
lines.shift # remove header row
|
||||
lines.map do |line|
|
||||
_, name, driver = line.split
|
||||
inspect = docker(['network', 'inspect', name])
|
||||
obj = JSON.parse(inspect).first
|
||||
ipam_driver = (obj['IPAM']['Driver'] unless obj['IPAM']['Driver'].nil?)
|
||||
subnet = (obj['IPAM']['Config'].first['Subnet'] if !(obj['IPAM']['Config'].nil? || obj['IPAM']['Config'].empty?) && (obj['IPAM']['Config'].first.key? 'Subnet'))
|
||||
new(
|
||||
name: name,
|
||||
id: obj['Id'],
|
||||
ipam_driver: ipam_driver,
|
||||
subnet: subnet,
|
||||
ensure: :present,
|
||||
driver: driver,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
instances.each do |prov|
|
||||
if resource = resources[prov.name] # rubocop:disable Lint/AssignmentInCondition
|
||||
resource.provider = prov
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def flush
|
||||
raise Puppet::Error, _('Docker network does not support mutating existing networks') if !@property_hash.empty? && @property_hash[:ensure] != :absent
|
||||
end
|
||||
|
||||
def exists?
|
||||
Puppet.info("Checking if docker network #{name} exists")
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
def create
|
||||
Puppet.info("Creating docker network #{name}")
|
||||
docker(network_conf)
|
||||
end
|
||||
|
||||
def destroy
|
||||
Puppet.info("Removing docker network #{name}")
|
||||
docker(['network', 'rm', name])
|
||||
end
|
||||
end
|
88
environments/production/thirdparty/docker/lib/puppet/provider/docker_stack/ruby.rb
vendored
Normal file
88
environments/production/thirdparty/docker/lib/puppet/provider/docker_stack/ruby.rb
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
# 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
|
||||
|
||||
has_command(:docker, 'docker')
|
||||
|
||||
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
|
||||
|
||||
return false if stack_services.count != stack_containers.count
|
||||
|
||||
counts = Hash[*stack_services.each.map { |key, 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
|
||||
end
|
70
environments/production/thirdparty/docker/lib/puppet/provider/docker_volume/ruby.rb
vendored
Normal file
70
environments/production/thirdparty/docker/lib/puppet/provider/docker_volume/ruby.rb
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'json'
|
||||
|
||||
Puppet::Type.type(:docker_volume).provide(:ruby) do
|
||||
desc 'Support for Docker Volumes'
|
||||
|
||||
mk_resource_methods
|
||||
|
||||
has_command(:docker, 'docker')
|
||||
|
||||
def volume_conf
|
||||
flags = ['volume', 'create']
|
||||
multi_flags = ->(values, format) {
|
||||
filtered = [values].flatten.compact
|
||||
filtered.map { |val| format % val }
|
||||
}
|
||||
|
||||
[
|
||||
['--driver=%s', :driver],
|
||||
['--opt=%s', :options],
|
||||
].each do |(format, key)|
|
||||
values = resource[key]
|
||||
new_flags = multi_flags.call(values, format)
|
||||
flags.concat(new_flags)
|
||||
end
|
||||
flags << resource[:name]
|
||||
end
|
||||
|
||||
def self.instances
|
||||
output = docker(['volume', 'ls'])
|
||||
lines = output.split("\n")
|
||||
lines.shift # remove header row
|
||||
lines.map do |line|
|
||||
driver, name = line.split
|
||||
inspect = docker(['volume', 'inspect', name])
|
||||
obj = JSON.parse(inspect).first
|
||||
new(
|
||||
name: name,
|
||||
mountpoint: obj['Mountpoint'],
|
||||
options: obj['Options'],
|
||||
ensure: :present,
|
||||
driver: driver,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.prefetch(resources)
|
||||
instances.each do |prov|
|
||||
if (resource = resources[prov.name])
|
||||
resource.provider = prov
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def exists?
|
||||
Puppet.info("Checking if docker volume #{name} exists")
|
||||
@property_hash[:ensure] == :present
|
||||
end
|
||||
|
||||
def create
|
||||
Puppet.info("Creating docker volume #{name}")
|
||||
docker(volume_conf)
|
||||
end
|
||||
|
||||
def destroy
|
||||
Puppet.info("Removing docker volume #{name}")
|
||||
docker(['volume', 'rm', name])
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue