rye 0.9.7 → 0.9.8
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.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)
|