i2cssh 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.markdown +25 -8
- data/VERSION +1 -1
- data/bin/i2cssh +133 -35
- data/i2cssh.gemspec +3 -3
- data/lib/i2cssh.rb +71 -29
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: c0b81c1ed4337a2a5d055b5856fc1aec9285020b
         | 
| 4 | 
            +
              data.tar.gz: 56daca4591c06fa6b439c4e6fc88991420d558ab
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 0dfa9d489d8eeef193b4e8b59ba538a534e588f63da4d2f804d19fcfe36918ece3a0eb8e00916d2a22dc1201e41ac6c63a9c4bdb5bce5343b60970571f7b779e
         | 
| 7 | 
            +
              data.tar.gz: bd48eb7b7bdb22242b00c2f412cdda2ddbee2c20549718eef57fb8429096f5d6fdd2b0101da5752bfdd2ef97adb4fef88993b6cf62c60ef5cec298b4413e793c
         | 
    
        data/README.markdown
    CHANGED
    
    | @@ -9,10 +9,16 @@ to all sessions. | |
| 9 9 | 
             
                $ gem install i2cssh
         | 
| 10 10 |  | 
| 11 11 | 
             
            ## Usage
         | 
| 12 | 
            -
                Usage: i2cssh [options] | 
| 12 | 
            +
                Usage: i2cssh [options] [(username@host [username@host] | username@cluster)]
         | 
| 13 | 
            +
                -c, --clusters clus1,clus2       Comma-separated list of clusters specified in ~/.i2csshrc
         | 
| 14 | 
            +
                -m, --machines a,b,c             Comma-separated list of hosts
         | 
| 15 | 
            +
                -f, --file FILE                  Cluster file (one hostname per line)
         | 
| 16 | 
            +
                -t, --tab-split                  Split servers/clusters into tabs (group arguments)
         | 
| 17 | 
            +
                -T, --tab-split-nogroup          Split servers/clusters into tabs (don't group arguments)
         | 
| 13 18 | 
             
                -A, --forward-agent              Enable SSH agent forwarding
         | 
| 14 19 | 
             
                -l, --login LOGIN                SSH login name
         | 
| 15 20 | 
             
                -e, --environment KEY=VAL        Send environment vars (comma-separated list, need to start with LC_)
         | 
| 21 | 
            +
                -r, --rank                       Send LC_RANK with the host number as environment variable
         | 
| 16 22 | 
             
                -F, --fullscreen                 Make the window fullscreen
         | 
| 17 23 | 
             
                -C, --columns COLUMNS            Number of columns (rows will be calculated)
         | 
| 18 24 | 
             
                -R, --rows ROWS                  Number of rows (columns will be calculated)
         | 
| @@ -21,11 +27,8 @@ to all sessions. | |
| 21 27 | 
             
                -p, --profile PROFILE            Name of the iTerm2 profile (default: Default)
         | 
| 22 28 | 
             
                -2, --iterm2                     Use iTerm2 instead of iTerm
         | 
| 23 29 | 
             
                -i, --itermname NAME             Name of the application to use (default: iTerm)
         | 
| 24 | 
            -
                -f, --file FILE                  Cluster file (one hostname per line)
         | 
| 25 | 
            -
                -c, --cluster CLUSTERNAME        Name of the cluster specified in ~/.i2csshrc
         | 
| 26 | 
            -
                -r, --rank                       Send LC_RANK with the host number as environment variable
         | 
| 27 | 
            -
                -m, --machines a,b,c             Comma-separated list of hosts
         | 
| 28 30 | 
             
                -s, --sleep SLEEP                Number of seconds to sleep between creating SSH sessions
         | 
| 31 | 
            +
                -d, --direction DIRECTION        Direction that new sessions are created (default: column)
         | 
| 29 32 | 
             
                -X, --extra EXTRA_PARAM          Additional ssh parameters (e.g. -Xi=myidentity.pem)
         | 
| 30 33 |  | 
| 31 34 | 
             
            i2cssh will assume you want to connect to a cluster when only one host is given.
         | 
| @@ -37,6 +40,10 @@ The following commands are exactly the same, however, they might serve different | |
| 37 40 | 
             
                $ i2cssh -m user1@host1,user2@host2
         | 
| 38 41 | 
             
                $ i2cssh user1@host1 user2@host2
         | 
| 39 42 |  | 
| 43 | 
            +
            You can combine these options and use them multiple times:
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                $ i2cssh -m user1@host1,user2@host2 -m user3@host3 user4@host4 user5@host5
         | 
| 46 | 
            +
             | 
| 40 47 | 
             
            Using the `-l` option will override all usernames:
         | 
| 41 48 |  | 
| 42 49 | 
             
                $ i2cssh -l foo user1@host1 user2@host2
         | 
| @@ -57,7 +64,7 @@ The `i2csshrc` file is a YAML formatted file that contains the following structu | |
| 57 64 | 
             
                      - host1
         | 
| 58 65 | 
             
                      - host2
         | 
| 59 66 |  | 
| 60 | 
            -
            Optional parameters can be used  | 
| 67 | 
            +
            Optional parameters can be used globally or per cluster and include:
         | 
| 61 68 |  | 
| 62 69 | 
             
                broadcast: (true/false)     # Enable/disable broadcast on start
         | 
| 63 70 | 
             
                login: <username>           # Use this username for login
         | 
| @@ -133,9 +140,9 @@ Name of the application to use (default: iTerm). It happens sometimes iTerm isn' | |
| 133 140 |  | 
| 134 141 | 
             
            Will read nodes from a file. These will be added to any hosts specified on the command line or in the config
         | 
| 135 142 |  | 
| 136 | 
            -
            ### -c, -- | 
| 143 | 
            +
            ### -c, --clusters clus1,clus2
         | 
| 137 144 |  | 
| 138 | 
            -
            Connect to  | 
| 145 | 
            +
            Connect to one or more clusters that are specified in the config 
         | 
| 139 146 |  | 
| 140 147 | 
             
            ### -r, --rank
         | 
| 141 148 |  | 
| @@ -145,6 +152,16 @@ Send a LC_RANK environment variable different for each host (from 0 to n) | |
| 145 152 |  | 
| 146 153 | 
             
            Connect to the machines a, b and c
         | 
| 147 154 |  | 
| 155 | 
            +
            ### -t, --tab-split
         | 
| 156 | 
            +
             | 
| 157 | 
            +
            Split servers/clusters into tabs, grouping arguments. 
         | 
| 158 | 
            +
            Tabs are created as follows: hosts after a -m option are put in one tab, each cluster is always in its own tab, all the arguments are in one tab.
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            ### -T, --tab-split-nogroup
         | 
| 161 | 
            +
             | 
| 162 | 
            +
            Split servers/clusters into tabs, *not* grouping arguments. 
         | 
| 163 | 
            +
            Tabs are created as follows: hosts after a -m option are put in one tab, each cluster is always in its own tab, each argument is in its own tab.
         | 
| 164 | 
            +
             | 
| 148 165 | 
             
            ### -s, --sleep SLEEP
         | 
| 149 166 |  | 
| 150 167 | 
             
            Wait SLEEP seconds between starting each ssh session. This will take decimals as well (0.5 for half a second)
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            1. | 
| 1 | 
            +
            1.13.0
         | 
    
        data/bin/i2cssh
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            #!/usr/bin/ruby
         | 
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 2 | 
             
            require 'rubygems'
         | 
| 3 3 | 
             
            require 'optparse'
         | 
| 4 4 | 
             
            require 'i2cssh'
         | 
| @@ -6,51 +6,71 @@ require 'yaml' | |
| 6 6 |  | 
| 7 7 | 
             
            @config_file = File.expand_path "~/.i2csshrc"
         | 
| 8 8 |  | 
| 9 | 
            -
            @i2_options, ssh_options, @servers, @clusters, @ssh_environment, opts_from_cmdline =  | 
| 9 | 
            +
            @i2_options, ssh_options, @servers, @clusters, @ssh_environment, opts_from_cmdline = [], [], [], {}, [], {} 
         | 
| 10 10 |  | 
| 11 11 | 
             
            def get_hosts(c)
         | 
| 12 | 
            -
                 | 
| 13 | 
            -
                    login_from_cli = $1
         | 
| 14 | 
            -
                    c = $2
         | 
| 15 | 
            -
                end
         | 
| 12 | 
            +
                c.each do |clus| 
         | 
| 16 13 |  | 
| 17 | 
            -
             | 
| 14 | 
            +
                    if clus =~ /(.+)@(.+)/ 
         | 
| 15 | 
            +
                        login_from_cli = $1
         | 
| 16 | 
            +
                        clus = $2
         | 
| 17 | 
            +
                    end
         | 
| 18 18 |  | 
| 19 | 
            -
             | 
| 20 | 
            -
                     | 
| 19 | 
            +
                    cluster = @clusters[clus]
         | 
| 20 | 
            +
                    if cluster
         | 
| 21 | 
            +
                        set_options(cluster, login_from_cli)
         | 
| 21 22 |  | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 23 | 
            +
                        if @i2_options.last[:login] 
         | 
| 24 | 
            +
                            @servers << cluster["hosts"].map{|h| "#{@i2_options.last[:login]}@#{h}"}
         | 
| 25 | 
            +
                        else
         | 
| 26 | 
            +
                            @servers << cluster["hosts"]
         | 
| 27 | 
            +
                        end
         | 
| 24 28 | 
             
                    else
         | 
| 25 | 
            -
                         | 
| 29 | 
            +
                        puts "ERROR: unknown cluster #{c}. Check your #{@config_file}"
         | 
| 30 | 
            +
                        exit 1
         | 
| 26 31 | 
             
                    end
         | 
| 27 | 
            -
                else
         | 
| 28 | 
            -
                    puts "ERROR: unknown cluster #{c}. Check your #{@config_file}"
         | 
| 29 | 
            -
                    exit 1
         | 
| 30 32 | 
             
                end
         | 
| 33 | 
            +
                
         | 
| 31 34 | 
             
            end
         | 
| 32 35 |  | 
| 33 36 | 
             
            def set_options(config_hash, login_override=nil)
         | 
| 34 | 
            -
                if config_hash["columns"] and config_hash["rows"]  | 
| 37 | 
            +
                if config_hash["columns"] and config_hash["rows"] 
         | 
| 35 38 | 
             
                    puts "CONFIG ERROR: rows and columns can't be used at the same time"
         | 
| 36 39 | 
             
                    exit 1
         | 
| 37 40 | 
             
                end
         | 
| 41 | 
            +
                
         | 
| 42 | 
            +
                if @i2_options.size == 0 
         | 
| 43 | 
            +
                    @i2_options << {}
         | 
| 44 | 
            +
                else 
         | 
| 45 | 
            +
                    # The first member includes the default options from the conf file
         | 
| 46 | 
            +
                    @i2_options << @i2_options.first.clone
         | 
| 47 | 
            +
                end
         | 
| 38 48 |  | 
| 39 49 | 
             
                [:broadcast, :profile, :rank, :iterm2, :login, :columns, :rows, :sleep, :direction, :itermname].each do |p|
         | 
| 40 | 
            -
                    @i2_options[p] = config_hash[p.to_s].nil? ? @i2_options[p] : config_hash[p.to_s]
         | 
| 50 | 
            +
                    @i2_options.last[p] = config_hash[p.to_s].nil? ? @i2_options.last[p] : config_hash[p.to_s]
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
                
         | 
| 53 | 
            +
                @i2_options.last[:login] = login_override if login_override
         | 
| 54 | 
            +
                @i2_options.last[:direction] ||= :column
         | 
| 55 | 
            +
                @i2_options.last[:direction] = @i2_options.last[:direction].to_sym
         | 
| 56 | 
            +
                if config_hash["environment"] 
         | 
| 57 | 
            +
                    if @ssh_environment.empty? 
         | 
| 58 | 
            +
                        @ssh_environment << {}
         | 
| 59 | 
            +
                    else 
         | 
| 60 | 
            +
                        # We have some global env so copy it
         | 
| 61 | 
            +
                        @ssh_environment << @ssh_environment.first.clone
         | 
| 62 | 
            +
                    end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    @ssh_environment.last.merge!(config_hash["environment"].inject({}){|m, v| m.merge(v)})
         | 
| 41 65 | 
             
                end
         | 
| 42 66 |  | 
| 43 | 
            -
                @i2_options[:login] = login_override if login_override
         | 
| 44 | 
            -
                @i2_options[:direction] ||= :column
         | 
| 45 | 
            -
                @i2_options[:direction] = @i2_options[:direction].to_sym
         | 
| 46 | 
            -
                @ssh_environment.merge!(config_hash["environment"].inject({}){|m, v| m.merge(v)}) if config_hash["environment"]
         | 
| 47 67 | 
             
            end
         | 
| 48 68 |  | 
| 49 69 | 
             
            if File.exists?(@config_file) 
         | 
| 50 70 | 
             
                config_hash = YAML.load File.read @config_file
         | 
| 51 71 |  | 
| 52 72 | 
             
                # Read config and set defaults from config
         | 
| 53 | 
            -
                if config_hash["version"] && config_hash["version"].to_i >= 2  | 
| 73 | 
            +
                if config_hash["version"] && config_hash["version"].to_i >= 2 
         | 
| 54 74 | 
             
                    set_options(config_hash)
         | 
| 55 75 | 
             
                    @clusters = config_hash["clusters"]
         | 
| 56 76 | 
             
                else
         | 
| @@ -62,24 +82,51 @@ else | |
| 62 82 | 
             
                set_options({})
         | 
| 63 83 | 
             
            end
         | 
| 64 84 |  | 
| 85 | 
            +
             | 
| 65 86 | 
             
            optparse = OptionParser.new do |opts|
         | 
| 66 87 | 
             
                opts.banner = "Usage: #{File.basename(__FILE__)} [options] [(username@host [username@host] | username@cluster)]"
         | 
| 67 88 |  | 
| 68 89 | 
             
                # Check if we have a cluster. 
         | 
| 69 | 
            -
                opts.on '-c', '-- | 
| 70 | 
            -
                    ' | 
| 90 | 
            +
                opts.on '-c', '--clusters clus1,clus2', Array,
         | 
| 91 | 
            +
                    'Comma-separated list of clusters specified in ~/.i2csshrc' do |c|
         | 
| 71 92 | 
             
                    get_hosts(c)
         | 
| 72 93 | 
             
                end
         | 
| 73 94 |  | 
| 95 | 
            +
             | 
| 74 96 | 
             
                opts.on '-m', '--machines a,b,c', Array,
         | 
| 75 97 | 
             
                    'Comma-separated list of hosts' do |h|
         | 
| 76 | 
            -
                     | 
| 98 | 
            +
                    
         | 
| 99 | 
            +
                    # Add to servers array and get a clone of default options
         | 
| 100 | 
            +
                    @servers << h
         | 
| 101 | 
            +
                    @i2_options << @i2_options.first.clone
         | 
| 102 | 
            +
                    if @ssh_environment.empty?
         | 
| 103 | 
            +
                        @ssh_environment << {}
         | 
| 104 | 
            +
                    else
         | 
| 105 | 
            +
                        @ssh_environment << @ssh_environment.first.clone
         | 
| 106 | 
            +
                    end
         | 
| 77 107 | 
             
                end
         | 
| 78 108 |  | 
| 79 109 | 
             
                # Hosts
         | 
| 80 110 | 
             
                opts.on '-f', '--file FILE',
         | 
| 81 111 | 
             
                    'Cluster file (one hostname per line)' do |f|
         | 
| 82 | 
            -
                    @servers  | 
| 112 | 
            +
                    @servers << File.read(f).split("\n")
         | 
| 113 | 
            +
                    @i2_options << @i2_options.first.clone
         | 
| 114 | 
            +
                    if @ssh_environment.empty?
         | 
| 115 | 
            +
                        @ssh_environment << {}
         | 
| 116 | 
            +
                    else
         | 
| 117 | 
            +
                        @ssh_environment << @ssh_environment.first.clone
         | 
| 118 | 
            +
                    end
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                opts.on '-t', '--tab-split',
         | 
| 122 | 
            +
                        'Split servers/clusters into tabs (group arguments)' do 
         | 
| 123 | 
            +
                    opts_from_cmdline[:tabs] = true
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                opts.on '-T', '--tab-split-nogroup',
         | 
| 127 | 
            +
                        'Split servers/clusters into tabs (don\'t group arguments)' do 
         | 
| 128 | 
            +
                    opts_from_cmdline[:tabs] = true
         | 
| 129 | 
            +
                    opts_from_cmdline[:tabs_nogroup] = true
         | 
| 83 130 | 
             
                end
         | 
| 84 131 |  | 
| 85 132 | 
             
                # Command line options override config file
         | 
| @@ -89,15 +136,19 @@ optparse = OptionParser.new do |opts| | |
| 89 136 | 
             
                    'Enable SSH agent forwarding' do
         | 
| 90 137 | 
             
                    ssh_options << '-A'
         | 
| 91 138 | 
             
                end
         | 
| 139 | 
            +
             | 
| 92 140 | 
             
                opts.on '-l', '--login LOGIN',
         | 
| 93 141 | 
             
                    'SSH login name' do |u|
         | 
| 94 142 | 
             
                    opts_from_cmdline[:login] = u
         | 
| 95 143 |  | 
| 96 144 | 
             
                end
         | 
| 145 | 
            +
             | 
| 97 146 | 
             
                opts.on '-e', '--environment KEY=VAL',
         | 
| 98 147 | 
             
                    'Send environment vars (comma-separated list, need to start with LC_)' do |e|
         | 
| 99 | 
            -
                     | 
| 148 | 
            +
                    #Overwrite global ssh environment from config file
         | 
| 149 | 
            +
                    @ssh_environment[0] =  e.split(",").inject({}) {|m, x| key, val = x.split("="); m[key] = val; m}
         | 
| 100 150 | 
             
                end
         | 
| 151 | 
            +
             | 
| 101 152 | 
             
                opts.on '-r', '--rank',
         | 
| 102 153 | 
             
                    'Send LC_RANK with the host number as environment variable' do
         | 
| 103 154 | 
             
                    opts_from_cmdline[:rank] = true
         | 
| @@ -108,6 +159,7 @@ optparse = OptionParser.new do |opts| | |
| 108 159 | 
             
                    'Make the window fullscreen' do
         | 
| 109 160 | 
             
                    opts_from_cmdline[:fullscreen] = true
         | 
| 110 161 | 
             
                end
         | 
| 162 | 
            +
             | 
| 111 163 | 
             
                opts.on '-C', '--columns COLUMNS', Integer,
         | 
| 112 164 | 
             
                    'Number of columns (rows will be calculated)' do |c|
         | 
| 113 165 | 
             
                    if opts_from_cmdline[:rows]
         | 
| @@ -154,7 +206,7 @@ optparse = OptionParser.new do |opts| | |
| 154 206 | 
             
                end
         | 
| 155 207 | 
             
                opts.on "-d", '--direction DIRECTION', String,
         | 
| 156 208 | 
             
                    'Direction that new sessions are created (default: column)' do |d|
         | 
| 157 | 
            -
                    unless ["row", "column"].include?(d)  | 
| 209 | 
            +
                    unless ["row", "column"].include?(d) 
         | 
| 158 210 | 
             
                        puts "ERROR: -d requires 'row' or 'column'"
         | 
| 159 211 | 
             
                        puts optparse.help
         | 
| 160 212 | 
             
                        exit 1
         | 
| @@ -170,19 +222,65 @@ optparse = OptionParser.new do |opts| | |
| 170 222 | 
             
            end
         | 
| 171 223 | 
             
            optparse.parse!
         | 
| 172 224 |  | 
| 173 | 
            -
            if  | 
| 174 | 
            -
                 | 
| 225 | 
            +
            if opts_from_cmdline[:tabs] 
         | 
| 226 | 
            +
                puts 'Disabling broadcast for tab split mode...'
         | 
| 227 | 
            +
                opts_from_cmdline[:broadcast] = false
         | 
| 228 | 
            +
            end
         | 
| 229 | 
            +
             | 
| 230 | 
            +
            # One argument = one cluster
         | 
| 231 | 
            +
            if ARGV.length == 1 
         | 
| 232 | 
            +
                c = [ARGV[0]]
         | 
| 175 233 | 
             
                get_hosts(c)
         | 
| 176 | 
            -
             | 
| 177 | 
            -
             | 
| 234 | 
            +
             | 
| 235 | 
            +
            # Otherwise we have a list of hosts
         | 
| 236 | 
            +
            elsif ARGV.length > 1 
         | 
| 237 | 
            +
                if opts_from_cmdline[:tabs_nogroup] 
         | 
| 238 | 
            +
                    ARGV.each do |serv|
         | 
| 239 | 
            +
                        @servers << [serv]
         | 
| 240 | 
            +
                        if @i2_options.size > 1 # We added stuff in with cmdline options
         | 
| 241 | 
            +
                            @i2_options << @i2_options.first.clone
         | 
| 242 | 
            +
                            if @ssh_environment.empty?
         | 
| 243 | 
            +
                                @ssh_environment << {}
         | 
| 244 | 
            +
                            else
         | 
| 245 | 
            +
                                @ssh_environment << @ssh_environment.first.clone
         | 
| 246 | 
            +
                            end
         | 
| 247 | 
            +
                        end
         | 
| 248 | 
            +
                    end 
         | 
| 249 | 
            +
                else
         | 
| 250 | 
            +
                    @servers << ARGV
         | 
| 251 | 
            +
                    if @i2_options.size > 1 # We added stuff in with cmdline options
         | 
| 252 | 
            +
                        @i2_options << @i2_options.first.clone
         | 
| 253 | 
            +
                        if @ssh_environment.empty?
         | 
| 254 | 
            +
                            @ssh_environment << {}
         | 
| 255 | 
            +
                        else
         | 
| 256 | 
            +
                            @ssh_environment << @ssh_environment.first.clone
         | 
| 257 | 
            +
                        end
         | 
| 258 | 
            +
                    end
         | 
| 259 | 
            +
                end
         | 
| 178 260 | 
             
            end
         | 
| 179 261 |  | 
| 180 | 
            -
            @i2_options.merge!(opts_from_cmdline)
         | 
| 181 262 |  | 
| 182 | 
            -
             | 
| 183 | 
            -
             | 
| 263 | 
            +
            # Drop default options
         | 
| 264 | 
            +
            if @i2_options.size > @servers.size
         | 
| 265 | 
            +
                @i2_options.shift
         | 
| 266 | 
            +
            end
         | 
| 267 | 
            +
             | 
| 268 | 
            +
            if @ssh_environment.size > @servers.size 
         | 
| 269 | 
            +
                @ssh_environment.shift
         | 
| 184 270 | 
             
            end
         | 
| 185 271 |  | 
| 272 | 
            +
             | 
| 273 | 
            +
            @i2_options.each do |opt| 
         | 
| 274 | 
            +
                opt.merge!(opts_from_cmdline)
         | 
| 275 | 
            +
            end
         | 
| 276 | 
            +
             | 
| 277 | 
            +
            @i2_options.each_with_index do |opt, i| 
         | 
| 278 | 
            +
                if opt[:login] 
         | 
| 279 | 
            +
                    @servers[i] = @servers[i].map{|h| "#{opt[:login]}@#{h.gsub(/.+@/,'')}"}
         | 
| 280 | 
            +
                end    
         | 
| 281 | 
            +
            end
         | 
| 282 | 
            +
             | 
| 283 | 
            +
             | 
| 186 284 | 
             
            if @servers.empty?
         | 
| 187 285 | 
             
                puts "ERROR: no servers given"
         | 
| 188 286 | 
             
                puts optparse.help
         | 
    
        data/i2cssh.gemspec
    CHANGED
    
    | @@ -5,11 +5,11 @@ | |
| 5 5 |  | 
| 6 6 | 
             
            Gem::Specification.new do |s|
         | 
| 7 7 | 
             
              s.name = "i2cssh"
         | 
| 8 | 
            -
              s.version = "1. | 
| 8 | 
            +
              s.version = "1.13.0"
         | 
| 9 9 |  | 
| 10 10 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         | 
| 11 11 | 
             
              s.authors = ["Wouter de Bie"]
         | 
| 12 | 
            -
              s.date = " | 
| 12 | 
            +
              s.date = "2015-03-19"
         | 
| 13 13 | 
             
              s.description = "csshX like cluster ssh using iTerm2 panes"
         | 
| 14 14 | 
             
              s.email = "wouter@evenflow.se"
         | 
| 15 15 | 
             
              s.executables = ["i2cssh"]
         | 
| @@ -34,7 +34,7 @@ Gem::Specification.new do |s| | |
| 34 34 | 
             
              s.homepage = "http://github.com/wouterdebie/i2cssh"
         | 
| 35 35 | 
             
              s.licenses = ["MIT"]
         | 
| 36 36 | 
             
              s.require_paths = ["lib"]
         | 
| 37 | 
            -
              s.rubygems_version = "2.0. | 
| 37 | 
            +
              s.rubygems_version = "2.0.14"
         | 
| 38 38 | 
             
              s.summary = "csshX like cluster ssh using iTerm2 panes"
         | 
| 39 39 |  | 
| 40 40 | 
             
              if s.respond_to? :specification_version then
         | 
    
        data/lib/i2cssh.rb
    CHANGED
    
    | @@ -1,14 +1,13 @@ | |
| 1 1 | 
             
            require 'appscript'
         | 
| 2 | 
            -
             | 
| 3 2 | 
             
            class I2Cssh
         | 
| 4 3 | 
             
                def initialize servers, ssh_options, i2_options, ssh_environment
         | 
| 5 4 | 
             
                    @ssh_prefix         = "ssh " + ssh_options.join(' ')
         | 
| 6 5 | 
             
                    @ssh_options        = ssh_options
         | 
| 7 | 
            -
                    @i2_options         = i2_options
         | 
| 6 | 
            +
                    @i2_options         = i2_options.clone
         | 
| 8 7 | 
             
                    @servers            = servers
         | 
| 9 8 | 
             
                    @ssh_environment    = ssh_environment
         | 
| 10 9 |  | 
| 11 | 
            -
                    app_name = (i2_options[:iterm2]) ? 'iTerm2' : ((i2_options[:itermname]) ? i2_options[:itermname] : 'iTerm')
         | 
| 10 | 
            +
                    app_name = (i2_options.first[:iterm2]) ? 'iTerm2' : ((i2_options.first[:itermname]) ? i2_options.first[:itermname] : 'iTerm')
         | 
| 12 11 |  | 
| 13 12 | 
             
                    raise Exception.new 'No servers given' if servers.empty?
         | 
| 14 13 |  | 
| @@ -19,16 +18,28 @@ class I2Cssh | |
| 19 18 | 
             
                    @shell_menu = @sys_events.processes[app_name].menu_bars[1].menu_bar_items["Shell"].menus["Shell"]
         | 
| 20 19 | 
             
                    @term = @iterm.make(:new => :terminal)
         | 
| 21 20 |  | 
| 22 | 
            -
                    @profile = i2_options[:profile] || "Default"
         | 
| 21 | 
            +
                    @profile = i2_options.first[:profile] || "Default"
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    @term.launch_(:session => "Default Session")
         | 
| 24 | 
            +
                    
         | 
| 25 | 
            +
                    maximize(app_name) if i2_options.first[:fullscreen]
         | 
| 26 | 
            +
             | 
| 23 27 |  | 
| 24 | 
            -
                     | 
| 25 | 
            -
             | 
| 28 | 
            +
                    while !@servers.empty? do
         | 
| 29 | 
            +
                        compute_geometry
         | 
| 30 | 
            +
                        split_session
         | 
| 31 | 
            +
                        start_ssh
         | 
| 32 | 
            +
                        enable_broadcast if i2_options.first[:broadcast]
         | 
| 33 | 
            +
                        @servers.shift
         | 
| 34 | 
            +
                        @i2_options.shift
         | 
| 35 | 
            +
                        @ssh_environment.shift
         | 
| 26 36 |  | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
                     | 
| 37 | 
            +
                        if !@servers.empty?  && @i2_options.first[:tabs] then
         | 
| 38 | 
            +
                            # By default, a new session = a new tab
         | 
| 39 | 
            +
                            @term.launch_(:session => "Default Session")
         | 
| 40 | 
            +
                        end
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                    @term.select(@term.sessions[1])
         | 
| 32 43 | 
             
                end
         | 
| 33 44 |  | 
| 34 45 | 
             
                private
         | 
| @@ -44,9 +55,24 @@ class I2Cssh | |
| 44 55 | 
             
                end
         | 
| 45 56 |  | 
| 46 57 | 
             
                def compute_geometry
         | 
| 47 | 
            -
                     | 
| 48 | 
            -
                    @ | 
| 49 | 
            -
             | 
| 58 | 
            +
                    # Keep track of session index for multi-tab mode
         | 
| 59 | 
            +
                    if @session_index then
         | 
| 60 | 
            +
                        @session_index += @rows*@columns
         | 
| 61 | 
            +
                    else
         | 
| 62 | 
            +
                        @session_index = 0
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    # Create geometry when combining and ignore rows/columns preference
         | 
| 66 | 
            +
                    if @servers.size > 1 && !@i2_options.first[:tabs]
         | 
| 67 | 
            +
                        count = 0
         | 
| 68 | 
            +
                        @servers.each do |srv|
         | 
| 69 | 
            +
                            count += srv.size
         | 
| 70 | 
            +
                        end
         | 
| 71 | 
            +
                    else
         | 
| 72 | 
            +
                        count = @servers.first.size
         | 
| 73 | 
            +
                        @rows = @i2_options.first[:rows]
         | 
| 74 | 
            +
                        @columns = @i2_options.first[:columns]
         | 
| 75 | 
            +
                    end
         | 
| 50 76 |  | 
| 51 77 | 
             
                    if @rows then
         | 
| 52 78 | 
             
                        @columns = (count / @rows.to_f).ceil
         | 
| @@ -59,7 +85,7 @@ class I2Cssh | |
| 59 85 | 
             
                    # Quick hack: iTerms default window only supports up to 11 rows and 22 columns
         | 
| 60 86 | 
             
                    # If we surpass either one, we resort to full screen.
         | 
| 61 87 | 
             
                    if @rows > 11 or @columns > 22 then
         | 
| 62 | 
            -
                        @i2_options[:fullscreen] = true
         | 
| 88 | 
            +
                        @i2_options.first[:fullscreen] = true
         | 
| 63 89 | 
             
                    end
         | 
| 64 90 | 
             
                end
         | 
| 65 91 |  | 
| @@ -84,7 +110,7 @@ class I2Cssh | |
| 84 110 | 
             
                        :column => {0 => split_vert, 1 => left, 2 => split_hori, 3=> right, :x => @columns, :y => @rows}, 
         | 
| 85 111 | 
             
                        :row => {0 => split_hori, 1=> up, 2 => split_vert, 3=> down, :x => @rows, :y => @columns}
         | 
| 86 112 | 
             
                    }
         | 
| 87 | 
            -
                    splitconfig = splitmap[@i2_options[:direction]]
         | 
| 113 | 
            +
                    splitconfig = splitmap[@i2_options.first[:direction]]
         | 
| 88 114 |  | 
| 89 115 | 
             
                    first = true
         | 
| 90 116 | 
             
                    2.upto splitconfig[:x] do
         | 
| @@ -109,31 +135,47 @@ class I2Cssh | |
| 109 135 | 
             
                end
         | 
| 110 136 |  | 
| 111 137 | 
             
                def start_ssh
         | 
| 138 | 
            +
                    old_size = 0
         | 
| 139 | 
            +
             | 
| 112 140 | 
             
                    1.upto(@rows*@columns) do |i|
         | 
| 113 | 
            -
                        @term.sessions[i].write :text => "/bin/bash -l"
         | 
| 141 | 
            +
                        @term.sessions[@session_index + i].write :text => "/usr/bin/env bash -l"
         | 
| 142 | 
            +
                        
         | 
| 143 | 
            +
                        # Without the tab flag, combine all servers and clusters into one window
         | 
| 144 | 
            +
                        if !@servers.empty? && (i - old_size) > @servers.first.size
         | 
| 145 | 
            +
                            old_size = @servers.first.size
         | 
| 146 | 
            +
                            @servers.shift
         | 
| 147 | 
            +
                            @i2_options.shift
         | 
| 148 | 
            +
                            @ssh_environment.shift
         | 
| 149 | 
            +
                        end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                        if @servers.empty?
         | 
| 152 | 
            +
                            server = nil
         | 
| 153 | 
            +
                        else
         | 
| 154 | 
            +
                            server = @servers.first[i-old_size-1]
         | 
| 155 | 
            +
                        end
         | 
| 156 | 
            +
             | 
| 114 157 |  | 
| 115 | 
            -
                        server = @servers[i-1]
         | 
| 116 158 | 
             
                        if server then
         | 
| 117 159 | 
             
                            send_env = ""
         | 
| 118 160 |  | 
| 119 | 
            -
                            if @i2_options[:rank] then
         | 
| 120 | 
            -
                                @ssh_environment['LC_RANK'] = i-1
         | 
| 161 | 
            +
                            if @i2_options.first[:rank] then
         | 
| 162 | 
            +
                                @ssh_environment.first['LC_RANK'] = i-1
         | 
| 121 163 | 
             
                            end
         | 
| 122 164 |  | 
| 123 | 
            -
                            if !@ssh_environment.empty? then
         | 
| 124 | 
            -
                                send_env = "-o SendEnv=#{@ssh_environment.keys.join(",")}"
         | 
| 125 | 
            -
                                @term.sessions[i].write :text => "#{@ssh_environment.map{|k,v| "export #{k}=#{v}"}.join('; ')}"
         | 
| 165 | 
            +
                            if !@ssh_environment.empty? && !@ssh_environment.first.empty? then
         | 
| 166 | 
            +
                                send_env = "-o SendEnv=#{@ssh_environment.first.keys.join(",")}"
         | 
| 167 | 
            +
                                @term.sessions[@session_index + i].write :text => "#{@ssh_environment.first.map{|k,v| "export #{k}=#{v}"}.join('; ')}"
         | 
| 126 168 | 
             
                            end
         | 
| 127 | 
            -
                            if @i2_options[:sleep] then
         | 
| 128 | 
            -
                                sleep @i2_options[:sleep] * i
         | 
| 169 | 
            +
                            if @i2_options.first[:sleep] then
         | 
| 170 | 
            +
                                sleep @i2_options.first[:sleep] * i
         | 
| 129 171 | 
             
                            end
         | 
| 130 | 
            -
                            @term.sessions[i].write :text => "unset HISTFILE && echo -e \"\\033]50;SetProfile=#{@profile}\\a\" && #{@ssh_prefix} #{send_env} #{server}"
         | 
| 172 | 
            +
                            @term.sessions[@session_index + i].write :text => "unset HISTFILE && echo -e \"\\033]50;SetProfile=#{@profile}\\a\" && #{@ssh_prefix} #{send_env} #{server}"
         | 
| 131 173 | 
             
                        else
         | 
| 132 174 |  | 
| 133 | 
            -
                            @term.sessions[i].write :text => "unset HISTFILE && echo -e \"\\033]50;SetProfile=#{@profile}\\a\""
         | 
| 175 | 
            +
                            @term.sessions[@session_index + i].write :text => "unset HISTFILE && echo -e \"\\033]50;SetProfile=#{@profile}\\a\""
         | 
| 134 176 | 
             
                            sleep 0.3
         | 
| 135 | 
            -
                            @term.sessions[i].foreground_color.set "red"
         | 
| 136 | 
            -
                            @term.sessions[i].write :text => "stty -isig -icanon -echo && echo -e '#{"\n"*100}UNUSED' && cat > /dev/null"
         | 
| 177 | 
            +
                            @term.sessions[@session_index + i].foreground_color.set "red"
         | 
| 178 | 
            +
                            @term.sessions[@session_index + i].write :text => "stty -isig -icanon -echo && echo -e '#{"\n"*100}UNUSED' && cat > /dev/null"
         | 
| 137 179 | 
             
                        end
         | 
| 138 180 | 
             
                    end
         | 
| 139 181 | 
             
                end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: i2cssh
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.13.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Wouter de Bie
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2015-03-19 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -121,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 121 121 | 
             
                  version: '0'
         | 
| 122 122 | 
             
            requirements: []
         | 
| 123 123 | 
             
            rubyforge_project: 
         | 
| 124 | 
            -
            rubygems_version: 2.0. | 
| 124 | 
            +
            rubygems_version: 2.0.14
         | 
| 125 125 | 
             
            signing_key: 
         | 
| 126 126 | 
             
            specification_version: 4
         | 
| 127 127 | 
             
            summary: csshX like cluster ssh using iTerm2 panes
         |