Skip to content

Instantly share code, notes, and snippets.

@fearoffish
Created January 27, 2011 17:09
Show Gist options
  • Save fearoffish/798819 to your computer and use it in GitHub Desktop.
Save fearoffish/798819 to your computer and use it in GitHub Desktop.
Used in conjunction with Opscode's knife, we can open new terminal tabs for every instance in a cluster of machines
# Requires Mac OS X and Opscode's Chef Platform
#
# So you use Opscode's knife tool (with Chef) and you use a naming convention for your instance node names:
# app1.testing.your-domain.com, db1.testing.your-domain.com etc.
#
# Then you can use this script with 'knife exec' to open a new terminal tab for each instance of that cluster,
# each of these tabs will open an ssh session to the machine.
#
# Run with:
# CLUSTER=testing knife open_ssh_terminals.rb
if ENV['CLUSTER'].nil?
puts "Dude, you need to supply a CLUSTER env variable or I'll just open ALL instances!"
puts " CLUSTER=testing knife open_ssh_terminals.rb"
exit
end
username = ENV['CLUSTER_USER'] || `whoami`.chomp
@instances = nodes.find(:name => "*.#{ENV['CLUSTER']}").collect {|n| {:hostname => n["ec2"]["public_ipv4"], :username => username}}
template =<<EOF
global window_id
global window_name
set window_id to 0
set window_name to ""
-- `menu_click`, by Jacob Rus, September 2006
--
-- Accepts a list of form: `{"Finder", "View", "Arrange By", "Date"}`
-- Execute the specified menu item. In this case, assuming the Finder
-- is the active application, arranging the frontmost folder by date.
on menu_click(mList)
local appName, topMenu, r
-- Validate our input
if mList's length < 3 then error "Menu list is not long enough"
-- Set these variables for clarity and brevity later on
set {appName, topMenu} to (items 1 through 2 of mList)
set r to (items 3 through (mList's length) of mList)
-- This overly-long line calls the menu_recurse function with
-- two arguments: r, and a reference to the top-level menu
tell app "System Events" to my menu_click_recurse(r, ((process appName)'s (menu bar 1)'s (menu bar item topMenu)'s (menu topMenu)))
end menu_click
on menu_click_recurse(mList, parentObject)
local f, r
-- `f` = first item, `r` = rest of items
set f to item 1 of mList
if mList's length > 1 then set r to (items 2 through (mList's length) of mList)
-- either actually click the menu item, or recurse again
tell app "System Events"
if mList's length is 1 then
click parentObject's menu item f
else
my menu_click_recurse(r, (parentObject's (menu item f)'s (menu f)))
end if
end tell
end menu_click_recurse
-- MAINLINE
tell application "Terminal"
activate
-- make a new window with the execution of a trivial command
my menu_click({"Terminal", "Shell", "New Window"})
-- load up the window id of the window we just created
set window_id to id of first window whose frontmost is true
-- make tabs 2, 3 and 4
repeat with i from 1 to <%= @instances.size - 1 %>
my menu_click({"Terminal", "Shell", "New Tab"})
end repeat
<% @instances.each_with_index do |instance, i| %>
set cmd to "ssh <%= instance[:username] %>@<%= instance[:hostname] %>"
do script cmd in tab <%= i + 1 %> of window id window_id of application "Terminal"
<% end %>
-- resize
set region to the bounds of window id window_id of application "Terminal"
set x to item 1 of region
set y to item 2 of region
set w to item 3 of region
-- set the bounds of the first window to {x,y,w,640}
end tell
EOF
evaluated = ERB.new( template ).result( binding )
tempfile = Tempfile.new("new_terminal_window")
tempfile.puts(evaluated)
tempfile.close
%x{ osascript #{tempfile.path} }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment