From 272e68c43e280ef322024452254b2ad4d110af34 Mon Sep 17 00:00:00 2001 From: MarkW Date: Thu, 27 Sep 2018 10:50:50 +0100 Subject: [PATCH 1/7] CLOUD-2146-cleanup-of-cocker-compose-acceptance-tests (#341) --- spec/acceptance/compose_spec.rb | 123 ----------------------------- spec/acceptance/compose_v2_spec.rb | 120 ---------------------------- spec/spec_helper_acceptance.rb | 32 -------- 3 files changed, 275 deletions(-) delete mode 100644 spec/acceptance/compose_spec.rb delete mode 100644 spec/acceptance/compose_v2_spec.rb diff --git a/spec/acceptance/compose_spec.rb b/spec/acceptance/compose_spec.rb deleted file mode 100644 index 07813712..00000000 --- a/spec/acceptance/compose_spec.rb +++ /dev/null @@ -1,123 +0,0 @@ -require 'spec_helper_acceptance' - -broken = false - -if fact('osfamily') == 'windows' - puts "Not implemented on Windows" - broken = true -elsif fact('osfamily') == 'RedHat' - docker_args = "repo_opt => '--enablerepo=localmirror-extras'" -end - -describe 'docker compose', :win_broken => broken do - before(:all) do - install_code = <<-code - class { 'docker': #{docker_args}} - class { 'docker::compose': } - code - apply_manifest(install_code, :catch_failures=>true) - end - - describe command("docker-compose --help") do - its(:exit_status) { should eq 0 } - end - - context 'Creating compose projects' do - before(:all) do - @install = <<-code -docker_compose { 'test3': - compose_files => ['#{tmp_path}/docker-compose.yml'], - ensure => present, -} - code - apply_manifest(@install, :catch_failures=>true) - end - - it 'should be idempotent' do - apply_manifest(@install, :catch_changes=>true) - end - - describe command("docker inspect test3_compose_test_1"), :sudo => true do - its(:exit_status) { should eq 0 } - end - end - - context 'Destroying compose projects' do - before(:all) do - install = <<-code -docker_compose { 'test4': - compose_files => ['#{tmp_path}/docker-compose.yml'], - ensure => present, -} - code - apply_manifest(install, :catch_failures=>true) - @uninstall = <<-code -docker_compose { 'test4': - compose_files => ['#{tmp_path}/docker-compose.yml'], - ensure => absent, -} - code - apply_manifest(@uninstall, :catch_failures=>true) - end - - it 'should be idempotent' do - apply_manifest(@uninstall, :catch_changes=>true) - end - - describe command("docker inspect test4_compose_test_1"), :sudo => true do - its(:exit_status) { should eq 1 } - end - end - - context 'Requesting a specific version of compose' do - before(:all) do - @version = '1.5.1' - @pp = <<-code - class { 'docker::compose': - version => '#{@version}', - } - code - apply_manifest(@pp, :catch_failures=>true) - end - - it 'should be idempotent' do - apply_manifest(@pp, :catch_changes=>true) - end - - it 'should have installed the requested version' do - shell('docker-compose --version', :acceptable_exit_codes => [0]) do |r| - expect(r.stdout).to match(/#{@version}/) - end - end - end - - context 'Removing docker compose' do - before(:all) do - @version = '1.7.0' - @pp = <<-code - class { 'docker::compose': - ensure => absent, - version => '#{@version}', - } - code - apply_manifest(@pp, :catch_failures=>true) - end - - it 'should be idempotent' do - apply_manifest(@pp, :catch_changes=>true) - end - - it 'should have removed the relevant files' do - shell('test -e /usr/local/bin/docker-compose', :acceptable_exit_codes => [1]) - shell("test -e /usr/local/bin/docker-compose-#{@version}", :acceptable_exit_codes => [1]) - end - - after(:all) do - install_code = <<-code - class { 'docker': } - class { 'docker::compose': } - code - apply_manifest(install_code, :catch_failures=>true) - end - end -end diff --git a/spec/acceptance/compose_v2_spec.rb b/spec/acceptance/compose_v2_spec.rb deleted file mode 100644 index 2f53cdbf..00000000 --- a/spec/acceptance/compose_v2_spec.rb +++ /dev/null @@ -1,120 +0,0 @@ -require 'spec_helper_acceptance' - -broken = false - -if fact('osfamily') == 'windows' - puts "Not implemented on Windows" - broken = true -elsif fact('osfamily') == 'RedHat' - docker_args = "repo_opt => '--enablerepo=localmirror-extras'" -end - -describe 'docker compose', :win_broken => broken do - before(:all) do - install_code = <<-code - class { 'docker': #{docker_args}} - class { 'docker::compose': } - code - apply_manifest(install_code, :catch_failures=>true) - end - - describe command("docker-compose --help") do - its(:exit_status) { should eq 0 } - end - - context 'Creating compose v2 projects' do - before(:all) do - @install = <<-code -docker_compose { '/tmp/docker-compose-v2.yml': - ensure => present, -} - code - apply_manifest(@install, :catch_failures=>true) - end - - it 'should be idempotent' do - apply_manifest(@install, :catch_changes=>true) - end - - describe command("docker inspect tmp_compose_test_1"), :sudo => true do - its(:exit_status) { should eq 0 } - end - end - - context 'Destroying compose v2 projects' do - before(:all) do - install = <<-code -docker_compose { '/tmp/docker-compose-v2.yml': - ensure => present, -} - code - apply_manifest(install, :catch_failures=>true) - @uninstall = <<-code -docker_compose { '/tmp/docker-compose-v2.yml': - ensure => absent, -} - code - apply_manifest(@uninstall, :catch_failures=>true) - end - - it 'should be idempotent' do - apply_manifest(@uninstall, :catch_changes=>true) - end - - describe command("docker inspect tmp_compose_test_1"), :sudo => true do - its(:exit_status) { should eq 1 } - end - end - - context 'Requesting a specific version of compose' do - before(:all) do - @version = '1.6.2' - @pp = <<-code - class { 'docker::compose': - version => '#{@version}', - } - code - apply_manifest(@pp, :catch_failures=>true) - end - - it 'should be idempotent' do - apply_manifest(@pp, :catch_changes=>true) - end - - it 'should have installed the requested version' do - shell('docker-compose --version', :acceptable_exit_codes => [0]) do |r| - expect(r.stdout).to match(/#{@version}/) - end - end - end - - context 'Removing docker compose' do - before(:all) do - @version = '1.7.0' - @pp = <<-code - class { 'docker::compose': - ensure => absent, - version => '#{@version}', - } - code - apply_manifest(@pp, :catch_failures=>true) - end - - it 'should be idempotent' do - apply_manifest(@pp, :catch_changes=>true) - end - - it 'should have removed the relevant files' do - shell('test -e /usr/local/bin/docker-compose', :acceptable_exit_codes => [1]) - shell("test -e /usr/local/bin/docker-compose-#{@version}", :acceptable_exit_codes => [1]) - end - - after(:all) do - install_code = <<-code - class { 'docker': } - class { 'docker::compose': } - code - apply_manifest(install_code, :catch_failures=>true) - end - end -end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index d77427ba..b4587d71 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -73,36 +73,6 @@ def retry_on_error_matching(max_retry_count = 3, retry_wait_interval_secs = 5, e on(host, 'yum install -y net-tools device-mapper') end - docker_compose_content = <<-EOS -compose_test: - image: ubuntu:14.04 - command: /bin/sh -c "while true; do echo hello world; sleep 1; done" -extends_service: - extends: compose_test - command: /bin/sh -c "while true; do echo hello world; sleep 1; done" -extends_extends_service: - extends: extends_service - command: /bin/sh -c "while true; do echo hello world; sleep 1; done" -second_test: - image: ubuntu:14.04 - command: /bin/sh -c "while true; do echo hello world; sleep 1; done" - EOS - docker_compose_content_v2 = <<-EOS -version: "2" -services: - compose_test: - image: ubuntu:14.04 - command: /bin/sh -c "while true; do echo hello world; sleep 1; done" - extends_service: - extends: compose_test - command: /bin/sh -c "while true; do echo hello world; sleep 1; done" - extends_extends_service: - extends: extends_service - command: /bin/sh -c "while true; do echo hello world; sleep 1; done" - second_test: - image: ubuntu:14.04 - command: /bin/sh -c "while true; do echo hello world; sleep 1; done" - EOS docker_compose_content_v3 = <<-EOS version: "3.4" services: @@ -139,8 +109,6 @@ def retry_on_error_matching(max_retry_count = 3, retry_wait_interval_secs = 5, e external: name: nat EOS - create_remote_file(host, "/tmp/docker-compose.yml", docker_compose_content) - create_remote_file(host, "/tmp/docker-compose-v2.yml", docker_compose_content_v2) if fact_on(host, 'osfamily') == 'windows' create_remote_file(host, "/tmp/docker-compose-v3.yml", docker_compose_content_v3_windows) create_remote_file(host, "/tmp/docker-compose-override-v3.yml", docker_compose_override_v3_windows) From 58adcd6fde0baa26d7d474e541aa6e500b70f7b9 Mon Sep 17 00:00:00 2001 From: MarkW Date: Thu, 27 Sep 2018 17:36:31 +0100 Subject: [PATCH 2/7] post release rebase of release branch into master (#347) * adding in note about use of latest image tag * release prep for 3.0.0 (#342) * V3.0.0 release prep (#343) * release prep for 3.0.0 * Readme updates prior to release prep * Minor updates Minor updates * CLOUD-2146-cleanup-of-cocker-compose-acceptance-tests (#341) (#344) * pinning puppet version to fix failing spec tests (#346) * CLOUD-2146-cleanup-of-cocker-compose-acceptance-tests (#341) * pinning puppet version to fix failing spec tests --- CHANGELOG.md | 24 +++++++++++++++++++++++- Gemfile | 2 +- README.md | 41 +++++++++++++++++++++++------------------ metadata.json | 2 +- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6be1a6b4..6facf06f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,25 @@ +# Version 3.0.0 + +Various fixes for github issues +- 206 +- 226 +- 241 +- 280 +- 281 +- 287 +- 289 +- 294 +- 303 +- 312 +- 314 + +Adding in the following features/functionality + +-Support for multiple compose files. + +A full list of issues and PRs associated with this release can be found [here](https://github.com/puppetlabs/puppetlabs-docker/issues?q=is%3Aissue+milestone%3AV3.0.0+is%3Aclosed) + + # Version 2.0.0 Various fixes for github issues @@ -129,4 +151,4 @@ Forked for garethr/docker v5.3.0 Added support for: - Docker services within a swarm cluster - Swarm mode -- Docker secrets \ No newline at end of file +- Docker secrets diff --git a/Gemfile b/Gemfile index 0874b4d9..7daea050 100755 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ group :test do elsif puppet_git_url = ENV['PUPPET_GIT_URL'] gem "puppet", :git => puppet_git_url else - gem "puppet" + gem "puppet", "5.5.6" end gem "puppet-lint", "2.3.3" gem "puppet-lint-unquoted_string-check", "0.3.0" diff --git a/README.md b/README.md index 5194c0bf..c224671f 100755 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ The Puppet docker module installs, configures, and manages [Docker](https://gith ## Description -This module installs, configures, and manages [Docker](https://github.com/docker/docker). +This module install, configures, and manages [Docker](https://github.com/docker/docker). Due to the new naming convention for Docker packages, this module prefaces any params that refer to the release with `_ce` or `_engine`. Examples of these are documented in this README. @@ -57,7 +57,7 @@ class { 'docker': } ``` -The latest Docker [repositories](https://docs.docker.com/engine/installation/linux/docker-ce/debian/#set-up-the-repository) are now the default repositories for version 17.06 and above. If you are using a version prior to this, the old repositories are still configured based on the version number passed into the module. +The latest Docker [repositories](https://docs.docker.com/engine/installation/linux/docker-ce/debian/#set-up-the-repository) are now the default repositories for version 17.06 and above. If you are using an older version, the repositories are still configured based on the version number passed into the module. To ensure the module configures the latest repositories, add the following code to the manifest file: @@ -232,7 +232,7 @@ service { 'docker' ### Images -Each image requires a unique name, otherwise the installation fails when a duplicate name is detected. +Each image requires a unique name; otherwise, the installation fails when a duplicate name is detected. To install a Docker image, add the `docker::image` defined type to the manifest file: @@ -240,7 +240,7 @@ To install a Docker image, add the `docker::image` defined type to the manifest docker::image { 'base': } ``` -The code above is equivalent to running the `docker pull base` command. However, it removes the default five minute execution timeout. +The code above is equivalent to running the `docker pull base` command. However, it removes the default five-minute execution timeout. To include an optional parameter for installing image tags that is the equivalent to running `docker pull -t="precise" ubuntu`, add the following code to the manifest file: @@ -360,15 +360,17 @@ To pull the image before it starts, specify the `pull_on_start` parameter. To execute a command before the container stops, specify the `before_stop` parameter. -Add the container name to the `after` parameter to specify which containers start first. This affects the generation of the `init.d/systemd` script. +Adding the container name to the `after` parameter to specify which containers start first, affects the generation of the `init.d/systemd` script. -Add container dependencies to the `depends` parameter. The container starts before this container and stops before the depended container. This affects the generation of the `init.d/systemd` script. Use the `depend_services` parameter to specify dependencies for generic services, which are not Docker related, that start before this container. +Add container dependencies to the `depends` parameter. The container starts before this container and stops before the depended container. This affects the generation of the `init.d/systemd` script. Use the `depend_services` parameter to specify dependencies for general services, which are not Docker related, that start before this container. -The `extra_parameters` parameter contains an array of command line arguments to pass to the `docker run` command. This parameter is useful for adding additional or experimental options that the docker module currently does not support. +The `extra_parameters` parameter, which contains an array of command line arguments to pass to the `docker run` command, is useful for adding additional or experimental options that the docker module currently does not support. By default, automatic restarting of the service on failure is enabled by the service file for systemd based systems. -It is highly recommended that an image tag be used at all times with the `docker::run` define type. If not, the latest image will be used, whether it be in a remote registry or installed on the server already by the `docker::image` define type. +It's recommended that an image tag is used at all times with the `docker::run` define type. If not, the latest image ise used, whether it be in a remote registry or installed on the server already by the `docker::image` define type. + +NOTE: As of v3.0.0, if the latest tag is used, the image will be the latest at the time the of the initial puppet run. Any subsequent puppet runs will always reference the latest local image. For this this reason it highly recommended that an alternative tag be used, or the image be removed before pulling latest again. To use an image tag, add the following code to the manifest file: @@ -403,7 +405,7 @@ If using Hiera, you can configure the `docker::run_instance` class: command: '/bin/sh -c "while true; do echo hello world; sleep 1; done"' ``` -To remove a running container, add the following code to the manifest file. This will also remove the systemd service file associated with the container. +To remove a running container, add the following code to the manifest file. This also removes the systemd service file associated with the container. ```puppet docker::run { 'helloworld': @@ -411,7 +413,7 @@ docker::run { 'helloworld': } ``` -To enable the restart of an unhealthy container add the following code to the manifest file.In order to set the health check interval time set the optional health_check_interval parameter, the default health check interval is 30 seconds. +To enable the restart of an unhealthy container, add the following code to the manifest file. In order to set the health check interval time set the optional health_check_interval parameter, the default health check interval is 30 seconds. ```puppet docker::run { 'helloworld': @@ -470,7 +472,7 @@ A defined network can be used on a `docker::run` resource with the `net` paramet #### Windows -On windows, only one NAT network is supported. To support multiple networks Windows Server 2016 with KB4015217 is required. See [Windows Container Network Drivers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/network-drivers-topologies) and [Windows Container Networking](https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/architecture). +On windows, only one NAT network is supported. To support multiple networks, Windows Server 2016 with KB4015217 is required. See [Windows Container Network Drivers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/network-drivers-topologies) and [Windows Container Networking](https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/architecture). The Docker daemon will create a default NAT network on the first start unless specified otherwise. To disable the network creation, use the parameter `bridge => 'none'` when installing docker. @@ -543,7 +545,7 @@ class {'docker::compose': ``` Set the `version` parameter to any version you need to install. -This is a example of a Compose file: +This is an example of a Compose file: ```yaml compose_test: @@ -562,7 +564,7 @@ docker_compose { 'test': Puppet automatically runs Compose, because the relevant Compose services aren't running. If required, include additional options such as enabling experimental features and scaling rules. -In the example below, Puppet runs Compose when the number of containers specified for a service don't match the scale values. +In the example below, Puppet runs Compose when the number of containers specified for a service doesn't match the scale values. ```puppet docker_compose { 'test': @@ -585,7 +587,7 @@ docker_compose {'test': } ``` -Please note you should supply your master docker-compose file as the first element in the array. As per docker multi compose file support compose files will be merged in the order they are specified in the array. +Please note you should supply your master docker-compose file as the first element in the array. As per docker, multi compose file support compose files are merged in the order they are specified in the array. If you are using a v3.2 compose file or above on a Docker Swarm cluster, use the `docker::stack` class. Include the file resource before you run the stack command. @@ -720,7 +722,7 @@ Ran on 1 node in 6.16 seconds ### Docker services -Docker services create distributed applications across multiple swarm nodes. Each Docker service contains a set of containers which are replicated across the swarm. +Docker services create distributed applications across multiple swarm nodes. Each Docker service replicates a set of containers across the swarm. To create a Docker service, add the following code to the manifest file: @@ -888,6 +890,7 @@ docker::plugin {'foo/fooplugin:latest' ensure => 'absent', force_remove => true, } +thub.com ``` ## Reference @@ -937,14 +940,15 @@ docker::plugin {'foo/fooplugin:latest' The following parameters are available in the `docker_compose` type: -#### `name` +#### 'compose_files' -The Docker compose file path. +An array containing the docker compose file paths. #### `scale` A hash of the name of compose services and number of containers. -Values- Compose services: 'string' , containers: 'an integrer'. + +Values - Compose services: 'string' , containers: 'integer'. #### `options` @@ -1500,3 +1504,4 @@ This module supports: ## Development If you would like to contribute to this module, see the guidelines in [CONTRIBUTING.MD](https://github.com/puppetlabs/puppetlabs-docker/blob/master/CONTRIBUTING.md). + diff --git a/metadata.json b/metadata.json index f83bfd43..0d4a0b45 100755 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-docker", - "version": "2.0.0", + "version": "3.0.0", "author": "Puppet Labs", "summary": "Module for installing and managing docker", "license": "Apache-2.0", From 98c1552a8e6273b6fd03a3817922506b565d6ad9 Mon Sep 17 00:00:00 2001 From: Florin Dragos Date: Mon, 8 Oct 2018 09:10:45 +0300 Subject: [PATCH 3/7] Docker stack on windows (#350) --- manifests/stack.pp | 17 +++++++++---- spec/defines/stack.rb | 59 +++++++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/manifests/stack.pp b/manifests/stack.pp index 7ed2b9f2..72aa55dc 100644 --- a/manifests/stack.pp +++ b/manifests/stack.pp @@ -49,6 +49,14 @@ $docker_command = "${docker::params::docker_command} stack" + if $::osfamily == 'windows' { + $exec_path = ['C:/Program Files/Docker/'] + $check_stack = "${docker_command} ls | select-string -pattern ${stack_name}" + } else { + $exec_path = ['/bin', '/usr/bin'] + $check_stack = "${docker_command} ls | grep ${stack_name}" + } + if $ensure == 'present'{ $docker_stack_flags = docker_stack_flags ({ stack_name => $stack_name, @@ -60,12 +68,11 @@ }) $exec_stack = "${docker_command} deploy ${docker_stack_flags} ${stack_name}" - $unless_stack = "${docker_command} ls | grep ${stack_name}" exec { "docker stack create ${stack_name}": command => $exec_stack, - unless => $unless_stack, - path => ['/bin', '/usr/bin'], + unless => $check_stack, + path => $exec_path, } } @@ -73,8 +80,8 @@ exec { "docker stack ${stack_name}": command => "${docker_command} rm ${stack_name}", - onlyif => "${docker_command} ls | grep ${stack_name}", - path => ['/bin', '/usr/bin'], + onlyif => $check_stack, + path => $exec_path, } } } diff --git a/spec/defines/stack.rb b/spec/defines/stack.rb index 41fceebe..a82d48dd 100644 --- a/spec/defines/stack.rb +++ b/spec/defines/stack.rb @@ -1,29 +1,40 @@ require 'spec_helper' -describe 'docker::stack', :type => :define do - let(:title) { 'test_stack' } - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - } } +['Debian', 'Windows'].each do |osfamily| + describe 'docker::stack', :type => :define do + let(:title) { 'test_stack' } + if osfamily == 'Debian' + let(:facts) { { + :osfamily => 'Debian', + :operatingsystem => 'Debian', + :lsbdistid => 'Debian', + :lsbdistcodename => 'jessie', + :kernelrelease => '3.2.0-4-amd64', + :operatingsystemmajrelease => '8', + } } + elsif osfamily == 'Windows' + let(:facts) { { + :osfamily => 'windows', + :operatingsystem => 'windows', + :kernelrelease => '10.0.14393', + :operatingsystemmajrelease => '2016', + } } + end - context 'Create stack with compose file' do - let(:params) { { - 'stack_name' => 'foo', - 'compose_file' => '/tmpdocker-compose.yaml', - 'resolve_image' => 'always', - } } - it { should contain_exec('docker stack deploy').with_command(/docker stack deploy/) } - end + context 'Create stack with compose file' do + let(:params) { { + 'stack_name' => 'foo', + 'compose_file' => '/tmp/docker-compose.yaml', + 'resolve_image' => 'always', + } } + it { should contain_exec('docker stack deploy').with_command(/docker stack deploy/) } + end - context 'with ensure => absent' do - let(:params) { { - 'ensure' => 'absent', - 'stack_name' => 'foo'} } - it { should contain_exec('docker stack rm').with_command(/docker stack rm/) } + context 'with ensure => absent' do + let(:params) { { + 'ensure' => 'absent', + 'stack_name' => 'foo'} } + it { should contain_exec('docker stack rm').with_command(/docker stack rm/) } + end end -end +end \ No newline at end of file From b53adc61b1596b3cbbae94443d05f11ad43ec8b5 Mon Sep 17 00:00:00 2001 From: Florin Dragos Date: Mon, 15 Oct 2018 22:59:45 +0300 Subject: [PATCH 4/7] Fix acceptance tests for windows (#349) * Fix timeout while waiting for windows service to stop * Fix acceptance tests for windows --- spec/acceptance/docker_full_spec.rb | 22 +++++++++++++++------- templates/windows/download_docker.ps1.erb | 4 ++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/spec/acceptance/docker_full_spec.rb b/spec/acceptance/docker_full_spec.rb index f351b1b7..86f90a2c 100644 --- a/spec/acceptance/docker_full_spec.rb +++ b/spec/acceptance/docker_full_spec.rb @@ -56,7 +56,7 @@ # Delete all running containers shell("#{docker_command} rm -f $(#{docker_command} ps -a -q) || true") # Delete all existing images - shell("#{docker_command} rmi $(#{docker_command} images -q) || true") + shell("#{docker_command} rmi -f $(#{docker_command} images -q) || true") # Check to make sure no images are present shell("#{docker_command} images | wc -l") do |r| expect(r.stdout).to match(/^0|1$/) @@ -228,20 +228,28 @@ class { 'docker': end end - context 'uninstall docker' do - before(:each) do + after(:all) do @pp =<<-EOS - class {'docker': - ensure => 'absent' + class {'docker': #{docker_args}, + ensure => 'present' } EOS apply_manifest(@pp, :catch_failures => true) - sleep 4 + + # Wait for reboot if windows + sleep 300 if fact('osfamily') == 'windows' end it 'should uninstall successfully' do - shell('docker ps', :acceptable_exit_codes => [1, 127]) + @pp =<<-EOS + class {'docker': #{docker_args}, + ensure => 'absent' + } + EOS + apply_manifest(@pp, :catch_failures => true) + sleep 4 + shell('docker ps', :acceptable_exit_codes => [1, 127]) end end end diff --git a/templates/windows/download_docker.ps1.erb b/templates/windows/download_docker.ps1.erb index ddeab17b..929ed221 100644 --- a/templates/windows/download_docker.ps1.erb +++ b/templates/windows/download_docker.ps1.erb @@ -8,10 +8,10 @@ $service = Get-Service "docker" -ErrorAction Ignore if ( -not $service ) { $cleanInstall = $true } elseif ( $service.Status -ne [ServiceProcess.ServiceControllerStatus]::Stopped ) { - $timeSpan = New-Object Timespan 0,0,60 + $timeSpan = New-Timespan -Seconds 60 try { $service.Stop() - $service.WaitForStatus([ServiceProcess.ServiceControllerStatus]::Stopped, 60) + $service.WaitForStatus([ServiceProcess.ServiceControllerStatus]::Stopped, $timeSpan) } catch [Management.Automation.MethodInvocationException],[ServiceProcess.TimeoutException] { Write-Error "Failed to stop docker service" From fdf2b787f4aa14ad92071f6c25a47d43990e09c4 Mon Sep 17 00:00:00 2001 From: Florin Dragos Date: Mon, 22 Oct 2018 16:07:36 +0300 Subject: [PATCH 5/7] Add docker stack tests (#356) --- .../parser/functions/docker_stack_flags.rb | 6 +- manifests/stack.pp | 25 +-- spec/acceptance/stack_spec.rb | 147 ++++++++++++++++++ spec/defines/{stack.rb => stack_spec.rb} | 18 ++- spec/spec_helper_acceptance.rb | 25 +++ 5 files changed, 206 insertions(+), 15 deletions(-) create mode 100644 spec/acceptance/stack_spec.rb rename spec/defines/{stack.rb => stack_spec.rb} (52%) diff --git a/lib/puppet/parser/functions/docker_stack_flags.rb b/lib/puppet/parser/functions/docker_stack_flags.rb index a1a815d8..6df7a62d 100644 --- a/lib/puppet/parser/functions/docker_stack_flags.rb +++ b/lib/puppet/parser/functions/docker_stack_flags.rb @@ -12,8 +12,10 @@ module Puppet::Parser::Functions flags << "--bundle-file '#{opts['bundle_file']}'" end - if opts['compose_file'].to_s != 'undef' - flags << "--compose-file '#{opts['compose_file']}'" + if opts['compose_files'].to_s != 'undef' + opts['compose_files'].each do |file| + flags << "--compose-file '#{file}'" + end end if opts['resolve_image'].to_s != 'undef' diff --git a/manifests/stack.pp b/manifests/stack.pp index 72aa55dc..7cffd85d 100644 --- a/manifests/stack.pp +++ b/manifests/stack.pp @@ -39,7 +39,7 @@ Optional[Pattern[/^present$|^absent$/]] $ensure = 'present', Optional[String] $stack_name = undef, Optional[String] $bundle_file = undef, - Optional[String] $compose_file = undef, + Optional[Array] $compose_files = undef, Optional[String] $prune = undef, Optional[String] $with_registry_auth = undef, Optional[Pattern[/^always$|^changed$|^never$/]] $resolve_image = undef, @@ -51,17 +51,20 @@ if $::osfamily == 'windows' { $exec_path = ['C:/Program Files/Docker/'] - $check_stack = "${docker_command} ls | select-string -pattern ${stack_name}" + $check_stack = '$info = docker stack ls | select-string -pattern web + if ($info -eq $null) { Exit 1 } else { Exit 0 }' + $provider = 'powershell' } else { $exec_path = ['/bin', '/usr/bin'] $check_stack = "${docker_command} ls | grep ${stack_name}" + $provider = undef } if $ensure == 'present'{ $docker_stack_flags = docker_stack_flags ({ stack_name => $stack_name, bundle_file => $bundle_file, - compose_file => $compose_file, + compose_files => $compose_files, prune => $prune, with_registry_auth => $with_registry_auth, resolve_image => $resolve_image, @@ -70,18 +73,20 @@ $exec_stack = "${docker_command} deploy ${docker_stack_flags} ${stack_name}" exec { "docker stack create ${stack_name}": - command => $exec_stack, - unless => $check_stack, - path => $exec_path, + command => $exec_stack, + unless => $check_stack, + path => $exec_path, + provider => $provider, } } if $ensure == 'absent'{ - exec { "docker stack ${stack_name}": - command => "${docker_command} rm ${stack_name}", - onlyif => $check_stack, - path => $exec_path, + exec { "docker stack destroy ${stack_name}": + command => "${docker_command} rm ${stack_name}", + onlyif => $check_stack, + path => $exec_path, + provider => $provider, } } } diff --git a/spec/acceptance/stack_spec.rb b/spec/acceptance/stack_spec.rb new file mode 100644 index 00000000..333a756b --- /dev/null +++ b/spec/acceptance/stack_spec.rb @@ -0,0 +1,147 @@ +require 'spec_helper_acceptance' + +if fact('osfamily') == 'windows' + docker_args = 'docker_ee => true' + tmp_path = 'C:/cygwin64/tmp' + test_container = 'nanoserver-sac2016' + wait_for_container_seconds = 120 +else + docker_args = '' + tmp_path = '/tmp' + test_container = 'debian' + wait_for_container_seconds = 10 +end + +describe 'docker stack' do + before(:all) do + retry_on_error_matching(60, 5, /connection failure running/) do + @install_code = <<-code + class { 'docker': #{docker_args} } + docker::swarm {'cluster_manager': + init => true, + ensure => 'present', + } + code + apply_manifest(@install_code, :catch_failures=>true) + end + end + + context 'Creating stack' do + let(:install) {" + docker::stack { 'web': + stack_name => 'web', + compose_files => ['#{tmp_path}/docker-stack.yml'], + ensure => present, + }" + } + + it 'should deploy stack' do + apply_manifest(install, :catch_failures=>true) + sleep wait_for_container_seconds + end + + it 'should be idempotent' do + apply_manifest(install, :catch_changes=>true) + end + + it 'should find a stack' do + shell('docker stack ls') do |r| + expect(r.stdout).to match(/web/) + end + end + + it 'should find a docker container' do + shell("docker ps | grep web_compose_test", :acceptable_exit_codes => [0]) + end + end + + context 'Destroying stack' do + let(:install) {" + docker::stack { 'web': + stack_name => 'web', + compose_files => ['#{tmp_path}/docker-stack.yml'], + ensure => present, + }" + } + let(:destroy) {" + docker::stack { 'web': + stack_name => 'web', + compose_files => ['#{tmp_path}/docker-stack.yml'], + ensure => absent, + }" + } + it 'should run successfully' do + apply_manifest(destroy, :catch_failures=>true) + end + + it 'should be idempotent' do + apply_manifest(destroy, :catch_changes=>true) + end + + it 'should not find a docker stack' do + shell('docker stack ls') do |r| + expect(r.stdout).to_not match(/web/) + end + end + end + + context 'creating stack with multi compose files' do + + before(:all) do + @install_code = <<-code + docker::stack { 'web': + stack_name => 'web', + compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], + ensure => present, + } + code + + apply_manifest(@install_code, :catch_failures=>true) + end + + it "should find container with web_compose_test tag" do + sleep wait_for_container_seconds + shell("docker ps | grep web_compose_test", :acceptable_exit_codes => [0]) + end + end + + context 'Destroying project with multiple compose files' do + before(:all) do + @install_code = <<-code + docker::stack { 'web': + stack_name => 'web', + compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], + ensure => present, + } + code + + apply_manifest(@install_code, :catch_failures=>true) + + @destroy_code = <<-code + docker::stack { 'web': + stack_name => 'web', + compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], + ensure => absent, + } + code + + apply_manifest(@destroy_code, :catch_failures=>true) + sleep 5 # wait for containers to stop + end + + it 'should be idempotent' do + apply_manifest(@destroy_code, :catch_changes=>true) + end + + it 'should not find a docker stack' do + shell('docker stack ls') do |r| + expect(r.stdout).to_not match(/web/) + end + end + + it 'should not find a docker container' do + shell("docker ps | grep #{test_container}", :acceptable_exit_codes => [1]) + end + end + +end \ No newline at end of file diff --git a/spec/defines/stack.rb b/spec/defines/stack_spec.rb similarity index 52% rename from spec/defines/stack.rb rename to spec/defines/stack_spec.rb index a82d48dd..227e672b 100644 --- a/spec/defines/stack.rb +++ b/spec/defines/stack_spec.rb @@ -24,17 +24,29 @@ context 'Create stack with compose file' do let(:params) { { 'stack_name' => 'foo', - 'compose_file' => '/tmp/docker-compose.yaml', + 'compose_files' => ['/tmp/docker-compose.yaml'], 'resolve_image' => 'always', } } - it { should contain_exec('docker stack deploy').with_command(/docker stack deploy/) } + it { should contain_exec('docker stack create foo').with_command(/docker stack deploy/) } + it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose.yaml'/) } + end + + context 'Create stack with multiple compose files' do + let(:params) { { + 'stack_name' => 'foo', + 'compose_files' => ['/tmp/docker-compose.yaml', '/tmp/docker-compose-2.yaml'], + 'resolve_image' => 'always', + } } + it { should contain_exec('docker stack create foo').with_command(/docker stack deploy/) } + it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose.yaml'/) } + it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose-2.yaml'/) } end context 'with ensure => absent' do let(:params) { { 'ensure' => 'absent', 'stack_name' => 'foo'} } - it { should contain_exec('docker stack rm').with_command(/docker stack rm/) } + it { should contain_exec('docker stack destroy foo').with_command(/docker stack rm/) } end end end \ No newline at end of file diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index b4587d71..75fac3b6 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -82,6 +82,13 @@ def retry_on_error_matching(max_retry_count = 3, retry_wait_interval_secs = 5, e EOS docker_compose_override_v3 = <<-EOS version: "3.4" +services: + compose_test: + image: debian:jessie + command: /bin/sh -c "while true; do echo hello world; sleep 1; done" + EOS + docker_stack_override_v3 = <<-EOS +version: "3.4" services: compose_test: image: debian:jessie @@ -108,13 +115,31 @@ def retry_on_error_matching(max_retry_count = 3, retry_wait_interval_secs = 5, e default: external: name: nat + EOS + docker_stack_content_windows = <<-EOS +version: "3" +services: + compose_test: + image: hello-world:nanoserver + command: cmd.exe /C "ping /t 8.8.8.8" + EOS + docker_stack_override_windows = <<-EOS +version: "3" +services: + compose_test: + image: hello-world:nanoserver-sac2016 + command: cmd.exe /C "ping /t 8.8.8.8" EOS if fact_on(host, 'osfamily') == 'windows' create_remote_file(host, "/tmp/docker-compose-v3.yml", docker_compose_content_v3_windows) + create_remote_file(host, "/tmp/docker-stack.yml", docker_stack_content_windows) create_remote_file(host, "/tmp/docker-compose-override-v3.yml", docker_compose_override_v3_windows) + create_remote_file(host, "/tmp/docker-stack-override.yml", docker_stack_override_windows) else create_remote_file(host, "/tmp/docker-compose-v3.yml", docker_compose_content_v3) + create_remote_file(host, "/tmp/docker-stack.yml", docker_compose_content_v3) create_remote_file(host, "/tmp/docker-compose-override-v3.yml", docker_compose_override_v3) + create_remote_file(host, "/tmp/docker-stack-override.yml", docker_stack_override_v3) end if fact_on(host, 'osfamily') == 'windows' From 6662b81ae08c08377b05d9d0d147f202e9c9f1ae Mon Sep 17 00:00:00 2001 From: Florin Dragos Date: Mon, 22 Oct 2018 19:01:17 +0300 Subject: [PATCH 6/7] Update readme for docker stack (#359) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c224671f..c8e84fe5 100755 --- a/README.md +++ b/README.md @@ -597,7 +597,7 @@ To deploy the stack, add the following code to the manifest file: docker::stack { 'yourapp': ensure => present, stack_name => 'yourapp', - compose_file => '/tmp/docker-compose.yaml', + compose_files => ['/tmp/docker-compose.yaml'], require => [Class['docker'], File['/tmp/docker-compose.yaml']], } ``` @@ -612,7 +612,7 @@ To deploy the stack, add the following code to the manifest file. docker::stack { 'yourapp': ensure => present, stack_name => 'yourapp', - compose_file => '/tmp/docker-compose.yaml', + compose_files => ['/tmp/docker-compose.yaml'], require => [Class['docker'], File['/tmp/docker-compose.yaml']], } ``` From 4694e3d99a81ff28730039213e582311a0576ba2 Mon Sep 17 00:00:00 2001 From: Mark Wilson Date: Mon, 22 Oct 2018 22:30:35 +0100 Subject: [PATCH 7/7] release prep for Docker 3.1.0 release. --- CHANGELOG.md | 6 ++++++ metadata.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6facf06f..f6a05e3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# Version 3.1.0 + +Adding in the following faetures/functionality + +- Docker Stack support on Windows. + # Version 3.0.0 Various fixes for github issues diff --git a/metadata.json b/metadata.json index 0d4a0b45..bc848403 100755 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-docker", - "version": "3.0.0", + "version": "3.1.0", "author": "Puppet Labs", "summary": "Module for installing and managing docker", "license": "Apache-2.0",