Skip to content

(IAC-1218) - docker_params_changed should be run by agent #705

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 1, 2021
Original file line number Diff line number Diff line change
@@ -1,13 +1,80 @@
# frozen_string_literal: true

require 'open3'
require 'json'
Puppet::Functions.create_function(:docker_params_changed) do
dispatch :detect_changes do
param 'Hash', :opts
return_type 'String'
end

def run_with_powershell(cmd)
"powershell.exe -Command \"& {#{cmd}}\" "
end

module Puppet::Parser::Functions
# Checks if at least one parammeter is changed
newfunction(:docker_params_changed, type: :rvalue) do |args|
opts = args[0] || {}
return_value = []
def remove_cidfile(cidfile, osfamily)
delete_command = if osfamily == 'windows'
run_with_powershell("del #{cidfile}")
else
"rm -f #{cidfile}"
end
_stdout, _stderr, _status = Open3.capture3(delete_command)
end

def start_container(name, osfamily)
start_command = if osfamily == 'windows'
run_with_powershell("docker start #{name}")
else
"docker start #{name}"
end
_stdout, _stderr, _status = Open3.capture3(start_command)
end

def stop_container(name, osfamily)
stop_command = if osfamily == 'windows'
run_with_powershell("docker stop #{name}")
else
"docker stop #{name}"
end
_stdout, _stderr, _status = Open3.capture3(stop_command)
end

def remove_container(name, osfamily, stop_wait_time, cidfile)
stop_command = if osfamily == 'windows'
run_with_powershell("docker stop --time=#{stop_wait_time} #{name}")
else
"docker stop --time=#{stop_wait_time} #{name}"
end
_stdout, _stderr, _status = Open3.capture3(stop_command)

remove_command = if osfamily == 'windows'
run_with_powershell("docker rm -v #{name}")
else
"docker rm -v #{name}"
end
_stdout, _stderr, _status = Open3.capture3(remove_command)

remove_cidfile(cidfile, osfamily)
end

def create_container(cmd, osfamily, image)
pull_command = if osfamily == 'windows'
run_with_powershell("docker pull #{image} -q")
else
"docker pull #{image} -q"
end
_stdout, _stderr, _status = Open3.capture3(pull_command)

create_command = if osfamily == 'windows'
run_with_powershell(cmd)
else
cmd
end
_stdout, _stderr, _status = Open3.capture3(create_command)
end

def detect_changes(opts)
require 'open3'
require 'json'
return_value = 'No changes detected'

if opts['sanitised_title'] && opts['osfamily']
stdout, stderr, status = Open3.capture3("docker inspect #{opts['sanitised_title']}")
Expand Down Expand Up @@ -61,18 +128,30 @@ module Puppet::Parser::Functions

param_changed = true if pp_ports && pp_ports != ports

return_value << if param_changed
'PARAM_CHANGED'
else
'NO_CHANGE'
end
if param_changed
remove_container(opts['sanitised_title'], opts['osfamily'], opts['stop_wait_time'], opts['cidfile'])
create_container(opts['command'], opts['osfamily'], opts['image'])
return_value = 'Param changed'
end
else
return_value << 'CONTAINER_NOT_FOUND'
create_container(opts['command'], opts['osfamily'], opts['image']) unless File.exist?(opts['cidfile'])
_stdout, _stderr, status = Open3.capture3("docker inspect #{opts['sanitised_title']}")
unless status.to_s.include?('exit 0')
remove_cidfile(opts['cidfile'], opts['osfamily'])
create_container(opts['command'], opts['osfamily'], opts['image'])
end
return_value = 'No changes detected'
end
else
return_value << 'ARG_REQUIRED_MISSING'
return_value = 'Arg required missing'
end

if opts['container_running']
start_container(opts['sanitised_title'], opts['osfamily'])
else
stop_container(opts['sanitised_title'], opts['osfamily'])
end

return_value.flatten.join(' ')
return_value
end
end
100 changes: 34 additions & 66 deletions manifests/run.pp
Original file line number Diff line number Diff line change
Expand Up @@ -414,93 +414,61 @@
$inspect = [ "${docker_command} inspect ${sanitised_title}", ]

if $custom_unless {
$exec_unless = $custom_unless
$exec_unless = concat($custom_unless, $inspect)
} else {
$exec_unless = $inspect
}

$detect_changes = docker_params_changed(
{
sanitised_title => $sanitised_title,
osfamily => $facts['os']['family'],
image => $image,
volumes => $volumes,
ports => $ports,
if versioncmp($facts['puppetversion'], '6') < 0 {
exec { "run ${title} with docker":
command => join($run_with_docker_command, ' '),
unless => $exec_unless,
environment => $exec_environment,
path => $exec_path,
provider => $exec_provider,
timeout => $exec_timeout,
}
)

case $detect_changes {
'CONTAINER_NOT_FOUND': {
exec { "run ${title} with docker":
command => join($run_with_docker_command, ' '),
unless => $exec_unless,
environment => $exec_environment,
path => $exec_path,
provider => $exec_provider,
timeout => $exec_timeout,
}
}
'PARAM_CHANGED': {
if $running == false {
exec { "stop ${title} with docker":
command => "${docker_command} stop --time=${stop_wait_time} ${sanitised_title}",
onlyif => "${docker_command} inspect ${sanitised_title}",
onlyif => $container_running_check,
environment => $exec_environment,
path => $exec_path,
provider => $exec_provider,
timeout => $exec_timeout,
}

exec { "remove ${title} with docker":
command => "${docker_command} rm -v ${sanitised_title}",
onlyif => "${docker_command} inspect ${sanitised_title}",
environment => $exec_environment,
path => $exec_path,
provider => $exec_provider,
timeout => $exec_timeout,
}

file { $cidfile:
ensure => absent,
}

exec { "run ${title} with docker":
command => join($run_with_docker_command, ' '),
unless => $exec_unless,
} else {
exec { "start ${title} with docker":
command => "${docker_command} start ${sanitised_title}",
unless => $container_running_check,
environment => $exec_environment,
path => $exec_path,
provider => $exec_provider,
timeout => $exec_timeout,
}
}
'ARG_REQUIRED_MISSING': {
fail(translate('sanitised_title and osfamily are required for docker_params_changed function'))
}
default: {
# Use ONLY on debugging - DO NOT UNCOMMENT OTHERWISE
# notify { 'this case should not be executed':
# message => "detect_changes: ${detect_changes}",
# withpath => true,
# }
} else {
$docker_params_changed_args = {
sanitised_title => $sanitised_title,
osfamily => $facts['os']['family'],
command => join($run_with_docker_command, ' '),
cidfile => $cidfile,
image => $image,
volumes => $volumes,
ports => $ports,
stop_wait_time => $stop_wait_time,
container_running => $running,
# logfile_path => ($facts['os']['family'] == 'windows') ? {
# true => ::docker_user_temp_path,
# default => '/tmp',
# },
}
}

if $running == false {
exec { "stop ${title} with docker":
command => "${docker_command} stop --time=${stop_wait_time} ${sanitised_title}",
onlyif => $container_running_check,
environment => $exec_environment,
path => $exec_path,
provider => $exec_provider,
timeout => $exec_timeout,
}
} else {
exec { "start ${title} with docker":
command => "${docker_command} start ${sanitised_title}",
unless => $container_running_check,
environment => $exec_environment,
path => $exec_path,
provider => $exec_provider,
timeout => $exec_timeout,
$detect_changes = Deferred('docker_params_changed', [$docker_params_changed_args])

notify { 'docker_params_changed':
message => $detect_changes,
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions spec/acceptance/docker_params_changed_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
docker_image = 'hello-world:linux'
end

describe 'docker trigger parammeters change' do
describe 'docker trigger parameters change', if: fetch_puppet_version > 5 do
before(:all) do
if os[:family] != 'windows'
install_pp = "class { 'docker': #{docker_args}}"
Expand Down Expand Up @@ -56,7 +56,7 @@ class {'docker': #{docker_args}}
end

it 'creates servercore with first image' do
idempotent_apply(pp1)
expect(docker_run_idempotent_apply(pp1)).to be true
end

it 'detect image change and apply the change' do
Expand Down Expand Up @@ -91,7 +91,7 @@ class {'docker': #{docker_args}}
end

it "creates servercore with #{volumes1}" do
idempotent_apply(pp1)
expect(docker_run_idempotent_apply(pp1)).to be true
end

it "creates servercore with #{volumes2}" do
Expand Down Expand Up @@ -123,7 +123,7 @@ class {'docker': #{docker_args}}
end

it 'creates servercore with ports => ["4444"]' do
idempotent_apply(pp1)
expect(docker_run_idempotent_apply(pp1)).to be true
end

it 'creates servercore with ports => ["4444", "4445"]' do
Expand Down
11 changes: 10 additions & 1 deletion spec/acceptance/docker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
service_name = 'docker'
command = 'docker'

before(:all) do
install_pp = "class { 'docker': #{docker_args}}"
apply_manifest(install_pp)
end

context 'When adding system user', win_broken: broken do
let(:pp) do
"
Expand Down Expand Up @@ -150,7 +155,11 @@ class { 'docker':
end

it 'is idempotent' do
apply_manifest(pp, catch_changes: true)
if fetch_puppet_version > 5
expect(docker_run_idempotent_apply(pp)).to be true
else
apply_manifest(pp, catch_changes: true)
end
end

describe package(package_name) do
Expand Down
3 changes: 2 additions & 1 deletion spec/defines/run_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
##
if %r{windows}.match?(os)
facts = windows_facts.merge(os_facts)
facts = facts.merge({ puppetversion: Puppet.version })

os_params = {
'restart' => 'no',
Expand All @@ -216,7 +217,7 @@
'docker_ee' => true,
}
else
facts = {}.merge(os_facts)
facts = { puppetversion: Puppet.version }.merge(os_facts)

os_params = {}

Expand Down
Loading