SSH Kit Gem Basics
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.
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.
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?
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.
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.
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.
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
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
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.
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).
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.