Skip to content

Commit

Permalink
Merge pull request #975 from nathanlcarlson/update_compose
Browse files Browse the repository at this point in the history
Use the docker-compose-plugin via 'docker compose' instead of 'docker-compose'
  • Loading branch information
Ramesh7 committed Jul 4, 2024
2 parents 715743d + e7bce6a commit 6a566e1
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 335 deletions.
30 changes: 14 additions & 16 deletions lib/puppet/provider/docker_compose/ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

has_command(:docker, 'docker')

has_command(:dockercompose, 'docker-compose')

def set_tmpdir
return unless resource[:tmpdir]

Expand All @@ -28,8 +26,8 @@ def exists?
set_tmpdir

# get merged config using docker-compose config
args = [compose_files, '-p', name, 'config'].insert(3, resource[:options]).compact
compose_output = Puppet::Util::Yaml.safe_load(execute([command(:dockercompose)] + args, combine: false), [Symbol])
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',
Expand Down Expand Up @@ -76,32 +74,32 @@ def get_image(service_name, compose_services)

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)
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_files, '-p', name, 'scale'].insert(3, resource[:options]).compact + instructions
dockercompose(args)
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_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)
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_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)
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

Expand Down
130 changes: 30 additions & 100 deletions manifests/compose.pp
Original file line number Diff line number Diff line change
Expand Up @@ -7,118 +7,48 @@
# @param version
# The version of Docker Compose to install.
#
# @param install_path
# The path where to install Docker Compose.
#
# @param symlink_name
# The name of the symlink created pointing to the actual docker-compose binary
# This allows use of own docker-compose wrapper scripts for the times it's
# necessary to set certain things before running the docker-compose binary
#
# @param proxy
# Proxy to use for downloading Docker Compose.
#
# @param base_url
# The base url for installation
# This allows use of a mirror that follows the same layout as the
# official repository
#
# @param raw_url
# Override the raw URL for installation
# The default is to build a URL from baseurl. If rawurl is set, the caller is
# responsible for ensuring the URL points to the correct version and
# architecture.
#
# @param curl_ensure
# Whether or not the curl package is ensured by this module.
#
class docker::compose (
Enum[present,absent] $ensure = present,
Optional[String] $version = $docker::params::compose_version,
Optional[String] $install_path = $docker::params::compose_install_path,
Optional[String] $symlink_name = $docker::params::compose_symlink_name,
Optional[Pattern['^((http[s]?)?:\/\/)?([^:^@]+:[^:^@]+@|)([\da-z\.-]+)\.([\da-z\.]{2,6})(:[\d])?([\/\w \.-]*)*\/?$']] $proxy = undef,
Optional[String] $base_url = $docker::params::compose_base_url,
Optional[String] $raw_url = undef,
Optional[Boolean] $curl_ensure = $docker::params::curl_ensure,
) inherits docker::params {
if $facts['os']['family'] == 'windows' {
$file_extension = '.exe'
$file_owner = 'Administrator'
} else {
$file_extension = ''
$file_owner = 'root'
}
Enum[present,absent] $ensure = present,
Optional[String] $version = undef,
) {
include docker

$docker_compose_location = "${install_path}/${symlink_name}${file_extension}"
$docker_compose_location_versioned = "${install_path}/docker-compose-${version}${file_extension}"
if $docker::manage_package {
include docker::params

if $ensure == 'present' {
if $raw_url != undef {
$docker_compose_url = $raw_url
} else {
$docker_compose_url = "${base_url}/${version}/docker-compose-${facts['kernel']}-${facts['os']['hardware']}${file_extension}"
$_version = $version ? {
undef => $docker::params::compose_version,
default => $version,
}

if $proxy != undef {
$proxy_opt = "--proxy ${proxy}"
if $_version and $ensure != 'absent' {
$package_ensure = $_version
} else {
$proxy_opt = ''
$package_ensure = $ensure
}

if $facts['os']['family'] == 'windows' {
$docker_download_command = "if (Invoke-WebRequest ${docker_compose_url} ${proxy_opt} -UseBasicParsing -OutFile \"${docker_compose_location_versioned}\") { exit 0 } else { exit 1}" # lint:ignore:140chars

$parameters = {
'proxy' => $proxy,
'docker_compose_url' => $docker_compose_url,
'docker_compose_location_versioned' => $docker_compose_location_versioned,
case $facts['os']['family'] {
'Debian': {
$_require = $docker::use_upstream_package_source ? {
true => [Apt::Source['docker'], Class['apt::update']],
false => undef,
}
}

exec { "Install Docker Compose ${version}":
command => epp('docker/windows/download_docker_compose.ps1.epp', $parameters),
provider => powershell,
creates => $docker_compose_location_versioned,
'RedHat': {
$_require = $docker::use_upstream_package_source ? {
true => Yumrepo['docker'],
false => undef,
}
}

file { $docker_compose_location:
ensure => 'link',
target => $docker_compose_location_versioned,
require => Exec["Install Docker Compose ${version}"],
}
} else {
if $curl_ensure {
stdlib::ensure_packages(['curl'])
}

exec { "Install Docker Compose ${version}":
path => '/usr/bin/',
cwd => '/tmp',
command => "curl -s -S -L ${proxy_opt} ${docker_compose_url} -o ${docker_compose_location_versioned}",
creates => $docker_compose_location_versioned,
require => Package['curl'],
'Windows': {
fail('The docker compose portion of this module is not supported on Windows')
}

file { $docker_compose_location_versioned:
owner => $file_owner,
mode => '0755',
seltype => 'container_runtime_exec_t',
require => Exec["Install Docker Compose ${version}"],
}

file { $docker_compose_location:
ensure => 'link',
target => $docker_compose_location_versioned,
require => File[$docker_compose_location_versioned],
default: {
fail('The docker compose portion of this module only works on Debian or RedHat')
}
}
} else {
file { $docker_compose_location_versioned:
ensure => absent,
}

file { $docker_compose_location:
ensure => absent,
package { 'docker-compose-plugin':
ensure => $package_ensure,
require => $_require,
}
}
}
7 changes: 1 addition & 6 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@
$dns = undef
$dns_search = undef
$proxy = undef
$compose_base_url = 'https://github.com/docker/compose/releases/download'
$compose_symlink_name = 'docker-compose'
$compose_version = undef
$no_proxy = undef
$execdriver = undef
$storage_driver = undef
Expand Down Expand Up @@ -90,16 +89,12 @@
$docker_command = 'docker'

if ($facts['os']['family'] == 'windows') {
$compose_install_path = "${facts['docker_program_files_path']}/Docker"
$compose_version = '1.29.2'
$docker_ee_package_name = 'Docker'
$machine_install_path = "${facts['docker_program_files_path']}/Docker"
$tls_cacert = "${facts['docker_program_data_path']}/docker/certs.d/ca.pem"
$tls_cert = "${facts['docker_program_data_path']}/docker/certs.d/server-cert.pem"
$tls_key = "${facts['docker_program_data_path']}/docker/certs.d/server-key.pem"
} else {
$compose_install_path = '/usr/local/bin'
$compose_version = '1.29.2'
$docker_ee_package_name = 'docker-ee'
$machine_install_path = '/usr/local/bin'
$tls_cacert = '/etc/docker/tls/ca.pem'
Expand Down
64 changes: 18 additions & 46 deletions spec/acceptance/compose_v3_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,21 @@

require 'spec_helper_acceptance'

if os[:family] == 'windows'
install_dir = '/cygdrive/c/Program Files/Docker'
file_extension = '.exe'
docker_args = 'docker_ee => true'
tmp_path = 'C:/cygwin64/tmp'
test_container = if %r{2019|2022}.match?(os[:release])
'nanoserver'
else
'nanoserver-sac2016'
end
else
docker_args = ''
install_dir = '/usr/local/bin'
file_extension = ''
tmp_path = '/tmp'
test_container = 'debian'
end
tmp_path = '/tmp'
test_container = 'debian'

describe 'docker compose' do
describe 'docker compose', :win_broken do
before(:all) do
retry_on_error_matching(60, 5, %r{connection failure running}) do
install_code = <<-CODE
class { 'docker': #{docker_args} }
class { 'docker::compose':
version => '1.23.2',
}
class { 'docker': }
class { 'docker::compose': }
CODE
apply_manifest(install_code, catch_failures: true)
end
end

context 'Creating compose v3 projects', :win_broken do
context 'Creating compose v3 projects' do
let(:install_pp) do
<<-MANIFEST
docker_compose { 'web':
Expand All @@ -51,15 +34,15 @@ class { 'docker::compose':
end

it 'has docker compose installed' do
run_shell('docker-compose --help', expect_failures: false)
run_shell('docker compose --help', expect_failures: false)
end

it 'finds a docker container' do
run_shell('docker inspect web_compose_test_1', expect_failures: false)
run_shell('docker inspect web-compose_test_1', expect_failures: false)
end
end

context 'creating compose projects with multi compose files', :win_broken do
context 'creating compose projects with multi compose files' do
before(:all) do
install_pp = <<-MANIFEST
docker_compose { 'web1':
Expand All @@ -75,11 +58,11 @@ class { 'docker::compose':
end

it "finds container with #{test_container} tag" do
run_shell("docker inspect web1_compose_test_1 | grep #{test_container}", acceptable_exit_codes: [0])
run_shell("docker inspect web1-compose_test_1 | grep #{test_container}", acceptable_exit_codes: [0])
end
end

context 'Destroying project with multiple compose files', :win_broken do
context 'Destroying project with multiple compose files' do
let(:destroy_pp) do
<<-MANIFEST
docker_compose { 'web1':
Expand All @@ -105,31 +88,26 @@ class { 'docker::compose':
end

it 'does not find a docker container' do
run_shell('docker inspect web1_compose_test_1', expect_failures: true)
run_shell('docker inspect web1-compose_test_1', expect_failures: true)
end
end

context 'Requesting a specific version of compose' do
let(:version) do
'1.21.2'
'2.25.0'
end

it 'is idempotent' do
pp = <<-MANIFEST
class { 'docker::compose':
version => '#{version}',
version => '#{version}-*',
}
MANIFEST
idempotent_apply(pp)
end

it 'has installed the requested version' do
if os[:family] == 'redhat' && os[:release].to_i == 7
run_shell('sudo mv /usr/local/bin/docker-compose /usr/bin/docker-compose')
run_shell('sudo chmod +x /usr/bin/docker-compose')
end
command = 'docker-compose --version'
command = "export PATH=/usr/local/bin:$PATH && #{command}" if os[:family] == 'redhat'
command = 'docker compose version'

run_shell(command, expect_failures: false) do |r|
expect(r.stdout).to match(%r{#{version}})
Expand All @@ -138,13 +116,9 @@ class { 'docker::compose':
end

context 'Removing docker compose' do
let(:version) do
'1.21.2'
end

after(:all) do
install_pp = <<-MANIFEST
class { 'docker': #{docker_args}}
class { 'docker': }
class { 'docker::compose': }
MANIFEST
apply_manifest(install_pp, catch_failures: true)
Expand All @@ -154,15 +128,13 @@ class { 'docker::compose': }
pp = <<-MANIFEST
class { 'docker::compose':
ensure => absent,
version => '#{version}',
}
MANIFEST
idempotent_apply(pp)
end

it 'has removed the relevant files' do
run_shell("test -e \"#{install_dir}/docker-compose#{file_extension}\"", expect_failures: true)
run_shell("test -e \"#{install_dir}/docker-compose-#{version}#{file_extension}\"", expect_failures: true)
it 'has removed the compose plugin' do
run_shell('docker compose version', expect_failures: true)
end
end
end
Loading

0 comments on commit 6a566e1

Please sign in to comment.