Skip to content

Commit

Permalink
Merge pull request #251 from mihaibuzgau/master
Browse files Browse the repository at this point in the history
Add docker exec functionality for Docker on Windows
  • Loading branch information
davejrt authored Jun 25, 2018
2 parents 52098fd + 4235b70 commit c3d70cb
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 23 deletions.
19 changes: 16 additions & 3 deletions manifests/exec.pp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@

$docker_command = $docker::params::docker_command

if $::osfamily == 'windows' {
$exec_environment = 'PATH=C:/Program Files/Docker/'
$exec_timeout = 3000
$exec_path = ['c:/Windows/Temp/', 'C:/Program Files/Docker/']
$exec_provider = 'powershell'
} else {
$exec_environment = 'HOME=/root'
$exec_path = ['/bin', '/usr/bin']
$exec_timeout = 0
$exec_provider = undef
}

$docker_exec_flags = docker_exec_flags({
detach => $detach,
interactive => $interactive,
Expand All @@ -43,11 +55,12 @@
}

exec { $exec:
environment => 'HOME=/root',
environment => $exec_environment,
onlyif => $onlyif_command,
path => ['/bin', '/usr/bin'],
path => $exec_path,
refreshonly => $refreshonly,
timeout => 0,
timeout => $exec_timeout,
provider => $exec_provider,
unless => $unless_command,
}
}
62 changes: 42 additions & 20 deletions spec/acceptance/docker_full_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
default_docker_run_arg = "restart => 'always', net => 'nat',"
default_run_command = "ping 127.0.0.1 -t"
docker_command = "\"/cygdrive/c/Program Files/Docker/docker\""
default_docker_exec_command = 'cmd /c "ping 127.0.0.1 -t > c:\windows\temp\test_file.txt"'
default_docker_exec_lr_command = 'cmd /c "ping 127.0.0.1 -t > c:\windows\temp\test_file.txt"'
default_docker_exec_command = 'cmd /c "echo test > c:\windows\temp\test_file.txt"'
docker_mount_path = "c:/windows/temp"
else
docker_ee_arg = ''
Expand All @@ -25,7 +26,8 @@
docker_command = "docker"
default_docker_run_arg = ''
default_run_command = "init"
default_docker_exec_command = '/bin/sh -c "touch /root/test_file.txt; while true; do echo hello world; sleep 1; done"'
default_docker_exec_lr_command = '/bin/sh -c "touch /root/test_file.txt; while true; do echo hello world; sleep 1; done"'
default_docker_exec_command = 'touch /root/test_file.txt'
docker_mount_path = "/root"
end

Expand Down Expand Up @@ -389,7 +391,7 @@ class { 'docker': #{docker_ee_arg}
docker::run { 'container_3_1':
image => '#{default_image}',
command => '#{default_docker_exec_command}',
command => '#{default_docker_exec_lr_command}',
require => Docker::Image['#{default_image}'],
#{default_docker_run_arg}
}
Expand Down Expand Up @@ -728,19 +730,20 @@ class { 'docker': #{docker_ee_arg} }
end
end

describe "docker::exec", :win_broken => true do
describe "docker::exec" do
it 'should run a command inside an already running container' do
pp=<<-EOS
class { 'docker': #{docker_ee_arg} }
docker::image { 'alpine':
docker::image { '#{default_image}':
require => Class['docker'],
}
docker::run { 'container_4_1':
image => 'alpine',
command => 'init',
require => Docker::Image['alpine'],
image => '#{default_image}',
command => '#{default_run_command}',
require => Docker::Image['#{default_image}'],
#{default_docker_run_arg}
}
EOS

Expand All @@ -756,7 +759,7 @@ class { 'docker': #{docker_ee_arg} }
class { 'docker': #{docker_ee_arg} }
docker::exec { 'test_command':
container => '#{container_1.stdout.strip}',
command => 'touch /root/test_command_file.txt',
command => '#{default_docker_exec_command}',
tty => true,
}
EOS
Expand All @@ -767,8 +770,14 @@ class { 'docker': #{docker_ee_arg} }
sleep 4

container_id = shell("#{docker_command} ps | awk 'FNR == 2 {print $1}'")
shell("#{docker_command} exec #{container_id.stdout.strip} ls /root") do |r|
expect(r.stdout).to match(/test_command_file.txt/)
if fact('osfamily') == 'windows'
shell("#{docker_command} exec #{container_id.stdout.strip} cmd /c dir Windows\\\\Temp") do |r|
expect(r.stdout).to match(/test_file.txt/)
end
else
shell("#{docker_command} exec #{container_id.stdout.strip} ls /root") do |r|
expect(r.stdout).to match(/test_file.txt/)
end
end
end

Expand All @@ -777,16 +786,17 @@ class { 'docker': #{docker_ee_arg} }
pp=<<-EOS
class { 'docker': #{docker_ee_arg} }
docker::image { 'alpine': }
docker::image { '#{default_image}': }
docker::run { '#{container_name}':
image => 'alpine',
command => 'init',
image => '#{default_image}',
command => '#{default_run_command}',
#{default_docker_run_arg}
}
docker::exec { 'test_command':
container => '#{container_name}',
command => 'touch /root/test_command_file.txt',
command => '#{default_docker_exec_command}',
refreshonly => true,
}
EOS
Expand All @@ -797,12 +807,18 @@ class { 'docker': #{docker_ee_arg} }
# A sleep to give docker time to execute properly
sleep 4

shell("#{docker_command} exec #{container_name} ls /root") do |r|
expect(r.stdout).to_not match(/test_command_file.txt/)
if fact('osfamily') == 'windows'
shell("#{docker_command} exec #{container_name} cmd /c dir Windows\\\\Temp") do |r|
expect(r.stdout).to_not match(/test_file.txt/)
end
else
shell("#{docker_command} exec #{container_name} ls /root") do |r|
expect(r.stdout).to_not match(/test_file.txt/)
end
end

pp_extra=<<-EOS
file { '/tmp/dummy_file':
file { '#{default_dockerfile}_dummy_file':
ensure => 'present',
notify => Docker::Exec['test_command'],
}
Expand All @@ -816,8 +832,14 @@ class { 'docker': #{docker_ee_arg} }
# A sleep to give docker time to execute properly
sleep 4

shell("#{docker_command} exec #{container_name} ls /root") do |r|
expect(r.stdout).to match(/test_command_file.txt/)
if fact('osfamily') == 'windows'
shell("#{docker_command} exec #{container_name} cmd /c dir Windows\\\\Temp") do |r|
expect(r.stdout).to match(/test_file.txt/)
end
else
shell("#{docker_command} exec #{container_name} ls /root") do |r|
expect(r.stdout).to match(/test_file.txt/)
end
end
end
end
Expand Down
59 changes: 59 additions & 0 deletions spec/defines/exec_windows_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require 'spec_helper'

describe 'docker::exec', :type => :define do
let(:title) { 'sample' }
let(:facts) { {
:architecture => 'amd64',
:osfamily => 'windows',
:operatingsystem => 'windows',
:kernelrelease => '10.0.14393',
:operatingsystemrelease => '2016',
:operatingsystemmajrelease => '2016',
:os => { :family => 'windows', :name => 'windows', :release => { :major => '2016', :full => '2016' } }
} }

context 'when running detached' do
let(:params) { {'command' => 'command', 'container' => 'container', 'detach' => true} }
it { should contain_exec('docker exec --detach=true container command') }
end

context 'when running with tty' do
let(:params) { {'command' => 'command', 'container' => 'container', 'tty' => true} }
it { should contain_exec('docker exec --tty=true container command') }
end

context 'when running with interactive' do
let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true} }
it { should contain_exec('docker exec --interactive=true container command') }
end

context 'when running with onlyif "running"' do
let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'running'} }
it { should contain_exec('docker exec --interactive=true container command').with_onlyif ('docker ps --no-trunc --format=\'table {{.Names}}\' | grep \'^container$\'') }
end

context 'when running without onlyif custom command' do
let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'custom'} }
it { should contain_exec('docker exec --interactive=true container command').with_onlyif ('custom') }
end

context 'when running without onlyif' do
let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true} }
it { should contain_exec('docker exec --interactive=true container command').with_onlyif (nil) }
end

context 'when running with unless' do
let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true, 'unless' => 'some_command arg1'} }
it { should contain_exec('docker exec --interactive=true container command').with_unless ('docker exec --interactive=true container some_command arg1') }
end

context 'when running without unless' do
let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true,} }
it { should contain_exec('docker exec --interactive=true container command').with_unless (nil) }
end

context 'with title that need sanitisation' do
let(:params) { {'command' => 'command', 'container' => 'container_sample/1', 'detach' => true, 'sanitise_name' => true} }
it { should contain_exec('docker exec --detach=true container_sample-1 command') }
end
end

0 comments on commit c3d70cb

Please sign in to comment.