Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return code validation #62

Merged
merged 4 commits into from
Feb 8, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ install_dir | Installation directory for docker binary | String | auto-detected
install_type | Installation type for docker ("binary", "package" or "source") | String | "package"
options | Additional options to pass to docker. These could be flags like "-api-enable-cors". | String | nil
registry_cmd_timeout | registry LWRP default cmd_timeout seconds | Fixnum | 60
docker_daemon_timeout | Timeout to wait for the docker daemon to start in seconds | Fixnum | 10
storage_type | Storage driver for docker (nil, "aufs", or "devmapper") | String | auto-detected (see attributes/default.rb)
version | Version of docker | String | nil
virtualization_type | Virtualization driver for docker (nil or "lxc") | String | auto-detected (see attributes/default.rb)
Expand Down
1 change: 1 addition & 0 deletions attributes/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
default['docker']['http_proxy'] = nil
default['docker']['image_cmd_timeout'] = 300
default['docker']['registry_cmd_timeout'] = 60
default['docker']['docker_daemon_timeout'] = 10

default['docker']['init_type'] = value_for_platform(
%w{ centos debian oracle redhat } => {
Expand Down
90 changes: 90 additions & 0 deletions libraries/helpers.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
require 'chef/mixin/shell_out'
include Chef::Mixin::ShellOut

# Helpers module
module Helpers
# Helpers::Docker module
module Docker
# Exception to signify that the Docker daemon is not yet ready to handle
# docker commands.
class DockerNotReady < StandardError
def initialize(timeout)
super <<-EOH
The Docker daemon did not become ready within #{timeout} seconds.
This most likely means that Docker failed to start.
Docker can fail to start if:

- a configuration file is invalid
- permissions are incorrect for the root directory of the docker runtime.

If this problem persists, check your service log files.
EOH
end
end

def cli_args(spec)
cli_line = ''
spec.each_pair do |arg, value|
Expand All @@ -28,5 +48,75 @@ def docker_inspect_id(id)
inspect = docker_inspect(id)
inspect['id'] if inspect
end

def timeout
node['docker']['docker_daemon_timeout']
end

# This is based upon wait_until_ready! from the opscode jenkins cookbook.
#
# Since the docker service returns immediately and the actual docker
# process is started as a daemon, we block the Chef Client run until the
# daemon is actually ready.
#
# This method will effectively "block" the current thread until the docker
# daemon is ready
#
# @raise [DockerNotReady]
# if the Docker master does not respond within (+timeout+) seconds
#
def wait_until_ready!
Timeout.timeout(timeout) do
loop do
result = shell_out('docker info')
break if Array(result.valid_exit_codes).include?(result.exitstatus)
Chef::Log.debug("Docker daemon is not running - #{result.stdout}\n#{result.stderr}")
sleep(0.5)
end
end
rescue Timeout::Error
raise DockerNotReady.new(timeout), 'docker timeout exceeded'
end

# the Error message to display if a command times out. Subclasses
# may want to override this to provide more details on the timeout.
def command_timeout_error_message
<<-EOM

Command timed out:
#{cmd}

EOM
end

# Runs a docker command. Does not raise exception on non-zero exit code.
def docker_cmd(cmd, timeout = new_resource.cmd_timeout)
execute_cmd('docker ' + cmd, timeout)
end

# Executes the given command with the specified timeout. Does not raise an
# exception on a non-zero exit code.
def execute_cmd(cmd, timeout = new_resource.cmd_timeout)
Chef::Log.debug('Executing: ' + cmd)
begin
shell_out(cmd, :timeout => timeout)
rescue Mixlib::ShellOut::CommandTimeout
raise CommandTimeout, command_timeout_error_message
end
end

# Executes the given docker command with the specified timeout. Raises an
# exception if the command returns a non-zero exit code.
def docker_cmd!(cmd, timeout = new_resource.cmd_timeout)
execute_cmd!('docker ' + cmd, timeout)
end

# Executes teh given command with the specified timeout. Raises an
# exception if the command returns a non-zero exit code.
def execute_cmd!(cmd, timeout = new_resource.cmd_timeout)
cmd = execute_cmd(cmd, timeout)
cmd.error!
cmd
end
end
end
32 changes: 14 additions & 18 deletions providers/container.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ class CommandTimeout < RuntimeError; end

def load_current_resource
@current_resource = Chef::Resource::DockerContainer.new(new_resource)
dps = docker_cmd('ps -a -notrunc')
wait_until_ready!
dps = docker_cmd!('ps -a -notrunc')
dps.stdout.each_line do |dps_line|
ps = dps(dps_line)
unless container_id_matches?(ps['id'])
Expand Down Expand Up @@ -121,7 +122,7 @@ def commit
commit_end_args = new_resource.repository
commit_end_args += ":#{new_resource.tag}" if new_resource.tag
end
docker_cmd("commit #{commit_args} #{current_resource.id} #{commit_end_args}")
docker_cmd!("commit #{commit_args} #{current_resource.id} #{commit_end_args}")
end

def container_command_matches_if_exists?(command)
Expand Down Expand Up @@ -151,7 +152,7 @@ def container_name
end

def cp
docker_cmd("cp #{current_resource.id}:#{new_resource.source} #{new_resource.destination}")
docker_cmd!("cp #{current_resource.id}:#{new_resource.source} #{new_resource.destination}")
end

def docker_cmd(cmd, timeout = new_resource.cmd_timeout)
Expand All @@ -175,34 +176,29 @@ def dps(dps_line)
ps
end

def execute_cmd(cmd, timeout = new_resource.cmd_timeout)
Chef::Log.debug('Executing: ' + cmd)
begin
shell_out(cmd, :timeout => timeout)
rescue Mixlib::ShellOut::CommandTimeout
raise CommandTimeout, <<-EOM
def command_timeout_error_message
<<-EOM

Command timed out:
#{cmd}

Please adjust node container_cmd_timeout attribute or this docker_container cmd_timeout attribute if necessary.
EOM
end
end

def exists?
@current_resource.id
end

def export
docker_cmd("export #{current_resource.id} > #{new_resource.destination}")
docker_cmd!("export #{current_resource.id} > #{new_resource.destination}")
end

def kill
if service?
service_stop
else
docker_cmd("kill #{current_resource.id}")
docker_cmd!("kill #{current_resource.id}")
end
end

Expand All @@ -221,15 +217,15 @@ def remove
rm_args = cli_args(
'link' => new_resource.link
)
docker_cmd("rm #{rm_args} #{current_resource.id}")
docker_cmd!("rm #{rm_args} #{current_resource.id}")
service_remove if service?
end

def restart
if service?
service_restart
else
docker_cmd("restart #{current_resource.id}")
docker_cmd!("restart #{current_resource.id}")
end
end

Expand Down Expand Up @@ -258,7 +254,7 @@ def run
'volumes-from' => new_resource.volumes_from,
'w' => new_resource.working_directory
)
dr = docker_cmd("run #{run_args} #{new_resource.image} #{new_resource.command}")
dr = docker_cmd!("run #{run_args} #{new_resource.image} #{new_resource.command}")
dr.error!
new_resource.id(dr.stdout.chomp)
service_create if service?
Expand Down Expand Up @@ -442,7 +438,7 @@ def start
if service?
service_create
else
docker_cmd("start #{start_args} #{current_resource.id}")
docker_cmd!("start #{start_args} #{current_resource.id}")
end
end

Expand All @@ -453,10 +449,10 @@ def stop
if service?
service_stop
else
docker_cmd("stop #{stop_args} #{current_resource.id}", (new_resource.cmd_timeout + 15))
docker_cmd!("stop #{stop_args} #{current_resource.id}", (new_resource.cmd_timeout + 15))
end
end

def wait
docker_cmd("wait #{current_resource.id}")
docker_cmd!("wait #{current_resource.id}")
end
34 changes: 14 additions & 20 deletions providers/image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class CommandTimeout < RuntimeError; end

def load_current_resource
wait_until_ready!
@current_resource = Chef::Resource::DockerImage.new(new_resource)
dimages = docker_cmd('images -a -notrunc')
if dimages.stdout.include?(new_resource.image_name)
Expand Down Expand Up @@ -122,7 +123,7 @@ def build
command = new_resource.source
end

docker_cmd("build #{build_args} #{command}")
docker_cmd!("build #{build_args} #{command}")
end

def di(di_line)
Expand All @@ -136,23 +137,14 @@ def di(di_line)
image
end

def docker_cmd(cmd, timeout = new_resource.cmd_timeout)
execute_cmd('docker ' + cmd, timeout)
end

def execute_cmd(cmd, timeout = new_resource.cmd_timeout)
Chef::Log.debug('Executing: ' + cmd)
begin
shell_out(cmd, :timeout => timeout)
rescue Mixlib::ShellOut::CommandTimeout
raise CommandTimeout, <<-EOM
def command_timeout_error_message
<<-EOM

Command timed out:
#{cmd}

Please adjust node image_cmd_timeout attribute or this docker_image cmd_timeout attribute if necessary.
EOM
end
end

def image_id_matches?(id)
Expand Down Expand Up @@ -183,36 +175,38 @@ def import
import_args += new_resource.source
import_args += " #{new_resource.image_name}"
end
docker_cmd("import #{import_args} #{repository_and_tag_args}")
docker_cmd!("import #{import_args} #{repository_and_tag_args}")
end
end

def insert
docker_cmd("insert #{new_resource.image_name} #{new_resource.source} #{new_resource.destination}")
docker_cmd!("insert #{new_resource.image_name} #{new_resource.source} #{new_resource.destination}")
end

def installed?
@current_resource.id
end

def load
docker_cmd("load < #{new_resource.source}")
docker_cmd!("load < #{new_resource.source}")
end

def pull
pull_args = cli_args(
'registry' => new_resource.registry,
't' => new_resource.tag
)
docker_cmd("pull #{new_resource.image_name} #{pull_args}")
docker_cmd!("pull #{new_resource.image_name} #{pull_args}")
end

def push
docker_cmd("push #{new_resource.image_name}")
docker_cmd!("push #{new_resource.image_name}")
end

def remove
docker_cmd("rmi #{new_resource.image_name}")
image_name = new_resource.image_name
image_name = "#{image_name}:#{new_resource.tag}" if new_resource.tag
docker_cmd!("rmi #{image_name}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! Thanks!

end

def repository_and_tag_args
Expand All @@ -225,12 +219,12 @@ def repository_and_tag_args
end

def save
docker_cmd("save #{new_resource.image_name} > #{new_resource.destination}")
docker_cmd!("save #{new_resource.image_name} > #{new_resource.destination}")
end

def tag
tag_args = cli_args(
'f' => new_resource.force
)
docker_cmd("tag #{tag_args} #{new_resource.image_name} #{repository_and_tag_args}")
docker_cmd!("tag #{tag_args} #{new_resource.image_name} #{repository_and_tag_args}")
end
16 changes: 4 additions & 12 deletions providers/registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class CommandTimeout < RuntimeError; end

def load_current_resource
@current_resource = Chef::Resource::DockerRegistry.new(new_resource)
wait_until_ready!
# TODO: load current resource?
@current_resource
end
Expand All @@ -17,23 +18,14 @@ def load_current_resource
end
end

def docker_cmd(cmd, timeout = new_resource.cmd_timeout)
execute_cmd('docker ' + cmd, timeout)
end

def execute_cmd(cmd, timeout = new_resource.cmd_timeout)
Chef::Log.debug('Executing: ' + cmd)
begin
shell_out(cmd, :timeout => timeout)
rescue Mixlib::ShellOut::CommandTimeout
raise CommandTimeout, <<-EOM
def command_timeout_error_message
<<-EOM

Command timed out:
#{cmd}

Please adjust node registry_cmd_timeout attribute or this docker_registry cmd_timeout attribute if necessary.
EOM
end
end

def logged_in?
Expand All @@ -46,5 +38,5 @@ def login
'p' => new_resource.password,
'u' => new_resource.username
)
docker_cmd("login #{new_resource.server} #{login_args}")
docker_cmd!("login #{new_resource.server} #{login_args}")
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

describe_recipe "docker_test::image_lwrp_test" do
include Helpers::DockerTest

it "has base image not installed" do
refute image_exists?("base")
end
Expand All @@ -14,4 +14,8 @@
it "has bflad/testcontainerd image installed" do
assert image_exists?("bflad/testcontainerd")
end

it "has myImage image not installed" do
refute image_exists?("myImage")
end
end
Loading