#!/usr/bin/ruby require 'rubygems' require 'optparse' require 'i2cssh' require 'yaml' require 'pp' config_file = File.expand_path "~/.i2csshrc" i2_options, ssh_options, servers, clusters, login_from_cli = {}, [], [], {}, false if File.exists?(config_file) config_hash = YAML.load File.read config_file # Read config and set defaults from config if config_hash["version"] && config_hash["version"].to_i >= 2 then clusters = config_hash["clusters"] # Options from the config file i2_options[:iterm2] = config_hash["iterm2"] i2_options[:login_override] = config_hash["login"] i2_options[:broadcast] = config_hash["broadcast"] else # Convert version 1 format to version 2 clusters = config_hash["clusters"].inject({}){|m, c| m[c[0]] = {"hosts" => c[1]}; m} end end optparse = OptionParser.new do |opts| opts.banner = "Usage: #{File.basename(__FILE__)} [options]" # Check if we have a cluster. opts.on '-c', '--cluster CLUSTERNAME', 'Name of the cluster specified in ~/.i2csshrc' do |c| if c =~ /(.+)@(.+)/ then login_from_cli = $1 c = $2 end cluster = clusters[c] if clusters cluster_hosts = cluster["hosts"] i2_options[:login_override] = cluster["login"] || i2_options[:login_override] i2_options[:login_override] = login_from_cli if login_from_cli i2_options[:broadcast] = cluster["broadcast"] || i2_options[:broadcast] servers += cluster_hosts else puts "ERROR: unknown cluster #{c}" puts optparse.help exit 1 end end opts.on '-m', '--machines a,b,c', Array, 'Comma-separated list of hosts' do |h| h.each do |host| if host =~ /(.+)@(.+)/ then i2_options[:login_override] = $1 host = $2 end servers << host end end # Hosts opts.on '-f', '--file FILE', 'Cluster file (one hostname per line)' do |f| servers += File.read(f).split "\n" end # Command line options override config file # SSH options opts.on '-A', '--forward-agent', 'Enable SSH agent forwarding' do ssh_options << '-A' end opts.on '-l', '--login LOGIN', 'SSH login name' do |u| i2_options[:login_override] = u end # iTerm2 options opts.on '-F', '--fullscreen', 'Make the window fullscreen' do i2_options[:fullscreen] = true end opts.on '-C', '--columns COLUMNS', Integer, 'Number of columns (rows will be calculated)' do |c| i2_options[:columns] = c end opts.on '-R', '--rows ROWS', Integer, 'Number of rows (columns will be calculated)' do |r| if i2_options[:columns] puts "ERROR: -C and -R can't be used at the same time" puts optparse.help exit else i2_options[:rows] = r end end opts.on '-b', '--broadcast', 'Start with broadcast input (DANGEROUS!)' do i2_options[:broadcast] = true end opts.on '-nb', '--nobroadcast', 'Disable broadcast' do i2_options[:broadcast] = false end opts.on '-p', '--profile PROFILE', 'Name of the iTerm2 profile (default: Default)' do |p| i2_options[:profile] = p puts p end opts.on "-2", '--iterm2', 'Use iTerm2 instead of iTerm' do i2_options[:iterm2] = true end end optparse.parse! if i2_options[:login_override] then ssh_options << "-l #{i2_options[:login_override]}" end if servers.empty? puts "ERROR: no servers given" puts optparse.help exit end I2Cssh.new servers, ssh_options, i2_options