i2cssh 1.1.0 → 1.2.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.
- data/README.markdown +4 -3
- data/VERSION +1 -1
- data/bin/i2cssh +54 -100
- data/i2cssh.gemspec +1 -1
- data/lib/i2cssh.rb +71 -0
- metadata +2 -2
data/README.markdown
CHANGED
@@ -9,13 +9,14 @@ to all sessions.
|
|
9
9
|
$ gem install i2cssh
|
10
10
|
|
11
11
|
## Usage
|
12
|
-
|
13
12
|
Usage: i2cssh [options]
|
14
13
|
-d, --debug Start RIPL after creating terminals
|
15
|
-
-
|
14
|
+
-A, --forward-agent Enable SSH agent forwarding
|
15
|
+
-f, --file FILE Cluster file (one hostname per line)
|
16
16
|
-F, --fullscreen Fullscreen
|
17
|
-
-
|
17
|
+
-l, --login LOGIN SSH login name
|
18
18
|
-c, --cluster CLUSTERNAME Name of the cluster specified in ~/.i2csshrc
|
19
|
+
-m, --machines a,b,c Comma-separated list of hosts
|
19
20
|
-C, --columns COLUMNS Amount of columns (rows will be calculated)
|
20
21
|
-R, --rows ROWS Amount of rows (columns will be calculated)
|
21
22
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/bin/i2cssh
CHANGED
@@ -1,111 +1,65 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
require 'rubygems'
|
3
|
-
require 'appscript'
|
4
3
|
require 'optparse'
|
4
|
+
require 'i2cssh'
|
5
5
|
|
6
|
-
|
6
|
+
i2_options, ssh_options, servers = {}, [], []
|
7
7
|
|
8
8
|
optparse = OptionParser.new do |opts|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
#
|
9
|
+
opts.banner = "Usage: #{File.basename(__FILE__)} [options]"
|
10
|
+
|
11
|
+
# SSH options
|
12
|
+
opts.on '-A', '--forward-agent',
|
13
|
+
'Enable SSH agent forwarding' do
|
14
|
+
ssh_options << '-A'
|
15
|
+
end
|
16
|
+
opts.on '-l', '--login LOGIN',
|
17
|
+
'SSH login name' do |u|
|
18
|
+
ssh_options << "-l #{u}"
|
19
|
+
end
|
20
|
+
|
21
|
+
# iTerm2 options
|
22
|
+
opts.on '-F', '--fullscreen',
|
23
|
+
'Make the window fullscreen' do
|
24
|
+
i2_options[:fullscreen] = true
|
25
|
+
end
|
26
|
+
opts.on '-C', '--columns COLUMNS', Integer,
|
27
|
+
'Number of columns (rows will be calculated)' do |c|
|
28
|
+
i2_options[:columns] = c
|
29
|
+
end
|
30
|
+
opts.on '-R', '--rows ROWS', Integer,
|
31
|
+
'Number of rows (columns will be calculated)' do |r|
|
32
|
+
if i2_options[:columns]
|
33
|
+
puts "ERROR: -C and -R can't be used at the same time"
|
34
|
+
puts optparse.help
|
35
|
+
exit
|
36
|
+
else
|
37
|
+
i2_options[:rows] = r
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Hosts
|
42
|
+
opts.on '-f', '--file FILE',
|
43
|
+
'Cluster file (one hostname per line)' do |f|
|
44
|
+
servers += File.read(f).split "\n"
|
45
|
+
end
|
46
|
+
opts.on '-c', '--cluster CLUSTERNAME',
|
47
|
+
'Name of the cluster specified in ~/.i2csshrc' do |c|
|
48
|
+
require 'yaml'
|
49
|
+
config_hash = YAML.load File.read File.expand_path '~/.i2csshrc'
|
50
|
+
servers += config_hash["clusters"][c]
|
51
|
+
end
|
52
|
+
opts.on '-m', '--machines a,b,c', Array,
|
53
|
+
'Comma-separated list of hosts' do |h|
|
54
|
+
servers += h
|
55
|
+
end
|
22
56
|
end
|
23
|
-
|
24
57
|
optparse.parse!
|
25
58
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
if [ options[:file], options[:cluster], options[:hosts] ].compact.length > 1 then
|
32
|
-
puts "ERROR: neither -f, -c or -h can be combined"
|
33
|
-
puts optparse.help
|
34
|
-
exit
|
35
|
-
end
|
36
|
-
|
37
|
-
if options[:columns] && options[:rows] then
|
38
|
-
puts "ERROR: -C and -R can't be used at the same time"
|
39
|
-
puts optparse.help
|
40
|
-
exit
|
41
|
-
end
|
42
|
-
|
43
|
-
ssh_prefix = "ssh " +
|
44
|
-
(options[:forward] ? "-A " : "") +
|
45
|
-
(options[:login] ? "-l #{options[:login]} " : "")
|
46
|
-
|
47
|
-
rows = options[:rows].to_i if options[:rows]
|
48
|
-
columns = options[:columns].to_i if options[:columns]
|
49
|
-
|
50
|
-
|
51
|
-
if options[:file] then
|
52
|
-
servers = File.read(options[:file]).split("\n")
|
53
|
-
elsif options[:cluster] then
|
54
|
-
require 'yaml'
|
55
|
-
config_hash = YAML.load(File.read(File.expand_path("~/.i2csshrc")))
|
56
|
-
servers = config_hash["clusters"][options[:cluster]]
|
57
|
-
elsif options[:hosts] then
|
58
|
-
servers = options[:hosts]
|
59
|
-
end
|
60
|
-
|
61
|
-
count = servers.size
|
62
|
-
if rows then
|
63
|
-
columns = (count / rows.to_f).ceil
|
64
|
-
elsif columns then
|
65
|
-
rows = (count / columns.to_f).ceil
|
66
|
-
else
|
67
|
-
rows = Math.sqrt(count).ceil
|
68
|
-
columns = (count / rows.to_f).ceil
|
59
|
+
if servers.empty?
|
60
|
+
puts "ERROR: no servers given"
|
61
|
+
puts optparse.help
|
62
|
+
exit
|
69
63
|
end
|
70
64
|
|
71
|
-
|
72
|
-
finder = Appscript.app.by_name('Finder')
|
73
|
-
sys_events = Appscript.app.by_name('System Events')
|
74
|
-
term = iterm.make(:new => :terminal)
|
75
|
-
|
76
|
-
session = term.sessions.after.make(:new => :session)
|
77
|
-
session.exec(:command => "/bin/bash -l")
|
78
|
-
|
79
|
-
if options[:fullscreen] then
|
80
|
-
window_bounds = finder.desktop.window.bounds
|
81
|
-
window = iterm.windows.get.sort_by{|x| x.id_.get}.last
|
82
|
-
window.bounds.set(window_bounds.get)
|
83
|
-
end
|
84
|
-
|
85
|
-
(columns - 1).times do
|
86
|
-
sys_events.keystroke("d", :using => :command_down)
|
87
|
-
end
|
88
|
-
(rows - 1).times do
|
89
|
-
(columns - 1).times do
|
90
|
-
sys_events.key_code(123, :using => [:command_down, :option_down])
|
91
|
-
end
|
92
|
-
(columns).times do |x|
|
93
|
-
sys_events.keystroke("D", :using => :command_down)
|
94
|
-
sys_events.key_code(124, :using => [:command_down, :option_down]) unless (columns - 1) == x
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
(rows * columns).times do |i|
|
99
|
-
if servers && servers[i] then
|
100
|
-
term.sessions[i+1].write(:text => "history -d $(($HISTCMD-1)) && #{ssh_prefix}#{servers[i]}")
|
101
|
-
else
|
102
|
-
term.sessions[i+1].foreground_color.set("red")
|
103
|
-
term.sessions[i+1].write(:text => "history -d $(($HISTCMD-1)) && stty -isig -icanon -echo && echo -e '#{"\n"*100}UNUSED' && cat > /dev/null")
|
104
|
-
end
|
105
|
-
end
|
106
|
-
if options[:debug] then
|
107
|
-
require 'ripl'
|
108
|
-
Ripl.start :binding => binding
|
109
|
-
end
|
110
|
-
|
111
|
-
|
65
|
+
I2Cssh.new servers, ssh_options, i2_options
|
data/i2cssh.gemspec
CHANGED
data/lib/i2cssh.rb
CHANGED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'appscript'
|
2
|
+
|
3
|
+
class I2Cssh
|
4
|
+
def initialize servers, ssh_options, i2_options
|
5
|
+
@ssh_prefix = "ssh " + ssh_options.join(' ')
|
6
|
+
@ssh_options = ssh_options
|
7
|
+
@i2_options = i2_options
|
8
|
+
@servers = servers
|
9
|
+
|
10
|
+
raise Exception.new 'No servers given' if servers.empty?
|
11
|
+
|
12
|
+
@sys_events = Appscript.app.by_name('System Events')
|
13
|
+
@iterm = Appscript.app.by_name('iTerm')
|
14
|
+
@term = @iterm.make(:new => :terminal)
|
15
|
+
session = @term.sessions.after.make :new => :session
|
16
|
+
session.exec :command => "/bin/bash -l"
|
17
|
+
|
18
|
+
compute_geometry
|
19
|
+
split_session
|
20
|
+
maximize if i2_options[:fullscreen]
|
21
|
+
start_ssh
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def maximize
|
26
|
+
fullscreen_bounds = Appscript.app.by_name('Finder').desktop.window.bounds
|
27
|
+
window = @iterm.windows.get.sort_by{|x| x.id_.get}.last
|
28
|
+
window.bounds.set fullscreen_bounds.get
|
29
|
+
end
|
30
|
+
|
31
|
+
def compute_geometry
|
32
|
+
count = @servers.size
|
33
|
+
if @i2_options[:rows] then
|
34
|
+
@columns = (count / @i2_options[:rows].to_f).ceil
|
35
|
+
elsif @i2_options[:rows] then
|
36
|
+
@rows = (count / @i2_options[:columns].to_f).ceil
|
37
|
+
else
|
38
|
+
@columns = Math.sqrt(count).ceil
|
39
|
+
@rows = (count / @columns.to_f).ceil
|
40
|
+
end
|
41
|
+
puts @rows
|
42
|
+
puts @columns
|
43
|
+
end
|
44
|
+
|
45
|
+
def split_session
|
46
|
+
2.upto @columns do
|
47
|
+
@sys_events.keystroke "d", :using => :command_down
|
48
|
+
end
|
49
|
+
2.upto @rows do
|
50
|
+
1.upto @columns do
|
51
|
+
@sys_events.key_code 123, :using => [:command_down, :option_down]
|
52
|
+
end
|
53
|
+
@columns.times do |x|
|
54
|
+
@sys_events.keystroke "D", :using => :command_down
|
55
|
+
@sys_events.key_code 124, :using => [:command_down, :option_down] unless @columns - 1 == x
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def start_ssh
|
61
|
+
1.upto(@rows*@columns) do |i|
|
62
|
+
server = @servers[i-1]
|
63
|
+
if server then
|
64
|
+
@term.sessions[i].write :text => "unset HISTFILE && #{@ssh_prefix} #{server}"
|
65
|
+
else
|
66
|
+
@term.sessions[i].foreground_color.set "red"
|
67
|
+
@term.sessions[i].write :text => "unset HISTFILE && stty -isig -icanon -echo && echo -e '#{"\n"*100}UNUSED' && cat > /dev/null"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|