mobilize-ssh 1.361 → 1.363

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.
@@ -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.pop_comm_dir(comm_dir,file_hash)
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 = "#{comm_dir}/#{fname}"
9
+ fpath = "#{loc_dir}/#{fname}"
8
10
  #for now, only gz is binary
9
- binary = fname.ends_with?(".gz") ? true : false
10
- #read data from cache, put it in a tmp_file
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 true if file_hash.keys.length>0
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
- #populate comm dir with any files
85
- Ssh.pop_comm_dir(comm_dir,file_hash)
86
- #make sure user starts in rem_dir
87
- rem_dir = "#{comm_md5}/"
88
- #make sure the rem_dir is gone
89
- Ssh.fire!(node,"sudo rm -rf #{rem_dir}")
90
- if File.exists?(comm_dir)
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
- Ssh.fire!(node,rm_cmd)
115
- result
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? and Ssh.su_all_users(node)
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
@@ -1,5 +1,5 @@
1
1
  module Mobilize
2
2
  module Ssh
3
- VERSION = "1.361"
3
+ VERSION = "1.363"
4
4
  end
5
5
  end
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.361"
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.361'
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-05-31 00:00:00.000000000 Z
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.361'
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.361'
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: -3139478933470599366
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: -3139478933470599366
133
+ hash: 4500700013252989723
134
134
  requirements: []
135
135
  rubyforge_project:
136
136
  rubygems_version: 1.8.25