i2cssh 1.16.0 → 2.0.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 +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
|