-
-
Save leehambley/d5a67911bf39c5b2ff2a to your computer and use it in GitHub Desktop.
Proposed SSH DSL for Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Please read the examples inline thoroughly, these comprise some of the proposed | |
# DSLs for a better SSH Ruby SSH driver, upon which people can build decent tools | |
# | |
servers = %w( example.com beispeil.de ejemplo.es ) | |
environment = {rails_env: production, rack_env: production} | |
LibSSH.configure do |config| | |
# | |
# Connection Timeout | |
# | |
config.connection_timeout = 10.seconds | |
# | |
# Connection "handler" - replacable | |
# if you don't need to raise an exception | |
# when a host times out | |
# | |
config.timeout_handler = lambda do | |
raise LibSSH::ConnectionTimeoutError | |
end | |
# | |
# Pool, and reuse connections to servers | |
# where possible | |
# | |
config.connection_pooling = true | |
# | |
# Send a default environment hash, where possible | |
# | |
config.default_environment = environment | |
# | |
# An interactive terminal (or PTY) is a connection | |
# that behaves like a user, sitting at a terminal | |
# programs running in a PTY expect to be able to | |
# prompt the user for feedback and input. | |
# Shells, for example typically use the presence | |
# of a PTY to justify loading a user's dotfiles | |
# | |
config.prefer_interative_terminal = true | |
# | |
# Default shell configutation | |
# | |
config.default_shell = 'sh' | |
end | |
# | |
# Runs "hostname" on one host, echos the result locally | |
# | |
on servers.first do | |
puts remote("hostname") | |
end | |
# | |
# Demonstrates connecting in parallel to two servers, and | |
# writing the result, IO#print is used because of thread | |
# safety | |
# | |
on servers[0..2] do | |
in "/etc/" do | |
remote("ls").each_line do |line| | |
print line + "\n" | |
end | |
end | |
end | |
# | |
# Change a user's password, includes some trimmings | |
# | |
responder = lambda do |prompt| | |
"MyAwesomePassword" if prompt =~ /Password:/ | |
end | |
on servers.first do | |
as "root", :with => responder do | |
if run("passwd anotheruser", "User'sNewPassword") | |
puts "Changed 'anotheruser's Password Successfully" | |
else | |
puts "There was an error changing the other user's password #{exit_status}" | |
end | |
end | |
end | |
# | |
# Operates on all four servers, in sequence | |
# waiting 5 seconds between each operation | |
# does not have to concern itself with thread safety | |
# | |
on servers, :in => :sequence, :wait => 5 do | |
in "/var/www" do | |
with {queue: '*'} do | |
unless run("service resque restart") | |
# Break unless we can restart the server | |
break | |
end | |
end | |
end | |
end |
I agree that on
, in
and run
do read well, it was more that I could not think of what function/behavior they provide/facilitate.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's about the vocabulary
on ____ in ____ run ____
it reads quite well, at least in my opinion, and there's also no reason that it couldn't be calledservers
My thoughts exactly, write a good, single threaded, single-server version, and then invest in writing something to multiplex connections. (Even if I write it myself) - I expect to have to do that pre 1.0, as I expect the API of the single threaded version will need to be written with multithreading/em in mind.
I'm not able to install FFI under Ruby 1.9.3, that's a problem - but I had thought that an FFI binding might be better, FFI has matured a lot since I wrote the blog post, maybe I'll go back to the drawing board!
I'm actually daemonizing the
openssh
that's installed on the host machine… although libssh has support for running a server (and I believe it's quite mature) - I'm just spinning up an Openssh with a chroot jail to test in.