libssh 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +4 -0
- data/README.md +5 -1
- data/example/exec.rb +2 -0
- data/example/scp_download.rb +51 -0
- data/example/scp_upload.rb +31 -0
- data/example/sshkit.rb +11 -0
- data/ext/libssh_ruby/channel.c +91 -0
- data/ext/libssh_ruby/key.c +36 -0
- data/ext/libssh_ruby/libssh_ruby.c +38 -0
- data/ext/libssh_ruby/libssh_ruby.h +1 -0
- data/ext/libssh_ruby/scp.c +457 -0
- data/ext/libssh_ruby/session.c +386 -2
- data/lib/libssh.rb +0 -4
- data/lib/libssh/version.rb +1 -1
- data/lib/sshkit/backends/libssh.rb +108 -5
- data/libssh.gemspec +2 -1
- metadata +23 -5
data/lib/libssh.rb
CHANGED
data/lib/libssh/version.rb
CHANGED
@@ -17,6 +17,43 @@ module SSHKit
|
|
17
17
|
end
|
18
18
|
|
19
19
|
BUFSIZ = 16384
|
20
|
+
private_constant :BUFSIZ
|
21
|
+
|
22
|
+
# @override
|
23
|
+
def upload!(local, remote, _options = {})
|
24
|
+
with_session do |session|
|
25
|
+
scp = LibSSH::Scp.new(session, :write, File.dirname(remote))
|
26
|
+
wrap_local_reader(local) do |io, mode|
|
27
|
+
scp.init do
|
28
|
+
scp.push_file(File.basename(remote), io.size, mode)
|
29
|
+
info "Uploading #{remote}"
|
30
|
+
while (buf = io.read(BUFSIZ))
|
31
|
+
scp.write(buf)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @override
|
39
|
+
def download!(remote, local, _options = {})
|
40
|
+
with_session do |session|
|
41
|
+
scp = LibSSH::Scp.new(session, :read, remote)
|
42
|
+
scp.init do
|
43
|
+
loop do
|
44
|
+
case scp.pull_request
|
45
|
+
when LibSSH::Scp::REQUEST_NEWFILE
|
46
|
+
info "Downloading #{remote}"
|
47
|
+
download_file(scp, local)
|
48
|
+
when LibSSH::Scp::REQUEST_NEWDIR
|
49
|
+
scp.deny_request('Only NEWFILE is acceptable')
|
50
|
+
when LibSSH::Scp::REQUEST_EOF
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
20
57
|
|
21
58
|
@pool = SSHKit::Backend::ConnectionPool.new
|
22
59
|
|
@@ -64,13 +101,52 @@ module SSHKit
|
|
64
101
|
end
|
65
102
|
end
|
66
103
|
|
104
|
+
def wrap_local_reader(local)
|
105
|
+
if local.respond_to?(:read)
|
106
|
+
# local is IO-like object
|
107
|
+
yield(local, 0644)
|
108
|
+
else
|
109
|
+
File.open(local, 'rb') do |f|
|
110
|
+
yield(f, File.stat(local).mode & 0xfff)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def wrap_local_writer(local, mode)
|
116
|
+
if local.respond_to?(:write)
|
117
|
+
# local is IO-like object
|
118
|
+
yield(local)
|
119
|
+
else
|
120
|
+
File.open(local, 'wb', mode) do |f|
|
121
|
+
yield(f)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def download_file(scp, local)
|
127
|
+
size = scp.request_size
|
128
|
+
mode = scp.request_permissions
|
129
|
+
scp.accept_request
|
130
|
+
wrap_local_writer(local, mode) do |io|
|
131
|
+
n = 0
|
132
|
+
while n < size
|
133
|
+
buf = scp.read(size - n)
|
134
|
+
io.write(buf)
|
135
|
+
n += buf.size
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
67
140
|
def with_session
|
68
|
-
|
141
|
+
host.ssh_options = Libssh.config.ssh_options.merge(host.ssh_options || {})
|
142
|
+
entry = self.class.pool.checkout(String(host.hostname), host.username, host.netssh_options) do |hostname, username, ssh_options|
|
69
143
|
LibSSH::Session.new.tap do |session|
|
70
|
-
session.host =
|
71
|
-
|
72
|
-
|
73
|
-
|
144
|
+
session.host = hostname
|
145
|
+
username = ssh_options.fetch(:user, username)
|
146
|
+
if username
|
147
|
+
session.user = username
|
148
|
+
end
|
149
|
+
configure_session(session, ssh_options)
|
74
150
|
session.connect
|
75
151
|
if session.server_known != LibSSH::SERVER_KNOWN_OK
|
76
152
|
raise 'unknown host'
|
@@ -87,6 +163,33 @@ module SSHKit
|
|
87
163
|
self.class.pool.checkin(entry)
|
88
164
|
end
|
89
165
|
end
|
166
|
+
|
167
|
+
def configure_session(session, ssh_options)
|
168
|
+
if ssh_options[:port]
|
169
|
+
session.port = ssh_options[:port]
|
170
|
+
end
|
171
|
+
|
172
|
+
session.add_identity('%d/id_ed25519')
|
173
|
+
keys = Array(ssh_options[:keys])
|
174
|
+
unless keys.empty?
|
175
|
+
keys.each do |key|
|
176
|
+
session.add_identity(key)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
ssh_options.fetch(:config, true).tap do |config|
|
181
|
+
case config
|
182
|
+
when true
|
183
|
+
# Load from default ssh_config
|
184
|
+
session.parse_config
|
185
|
+
when false, nil
|
186
|
+
# Don't load from ssh_config
|
187
|
+
else
|
188
|
+
# Load from specified path
|
189
|
+
session.parse_config(config)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
90
193
|
end
|
91
194
|
end
|
92
195
|
end
|
data/libssh.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency 'bundler'
|
25
25
|
spec.add_development_dependency 'rake'
|
26
26
|
spec.add_development_dependency 'rake-compiler'
|
27
|
-
spec.add_development_dependency 'sshkit'
|
28
27
|
spec.add_development_dependency 'rubocop', '>= 0.36.0'
|
28
|
+
spec.add_development_dependency 'sshkit'
|
29
|
+
spec.add_development_dependency 'yard'
|
29
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kohei Suzuki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.36.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.36.0
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: sshkit
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,19 +81,19 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: yard
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0
|
89
|
+
version: '0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0
|
96
|
+
version: '0'
|
83
97
|
description: Ruby binding for libssh.
|
84
98
|
email:
|
85
99
|
- eagletmt@gmail.com
|
@@ -101,6 +115,8 @@ files:
|
|
101
115
|
- bin/console
|
102
116
|
- bin/setup
|
103
117
|
- example/exec.rb
|
118
|
+
- example/scp_download.rb
|
119
|
+
- example/scp_upload.rb
|
104
120
|
- example/sshkit.rb
|
105
121
|
- example/write.rb
|
106
122
|
- ext/libssh_ruby/channel.c
|
@@ -109,6 +125,7 @@ files:
|
|
109
125
|
- ext/libssh_ruby/key.c
|
110
126
|
- ext/libssh_ruby/libssh_ruby.c
|
111
127
|
- ext/libssh_ruby/libssh_ruby.h
|
128
|
+
- ext/libssh_ruby/scp.c
|
112
129
|
- ext/libssh_ruby/session.c
|
113
130
|
- lib/libssh.rb
|
114
131
|
- lib/libssh/key.rb
|
@@ -140,3 +157,4 @@ signing_key:
|
|
140
157
|
specification_version: 4
|
141
158
|
summary: Ruby binding for libssh.
|
142
159
|
test_files: []
|
160
|
+
has_rdoc:
|