rye 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGES.txt +44 -38
- data/README.rdoc +44 -30
- data/Rakefile +41 -82
- data/VERSION +1 -0
- data/gem-public_cert.pem +20 -0
- data/lib/rye.rb +74 -52
- data/lib/rye/box.rb +7 -4
- data/lib/rye/dsl.rb +100 -0
- data/rye.gemspec +95 -55
- data/try/10_basic_tryouts.rb +44 -0
- data/try/12_batch_tryouts.rb +26 -0
- data/try/13_set_tryouts.rb +42 -0
- data/try/14_auth_methods_tryouts.rb +28 -0
- data/try/15_file_tryouts.rb +12 -0
- data/try/20_file_transfer_tryouts.rb +46 -0
- data/try/25_template_upload.rb +37 -0
- data/try/30_safemode_tryouts.rb +85 -0
- data/try/35_basics_with_hop.rb +36 -0
- data/try/70_rye_cli_tryouts.rb +0 -0
- data/try/copying.rb +18 -0
- data/try/keys.rb +141 -0
- data/tst/10-key1 +27 -0
- data/tst/10-key1.pub +1 -0
- data/tst/10-key2 +30 -0
- data/tst/10-key2.pub +1 -0
- data/tst/10_keys_test.rb +88 -0
- data/tst/50_rset_test.rb +54 -0
- data/tst/60-file.mp3 +0 -0
- data/tst/60_rbox_transfer_test.rb +53 -0
- data/tst/65_rbox_file_append_test.rb +53 -0
- data/tst/70_rbox_env_test.rb +19 -0
- data/tst/dsl_example.rb +80 -0
- data/tst/rye.rb +13 -0
- data/tst/shell.rb +280 -0
- data/tst/shell2.rb +278 -0
- data/tst/shell3.rb +280 -0
- data/tst/test_hop.rb +25 -0
- metadata +86 -25
- metadata.gz.sig +0 -0
- data/bin/try +0 -246
data/tst/10-key1
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEogIBAAKCAQEAzRTl7NX++irdkHdH68/JFu9EXimuih6wgfDn0cIC15isHons
|
3
|
+
sxN5i7SuIDfP9zLc9QJWgfUyn0nsdOp5Di8KStvidlMnNeZUSA2YwjQUH++1z4z5
|
4
|
+
bbjUixCBkn8Jv6uV+CxPeB3DFJKOrc1DKfkzf1oaUhEPPcfS78ZGM7fEW5wXX8zX
|
5
|
+
OS0BnRvX9oTpQtypdm6vjcdZnW76eSudjJvk0yruV6UquEcud+RVNtJlM7uqgm2C
|
6
|
+
EBhD18qxQINwTG0NFALYMaNzXKrAu6MSvk9uHof/nSk4V5IwBh+2fQAyvukpgmqv
|
7
|
+
L5yYVm1mXGs4DwG9ukJ+PuGzh02sUKcGoc3yIwIBIwKCAQEAtaTLpeIcWetzyRkx
|
8
|
+
ErC5bBXANiTrDJ7W2X2aIC9+3DbEVZAayn72oE+S6VYBV0pOrR9T73LGb9PCzfQ/
|
9
|
+
VbSit1UKaM1OnXQ8BU3fEmikHElX47dglGHg0vFc0jYBUf5gQjXf/KyleJ8QqJE7
|
10
|
+
fPKp9HRgdJLEW0qWQhYDqiZsFp6cEjaLPz1URDV3NQhc2zMa1wvq22rVbhiGolev
|
11
|
+
J9Mpt/x0VEzTkMCQ+zRp5ca9wrbybN3V9MPS+rW8BUhhf2ZGNwvlV9MXJ2Y+IG8l
|
12
|
+
OTrVA8+0o500d/TVqhgj4dQNsJG8NYOel2q8kzMt2wmilnM5guuTQKV6vA5gBqNe
|
13
|
+
4rfxuwKBgQDlUINrk4Y2R5X2BGjYRq+n8Ct7LPM5DHgWMCl11dtptncrMnES+DsQ
|
14
|
+
06rs1kfd7tchpsoXkZw7xRAfdcqoPyQgH/pflI1beTNzzB2BSQYzsP8oCqn/qLw1
|
15
|
+
8F+Uj7IoQ/AixWJOUcgvx+85Fwht/u6lTi+ak7caVlTk8LHS8SAJmQKBgQDk8ncx
|
16
|
+
h4rXjKRbW2U0iNJGUWdMP88fFKmnHhsHHm75bgIWg/YgoL8W2y/HhmgUHrskkkXc
|
17
|
+
BwpLa0g5YakgKt22c9HAAB+B4EXuBLWANKv3WLccJBgN9dpTLGsSMGbiQAHn6/fn
|
18
|
+
njrd+NDH8z8jAx1j4ITJzYiKfa6+DiP6HA/HGwKBgA0aiyq3+QpqfZkHkPZqcG//
|
19
|
+
GG1wSGmo8OtTNZG0cvAZDh+5vVGKhwhGnA2IlmR0DEsQ2FkeQ3EhNB8OC5SV5M6i
|
20
|
+
vdmTdcq2d/f9CQASzSeGdPr5S4rzsvvEl79Yqxg+ZX5UbAR5s6r1e2JZFmyve1nn
|
21
|
+
NeuTaYx59jj3z6WnYOqbAoGADRUrYep89l/O4KYjClD2EqWQ38khx0MCYVItbh7/
|
22
|
+
BvBX5AeKaEOzJeCjpQBduAHBjQ+sOHVuTXPYPcsQ+oYbTEEh7bbdOp8Z8FgKXxjz
|
23
|
+
4j+Vb1KFCBytY9anCFqJiUV8c6cVevMZToM/IV5bYRYe78Ov0QRuM8yq5knzbWCw
|
24
|
+
cccCgYEAx681uFoi74fmii8cecItcxW1jPT+C9kmh1bpN6hgTeoWH9W0fi0we77D
|
25
|
+
35I5hd7Qxh+6DhW75dWcWil6V3UqsBkpzlOx8+SdXJT7J5IDSNuCIRctct1prEqS
|
26
|
+
C6x5mIzPqKTY/Ebn12u68HMNecGVWQXNJrfYceQ9HyDKYC5OrRg=
|
27
|
+
-----END RSA PRIVATE KEY-----
|
data/tst/10-key1.pub
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzRTl7NX++irdkHdH68/JFu9EXimuih6wgfDn0cIC15isHonssxN5i7SuIDfP9zLc9QJWgfUyn0nsdOp5Di8KStvidlMnNeZUSA2YwjQUH++1z4z5bbjUixCBkn8Jv6uV+CxPeB3DFJKOrc1DKfkzf1oaUhEPPcfS78ZGM7fEW5wXX8zXOS0BnRvX9oTpQtypdm6vjcdZnW76eSudjJvk0yruV6UquEcud+RVNtJlM7uqgm2CEBhD18qxQINwTG0NFALYMaNzXKrAu6MSvk9uHof/nSk4V5IwBh+2fQAyvukpgmqvL5yYVm1mXGs4DwG9ukJ+PuGzh02sUKcGoc3yIw== delano@vanya.local
|
data/tst/10-key2
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
Proc-Type: 4,ENCRYPTED
|
3
|
+
DEK-Info: DES-EDE3-CBC,A2D419194B51170A
|
4
|
+
|
5
|
+
5GWquKZfufjYD/dcjU7aZ8LauEQzJSF+o9pz8X1eeuqcJ8bc68tm7LtJP1kiPQcD
|
6
|
+
vPsXCWYx3eXPSGBkYUqP0Ta6EqHRpoBnOSHKCurMMAYxrfWxECp7A6rkVALpFXR4
|
7
|
+
UQcts+lAssdg15GqQnDJxDg2zQc5kiWb10NVu01kuuevLj+nqr/PC/os/vuFfPqG
|
8
|
+
C+guJzmhaILqGSKNWkIuBS8lojjKHrJxyBcrLF0/yfTVPsA6TAQNRz9cDuzfnLvy
|
9
|
+
HAcHKW/OgdJkoQ/D0sxEHRQLm/yqoyuxUs0vb0iQja4P1/qsjGJr6QYk2gUJETun
|
10
|
+
hyvHtpUc+F059is2ezrl9RNkz1pbINp2Wz7QYVJy9NpYkI6ZieWANR4ZdrQcp0uQ
|
11
|
+
lV7jS2w0UZelXe4jLFoM9sG4g28OMNZyFk+i49J74F5E8SBnYeupNoTb6Ujs7cMZ
|
12
|
+
lVc47aTaT+2a/5TY043GSmo/vp18dN3Fp9u5QuO1mtw/VbmmyK8CO0OFflEgnG3a
|
13
|
+
Ke09tJ9+R11eDU+mG0cNl/OUcqsKTIjQEfeHCKszzbfyLXDMQOIgUhirv8kMR8/0
|
14
|
+
i8tCk/uEKZ1rYpsoocdBqXMqOV1/QySQ4CifeuDXx2uVTHBZrKh5Ips69QAkof1v
|
15
|
+
Aholk9V1jdl/sXWCII73Z7OoATng6gSfjmSHDGrDmoBeTpYkdgXTL4ndENIyHt3e
|
16
|
+
InRvfiN/Jk/5nqOpDJs6AV95phAADAaNclR6o/gnKZntlBpWjn3N9hdXAGumty2V
|
17
|
+
7XZjmQtj3sYD1XvI0fKD4t2eKvbJANxHAkiyYVsD4DbjmdIW5mw6RtYrchBDKIBA
|
18
|
+
fZIeSAt9Hqsy6h0IzFxC1kxMa1GxdKXepYjbDjqRDFhw0zRyBHDMQTDDFuX/QjsU
|
19
|
+
ZVCG8djcvY4hjAB+D+/lmgGRKXyB+VbqMpDhpvZAhyarbXzeKv52v/Ae2H3MfHwF
|
20
|
+
KfHrn9jBPIT8AqsMsfxMXNFj/l6a+vZfhcYgo3I12lHA2AOA4AdSbI3YDO40o6Bi
|
21
|
+
tfXohXsouaPHNT2zksoUDeam6F7qzewZ6+P9+jXsPm0tzZzVsv7cKqs45bTIi8ii
|
22
|
+
Rjr+b4vKUhdzbV7TvrwBzg6VNjD/sHoC6j7ViMRyrqwuOBXT4fMC3F3lEcRLRM8G
|
23
|
+
37wrF96RCrJCPP2UjN2jNk/601QIQ8mID2N//GUXZiQd4eWhTg3R8fK5aiSOA8xs
|
24
|
+
32jzmHksfENoeZHtcrdSRUaas1xsn3mU+KnWSOnRl70zL+TR/CtN1cZPrmCD+x5E
|
25
|
+
N+aWvEDz+kB6dzfqGOi4c/I6GoLmK0dPQj6/7QzlRsDhgBsW+Kzc/tHm7jf+q4bG
|
26
|
+
zKyqZ4deqP8/bfte2fE4nMukyMHIDxijEr7OMcJr7VY0eICQoeMgQGW/oXsUe1eO
|
27
|
+
p7QYAkNZwvV9QU1BKOjzGOfFz6kt+zLrOZYem0tWVfV+mf5KogRYhoQaf4jO7bAL
|
28
|
+
P2AmjMulYk/crR2OqhfszpZ9nNXovw9OqqTjJ1AEf75fmfSnr4UmmUxVKHkmKTHI
|
29
|
+
3uQFtBl2ZDVctOS3vMAOQS8AlKL+u2RIt/d0LiX2jv8h4j1wg+i7Wg==
|
30
|
+
-----END RSA PRIVATE KEY-----
|
data/tst/10-key2.pub
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAyWv+kF4ZZ5DzQNdXdkdoEdjeFfiQ59HxbD1WZVn6WQGAgydGR13A9X+g5eC7rNM/EAFdRaaUfgzGPh8O5ZwpuYEYfcYzDnjLlVXK0cXsGq/OUufUPcB2WaAzW8IjLFak51c92oHKrp3BPZPfFq3hTjUAgV9m8hFGTRustvkh1G+gXnuXTz/Bn9KS7kJMV6iWz5k6b4MzXaKO9S/CZxIw+VWt0F7MdIGiNfpvmPcXaAPpRiyDLpzXwrkU7eUphpK50iPSR2d1tIKtD/Jtr8PhAafzpZd6fXBK/L8/yufSFehSflMIg4BOdjk6xlC5ls9MLjbz+zZz9ZzXQg0xJ/JR6Q== delano@vanya.local
|
data/tst/10_keys_test.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
TEST_HOME = File.dirname(__FILE__)
|
4
|
+
$:.unshift File.join(TEST_HOME, '..', 'lib')
|
5
|
+
|
6
|
+
require 'rye'
|
7
|
+
|
8
|
+
private_key_path = File.join(TEST_HOME, '10-key1')
|
9
|
+
rpk = Rye::Key.from_file(private_key_path)
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
puts "RYE::KEY PUBLIC KEY GOOD TIMES: #{private_key_path}", $/
|
14
|
+
puts "1-2 should be the same. I don't understand why they are not."
|
15
|
+
puts "3-6 should have identical key content (ignoring spaces and 'ssh-rsa')"
|
16
|
+
|
17
|
+
# PKCS#1 RSAPublicKey* (PEM header: BEGIN RSA PUBLIC KEY)
|
18
|
+
puts "[1] PEM encoded public key (via Rye::Key#public_key)"
|
19
|
+
puts rpk.public_key.to_pem
|
20
|
+
# -----BEGIN RSA PUBLIC KEY-----
|
21
|
+
# MIIBCAKCAQEAzRTl7NX++irdkHdH68/JFu9EXimuih6wgfDn0cIC15isHonssxN5
|
22
|
+
# i7SuIDfP9zLc9QJWgfUyn0nsdOp5Di8KStvidlMnNeZUSA2YwjQUH++1z4z5bbjU
|
23
|
+
# ixCBkn8Jv6uV+CxPeB3DFJKOrc1DKfkzf1oaUhEPPcfS78ZGM7fEW5wXX8zXOS0B
|
24
|
+
# nRvX9oTpQtypdm6vjcdZnW76eSudjJvk0yruV6UquEcud+RVNtJlM7uqgm2CEBhD
|
25
|
+
# 18qxQINwTG0NFALYMaNzXKrAu6MSvk9uHof/nSk4V5IwBh+2fQAyvukpgmqvL5yY
|
26
|
+
# Vm1mXGs4DwG9ukJ+PuGzh02sUKcGoc3yIwIBIw==
|
27
|
+
# -----END RSA PUBLIC KEY-----
|
28
|
+
|
29
|
+
# X.509 SubjectPublicKeyInfo** (PEM header: BEGIN PUBLIC KEY)
|
30
|
+
puts $/, "[2] PEM encoded public key (via openssl rsa -in #{private_key_path} -pubout)"
|
31
|
+
puts Rye.shell('openssl', "rsa -in #{private_key_path} -pubout")
|
32
|
+
# -----BEGIN PUBLIC KEY-----
|
33
|
+
# MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAzRTl7NX++irdkHdH68/J
|
34
|
+
# Fu9EXimuih6wgfDn0cIC15isHonssxN5i7SuIDfP9zLc9QJWgfUyn0nsdOp5Di8K
|
35
|
+
# StvidlMnNeZUSA2YwjQUH++1z4z5bbjUixCBkn8Jv6uV+CxPeB3DFJKOrc1DKfkz
|
36
|
+
# f1oaUhEPPcfS78ZGM7fEW5wXX8zXOS0BnRvX9oTpQtypdm6vjcdZnW76eSudjJvk
|
37
|
+
# 0yruV6UquEcud+RVNtJlM7uqgm2CEBhD18qxQINwTG0NFALYMaNzXKrAu6MSvk9u
|
38
|
+
# Hof/nSk4V5IwBh+2fQAyvukpgmqvL5yYVm1mXGs4DwG9ukJ+PuGzh02sUKcGoc3y
|
39
|
+
# IwIBIw==
|
40
|
+
# -----END PUBLIC KEY-----
|
41
|
+
|
42
|
+
|
43
|
+
puts $/, "[3] Base64 encoded"
|
44
|
+
puts Base64.encode64(rpk.public_key.to_blob)
|
45
|
+
# AAAAB3NzaC1yc2EAAAABIwAAAQEAzRTl7NX++irdkHdH68/JFu9EXimuih6w
|
46
|
+
# gfDn0cIC15isHonssxN5i7SuIDfP9zLc9QJWgfUyn0nsdOp5Di8KStvidlMn
|
47
|
+
# NeZUSA2YwjQUH++1z4z5bbjUixCBkn8Jv6uV+CxPeB3DFJKOrc1DKfkzf1oa
|
48
|
+
# UhEPPcfS78ZGM7fEW5wXX8zXOS0BnRvX9oTpQtypdm6vjcdZnW76eSudjJvk
|
49
|
+
# 0yruV6UquEcud+RVNtJlM7uqgm2CEBhD18qxQINwTG0NFALYMaNzXKrAu6MS
|
50
|
+
# vk9uHof/nSk4V5IwBh+2fQAyvukpgmqvL5yYVm1mXGs4DwG9ukJ+PuGzh02s
|
51
|
+
# UKcGoc3yIw==
|
52
|
+
|
53
|
+
puts $/, "[4] Base64 encoded, SSH2 format (manual)"
|
54
|
+
puts Base64.encode64(rpk.public_key.to_blob).strip.gsub(/[\r\n]/, '')
|
55
|
+
# AAAAB3NzaC1yc2EAAAABIwAAAQEAzRTl7NX++irdkHdH68/JFu9EXimuih6wgfDn0cIC15isHonssxN5i7SuIDfP9zLc9QJWgfUyn0nsdOp5Di8KStvidlMnNeZUSA2YwjQUH++1z4z5bbjUixCBkn8Jv6uV+CxPeB3DFJKOrc1DKfkzf1oaUhEPPcfS78ZGM7fEW5wXX8zXOS0BnRvX9oTpQtypdm6vjcdZnW76eSudjJvk0yruV6UquEcud+RVNtJlM7uqgm2CEBhD18qxQINwTG0NFALYMaNzXKrAu6MSvk9uHof/nSk4V5IwBh+2fQAyvukpgmqvL5yYVm1mXGs4DwG9ukJ+PuGzh02sUKcGoc3yIw==
|
56
|
+
|
57
|
+
puts $/, "[5] Base64 encoded, SSH2 format (via Rye::Key.public_key.to_ssh2)"
|
58
|
+
puts rpk.public_key.to_ssh2
|
59
|
+
# ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzRTl7NX++irdkHdH68/JFu9EXimuih6wgfDn0cIC15isHonssxN5i7SuIDfP9zLc9QJWgfUyn0nsdOp5Di8KStvidlMnNeZUSA2YwjQUH++1z4z5bbjUixCBkn8Jv6uV+CxPeB3DFJKOrc1DKfkzf1oaUhEPPcfS78ZGM7fEW5wXX8zXOS0BnRvX9oTpQtypdm6vjcdZnW76eSudjJvk0yruV6UquEcud+RVNtJlM7uqgm2CEBhD18qxQINwTG0NFALYMaNzXKrAu6MSvk9uHof/nSk4V5IwBh+2fQAyvukpgmqvL5yYVm1mXGs4DwG9ukJ+PuGzh02sUKcGoc3yIw==
|
60
|
+
|
61
|
+
puts $/, "[6] Base64 encoded, SSH2 format (via ssh-keygen -y -f #{private_key_path})"
|
62
|
+
puts Rye.shell('ssh-keygen', "-y -f #{private_key_path}")
|
63
|
+
# ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzRTl7NX++irdkHdH68/JFu9EXimuih6wgfDn0cIC15isHonssxN5i7SuIDfP9zLc9QJWgfUyn0nsdOp5Di8KStvidlMnNeZUSA2YwjQUH++1z4z5bbjUixCBkn8Jv6uV+CxPeB3DFJKOrc1DKfkzf1oaUhEPPcfS78ZGM7fEW5wXX8zXOS0BnRvX9oTpQtypdm6vjcdZnW76eSudjJvk0yruV6UquEcud+RVNtJlM7uqgm2CEBhD18qxQINwTG0NFALYMaNzXKrAu6MSvk9uHof/nSk4V5IwBh+2fQAyvukpgmqvL5yYVm1mXGs4DwG9ukJ+PuGzh02sUKcGoc3yIw==
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
__END__
|
69
|
+
|
70
|
+
* http://cryptosys.net/pki/rsakeyformats.html
|
71
|
+
|
72
|
+
Public key formats supported
|
73
|
+
|
74
|
+
* PKCS#1 RSAPublicKey* (PEM header: BEGIN RSA PUBLIC KEY)
|
75
|
+
* X.509 SubjectPublicKeyInfo** (PEM header: BEGIN PUBLIC KEY)
|
76
|
+
* XML <RSAKeyValue>
|
77
|
+
|
78
|
+
Encrypted private key format supported
|
79
|
+
|
80
|
+
* PKCS#8 EncryptedPrivateKeyInfo** (PEM header: BEGIN ENCRYPTED PRIVATE KEY)
|
81
|
+
|
82
|
+
Private key formats supported (unencrypted)
|
83
|
+
|
84
|
+
* PKCS#1 RSAPrivateKey** (PEM header: BEGIN RSA PRIVATE KEY)
|
85
|
+
* PKCS#8 PrivateKeyInfo* (PEM header: BEGIN PRIVATE KEY)
|
86
|
+
* XML <RSAKeyPair> and <RSAKeyValue>
|
87
|
+
|
88
|
+
|
data/tst/50_rset_test.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# Usage: test/50_rye_test.rb
|
5
|
+
#
|
6
|
+
|
7
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
8
|
+
|
9
|
+
require 'benchmark'
|
10
|
+
require 'rubygems'
|
11
|
+
require 'stringio'
|
12
|
+
require 'yaml'
|
13
|
+
require 'rye'
|
14
|
+
|
15
|
+
|
16
|
+
machine_key = {
|
17
|
+
:host => 'localhost',
|
18
|
+
:user => "delano",
|
19
|
+
:key => '/proj/git/rudy/.rudy/key-test-app.private'
|
20
|
+
}
|
21
|
+
|
22
|
+
machine_pass = {
|
23
|
+
:host => 'localhost',
|
24
|
+
:user => 'delano',
|
25
|
+
# :pass => 'pablo9001'
|
26
|
+
}
|
27
|
+
|
28
|
+
machine_local = {
|
29
|
+
:host => "localhost"
|
30
|
+
}
|
31
|
+
|
32
|
+
rbox_key = Rye::Box.new(machine_key[:host], :user => machine_key[:user], :keys => machine_key[:key])
|
33
|
+
rbox_pass = Rye::Box.new(machine_pass[:host], :user => machine_pass[:user], :password=> machine_pass[:pass])
|
34
|
+
rbox_local = Rye::Box.new(machine_local[:host], :safe => false)
|
35
|
+
|
36
|
+
|
37
|
+
rset_serial = Rye::Set.new("example", :parallel => false) #, :debug => STDOUT
|
38
|
+
rset_parallel = Rye::Set.new("example", :parallel => true)
|
39
|
+
rset_serial.add_boxes(rbox_key, rbox_local, rbox_pass)
|
40
|
+
rset_parallel.add_boxes(rbox_key, rbox_local, rbox_pass)
|
41
|
+
|
42
|
+
# The Rehersal will be slower because they'll include the connection time
|
43
|
+
Benchmark.bmbm do |x|
|
44
|
+
x.report('rbox: ') { puts "%10s:%s:%s" % [rbox_key.uname, rbox_local.uname, rbox_pass.uname] }
|
45
|
+
x.report('rset-S:') { puts "%10s:%s:%s" % rset_serial.uname }
|
46
|
+
x.report('rset-P:') { puts "%10s:%s:%s" % rset_parallel.uname }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Parallel should obviously be faster here
|
50
|
+
Benchmark.bmbm do |x|
|
51
|
+
x.report('rbox: ') { puts "%10s:%s:%s" % [rbox_key.sleep(2), rbox_local.sleep(2), rbox_pass.sleep(2)] }
|
52
|
+
x.report('rset-S:') { puts "%10s:%s:%s" % rset_serial.sleep(2) }
|
53
|
+
x.report('rset-P:') { puts "%10s:%s:%s" % rset_parallel.sleep(2) }
|
54
|
+
end
|
data/tst/60-file.mp3
ADDED
Binary file
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# Usage: test/60_rbox_upload_test.rb
|
5
|
+
#
|
6
|
+
|
7
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
8
|
+
|
9
|
+
require "rubygems"
|
10
|
+
require "stringio"
|
11
|
+
require "yaml"
|
12
|
+
require "rye"
|
13
|
+
|
14
|
+
tmpdir = Rye.sysinfo.tmpdir
|
15
|
+
|
16
|
+
rbox = Rye::Box.new("localhost", :info => true)
|
17
|
+
def rbox.rm(*args); __allow('rm', args); end
|
18
|
+
rbox.rm(:r, :f, "#{tmpdir}/rye-upload") # Silently delete test dir
|
19
|
+
|
20
|
+
# /tmp/rye-upload will be created if it doesn't exist
|
21
|
+
rbox.file_upload("README.rdoc", "LICENSE.txt", "#{tmpdir}/rye-upload")
|
22
|
+
|
23
|
+
# A single file can be renamed
|
24
|
+
rbox.file_upload("README.rdoc", "#{tmpdir}/rye-upload/README-renamed")
|
25
|
+
|
26
|
+
# StringIO objects can be sent as files
|
27
|
+
applejack = StringIO.new
|
28
|
+
applejack.puts "Delano: What's happening Applejack?"
|
29
|
+
applejack.puts "Applejack: Just trying to get by."
|
30
|
+
rbox.file_upload(applejack, "#{tmpdir}/rye-upload/applejack")
|
31
|
+
|
32
|
+
rbox.file_upload("tst/60-file.mp3", "#{tmpdir}/rye-upload") # demonstrates
|
33
|
+
rbox.file_upload("tst/60-file.mp3", "#{tmpdir}/rye-upload") # progress
|
34
|
+
rbox.file_upload("tst/60-file.mp3", "#{tmpdir}/rye-upload") # bar
|
35
|
+
|
36
|
+
puts "Content of /tmp/rye-upload"
|
37
|
+
puts rbox.ls(:l, "#{tmpdir}/rye-upload")
|
38
|
+
|
39
|
+
rbox.file_download("#{tmpdir}/rye-upload/README.rdoc",
|
40
|
+
"#{tmpdir}/rye-upload/README-renamed", "#{tmpdir}/rye-download")
|
41
|
+
|
42
|
+
# You can't download a StringIO object. This raises an exception:
|
43
|
+
#rbox.file_download(applejack, "#{tmpdir}/rye-download/applejack")
|
44
|
+
# But you can download _to_ a StringIO object
|
45
|
+
applejack = StringIO.new
|
46
|
+
rbox.file_download("#{tmpdir}/rye-upload/applejack", applejack)
|
47
|
+
|
48
|
+
puts $/, "Content of /tmp/rye-download"
|
49
|
+
puts rbox.ls(:l, "#{tmpdir}/rye-download")
|
50
|
+
|
51
|
+
puts $/, "Content of applejack StringIO object"
|
52
|
+
applejack.rewind
|
53
|
+
puts applejack.read
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# Usage: test/65_rbox_file_append_test.rb
|
5
|
+
#
|
6
|
+
|
7
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
8
|
+
|
9
|
+
require "rubygems"
|
10
|
+
require "stringio"
|
11
|
+
require "yaml"
|
12
|
+
require "rye"
|
13
|
+
|
14
|
+
tmpdir = Rye.sysinfo.tmpdir
|
15
|
+
|
16
|
+
rbox = Rye::Box.new("localhost", :info => false)
|
17
|
+
def rbox.rm(*args); __allow('rm', args); end
|
18
|
+
rbox.rm(:r, :f, "#{tmpdir}/rye-upload") # Silently delete test dir
|
19
|
+
rbox.mkdir("#{tmpdir}/rye-upload")
|
20
|
+
|
21
|
+
# Create a file with one line so we have something to append to.
|
22
|
+
initfile = StringIO.new
|
23
|
+
initfile.puts "Initial file content (before append)"
|
24
|
+
rbox.file_upload(initfile, "#{tmpdir}/rye-upload/initfile")
|
25
|
+
|
26
|
+
# Append a single line to the file
|
27
|
+
rbox.file_append("#{tmpdir}/rye-upload/initfile", "APPENDED: a single line")
|
28
|
+
|
29
|
+
puts $/, "SHOULD BE 2 lines"
|
30
|
+
puts rbox.cat("#{tmpdir}/rye-upload/initfile")
|
31
|
+
|
32
|
+
puts $/, "THE LAST APPEND DID NOT REQUEST A BACKUP. SUCCESS? (should be false):"
|
33
|
+
puts rbox.file_exists?("#{tmpdir}/rye-upload/initfile-previous")
|
34
|
+
|
35
|
+
|
36
|
+
# Append multiple lines from an Array
|
37
|
+
rbox.file_append("#{tmpdir}/rye-upload/initfile", ['line3', 'line4'])
|
38
|
+
|
39
|
+
puts $/, "SHOULD BE 4 lines"
|
40
|
+
puts rbox.cat("#{tmpdir}/rye-upload/initfile")
|
41
|
+
|
42
|
+
junk = StringIO.new
|
43
|
+
junk.puts('line5')
|
44
|
+
junk.puts('line6')
|
45
|
+
junk.puts('line7')
|
46
|
+
rbox.file_append("#{tmpdir}/rye-upload/initfile", junk, :backup)
|
47
|
+
|
48
|
+
puts $/, "SHOULD BE 7 lines"
|
49
|
+
puts rbox.cat("#{tmpdir}/rye-upload/initfile")
|
50
|
+
|
51
|
+
puts $/, "THE LAST APPEND REQUESTED A BACKUP. SUCCESS? (should be true):"
|
52
|
+
puts rbox.file_exists?("#{tmpdir}/rye-upload/initfile-previous")
|
53
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# Usage: test/70_rbox_env_test.rb
|
5
|
+
#
|
6
|
+
|
7
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
8
|
+
|
9
|
+
require "rubygems"
|
10
|
+
require "stringio"
|
11
|
+
require "yaml"
|
12
|
+
require "rye"
|
13
|
+
|
14
|
+
tmpdir = Rye.sysinfo.tmpdir
|
15
|
+
|
16
|
+
rbox = Rye::Box.new("localhost", :info => true)
|
17
|
+
|
18
|
+
puts rbox.getenv['HOME'] # slight delay while vars are fetched
|
19
|
+
puts rbox.getenv['HOME'] # returned from memory
|
data/tst/dsl_example.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# vim: filetype=ruby
|
2
|
+
|
3
|
+
host '192.168.56.101', :user => 'root' do
|
4
|
+
disable_safe_mode
|
5
|
+
cd '/'
|
6
|
+
info ls '-lah'
|
7
|
+
end
|
8
|
+
|
9
|
+
host '192.168.56.102', :user => 'root'
|
10
|
+
|
11
|
+
parallel false
|
12
|
+
|
13
|
+
hostset 'virtualbox machines', '192.168.56.101', '192.168.56.102' do
|
14
|
+
disable_safe_mode
|
15
|
+
disable_quiet_mode
|
16
|
+
cd '/root'
|
17
|
+
info ls '-lah'
|
18
|
+
end
|
19
|
+
|
20
|
+
hostset 'virtualbox machines' do
|
21
|
+
info execute 'ps -Af | grep "getty"'
|
22
|
+
end
|
23
|
+
|
24
|
+
host 'main01', :user => 'root'
|
25
|
+
host 'test01', :user => 'root'
|
26
|
+
|
27
|
+
hostset 'virtualbox machines by hostname', 'main01', 'test01'
|
28
|
+
|
29
|
+
parallel true
|
30
|
+
|
31
|
+
hostset 'virtualbox machines by hostname' do
|
32
|
+
# Since this is a different Rye::Set instance from 'virtualbox machines', it starts from scratch
|
33
|
+
# so safe mode has to be disabled again to run ping
|
34
|
+
disable_safe_mode
|
35
|
+
disable_quiet_mode
|
36
|
+
info execute 'ping -c 1 localhost'
|
37
|
+
end
|
38
|
+
|
39
|
+
command_group 'library list' do
|
40
|
+
cd '/usr/lib/'
|
41
|
+
info ls('-la | head -n 5')
|
42
|
+
end
|
43
|
+
|
44
|
+
command_group 'top five processes' do
|
45
|
+
info execute 'ps -Af | head'
|
46
|
+
end
|
47
|
+
|
48
|
+
command_group 'check tunnel' do
|
49
|
+
exit_status_check 'ps -Af | grep "ssh -N -f -D 9050" | grep -v "grep"'
|
50
|
+
end
|
51
|
+
|
52
|
+
command_group 'check tmux' do
|
53
|
+
# Should pass if tmux is running
|
54
|
+
exit_status_check 'ps -Af | grep start-server | grep -v "grep"',
|
55
|
+
:pass_str => 'Tmux Check Passed',
|
56
|
+
:fail_str => 'Tmux Check Failed'
|
57
|
+
# Should fail
|
58
|
+
exit_status_check 'ps -Af | grep "start-serverz" | grep -v "grep"'
|
59
|
+
end
|
60
|
+
|
61
|
+
hostset 'virtualbox machines by hostname' do
|
62
|
+
colors false
|
63
|
+
run 'library list'
|
64
|
+
end
|
65
|
+
|
66
|
+
colors true
|
67
|
+
|
68
|
+
host 'main01' do
|
69
|
+
disable_safe_mode
|
70
|
+
run 'library list'
|
71
|
+
run 'top five processes'
|
72
|
+
debug ls '-la /etc | head -n 5'
|
73
|
+
run 'check tunnel'
|
74
|
+
end
|
75
|
+
|
76
|
+
host 'localhost' do
|
77
|
+
disable_safe_mode
|
78
|
+
run 'check tmux'
|
79
|
+
end
|
80
|
+
|
data/tst/rye.rb
ADDED
data/tst/shell.rb
ADDED
@@ -0,0 +1,280 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
require 'annoy'
|
3
|
+
|
4
|
+
#
|
5
|
+
# For channel requests, see SSH_MSG_CHANNEL_REQUEST messages
|
6
|
+
# in http://www.snailbook.com/docs/connection.txt
|
7
|
+
DEBUG = false
|
8
|
+
|
9
|
+
module Rye
|
10
|
+
class Box
|
11
|
+
def debug(state, msg='')
|
12
|
+
return unless DEBUG
|
13
|
+
puts " ------ %s: %s" % [state, msg]
|
14
|
+
end
|
15
|
+
|
16
|
+
def start_session_state(channel)
|
17
|
+
debug :start_session, channel[:handler]
|
18
|
+
if channel[:block]
|
19
|
+
channel[:state] = :run_block
|
20
|
+
else
|
21
|
+
channel[:state] = :await_response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def await_response_state(channel)
|
26
|
+
debug :await_response, channel[:handler]
|
27
|
+
@await_response_counter ||= 0
|
28
|
+
if channel[:stdout].available > 0
|
29
|
+
channel[:state] = :read_input
|
30
|
+
elsif @await_response_counter > 10
|
31
|
+
@await_response_counter = 0
|
32
|
+
channel[:state] = :await_input
|
33
|
+
end
|
34
|
+
@await_response_counter += 1
|
35
|
+
end
|
36
|
+
|
37
|
+
def read_input_state(channel)
|
38
|
+
debug :read_input, channel[:handler]
|
39
|
+
if channel[:stdout].available > 0
|
40
|
+
print channel[:stdout].read
|
41
|
+
|
42
|
+
if channel[:stack].empty?
|
43
|
+
channel[:state] = :await_input
|
44
|
+
elsif channel[:stdout].available > 0
|
45
|
+
channel[:state] = :read_input
|
46
|
+
else
|
47
|
+
channel[:state] = :send_data
|
48
|
+
end
|
49
|
+
else
|
50
|
+
channel[:state] = :await_response
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def send_data_state(channel)
|
55
|
+
debug :send_data, channel[:handler]
|
56
|
+
#if channel[:stack].empty?
|
57
|
+
# channel[:state] = :await_input
|
58
|
+
#else
|
59
|
+
cmd = channel[:stack].shift
|
60
|
+
#return if cmd.strip.empty?
|
61
|
+
debug :send_data, "calling #{cmd.inspect}"
|
62
|
+
channel[:state] = :await_response
|
63
|
+
channel.send_data("#{cmd}\n") unless channel.eof?
|
64
|
+
#channel.exec("#{cmd}\n", &create_channel)
|
65
|
+
#end
|
66
|
+
end
|
67
|
+
|
68
|
+
def await_input_state(channel)
|
69
|
+
debug :await_input, channel[:handler]
|
70
|
+
if channel[:stdout].available > 0
|
71
|
+
channel[:state] = :read_input
|
72
|
+
else
|
73
|
+
if channel[:prompt]
|
74
|
+
puts channel[:prompt]
|
75
|
+
channel[:prompt] = nil
|
76
|
+
end
|
77
|
+
ret = STDIN.gets
|
78
|
+
if ret.nil?
|
79
|
+
channel.eof!
|
80
|
+
channel[:state] = :exit
|
81
|
+
else
|
82
|
+
channel[:stack] << ret.chomp
|
83
|
+
channel[:state] = :send_data
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
def ignore_response_state(channel)
|
90
|
+
debug :ignore_response, channel[:handler]
|
91
|
+
@ignore_response_counter ||= 0
|
92
|
+
if channel[:stdout].available > 0
|
93
|
+
@await_response_counter = 0
|
94
|
+
channel[:stdout].read
|
95
|
+
channel[:state] = :process
|
96
|
+
elsif @ignore_response_counter > 2
|
97
|
+
@await_response_counter = 0
|
98
|
+
channel[:state] = :process
|
99
|
+
end
|
100
|
+
@ignore_response_counter += 1
|
101
|
+
end
|
102
|
+
|
103
|
+
def exit_state(channel)
|
104
|
+
debug :exit_state, channel[:exit_status]
|
105
|
+
puts
|
106
|
+
channel.eof!
|
107
|
+
end
|
108
|
+
|
109
|
+
def handle_error_state(channel)
|
110
|
+
debug :handle_error, channel[:handler]
|
111
|
+
channel.eof!
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
def run_block_state(channel)
|
116
|
+
debug :run_block, channel[:handler]
|
117
|
+
channel[:state] = nil
|
118
|
+
blk = channel[:block]
|
119
|
+
channel[:block] = nil
|
120
|
+
instance_eval &blk
|
121
|
+
channel[:state] = :exit
|
122
|
+
end
|
123
|
+
|
124
|
+
def command(name,*args, &blk)
|
125
|
+
#debug :command, "(#{channel[:handler]})"
|
126
|
+
#if channel.eof?
|
127
|
+
# p [:channel_eof]
|
128
|
+
#end
|
129
|
+
cmd = "%s %s" % [name, args.join(' ')]
|
130
|
+
debug :command, "Running: #{cmd}"
|
131
|
+
|
132
|
+
pty_opts = { :term => "xterm",
|
133
|
+
:chars_wide => 80,
|
134
|
+
:chars_high => 24,
|
135
|
+
:pixels_wide => 640,
|
136
|
+
:pixels_high => 480,
|
137
|
+
:modes => {} }
|
138
|
+
|
139
|
+
channel = @session.open_channel do |channel|
|
140
|
+
channel.request_pty(pty_opts) do |ch,success|
|
141
|
+
self.pty = success
|
142
|
+
raise "pty request denied" unless success
|
143
|
+
end
|
144
|
+
channel.exec(cmd, &create_channel)
|
145
|
+
channel[:state] = :start_session
|
146
|
+
end
|
147
|
+
|
148
|
+
@session.loop(0.1) do
|
149
|
+
break if channel.nil? || !channel.active?
|
150
|
+
!channel.eof? # otherwise keep returning true
|
151
|
+
end
|
152
|
+
|
153
|
+
channel[:stdout].read
|
154
|
+
end
|
155
|
+
|
156
|
+
def wait_for_command_state(channel)
|
157
|
+
debug :wait_for_command, channel[:handler]
|
158
|
+
end
|
159
|
+
|
160
|
+
def ls(*args) command(:ls, *args) end
|
161
|
+
def cat(*args) command(:cat, *args) end
|
162
|
+
def echo(*args) command(:echo, *args) end
|
163
|
+
def sudo(*args) command(:sudo, *args) end
|
164
|
+
def date(*args) command(:date, *args) end
|
165
|
+
def uname(*args) command(:uname, *args) end
|
166
|
+
def chroot(*args) command(:chroot, *args) end
|
167
|
+
def bash(*args, &blk) command(:bash, *args, &blk) end
|
168
|
+
def exit(*args, &blk) command(:exit, *args, &blk) end
|
169
|
+
|
170
|
+
attr_reader :session, :channel
|
171
|
+
attr_accessor :running, :pty
|
172
|
+
|
173
|
+
def connect(host, user, opts={})
|
174
|
+
opts = {
|
175
|
+
:auth_methods => %w[keyboard-interactive]
|
176
|
+
}.merge(opts)
|
177
|
+
opts[:auth_methods].unshift 'publickey' unless opts[:keys].nil?
|
178
|
+
opts[:auth_methods].unshift 'password' unless opts[:password].nil?
|
179
|
+
@sessions ||= []
|
180
|
+
@session = Net::SSH.start(host, user, opts)
|
181
|
+
end
|
182
|
+
|
183
|
+
def run(shell=nil, &blk)
|
184
|
+
|
185
|
+
if shell.nil?
|
186
|
+
instance_eval &blk
|
187
|
+
else
|
188
|
+
command(shell)
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
def stop
|
195
|
+
@control.join if @control
|
196
|
+
@ssh.running = false
|
197
|
+
@ssh.close
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
def create_channel()
|
203
|
+
Proc.new do |channel,success|
|
204
|
+
channel[:stdout ] = Net::SSH::Buffer.new
|
205
|
+
channel[:stderr ] = Net::SSH::Buffer.new
|
206
|
+
channel[:stack] ||= []
|
207
|
+
channel.on_close { |ch|
|
208
|
+
channel[:handler] = ":on_close"
|
209
|
+
}
|
210
|
+
channel.on_data { |ch, data|
|
211
|
+
channel[:handler] = ":on_data"
|
212
|
+
if self.pty && data =~ /\Apassword/i
|
213
|
+
channel[:prompt] = data
|
214
|
+
channel[:state] = :await_input
|
215
|
+
else
|
216
|
+
channel[:stdout].append(data)
|
217
|
+
end
|
218
|
+
}
|
219
|
+
channel.on_extended_data { |ch, type, data|
|
220
|
+
channel[:handler] = ":on_extended_data"
|
221
|
+
channel[:stderr].append(data)
|
222
|
+
channel[:state] = :handle_error
|
223
|
+
}
|
224
|
+
channel.on_request("exit-status") { |ch, data|
|
225
|
+
channel[:handler] = ":on_request (exit-status)"
|
226
|
+
channel[:exit_status] = data.read_long
|
227
|
+
}
|
228
|
+
channel.on_request("exit-signal") do |ch, data|
|
229
|
+
channel[:handler] = ":on_request (exit-signal)"
|
230
|
+
# This should be the POSIX SIGNAL that ended the process
|
231
|
+
channel[:exit_signal] = data.read_long
|
232
|
+
end
|
233
|
+
channel.on_process {
|
234
|
+
channel[:handler] = :on_process
|
235
|
+
print channel[:stderr].read if channel[:stderr].available > 0
|
236
|
+
begin
|
237
|
+
send("#{channel[:state]}_state", channel) unless channel[:state].nil?
|
238
|
+
rescue Interrupt
|
239
|
+
debug :await_input_interrupt
|
240
|
+
channel[:state] = :exit
|
241
|
+
end
|
242
|
+
}
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
begin
|
250
|
+
puts $$
|
251
|
+
rbox = Rye::Box.new
|
252
|
+
rbox.connect 'localhost', 'delano', :verbose => :fatal, :keys => []
|
253
|
+
|
254
|
+
rbox.run 'bash'
|
255
|
+
#rbox.run do
|
256
|
+
# puts command("date")
|
257
|
+
# puts command("SUDO_PS1=POOP\n")
|
258
|
+
# #puts command("echo $GLORIA_HOME; echo $?")
|
259
|
+
# #puts command("sudo whoami")
|
260
|
+
# #puts command("sudo -k")
|
261
|
+
#
|
262
|
+
# command("cpan")
|
263
|
+
# puts command("uptime")
|
264
|
+
# #puts command("SUDO_PS1='POOP'")
|
265
|
+
# #puts command("echo $SUDO_PS1")
|
266
|
+
# ##puts sudo( 'chroot', '/mnt/archlinux-x86_64')
|
267
|
+
# #command("unset PS1;")
|
268
|
+
#end
|
269
|
+
#puts rbox.channel[:stderr] if rbox.channel[:stderr]
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
__END__
|
274
|
+
http://tldp.org/LDP/abs/html/intandnonint.html
|
275
|
+
case $- in
|
276
|
+
*i*) # interactive shell
|
277
|
+
;;
|
278
|
+
*) # non-interactive shell
|
279
|
+
;;
|
280
|
+
# (Courtesy of "UNIX F.A.Q.," 1993)
|