corl 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitmodules +1 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +15 -8
- data/VERSION +1 -1
- data/bootstrap/os/ubuntu/00_base.sh +10 -1
- data/bootstrap/os/ubuntu/05_ruby.sh +6 -0
- data/bootstrap/os/ubuntu/06_puppet.sh +6 -6
- data/bootstrap/os/ubuntu/09_nucleon.sh +14 -0
- data/bootstrap/os/ubuntu/10_corl.sh +7 -2
- data/corl.gemspec +16 -9
- data/lib/CORL/action/authorize.rb +57 -0
- data/lib/CORL/action/bootstrap.rb +5 -0
- data/lib/CORL/action/destroy.rb +64 -0
- data/lib/CORL/action/exec.rb +9 -0
- data/lib/CORL/action/image.rb +39 -7
- data/lib/CORL/action/images.rb +4 -3
- data/lib/CORL/action/lookup.rb +2 -2
- data/lib/CORL/action/regions.rb +51 -0
- data/lib/CORL/action/seed.rb +1 -1
- data/lib/CORL/action/spawn.rb +8 -9
- data/lib/CORL/action/ssh.rb +74 -0
- data/lib/CORL/action/start.rb +37 -5
- data/lib/CORL/action/stop.rb +37 -5
- data/lib/CORL/configuration/file.rb +34 -7
- data/lib/CORL/event/puppet.rb +1 -1
- data/lib/CORL/machine/aws.rb +153 -0
- data/lib/CORL/machine/physical.rb +14 -5
- data/lib/CORL/machine/rackspace.rb +58 -0
- data/lib/CORL/network/default.rb +1 -1
- data/lib/CORL/node/aws.rb +40 -16
- data/lib/CORL/node/local.rb +4 -3
- data/lib/CORL/node/rackspace.rb +25 -7
- data/lib/CORL/provisioner/puppetnode.rb +11 -9
- data/lib/core/errors.rb +6 -0
- data/lib/core/mod/fog_aws_server.rb +38 -0
- data/lib/core/plugin/action.rb +3 -11
- data/lib/core/plugin/configuration.rb +20 -2
- data/lib/{CORL/machine/fog.rb → core/plugin/fog_machine.rb} +92 -92
- data/lib/core/plugin/{fog.rb → fog_node.rb} +20 -7
- data/lib/core/plugin/machine.rb +58 -37
- data/lib/core/plugin/network.rb +76 -111
- data/lib/core/plugin/node.rb +271 -87
- data/lib/core/plugin/provisioner.rb +1 -1
- data/lib/corl.rb +6 -14
- data/locales/en.yml +18 -1
- metadata +39 -32
- data/lib/CORL/node/google.rb +0 -111
- data/lib/core/util/ssh.rb +0 -286
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: corl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-03-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nucleon
|
16
|
-
requirement: &
|
16
|
+
requirement: &8964100 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,32 +21,32 @@ dependencies:
|
|
21
21
|
version: '0.1'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *8964100
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
27
|
-
requirement: &
|
26
|
+
name: fog
|
27
|
+
requirement: &8963100 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '1.
|
32
|
+
version: '1.20'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *8963100
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement: &
|
37
|
+
name: unf
|
38
|
+
requirement: &8962060 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: '1
|
43
|
+
version: '0.1'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *8962060
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: facter
|
49
|
-
requirement: &
|
49
|
+
requirement: &8961060 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '1.7'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *8961060
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: hiera
|
60
|
-
requirement: &
|
60
|
+
requirement: &8959780 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '1.3'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *8959780
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: puppet
|
71
|
-
requirement: &
|
71
|
+
requirement: &8957320 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '3.2'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *8957320
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: bundler
|
82
|
-
requirement: &
|
82
|
+
requirement: &8954800 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '1.2'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *8954800
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: jeweler
|
93
|
-
requirement: &
|
93
|
+
requirement: &8952820 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: '2.0'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *8952820
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: rspec
|
104
|
-
requirement: &
|
104
|
+
requirement: &8951080 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ~>
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: '2.10'
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *8951080
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: rdoc
|
115
|
-
requirement: &
|
115
|
+
requirement: &8944580 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - ~>
|
@@ -120,10 +120,10 @@ dependencies:
|
|
120
120
|
version: '3.12'
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *8944580
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: yard
|
126
|
-
requirement: &
|
126
|
+
requirement: &8943360 !ruby/object:Gem::Requirement
|
127
127
|
none: false
|
128
128
|
requirements:
|
129
129
|
- - ~>
|
@@ -131,7 +131,7 @@ dependencies:
|
|
131
131
|
version: '0.8'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
|
-
version_requirements: *
|
134
|
+
version_requirements: *8943360
|
135
135
|
description: Framework that provides a simple foundation for growing organically in
|
136
136
|
the cloud
|
137
137
|
email: adrian.webb@coralnexus.com
|
@@ -164,45 +164,52 @@ files:
|
|
164
164
|
- bootstrap/os/ubuntu/01_git.sh
|
165
165
|
- bootstrap/os/ubuntu/05_ruby.sh
|
166
166
|
- bootstrap/os/ubuntu/06_puppet.sh
|
167
|
+
- bootstrap/os/ubuntu/09_nucleon.sh
|
167
168
|
- bootstrap/os/ubuntu/10_corl.sh
|
168
169
|
- corl.gemspec
|
170
|
+
- lib/CORL/action/authorize.rb
|
169
171
|
- lib/CORL/action/bootstrap.rb
|
172
|
+
- lib/CORL/action/destroy.rb
|
170
173
|
- lib/CORL/action/exec.rb
|
171
174
|
- lib/CORL/action/image.rb
|
172
175
|
- lib/CORL/action/images.rb
|
173
176
|
- lib/CORL/action/lookup.rb
|
174
177
|
- lib/CORL/action/machines.rb
|
175
178
|
- lib/CORL/action/provision.rb
|
179
|
+
- lib/CORL/action/regions.rb
|
176
180
|
- lib/CORL/action/seed.rb
|
177
181
|
- lib/CORL/action/spawn.rb
|
182
|
+
- lib/CORL/action/ssh.rb
|
178
183
|
- lib/CORL/action/start.rb
|
179
184
|
- lib/CORL/action/stop.rb
|
180
185
|
- lib/CORL/configuration/file.rb
|
181
186
|
- lib/CORL/event/puppet.rb
|
182
187
|
- lib/CORL/extension/puppetloader.rb
|
183
|
-
- lib/CORL/machine/
|
188
|
+
- lib/CORL/machine/aws.rb
|
184
189
|
- lib/CORL/machine/physical.rb
|
190
|
+
- lib/CORL/machine/rackspace.rb
|
185
191
|
- lib/CORL/network/default.rb
|
186
192
|
- lib/CORL/node/aws.rb
|
187
|
-
- lib/CORL/node/google.rb
|
188
193
|
- lib/CORL/node/local.rb
|
189
194
|
- lib/CORL/node/rackspace.rb
|
190
195
|
- lib/CORL/provisioner/puppetnode.rb
|
191
196
|
- lib/CORL/provisioner/puppetnode/resource.rb
|
192
197
|
- lib/CORL/provisioner/puppetnode/resource_group.rb
|
193
198
|
- lib/CORL/template/environment.rb
|
199
|
+
- lib/core/errors.rb
|
194
200
|
- lib/core/facade.rb
|
195
201
|
- lib/core/mixin/action/keypair.rb
|
196
202
|
- lib/core/mixin/lookup.rb
|
203
|
+
- lib/core/mod/fog_aws_server.rb
|
197
204
|
- lib/core/mod/hiera_backend.rb
|
198
205
|
- lib/core/plugin/action.rb
|
199
206
|
- lib/core/plugin/configuration.rb
|
200
|
-
- lib/core/plugin/
|
207
|
+
- lib/core/plugin/fog_machine.rb
|
208
|
+
- lib/core/plugin/fog_node.rb
|
201
209
|
- lib/core/plugin/machine.rb
|
202
210
|
- lib/core/plugin/network.rb
|
203
211
|
- lib/core/plugin/node.rb
|
204
212
|
- lib/core/plugin/provisioner.rb
|
205
|
-
- lib/core/util/ssh.rb
|
206
213
|
- lib/corl.rb
|
207
214
|
- lib/facter/corl_config_ready.rb
|
208
215
|
- lib/facter/corl_exists.rb
|
data/lib/CORL/node/google.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
|
2
|
-
module CORL
|
3
|
-
module Node
|
4
|
-
class Google < Node::Fog
|
5
|
-
|
6
|
-
#-----------------------------------------------------------------------------
|
7
|
-
# Node plugin interface
|
8
|
-
|
9
|
-
#-----------------------------------------------------------------------------
|
10
|
-
# Checks
|
11
|
-
|
12
|
-
def usable_image?(image)
|
13
|
-
image.status == 'READY' && ! image.description.match(/DEPRECATED/i)
|
14
|
-
end
|
15
|
-
|
16
|
-
#-----------------------------------------------------------------------------
|
17
|
-
# Property accessors / modifiers
|
18
|
-
|
19
|
-
def project_name=project_name
|
20
|
-
myself[:project_name] = project_name
|
21
|
-
end
|
22
|
-
|
23
|
-
def project_name
|
24
|
-
myself[:project_name]
|
25
|
-
end
|
26
|
-
|
27
|
-
#---
|
28
|
-
|
29
|
-
def regions
|
30
|
-
[
|
31
|
-
'us-central1-a',
|
32
|
-
'us-central1-b',
|
33
|
-
'europe-west1-a',
|
34
|
-
'europe-west1-b'
|
35
|
-
]
|
36
|
-
end
|
37
|
-
|
38
|
-
#-----------------------------------------------------------------------------
|
39
|
-
# Settings groups
|
40
|
-
|
41
|
-
def machine_config
|
42
|
-
super do |config|
|
43
|
-
config.import({
|
44
|
-
:provider => 'google'
|
45
|
-
})
|
46
|
-
|
47
|
-
config[:google_project] = project_name if project_name
|
48
|
-
config[:google_client_email] = api_user if api_user
|
49
|
-
config[:google_key_location] = api_key if api_key
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
#-----------------------------------------------------------------------------
|
54
|
-
# Node operations
|
55
|
-
|
56
|
-
def create(options = {})
|
57
|
-
super do |op, config|
|
58
|
-
if op == :config
|
59
|
-
config[:private_key_path] = private_key if private_key
|
60
|
-
config[:public_key_path] = public_key if public_key
|
61
|
-
|
62
|
-
config.defaults({
|
63
|
-
:name => hostname,
|
64
|
-
:machine_type => machine_type,
|
65
|
-
:image_name => image
|
66
|
-
})
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
#-----------------------------------------------------------------------------
|
72
|
-
# Utilities
|
73
|
-
|
74
|
-
def machine_type_id(machine_type)
|
75
|
-
machine_type.name
|
76
|
-
end
|
77
|
-
|
78
|
-
#---
|
79
|
-
|
80
|
-
def render_machine_type(machine_type)
|
81
|
-
sprintf("[ %20s ][ VCPUS: %2i ] %-55s ( RAM: %6iMB | DISK: %3iGB ) ( MAX DISKS: %2i | MAX STORAGE: %6iGB )",
|
82
|
-
machine_type_id(machine_type),
|
83
|
-
machine_type.guest_cpus,
|
84
|
-
machine_type.description,
|
85
|
-
machine_type.memory_mb,
|
86
|
-
machine_type.image_space_gb,
|
87
|
-
machine_type.maximum_persistent_disks,
|
88
|
-
machine_type.maximum_persistent_disks_size
|
89
|
-
)
|
90
|
-
end
|
91
|
-
|
92
|
-
#---
|
93
|
-
|
94
|
-
def image_id(image)
|
95
|
-
image.name
|
96
|
-
end
|
97
|
-
|
98
|
-
#---
|
99
|
-
|
100
|
-
def render_image(image)
|
101
|
-
sprintf("[ %40s ][ %10s ] %s - %s", image_id(image), image.status, image.description, image.project)
|
102
|
-
end
|
103
|
-
|
104
|
-
#---
|
105
|
-
|
106
|
-
def image_search_text(image)
|
107
|
-
sprintf("%s %s %s %s", image.name, image.description, image.status, image.project)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
data/lib/core/util/ssh.rb
DELETED
@@ -1,286 +0,0 @@
|
|
1
|
-
|
2
|
-
module CORL
|
3
|
-
module Util
|
4
|
-
class SSH < Nucleon::Core
|
5
|
-
|
6
|
-
#-----------------------------------------------------------------------------
|
7
|
-
# User key home
|
8
|
-
|
9
|
-
@@key_path = nil
|
10
|
-
|
11
|
-
#---
|
12
|
-
|
13
|
-
def self.key_path
|
14
|
-
unless @@key_path
|
15
|
-
home_path = ( ENV['USER'] == 'root' ? '/root' : ENV['HOME'] ) # In case we are using sudo
|
16
|
-
@@key_path = File.join(home_path, '.ssh')
|
17
|
-
|
18
|
-
FileUtils.mkdir(@@key_path) unless File.directory?(@@key_path)
|
19
|
-
end
|
20
|
-
@@key_path
|
21
|
-
end
|
22
|
-
|
23
|
-
#-----------------------------------------------------------------------------
|
24
|
-
# Instance generators
|
25
|
-
|
26
|
-
def self.generate(options = {})
|
27
|
-
config = Config.ensure(options)
|
28
|
-
|
29
|
-
private_key = config.get(:private_key, nil)
|
30
|
-
original_key = nil
|
31
|
-
key_comment = config.get(:comment, '')
|
32
|
-
|
33
|
-
if private_key.nil?
|
34
|
-
key_type = config.get(:type, "RSA")
|
35
|
-
key_bits = config.get(:bits, 2048)
|
36
|
-
passphrase = config.get(:passphrase, nil)
|
37
|
-
|
38
|
-
key_data = SSHKey.generate(
|
39
|
-
:type => key_type,
|
40
|
-
:bits => key_bits,
|
41
|
-
:comment => key_comment,
|
42
|
-
:passphrase => passphrase
|
43
|
-
)
|
44
|
-
is_new = true
|
45
|
-
|
46
|
-
else
|
47
|
-
if private_key.include?('PRIVATE KEY')
|
48
|
-
original_key = private_key
|
49
|
-
else
|
50
|
-
original_key = Disk.read(private_key)
|
51
|
-
end
|
52
|
-
|
53
|
-
key_data = SSHKey.new(original_key, :comment => key_comment) if original_key
|
54
|
-
is_new = false
|
55
|
-
end
|
56
|
-
|
57
|
-
return nil unless key_data && ! key_data.ssh_public_key.empty?
|
58
|
-
Keypair.new(key_data, is_new, original_key)
|
59
|
-
end
|
60
|
-
|
61
|
-
#-----------------------------------------------------------------------------
|
62
|
-
# Checks
|
63
|
-
|
64
|
-
def self.valid?(public_ssh_key)
|
65
|
-
SSHKey.valid_ssh_public_key?(public_ssh_key)
|
66
|
-
end
|
67
|
-
|
68
|
-
#-----------------------------------------------------------------------------
|
69
|
-
# Keypair interface
|
70
|
-
|
71
|
-
class Keypair
|
72
|
-
attr_reader :type, :private_key, :encrypted_key, :public_key, :ssh_key
|
73
|
-
|
74
|
-
def initialize(key_data, is_new, original_key)
|
75
|
-
@type = key_data.type
|
76
|
-
@private_key = key_data.private_key
|
77
|
-
@encrypted_key = is_new ? key_data.encrypted_private_key : original_key
|
78
|
-
@public_key = key_data.public_key
|
79
|
-
@ssh_key = key_data.ssh_public_key
|
80
|
-
end
|
81
|
-
|
82
|
-
#---
|
83
|
-
|
84
|
-
def store(key_path = nil, key_base = 'id')
|
85
|
-
key_path = SSH.key_path if key_path.nil?
|
86
|
-
private_key_file = File.join(key_path, "#{key_base}_#{type.downcase}")
|
87
|
-
public_key_file = File.join(key_path, "#{key_base}_#{type.downcase}.pub")
|
88
|
-
|
89
|
-
private_success = Disk.write(private_key_file, encrypted_key)
|
90
|
-
FileUtils.chmod(0600, private_key_file) if private_success
|
91
|
-
|
92
|
-
public_success = Disk.write(public_key_file, ssh_key)
|
93
|
-
|
94
|
-
if private_success && public_success
|
95
|
-
return { :private_key => private_key_file, :public_key => public_key_file }
|
96
|
-
end
|
97
|
-
false
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
#-----------------------------------------------------------------------------
|
102
|
-
# SSH Execution interface
|
103
|
-
|
104
|
-
@@sessions = {}
|
105
|
-
|
106
|
-
#---
|
107
|
-
|
108
|
-
def self.session_id(hostname, user)
|
109
|
-
"#{hostname}-#{user}"
|
110
|
-
end
|
111
|
-
|
112
|
-
#---
|
113
|
-
|
114
|
-
def self.session(hostname, user, port = 22, private_key = nil, reset = false, options = {})
|
115
|
-
require 'net/ssh'
|
116
|
-
|
117
|
-
ssh_options = Config.new({
|
118
|
-
:user_known_hosts_file => [ File.join(key_path, 'known_hosts'), File.join(key_path, 'known_hosts2') ],
|
119
|
-
:key_data => [],
|
120
|
-
:keys_only => false,
|
121
|
-
:auth_methods => [ 'publickey' ],
|
122
|
-
:paranoid => :very
|
123
|
-
}).import(options)
|
124
|
-
|
125
|
-
ssh_options[:port] = port
|
126
|
-
ssh_options[:keys] = private_key.nil? ? [] : [ private_key ]
|
127
|
-
|
128
|
-
session_id = session_id(hostname, user)
|
129
|
-
|
130
|
-
if reset || ! @@sessions.has_key?(session_id)
|
131
|
-
@@sessions[session_id] = Net::SSH.start(hostname, user, ssh_options.export)
|
132
|
-
end
|
133
|
-
yield(@@sessions[session_id]) if block_given? && @@sessions[session_id]
|
134
|
-
@@sessions[session_id]
|
135
|
-
end
|
136
|
-
|
137
|
-
def self.init_session(hostname, user, port = 22, private_key = nil, options = {})
|
138
|
-
session(hostname, user, port, private_key, true, options)
|
139
|
-
end
|
140
|
-
|
141
|
-
#---
|
142
|
-
|
143
|
-
def self.close(hostname = nil, user = nil)
|
144
|
-
if hostname && user.nil? # Assume we entered a session id
|
145
|
-
if @@sessions.has_key?(hostname)
|
146
|
-
@@sessions[hostname].close
|
147
|
-
@@sessions.delete(hostname)
|
148
|
-
end
|
149
|
-
|
150
|
-
elsif hostname && user # Generate session id from args
|
151
|
-
session_id = session_id(hostname, user)
|
152
|
-
|
153
|
-
if @@sessions.has_key?(session_id)
|
154
|
-
@@sessions[session_id].close
|
155
|
-
@@sessions.delete(session_id)
|
156
|
-
end
|
157
|
-
|
158
|
-
else # Close all connections
|
159
|
-
@@sessions.keys.each do |id|
|
160
|
-
@@sessions[id].close
|
161
|
-
@@sessions.delete(id)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
#---
|
167
|
-
|
168
|
-
def self.exec(hostname, user, commands)
|
169
|
-
results = []
|
170
|
-
|
171
|
-
begin
|
172
|
-
session(hostname, user) do |ssh|
|
173
|
-
Data.array(commands).each do |command|
|
174
|
-
command = command.flatten.join(' ') if command.is_a?(Array)
|
175
|
-
command = command.to_s
|
176
|
-
result = Shell::Result.new(command)
|
177
|
-
|
178
|
-
ssh.open_channel do |ssh_channel|
|
179
|
-
ssh_channel.request_pty
|
180
|
-
ssh_channel.exec(command) do |channel, success|
|
181
|
-
unless success
|
182
|
-
raise "Could not execute command: #{command.inspect}"
|
183
|
-
end
|
184
|
-
|
185
|
-
channel.on_data do |ch, data|
|
186
|
-
result.append_output(data)
|
187
|
-
yield(:output, command, data) if block_given?
|
188
|
-
end
|
189
|
-
|
190
|
-
channel.on_extended_data do |ch, type, data|
|
191
|
-
next unless type == 1
|
192
|
-
result.append_errors(data)
|
193
|
-
yield(:error, command, data) if block_given?
|
194
|
-
end
|
195
|
-
|
196
|
-
channel.on_request('exit-status') do |ch, data|
|
197
|
-
result.status = data.read_long
|
198
|
-
end
|
199
|
-
|
200
|
-
channel.on_request('exit-signal') do |ch, data|
|
201
|
-
result.status = 255
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
ssh.loop
|
206
|
-
results << result
|
207
|
-
end
|
208
|
-
end
|
209
|
-
rescue Net::SSH::HostKeyMismatch => error
|
210
|
-
error.remember_host!
|
211
|
-
sleep 0.2
|
212
|
-
retry
|
213
|
-
end
|
214
|
-
results
|
215
|
-
end
|
216
|
-
|
217
|
-
#---
|
218
|
-
|
219
|
-
def self.download(hostname, user, remote_path, local_path, options = {})
|
220
|
-
config = Config.ensure(options)
|
221
|
-
|
222
|
-
require 'net/scp'
|
223
|
-
|
224
|
-
# Accepted options:
|
225
|
-
# * :recursive - the +remote+ parameter refers to a remote directory, which
|
226
|
-
# should be downloaded to a new directory named +local+ on the local
|
227
|
-
# machine.
|
228
|
-
# * :preserve - the atime and mtime of the file should be preserved.
|
229
|
-
# * :verbose - the process should result in verbose output on the server
|
230
|
-
# end (useful for debugging).
|
231
|
-
#
|
232
|
-
config.init(:recursive, true)
|
233
|
-
config.init(:preserve, true)
|
234
|
-
config.init(:verbose, true)
|
235
|
-
|
236
|
-
blocking = config.delete(:blocking, true)
|
237
|
-
|
238
|
-
session(hostname, user) do |ssh|
|
239
|
-
if blocking
|
240
|
-
ssh.scp.download!(remote_path, local_path, config.export) do |ch, name, received, total|
|
241
|
-
yield(name, received, total) if block_given?
|
242
|
-
end
|
243
|
-
else
|
244
|
-
ssh.scp.download(remote_path, local_path, config.export)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
#---
|
250
|
-
|
251
|
-
def self.upload(hostname, user, local_path, remote_path, options = {})
|
252
|
-
config = Config.ensure(options)
|
253
|
-
|
254
|
-
require 'net/scp'
|
255
|
-
|
256
|
-
# Accepted options:
|
257
|
-
# * :recursive - the +local+ parameter refers to a local directory, which
|
258
|
-
# should be uploaded to a new directory named +remote+ on the remote
|
259
|
-
# server.
|
260
|
-
# * :preserve - the atime and mtime of the file should be preserved.
|
261
|
-
# * :verbose - the process should result in verbose output on the server
|
262
|
-
# end (useful for debugging).
|
263
|
-
# * :chunk_size - the size of each "chunk" that should be sent. Defaults
|
264
|
-
# to 2048. Changing this value may improve throughput at the expense
|
265
|
-
# of decreasing interactivity.
|
266
|
-
#
|
267
|
-
config.init(:recursive, true)
|
268
|
-
config.init(:preserve, true)
|
269
|
-
config.init(:verbose, true)
|
270
|
-
config.init(:chunk_size, 2048)
|
271
|
-
|
272
|
-
blocking = config.delete(:blocking, true)
|
273
|
-
|
274
|
-
session(hostname, user) do |ssh|
|
275
|
-
if blocking
|
276
|
-
ssh.scp.upload!(local_path, remote_path, config.export) do |ch, name, sent, total|
|
277
|
-
yield(name, sent, total) if block_given?
|
278
|
-
end
|
279
|
-
else
|
280
|
-
ssh.scp.upload(local_path, remote_path, config.export)
|
281
|
-
end
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|