rosh 0.9.4 → 0.9.6
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/Makefile +6 -0
- data/README.md +1 -0
- data/lib/rosh/version.rb +1 -1
- data/lib/rosh.rb +32 -21
- data/test/rosh_forwarding_test.rb +23 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1399835146cfcd6615a17868694c426b4c06b25649fab1c02192bf8f4534fe1d
|
|
4
|
+
data.tar.gz: 835a84fe3a697e322fb28aa6c67e16f0ad1cbf832616b23991c65f0333fde8f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ecaffa32659f87db955a586bced2a742f15735cc75c5d76b00cc7113a9378673cfb54294b7d33ffa29eefdda0213cee56ea09f07de4caae68b3239875f4d9d7c
|
|
7
|
+
data.tar.gz: 66a075c156779a0d33907187ada1195f8d7ebce66fb59de8136e585f7e3b4ce1d0e9f641961d3be12c6b956ae8215f0071e60e16a2a46ea153f0b5c8f377fbd0
|
data/Makefile
ADDED
data/README.md
CHANGED
|
@@ -26,6 +26,7 @@ Or install it yourself as:
|
|
|
26
26
|
Default: "^t"
|
|
27
27
|
-I interval Reconnection interval.
|
|
28
28
|
-S Use GNU screen instead of tmux
|
|
29
|
+
-L socket-name Specify tmux socket name (tmux -L socket-name)
|
|
29
30
|
|
|
30
31
|
If ~/.ssh/config contains LocalForward or RemoteForward for the host, the same
|
|
31
32
|
forwarding options are passed to `ssh` automatically.
|
data/lib/rosh/version.rb
CHANGED
data/lib/rosh.rb
CHANGED
|
@@ -11,6 +11,7 @@ class Rosh
|
|
|
11
11
|
@ssh_opts = []
|
|
12
12
|
alive_interval = 5
|
|
13
13
|
@escape = '^t'
|
|
14
|
+
@tmux_socket_name = nil
|
|
14
15
|
OptionParser.new("test").tap do |opt|
|
|
15
16
|
opt.banner = 'Usage: rosh [options] hostname [session-name]'
|
|
16
17
|
opt.on('-a alive-interval'){|v| alive_interval = v.to_i}
|
|
@@ -18,6 +19,7 @@ class Rosh
|
|
|
18
19
|
opt.on('-I interval'){|v| @interval = v.to_f}
|
|
19
20
|
opt.on('-V'){|v| @verbose = true}
|
|
20
21
|
opt.on('-S'){|v| @screen = true}
|
|
22
|
+
opt.on('-L socket-name'){|v| @tmux_socket_name = v}
|
|
21
23
|
end.parse! args
|
|
22
24
|
@host, @name = *args, :default
|
|
23
25
|
abort 'hostname is required' if @host == :default
|
|
@@ -30,8 +32,6 @@ class Rosh
|
|
|
30
32
|
if @verbose
|
|
31
33
|
puts "ssh-config: #{config}"
|
|
32
34
|
end
|
|
33
|
-
@forward_opts = []
|
|
34
|
-
@forwarding_disabled = false
|
|
35
35
|
@oom_reported = false
|
|
36
36
|
@last_exit_status = nil
|
|
37
37
|
local_forwards(alias_name).each do |f|
|
|
@@ -62,8 +62,9 @@ class Rosh
|
|
|
62
62
|
["ssh", *@ssh_opts, resolv,
|
|
63
63
|
'-t', "'screen -rx #{@name}'", '2>/dev/null']*' '
|
|
64
64
|
else
|
|
65
|
+
remote_cmd = single_quote(tmux_attach_command)
|
|
65
66
|
["ssh", *@ssh_opts, resolv,
|
|
66
|
-
'-t',
|
|
67
|
+
'-t', remote_cmd, '2>/dev/null']*' '
|
|
67
68
|
end
|
|
68
69
|
if @verbose
|
|
69
70
|
puts "connecting to #{@host}..."
|
|
@@ -117,26 +118,12 @@ private
|
|
|
117
118
|
end
|
|
118
119
|
|
|
119
120
|
def add_forward_option(kind, spec)
|
|
120
|
-
return if forwarding_disabled?
|
|
121
121
|
if kind == :local && !local_forward_available?(spec)
|
|
122
122
|
puts "skip forwarding: #{spec} is already in use"
|
|
123
|
-
disable_forwarding!
|
|
124
123
|
return
|
|
125
124
|
end
|
|
126
125
|
opt = kind == :local ? "-L #{spec}" : "-R #{spec}"
|
|
127
126
|
@ssh_opts << opt
|
|
128
|
-
@forward_opts << opt
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def disable_forwarding!
|
|
132
|
-
return if @forwarding_disabled
|
|
133
|
-
@forwarding_disabled = true
|
|
134
|
-
@forward_opts.each { |opt| @ssh_opts.delete(opt) }
|
|
135
|
-
@forward_opts.clear
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def forwarding_disabled?
|
|
139
|
-
@forwarding_disabled
|
|
140
127
|
end
|
|
141
128
|
|
|
142
129
|
def local_forward_available?(spec)
|
|
@@ -227,24 +214,25 @@ private
|
|
|
227
214
|
|
|
228
215
|
def sh_has_session?
|
|
229
216
|
# tmux has-session -t <session_name>
|
|
230
|
-
ssh_tmux("
|
|
217
|
+
ssh_tmux("#{tmux_prefix} has-session -t #{tmux_session_name} 2>/dev/null")
|
|
231
218
|
end
|
|
232
219
|
|
|
233
220
|
def sh_new_session?
|
|
234
221
|
# tmux new-session -s <session_name> -d
|
|
235
|
-
create_with_override = "
|
|
222
|
+
create_with_override = "#{tmux_prefix} new-session -s #{tmux_session_name} -d \\; set-option -t #{tmux_session_name} destroy-unattached off"
|
|
236
223
|
return true if ssh_tmux(create_with_override)
|
|
237
224
|
|
|
238
225
|
puts "retrying tmux new-session without destroy-unattached override" if @verbose
|
|
239
|
-
ssh_tmux("
|
|
226
|
+
ssh_tmux("#{tmux_prefix} new-session -s #{tmux_session_name} -d")
|
|
240
227
|
end
|
|
241
228
|
|
|
242
229
|
def ssh_tmux(command)
|
|
230
|
+
remote_command = single_quote(command.to_s)
|
|
243
231
|
cmd = [
|
|
244
232
|
"ssh",
|
|
245
233
|
*@ssh_opts,
|
|
246
234
|
resolv,
|
|
247
|
-
|
|
235
|
+
remote_command
|
|
248
236
|
]*' '
|
|
249
237
|
puts cmd if @verbose
|
|
250
238
|
system cmd
|
|
@@ -293,4 +281,27 @@ private
|
|
|
293
281
|
rescue Exception
|
|
294
282
|
@host
|
|
295
283
|
end
|
|
284
|
+
|
|
285
|
+
def tmux_attach_command
|
|
286
|
+
"#{tmux_prefix} attach -t #{tmux_session_name}"
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def tmux_prefix
|
|
290
|
+
return 'tmux' unless @tmux_socket_name
|
|
291
|
+
"tmux -L #{format_remote_arg(@tmux_socket_name)}"
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def tmux_session_name
|
|
295
|
+
format_remote_arg(@name)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def format_remote_arg(value)
|
|
299
|
+
str = value.to_s
|
|
300
|
+
return str if str.match?(%r{\A[[:alnum:]@%+=:,./_-]+\z})
|
|
301
|
+
%("#{str.gsub(/(["\\$`])/, '\\\\\1')}")
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def single_quote(str)
|
|
305
|
+
"'" + str.to_s.gsub("'", %q('\'') ) + "'"
|
|
306
|
+
end
|
|
296
307
|
end
|
|
@@ -57,7 +57,7 @@ class RoshForwardingTest < Minitest::Test
|
|
|
57
57
|
ssh_opts = rosh.instance_variable_get(:@ssh_opts)
|
|
58
58
|
|
|
59
59
|
refute_includes ssh_opts, '-L 127.0.0.1:3131:localhost:3131'
|
|
60
|
-
|
|
60
|
+
assert_includes ssh_opts, '-R 8082:localhost:8082'
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def test_verbose_logs_when_session_is_missing
|
|
@@ -118,4 +118,26 @@ class RoshForwardingTest < Minitest::Test
|
|
|
118
118
|
assert_includes commands.first, 'set-option -t grav destroy-unattached off'
|
|
119
119
|
refute_includes commands.last, 'set-option -t grav destroy-unattached off'
|
|
120
120
|
end
|
|
121
|
+
|
|
122
|
+
def test_tmux_commands_include_socket_name_when_specified
|
|
123
|
+
socket_name = 'work'
|
|
124
|
+
rosh = Rosh.new('-L', socket_name, 'grav')
|
|
125
|
+
rosh.instance_variable_set(:@name, 'grav')
|
|
126
|
+
|
|
127
|
+
assert_includes rosh.send(:tmux_attach_command), "-L #{socket_name}"
|
|
128
|
+
|
|
129
|
+
commands = []
|
|
130
|
+
rosh.stub(:system, ->(cmd) { commands << cmd; true }) do
|
|
131
|
+
rosh.send(:sh_has_session?)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
assert_includes commands.first, "-L #{socket_name}"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_tmux_default_socket_used_when_not_specified
|
|
138
|
+
rosh = Rosh.new('grav')
|
|
139
|
+
command = rosh.send(:tmux_attach_command)
|
|
140
|
+
|
|
141
|
+
refute_includes command, '-L'
|
|
142
|
+
end
|
|
121
143
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rosh
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Genki Takiuchi
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-12-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: net-ssh
|
|
@@ -79,6 +79,7 @@ files:
|
|
|
79
79
|
- ".gitignore"
|
|
80
80
|
- Gemfile
|
|
81
81
|
- LICENSE.txt
|
|
82
|
+
- Makefile
|
|
82
83
|
- README.md
|
|
83
84
|
- Rakefile
|
|
84
85
|
- bin/rosh
|