mobilize-ssh 1.361 → 1.363
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mobilize-ssh/handlers/ssh.rb +57 -44
- data/lib/mobilize-ssh/helpers/ssh_helper.rb +9 -4
- data/lib/mobilize-ssh/version.rb +1 -1
- data/lib/samples/ssh.yml +2 -0
- data/mobilize-ssh.gemspec +1 -1
- data/test/fixtures/integration_jobs.yml +4 -4
- data/test/integration/mobilize-ssh_test.rb +1 -1
- metadata +6 -6
@@ -2,15 +2,44 @@ module Mobilize
|
|
2
2
|
module Ssh
|
3
3
|
#adds convenience methods
|
4
4
|
require "#{File.dirname(__FILE__)}/../helpers/ssh_helper"
|
5
|
-
def Ssh.
|
5
|
+
def Ssh.pop_loc_dir(unique_name,file_hash)
|
6
|
+
loc_dir = "/tmp/#{unique_name}"
|
7
|
+
`rm -rf #{loc_dir} && mkdir -p #{loc_dir}`
|
6
8
|
file_hash.each do |fname,fdata|
|
7
|
-
fpath = "#{
|
9
|
+
fpath = "#{loc_dir}/#{fname}"
|
8
10
|
#for now, only gz is binary
|
9
|
-
|
10
|
-
|
11
|
-
Ssh.tmp_file(fdata,binary,fpath)
|
11
|
+
mode = fname.ends_with?(".gz") ? "wb" : "w"
|
12
|
+
File.open(fpath,mode) {|f| f.print(fdata)}
|
12
13
|
end
|
13
|
-
return
|
14
|
+
return loc_dir if file_hash.keys.length>0
|
15
|
+
end
|
16
|
+
|
17
|
+
def Ssh.deploy(node,user_name,unique_name,command,file_hash)
|
18
|
+
loc_dir = Ssh.pop_loc_dir(unique_name,file_hash)
|
19
|
+
Ssh.fire!(node,"rm -rf #{unique_name} && mkdir -p #{unique_name} && chown -R #{Ssh.node_owner(node)} #{unique_name}")
|
20
|
+
if loc_dir
|
21
|
+
Ssh.scp(node,loc_dir,".")
|
22
|
+
#make sure loc_dir is removed
|
23
|
+
FileUtils.rm_r(loc_dir,:force=>true)
|
24
|
+
end
|
25
|
+
#create cmd_file in unique_name
|
26
|
+
cmd_path = "#{unique_name}/cmd.sh"
|
27
|
+
Ssh.write(node,command,cmd_path)
|
28
|
+
#move folder to user's home, change ownership
|
29
|
+
user_dir = "/home/#{user_name}/"
|
30
|
+
mobilize_dir = "#{user_dir}mobilize/"
|
31
|
+
deploy_dir = "#{mobilize_dir}#{unique_name}/"
|
32
|
+
deploy_cmd_path = "#{deploy_dir}cmd.sh"
|
33
|
+
deploy_cmd = "sudo mkdir -p #{mobilize_dir} && " +
|
34
|
+
"sudo rm -rf #{mobilize_dir}#{unique_name} && " +
|
35
|
+
"sudo mv #{unique_name} #{mobilize_dir} && " +
|
36
|
+
"sudo chown -R #{user_name} #{mobilize_dir}"
|
37
|
+
Ssh.fire!(node,deploy_cmd)
|
38
|
+
#need to use bash or we get no tee
|
39
|
+
full_cmd = "/bin/bash -l -c '(cd #{deploy_dir} && sh #{deploy_cmd_path} > >(tee stdout) 2> >(tee stderr >&2))'"
|
40
|
+
#fire_cmd runs sh on cmd_path, optionally with sudo su
|
41
|
+
fire_cmd = %{sudo su #{user_name} -c "#{full_cmd}"}
|
42
|
+
return fire_cmd
|
14
43
|
end
|
15
44
|
|
16
45
|
# converts a source path or target path to a dst in the context of handler and stage
|
@@ -67,13 +96,9 @@ module Mobilize
|
|
67
96
|
return true
|
68
97
|
end
|
69
98
|
|
70
|
-
def Ssh.run(node,command,user_name,file_hash={},run_params=nil)
|
71
|
-
default_user_name = Ssh.host(node)['user']
|
99
|
+
def Ssh.run(node,command,user_name,stage_path=nil,file_hash={},run_params=nil)
|
72
100
|
file_hash ||= {}
|
73
101
|
run_params ||={}
|
74
|
-
#make sure the dir for this command is clear
|
75
|
-
comm_md5 = [user_name,node,command,file_hash.keys.to_s,Time.now.to_f.to_s].join.to_md5
|
76
|
-
comm_dir = Dir.mktmpdir
|
77
102
|
#replace any params in the file_hash and command
|
78
103
|
run_params.each do |k,v|
|
79
104
|
command.gsub!("@#{k}",v)
|
@@ -81,41 +106,25 @@ module Mobilize
|
|
81
106
|
data.gsub!("@#{k}",v)
|
82
107
|
end
|
83
108
|
end
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
Ssh.scp(node,comm_dir,rem_dir)
|
92
|
-
#make sure comm_dir is removed
|
93
|
-
FileUtils.rm_r(comm_dir,:force=>true)
|
94
|
-
else
|
95
|
-
#create folder
|
96
|
-
mkdir_command = "mkdir #{rem_dir}"
|
97
|
-
Ssh.fire!(node,mkdir_command)
|
98
|
-
end
|
99
|
-
#create cmd_file in rem_folder
|
100
|
-
cmd_file = "#{comm_md5}.sh"
|
101
|
-
cmd_path = "#{rem_dir}#{cmd_file}"
|
102
|
-
Ssh.write(node,command,cmd_path)
|
103
|
-
full_cmd = "(cd #{rem_dir} && sh #{cmd_file})"
|
104
|
-
#fire_cmd runs sh on cmd_path, optionally with sudo su
|
105
|
-
if user_name != default_user_name
|
106
|
-
#make sure user owns the folder and all files
|
107
|
-
fire_cmd = %{sudo chown -R #{user_name} #{rem_dir}; sudo su #{user_name} -c "#{full_cmd}"}
|
108
|
-
rm_cmd = %{sudo rm -rf #{rem_dir}}
|
109
|
-
else
|
110
|
-
fire_cmd = full_cmd
|
111
|
-
rm_cmd = "rm -rf #{rem_dir}"
|
112
|
-
end
|
109
|
+
#make sure the dir for this command is unique
|
110
|
+
unique_name = if stage_path
|
111
|
+
stage_path.downcase.alphanunderscore
|
112
|
+
else
|
113
|
+
[user_name,node,command,file_hash.keys.to_s,Time.now.to_f.to_s].join.to_md5
|
114
|
+
end
|
115
|
+
fire_cmd = Ssh.deploy(node, user_name, unique_name, command, file_hash)
|
113
116
|
result = Ssh.fire!(node,fire_cmd)
|
114
|
-
|
115
|
-
|
117
|
+
#clear out the md5 folders and those not requested to keep
|
118
|
+
s = Stage.find_by_path(stage_path) if stage_path
|
119
|
+
unless s and s.params['keep_logs']
|
120
|
+
rm_cmd = "sudo rm -rf /home/#{user_name}/mobilize/#{unique_name}"
|
121
|
+
Ssh.fire!(node,rm_cmd)
|
122
|
+
end
|
123
|
+
return result
|
116
124
|
end
|
117
125
|
|
118
126
|
def Ssh.fire!(node,cmd)
|
127
|
+
puts "#{Time.now.utc}--Ssh on #{node}: #{cmd}"
|
119
128
|
name,key,port,user = Ssh.host(node).ie{|h| ['name','key','port','user'].map{|k| h[k]}}
|
120
129
|
key_path = "#{Base.root}/#{key}"
|
121
130
|
opts = {:port=>(port || 22),:keys=>key_path}
|
@@ -169,7 +178,7 @@ module Mobilize
|
|
169
178
|
node = Ssh.default_node unless Ssh.nodes.include?(node)
|
170
179
|
if user_name and !Ssh.sudoers(node).include?(u.name)
|
171
180
|
raise "#{u.name} does not have su permissions for this node"
|
172
|
-
elsif user_name.nil?
|
181
|
+
elsif user_name.nil?
|
173
182
|
user_name = u.name
|
174
183
|
end
|
175
184
|
return user_name
|
@@ -213,10 +222,14 @@ module Mobilize
|
|
213
222
|
node, command = [params['node'],params['cmd']]
|
214
223
|
node ||= Ssh.default_node
|
215
224
|
user_name = Ssh.user_name_by_stage_path(stage_path)
|
225
|
+
#do not allow server commands from non-sudoers for the special server node
|
226
|
+
if node=='server' and !Ssh.sudoers(node).include?(user_name)
|
227
|
+
raise "You do not have permission to run commands on the mobilize server"
|
228
|
+
end
|
216
229
|
file_hash = Ssh.file_hash_by_stage_path(stage_path,gdrive_slot)
|
217
230
|
Gdrive.unslot_worker_by_path(stage_path)
|
218
231
|
run_params = params['params']
|
219
|
-
result = Ssh.run(node,command,user_name,file_hash,run_params)
|
232
|
+
result = Ssh.run(node,command,user_name,stage_path,file_hash,run_params)
|
220
233
|
#use Gridfs to cache result
|
221
234
|
response = {}
|
222
235
|
response['out_url'] = Dataset.write_by_url("gridfs://#{s.path}/out",result['stdout'].to_s,Gdrive.owner_name)
|
@@ -16,10 +16,6 @@ module Mobilize
|
|
16
16
|
self.config['nodes'][node]['sudoers']
|
17
17
|
end
|
18
18
|
|
19
|
-
def self.su_all_users(node)
|
20
|
-
self.config['nodes'][node]['su_all_users']
|
21
|
-
end
|
22
|
-
|
23
19
|
def self.nodes
|
24
20
|
self.config['nodes'].keys
|
25
21
|
end
|
@@ -28,8 +24,17 @@ module Mobilize
|
|
28
24
|
self.nodes.first
|
29
25
|
end
|
30
26
|
|
27
|
+
def self.node_owner(node)
|
28
|
+
self.host(node)['user']
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.skip_gateway?(node)
|
32
|
+
self.config['nodes'][node]['skip_gateway']
|
33
|
+
end
|
34
|
+
|
31
35
|
#determine if current machine is on host domain, needs gateway if one is provided and it is not
|
32
36
|
def self.needs_gateway?(node)
|
37
|
+
return false if self.skip_gateway?(node)
|
33
38
|
host_domain_name = self.host(node)['name'].split(".")[-2..-1].join(".")
|
34
39
|
return true if self.gateway(node) and Socket.domain_name != host_domain_name
|
35
40
|
end
|
data/lib/mobilize-ssh/version.rb
CHANGED
data/lib/samples/ssh.yml
CHANGED
@@ -23,11 +23,13 @@ test:
|
|
23
23
|
su_all_users: true
|
24
24
|
host:
|
25
25
|
name: test-host.com
|
26
|
+
skip_gateway: true
|
26
27
|
key: config/mobilize/ssh_private.key
|
27
28
|
port: 22
|
28
29
|
user: host_user
|
29
30
|
gateway:
|
30
31
|
name: test-gateway.com
|
32
|
+
skip_gateway: true
|
31
33
|
key: config/mobilize/ssh_private.key
|
32
34
|
port: 22
|
33
35
|
user: gateway_user
|
data/mobilize-ssh.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
|
-
gem.add_runtime_dependency "mobilize-base","1.
|
19
|
+
gem.add_runtime_dependency "mobilize-base","1.363"
|
20
20
|
gem.add_runtime_dependency "net-ssh"
|
21
21
|
gem.add_runtime_dependency "net-scp"
|
22
22
|
gem.add_runtime_dependency "net-ssh-gateway"
|
@@ -3,23 +3,23 @@
|
|
3
3
|
active: true
|
4
4
|
trigger: once
|
5
5
|
status: ""
|
6
|
-
stage1: ssh.run node:"test_node", cmd:"ruby code.rb", user:"root", sources:["code.rb", "code.sh"]
|
6
|
+
stage1: ssh.run keep_logs:true, node:"test_node", cmd:"ruby code.rb", user:"root", sources:["code.rb", "code.sh"]
|
7
7
|
stage2: gsheet.write source:"stage1", target:"ssh1.out"
|
8
8
|
- name: ssh2
|
9
9
|
active: true
|
10
10
|
trigger: "after ssh1"
|
11
11
|
status: ""
|
12
|
-
stage1: ssh.run cmd:"sh code2.sh", user:"root", sources:["code2.sh","test_node/var/log/syslog"], params:{file:"syslog"}
|
12
|
+
stage1: ssh.run keep_logs:true, cmd:"sh code2.sh", user:"root", sources:["code2.sh","test_node/var/log/syslog"], params:{file:"syslog"}
|
13
13
|
stage2: gsheet.write source:"stage1", target:"ssh2.out"
|
14
14
|
- name: ssh3
|
15
15
|
active: true
|
16
16
|
trigger: "after ssh2"
|
17
17
|
status: ""
|
18
|
-
stage1: ssh.run cmd:"echo '@test_param'", params:{test_param:"test param successful"}
|
18
|
+
stage1: ssh.run keep_logs:true, cmd:"echo '@test_param'", params:{test_param:"test param successful"}
|
19
19
|
stage2: gsheet.write source:"stage1", target:"ssh3.out"
|
20
20
|
- name: ssh4
|
21
21
|
active: true
|
22
22
|
trigger: "after ssh3"
|
23
23
|
status: ""
|
24
|
-
stage1: ssh.run node:"test_node", user:root, sources:["git://DeNA/mobilize-ssh/test/fixtures/code.rb","git://DeNA/mobilize-ssh/test/fixtures/code.sh"], cmd:"ruby code.rb"
|
24
|
+
stage1: ssh.run keep_logs:true, node:"test_node", user:root, sources:["git://DeNA/mobilize-ssh/test/fixtures/code.rb","git://DeNA/mobilize-ssh/test/fixtures/code.sh"], cmd:"ruby code.rb"
|
25
25
|
stage2: gsheet.write source:stage1, target:"ssh4.out"
|
@@ -18,7 +18,7 @@ describe "Mobilize" do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
puts "add/update jobs"
|
21
|
-
u.jobs.each{|j| j.delete}
|
21
|
+
u.jobs.each{|j| j.stages.each{|s| s.delete}; j.delete}
|
22
22
|
jobs_fixture_name = "integration_jobs"
|
23
23
|
jobs_target_url = "gsheet://#{r.title}/jobs"
|
24
24
|
TestHelper.write_fixture(jobs_fixture_name, jobs_target_url, 'update')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mobilize-ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.363'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mobilize-base
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '1.
|
21
|
+
version: '1.363'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - '='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '1.
|
29
|
+
version: '1.363'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: net-ssh
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,7 +121,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
121
|
version: '0'
|
122
122
|
segments:
|
123
123
|
- 0
|
124
|
-
hash:
|
124
|
+
hash: 4500700013252989723
|
125
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
126
|
none: false
|
127
127
|
requirements:
|
@@ -130,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
130
|
version: '0'
|
131
131
|
segments:
|
132
132
|
- 0
|
133
|
-
hash:
|
133
|
+
hash: 4500700013252989723
|
134
134
|
requirements: []
|
135
135
|
rubyforge_project:
|
136
136
|
rubygems_version: 1.8.25
|