kitchen-docker 2.9.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.kitchen.windows.yml +33 -0
- data/.kitchen.yml +8 -1
- data/.travis.yml +49 -15
- data/CHANGELOG.md +6 -0
- data/README.md +64 -12
- data/docker.ps1 +9 -0
- data/kitchen-docker.gemspec +4 -5
- data/lib/docker/version.rb +25 -0
- data/lib/kitchen/docker/container.rb +70 -0
- data/lib/kitchen/docker/container/linux.rb +211 -0
- data/lib/kitchen/docker/container/windows.rb +84 -0
- data/lib/kitchen/{driver → docker}/docker_version.rb +2 -5
- data/lib/kitchen/{driver/docker/erb.rb → docker/erb_context.rb} +2 -5
- data/lib/kitchen/docker/helpers/cli_helper.rb +147 -0
- data/lib/kitchen/docker/helpers/container_helper.rb +172 -0
- data/lib/kitchen/docker/helpers/file_helper.rb +40 -0
- data/lib/kitchen/docker/helpers/image_helper.rb +68 -0
- data/lib/kitchen/docker/helpers/inspec_helper.rb +40 -0
- data/lib/kitchen/driver/docker.rb +164 -457
- data/lib/kitchen/transport/docker.rb +111 -0
- data/lib/train/docker.rb +125 -0
- data/test/integration/default/serverspec/default_spec.rb +1 -1
- data/test/integration/default/serverspec/spec_helper.rb +21 -0
- data/test/integration/inspec/inspec_spec.rb +8 -2
- metadata +42 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: df5438ae1f2f9b74072ba1c53c9b0c7876dd4abdd6e5cb864fddfa62c2bda75f
|
|
4
|
+
data.tar.gz: 4e7531d5e26a6c7bceeb7cd14779e256cf2ebf21a866d1ea66f18957567c6623
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cafda9489c84bbbe7848ca36f777c33910a0696f52b78a1333cfe1ea9c1a7c9a89a9ec0ad1b674dc38141e03929886653bbe39424789294dc84d99d9a333c93f
|
|
7
|
+
data.tar.gz: b5b121d05430ff88899cefe3d2754c00142f508237de92a9694919a5559227196b4d6d48651de6d7c620328207bea423e889671218c428e690fb59226e91e6c4
|
data/.gitignore
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<% # Make sure the local copy of the driver is loaded %>
|
|
2
|
+
<% lib = File.expand_path('../lib', __FILE__) %>
|
|
3
|
+
<% $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) %>
|
|
4
|
+
---
|
|
5
|
+
driver:
|
|
6
|
+
name: docker
|
|
7
|
+
provision_command:
|
|
8
|
+
- powershell -ExecutionPolicy Bypass -NoLogo -Command . { iwr -useb https://omnitruck.chef.io/install.ps1 } ^| iex; install
|
|
9
|
+
- powershell -Command $path=$env:Path + ';c:\opscode\chef\embedded\bin'; Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\' -Name Path -Value $path
|
|
10
|
+
|
|
11
|
+
transport:
|
|
12
|
+
name: docker
|
|
13
|
+
socket: tcp://localhost:2375
|
|
14
|
+
|
|
15
|
+
provisioner:
|
|
16
|
+
name: dummy
|
|
17
|
+
|
|
18
|
+
platforms:
|
|
19
|
+
- name: windows
|
|
20
|
+
driver_config:
|
|
21
|
+
image: mcr.microsoft.com/windows/servercore:1803
|
|
22
|
+
platform: windows
|
|
23
|
+
|
|
24
|
+
suites:
|
|
25
|
+
- name: default
|
|
26
|
+
- name: context
|
|
27
|
+
driver:
|
|
28
|
+
build_context: false
|
|
29
|
+
- name: inspec
|
|
30
|
+
driver:
|
|
31
|
+
provision_command: echo 1
|
|
32
|
+
verifier:
|
|
33
|
+
name: inspec
|
data/.kitchen.yml
CHANGED
|
@@ -6,6 +6,9 @@ driver:
|
|
|
6
6
|
name: docker
|
|
7
7
|
provision_command: curl -L https://www.chef.io/chef/install.sh | bash
|
|
8
8
|
|
|
9
|
+
transport:
|
|
10
|
+
name: docker
|
|
11
|
+
|
|
9
12
|
provisioner:
|
|
10
13
|
name: dummy
|
|
11
14
|
|
|
@@ -14,6 +17,10 @@ platforms:
|
|
|
14
17
|
- name: ubuntu-16.04
|
|
15
18
|
- name: ubuntu-18.04
|
|
16
19
|
- name: fedora-latest
|
|
20
|
+
driver:
|
|
21
|
+
provision_command:
|
|
22
|
+
- yum install libxcrypt-compat.x86_64 -y
|
|
23
|
+
- curl -L https://www.chef.io/chef/install.sh | bash
|
|
17
24
|
- name: centos-6
|
|
18
25
|
- name: centos-7
|
|
19
26
|
- name: oraclelinux-6
|
|
@@ -22,7 +29,7 @@ platforms:
|
|
|
22
29
|
- name: debian-9
|
|
23
30
|
- name: opensuse-42.3
|
|
24
31
|
driver:
|
|
25
|
-
image: opensuse:42.3
|
|
32
|
+
image: opensuse/leap:42.3
|
|
26
33
|
- name: opensuse/leap-42
|
|
27
34
|
# - name: arch
|
|
28
35
|
# driver:
|
data/.travis.yml
CHANGED
|
@@ -1,18 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
1
|
+
matrix:
|
|
2
|
+
include:
|
|
3
|
+
- os: linux
|
|
4
|
+
rvm: 2.4.9
|
|
5
|
+
dist: xenial
|
|
6
|
+
language: ruby
|
|
7
|
+
cache: bundler
|
|
8
|
+
script:
|
|
9
|
+
- bundle exec docker version
|
|
10
|
+
- bundle exec kitchen --version
|
|
11
|
+
- bundle exec rake spec
|
|
12
|
+
- bundle exec kitchen test -d always
|
|
13
|
+
- os: linux
|
|
14
|
+
rvm: 2.5.7
|
|
15
|
+
dist: xenial
|
|
16
|
+
language: ruby
|
|
17
|
+
cache: bundler
|
|
18
|
+
script:
|
|
19
|
+
- bundle exec docker version
|
|
20
|
+
- bundle exec kitchen --version
|
|
21
|
+
- bundle exec rake spec
|
|
22
|
+
- bundle exec kitchen test -d always
|
|
23
|
+
- os: linux
|
|
24
|
+
rvm: 2.6.5
|
|
25
|
+
dist: xenial
|
|
26
|
+
language: ruby
|
|
27
|
+
cache: bundler
|
|
28
|
+
script:
|
|
29
|
+
- bundle exec docker version
|
|
30
|
+
- bundle exec kitchen --version
|
|
31
|
+
- bundle exec rake spec
|
|
32
|
+
- bundle exec kitchen test -d always
|
|
33
|
+
- os: windows
|
|
34
|
+
language: bash
|
|
35
|
+
install:
|
|
36
|
+
- choco install mingw
|
|
37
|
+
- choco install msys2
|
|
38
|
+
- ridk.cmd exec pacman -S --noconfirm --needed base-devel mingw-w64-x86_64-toolchain
|
|
39
|
+
script:
|
|
40
|
+
- taskkill -IM "gpg-agent.exe" -F
|
|
41
|
+
- powershell -ExecutionPolicy Bypass -NoLogo -File docker.ps1
|
|
42
|
+
- export KITCHEN_YAML=.kitchen.windows.yml
|
|
43
|
+
- ruby -v
|
|
44
|
+
- gem install bundler
|
|
45
|
+
- bundle install
|
|
46
|
+
- bundle exec docker version
|
|
47
|
+
- bundle exec kitchen --version
|
|
48
|
+
- bundle exec rake spec
|
|
49
|
+
- bundle exec kitchen test -d always
|
|
10
50
|
|
|
11
51
|
services:
|
|
12
52
|
- docker
|
|
13
|
-
|
|
14
|
-
script:
|
|
15
|
-
- bundle exec docker version
|
|
16
|
-
- bundle exec kitchen --version
|
|
17
|
-
- bundle exec rake spec
|
|
18
|
-
- bundle exec kitchen test -d always
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Kitchen-Docker Changelog
|
|
2
2
|
|
|
3
|
+
## 2.10.0 - Mar 28, 2020
|
|
4
|
+
|
|
5
|
+
* Switched from require to require_relative to slightly improve load time performance
|
|
6
|
+
* Allow for train gem 3.x
|
|
7
|
+
* Refactor driver to include Windows support (includes new transport for all supported platforms)
|
|
8
|
+
|
|
3
9
|
## 2.9.0 - Mar 15, 2019
|
|
4
10
|
|
|
5
11
|
* Add automatic OS detection for amazonlinux, opensuse/leap, and opensuse/tumbleweed
|
data/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://codecov.io/github/test-kitchen/kitchen-docker)
|
|
6
6
|
[](https://www.apache.org/licenses/LICENSE-2.0)
|
|
7
7
|
|
|
8
|
-
A Test Kitchen Driver for Docker.
|
|
8
|
+
A Test Kitchen Driver and Transport for Docker.
|
|
9
9
|
|
|
10
10
|
## Requirements
|
|
11
11
|
|
|
@@ -15,13 +15,15 @@ A Test Kitchen Driver for Docker.
|
|
|
15
15
|
|
|
16
16
|
Please read the Test Kitchen [docs][test_kitchen_docs] for more details.
|
|
17
17
|
|
|
18
|
-
Example `.kitchen.local.yml`:
|
|
18
|
+
Example (Linux) `.kitchen.local.yml`:
|
|
19
19
|
|
|
20
20
|
```yaml
|
|
21
21
|
---
|
|
22
22
|
driver:
|
|
23
23
|
name: docker
|
|
24
|
-
|
|
24
|
+
env_variables:
|
|
25
|
+
TEST_KEY: TEST_VALUE
|
|
26
|
+
|
|
25
27
|
platforms:
|
|
26
28
|
- name: ubuntu
|
|
27
29
|
run_list:
|
|
@@ -32,6 +34,30 @@ platforms:
|
|
|
32
34
|
platform: rhel
|
|
33
35
|
run_list:
|
|
34
36
|
- recipe[yum]
|
|
37
|
+
|
|
38
|
+
transport:
|
|
39
|
+
name: docker
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Example (Windows) `.kitchen.local.yml`:
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
---
|
|
46
|
+
driver:
|
|
47
|
+
name: docker
|
|
48
|
+
|
|
49
|
+
platforms:
|
|
50
|
+
- name: windows
|
|
51
|
+
driver_config:
|
|
52
|
+
image: mcr.microsoft.com/windows/servercore:1607
|
|
53
|
+
platform: windows
|
|
54
|
+
run_list:
|
|
55
|
+
- recipe[chef_client]
|
|
56
|
+
|
|
57
|
+
transport:
|
|
58
|
+
name: docker
|
|
59
|
+
env_variables:
|
|
60
|
+
TEST_KEY: TEST_VALUE
|
|
35
61
|
```
|
|
36
62
|
|
|
37
63
|
## Default Configuration
|
|
@@ -83,11 +109,9 @@ Examples:
|
|
|
83
109
|
|
|
84
110
|
### socket
|
|
85
111
|
|
|
86
|
-
The Docker daemon socket to use. By default, Docker will listen on
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
this option. If a TCP socket is set, its host will be used for SSH access
|
|
90
|
-
to suite containers.
|
|
112
|
+
The Docker daemon socket to use. By default, Docker will listen on `unix:///var/run/docker.sock` (On Windows, `npipe:////./pipe/docker_engine`),
|
|
113
|
+
and no configuration here is required. If Docker is binding to another host/port or Unix socket, you will need to set this option.
|
|
114
|
+
If a TCP socket is set, its host will be used for SSH access to suite containers.
|
|
91
115
|
|
|
92
116
|
Examples:
|
|
93
117
|
|
|
@@ -99,10 +123,27 @@ Examples:
|
|
|
99
123
|
socket: tcp://docker.example.com:4242
|
|
100
124
|
```
|
|
101
125
|
|
|
102
|
-
If you
|
|
103
|
-
|
|
126
|
+
If you are using the InSpec verifier on Windows, using named pipes for the Docker engine will not work with the Docker transport.
|
|
127
|
+
Set the socket option with the TCP socket address of the Docker engine as shown below:
|
|
104
128
|
```yaml
|
|
105
|
-
socket:
|
|
129
|
+
socket: tcp://localhost:2375
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The Docker engine must be configured to listen on a TCP port (default port is 2375). This can be configured by editing the configuration file
|
|
133
|
+
(usually located in `C:\ProgramData\docker\config\daemon.json`) and adding the hosts value:
|
|
134
|
+
```
|
|
135
|
+
"hosts": ["tcp://0.0.0.0:2375"]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Example configuration is shown below:
|
|
139
|
+
```
|
|
140
|
+
{
|
|
141
|
+
"registry-mirrors": [],
|
|
142
|
+
"insecure-registries": [],
|
|
143
|
+
"debug": true,
|
|
144
|
+
"experimental": false,
|
|
145
|
+
"hosts": ["tcp://0.0.0.0:2375"]
|
|
146
|
+
}
|
|
106
147
|
```
|
|
107
148
|
|
|
108
149
|
If you use [Boot2Docker](https://github.com/boot2docker/boot2docker)
|
|
@@ -115,7 +156,6 @@ $MACHINE)"` then use the following:
|
|
|
115
156
|
socket: tcp://192.168.59.103:2375
|
|
116
157
|
```
|
|
117
158
|
|
|
118
|
-
|
|
119
159
|
### image
|
|
120
160
|
|
|
121
161
|
The Docker image to use as the base for the suite containers. You can find
|
|
@@ -134,6 +174,7 @@ suite container for Test Kitchen. Kitchen Docker currently supports:
|
|
|
134
174
|
* `amazonlinux`, `rhel`, `centos`, `fedora` or `oraclelinux`
|
|
135
175
|
* `gentoo` or `gentoo-paludis`
|
|
136
176
|
* `opensuse/tumbleweed`, `opensuse/leap`, `opensuse` or `sles`
|
|
177
|
+
* `windows`
|
|
137
178
|
|
|
138
179
|
The default will be computed, using the platform name (see the Default
|
|
139
180
|
Configuration section for more details).
|
|
@@ -182,6 +223,17 @@ driver_config:
|
|
|
182
223
|
provision_command: curl -L https://www.opscode.com/chef/install.sh | bash
|
|
183
224
|
require_chef_omnibus: false
|
|
184
225
|
```
|
|
226
|
+
### env_variables
|
|
227
|
+
|
|
228
|
+
Adds environment variables to Docker container
|
|
229
|
+
|
|
230
|
+
Examples:
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
env_variables:
|
|
234
|
+
TEST_KEY_1: TEST_VALUE
|
|
235
|
+
SOME_VAR: SOME_VALUE
|
|
236
|
+
```
|
|
185
237
|
|
|
186
238
|
### use\_cache
|
|
187
239
|
|
data/docker.ps1
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# This script is used to configure the Docker service for Windows builds in Travis CI
|
|
2
|
+
Write-Host "Configuring Docker service to listen on TCP port 2375..."
|
|
3
|
+
$dockerSvcArgs = (Get-WmiObject Win32_Service | ?{$_.Name -eq 'docker'} | Select PathName).PathName
|
|
4
|
+
$dockerSvcArgs = "$dockerSvcArgs -H tcp://0.0.0.0:2375 -H npipe:////./pipe/docker_engine"
|
|
5
|
+
Write-Host "Docker Service Args: $dockerSvcArgs"
|
|
6
|
+
|
|
7
|
+
Get-WmiObject Win32_Service -Filter "Name='docker'" | Invoke-WmiMethod -Name Change -ArgumentList @($null,$null,$null,$null,$null, $dockerSvcArgs) | Out-Null
|
|
8
|
+
|
|
9
|
+
Restart-Service docker -Force -Verbose
|
data/kitchen-docker.gemspec
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
lib = File.expand_path('../lib', __FILE__)
|
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require 'kitchen/
|
|
3
|
+
require 'kitchen/docker/docker_version'
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |spec|
|
|
7
6
|
spec.name = 'kitchen-docker'
|
|
8
|
-
spec.version = Kitchen::
|
|
7
|
+
spec.version = Kitchen::Docker::DOCKER_VERSION
|
|
9
8
|
spec.authors = ['Sean Porter']
|
|
10
9
|
spec.email = ['portertech@gmail.com']
|
|
11
10
|
spec.description = %q{A Docker Driver for Test Kitchen}
|
|
@@ -14,7 +13,6 @@ Gem::Specification.new do |spec|
|
|
|
14
13
|
spec.license = 'Apache 2.0'
|
|
15
14
|
|
|
16
15
|
spec.files = `git ls-files`.split($/)
|
|
17
|
-
spec.executables = []
|
|
18
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
17
|
spec.require_paths = ['lib']
|
|
20
18
|
|
|
@@ -36,5 +34,6 @@ Gem::Specification.new do |spec|
|
|
|
36
34
|
spec.add_development_dependency 'codecov', '~> 0.0', '>= 0.0.2'
|
|
37
35
|
|
|
38
36
|
# Integration testing gems.
|
|
39
|
-
spec.add_development_dependency 'kitchen-inspec', '~>
|
|
37
|
+
spec.add_development_dependency 'kitchen-inspec', '~> 1.1'
|
|
38
|
+
spec.add_development_dependency 'train', '>= 2.1', '< 4.0' # validate 4.x when it's released
|
|
40
39
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
begin
|
|
15
|
+
require 'docker'
|
|
16
|
+
|
|
17
|
+
# Override API_VERSION constant in docker-api gem to use version 1.24 of the Docker API
|
|
18
|
+
# This override is for the docker-api gem to communicate to the Docker engine on Windows
|
|
19
|
+
module Docker
|
|
20
|
+
VERSION = '0.0.0'
|
|
21
|
+
API_VERSION = '1.24'
|
|
22
|
+
end
|
|
23
|
+
rescue LoadError => e
|
|
24
|
+
logger.debug("[Docker] docker-api gem not found for InSpec verifier. #{e}")
|
|
25
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
require_relative 'helpers/cli_helper'
|
|
15
|
+
require_relative 'helpers/container_helper'
|
|
16
|
+
require_relative 'helpers/file_helper'
|
|
17
|
+
require_relative 'helpers/image_helper'
|
|
18
|
+
|
|
19
|
+
module Kitchen
|
|
20
|
+
module Docker
|
|
21
|
+
class Container
|
|
22
|
+
include Kitchen::Docker::Helpers::CliHelper
|
|
23
|
+
include Kitchen::Docker::Helpers::ContainerHelper
|
|
24
|
+
include Kitchen::Docker::Helpers::FileHelper
|
|
25
|
+
include Kitchen::Docker::Helpers::ImageHelper
|
|
26
|
+
|
|
27
|
+
def initialize(config)
|
|
28
|
+
@config = config
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def create(state)
|
|
32
|
+
if container_exists?(state)
|
|
33
|
+
info("Container ID #{state[:container_id]} already exists.")
|
|
34
|
+
elsif !container_exists?(state) && state[:container_id]
|
|
35
|
+
raise ActionFailed, "Container ID #{state[:container_id]} was found in the kitchen state data, "\
|
|
36
|
+
'but the container does not exist.'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
state[:username] = @config[:username]
|
|
40
|
+
state[:hostname] = 'localhost'
|
|
41
|
+
|
|
42
|
+
if remote_socket?
|
|
43
|
+
state[:hostname] = socket_uri.host
|
|
44
|
+
elsif config[:use_internal_docker_network]
|
|
45
|
+
state[:hostname] = container_ip_address(state)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def upload(locals, remote)
|
|
50
|
+
files = locals
|
|
51
|
+
files = Array(locals) unless locals.is_a?(Array)
|
|
52
|
+
|
|
53
|
+
files.each do |file|
|
|
54
|
+
copy_file_to_container(@config, file, remote)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
files
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def destroy(state)
|
|
61
|
+
info("[Docker] Destroying Docker container #{state[:container_id]}") if state[:container_id]
|
|
62
|
+
remove_container(state) if container_exists?(state)
|
|
63
|
+
|
|
64
|
+
if @config[:remove_images] && state[:image_id]
|
|
65
|
+
remove_image(state) if image_exists?(state)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
require 'base64'
|
|
15
|
+
require 'openssl'
|
|
16
|
+
require 'securerandom'
|
|
17
|
+
require 'shellwords'
|
|
18
|
+
|
|
19
|
+
require_relative '../container'
|
|
20
|
+
|
|
21
|
+
module Kitchen
|
|
22
|
+
module Docker
|
|
23
|
+
class Container
|
|
24
|
+
class Linux < Kitchen::Docker::Container
|
|
25
|
+
MUTEX_FOR_SSH_KEYS = Mutex.new
|
|
26
|
+
|
|
27
|
+
def initialize(config)
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def create(state)
|
|
32
|
+
super
|
|
33
|
+
|
|
34
|
+
debug('Creating Linux container')
|
|
35
|
+
generate_keys
|
|
36
|
+
|
|
37
|
+
state[:ssh_key] = @config[:private_key]
|
|
38
|
+
state[:image_id] = build_image(state, dockerfile) unless state[:image_id]
|
|
39
|
+
state[:container_id] = run_container(state, 22) unless state[:container_id]
|
|
40
|
+
state[:hostname] = 'localhost'
|
|
41
|
+
state[:port] = container_ssh_port(state)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def execute(command)
|
|
45
|
+
# Create temp script file and upload files to container
|
|
46
|
+
debug("Executing command on Linux container (Platform: #{@config[:platform]})")
|
|
47
|
+
filename = "docker-#{::SecureRandom.uuid}.sh"
|
|
48
|
+
temp_file = "./.kitchen/temp/#{filename}"
|
|
49
|
+
create_temp_file(temp_file, command)
|
|
50
|
+
|
|
51
|
+
remote_path = @config[:temp_dir]
|
|
52
|
+
debug("Creating directory #{remote_path} on container")
|
|
53
|
+
create_dir_on_container(@config, remote_path)
|
|
54
|
+
|
|
55
|
+
debug("Uploading temp file #{temp_file} to #{remote_path} on container")
|
|
56
|
+
upload(temp_file, remote_path)
|
|
57
|
+
|
|
58
|
+
debug('Deleting temp file from local filesystem')
|
|
59
|
+
::File.delete(temp_file)
|
|
60
|
+
|
|
61
|
+
# Replace any environment variables used in the path and execute script file
|
|
62
|
+
debug("Executing temp script #{remote_path}/#{filename} on container")
|
|
63
|
+
remote_path = replace_env_variables(@config, remote_path)
|
|
64
|
+
|
|
65
|
+
container_exec(@config, "/bin/bash #{remote_path}/#{filename}")
|
|
66
|
+
rescue => e
|
|
67
|
+
raise "Failed to execute command on Linux container. #{e}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
protected
|
|
71
|
+
|
|
72
|
+
def generate_keys
|
|
73
|
+
MUTEX_FOR_SSH_KEYS.synchronize do
|
|
74
|
+
if !File.exist?(@config[:public_key]) || !File.exist?(@config[:private_key])
|
|
75
|
+
private_key = OpenSSL::PKey::RSA.new(2048)
|
|
76
|
+
blobbed_key = Base64.encode64(private_key.to_blob).gsub("\n", '')
|
|
77
|
+
public_key = "ssh-rsa #{blobbed_key} kitchen_docker_key"
|
|
78
|
+
File.open(@config[:private_key], 'w') do |file|
|
|
79
|
+
file.write(private_key)
|
|
80
|
+
file.chmod(0600)
|
|
81
|
+
end
|
|
82
|
+
File.open(@config[:public_key], 'w') do |file|
|
|
83
|
+
file.write(public_key)
|
|
84
|
+
file.chmod(0600)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def parse_container_ssh_port(output)
|
|
91
|
+
_host, port = output.split(':')
|
|
92
|
+
port.to_i
|
|
93
|
+
rescue => e
|
|
94
|
+
raise ActionFailed, "Could not parse Docker port output for container SSH port. #{e}"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def container_ssh_port(state)
|
|
98
|
+
return 22 if @config[:use_internal_docker_network]
|
|
99
|
+
|
|
100
|
+
output = docker_command("port #{state[:container_id]} 22/tcp")
|
|
101
|
+
parse_container_ssh_port(output)
|
|
102
|
+
rescue => e
|
|
103
|
+
raise ActionFailed, "Docker reports container has no ssh port mapped. #{e}"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def dockerfile
|
|
107
|
+
return dockerfile_template if @config[:dockerfile]
|
|
108
|
+
|
|
109
|
+
from = "FROM #{@config[:image]}"
|
|
110
|
+
|
|
111
|
+
platform = case @config[:platform]
|
|
112
|
+
when 'debian', 'ubuntu'
|
|
113
|
+
disable_upstart = <<-CODE
|
|
114
|
+
RUN [ ! -f "/sbin/initctl" ] || dpkg-divert --local --rename --add /sbin/initctl && ln -sf /bin/true /sbin/initctl
|
|
115
|
+
CODE
|
|
116
|
+
packages = <<-CODE
|
|
117
|
+
ENV DEBIAN_FRONTEND noninteractive
|
|
118
|
+
ENV container docker
|
|
119
|
+
RUN apt-get update
|
|
120
|
+
RUN apt-get install -y sudo openssh-server curl lsb-release
|
|
121
|
+
CODE
|
|
122
|
+
@config[:disable_upstart] ? disable_upstart + packages : packages
|
|
123
|
+
when 'rhel', 'centos', 'oraclelinux', 'amazonlinux'
|
|
124
|
+
<<-CODE
|
|
125
|
+
ENV container docker
|
|
126
|
+
RUN yum clean all
|
|
127
|
+
RUN yum install -y sudo openssh-server openssh-clients which curl
|
|
128
|
+
RUN [ -f "/etc/ssh/ssh_host_rsa_key" ] || ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''
|
|
129
|
+
RUN [ -f "/etc/ssh/ssh_host_dsa_key" ] || ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''
|
|
130
|
+
CODE
|
|
131
|
+
when 'fedora'
|
|
132
|
+
<<-CODE
|
|
133
|
+
ENV container docker
|
|
134
|
+
RUN dnf clean all
|
|
135
|
+
RUN dnf install -y sudo openssh-server openssh-clients which curl
|
|
136
|
+
RUN [ -f "/etc/ssh/ssh_host_rsa_key" ] || ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''
|
|
137
|
+
RUN [ -f "/etc/ssh/ssh_host_dsa_key" ] || ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''
|
|
138
|
+
CODE
|
|
139
|
+
when 'opensuse/tumbleweed', 'opensuse/leap', 'opensuse', 'sles'
|
|
140
|
+
<<-CODE
|
|
141
|
+
ENV container docker
|
|
142
|
+
RUN zypper install -y sudo openssh which curl
|
|
143
|
+
RUN [ -f "/etc/ssh/ssh_host_rsa_key" ] || ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ''
|
|
144
|
+
RUN [ -f "/etc/ssh/ssh_host_dsa_key" ] || ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ''
|
|
145
|
+
CODE
|
|
146
|
+
when 'arch'
|
|
147
|
+
# See https://bugs.archlinux.org/task/47052 for why we
|
|
148
|
+
# blank out limits.conf.
|
|
149
|
+
<<-CODE
|
|
150
|
+
RUN pacman --noconfirm -Sy archlinux-keyring
|
|
151
|
+
RUN pacman-db-upgrade
|
|
152
|
+
RUN pacman --noconfirm -Syu openssl openssh sudo curl
|
|
153
|
+
RUN [ -f "/etc/ssh/ssh_host_rsa_key" ] || ssh-keygen -A -t rsa -f /etc/ssh/ssh_host_rsa_key
|
|
154
|
+
RUN [ -f "/etc/ssh/ssh_host_dsa_key" ] || ssh-keygen -A -t dsa -f /etc/ssh/ssh_host_dsa_key
|
|
155
|
+
RUN echo >/etc/security/limits.conf
|
|
156
|
+
CODE
|
|
157
|
+
when 'gentoo'
|
|
158
|
+
<<-CODE
|
|
159
|
+
RUN emerge --sync
|
|
160
|
+
RUN emerge net-misc/openssh app-admin/sudo
|
|
161
|
+
RUN [ -f "/etc/ssh/ssh_host_rsa_key" ] || ssh-keygen -A -t rsa -f /etc/ssh/ssh_host_rsa_key
|
|
162
|
+
RUN [ -f "/etc/ssh/ssh_host_dsa_key" ] || ssh-keygen -A -t dsa -f /etc/ssh/ssh_host_dsa_key
|
|
163
|
+
CODE
|
|
164
|
+
when 'gentoo-paludis'
|
|
165
|
+
<<-CODE
|
|
166
|
+
RUN cave sync
|
|
167
|
+
RUN cave resolve -zx net-misc/openssh app-admin/sudo
|
|
168
|
+
RUN [ -f "/etc/ssh/ssh_host_rsa_key" ] || ssh-keygen -A -t rsa -f /etc/ssh/ssh_host_rsa_key
|
|
169
|
+
RUN [ -f "/etc/ssh/ssh_host_dsa_key" ] || ssh-keygen -A -t dsa -f /etc/ssh/ssh_host_dsa_key
|
|
170
|
+
CODE
|
|
171
|
+
else
|
|
172
|
+
raise ActionFailed, "Unknown platform '#{@config[:platform]}'"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
username = @config[:username]
|
|
176
|
+
public_key = IO.read(@config[:public_key]).strip
|
|
177
|
+
homedir = username == 'root' ? '/root' : "/home/#{username}"
|
|
178
|
+
|
|
179
|
+
base = <<-CODE
|
|
180
|
+
RUN if ! getent passwd #{username}; then \
|
|
181
|
+
useradd -d #{homedir} -m -s /bin/bash -p '*' #{username}; \
|
|
182
|
+
fi
|
|
183
|
+
RUN echo "#{username} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
|
184
|
+
RUN echo "Defaults !requiretty" >> /etc/sudoers
|
|
185
|
+
RUN mkdir -p #{homedir}/.ssh
|
|
186
|
+
RUN chown -R #{username} #{homedir}/.ssh
|
|
187
|
+
RUN chmod 0700 #{homedir}/.ssh
|
|
188
|
+
RUN touch #{homedir}/.ssh/authorized_keys
|
|
189
|
+
RUN chown #{username} #{homedir}/.ssh/authorized_keys
|
|
190
|
+
RUN chmod 0600 #{homedir}/.ssh/authorized_keys
|
|
191
|
+
RUN mkdir -p /run/sshd
|
|
192
|
+
CODE
|
|
193
|
+
|
|
194
|
+
custom = ''
|
|
195
|
+
Array(@config[:provision_command]).each do |cmd|
|
|
196
|
+
custom << "RUN #{cmd}\n"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
ssh_key = "RUN echo #{Shellwords.escape(public_key)} >> #{homedir}/.ssh/authorized_keys"
|
|
200
|
+
|
|
201
|
+
# Empty string to ensure the file ends with a newline.
|
|
202
|
+
output = [from, dockerfile_proxy_config, platform, base, custom, ssh_key, ''].join("\n")
|
|
203
|
+
debug('--- Start Dockerfile ---')
|
|
204
|
+
debug(output.strip)
|
|
205
|
+
debug('--- End Dockerfile ---')
|
|
206
|
+
output
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|