i2cssh 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/README.markdown +4 -3
  2. data/VERSION +1 -1
  3. data/bin/i2cssh +54 -100
  4. data/i2cssh.gemspec +1 -1
  5. data/lib/i2cssh.rb +71 -0
  6. metadata +2 -2
@@ -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
- -f, --file FILE Cluster file
14
+ -A, --forward-agent Enable SSH agent forwarding
15
+ -f, --file FILE Cluster file (one hostname per line)
16
16
  -F, --fullscreen Fullscreen
17
- -u, --username USERNAME SSH username
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.0
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
- options = {}
6
+ i2_options, ssh_options, servers = {}, [], []
7
7
 
8
8
  optparse = OptionParser.new do |opts|
9
- opts.banner = "Usage: #{File.basename(__FILE__)} [options]"
10
- options[:debug] = false
11
- options[:fullscreen] = false
12
- opts.on('-d', '--debug', "Start RIPL after creating terminals") { options[:debug] = true }
13
- opts.on('-A', '--forward-agent', "Enable SSH agent forwarding") { options[:forward] = true }
14
- opts.on('-f', '--file FILE', "Cluster file (one hostname per line)") { |f| options[:file] = f }
15
- opts.on('-F', '--fullscreen', "Fullscreen") { options[:fullscreen] = true }
16
- opts.on('-l', '--login LOGIN', "SSH login name") { |u| options[:login] = u }
17
- opts.on('-c', '--cluster CLUSTERNAME', "Name of the cluster specified in ~/.i2csshrc") { |c| options[:cluster] = c }
18
- opts.on('-m', '--machines a,b,c', Array, "Comma-separated list of hosts") { |h| options[:hosts] = h }
19
- opts.on('-C', '--columns COLUMNS', "Amount of columns (rows will be calculated)") { |c| options[:columns] = c }
20
- opts.on('-R', '--rows ROWS', "Amount of rows (columns will be calculated)") { |r| options[:rows] = r }
21
- # opts.on('-s', '--session SESSIONNAME', "Name of an iTerm2 session") { |s| options[:session_name] = s }
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
- unless options[:file] || options[:cluster] || options[:hosts] then
27
- puts optparse.help
28
- exit
29
- end
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
- iterm = Appscript.app.by_name('iTerm')
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
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{i2cssh}
8
- s.version = "1.1.0"
8
+ s.version = "1.2.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"]
@@ -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
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 1.1.0
9
+ version: 1.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Wouter de Bie