Skip to content

Commit

Permalink
Merge pull request #340 from jeffreycoe/windows-support
Browse files Browse the repository at this point in the history
Refactor driver to include Windows support (includes new transport for all supported platforms)
  • Loading branch information
Stuart Preston authored Jul 30, 2019
2 parents 9f214f2 + 3e4da0f commit c43a4af
Show file tree
Hide file tree
Showing 24 changed files with 1,457 additions and 500 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ tmp
.kitchen/
.kitchen.local.yml
Dockerfile*
.DS_Store
33 changes: 33 additions & 0 deletions .kitchen.windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<% # Make sure the local copy of the driver is loaded %>
<% lib = File.expand_path('../lib', __FILE__) %>
<% $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) %>
---
driver:
name: docker
provision_command:
- powershell -ExecutionPolicy Bypass -NoLogo -Command . { iwr -useb https://omnitruck.chef.io/install.ps1 } ^| iex; install
- powershell -Command $path=$env:Path + ';c:\opscode\chef\embedded\bin'; Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\' -Name Path -Value $path

transport:
name: docker
socket: tcp://localhost:2375

provisioner:
name: dummy

platforms:
- name: windows
driver_config:
image: mcr.microsoft.com/windows/servercore:1803
platform: windows

suites:
- name: default
- name: context
driver:
build_context: false
- name: inspec
driver:
provision_command: echo 1
verifier:
name: inspec
7 changes: 7 additions & 0 deletions .kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ driver:
name: docker
provision_command: curl -L https://www.chef.io/chef/install.sh | bash

transport:
name: docker

provisioner:
name: dummy

Expand All @@ -14,6 +17,10 @@ platforms:
- name: ubuntu-16.04
- name: ubuntu-18.04
- name: fedora-latest
driver:
provision_command:
- yum install libxcrypt-compat.x86_64 -y
- curl -L https://www.chef.io/chef/install.sh | bash
- name: centos-6
- name: centos-7
- name: oraclelinux-6
Expand Down
64 changes: 49 additions & 15 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,52 @@
dist: xenial
language: ruby
cache: bundler

rvm:
- 2.3.8
- 2.4.5
- 2.5.4
- 2.6.2
matrix:
include:
- os: linux
rvm: 2.4.5
dist: xenial
language: ruby
cache: bundler
script:
- bundle exec docker version
- bundle exec kitchen --version
- bundle exec rake spec
- bundle exec kitchen test -d always
- os: linux
rvm: 2.5.4
dist: xenial
language: ruby
cache: bundler
script:
- bundle exec docker version
- bundle exec kitchen --version
- bundle exec rake spec
- bundle exec kitchen test -d always
- os: linux
rvm: 2.6.2
dist: xenial
language: ruby
cache: bundler
script:
- bundle exec docker version
- bundle exec kitchen --version
- bundle exec rake spec
- bundle exec kitchen test -d always
- os: windows
language: bash
install:
- choco install mingw
- choco install msys2
- ridk.cmd exec pacman -S --noconfirm --needed base-devel mingw-w64-x86_64-toolchain
script:
- taskkill -IM "gpg-agent.exe" -F
- powershell -ExecutionPolicy Bypass -NoLogo -File docker.ps1
- export KITCHEN_YAML=.kitchen.windows.yml
- ruby -v
- gem install bundler
- bundle install
- bundle exec docker version
- bundle exec kitchen --version
- bundle exec rake spec
- bundle exec kitchen test -d always

services:
- docker

script:
- bundle exec docker version
- bundle exec kitchen --version
- bundle exec rake spec
- bundle exec kitchen test -d always
76 changes: 64 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Coverage](https://img.shields.io/codecov/c/github/test-kitchen/kitchen-docker.svg)](https://codecov.io/github/test-kitchen/kitchen-docker)
[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)

A Test Kitchen Driver for Docker.
A Test Kitchen Driver and Transport for Docker.

## Requirements

Expand All @@ -15,13 +15,15 @@ A Test Kitchen Driver for Docker.

Please read the Test Kitchen [docs][test_kitchen_docs] for more details.

Example `.kitchen.local.yml`:
Example (Linux) `.kitchen.local.yml`:

```yaml
---
driver:
name: docker

env_variables:
TEST_KEY: TEST_VALUE

platforms:
- name: ubuntu
run_list:
Expand All @@ -32,6 +34,30 @@ platforms:
platform: rhel
run_list:
- recipe[yum]

transport:
name: docker
```
Example (Windows) `.kitchen.local.yml`:

```yaml
---
driver:
name: docker
platforms:
- name: windows
driver_config:
image: mcr.microsoft.com/windows/servercore:1607
platform: windows
run_list:
- recipe[chef_client]
transport:
name: docker
env_variables:
TEST_KEY: TEST_VALUE
```

## Default Configuration
Expand Down Expand Up @@ -83,11 +109,9 @@ Examples:

### socket

The Docker daemon socket to use. By default, Docker will listen on
`unix:///var/run/docker.sock`, and no configuration here is required. If
Docker is binding to another host/port or Unix socket, you will need to set
this option. If a TCP socket is set, its host will be used for SSH access
to suite containers.
The Docker daemon socket to use. By default, Docker will listen on `unix:///var/run/docker.sock` (On Windows, `npipe:////./pipe/docker_engine`),
and no configuration here is required. If Docker is binding to another host/port or Unix socket, you will need to set this option.
If a TCP socket is set, its host will be used for SSH access to suite containers.

Examples:

Expand All @@ -99,10 +123,27 @@ Examples:
socket: tcp://docker.example.com:4242
```

If you use [Docker for Windows](https://docs.docker.com/docker-for-windows/)

If you are using the InSpec verifier on Windows, using named pipes for the Docker engine will not work with the Docker transport.
Set the socket option with the TCP socket address of the Docker engine as shown below:
```yaml
socket: npipe:////./pipe/docker_engine
socket: tcp://localhost:2375
```

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
(usually located in `C:\ProgramData\docker\config\daemon.json`) and adding the hosts value:
```
"hosts": ["tcp://0.0.0.0:2375"]
```

Example configuration is shown below:
```
{
"registry-mirrors": [],
"insecure-registries": [],
"debug": true,
"experimental": false,
"hosts": ["tcp://0.0.0.0:2375"]
}
```

If you use [Boot2Docker](https://github.com/boot2docker/boot2docker)
Expand All @@ -115,7 +156,6 @@ $MACHINE)"` then use the following:
socket: tcp://192.168.59.103:2375
```


### image

The Docker image to use as the base for the suite containers. You can find
Expand All @@ -134,6 +174,7 @@ suite container for Test Kitchen. Kitchen Docker currently supports:
* `amazonlinux`, `rhel`, `centos`, `fedora` or `oraclelinux`
* `gentoo` or `gentoo-paludis`
* `opensuse/tumbleweed`, `opensuse/leap`, `opensuse` or `sles`
* `windows`

The default will be computed, using the platform name (see the Default
Configuration section for more details).
Expand Down Expand Up @@ -182,6 +223,17 @@ driver_config:
provision_command: curl -L https://www.opscode.com/chef/install.sh | bash
require_chef_omnibus: false
```
### env_variables

Adds environment variables to Docker container

Examples:

```yaml
env_variables:
TEST_KEY_1: TEST_VALUE
SOME_VAR: SOME_VALUE
```

### use\_cache

Expand Down
9 changes: 9 additions & 0 deletions docker.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# This script is used to configure the Docker service for Windows builds in Travis CI
Write-Host "Configuring Docker service to listen on TCP port 2375..."
$dockerSvcArgs = (Get-WmiObject Win32_Service | ?{$_.Name -eq 'docker'} | Select PathName).PathName
$dockerSvcArgs = "$dockerSvcArgs -H tcp://0.0.0.0:2375 -H npipe:////./pipe/docker_engine"
Write-Host "Docker Service Args: $dockerSvcArgs"

Get-WmiObject Win32_Service -Filter "Name='docker'" | Invoke-WmiMethod -Name Change -ArgumentList @($null,$null,$null,$null,$null, $dockerSvcArgs) | Out-Null

Restart-Service docker -Force -Verbose
8 changes: 4 additions & 4 deletions kitchen-docker.gemspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'kitchen/driver/docker_version'
require 'kitchen/docker/docker_version'

Gem::Specification.new do |spec|
spec.name = 'kitchen-docker'
spec.version = Kitchen::Driver::DOCKER_VERSION
spec.version = Kitchen::Docker::DOCKER_VERSION
spec.authors = ['Sean Porter']
spec.email = ['[email protected]']
spec.description = %q{A Docker Driver for Test Kitchen}
Expand Down Expand Up @@ -36,5 +35,6 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'codecov', '~> 0.0', '>= 0.0.2'

# Integration testing gems.
spec.add_development_dependency 'kitchen-inspec', '~> 0.14'
spec.add_development_dependency 'kitchen-inspec', '~> 1.1'
spec.add_development_dependency 'train', '~> 2.1'
end
25 changes: 25 additions & 0 deletions lib/docker/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

begin
require 'docker'

# Override API_VERSION constant in docker-api gem to use version 1.24 of the Docker API
# This override is for the docker-api gem to communicate to the Docker engine on Windows
module Docker
VERSION = '0.0.0'
API_VERSION = '1.24'
end
rescue LoadError => e
logger.debug("[Docker] docker-api gem not found for InSpec verifier. #{e}")
end
70 changes: 70 additions & 0 deletions lib/kitchen/docker/container.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'kitchen/docker/helpers/cli_helper'
require 'kitchen/docker/helpers/container_helper'
require 'kitchen/docker/helpers/file_helper'
require 'kitchen/docker/helpers/image_helper'

module Kitchen
module Docker
class Container
include Kitchen::Docker::Helpers::CliHelper
include Kitchen::Docker::Helpers::ContainerHelper
include Kitchen::Docker::Helpers::FileHelper
include Kitchen::Docker::Helpers::ImageHelper

def initialize(config)
@config = config
end

def create(state)
if container_exists?(state)
info("Container ID #{state[:container_id]} already exists.")
elsif !container_exists?(state) && state[:container_id]
raise ActionFailed, "Container ID #{state[:container_id]} was found in the kitchen state data, "\
'but the container does not exist.'
end

state[:username] = @config[:username]
state[:hostname] = 'localhost'

if remote_socket?
state[:hostname] = socket_uri.host
elsif config[:use_internal_docker_network]
state[:hostname] = container_ip_address(state)
end
end

def upload(locals, remote)
files = locals
files = Array(locals) unless locals.is_a?(Array)

files.each do |file|
copy_file_to_container(@config, file, remote)
end

files
end

def destroy(state)
info("[Docker] Destroying Docker container #{state[:container_id]}") if state[:container_id]
remove_container(state) if container_exists?(state)

if @config[:remove_images] && state[:image_id]
remove_image(state) if image_exists?(state)
end
end
end
end
end
Loading

0 comments on commit c43a4af

Please sign in to comment.