Skip to content

Commit becbc77

Browse files
(MODULES-11645) Ignore services with restart option as 'no' in exists? method
Services who have restart option set as 'no' are meant to be batch processing jobs which terminate once completed. Docker compose does not restart them, but in the exists? method, puppet looks for a running service. When it is unable to see a running service, it incorrectly assumes non-desired state and makes a corrective change. This commit rejects services with restart 'no' from the compose_services to mitigate this bug.
1 parent aded8fc commit becbc77

3 files changed

Lines changed: 76 additions & 0 deletions

File tree

lib/puppet/provider/docker_compose/ruby.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ def exists?
4040

4141
compose_services = compose_output['services']
4242

43+
# Remove services with restart: 'no' from the compose_services list as they are not expected to be running.
44+
compose_services.reject! { |_k, v| v['restart'] == 'no' }
45+
4346
return false if compose_services.count != compose_containers.uniq.count
4447

4548
counts = Hash[*compose_services.each.map { |key, array|

spec/acceptance/compose_v3_spec.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,43 @@ class { 'docker::compose': }
9292
end
9393
end
9494

95+
context 'Creating compose projects with services having restart: no' do
96+
before(:all) do
97+
# Create a compose file with one service having restart: no
98+
compose_content = <<-YAML
99+
version: '3.8'
100+
services:
101+
db:
102+
image: mysql:5.7
103+
restart: always
104+
web:
105+
image: nginx
106+
restart: no
107+
YAML
108+
create_remote_file(hosts, "#{tmp_path}/docker-compose-restart-no.yml", compose_content)
109+
end
110+
111+
let(:install_pp) do
112+
<<-MANIFEST
113+
docker_compose { 'restart_test':
114+
compose_files => ['#{tmp_path}/docker-compose-restart-no.yml'],
115+
ensure => present,
116+
}
117+
MANIFEST
118+
end
119+
120+
it 'is idempotent' do
121+
idempotent_apply(install_pp)
122+
end
123+
124+
it 'finds the running service but ignores the restart: no service' do
125+
# Assuming the compose file has one service with restart: always and one with restart: no
126+
run_shell('docker inspect restart_test-db_1', expect_failures: false)
127+
# The web service with restart: no should not be running
128+
run_shell('docker inspect restart_test-web_1', expect_failures: true)
129+
end
130+
end
131+
95132
context 'Requesting a specific version of compose' do
96133
let(:version) do
97134
'2.25.0'
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe Puppet::Type.type(:docker_compose).provider(:ruby) do
6+
let(:resource) do
7+
Puppet::Type.type(:docker_compose).new(
8+
name: 'test_project',
9+
compose_files: ['/tmp/docker-compose.yml'],
10+
provider: :ruby,
11+
)
12+
end
13+
14+
let(:provider) { resource.provider }
15+
16+
describe '#exists?' do
17+
before(:each) do
18+
allow(Puppet::Util::Platform).to receive(:windows?).and_return(false)
19+
allow(provider).to receive(:execute).and_return(YAML.safe_load("services:\n web:\n image: mysql\n restart: always\n"))
20+
allow(provider).to receive(:docker).and_return("'db-mysql'\n")
21+
end
22+
23+
it 'ignores services with restart: no' do
24+
# Mock the compose_output to have services with restart: 'no'
25+
allow(Puppet::Util::Yaml).to receive(:safe_load).and_return({
26+
'services' => {
27+
'web' => { 'image' => 'nginx', 'restart' => 'no' },
28+
'db' => { 'image' => 'mysql', 'restart' => 'always' }
29+
}
30+
})
31+
32+
# Only db should be considered, and it matches the running container
33+
expect(provider.exists?).to be true
34+
end
35+
end
36+
end

0 commit comments

Comments
 (0)