skip to Main Content

I am trying to find the existence of Docker on a node with a guard before i install it.

the resource block looks like this:

ruby_block "install_docker" do
not_if {shell_out('docker -v').stdout =~ /Docker version/i}
block do
    #command_out = shell_out('docker version --format '{{.Server.Version}}'')
end
action :create
notifies :write, 'log[installing_docker_log]', :immediately
notifies :install, 'package[install_docker_ce]', :immediately
notifies :install, 'yum_package[install_docker_ce_cli]', :immediately
notifies :install, 'yum_package[install_containerd_io]', :immediately
notifies :create, "directory[create_docker_dir]", :immediately
notifies :create, "directory[create_etc_docker_dir]", :immediately
notifies :create, "cookbook_file[create_docker_daemon_json]", :immediately
notifies :create, "cookbook_file[create_docker_99_docker_config]", :immediately
notifies :run, "execute[chgrp docker_dir]", :immediately
notifies :run, "execute[chmod docker_dir]", :immediately
notifies :run, "execute[chgrp /etc/docker]", :immediately
notifies :run, "execute[chmod /etc/docker]", :immediately end

when running in kitchen i get this output saying the guard fails. It fails in the case when docker is not installed. So i assume the shell_out function is throwing an exception, but i am new to ruby and chef so am not sure how to silence it.

Do i want to check if docker is installed another way? Any help y’all could provide is greatly appreciated.

       Compiled Resource:
       ------------------
       # Declared in /tmp/kitchen/cache/cookbooks/kpmi_linux_base/recipes/install_docker.rb:54:in `from_file'

       ruby_block("install_docker") do
         action [:create]
         default_guard_interpreter :default
         declared_type :ruby_block
         cookbook_name "kpmi_linux_base"
         recipe_name "install_docker"
         block #<Proc:0x000000000470c8b8 /tmp/kitchen/cache/cookbooks/kpmi_linux_base/recipes/install_docker.rb:56>
         not_if { #code block }
       end

       System Info:
       ------------
       chef_version=16.1.16
       platform=centos
       platform_version=7.6.1810
       ruby=ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
       program_name=/opt/chef/bin/chef-client
       executable=/opt/chef/bin/chef-client


   Running handlers:
   [2020-06-05T18:30:39+00:00] ERROR: Running exception handlers
   Running handlers complete
   [2020-06-05T18:30:39+00:00] ERROR: Exception handlers complete
   Chef Infra Client failed. 0 resources updated in 10 seconds
   [2020-06-05T18:30:39+00:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
   [2020-06-05T18:30:39+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
   [2020-06-05T18:30:39+00:00] FATAL: Errno::ENOENT: ruby_block[install_docker] (kpmi_linux_base::install_docker line 54) had an error: Errno::ENOENT: No such file or directory - docker

2

Answers


  1. you can test whether docker engine is installed in many ways, here are some.

    • check whether docker command exist
    command -v docker
    
    • check the package manager (assuming you are using ubuntu)
    dpkg -l | grep -i docker
    
    • check whether docker is in the path
    which docker
    

    and you can find many other ways to check whether docker exist…

    Login or Signup to reply.
  2. Your problem is not “How to tell, if docker is installed”, but actually in how you use Chef. You are trying to write an ordinary bash script using Chef resources. This does not give you any advantage over bash script, but even more complicates the matter.

    Looking at your code I see that you:

    1. Check if docker installed
    2. Install it and configure it, if it is not installed.

    Chef is smart, so you don’t have to do point 1. Go to the point 2 straight away. Your recipe should look something like that:

    package 'docker_ce'           # install docker_ce package
    yum_package 'docker_ce_cli'   # install docker_ce_cli package
    yum_package 'containerd_io'   # install containerd_io package
    
    directory '/etc/docker' do    # create /etc/docker directory
      owner 'root'                # set owner for /etc/docker
      group 'root'                # set group for /etc/docker
      mode '0755'                 # set mode for /etc/docker
    end
    
    cookbook_file [...] do
      owner 'root'                
      group 'root'                
      mode '0755'
    end
    
    [...]
    

    Most Chef built-in resources (like package, directory, file etc.), except execute, ruby_block and other resources that just run arbitrary code, are idempotent. That means if the package is already installed, it will not try to install it again, if the directory exists, it will not try to create it etc. So you don’t have to make checks yourself, Chef will do that. You only need to describe the desired state of your machine.

    Also pay attention, that you don’t need your execute resources that change mode or group, you can set the mode and owner/group right inside the directory or cookbook_file resource itself.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search