lib/kitchen/driver/docker.rb in kitchen-docker-1.1.0.beta vs lib/kitchen/driver/docker.rb in kitchen-docker-1.2.0

- old
+ new

@@ -14,20 +14,22 @@ # See the License for the specific language governing permissions and # limitations under the License. require 'kitchen' require 'json' +require File.join(File.dirname(__FILE__), 'docker', 'erb') module Kitchen module Driver # Docker driver for Kitchen. # # @author Sean Porter <portertech@gmail.com> class Docker < Kitchen::Driver::SSHBase + default_config :binary, 'docker' default_config :socket, 'unix:///var/run/docker.sock' default_config :privileged, false default_config :use_cache, true default_config :remove_images, false default_config :run_command, '/usr/sbin/sshd -D -o UseDNS=no -o UsePAM=no' @@ -47,11 +49,11 @@ end default_config :disable_upstart, true def verify_dependencies - run_command('docker > /dev/null', :quiet => true) + run_command("#{config[:binary]} > /dev/null", :quiet => true) rescue raise UserError, 'You must first install the Docker CLI tool http://www.docker.io/gettingstarted/' end @@ -59,11 +61,11 @@ platform, release = instance.platform.name.split('-') release ? [platform, release].join(':') : platform end def default_platform - instance.platform.name.split('-').first || 'ubuntu' + instance.platform.name.split('-').first end def create(state) state[:image_id] = build_image(state) unless state[:image_id] state[:container_id] = run_container(state) unless state[:container_id] @@ -71,11 +73,11 @@ state[:port] = container_ssh_port(state) wait_for_sshd(state[:hostname], nil, :port => state[:port]) end def destroy(state) - rm_container(state) if state[:container_id] + rm_container(state) if container_exists?(state) if config[:remove_images] && state[:image_id] rm_image(state) end end @@ -88,16 +90,16 @@ def socket_uri URI.parse(config[:socket]) end def docker_command(cmd, options={}) - docker = "docker" + docker = config[:binary].dup docker << " -H #{config[:socket]}" if config[:socket] - run_command("#{docker} #{cmd}", options) + run_command("#{docker} #{cmd}", options.merge(:quiet => !logger.debug?)) end - def dockerfile + def build_dockerfile from = "FROM #{config[:image]}" platform = case config[:platform] when 'debian', 'ubuntu' disable_upstart = <<-eos RUN dpkg-divert --local --rename --add /sbin/initctl @@ -111,13 +113,20 @@ config[:disable_upstart] ? disable_upstart + packages : packages when 'rhel', 'centos' <<-eos RUN yum clean all RUN yum install -y sudo openssh-server openssh-clients which curl - RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key - RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key + RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' + RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N '' eos + when 'arch' + <<-eos + RUN pacman -Syu --noconfirm + RUN pacman -S --noconfirm openssh sudo curl + RUN ssh-keygen -A -t rsa -f /etc/ssh/ssh_host_rsa_key + RUN ssh-keygen -A -t dsa -f /etc/ssh/ssh_host_dsa_key + eos else raise ActionFailed, "Unknown platform '#{config[:platform]}'" end username = config[:username] @@ -133,10 +142,20 @@ custom << "RUN #{cmd}\n" end [from, platform, base, custom].join("\n") end + def dockerfile + if config[:dockerfile] + template = IO.read(File.expand_path(config[:dockerfile])) + context = DockerERBContext.new(config.to_hash) + ERB.new(template).result(context.get_binding) + else + build_dockerfile + end + end + def parse_image_id(output) output.each_line do |line| if line =~ /image id|build successful|successfully built/i return line.split(/\s+/).last end @@ -178,10 +197,19 @@ cmd = build_run_command(state[:image_id]) output = docker_command(cmd) parse_container_id(output) end + def inspect_container(state) + container_id = state[:container_id] + docker_command("inspect #{container_id}") + end + + def container_exists?(state) + !!inspect_container(state) rescue false + end + def parse_container_ssh_port(output) begin info = Array(::JSON.parse(output)).first ports = info['NetworkSettings']['Ports'] ssh_port = ports['22/tcp'].detect {|port| port['HostIp'] == '0.0.0.0'} @@ -191,11 +219,10 @@ 'Could not parse Docker inspect output for container SSH port' end end def container_ssh_port(state) - container_id = state[:container_id] - output = docker_command("inspect #{container_id}") + output = inspect_container(state) parse_container_ssh_port(output) end def rm_container(state) container_id = state[:container_id]