i2c2 1.0.0.beta4 → 1.0.0.beta5
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/CHANGELOG.md +6 -1
- data/Gemfile +1 -4
- data/Gemfile.lock +33 -38
- data/README.md +7 -18
- data/Rakefile +4 -3
- data/VERSION +1 -1
- data/bin/i2c2 +196 -232
- data/i2c2.gemspec +7 -17
- data/lib/i2c2.rb +144 -144
- metadata +8 -50
- data/.document +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0e5df5c0abdd9207ac837daa324f76e909c75d68d910e38a41cd74b8a5b9f831
|
|
4
|
+
data.tar.gz: 44ccc3cc3b3352b202803afe055af829e9a377b7f96781910463f06e76ccffe5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 26e238fc897f8319bcafceda6ea485720c798c1e8a504e216abe2900375a8420f64918d4a366e9aac38ff6626497116b971e27cd6d2be5bd00e9b6177921432d
|
|
7
|
+
data.tar.gz: afefcd2de29436d6d180e406ed06ddf952f7fdcbc3ba2f76ca6357ae89258b83fc2b48c70454785123559e3e91346f95bcec673d583b34e5376eb2ecb7f6282d
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.0.0.beta5] 2020-09-10
|
|
6
|
+
### Changed
|
|
7
|
+
- Remove support for connecting to cluster/hosts without using the explicit option
|
|
8
|
+
- Change default direction from column to row
|
|
9
|
+
|
|
5
10
|
## [1.0.0.beta4] 2019-05-15
|
|
6
11
|
### Changed
|
|
7
12
|
- Fix problem after config file convertion to version 2
|
|
@@ -22,4 +27,4 @@
|
|
|
22
27
|
- 100% compatible with i2cssh *branch master* at the time of fork (commit: ac0bf90), including auto complete config file name i2cssh-autocomplete.bash
|
|
23
28
|
|
|
24
29
|
## [0.99.0] - 2019-05-11
|
|
25
|
-
- 100% compatible with i2cssh *2.2.0 (latest
|
|
30
|
+
- 100% compatible with i2cssh *2.2.0 (latest release)*, including the config file ~/.i2csshrc
|
data/Gemfile
CHANGED
|
@@ -8,8 +8,5 @@ gem "rb-scpt", "~> 1.0.1"
|
|
|
8
8
|
# Add dependencies to develop your gem here.
|
|
9
9
|
# Include everything needed to run rake, tests, features, etc.
|
|
10
10
|
group :development do
|
|
11
|
-
gem "
|
|
12
|
-
gem "jeweler", "2.1.2"
|
|
13
|
-
gem "shoulda"
|
|
14
|
-
gem "builder"
|
|
11
|
+
gem "jeweler"
|
|
15
12
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,65 +1,60 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: https://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
addressable (2.
|
|
5
|
-
|
|
6
|
-
builder (3.2.2)
|
|
4
|
+
addressable (2.4.0)
|
|
5
|
+
builder (3.2.4)
|
|
7
6
|
descendants_tracker (0.0.4)
|
|
8
7
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
9
8
|
faraday (0.9.2)
|
|
10
9
|
multipart-post (>= 1.2, < 3)
|
|
11
|
-
git (1.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
git (1.7.0)
|
|
11
|
+
rchardet (~> 1.8)
|
|
12
|
+
github_api (0.16.0)
|
|
13
|
+
addressable (~> 2.4.0)
|
|
14
|
+
descendants_tracker (~> 0.0.4)
|
|
15
15
|
faraday (~> 0.8, < 0.10)
|
|
16
|
-
hashie (>=
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
jeweler (2.1.2)
|
|
16
|
+
hashie (>= 3.4)
|
|
17
|
+
mime-types (>= 1.16, < 3.0)
|
|
18
|
+
oauth2 (~> 1.0)
|
|
19
|
+
hashie (4.1.0)
|
|
20
|
+
highline (2.0.3)
|
|
21
|
+
jeweler (2.3.9)
|
|
23
22
|
builder
|
|
24
|
-
bundler
|
|
23
|
+
bundler
|
|
25
24
|
git (>= 1.2.5)
|
|
26
|
-
github_api (~> 0.
|
|
25
|
+
github_api (~> 0.16.0)
|
|
27
26
|
highline (>= 1.6.15)
|
|
28
27
|
nokogiri (>= 1.5.10)
|
|
28
|
+
psych
|
|
29
29
|
rake
|
|
30
30
|
rdoc
|
|
31
|
-
|
|
32
|
-
jwt (
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
semver2
|
|
32
|
+
jwt (2.2.2)
|
|
33
|
+
mime-types (2.99.3)
|
|
34
|
+
mini_portile2 (2.4.0)
|
|
35
|
+
multi_json (1.15.0)
|
|
35
36
|
multi_xml (0.6.0)
|
|
36
|
-
multipart-post (2.1.
|
|
37
|
-
nokogiri (1.
|
|
38
|
-
mini_portile2 (~> 2.
|
|
39
|
-
oauth2 (1.4.
|
|
40
|
-
faraday (>= 0.8, <
|
|
37
|
+
multipart-post (2.1.1)
|
|
38
|
+
nokogiri (1.10.10)
|
|
39
|
+
mini_portile2 (~> 2.4.0)
|
|
40
|
+
oauth2 (1.4.4)
|
|
41
|
+
faraday (>= 0.8, < 2.0)
|
|
41
42
|
jwt (>= 1.0, < 3.0)
|
|
42
43
|
multi_json (~> 1.3)
|
|
43
44
|
multi_xml (~> 0.5)
|
|
44
45
|
rack (>= 1.2, < 3)
|
|
45
|
-
|
|
46
|
-
rack (
|
|
47
|
-
rake (
|
|
46
|
+
psych (3.2.0)
|
|
47
|
+
rack (2.2.3)
|
|
48
|
+
rake (13.0.1)
|
|
48
49
|
rb-scpt (1.0.3)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
rchardet (1.8.0)
|
|
51
|
+
rdoc (6.2.1)
|
|
52
|
+
semver2 (3.4.2)
|
|
52
53
|
thread_safe (0.3.6)
|
|
53
54
|
|
|
54
55
|
PLATFORMS
|
|
55
56
|
ruby
|
|
56
57
|
|
|
57
58
|
DEPENDENCIES
|
|
58
|
-
|
|
59
|
-
bundler (>= 1.0.0)
|
|
60
|
-
jeweler (= 2.1.2)
|
|
59
|
+
jeweler
|
|
61
60
|
rb-scpt (~> 1.0.1)
|
|
62
|
-
shoulda
|
|
63
|
-
|
|
64
|
-
BUNDLED WITH
|
|
65
|
-
1.17.3
|
data/README.md
CHANGED
|
@@ -18,7 +18,7 @@ When using iTerm2 < 2.9, install old i2cssh version 1.16.0:
|
|
|
18
18
|
|
|
19
19
|
## Migrate from i2cssh
|
|
20
20
|
|
|
21
|
-
If you have used i2cssh and want to migrate, you can do it painless using i2c2 version 0.99.0 which is 100% compatible with i2cssh 2.2.0 (latest
|
|
21
|
+
If you have used i2cssh and want to migrate, you can do it painless using i2c2 version 0.99.0 which is 100% compatible with i2cssh 2.2.0 (latest release),
|
|
22
22
|
including the config file ~/.i2csshrc.
|
|
23
23
|
|
|
24
24
|
Version 0.99.1 is compatible with i2cssh branch master at the time of fork (commit: ac0bf90), including auto complete config file name i2cssh-autocomplete.bash.
|
|
@@ -46,19 +46,8 @@ Version 0.99.1 is compatible with i2cssh branch master at the time of fork (comm
|
|
|
46
46
|
-d, --direction DIRECTION Direction that new sessions are created (default: column)
|
|
47
47
|
-X, --extra EXTRA_PARAM Additional ssh parameters (e.g. -Xi=myidentity.pem)
|
|
48
48
|
|
|
49
|
-
i2c2 will assume you want to connect to a cluster when only one host is given.
|
|
50
|
-
|
|
51
49
|
For `-c` and `-m` options, the format `username@cluster` or `username@host` can be used.
|
|
52
50
|
|
|
53
|
-
The following commands are exactly the same, however, they might serve different purposes:
|
|
54
|
-
|
|
55
|
-
$ i2c2 -m user1@host1,user2@host2
|
|
56
|
-
$ i2c2 user1@host1 user2@host2
|
|
57
|
-
|
|
58
|
-
You can combine these options and use them multiple times:
|
|
59
|
-
|
|
60
|
-
$ i2c2 -m user1@host1,user2@host2 -m user3@host3 user4@host4 user5@host5
|
|
61
|
-
|
|
62
51
|
Using the `-l` option will override all usernames:
|
|
63
52
|
|
|
64
53
|
$ i2c2 -l foo user1@host1 user2@host2
|
|
@@ -79,12 +68,6 @@ The `i2csshrc` file is a YAML formatted file that contains the following structu
|
|
|
79
68
|
- host1
|
|
80
69
|
- host2
|
|
81
70
|
|
|
82
|
-
## Autocomplete
|
|
83
|
-
|
|
84
|
-
To allow autocomplete, add the following to your .bash_profile, .bashrc or .profile
|
|
85
|
-
|
|
86
|
-
$ source [path to ./extras/i2cssh-autocomplete.bash]
|
|
87
|
-
|
|
88
71
|
## Optional Parameters
|
|
89
72
|
|
|
90
73
|
They can be used globally or per cluster and include:
|
|
@@ -113,6 +96,12 @@ The following precedence is used:
|
|
|
113
96
|
|
|
114
97
|
Make sure the config file is valid YAML (e.g. use spaces instead of tabs)
|
|
115
98
|
|
|
99
|
+
## Autocomplete
|
|
100
|
+
|
|
101
|
+
To allow autocomplete, add the following to your .bash_profile, .bashrc or .profile
|
|
102
|
+
|
|
103
|
+
$ source [path to ./extras/i2cssh-autocomplete.bash]
|
|
104
|
+
|
|
116
105
|
## Options
|
|
117
106
|
|
|
118
107
|
### -A, --forward-agent
|
data/Rakefile
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
-
|
|
3
2
|
require 'rubygems'
|
|
4
3
|
require 'bundler'
|
|
4
|
+
|
|
5
5
|
begin
|
|
6
6
|
Bundler.setup(:default, :development)
|
|
7
7
|
rescue Bundler::BundlerError => e
|
|
@@ -9,13 +9,14 @@ rescue Bundler::BundlerError => e
|
|
|
9
9
|
$stderr.puts "Run `bundle install` to install missing gems"
|
|
10
10
|
exit e.status_code
|
|
11
11
|
end
|
|
12
|
-
require 'rake'
|
|
13
12
|
|
|
13
|
+
require 'rake'
|
|
14
14
|
require 'jeweler'
|
|
15
|
+
|
|
15
16
|
Jeweler::Tasks.new do |gem|
|
|
16
17
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
|
17
18
|
gem.name = "i2c2"
|
|
18
|
-
gem.homepage = "
|
|
19
|
+
gem.homepage = "https://github.com/dx7/i2c2"
|
|
19
20
|
gem.license = "MIT"
|
|
20
21
|
gem.summary = %Q{csshX like - cluster ssh using iTerm2 panes - based on i2cssh}
|
|
21
22
|
gem.description = %Q{csshX like - cluster ssh using iTerm2 panes - based on i2cssh}
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.0.
|
|
1
|
+
1.0.0.beta5
|
data/bin/i2c2
CHANGED
|
@@ -4,81 +4,66 @@ require 'optparse'
|
|
|
4
4
|
require_relative '../lib/i2c2'
|
|
5
5
|
require 'yaml'
|
|
6
6
|
|
|
7
|
-
@config_file = File.expand_path
|
|
8
|
-
|
|
7
|
+
@config_file = File.expand_path '~/.i2csshrc'
|
|
9
8
|
@i2_options, ssh_options, @servers, @clusters, @ssh_environment, opts_from_cmdline = [], [], [], {}, [], {}
|
|
10
9
|
|
|
11
|
-
def debug_vars
|
|
12
|
-
p '-----------------------------'
|
|
13
|
-
p '@i2_options'
|
|
14
|
-
p @i2_options
|
|
15
|
-
p '@servers'
|
|
16
|
-
p @servers
|
|
17
|
-
p '@clusters'
|
|
18
|
-
p @clusters
|
|
19
|
-
p '@ssh_environment'
|
|
20
|
-
p @ssh_environment
|
|
21
|
-
p '-----------------------------'
|
|
22
|
-
end
|
|
23
|
-
|
|
24
10
|
def get_hosts(c)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
cluster = @clusters[clus]
|
|
33
|
-
if cluster
|
|
34
|
-
set_options(cluster, login_from_cli)
|
|
35
|
-
|
|
36
|
-
if @i2_options.last[:login]
|
|
37
|
-
@servers << cluster["hosts"].map{|h| "#{@i2_options.last[:login]}@#{h}"}
|
|
38
|
-
else
|
|
39
|
-
@servers << cluster["hosts"]
|
|
40
|
-
end
|
|
41
|
-
else
|
|
42
|
-
puts "ERROR: unknown cluster #{c}. Check your #{@config_file}"
|
|
43
|
-
exit 1
|
|
44
|
-
end
|
|
11
|
+
c.each do |clus|
|
|
12
|
+
|
|
13
|
+
if clus =~ /(.+)@(.+)/
|
|
14
|
+
login_from_cli = $1
|
|
15
|
+
clus = $2
|
|
45
16
|
end
|
|
46
17
|
|
|
18
|
+
cluster = @clusters[clus]
|
|
19
|
+
if cluster
|
|
20
|
+
set_options(cluster, login_from_cli)
|
|
21
|
+
|
|
22
|
+
if @i2_options.last[:login]
|
|
23
|
+
@servers << cluster['hosts'].map{|h| "#{@i2_options.last[:login]}@#{h}"}
|
|
24
|
+
else
|
|
25
|
+
@servers << cluster['hosts']
|
|
26
|
+
end
|
|
27
|
+
else
|
|
28
|
+
puts "ERROR: unknown cluster #{c}. Check your #{@config_file}"
|
|
29
|
+
exit 1
|
|
30
|
+
end
|
|
31
|
+
end
|
|
47
32
|
end
|
|
48
33
|
|
|
49
34
|
def set_options(config_hash, login_override=nil)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
35
|
+
if config_hash['columns'] and config_hash['rows']
|
|
36
|
+
puts 'CONFIG ERROR: rows and columns can\'t be used at the same time'
|
|
37
|
+
exit 1
|
|
38
|
+
end
|
|
54
39
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
40
|
+
if @i2_options.size == 0
|
|
41
|
+
@i2_options << {}
|
|
42
|
+
else
|
|
43
|
+
# The first member includes the default options from the conf file
|
|
44
|
+
@i2_options << @i2_options.first.clone
|
|
45
|
+
end
|
|
61
46
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
47
|
+
[:broadcast, :profile, :rank, :iterm2, :login, :columns, :rows, :sleep, :shell, :direction, :itermname].each do |p|
|
|
48
|
+
@i2_options.last[p] = config_hash[p.to_s].nil? ? @i2_options.last[p] : config_hash[p.to_s]
|
|
49
|
+
end
|
|
65
50
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
else
|
|
73
|
-
# We have some global env so copy it
|
|
74
|
-
@ssh_environment << @ssh_environment.first.clone
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
@ssh_environment.last.merge!(config_hash["environment"].inject({}){|m, v| m.merge(v)})
|
|
51
|
+
@i2_options.last[:login] = login_override if login_override
|
|
52
|
+
@i2_options.last[:direction] ||= :row
|
|
53
|
+
@i2_options.last[:direction] = @i2_options.last[:direction].to_sym
|
|
54
|
+
if config_hash['environment']
|
|
55
|
+
if @ssh_environment.empty?
|
|
56
|
+
@ssh_environment << {}
|
|
78
57
|
else
|
|
79
|
-
|
|
58
|
+
# We have some global env so copy it
|
|
59
|
+
@ssh_environment << @ssh_environment.first.clone
|
|
80
60
|
end
|
|
81
61
|
|
|
62
|
+
@ssh_environment.last.merge!(config_hash['environment'].inject({}){|m, v| m.merge(v)})
|
|
63
|
+
else
|
|
64
|
+
@ssh_environment << {}
|
|
65
|
+
end
|
|
66
|
+
|
|
82
67
|
end
|
|
83
68
|
|
|
84
69
|
if File.exists?(@config_file)
|
|
@@ -91,224 +76,203 @@ if File.exists?(@config_file)
|
|
|
91
76
|
|
|
92
77
|
# Read config and set defaults from config
|
|
93
78
|
set_options(config_hash)
|
|
94
|
-
@clusters = config_hash[
|
|
79
|
+
@clusters = config_hash['clusters']
|
|
95
80
|
else
|
|
96
81
|
set_options({})
|
|
97
82
|
end
|
|
98
83
|
|
|
99
|
-
|
|
100
84
|
optparse = OptionParser.new do |opts|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
# Check if we have a cluster.
|
|
104
|
-
opts.on '-c', '--clusters clus1,clus2', Array,
|
|
105
|
-
'Comma-separated list of clusters specified in ~/.i2csshrc' do |c|
|
|
106
|
-
get_hosts(c)
|
|
107
|
-
end
|
|
85
|
+
opts.banner = "Usage: #{File.basename(__FILE__)} [options] [(username@host [username@host] | username@cluster)]"
|
|
108
86
|
|
|
87
|
+
# Check if we have a cluster.
|
|
88
|
+
opts.on '-c', '--clusters clus1,clus2', Array,
|
|
89
|
+
'Comma-separated list of clusters specified in ~/.i2csshrc' do |c|
|
|
90
|
+
get_hosts(c)
|
|
91
|
+
end
|
|
109
92
|
|
|
110
|
-
|
|
111
|
-
|
|
93
|
+
opts.on '-m', '--machines a,b,c', Array,
|
|
94
|
+
'Comma-separated list of hosts' do |h|
|
|
112
95
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
end
|
|
96
|
+
# Add to servers array and get a clone of default options
|
|
97
|
+
@servers << h
|
|
98
|
+
@i2_options << @i2_options.first.clone
|
|
99
|
+
if @ssh_environment.empty?
|
|
100
|
+
@ssh_environment << {}
|
|
101
|
+
else
|
|
102
|
+
@ssh_environment << @ssh_environment.first.clone
|
|
121
103
|
end
|
|
104
|
+
end
|
|
122
105
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
@ssh_environment << @ssh_environment.first.clone
|
|
132
|
-
end
|
|
106
|
+
opts.on '-f', '--file FILE',
|
|
107
|
+
'Cluster file (one hostname per line)' do |f|
|
|
108
|
+
@servers << File.read(f).split("\n")
|
|
109
|
+
@i2_options << @i2_options.first.clone
|
|
110
|
+
if @ssh_environment.empty?
|
|
111
|
+
@ssh_environment << {}
|
|
112
|
+
else
|
|
113
|
+
@ssh_environment << @ssh_environment.first.clone
|
|
133
114
|
end
|
|
115
|
+
end
|
|
134
116
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
end
|
|
117
|
+
opts.on '-t', '--tab-split',
|
|
118
|
+
'Split servers/clusters into tabs (group arguments)' do
|
|
119
|
+
opts_from_cmdline[:tabs] = true
|
|
139
120
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
opts_from_cmdline[:tabs_nogroup] = true
|
|
144
|
-
end
|
|
121
|
+
puts 'Disabling broadcast for tab split mode...'
|
|
122
|
+
opts_from_cmdline[:broadcast] = false
|
|
123
|
+
end
|
|
145
124
|
|
|
146
|
-
|
|
125
|
+
opts.on '-T', '--tab-split-nogroup',
|
|
126
|
+
'Split servers/clusters into tabs (don\'t group arguments)' do
|
|
127
|
+
opts_from_cmdline[:tabs] = true
|
|
128
|
+
opts_from_cmdline[:tabs_nogroup] = true
|
|
147
129
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
ssh_options << '-A'
|
|
152
|
-
end
|
|
130
|
+
puts 'Disabling broadcast for tab split mode...'
|
|
131
|
+
opts_from_cmdline[:broadcast] = false
|
|
132
|
+
end
|
|
153
133
|
|
|
154
|
-
|
|
155
|
-
'SSH login name' do |u|
|
|
156
|
-
opts_from_cmdline[:login] = u
|
|
134
|
+
# Command line options override config file
|
|
157
135
|
|
|
158
|
-
|
|
136
|
+
# SSH options
|
|
137
|
+
opts.on '-A', '--forward-agent',
|
|
138
|
+
'Enable SSH agent forwarding' do
|
|
139
|
+
ssh_options << '-A'
|
|
140
|
+
end
|
|
159
141
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
end
|
|
142
|
+
opts.on '-l', '--login LOGIN',
|
|
143
|
+
'SSH login name' do |u|
|
|
144
|
+
opts_from_cmdline[:login] = u
|
|
145
|
+
end
|
|
165
146
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
147
|
+
opts.on '-e', '--environment KEY=VAL',
|
|
148
|
+
'Send environment vars (comma-separated list, need to start with LC_)' do |e|
|
|
149
|
+
#Overwrite global ssh environment from config file
|
|
150
|
+
@ssh_environment[0] = e.split(',').inject({}) {|m, x| key, val = x.split('='); m[key] = val; m}
|
|
151
|
+
end
|
|
170
152
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
end
|
|
153
|
+
opts.on '-r', '--rank',
|
|
154
|
+
'Send LC_RANK with the host number as environment variable' do
|
|
155
|
+
opts_from_cmdline[:rank] = true
|
|
156
|
+
end
|
|
176
157
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
exit 1
|
|
183
|
-
else
|
|
184
|
-
opts_from_cmdline[:columns] = c
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
|
-
opts.on '-R', '--rows ROWS', Integer,
|
|
188
|
-
'Number of rows (columns will be calculated)' do |r|
|
|
189
|
-
if opts_from_cmdline[:columns]
|
|
190
|
-
puts "ERROR: -C and -R can't be used at the same time"
|
|
191
|
-
puts optparse.help
|
|
192
|
-
exit 1
|
|
193
|
-
else
|
|
194
|
-
opts_from_cmdline[:rows] = r
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
opts.on '-b', '--broadcast',
|
|
198
|
-
'Start with broadcast input (DANGEROUS!)' do
|
|
199
|
-
opts_from_cmdline[:broadcast] = true
|
|
200
|
-
end
|
|
201
|
-
opts.on '-nb', '--nobroadcast',
|
|
202
|
-
'Disable broadcast' do
|
|
203
|
-
opts_from_cmdline[:broadcast] = false
|
|
204
|
-
end
|
|
205
|
-
opts.on '-p', '--profile PROFILE',
|
|
206
|
-
'Name of the iTerm2 profile (default: Default)' do |p|
|
|
207
|
-
opts_from_cmdline[:profile] = p
|
|
208
|
-
end
|
|
209
|
-
opts.on "-2", '--iterm2',
|
|
210
|
-
'Use iTerm2 instead of iTerm' do
|
|
211
|
-
opts_from_cmdline[:iterm2] = true
|
|
212
|
-
end
|
|
213
|
-
opts.on "-i", '--itermname NAME', String,
|
|
214
|
-
'Name of the application to use (default: iTerm)' do |i|
|
|
215
|
-
opts_from_cmdline[:itermname] = i
|
|
216
|
-
end
|
|
217
|
-
opts.on '-s', '--sleep SLEEP', Float,
|
|
218
|
-
'Number of seconds to sleep between creating SSH sessions' do |s|
|
|
219
|
-
opts_from_cmdline[:sleep] = s
|
|
220
|
-
end
|
|
221
|
-
opts.on '-S', '--shell SHELL', String,
|
|
222
|
-
'Shell to use when spawning the SSH sessions' do |s|
|
|
223
|
-
opts_from_cmdline[:shell] = s
|
|
224
|
-
end
|
|
225
|
-
opts.on "-d", '--direction DIRECTION', String,
|
|
226
|
-
'Direction that new sessions are created (default: column)' do |d|
|
|
227
|
-
unless ["row", "column"].include?(d)
|
|
228
|
-
puts "ERROR: -d requires 'row' or 'column'"
|
|
229
|
-
puts optparse.help
|
|
230
|
-
exit 1
|
|
231
|
-
end
|
|
232
|
-
opts_from_cmdline[:direction] = d.to_sym
|
|
233
|
-
end
|
|
234
|
-
opts.on '-X', '--extra EXTRA_PARAM', String,
|
|
235
|
-
'Additional ssh parameters (e.g. -Xi=myidentity.pem)' do |x|
|
|
158
|
+
# iTerm2 options
|
|
159
|
+
opts.on '-F', '--fullscreen',
|
|
160
|
+
'Make the window fullscreen' do
|
|
161
|
+
opts_from_cmdline[:fullscreen] = true
|
|
162
|
+
end
|
|
236
163
|
|
|
237
|
-
|
|
164
|
+
opts.on '-C', '--columns COLUMNS', Integer,
|
|
165
|
+
'Number of columns (rows will be calculated)' do |c|
|
|
166
|
+
if opts_from_cmdline[:rows]
|
|
167
|
+
puts 'ERROR: -C and -R can\'t be used at the same time'
|
|
168
|
+
puts optparse.help
|
|
169
|
+
exit 1
|
|
170
|
+
else
|
|
171
|
+
opts_from_cmdline[:columns] = c
|
|
238
172
|
end
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
opts.on '-R', '--rows ROWS', Integer,
|
|
176
|
+
'Number of rows (columns will be calculated)' do |r|
|
|
177
|
+
if opts_from_cmdline[:columns]
|
|
178
|
+
puts 'ERROR: -C and -R can\'t be used at the same time'
|
|
179
|
+
puts optparse.help
|
|
180
|
+
exit 1
|
|
181
|
+
else
|
|
182
|
+
opts_from_cmdline[:rows] = r
|
|
243
183
|
end
|
|
244
|
-
end
|
|
245
|
-
optparse.parse!
|
|
184
|
+
end
|
|
246
185
|
|
|
247
|
-
|
|
248
|
-
|
|
186
|
+
opts.on '-b', '--broadcast',
|
|
187
|
+
'Start with broadcast input (DANGEROUS!)' do
|
|
188
|
+
opts_from_cmdline[:broadcast] = true
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
opts.on '-nb', '--nobroadcast',
|
|
192
|
+
'Disable broadcast' do
|
|
249
193
|
opts_from_cmdline[:broadcast] = false
|
|
250
|
-
end
|
|
194
|
+
end
|
|
251
195
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
196
|
+
opts.on '-p', '--profile PROFILE',
|
|
197
|
+
'Name of the iTerm2 profile (default: Default)' do |p|
|
|
198
|
+
opts_from_cmdline[:profile] = p
|
|
199
|
+
end
|
|
256
200
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
201
|
+
opts.on '-2', '--iterm2',
|
|
202
|
+
'Use iTerm2 instead of iTerm' do
|
|
203
|
+
opts_from_cmdline[:iterm2] = true
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
opts.on '-i', '--itermname NAME', String,
|
|
207
|
+
'Name of the application to use (default: iTerm)' do |i|
|
|
208
|
+
opts_from_cmdline[:itermname] = i
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
opts.on '-s', '--sleep SLEEP', Float,
|
|
212
|
+
'Number of seconds to sleep between creating SSH sessions' do |s|
|
|
213
|
+
opts_from_cmdline[:sleep] = s
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
opts.on '-S', '--shell SHELL', String,
|
|
217
|
+
'Shell to use when spawning the SSH sessions' do |s|
|
|
218
|
+
opts_from_cmdline[:shell] = s
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
opts.on '-d', '--direction DIRECTION', String,
|
|
222
|
+
'Direction that new sessions are created (default: row)' do |d|
|
|
223
|
+
unless ['row', 'column'].include?(d)
|
|
224
|
+
puts 'ERROR: -d requires \'row\' or \'column\''
|
|
225
|
+
puts optparse.help
|
|
226
|
+
exit 1
|
|
279
227
|
end
|
|
228
|
+
opts_from_cmdline[:direction] = d.to_sym
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
opts.on '-X', '--extra EXTRA_PARAM', String,
|
|
232
|
+
'Additional ssh parameters (e.g. -Xi=myidentity.pem)' do |x|
|
|
233
|
+
|
|
234
|
+
ssh_options << '-' + x.split('=').join(' ')
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
opts.on '-g', '--gateway HOST', String,
|
|
238
|
+
'Multihop SSH connection gateway string (e.g. username@gateway) - usually used with -A' do |g|
|
|
239
|
+
# ssh_gateway = g
|
|
240
|
+
opts_from_cmdline[:gateway] = g
|
|
241
|
+
end
|
|
280
242
|
end
|
|
281
243
|
|
|
244
|
+
optparse.parse!
|
|
245
|
+
|
|
282
246
|
# Drop default options
|
|
283
247
|
if @i2_options.size > @servers.size
|
|
284
|
-
|
|
248
|
+
@i2_options.shift
|
|
285
249
|
end
|
|
286
250
|
|
|
287
251
|
if @ssh_environment.size > @servers.size
|
|
288
|
-
|
|
252
|
+
@ssh_environment.shift
|
|
289
253
|
end
|
|
290
254
|
|
|
291
255
|
|
|
292
256
|
@i2_options.each do |opt|
|
|
293
|
-
|
|
257
|
+
opt.merge!(opts_from_cmdline)
|
|
294
258
|
end
|
|
295
259
|
|
|
296
260
|
@i2_options.each_with_index do |opt, i|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
261
|
+
if opt[:login]
|
|
262
|
+
@servers[i] = @servers[i].map{|h| "#{opt[:login]}@#{h.gsub(/.+@/,'')}"}
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
if opt[:gateway]
|
|
266
|
+
puts opt[:gateway]
|
|
267
|
+
@servers[i] = @servers[i].map{|h| "#{opt[:gateway]} -t ssh #{h}"}
|
|
268
|
+
end
|
|
304
269
|
end
|
|
305
270
|
|
|
306
271
|
|
|
307
272
|
if @servers.empty?
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
273
|
+
puts 'ERROR: no servers given'
|
|
274
|
+
puts optparse.help
|
|
275
|
+
exit
|
|
311
276
|
end
|
|
312
277
|
|
|
313
|
-
|
|
314
278
|
I2c2.new @servers, ssh_options, @i2_options, @ssh_environment
|
data/i2c2.gemspec
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
|
-
# stub: i2c2 1.0.0.
|
|
5
|
+
# stub: i2c2 1.0.0.beta5 ruby lib
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
8
|
s.name = "i2c2"
|
|
9
|
-
s.version = "1.0.0.
|
|
9
|
+
s.version = "1.0.0.beta5"
|
|
10
10
|
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
|
12
12
|
s.require_paths = ["lib"]
|
|
13
13
|
s.authors = ["dx7", "Wouter de Bie"]
|
|
14
|
-
s.date = "2019-05
|
|
14
|
+
s.date = "2019-06-05"
|
|
15
15
|
s.description = "csshX like - cluster ssh using iTerm2 panes - based on i2cssh"
|
|
16
16
|
s.email = "dx7@pm.me"
|
|
17
17
|
s.executables = ["i2c2"]
|
|
@@ -20,7 +20,6 @@ Gem::Specification.new do |s|
|
|
|
20
20
|
"README.md"
|
|
21
21
|
]
|
|
22
22
|
s.files = [
|
|
23
|
-
".document",
|
|
24
23
|
"CHANGELOG.md",
|
|
25
24
|
"Gemfile",
|
|
26
25
|
"Gemfile.lock",
|
|
@@ -35,7 +34,7 @@ Gem::Specification.new do |s|
|
|
|
35
34
|
"test/helper.rb",
|
|
36
35
|
"test/test_i2c2.rb"
|
|
37
36
|
]
|
|
38
|
-
s.homepage = "
|
|
37
|
+
s.homepage = "https://github.com/dx7/i2c2"
|
|
39
38
|
s.licenses = ["MIT"]
|
|
40
39
|
s.rubygems_version = "3.0.3"
|
|
41
40
|
s.summary = "csshX like - cluster ssh using iTerm2 panes - based on i2cssh"
|
|
@@ -45,23 +44,14 @@ Gem::Specification.new do |s|
|
|
|
45
44
|
|
|
46
45
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
47
46
|
s.add_runtime_dependency(%q<rb-scpt>, ["~> 1.0.1"])
|
|
48
|
-
s.add_development_dependency(%q<
|
|
49
|
-
s.add_development_dependency(%q<jeweler>, ["= 2.1.2"])
|
|
50
|
-
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
|
51
|
-
s.add_development_dependency(%q<builder>, [">= 0"])
|
|
47
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
|
52
48
|
else
|
|
53
49
|
s.add_dependency(%q<rb-scpt>, ["~> 1.0.1"])
|
|
54
|
-
s.add_dependency(%q<
|
|
55
|
-
s.add_dependency(%q<jeweler>, ["= 2.1.2"])
|
|
56
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
|
57
|
-
s.add_dependency(%q<builder>, [">= 0"])
|
|
50
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
58
51
|
end
|
|
59
52
|
else
|
|
60
53
|
s.add_dependency(%q<rb-scpt>, ["~> 1.0.1"])
|
|
61
|
-
s.add_dependency(%q<
|
|
62
|
-
s.add_dependency(%q<jeweler>, ["= 2.1.2"])
|
|
63
|
-
s.add_dependency(%q<shoulda>, [">= 0"])
|
|
64
|
-
s.add_dependency(%q<builder>, [">= 0"])
|
|
54
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
65
55
|
end
|
|
66
56
|
end
|
|
67
57
|
|
data/lib/i2c2.rb
CHANGED
|
@@ -1,167 +1,167 @@
|
|
|
1
1
|
require 'rb-scpt'
|
|
2
|
+
|
|
2
3
|
class I2c2
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# @iterm.create_tab(@profile)
|
|
35
|
-
@window.create_tab_with_default_profile()
|
|
36
|
-
@session_index = 0
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
@window.select(@window.tabs[1])
|
|
4
|
+
def initialize servers, ssh_options, i2_options, ssh_environment
|
|
5
|
+
@ssh_prefix = 'ssh ' + ssh_options.join(' ')
|
|
6
|
+
@ssh_options = ssh_options
|
|
7
|
+
@i2_options = i2_options.clone
|
|
8
|
+
@servers = servers
|
|
9
|
+
@ssh_environment = ssh_environment
|
|
10
|
+
|
|
11
|
+
raise Exception.new 'No servers given' if servers.empty?
|
|
12
|
+
|
|
13
|
+
@sys_events = Appscript.app.by_name('System Events')
|
|
14
|
+
@iterm = Appscript.app.by_name('iTerm')
|
|
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']
|
|
17
|
+
@profile = i2_options.first[:profile] || 'Default'
|
|
18
|
+
@shell = "/usr/bin/env #{@i2_options.first[:shell] || 'bash'}"
|
|
19
|
+
@iterm.create_window_with_profile(@profile, :command => "#{@shell} -l")
|
|
20
|
+
@window = @iterm.current_window
|
|
21
|
+
|
|
22
|
+
while !@servers.empty? do
|
|
23
|
+
compute_geometry
|
|
24
|
+
split_session
|
|
25
|
+
start_ssh
|
|
26
|
+
enable_broadcast if i2_options.first[:broadcast]
|
|
27
|
+
@servers.shift
|
|
28
|
+
@i2_options.shift
|
|
29
|
+
@ssh_environment.shift
|
|
30
|
+
|
|
31
|
+
if !@servers.empty? && i2_options.first[:tabs]
|
|
32
|
+
@window.create_tab_with_default_profile
|
|
33
|
+
@session_index = 0
|
|
34
|
+
end
|
|
40
35
|
end
|
|
36
|
+
@window.select(@window.tabs[1])
|
|
37
|
+
end
|
|
41
38
|
|
|
42
|
-
|
|
39
|
+
private
|
|
43
40
|
def maximize(app_name)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
begin
|
|
42
|
+
# OSX >= 10.8 has different behavior for full screen. First try out old behavior.
|
|
43
|
+
fullscreen_bounds = Appscript.app.by_name('Finder').desktop.window.bounds
|
|
44
|
+
window = @iterm.windows.get.sort_by{|x| x.id_.get}.last
|
|
45
|
+
window.bounds.set fullscreen_bounds.get
|
|
46
|
+
rescue
|
|
47
|
+
@sys_events.processes[app_name].windows.first.attributes['AXFullScreen'].value.set(true)
|
|
48
|
+
end
|
|
52
49
|
end
|
|
53
50
|
|
|
54
51
|
def compute_geometry
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
end
|
|
61
|
-
else
|
|
62
|
-
count = @servers.first.size
|
|
63
|
-
@rows = @i2_options.first[:rows]
|
|
64
|
-
@columns = @i2_options.first[:columns]
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
if @rows then
|
|
68
|
-
@columns = (count / @rows.to_f).ceil
|
|
69
|
-
elsif @columns then
|
|
70
|
-
@rows = (count / @columns.to_f).ceil
|
|
71
|
-
else
|
|
72
|
-
@columns = Math.sqrt(count).ceil
|
|
73
|
-
@rows = (count / @columns.to_f).ceil
|
|
74
|
-
end
|
|
75
|
-
# Quick hack: iTerms default window only supports up to 11 rows and 22 columns
|
|
76
|
-
# If we surpass either one, we resort to full screen.
|
|
77
|
-
if @rows > 11 or @columns > 22 then
|
|
78
|
-
@i2_options.first[:fullscreen] = true
|
|
52
|
+
# Create geometry when combining and ignore rows/columns preference
|
|
53
|
+
if @servers.size > 1 && !@i2_options.first[:tabs]
|
|
54
|
+
count = 0
|
|
55
|
+
@servers.each do |srv|
|
|
56
|
+
count += srv.size
|
|
79
57
|
end
|
|
58
|
+
else
|
|
59
|
+
count = @servers.first.size
|
|
60
|
+
@rows = @i2_options.first[:rows]
|
|
61
|
+
@columns = @i2_options.first[:columns]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
if @rows
|
|
65
|
+
@columns = (count / @rows.to_f).ceil
|
|
66
|
+
elsif @columns
|
|
67
|
+
@rows = (count / @columns.to_f).ceil
|
|
68
|
+
else
|
|
69
|
+
@columns = Math.sqrt(count).ceil
|
|
70
|
+
@rows = (count / @columns.to_f).ceil
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Quick hack: iTerms default window only supports up to 11 rows and 22 columns
|
|
74
|
+
# If we surpass either one, we resort to full screen.
|
|
75
|
+
if @rows > 11 or @columns > 22
|
|
76
|
+
@i2_options.first[:fullscreen] = true
|
|
77
|
+
end
|
|
80
78
|
end
|
|
81
79
|
|
|
82
80
|
def split_session
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
81
|
+
left = @pane_menu.menu_items['Select Pane Left']
|
|
82
|
+
right = @pane_menu.menu_items['Select Pane Right']
|
|
83
|
+
up = @pane_menu.menu_items['Select Pane Above']
|
|
84
|
+
down = @pane_menu.menu_items['Select Pane Below']
|
|
85
|
+
|
|
86
|
+
split_vert = lambda { @window.current_session.split_vertically_with_same_profile }
|
|
87
|
+
split_hori = lambda { @window.current_session.split_horizontally_with_same_profile }
|
|
88
|
+
|
|
89
|
+
splitmap = {
|
|
90
|
+
:column => {0 => split_vert, 1 => left, 2 => split_hori, 3=> right, :x => @columns, :y => @rows},
|
|
91
|
+
:row => {0 => split_hori, 1=> up, 2 => split_vert, 3=> down, :x => @rows, :y => @columns}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
splitconfig = splitmap[@i2_options.first[:direction]]
|
|
95
|
+
|
|
96
|
+
first = true
|
|
97
|
+
2.upto splitconfig[:x] do
|
|
98
|
+
splitconfig[0].call
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
2.upto splitconfig[:y] do
|
|
102
|
+
1.upto splitconfig[:x] do
|
|
103
|
+
splitconfig[1].click
|
|
104
|
+
first = false
|
|
100
105
|
end
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
end
|
|
106
|
-
splitconfig[:x].times do |x|
|
|
107
|
-
splitconfig[2].call
|
|
108
|
-
splitconfig[3].click
|
|
109
|
-
end
|
|
106
|
+
|
|
107
|
+
splitconfig[:x].times do |x|
|
|
108
|
+
splitconfig[2].call
|
|
109
|
+
splitconfig[3].click
|
|
110
110
|
end
|
|
111
|
+
end
|
|
111
112
|
end
|
|
112
113
|
|
|
113
114
|
def enable_broadcast
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
@sys_events.keystroke 'I', :using => :command_down
|
|
116
|
+
sleep 0.5
|
|
117
|
+
@sys_events.keystroke "\r"
|
|
117
118
|
end
|
|
118
119
|
|
|
119
120
|
def start_ssh
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
session.write :text => "stty -isig -icanon -echo && echo -e '#{"\n"*100}UNUSED' && cat > /dev/null"
|
|
164
|
-
end
|
|
121
|
+
old_size = 0
|
|
122
|
+
|
|
123
|
+
1.upto(@rows*@columns) do |i|
|
|
124
|
+
tab = @window.current_tab
|
|
125
|
+
session = tab.sessions[i]
|
|
126
|
+
session.write :text => "#{@shell} -l"
|
|
127
|
+
|
|
128
|
+
# Without the tab flag, combine all servers and clusters into one window
|
|
129
|
+
if !@servers.empty? && (i - old_size) > @servers.first.size && !@i2_options.first[:tabs]
|
|
130
|
+
old_size = @servers.first.size
|
|
131
|
+
@servers.shift
|
|
132
|
+
@i2_options.shift
|
|
133
|
+
@ssh_environment.shift
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
if @servers.empty?
|
|
137
|
+
server = nil
|
|
138
|
+
else
|
|
139
|
+
server = @servers.first[i-old_size-1]
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
if server
|
|
143
|
+
send_env = ''
|
|
144
|
+
|
|
145
|
+
if @i2_options.first[:rank]
|
|
146
|
+
@ssh_environment.first['LC_RANK'] = i-1
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
if !@ssh_environment.empty? && !@ssh_environment.first.empty?
|
|
150
|
+
send_env = "-o SendEnv=#{@ssh_environment.first.keys.join(',')}"
|
|
151
|
+
session.write :text => "#{@ssh_environment.first.map{|k,v| "export #{k}=#{v}"}.join('; ')}"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
if @i2_options.first[:sleep]
|
|
155
|
+
sleep @i2_options.first[:sleep] * i
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
session.write :text => "unset HISTFILE && echo -e \"\\033]50;SetProfile=#{@profile}\\a\" && #{@ssh_prefix} #{send_env} #{server}"
|
|
159
|
+
else
|
|
160
|
+
session.write :text => "unset HISTFILE && echo -e \"\\033]50;SetProfile=#{@profile}\\a\""
|
|
161
|
+
sleep 0.3
|
|
162
|
+
session.foreground_color.set ([65535,0,0])
|
|
163
|
+
session.write :text => "stty -isig -icanon -echo && echo -e '#{"\n"*100}UNUSED' && cat > /dev/null"
|
|
165
164
|
end
|
|
165
|
+
end
|
|
166
166
|
end
|
|
167
167
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: i2c2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.0.
|
|
4
|
+
version: 1.0.0.beta5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- dx7
|
|
8
8
|
- Wouter de Bie
|
|
9
|
-
autorequire:
|
|
9
|
+
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2020-09-10 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rb-scpt
|
|
@@ -25,50 +25,8 @@ dependencies:
|
|
|
25
25
|
- - "~>"
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
27
|
version: 1.0.1
|
|
28
|
-
- !ruby/object:Gem::Dependency
|
|
29
|
-
name: bundler
|
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
|
31
|
-
requirements:
|
|
32
|
-
- - ">="
|
|
33
|
-
- !ruby/object:Gem::Version
|
|
34
|
-
version: 1.0.0
|
|
35
|
-
type: :development
|
|
36
|
-
prerelease: false
|
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
-
requirements:
|
|
39
|
-
- - ">="
|
|
40
|
-
- !ruby/object:Gem::Version
|
|
41
|
-
version: 1.0.0
|
|
42
28
|
- !ruby/object:Gem::Dependency
|
|
43
29
|
name: jeweler
|
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
|
45
|
-
requirements:
|
|
46
|
-
- - '='
|
|
47
|
-
- !ruby/object:Gem::Version
|
|
48
|
-
version: 2.1.2
|
|
49
|
-
type: :development
|
|
50
|
-
prerelease: false
|
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
-
requirements:
|
|
53
|
-
- - '='
|
|
54
|
-
- !ruby/object:Gem::Version
|
|
55
|
-
version: 2.1.2
|
|
56
|
-
- !ruby/object:Gem::Dependency
|
|
57
|
-
name: shoulda
|
|
58
|
-
requirement: !ruby/object:Gem::Requirement
|
|
59
|
-
requirements:
|
|
60
|
-
- - ">="
|
|
61
|
-
- !ruby/object:Gem::Version
|
|
62
|
-
version: '0'
|
|
63
|
-
type: :development
|
|
64
|
-
prerelease: false
|
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
-
requirements:
|
|
67
|
-
- - ">="
|
|
68
|
-
- !ruby/object:Gem::Version
|
|
69
|
-
version: '0'
|
|
70
|
-
- !ruby/object:Gem::Dependency
|
|
71
|
-
name: builder
|
|
72
30
|
requirement: !ruby/object:Gem::Requirement
|
|
73
31
|
requirements:
|
|
74
32
|
- - ">="
|
|
@@ -87,10 +45,10 @@ executables:
|
|
|
87
45
|
- i2c2
|
|
88
46
|
extensions: []
|
|
89
47
|
extra_rdoc_files:
|
|
48
|
+
- CHANGELOG.md
|
|
90
49
|
- LICENSE.txt
|
|
91
50
|
- README.md
|
|
92
51
|
files:
|
|
93
|
-
- ".document"
|
|
94
52
|
- CHANGELOG.md
|
|
95
53
|
- Gemfile
|
|
96
54
|
- Gemfile.lock
|
|
@@ -104,11 +62,11 @@ files:
|
|
|
104
62
|
- lib/i2c2.rb
|
|
105
63
|
- test/helper.rb
|
|
106
64
|
- test/test_i2c2.rb
|
|
107
|
-
homepage:
|
|
65
|
+
homepage: https://github.com/dx7/i2c2
|
|
108
66
|
licenses:
|
|
109
67
|
- MIT
|
|
110
68
|
metadata: {}
|
|
111
|
-
post_install_message:
|
|
69
|
+
post_install_message:
|
|
112
70
|
rdoc_options: []
|
|
113
71
|
require_paths:
|
|
114
72
|
- lib
|
|
@@ -123,8 +81,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
123
81
|
- !ruby/object:Gem::Version
|
|
124
82
|
version: 1.3.1
|
|
125
83
|
requirements: []
|
|
126
|
-
rubygems_version: 3.
|
|
127
|
-
signing_key:
|
|
84
|
+
rubygems_version: 3.1.2
|
|
85
|
+
signing_key:
|
|
128
86
|
specification_version: 4
|
|
129
87
|
summary: csshX like - cluster ssh using iTerm2 panes - based on i2cssh
|
|
130
88
|
test_files: []
|