SSH Kit Gem Basics

Background


The Problem

How to make sure that the code is ready to be deployed to a server? Whatever tool you use, Capistrano, Moonshine, Chef, Puppet, we will end up with problems after deployment. I was looking to answer these questions:

1) What is the configuration for a given software?
2) Is it running?

I need to connect using the correct credentials for the external services, database etc and also test the connectivity to make sure that the process is running. My application dependencies such as Mailchimp, Redis, Resque, Amazon S3, Stripe etc must be configured properly and the processes must be running on the correct port and URL.

Why should I as a developer care? This is the job of Devops guy. The reason is if we have a way to test the configuration and the connectivity then we can quickly fix issues in any environment (QA, Staging, Acceptance, Production). We can also isolate and tell whether the problem is due to the code or configuration / connectivity issue. We also avoid deploying code to the server that blows up due to configuration issues.

It's like the washing machine problem. You put the coins in, the detergent and you expect the machine to work. Sometimes it takes your money and the detergent but does not work. You can kick it, curse and scream. You become more frustrated when you find out you cannot get your clothes out since the door gets jammed.

alt text

What if you had a switch that you could push to find out whether it's in good status or not? You will not waste your money or energy on an inoperative washing machine.

alt text

Pilots use checklist before takeoff. Why can't software engineers use tools that automates the checklist review and gives us the confidence that the deployed application will work on the target environment even before we deploy it?

alt text

Smoke Alarm with a Self-Test Button

Why not use Monit or God?

Those are monitoring tools. We need something to check dependencies and to make sure the application will work when we deploy. Once the application is up and running we can use those monitoring tools. Most of the time these tools are used by system admins and Devops. Also note that if your application runs on only one server, Monit or any other tool on that server will go down if that machine goes down for some reason. It would be better to use those tools in combination with some other external monitoring services.

Why SSH Kit?

You can use any Capistrano version to deploy your code. Since I use Moonshine and it depends on Capistrano 2, I cannot take advantage of Capistrano 3 features. So, if I develop my own tools then I can avoid some hairy problems on production. My desire for a tool was fueled by Docker. Developing our own tools to solve these problem allows us to make these tools available for certain people in QA and other departments. This removes the bottlenecks in the organization and speeds up the software release process. SSHKit was extracted from Capistrano and is a very good tool for interacting with remote servers.

So, let's learn SSHKit by examples. We will eventually have enough knowledge about SSHKit to solve our application installation problems.

Example 1


In this example we will see how to run a command on a terminal on the local machine and display the output of the command. Create sk.rb with the following contents:

require 'sshkit'
require 'sshkit/dsl'

run_locally do
  puts capture(:whoami)  
end

Run this program.

$ruby sk.rb

The capture method runs the given command and captures the resulting output. This is printed on the screen. You need to include both the sshkit and sshkit/dsl in the require statements. The run_locally tells SSHKit to run the capture command on your local machine.

Example 2


In this example we will see how to use the within() method to execute a command in a certain directory. Create ls.rb with:

run_locally do
  within '/tmp' do
    puts capture(:ls)
  end
end

It lists the files in /tmp directory. This is equivalent to :

$cd /tmp
$ls

Example 3


Step 1

In this example you will learn how to call a rake task from another rake task that uses sshkit dsl. Create lib/tasks/sshkit.rake in your Rails project.

task :hello do  
  puts "Hello world"
end

Run:

$rake hello

Step 2

Add gem 'sshkit' in Gemfile. Since Capistrano has sshkit dependency it is already installed if you are using Capistrano to deploy your application.

require 'sshkit/dsl'

task :hello do  
  puts "Hello world"
end

task :sshkit_hello do  
  run_locally do
    rake "hello"  
  end
end

Run the second rake task:

$rake sshkit_hello
INFO[dead2d1d] Running /usr/bin/env rake hello on localhost
INFO[dead2d1d] Finished in 2.688 seconds with exit status 0 (successful).

This did not have to be a rake task because this example's functionality can be achieved by writing a script using SSHKit API.

Example 4


In this example you will learn the execute() command. Add the echo rake task to your .rake file:

task :echo  do  
  run_locally do
    execute "echo 'hi'"
  end
end
$rake echo
INFO[bba26bc5] Running /usr/bin/env echo 'hi' on localhost
INFO[bba26bc5] Finished in 0.005 seconds with exit status 0 (successful).

This does not show the output of echo the 'hi'. To display the output, configure SSHKit as follows:

SSHKit.config.output_verbosity = :debug

task :echo  do  
  run_locally do
    execute "echo 'hi'"
  end
end

Now you can see the output of the echo command.

$rake echo
INFO[dc3b8278] Running /usr/bin/env echo 'hi' on localhost
DEBUG[dc3b8278] Command: echo 'hi'
DEBUG[dc3b8278]     hi
INFO[dc3b8278] Finished in 0.007 seconds with exit status 0 (successful).

If you provide two arguments to the echo command, the first argument is command to run and the second argument becomes the argument to the command given in the first argument. Here is an example:

task :hi  do  
  run_locally do
    execute "echo", 'hi'
  end
end
$rake hi
INFO[04a6d78d] Running /usr/bin/env echo hi on localhost
DEBUG[04a6d78d] Command: /usr/bin/env echo hi
DEBUG[04a6d78d]     hi
INFO[04a6d78d] Finished in 0.006 seconds with exit status 0 (successful).

Summary


In this article we discussed the problems encountered during deployment of a web application and how we can address them before it happens on the target environment. We saw simple examples that shows how to use SSHKit gem. In the next article we will see more examples about how to use SSHKit to develop our own probes and self-test diagnostic tools.


Related Articles


Create your own user feedback survey