Class: Kitchen::Docker::Container::Windows

Inherits:
Kitchen::Docker::Container show all
Defined in:
lib/kitchen/docker/container/windows.rb

Overview

A Windows container, driven through docker exec.

There is no SSH server and no key to inject: commands are uploaded as PowerShell scripts and executed in the container directly, so no port is published.

Constant Summary

Constants included from Helpers::ContainerHelper

Helpers::ContainerHelper::COPIED_MARKER

Instance Method Summary collapse

Methods inherited from Kitchen::Docker::Container

#destroy, #hostname, #upload

Methods included from Helpers::ImageHelper

#build_image, #image_exists?, #image_in_use?, #parse_image_id, #remove_image

Methods included from Helpers::ContainerHelper

#container_env_variables, #container_exec, #container_exists?, #container_ip_address, #container_running?, #copy_file_to_container, #create_dir_on_container, #dockerfile_path, #dockerfile_proxy_config, #dockerfile_template, #file_on_container?, #ip_address?, #parse_container_id, #proxy_env_vars, #remote_socket?, #remove_container, #replace_env_variables, #run_container, #socket_uri, #verify_file_copied

Methods included from Helpers::CliHelper

#build_copy_command, #build_env_variable_args, #build_exec_command, #build_powershell_command, #build_run_command, #config_to_options, #dev_null, #docker_command, #docker_shell_opts, #docker_sudo_opts, #run_command, #shell_escape

Methods included from Helpers::FileHelper

#create_temp_file

Constructor Details

#initialize(config) ⇒ Windows

Returns a new instance of Windows.

Parameters:

  • config (Hash)

    the driver configuration



28
29
30
# File 'lib/kitchen/docker/container/windows.rb', line 28

def initialize(config)
  super
end

Instance Method Details

#create(state) ⇒ void

This method returns an undefined value.

Builds the image and runs the container.

No port is published: Windows containers are driven through docker exec rather than SSH, so there is nothing to map.

Parameters:

  • state (Hash)

    mutable instance state; gains username, image_id, container_id, and hostname



40
41
42
43
44
45
46
47
48
# File 'lib/kitchen/docker/container/windows.rb', line 40

def create(state)
  super

  debug("Creating Windows container")
  state[:username] = @config[:username]
  state[:image_id] = build_image(state, dockerfile) unless state[:image_id]
  state[:container_id] = run_container(state) unless state[:container_id]
  state[:hostname] = hostname(state)
end

#dockerfileString (protected)

Builds the Dockerfile for a Windows container.

Much shorter than the Linux equivalent: there is no SSH server and no key to inject, so only the base image, proxy settings, and any provision_command entries are emitted.

Returns:

  • (String)

    the Dockerfile contents

Raises:

  • (Kitchen::ActionFailed)

    if the platform is not windows



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/kitchen/docker/container/windows.rb', line 96

def dockerfile
  raise ActionFailed, "Unknown platform '#{@config[:platform]}'" unless @config[:platform] == "windows"
  return dockerfile_template if @config[:dockerfile]

  from = "FROM #{@config[:image]}"

  custom = ""
  Array(@config[:provision_command]).each do |cmd|
    custom << "RUN #{cmd}\n"
  end

  output = [from, dockerfile_proxy_config, custom, ""].join("\n")
  debug("--- Start Dockerfile ---")
  debug(output.strip)
  debug("--- End Dockerfile ---")
  output
end

#execute(command) ⇒ String

Runs a command in the container by uploading it as a PowerShell script.

Parameters:

  • command (String)

    the PowerShell code to run

Returns:

  • (String)

    the command's combined output

Raises:

  • (RuntimeError)

    if the command fails



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/kitchen/docker/container/windows.rb', line 55

def execute(command)
  # Create temp script file and upload files to container
  debug("Executing command on Windows container")
  filename = "docker-#{::SecureRandom.uuid}.ps1"
  temp_file = ".\\.kitchen\\temp\\#{filename}"
  create_temp_file(temp_file, command)

  remote_path = @config[:temp_dir].tr("/", "\\")
  debug("Creating directory #{remote_path} on container")
  create_dir_on_container(@config, remote_path)

  debug("Uploading temp file #{temp_file} to #{remote_path} on container")
  upload(temp_file, remote_path)

  # Replace any environment variables used in the path and execute script file
  debug("Executing temp script #{remote_path}\\#{filename} on container")
  remote_path = replace_env_variables(@config, remote_path)
  cmd = build_powershell_command("-File #{remote_path}\\#{filename}")

  container_exec(@config, cmd)
rescue => e
  raise "Failed to execute command on Windows container. #{e}"
ensure
  # Removed here rather than after the upload, so that a failure part
  # way through does not leave the script behind in .kitchen/temp.
  if temp_file && ::File.exist?(temp_file)
    debug("Deleting temp file from local filesystem")
    ::File.delete(temp_file)
  end
end