i2cssh 1.16.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +12 -9
- data/VERSION +1 -1
- data/bin/i2cssh +31 -31
- data/i2cssh.gemspec +1 -1
- data/lib/i2cssh.rb +25 -41
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88668f1a5e023bfe629d1ef3ce8d37a1abb86b2f
|
4
|
+
data.tar.gz: 258cebb74a3b99a50c629a83f0001ca731581362
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96ec82ba52fc77aa1e43c5389b8ad385cad5d9cceb24f14f48568ba12a6cf80190ac636fd11a05c06b3b03c62d883fdb4e6a806261c1ce717c5f484f0e46e0ac
|
7
|
+
data.tar.gz: 71494be0c81efb397af53c4e00e7a56ad173425d8d6bba1d838cc07a1b9bcaad853fbabe19ea7ad530d6c7b4d8aea6ae22be7dec636a4a46221a12e55a40005e
|
data/README.markdown
CHANGED
@@ -4,8 +4,12 @@ i2cssh is a csshX (http://code.google.com/p/csshx/) like tool for connecting ove
|
|
4
4
|
a master window for input, i2cssh uses iterm2 split panes and "Send input to all sessions" (cmd-shift-i) to send commands
|
5
5
|
to all sessions.
|
6
6
|
|
7
|
-
## Installing
|
7
|
+
## Installing
|
8
8
|
|
9
|
+
When using iTerm2 < 2.9, install i2cssh version 1.16.0:
|
10
|
+
$ gem install i2cssh -v 1.16.0
|
11
|
+
|
12
|
+
Otherwise, just run:
|
9
13
|
$ gem install i2cssh
|
10
14
|
|
11
15
|
## Usage
|
@@ -79,7 +83,7 @@ Optional parameters can be used globally or per cluster and include:
|
|
79
83
|
environment: # Send the following enviroment variables
|
80
84
|
- LC_FOO: foo
|
81
85
|
- LC_BAR: bar
|
82
|
-
|
86
|
+
|
83
87
|
iterm2: true # Use iTerm2.app instead of iTerm.app (only available globally)
|
84
88
|
|
85
89
|
Note: rows and columns can't be used together.
|
@@ -142,7 +146,7 @@ Will read nodes from a file. These will be added to any hosts specified on the c
|
|
142
146
|
|
143
147
|
### -c, --clusters clus1,clus2
|
144
148
|
|
145
|
-
Connect to one or more clusters that are specified in the config
|
149
|
+
Connect to one or more clusters that are specified in the config
|
146
150
|
|
147
151
|
### -r, --rank
|
148
152
|
|
@@ -154,12 +158,12 @@ Connect to the machines a, b and c
|
|
154
158
|
|
155
159
|
### -t, --tab-split
|
156
160
|
|
157
|
-
Split servers/clusters into tabs, grouping arguments.
|
161
|
+
Split servers/clusters into tabs, grouping arguments.
|
158
162
|
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
163
|
|
160
164
|
### -T, --tab-split-nogroup
|
161
165
|
|
162
|
-
Split servers/clusters into tabs, *not* grouping arguments.
|
166
|
+
Split servers/clusters into tabs, *not* grouping arguments.
|
163
167
|
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
168
|
|
165
169
|
### -s, --sleep SLEEP
|
@@ -172,7 +176,7 @@ Set extra ssh parameters in the form -Xk=v. For example:
|
|
172
176
|
|
173
177
|
i2cssh -Xi=myidentity.pem
|
174
178
|
|
175
|
-
will result in
|
179
|
+
will result in
|
176
180
|
|
177
181
|
ssh -i myidentity.pem
|
178
182
|
|
@@ -191,9 +195,9 @@ will result in
|
|
191
195
|
|
192
196
|
## Contributing to i2cssh
|
193
197
|
|
194
|
-
I know that i2cssh doesn't have all the functionality of csshX, but either let me know what you really need or
|
198
|
+
I know that i2cssh doesn't have all the functionality of csshX, but either let me know what you really need or
|
195
199
|
fork, hack and create a pull request.
|
196
|
-
|
200
|
+
|
197
201
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
198
202
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
199
203
|
* Fork the project
|
@@ -206,4 +210,3 @@ fork, hack and create a pull request.
|
|
206
210
|
|
207
211
|
Copyright (c) 2011-2012 Wouter de Bie. See LICENSE.txt for
|
208
212
|
further details.
|
209
|
-
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
data/bin/i2cssh
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'rubygems'
|
3
3
|
require 'optparse'
|
4
|
-
|
4
|
+
require_relative '../lib/i2cssh'
|
5
5
|
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
|
-
c.each do |clus|
|
12
|
+
c.each do |clus|
|
13
13
|
|
14
|
-
if clus =~ /(.+)@(.+)/
|
14
|
+
if clus =~ /(.+)@(.+)/
|
15
15
|
login_from_cli = $1
|
16
16
|
clus = $2
|
17
17
|
end
|
@@ -20,7 +20,7 @@ def get_hosts(c)
|
|
20
20
|
if cluster
|
21
21
|
set_options(cluster, login_from_cli)
|
22
22
|
|
23
|
-
if @i2_options.last[:login]
|
23
|
+
if @i2_options.last[:login]
|
24
24
|
@servers << cluster["hosts"].map{|h| "#{@i2_options.last[:login]}@#{h}"}
|
25
25
|
else
|
26
26
|
@servers << cluster["hosts"]
|
@@ -30,18 +30,18 @@ def get_hosts(c)
|
|
30
30
|
exit 1
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
end
|
35
35
|
|
36
36
|
def set_options(config_hash, login_override=nil)
|
37
|
-
if config_hash["columns"] and config_hash["rows"]
|
37
|
+
if config_hash["columns"] and config_hash["rows"]
|
38
38
|
puts "CONFIG ERROR: rows and columns can't be used at the same time"
|
39
39
|
exit 1
|
40
40
|
end
|
41
|
-
|
42
|
-
if @i2_options.size == 0
|
41
|
+
|
42
|
+
if @i2_options.size == 0
|
43
43
|
@i2_options << {}
|
44
|
-
else
|
44
|
+
else
|
45
45
|
# The first member includes the default options from the conf file
|
46
46
|
@i2_options << @i2_options.first.clone
|
47
47
|
end
|
@@ -49,14 +49,14 @@ def set_options(config_hash, login_override=nil)
|
|
49
49
|
[:broadcast, :profile, :rank, :iterm2, :login, :columns, :rows, :sleep, :direction, :itermname].each do |p|
|
50
50
|
@i2_options.last[p] = config_hash[p.to_s].nil? ? @i2_options.last[p] : config_hash[p.to_s]
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
@i2_options.last[:login] = login_override if login_override
|
54
54
|
@i2_options.last[:direction] ||= :column
|
55
55
|
@i2_options.last[:direction] = @i2_options.last[:direction].to_sym
|
56
|
-
if config_hash["environment"]
|
57
|
-
if @ssh_environment.empty?
|
56
|
+
if config_hash["environment"]
|
57
|
+
if @ssh_environment.empty?
|
58
58
|
@ssh_environment << {}
|
59
|
-
else
|
59
|
+
else
|
60
60
|
# We have some global env so copy it
|
61
61
|
@ssh_environment << @ssh_environment.first.clone
|
62
62
|
end
|
@@ -68,11 +68,11 @@ def set_options(config_hash, login_override=nil)
|
|
68
68
|
|
69
69
|
end
|
70
70
|
|
71
|
-
if File.exists?(@config_file)
|
71
|
+
if File.exists?(@config_file)
|
72
72
|
config_hash = YAML.load File.read @config_file
|
73
73
|
|
74
74
|
# Read config and set defaults from config
|
75
|
-
if config_hash["version"] && config_hash["version"].to_i >= 2
|
75
|
+
if config_hash["version"] && config_hash["version"].to_i >= 2
|
76
76
|
set_options(config_hash)
|
77
77
|
@clusters = config_hash["clusters"]
|
78
78
|
else
|
@@ -88,7 +88,7 @@ end
|
|
88
88
|
optparse = OptionParser.new do |opts|
|
89
89
|
opts.banner = "Usage: #{File.basename(__FILE__)} [options] [(username@host [username@host] | username@cluster)]"
|
90
90
|
|
91
|
-
# Check if we have a cluster.
|
91
|
+
# Check if we have a cluster.
|
92
92
|
opts.on '-c', '--clusters clus1,clus2', Array,
|
93
93
|
'Comma-separated list of clusters specified in ~/.i2csshrc' do |c|
|
94
94
|
get_hosts(c)
|
@@ -97,7 +97,7 @@ optparse = OptionParser.new do |opts|
|
|
97
97
|
|
98
98
|
opts.on '-m', '--machines a,b,c', Array,
|
99
99
|
'Comma-separated list of hosts' do |h|
|
100
|
-
|
100
|
+
|
101
101
|
# Add to servers array and get a clone of default options
|
102
102
|
@servers << h
|
103
103
|
@i2_options << @i2_options.first.clone
|
@@ -121,12 +121,12 @@ optparse = OptionParser.new do |opts|
|
|
121
121
|
end
|
122
122
|
|
123
123
|
opts.on '-t', '--tab-split',
|
124
|
-
'Split servers/clusters into tabs (group arguments)' do
|
124
|
+
'Split servers/clusters into tabs (group arguments)' do
|
125
125
|
opts_from_cmdline[:tabs] = true
|
126
126
|
end
|
127
127
|
|
128
128
|
opts.on '-T', '--tab-split-nogroup',
|
129
|
-
'Split servers/clusters into tabs (don\'t group arguments)' do
|
129
|
+
'Split servers/clusters into tabs (don\'t group arguments)' do
|
130
130
|
opts_from_cmdline[:tabs] = true
|
131
131
|
opts_from_cmdline[:tabs_nogroup] = true
|
132
132
|
end
|
@@ -142,7 +142,7 @@ optparse = OptionParser.new do |opts|
|
|
142
142
|
opts.on '-l', '--login LOGIN',
|
143
143
|
'SSH login name' do |u|
|
144
144
|
opts_from_cmdline[:login] = u
|
145
|
-
|
145
|
+
|
146
146
|
end
|
147
147
|
|
148
148
|
opts.on '-e', '--environment KEY=VAL',
|
@@ -208,7 +208,7 @@ optparse = OptionParser.new do |opts|
|
|
208
208
|
end
|
209
209
|
opts.on "-d", '--direction DIRECTION', String,
|
210
210
|
'Direction that new sessions are created (default: column)' do |d|
|
211
|
-
unless ["row", "column"].include?(d)
|
211
|
+
unless ["row", "column"].include?(d)
|
212
212
|
puts "ERROR: -d requires 'row' or 'column'"
|
213
213
|
puts optparse.help
|
214
214
|
exit 1
|
@@ -228,19 +228,19 @@ optparse = OptionParser.new do |opts|
|
|
228
228
|
end
|
229
229
|
optparse.parse!
|
230
230
|
|
231
|
-
if opts_from_cmdline[:tabs]
|
231
|
+
if opts_from_cmdline[:tabs]
|
232
232
|
puts 'Disabling broadcast for tab split mode...'
|
233
233
|
opts_from_cmdline[:broadcast] = false
|
234
234
|
end
|
235
235
|
|
236
236
|
# One argument = one cluster
|
237
|
-
if ARGV.length == 1
|
237
|
+
if ARGV.length == 1
|
238
238
|
c = [ARGV[0]]
|
239
239
|
get_hosts(c)
|
240
240
|
|
241
241
|
# Otherwise we have a list of hosts
|
242
|
-
elsif ARGV.length > 1
|
243
|
-
if opts_from_cmdline[:tabs_nogroup]
|
242
|
+
elsif ARGV.length > 1
|
243
|
+
if opts_from_cmdline[:tabs_nogroup]
|
244
244
|
ARGV.each do |serv|
|
245
245
|
@servers << [serv]
|
246
246
|
@i2_options << @i2_options.first.clone
|
@@ -249,7 +249,7 @@ elsif ARGV.length > 1
|
|
249
249
|
else
|
250
250
|
@ssh_environment << @ssh_environment.first.clone
|
251
251
|
end
|
252
|
-
end
|
252
|
+
end
|
253
253
|
else
|
254
254
|
@servers << ARGV
|
255
255
|
if @i2_options.size > 1 # We added stuff in with cmdline options
|
@@ -268,17 +268,17 @@ if @i2_options.size > @servers.size
|
|
268
268
|
@i2_options.shift
|
269
269
|
end
|
270
270
|
|
271
|
-
if @ssh_environment.size > @servers.size
|
271
|
+
if @ssh_environment.size > @servers.size
|
272
272
|
@ssh_environment.shift
|
273
273
|
end
|
274
274
|
|
275
275
|
|
276
|
-
@i2_options.each do |opt|
|
276
|
+
@i2_options.each do |opt|
|
277
277
|
opt.merge!(opts_from_cmdline)
|
278
278
|
end
|
279
279
|
|
280
|
-
@i2_options.each_with_index do |opt, i|
|
281
|
-
if opt[:login]
|
280
|
+
@i2_options.each_with_index do |opt, i|
|
281
|
+
if opt[:login]
|
282
282
|
@servers[i] = @servers[i].map{|h| "#{opt[:login]}@#{h.gsub(/.+@/,'')}"}
|
283
283
|
end
|
284
284
|
if opt[:gateway]
|
data/i2cssh.gemspec
CHANGED
data/lib/i2cssh.rb
CHANGED
@@ -7,23 +7,18 @@ class I2Cssh
|
|
7
7
|
@servers = servers
|
8
8
|
@ssh_environment = ssh_environment
|
9
9
|
|
10
|
-
app_name = (i2_options.first[:iterm2]) ? 'iTerm2' : ((i2_options.first[:itermname]) ? i2_options.first[:itermname] : 'iTerm')
|
11
|
-
|
12
10
|
raise Exception.new 'No servers given' if servers.empty?
|
13
11
|
|
14
12
|
@sys_events = Appscript.app.by_name('System Events')
|
15
|
-
@iterm = Appscript.app.by_name(
|
13
|
+
@iterm = Appscript.app.by_name("iTerm")
|
16
14
|
|
17
|
-
@pane_menu = @sys_events.processes[
|
18
|
-
@shell_menu = @sys_events.processes[
|
19
|
-
@term = @iterm.make(:new => :terminal)
|
15
|
+
@pane_menu = @sys_events.processes["iTerm2"].menu_bars[1].menu_bar_items["Window"].menus["Window"].menu_items["Select Split Pane"].menus["Select Split Pane"]
|
16
|
+
@shell_menu = @sys_events.processes["iTerm2"].menu_bars[1].menu_bar_items["Shell"].menus["Shell"]
|
20
17
|
|
21
18
|
@profile = i2_options.first[:profile] || "Default"
|
22
19
|
|
23
|
-
@
|
24
|
-
|
25
|
-
maximize(app_name) if i2_options.first[:fullscreen]
|
26
|
-
|
20
|
+
@iterm.create_window_with_profile(@profile, :command => "/usr/bin/env bash -l")
|
21
|
+
@window = @iterm.current_window
|
27
22
|
|
28
23
|
while !@servers.empty? do
|
29
24
|
compute_geometry
|
@@ -35,11 +30,12 @@ class I2Cssh
|
|
35
30
|
@ssh_environment.shift
|
36
31
|
|
37
32
|
if !@servers.empty? && i2_options.first[:tabs] then
|
38
|
-
#
|
39
|
-
@
|
33
|
+
# @iterm.create_tab(@profile)
|
34
|
+
@window.create_tab_with_default_profile()
|
35
|
+
@session_index = 0
|
40
36
|
end
|
41
37
|
end
|
42
|
-
@
|
38
|
+
@window.select(@window.tabs[1])
|
43
39
|
end
|
44
40
|
|
45
41
|
private
|
@@ -55,13 +51,6 @@ class I2Cssh
|
|
55
51
|
end
|
56
52
|
|
57
53
|
def compute_geometry
|
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
54
|
# Create geometry when combining and ignore rows/columns preference
|
66
55
|
if @servers.size > 1 && !@i2_options.first[:tabs]
|
67
56
|
count = 0
|
@@ -95,26 +84,18 @@ class I2Cssh
|
|
95
84
|
up = @pane_menu.menu_items["Select Pane Above"]
|
96
85
|
down = @pane_menu.menu_items["Select Pane Below"]
|
97
86
|
|
98
|
-
|
99
|
-
|
100
|
-
split_vert = @shell_menu.menu_items["Split Vertically"]
|
101
|
-
split_hori = @shell_menu.menu_items["Split Horizontally"]
|
102
|
-
split_vert.get
|
103
|
-
split_hori.get
|
104
|
-
rescue
|
105
|
-
split_vert = @shell_menu.menu_items["Split Vertically with Current Profile"]
|
106
|
-
split_hori = @shell_menu.menu_items["Split Horizontally with Current Profile"]
|
107
|
-
end
|
87
|
+
split_vert = lambda { @window.current_session.split_vertically_with_same_profile }
|
88
|
+
split_hori = lambda { @window.current_session.split_horizontally_with_same_profile }
|
108
89
|
|
109
90
|
splitmap = {
|
110
|
-
:column => {0 => split_vert, 1 => left, 2 => split_hori, 3=> right, :x => @columns, :y => @rows},
|
91
|
+
:column => {0 => split_vert, 1 => left, 2 => split_hori, 3=> right, :x => @columns, :y => @rows},
|
111
92
|
:row => {0 => split_hori, 1=> up, 2 => split_vert, 3=> down, :x => @rows, :y => @columns}
|
112
93
|
}
|
113
94
|
splitconfig = splitmap[@i2_options.first[:direction]]
|
114
95
|
|
115
96
|
first = true
|
116
97
|
2.upto splitconfig[:x] do
|
117
|
-
splitconfig[0].
|
98
|
+
splitconfig[0].call
|
118
99
|
end
|
119
100
|
2.upto splitconfig[:y] do
|
120
101
|
1.upto splitconfig[:x] do
|
@@ -122,7 +103,7 @@ class I2Cssh
|
|
122
103
|
first = false
|
123
104
|
end
|
124
105
|
splitconfig[:x].times do |x|
|
125
|
-
splitconfig[2].
|
106
|
+
splitconfig[2].call
|
126
107
|
splitconfig[3].click
|
127
108
|
end
|
128
109
|
end
|
@@ -138,8 +119,10 @@ class I2Cssh
|
|
138
119
|
old_size = 0
|
139
120
|
|
140
121
|
1.upto(@rows*@columns) do |i|
|
141
|
-
|
142
|
-
|
122
|
+
tab = @window.current_tab
|
123
|
+
session = tab.sessions[i]
|
124
|
+
session.write :text => "/usr/bin/env bash -l"
|
125
|
+
|
143
126
|
# Without the tab flag, combine all servers and clusters into one window
|
144
127
|
if !@servers.empty? && (i - old_size) > @servers.first.size && !@i2_options.first[:tabs]
|
145
128
|
old_size = @servers.first.size
|
@@ -164,18 +147,19 @@ class I2Cssh
|
|
164
147
|
|
165
148
|
if !@ssh_environment.empty? && !@ssh_environment.first.empty? then
|
166
149
|
send_env = "-o SendEnv=#{@ssh_environment.first.keys.join(",")}"
|
167
|
-
|
150
|
+
session.write :text => "#{@ssh_environment.first.map{|k,v| "export #{k}=#{v}"}.join('; ')}"
|
168
151
|
end
|
169
152
|
if @i2_options.first[:sleep] then
|
170
153
|
sleep @i2_options.first[:sleep] * i
|
171
154
|
end
|
172
|
-
|
155
|
+
|
156
|
+
session.write :text => "unset HISTFILE && echo -e \"\\033]50;SetProfile=#{@profile}\\a\" && #{@ssh_prefix} #{send_env} #{server}"
|
173
157
|
else
|
174
|
-
|
175
|
-
|
158
|
+
|
159
|
+
session.write :text => "unset HISTFILE && echo -e \"\\033]50;SetProfile=#{@profile}\\a\""
|
176
160
|
sleep 0.3
|
177
|
-
|
178
|
-
|
161
|
+
session.foreground_color.set ([65535,0,0])
|
162
|
+
session.write :text => "stty -isig -icanon -echo && echo -e '#{"\n"*100}UNUSED' && cat > /dev/null"
|
179
163
|
end
|
180
164
|
end
|
181
165
|
end
|