mobilize-ssh 1.0.95 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +11 -6
- data/lib/mobilize-ssh/handlers/ssh.rb +24 -39
- data/lib/mobilize-ssh/tasks.rb +1 -0
- data/lib/mobilize-ssh/version.rb +1 -1
- data/lib/samples/ssh.yml +3 -0
- data/mobilize-ssh.gemspec +1 -1
- data/test/mobilize-ssh_test.rb +4 -4
- data/test/ssh_job_rows.yml +3 -3
- metadata +4 -4
data/README.md
CHANGED
@@ -84,14 +84,15 @@ over to the nodes. They will be deleted afterwards, unless the job
|
|
84
84
|
fails in mid-copy. By default this is tmp/file/.
|
85
85
|
* nodes, identified by aliases, such as `test_node`. This alias is what you should
|
86
86
|
pass into the "node" param over in the ssh.run task.
|
87
|
+
* default_node is where commands will be executed if no node is specified.
|
87
88
|
|
88
89
|
Each node has:
|
89
90
|
* a host;
|
90
91
|
* a gateway (optional); If you don't need a gateway, remove that row from the configuration file.
|
91
|
-
* sudoers; these are user names that are allowed to pass
|
92
|
+
* sudoers; these are user names that are allowed to pass user params
|
92
93
|
to the run call. This requires passwordless sudo for the host user.
|
93
94
|
* su_all_users true/false option, which ensures that commands are executed by the
|
94
|
-
user on the Runner. It prefixes all commands with sudo su <
|
95
|
+
user on the Runner. It prefixes all commands with sudo su <user> before executing the
|
95
96
|
command. This is strongly recommended if possible as it ensures users do
|
96
97
|
not overstep their permissions. This requires passwordless sudo for the
|
97
98
|
host user and accounts on the host machine for each user.
|
@@ -109,6 +110,7 @@ Sample ssh.yml:
|
|
109
110
|
---
|
110
111
|
development:
|
111
112
|
tmp_file_dir: tmp/file/
|
113
|
+
default_node: dev_node
|
112
114
|
nodes:
|
113
115
|
dev_node:
|
114
116
|
sudoers:
|
@@ -126,6 +128,7 @@ development:
|
|
126
128
|
user: gateway_user
|
127
129
|
test:
|
128
130
|
tmp_file_dir: tmp/file/
|
131
|
+
default_node: test_node
|
129
132
|
nodes:
|
130
133
|
test_node:
|
131
134
|
sudoers:
|
@@ -143,6 +146,7 @@ test:
|
|
143
146
|
user: gateway_user
|
144
147
|
production:
|
145
148
|
tmp_file_dir: tmp/file/
|
149
|
+
default_node: prod_node
|
146
150
|
nodes:
|
147
151
|
prod_node:
|
148
152
|
sudoers:
|
@@ -168,12 +172,13 @@ Start
|
|
168
172
|
### Create Job
|
169
173
|
|
170
174
|
* For mobilize-ssh, the following task is available:
|
171
|
-
* ssh.run `node: <node_alias>, cmd: <command>,
|
175
|
+
* ssh.run `node: <node_alias>, cmd: <command>, user: user, sources:[*<gsheet_full_paths>]`, which reads
|
172
176
|
all gsheets, copies them to a temporary folder on the selected node, and
|
173
177
|
runs the command inside that folder.
|
174
|
-
*
|
175
|
-
will cause the command to be prefixed with sudo su <
|
176
|
-
*
|
178
|
+
* user, sources, and node are optional; cmd is required.
|
179
|
+
* specifying user will cause the command to be prefixed with sudo su <user> -c.
|
180
|
+
* not specifying node will cause the command to be run on the default_node
|
181
|
+
* The test uses `ssh.run node:"test_node", cmd:"ruby code.rb", user: "root", sources:["Runner_mobilize(test)/code.rb","Runner_mobilize(test)/code.sh"]`
|
177
182
|
|
178
183
|
<a name='section_Start_Run_Test'></a>
|
179
184
|
### Run Test
|
@@ -24,6 +24,10 @@ module Mobilize
|
|
24
24
|
Ssh.config['nodes'][node]['su_all_users']
|
25
25
|
end
|
26
26
|
|
27
|
+
def Ssh.default_node
|
28
|
+
Ssh.config['default_node']
|
29
|
+
end
|
30
|
+
|
27
31
|
#determine if current machine is on host domain, needs gateway if one is provided and it is not
|
28
32
|
def Ssh.needs_gateway?(node)
|
29
33
|
host_domain_name = Ssh.host(node)['name'].split(".")[-2..-1].join(".")
|
@@ -67,14 +71,13 @@ module Mobilize
|
|
67
71
|
return true
|
68
72
|
end
|
69
73
|
|
70
|
-
def Ssh.run(node,command,file_hash=
|
71
|
-
key,
|
74
|
+
def Ssh.run(node,command,user,file_hash={})
|
75
|
+
key,default_user = Ssh.host(node).ie{|h| ['key','user'].map{|k| h[k]}}
|
72
76
|
key_path = "#{Base.root}/#{key}"
|
73
77
|
Ssh.set_key_permissions(key_path)
|
74
|
-
su_user ||= user
|
75
78
|
file_hash ||= {}
|
76
79
|
#make sure the dir for this command is clear
|
77
|
-
comm_md5 = [
|
80
|
+
comm_md5 = [user,node,command,file_hash.keys.to_s].join.to_md5
|
78
81
|
comm_dir = "#{Ssh.tmp_file_dir}#{comm_md5}"
|
79
82
|
#populate comm dir with any files
|
80
83
|
Ssh.pop_comm_dir(comm_dir,file_hash)
|
@@ -98,8 +101,8 @@ module Mobilize
|
|
98
101
|
Ssh.write(node,command,cmd_path)
|
99
102
|
full_cmd = "(cd #{rem_dir} && sh #{cmd_file})"
|
100
103
|
#fire_cmd runs sh on cmd_path, optionally with sudo su
|
101
|
-
fire_cmd = if
|
102
|
-
%{sudo su #{
|
104
|
+
fire_cmd = if user != default_user
|
105
|
+
%{sudo su #{user} -c "#{full_cmd}"}
|
103
106
|
else
|
104
107
|
full_cmd
|
105
108
|
end
|
@@ -149,47 +152,29 @@ module Mobilize
|
|
149
152
|
return tmp_file_path
|
150
153
|
end
|
151
154
|
|
152
|
-
def Ssh.file_hash_by_stage_path(stage_path)
|
153
|
-
#this is not meant to be called directly
|
154
|
-
#from the Runner -- it's used by run_by_stage_path
|
155
|
-
s = Stage.where(:path=>stage_path).first
|
156
|
-
params = s.params
|
157
|
-
gsheet_paths = if params['sources']
|
158
|
-
params['sources']
|
159
|
-
elsif params['source']
|
160
|
-
[params['source']]
|
161
|
-
end
|
162
|
-
if gsheet_paths and gsheet_paths.length>0
|
163
|
-
gdrive_slot = Gdrive.slot_worker_by_path(stage_path)
|
164
|
-
file_hash = {}
|
165
|
-
gsheet_paths.map do |gpath|
|
166
|
-
string = Gsheet.find_by_path(gpath,gdrive_slot).to_tsv
|
167
|
-
fname = gpath.split("/").last
|
168
|
-
{fname => string}
|
169
|
-
end.each do |f|
|
170
|
-
file_hash = f.merge(file_hash)
|
171
|
-
end
|
172
|
-
Gdrive.unslot_worker_by_path(stage_path)
|
173
|
-
return file_hash
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
155
|
def Ssh.run_by_stage_path(stage_path)
|
178
156
|
s = Stage.where(:path=>stage_path).first
|
179
157
|
u = s.job.runner.user
|
180
158
|
params = s.params
|
181
159
|
node, command = [params['node'],params['cmd']]
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
160
|
+
node ||= Ssh.default_node
|
161
|
+
gdrive_slot = Gdrive.slot_worker_by_path(s.path)
|
162
|
+
file_hash = {}
|
163
|
+
s.source_dsts(gdrive_slot).each do |sdst|
|
164
|
+
file_name = sdst.path.split("/").last
|
165
|
+
file_hash[file_name] = sdst.read(u.name)
|
166
|
+
end
|
167
|
+
Gdrive.unslot_worker_by_path(s.path)
|
168
|
+
user = s.params['user']
|
169
|
+
if user and !Ssh.sudoers(node).include?(u.name)
|
170
|
+
raise "#{u.name} does not have su permissions for this node"
|
171
|
+
elsif user.nil? and Ssh.su_all_users(node)
|
172
|
+
user = u.name
|
188
173
|
end
|
189
|
-
out_tsv = Ssh.run(node,command,file_hash
|
174
|
+
out_tsv = Ssh.run(node,command,user,file_hash)
|
190
175
|
#use Gridfs to cache result
|
191
176
|
out_url = "gridfs://#{s.path}/out"
|
192
|
-
Dataset.
|
177
|
+
Dataset.write_by_url(out_url,out_tsv,Gdrive.owner_name)
|
193
178
|
end
|
194
179
|
end
|
195
180
|
end
|
data/lib/mobilize-ssh/tasks.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
namespace :mobilize_ssh do
|
2
2
|
desc "Set up config and log folders and files"
|
3
3
|
task :setup do
|
4
|
+
require 'yaml'
|
4
5
|
sample_dir = File.dirname(__FILE__) + '/../samples/'
|
5
6
|
sample_files = Dir.entries(sample_dir)
|
6
7
|
config_dir = (ENV['MOBILIZE_CONFIG_DIR'] ||= "config/mobilize/")
|
data/lib/mobilize-ssh/version.rb
CHANGED
data/lib/samples/ssh.yml
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
---
|
2
2
|
development:
|
3
3
|
tmp_file_dir: tmp/file/
|
4
|
+
default_node: dev_node
|
4
5
|
nodes:
|
5
6
|
dev_node:
|
6
7
|
sudoers:
|
@@ -18,6 +19,7 @@ development:
|
|
18
19
|
user: gateway_user
|
19
20
|
test:
|
20
21
|
tmp_file_dir: tmp/file/
|
22
|
+
default_node: test_node
|
21
23
|
nodes:
|
22
24
|
test_node:
|
23
25
|
sudoers:
|
@@ -35,6 +37,7 @@ test:
|
|
35
37
|
user: gateway_user
|
36
38
|
production:
|
37
39
|
tmp_file_dir: tmp/file/
|
40
|
+
default_node: prod_node
|
38
41
|
nodes:
|
39
42
|
prod_node:
|
40
43
|
sudoers:
|
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.0
|
19
|
+
gem.add_runtime_dependency "mobilize-base","1.1.0"
|
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"
|
data/test/mobilize-ssh_test.rb
CHANGED
@@ -14,8 +14,8 @@ describe "Mobilize" do
|
|
14
14
|
|
15
15
|
gdrive_slot = Mobilize::Gdrive.owner_email
|
16
16
|
puts "create user 'mobilize'"
|
17
|
-
|
18
|
-
u = Mobilize::User.where(:name=>
|
17
|
+
user = gdrive_slot.split("@").first
|
18
|
+
u = Mobilize::User.where(:name=>user).first
|
19
19
|
r = u.runner
|
20
20
|
|
21
21
|
rb_code_sheet = Mobilize::Gsheet.find_by_path("#{r.path.split("/")[0..-2].join("/")}/code.rb",gdrive_slot)
|
@@ -25,11 +25,11 @@ describe "Mobilize" do
|
|
25
25
|
puts "add test code"
|
26
26
|
rb_code_sheet = Mobilize::Gsheet.find_or_create_by_path("#{r.path.split("/")[0..-2].join("/")}/code.rb",gdrive_slot)
|
27
27
|
rb_code_tsv = File.open("#{Mobilize::Base.root}/test/code.rb").read
|
28
|
-
rb_code_sheet.write(rb_code_tsv)
|
28
|
+
rb_code_sheet.write(rb_code_tsv,Mobilize::Gdrive.owner_name)
|
29
29
|
|
30
30
|
sh_code_sheet = Mobilize::Gsheet.find_or_create_by_path("#{r.path.split("/")[0..-2].join("/")}/code.sh",gdrive_slot)
|
31
31
|
sh_code_tsv = File.open("#{Mobilize::Base.root}/test/code.sh").read
|
32
|
-
sh_code_sheet.write(sh_code_tsv)
|
32
|
+
sh_code_sheet.write(sh_code_tsv,Mobilize::Gdrive.owner_name)
|
33
33
|
|
34
34
|
jobs_sheet = r.gsheet(gdrive_slot)
|
35
35
|
|
data/test/ssh_job_rows.yml
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
active: true
|
3
3
|
trigger: once
|
4
4
|
status: ""
|
5
|
-
stage1: 'ssh.run node:"test_node", cmd:"ruby code.rb",
|
5
|
+
stage1: 'ssh.run node:"test_node", cmd:"ruby code.rb", user:"root", sources:["Runner_mobilize(test)/code.rb", "Runner_mobilize(test)/code.sh"]'
|
6
6
|
stage2: 'gsheet.write source:"stage1", target:"Runner_mobilize(test)/test_ssh_1.out"'
|
7
7
|
- name: test_ssh_2
|
8
8
|
active: true
|
9
9
|
trigger: "after test_ssh_1"
|
10
10
|
status: ""
|
11
|
-
stage1: 'ssh.run
|
11
|
+
stage1: 'ssh.run cmd:"sh code.sh", user:"root", source:"Runner_mobilize(test)/code.sh"'
|
12
12
|
stage2: 'gsheet.write source:"stage1", target:"Runner_mobilize(test)/test_ssh_2.out"'
|
13
13
|
- name: test_ssh_3
|
14
14
|
active: true
|
15
15
|
trigger: "after test_ssh_2"
|
16
16
|
status: ""
|
17
|
-
stage1: 'ssh.run
|
17
|
+
stage1: 'ssh.run cmd:"whoami"'
|
18
18
|
stage2: 'gsheet.write source:"stage1", target:"Runner_mobilize(test)/test_ssh_3.out"'
|
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.0
|
4
|
+
version: 1.1.0
|
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-01-
|
12
|
+
date: 2013-01-18 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.0
|
21
|
+
version: 1.1.0
|
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.0
|
29
|
+
version: 1.1.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: net-ssh
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|