libssh 0.1.0 → 0.2.0
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/.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:
|