kitchen-docker 2.9.0 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a62c9e97edfb2215e2ad0f991eb88da0d9629e833af0165a78ebf7899894a81
4
- data.tar.gz: be82c57778795e8d4b0866ff0b7451eaf499ff81f71703cd3d92cdd2ec92f562
3
+ metadata.gz: df5438ae1f2f9b74072ba1c53c9b0c7876dd4abdd6e5cb864fddfa62c2bda75f
4
+ data.tar.gz: 4e7531d5e26a6c7bceeb7cd14779e256cf2ebf21a866d1ea66f18957567c6623
5
5
  SHA512:
6
- metadata.gz: 68bba42a990ad9335cc62be341448857a7c53312ff210366876f569a42f90e53f1a05fdb80aa263d26e4e2daaeea29fb2a79348fbdefe130ba4d53949aae2ecc
7
- data.tar.gz: 886d05137ffe4d7898f1865b7c03d4f504e9c1da7516b920685a32d5592d234cbd0c01d8a222ee266edb6504a85f95b6d2aef590c15131cdd8f89ac452e6f5a1
6
+ metadata.gz: cafda9489c84bbbe7848ca36f777c33910a0696f52b78a1333cfe1ea9c1a7c9a89a9ec0ad1b674dc38141e03929886653bbe39424789294dc84d99d9a333c93f
7
+ data.tar.gz: b5b121d05430ff88899cefe3d2754c00142f508237de92a9694919a5559227196b4d6d48651de6d7c620328207bea423e889671218c428e690fb59226e91e6c4
data/.gitignore CHANGED
@@ -18,3 +18,4 @@ tmp
18
18
  .kitchen/
19
19
  .kitchen.local.yml
20
20
  Dockerfile*
21
+ .DS_Store
@@ -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
@@ -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:
@@ -1,18 +1,52 @@
1
- dist: xenial
2
- language: ruby
3
- cache: bundler
4
-
5
- rvm:
6
- - 2.3.8
7
- - 2.4.5
8
- - 2.5.4
9
- - 2.6.2
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
@@ -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
  [![Coverage](https://img.shields.io/codecov/c/github/test-kitchen/kitchen-docker.svg)](https://codecov.io/github/test-kitchen/kitchen-docker)
6
6
  [![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](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
- `unix:///var/run/docker.sock`, and no configuration here is required. If
88
- Docker is binding to another host/port or Unix socket, you will need to set
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 use [Docker for Windows](https://docs.docker.com/docker-for-windows/)
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: npipe:////./pipe/docker_engine
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
 
@@ -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
@@ -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/driver/docker_version'
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::Driver::DOCKER_VERSION
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', '~> 0.14'
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