mobilize-ssh 1.297 → 1.298
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.
- data/README.md +56 -6
- data/lib/mobilize-ssh/handlers/git.rb +111 -0
- data/lib/mobilize-ssh/handlers/ssh.rb +21 -66
- data/lib/mobilize-ssh/helpers/ssh_helper.rb +45 -0
- data/lib/mobilize-ssh/version.rb +1 -1
- data/lib/mobilize-ssh.rb +1 -0
- data/mobilize-ssh.gemspec +1 -1
- data/test/mobilize-ssh_test.rb +5 -2
- data/test/ssh_job_rows.yml +7 -0
- metadata +8 -6
data/README.md
CHANGED
@@ -13,6 +13,7 @@ Table Of Contents
|
|
13
13
|
* [Install Dirs and Files](#section_Install_Dirs_and_Files)
|
14
14
|
* [Configure](#section_Configure)
|
15
15
|
* [Ssh](#section_Configure_Ssh)
|
16
|
+
* [Git](#section_Configure_Git)
|
16
17
|
* [Start](#section_Start)
|
17
18
|
* [Create Job](#section_Start_Create_Job)
|
18
19
|
* [Run Test](#section_Start_Run_Test)
|
@@ -79,9 +80,6 @@ Configure
|
|
79
80
|
### Configure Ssh
|
80
81
|
|
81
82
|
The Ssh configuration consists of:
|
82
|
-
* tmp_file_dir, which is where files will be stored before being scp'd
|
83
|
-
over to the nodes. They will be deleted afterwards, unless the job
|
84
|
-
fails in mid-copy. By default this is tmp/file/.
|
85
83
|
* nodes, identified by aliases, such as `test_node`. This alias is what you should
|
86
84
|
pass into the "node" param over in the ssh.run task.
|
87
85
|
* if no node is specified, commands will default to the first node listed.
|
@@ -109,7 +107,6 @@ Sample ssh.yml:
|
|
109
107
|
``` yml
|
110
108
|
---
|
111
109
|
development:
|
112
|
-
tmp_file_dir: tmp/file/
|
113
110
|
nodes:
|
114
111
|
dev_node:
|
115
112
|
sudoers:
|
@@ -126,7 +123,6 @@ development:
|
|
126
123
|
port: 22
|
127
124
|
user: gateway_user
|
128
125
|
test:
|
129
|
-
tmp_file_dir: tmp/file/
|
130
126
|
nodes:
|
131
127
|
test_node:
|
132
128
|
sudoers:
|
@@ -143,7 +139,6 @@ test:
|
|
143
139
|
port: 22
|
144
140
|
user: gateway_user
|
145
141
|
production:
|
146
|
-
tmp_file_dir: tmp/file/
|
147
142
|
nodes:
|
148
143
|
prod_node:
|
149
144
|
sudoers:
|
@@ -161,6 +156,57 @@ production:
|
|
161
156
|
user: gateway_user
|
162
157
|
```
|
163
158
|
|
159
|
+
<a name='section_Configure_Git'></a>
|
160
|
+
### Configure Git
|
161
|
+
|
162
|
+
Git configuration is not required but recommended, as it allows you to
|
163
|
+
pull files directly from public or private Git repositories.
|
164
|
+
|
165
|
+
The Git configuration consists of:
|
166
|
+
* domains, identified by aliases, such as `private` and `public`.
|
167
|
+
* domains are passed into the source parameters in the git.run task.
|
168
|
+
* if no domain is specified, commands will default to the first domain listed.
|
169
|
+
|
170
|
+
Each domain has:
|
171
|
+
* a host;
|
172
|
+
* a key (optional); If you don't need an ssh key to access the repo, remove that row from the configuration file.
|
173
|
+
* this is the relative path of the ssh key required to access the repository.
|
174
|
+
* a user, which is the user used for the git clone command.
|
175
|
+
|
176
|
+
Sample git.yml:
|
177
|
+
|
178
|
+
``` yml
|
179
|
+
---
|
180
|
+
development:
|
181
|
+
domains:
|
182
|
+
private:
|
183
|
+
host: github.<domain>.com
|
184
|
+
key: config/mobilize/ssh_private.key
|
185
|
+
user: git
|
186
|
+
public:
|
187
|
+
host: github.com
|
188
|
+
user: git
|
189
|
+
test:
|
190
|
+
domains:
|
191
|
+
private:
|
192
|
+
host: github.<domain>.com
|
193
|
+
key: config/mobilize/ssh_private.key
|
194
|
+
user: git
|
195
|
+
public:
|
196
|
+
host: github.com
|
197
|
+
user: git
|
198
|
+
production:
|
199
|
+
domains:
|
200
|
+
private:
|
201
|
+
host: github.<domain>.com
|
202
|
+
key: config/mobilize/ssh_private.key
|
203
|
+
user: git
|
204
|
+
public:
|
205
|
+
host: github.com
|
206
|
+
user: git
|
207
|
+
```
|
208
|
+
|
209
|
+
|
164
210
|
<a name='section_Start'></a>
|
165
211
|
Start
|
166
212
|
-----
|
@@ -173,6 +219,10 @@ Start
|
|
173
219
|
* user, sources, and node are optional; cmd is required.
|
174
220
|
* specifying user will cause the command to be prefixed with sudo su <user> -c.
|
175
221
|
* non-google sources will also be read as the specified user.
|
222
|
+
* git sources can be specified with syntax `git://<domain>/<repo_owner>/<repo_name>/<file_path>`.
|
223
|
+
* Accessing private repos requires that you add the Mobilize public key to the repository as a deploy key.
|
224
|
+
* there is no user-level access control for git repositories at this time.
|
225
|
+
* domain defaults to the first one listed, if not included.
|
176
226
|
* not specifying node will cause the command to be run on the default node.
|
177
227
|
* ssh sources can be specified with syntax
|
178
228
|
`ssh://<node><file_full_path>`. If node is omitted, default node will be used.
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Mobilize
|
2
|
+
module Git
|
3
|
+
def Git.config
|
4
|
+
Base.config('git')
|
5
|
+
end
|
6
|
+
|
7
|
+
def Git.host(domain)
|
8
|
+
Git.config['domains'][domain]['host']
|
9
|
+
end
|
10
|
+
|
11
|
+
def Git.domains
|
12
|
+
Git.config['domains'].keys
|
13
|
+
end
|
14
|
+
|
15
|
+
def Git.default_domain
|
16
|
+
Git.domains.first
|
17
|
+
end
|
18
|
+
|
19
|
+
# converts a source path or target path to a dst in the context of handler and stage
|
20
|
+
def Git.path_to_dst(path,stage_path,gdrive_slot)
|
21
|
+
red_path = path.split("://").last
|
22
|
+
git_url = Git.url_by_path(red_path)
|
23
|
+
return Dataset.find_or_create_by_url(git_url)
|
24
|
+
end
|
25
|
+
|
26
|
+
def Git.url_by_path(path)
|
27
|
+
path_nodes = path.split("/")
|
28
|
+
domain = path_nodes.first.to_s
|
29
|
+
revision = "HEAD"
|
30
|
+
if Git.domains.include?(domain)
|
31
|
+
repo = path_nodes[1..2].join("/")
|
32
|
+
file_path = path_nodes[3..-1].join("/")
|
33
|
+
else
|
34
|
+
domain = Git.default_domain
|
35
|
+
repo = path_nodes[0..1].join("/")
|
36
|
+
file_path = path_nodes[2..-1].join("/")
|
37
|
+
end
|
38
|
+
url = "git://#{domain}/#{repo}/#{revision}/#{file_path}"
|
39
|
+
return url
|
40
|
+
end
|
41
|
+
|
42
|
+
#return path to tar.gz of git repo
|
43
|
+
def Git.pack(domain,repo,revision="HEAD")
|
44
|
+
repo_dir = Git.pull(domain,repo,revision)
|
45
|
+
repo_name = repo.split("/").last
|
46
|
+
tar_gz_path = "#{repo_dir}/../#{repo_name}.tar.gz"
|
47
|
+
pack_cmd = "cd #{repo_dir} && git archive #{revision} --format=tar.gz > #{tar_gz_path}"
|
48
|
+
pack_cmd.bash(true)
|
49
|
+
FileUtils.rm_r(repo_dir,:force=>true)
|
50
|
+
return tar_gz_path
|
51
|
+
end
|
52
|
+
|
53
|
+
#confirm that git file exists
|
54
|
+
def Git.exists?(url)
|
55
|
+
domain,repo,revision,file_path=[]
|
56
|
+
url.split("/").ie do |url_nodes|
|
57
|
+
domain = url_nodes[2]
|
58
|
+
repo = url_nodes[3..4].join("/")
|
59
|
+
revision = url_nodes[5]
|
60
|
+
file_path = url_nodes[6..-1].join("/")
|
61
|
+
end
|
62
|
+
repo_dir = Git.pull(domain,repo,revision)
|
63
|
+
full_path = "#{repo_dir}/#{file_path}"
|
64
|
+
exists = File.exists?(full_path)
|
65
|
+
if exists
|
66
|
+
FileUtils.rm_r(repo_dir,:force=>true)
|
67
|
+
return exists
|
68
|
+
else
|
69
|
+
raise "Unable to find #{full_path}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
#pulls a git repo and sets it to the specified revision in the
|
74
|
+
#specified folder
|
75
|
+
def Git.pull(domain,repo,revision,run_dir=Dir.mktmpdir)
|
76
|
+
domain_properties = Git.config['domains'][domain]
|
77
|
+
user,host,key = ['user','host','key'].map{|k| domain_properties[k]}
|
78
|
+
#create folder for repo and command
|
79
|
+
run_file_path = run_dir + "/cmd.sh"
|
80
|
+
#put together command
|
81
|
+
git_prefix = key ? "ssh-add #{Base.root}/#{key};" : ""
|
82
|
+
git_suffix = (revision=="HEAD" ? " --depth=1" : "; git checkout -q #{revision}")
|
83
|
+
#add keys, clone repo, go to specific revision, execute command
|
84
|
+
full_cmd = "cd #{run_dir};#{git_prefix}git clone -q #{user}@#{host}:#{repo}.git#{git_suffix}"
|
85
|
+
#put command in file, run ssh-agent bash on it
|
86
|
+
File.open(run_file_path,"w") {|f| f.print(full_cmd)}
|
87
|
+
run_cmd = "ssh-agent bash #{run_file_path}"
|
88
|
+
#run the command, it will return an exception if there are issues
|
89
|
+
run_cmd.bash(true)
|
90
|
+
repo_name = repo.split("/").last
|
91
|
+
repo_dir = "#{run_dir}/#{repo_name}"
|
92
|
+
return repo_dir
|
93
|
+
end
|
94
|
+
|
95
|
+
def Git.read_by_dataset_path(dst_path,user_name,*args)
|
96
|
+
domain,repo,revision,file_path = []
|
97
|
+
dst_path.split("/").ie do |path_nodes|
|
98
|
+
domain = path_nodes[0]
|
99
|
+
repo = path_nodes[1..2].join("/")
|
100
|
+
revision = path_nodes[3]
|
101
|
+
file_path = path_nodes[4..-1].join("/")
|
102
|
+
end
|
103
|
+
#slash in front of path
|
104
|
+
repo_dir = Git.pull(domain,repo,revision)
|
105
|
+
full_path = "#{repo_dir}/#{file_path}"
|
106
|
+
result = "cat #{full_path}".bash(true)
|
107
|
+
FileUtils.rm_r(repo_dir,:force=>true)
|
108
|
+
return result
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -1,45 +1,8 @@
|
|
1
1
|
module Mobilize
|
2
2
|
module Ssh
|
3
|
-
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
def Ssh.tmp_file_dir
|
8
|
-
Ssh.config['tmp_file_dir']
|
9
|
-
end
|
10
|
-
|
11
|
-
def Ssh.host(node)
|
12
|
-
Ssh.config['nodes'][node]['host']
|
13
|
-
end
|
14
|
-
|
15
|
-
def Ssh.gateway(node)
|
16
|
-
Ssh.config['nodes'][node]['gateway']
|
17
|
-
end
|
18
|
-
|
19
|
-
def Ssh.sudoers(node)
|
20
|
-
Ssh.config['nodes'][node]['sudoers']
|
21
|
-
end
|
22
|
-
|
23
|
-
def Ssh.su_all_users(node)
|
24
|
-
Ssh.config['nodes'][node]['su_all_users']
|
25
|
-
end
|
26
|
-
|
27
|
-
def Ssh.nodes
|
28
|
-
Ssh.config['nodes'].keys
|
29
|
-
end
|
30
|
-
|
31
|
-
def Ssh.default_node
|
32
|
-
Ssh.nodes.first
|
33
|
-
end
|
34
|
-
|
35
|
-
#determine if current machine is on host domain, needs gateway if one is provided and it is not
|
36
|
-
def Ssh.needs_gateway?(node)
|
37
|
-
host_domain_name = Ssh.host(node)['name'].split(".")[-2..-1].join(".")
|
38
|
-
return true if Ssh.gateway(node) and Socket.domain_name != host_domain_name
|
39
|
-
end
|
40
|
-
|
3
|
+
#adds convenience methods
|
4
|
+
require "#{File.dirname(__FILE__)}/../helpers/ssh_helper"
|
41
5
|
def Ssh.pop_comm_dir(comm_dir,file_hash)
|
42
|
-
FileUtils.rm_r comm_dir, :force=>true
|
43
6
|
file_hash.each do |fname,fdata|
|
44
7
|
fpath = "#{comm_dir}/#{fname}"
|
45
8
|
#for now, only gz is binary
|
@@ -50,18 +13,6 @@ module Mobilize
|
|
50
13
|
return true if file_hash.keys.length>0
|
51
14
|
end
|
52
15
|
|
53
|
-
def Ssh.set_key_permissions(key_path)
|
54
|
-
#makes sure permissions are set as appropriate for ssh key
|
55
|
-
raise "could not find ssh key at #{key_path}" unless File.exists?(key_path)
|
56
|
-
#keys named with .pem are
|
57
|
-
if key_path.ends_with?(".pem")
|
58
|
-
File.chmod(0400,key_path) unless File.stat(key_path).mode.to_s(8)[3..5] == "400"
|
59
|
-
else
|
60
|
-
File.chmod(0600,key_path) unless File.stat(key_path).mode.to_s(8)[3..5] == "600"
|
61
|
-
end
|
62
|
-
return true
|
63
|
-
end
|
64
|
-
|
65
16
|
# converts a source path or target path to a dst in the context of handler and stage
|
66
17
|
def Ssh.path_to_dst(path,stage_path,gdrive_slot)
|
67
18
|
has_handler = true if path.index("://")
|
@@ -102,7 +53,6 @@ module Mobilize
|
|
102
53
|
def Ssh.scp(node,from_path,to_path)
|
103
54
|
name,key,port,user = Ssh.host(node).ie{|h| ['name','key','port','user'].map{|k| h[k]}}
|
104
55
|
key_path = "#{Base.root}/#{key}"
|
105
|
-
Ssh.set_key_permissions(key_path)
|
106
56
|
opts = {:port=>(port || 22),:keys=>key_path}
|
107
57
|
if Ssh.needs_gateway?(node)
|
108
58
|
gname,gkey,gport,guser = Ssh.gateway(node).ie{|h| ['name','key','port','user'].map{|k| h[k]}}
|
@@ -117,25 +67,31 @@ module Mobilize
|
|
117
67
|
return true
|
118
68
|
end
|
119
69
|
|
120
|
-
def Ssh.run(node,command,user,file_hash={})
|
121
|
-
|
122
|
-
key_path = "#{Base.root}/#{key}"
|
123
|
-
Ssh.set_key_permissions(key_path)
|
70
|
+
def Ssh.run(node,command,user,file_hash={},params={})
|
71
|
+
default_user = Ssh.host(node)['user']
|
124
72
|
file_hash ||= {}
|
125
73
|
#make sure the dir for this command is clear
|
126
74
|
comm_md5 = [user,node,command,file_hash.keys.to_s,Time.now.to_f.to_s].join.to_md5
|
127
|
-
comm_dir =
|
75
|
+
comm_dir = Dir.mktmpdir
|
76
|
+
#add in default methods to the params
|
77
|
+
params.merge(Ssh.default_params)
|
78
|
+
#replace any params in the file_hash and command
|
79
|
+
params.each do |k,v|
|
80
|
+
command.gsub!(k,v)
|
81
|
+
file_hash.each do |name,data|
|
82
|
+
data.gsub!(k,v)
|
83
|
+
end
|
84
|
+
end
|
128
85
|
#populate comm dir with any files
|
129
86
|
Ssh.pop_comm_dir(comm_dir,file_hash)
|
130
|
-
#move any files up to the node
|
131
|
-
rem_dir = nil
|
132
87
|
#make sure user starts in rem_dir
|
133
88
|
rem_dir = "#{comm_md5}/"
|
134
89
|
#make sure the rem_dir is gone
|
135
90
|
Ssh.fire!(node,"sudo rm -rf #{rem_dir}")
|
136
91
|
if File.exists?(comm_dir)
|
137
92
|
Ssh.scp(node,comm_dir,rem_dir)
|
138
|
-
|
93
|
+
#make sure comm_dir is removed
|
94
|
+
FileUtils.rm_r(comm_dir,:force=>true)
|
139
95
|
else
|
140
96
|
#create folder
|
141
97
|
mkdir_command = "mkdir #{rem_dir}"
|
@@ -163,7 +119,6 @@ module Mobilize
|
|
163
119
|
def Ssh.fire!(node,cmd)
|
164
120
|
name,key,port,user = Ssh.host(node).ie{|h| ['name','key','port','user'].map{|k| h[k]}}
|
165
121
|
key_path = "#{Base.root}/#{key}"
|
166
|
-
Ssh.set_key_permissions(key_path)
|
167
122
|
opts = {:port=>(port || 22),:keys=>key_path}
|
168
123
|
response = if Ssh.needs_gateway?(node)
|
169
124
|
gname,gkey,gport,guser = Ssh.gateway(node).ie{|h| ['name','key','port','user'].map{|k| h[k]}}
|
@@ -193,17 +148,15 @@ module Mobilize
|
|
193
148
|
def Ssh.write(node,fdata,to_path,binary=false)
|
194
149
|
from_path = Ssh.tmp_file(fdata,binary)
|
195
150
|
Ssh.scp(node,from_path,to_path)
|
196
|
-
|
151
|
+
#make sure local is removed
|
152
|
+
FileUtils.rm_r(from_path,:force=>true)
|
197
153
|
return true
|
198
154
|
end
|
199
155
|
|
200
156
|
def Ssh.tmp_file(fdata,binary=false,fpath=nil)
|
201
157
|
#creates a file under tmp/files with an md5 from the data
|
202
|
-
tmp_file_path = fpath || "#{
|
158
|
+
tmp_file_path = fpath || "#{Dir.mktmpdir}/#{(fdata + Time.now.utc.to_f.to_s).to_md5}"
|
203
159
|
write_mode = binary ? "wb" : "w"
|
204
|
-
#make sure folder is created
|
205
|
-
tmp_file_dir = tmp_file_path.split("/")[0..-2].join("/")
|
206
|
-
FileUtils.mkdir_p(tmp_file_dir)
|
207
160
|
#write data to path
|
208
161
|
File.open(tmp_file_path,write_mode) {|f| f.print(fdata)}
|
209
162
|
return tmp_file_path
|
@@ -268,6 +221,8 @@ module Mobilize
|
|
268
221
|
response = {}
|
269
222
|
response['out_url'] = Dataset.write_by_url("gridfs://#{s.path}/out",result['stdout'].to_s,Gdrive.owner_name)
|
270
223
|
response['err_url'] = Dataset.write_by_url("gridfs://#{s.path}/err",result['stderr'].to_s,Gdrive.owner_name) if result['stderr'].to_s.length>0
|
224
|
+
#is an error if there is no out and there is an err, regardless of signal
|
225
|
+
result['exit_code'] = 500 if result['stdout'].to_s.strip.length==0 and result['stderr'].to_s.strip.length>0
|
271
226
|
response['signal'] = result['exit_code']
|
272
227
|
response
|
273
228
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Mobilize
|
2
|
+
module Ssh
|
3
|
+
def self.config
|
4
|
+
Base.config('ssh')
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.host(node)
|
8
|
+
self.config['nodes'][node]['host']
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.gateway(node)
|
12
|
+
self.config['nodes'][node]['gateway']
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.sudoers(node)
|
16
|
+
self.config['nodes'][node]['sudoers']
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.su_all_users(node)
|
20
|
+
self.config['nodes'][node]['su_all_users']
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.nodes
|
24
|
+
self.config['nodes'].keys
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.default_node
|
28
|
+
self.nodes.first
|
29
|
+
end
|
30
|
+
|
31
|
+
#determine if current machine is on host domain, needs gateway if one is provided and it is not
|
32
|
+
def self.needs_gateway?(node)
|
33
|
+
host_domain_name = self.host(node)['name'].split(".")[-2..-1].join(".")
|
34
|
+
return true if self.gateway(node) and Socket.domain_name != host_domain_name
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.default_params
|
38
|
+
time = Time.now.utc
|
39
|
+
{
|
40
|
+
'$utc_date'=>time.strftime("%Y-%m-%d"),
|
41
|
+
'$utc_time'=>time.strftime("%H:%M"),
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/mobilize-ssh/version.rb
CHANGED
data/lib/mobilize-ssh.rb
CHANGED
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.298"
|
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_name = gdrive_slot.split("@").first
|
18
|
+
u = Mobilize::User.where(:name=>user_name).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)
|
@@ -42,6 +42,7 @@ describe "Mobilize" do
|
|
42
42
|
ssh_target_sheet_1 = Mobilize::Gsheet.find_by_path("#{r.path.split("/")[0..-2].join("/")}/test_ssh_1.out",gdrive_slot)
|
43
43
|
ssh_target_sheet_2 = Mobilize::Gsheet.find_by_path("#{r.path.split("/")[0..-2].join("/")}/test_ssh_2.out",gdrive_slot)
|
44
44
|
ssh_target_sheet_3 = Mobilize::Gsheet.find_by_path("#{r.path.split("/")[0..-2].join("/")}/test_ssh_3.out",gdrive_slot)
|
45
|
+
ssh_target_sheet_4 = Mobilize::Gsheet.find_by_path("#{r.path.split("/")[0..-2].join("/")}/test_ssh_4.out",gdrive_slot)
|
45
46
|
[ssh_target_sheet_1,ssh_target_sheet_2,ssh_target_sheet_3].each {|s| s.delete if s}
|
46
47
|
|
47
48
|
ssh_job_rows = ::YAML.load_file("#{Mobilize::Base.root}/test/ssh_job_rows.yml")
|
@@ -59,10 +60,12 @@ describe "Mobilize" do
|
|
59
60
|
ssh_target_sheet_1 = Mobilize::Gsheet.find_by_path("#{r.path.split("/")[0..-2].join("/")}/test_ssh_1.out",gdrive_slot)
|
60
61
|
ssh_target_sheet_2 = Mobilize::Gsheet.find_by_path("#{r.path.split("/")[0..-2].join("/")}/test_ssh_2.out",gdrive_slot)
|
61
62
|
ssh_target_sheet_3 = Mobilize::Gsheet.find_by_path("#{r.path.split("/")[0..-2].join("/")}/test_ssh_3.out",gdrive_slot)
|
63
|
+
ssh_target_sheet_4 = Mobilize::Gsheet.find_by_path("#{r.path.split("/")[0..-2].join("/")}/test_ssh_4.out",gdrive_slot)
|
62
64
|
|
63
65
|
assert ssh_target_sheet_1.to_tsv.length > 100
|
64
66
|
assert ssh_target_sheet_2.to_tsv.length > 100
|
65
67
|
assert ssh_target_sheet_3.to_tsv.length > 3
|
68
|
+
assert ssh_target_sheet_4.to_tsv.length > 100
|
66
69
|
|
67
70
|
end
|
68
71
|
|
data/test/ssh_job_rows.yml
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
---
|
1
2
|
- name: test_ssh_1
|
2
3
|
active: true
|
3
4
|
trigger: once
|
@@ -16,3 +17,9 @@
|
|
16
17
|
status: ""
|
17
18
|
stage1: 'ssh.run cmd:"whoami"'
|
18
19
|
stage2: 'gsheet.write source:"stage1", target:"test_ssh_3.out"'
|
20
|
+
- name: test_ssh_4
|
21
|
+
active: true
|
22
|
+
trigger: "after test_ssh_3"
|
23
|
+
status: ""
|
24
|
+
stage1: 'ssh.run node:"test_node", user:root, sources:["git://DeNA/mobilize-ssh/test/code.rb","git://DeNA/mobilize-ssh/test/code.sh"], cmd:"ruby code.rb"'
|
25
|
+
stage2: 'gsheet.write source:stage1, target:"test_ssh_4.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.
|
4
|
+
version: '1.298'
|
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-04-
|
12
|
+
date: 2013-04-17 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.298'
|
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.298'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: net-ssh
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,7 +91,9 @@ files:
|
|
91
91
|
- lib/mobilize-ssh/extensions/net-ssh-connection-session.rb
|
92
92
|
- lib/mobilize-ssh/extensions/net-ssh-gateway.rb
|
93
93
|
- lib/mobilize-ssh/extensions/socket.rb
|
94
|
+
- lib/mobilize-ssh/handlers/git.rb
|
94
95
|
- lib/mobilize-ssh/handlers/ssh.rb
|
96
|
+
- lib/mobilize-ssh/helpers/ssh_helper.rb
|
95
97
|
- lib/mobilize-ssh/tasks.rb
|
96
98
|
- lib/mobilize-ssh/version.rb
|
97
99
|
- lib/samples/ssh.yml
|
@@ -117,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
119
|
version: '0'
|
118
120
|
segments:
|
119
121
|
- 0
|
120
|
-
hash:
|
122
|
+
hash: 2943604812785338750
|
121
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
124
|
none: false
|
123
125
|
requirements:
|
@@ -126,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
128
|
version: '0'
|
127
129
|
segments:
|
128
130
|
- 0
|
129
|
-
hash:
|
131
|
+
hash: 2943604812785338750
|
130
132
|
requirements: []
|
131
133
|
rubyforge_project:
|
132
134
|
rubygems_version: 1.8.25
|