cnvrg 0.0.14.0 → 0.0.15
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.
- checksums.yaml +4 -4
- data/cnvrg.gemspec +9 -5
- data/lib/cnvrg/Images.rb +76 -15
- data/lib/cnvrg/api.rb +7 -4
- data/lib/cnvrg/cli.rb +2148 -526
- data/lib/cnvrg/data.rb +72 -0
- data/lib/cnvrg/datafiles.rb +509 -0
- data/lib/cnvrg/dataset.rb +296 -0
- data/lib/cnvrg/experiment.rb +19 -10
- data/lib/cnvrg/files.rb +302 -208
- data/lib/cnvrg/helpers.rb +42 -1
- data/lib/cnvrg/job.rb +0 -1
- data/lib/cnvrg/project.rb +55 -15
- data/lib/cnvrg/ssh.rb +95 -0
- data/lib/cnvrg/version.rb +2 -1
- data/lib/cnvrg.rb +0 -1
- metadata +48 -17
data/lib/cnvrg/cli.rb
CHANGED
@@ -7,7 +7,7 @@ require 'uri'
|
|
7
7
|
require 'open-uri'
|
8
8
|
require 'json'
|
9
9
|
require 'yaml'
|
10
|
-
require 'digest' #
|
10
|
+
require 'digest' # sha1up
|
11
11
|
require "highline/import"
|
12
12
|
require 'socket'
|
13
13
|
include Open4
|
@@ -18,6 +18,10 @@ require 'cnvrg/project'
|
|
18
18
|
require 'cnvrg/files'
|
19
19
|
require 'cnvrg/experiment'
|
20
20
|
require 'cnvrg/Images'
|
21
|
+
require 'cnvrg/dataset'
|
22
|
+
require 'cnvrg/datafiles'
|
23
|
+
require 'cnvrg/data'
|
24
|
+
require 'cnvrg/ssh'
|
21
25
|
require 'etc'
|
22
26
|
require 'logstash-logger'
|
23
27
|
require 'cnvrg/job'
|
@@ -29,28 +33,116 @@ require 'fileutils'
|
|
29
33
|
require 'zip'
|
30
34
|
require 'active_support/all'
|
31
35
|
require 'thor'
|
32
|
-
require '
|
36
|
+
require 'pathname'
|
37
|
+
require 'enumerator'
|
38
|
+
|
39
|
+
class Thor
|
40
|
+
module Base
|
41
|
+
def initialize(args = [], local_options = {}, config = {})
|
42
|
+
parse_options = Thor.class_options
|
43
|
+
|
44
|
+
# The start method splits inbound arguments at the first argument
|
45
|
+
# that looks like an option (starts with - or --). It then calls
|
46
|
+
# new, passing in the two halves of the arguments Array as the
|
47
|
+
# first two parameters.
|
48
|
+
|
49
|
+
command_options = config.delete(:command_options) # hook for start
|
50
|
+
parse_options = parse_options.merge(command_options) if command_options
|
51
|
+
if local_options.is_a?(Array)
|
52
|
+
array_options = local_options
|
53
|
+
hash_options = {}
|
54
|
+
else
|
55
|
+
# Handle the case where the class was explicitly instantiated
|
56
|
+
# with pre-parsed options.
|
57
|
+
array_options = []
|
58
|
+
hash_options = local_options
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
# Let Thor::Options parse the options first, so it can remove
|
63
|
+
# declared options from the array. This will leave us with
|
64
|
+
# a list of arguments that weren't declared.
|
65
|
+
stop_on_unknown = Thor.stop_on_unknown_option? config[:current_command]
|
66
|
+
opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown)
|
67
|
+
real_options = []
|
68
|
+
|
69
|
+
real_args = [].replace(array_options)
|
70
|
+
if local_options.is_a? (Array) and !local_options.empty? and args.empty?
|
71
|
+
array_options.each_with_index do |p, i|
|
72
|
+
opt = p
|
73
|
+
if p.include? "="
|
74
|
+
opt = p.split("=")[0]
|
75
|
+
end
|
76
|
+
option = is_option(parse_options.values, opt)
|
77
|
+
if !option
|
78
|
+
break
|
79
|
+
else
|
80
|
+
real_options << p
|
81
|
+
real_args.delete(p)
|
82
|
+
if !p.include? "=" and option.type != :boolean
|
83
|
+
if i+1< array_options.size
|
84
|
+
real_options << array_options[i+1]
|
85
|
+
real_args.delete(array_options[i+1])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
args = real_args
|
94
|
+
else
|
95
|
+
if !args.empty? and local_options.is_a? Array and !local_options.empty?
|
96
|
+
args = args + local_options
|
97
|
+
else
|
98
|
+
args = args.flatten()
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
self.options = opts.parse(real_options)
|
105
|
+
self.options = config[:class_options].merge(options) if config[:class_options]
|
106
|
+
|
107
|
+
# If unknown options are disallowed, make sure that none of the
|
108
|
+
# remaining arguments looks like an option.
|
109
|
+
opts.check_unknown! if Thor.check_unknown_options?(config)
|
110
|
+
|
111
|
+
# Add the remaining arguments from the options parser to the
|
112
|
+
# arguments passed in to initialize. Then remove any positional
|
113
|
+
# arguments declared using #argument (this is primarily used
|
114
|
+
# by Thor::Group). Tis will leave us with the remaining
|
115
|
+
# positional arguments.
|
116
|
+
to_parse = args
|
117
|
+
to_parse += opts.remaining unless self.class.strict_args_position?(config)
|
118
|
+
thor_args = Thor::Arguments.new(self.class.arguments)
|
119
|
+
thor_args.parse(to_parse).each { |k, v| __send__("#{k}=", v) }
|
120
|
+
@args = thor_args.remaining
|
121
|
+
end
|
122
|
+
|
123
|
+
def is_option (options, p)
|
124
|
+
options.each do |o|
|
125
|
+
if !o.aliases.nil?
|
126
|
+
if (o.aliases.is_a? Array and o.aliases.include? p) or (o.aliases.is_a? Array and o.aliases.size ==1 and o.aliases[0].split(",").include? p) or o.switch_name.eql? p
|
127
|
+
return o
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
return false
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
33
138
|
|
34
|
-
# DEV VERSION
|
35
|
-
#
|
36
139
|
module Cnvrg
|
140
|
+
|
37
141
|
class CLI < Thor
|
38
142
|
|
39
143
|
INSTALLATION_URLS = {docker: "https://docs.docker.com/engine/installation/", jupyter: "http://jupyter.readthedocs.io/en/latest/install.html"}
|
40
144
|
IP="localhost"
|
41
145
|
PORT=7654
|
42
|
-
desc '', ''
|
43
|
-
|
44
|
-
def printable_commands(all = true, subcommand = false)
|
45
|
-
(all ? all_commands : commands).map do |_, command|
|
46
|
-
next if command.hidden? or (command.description.empty? and command.usage.empty?)
|
47
|
-
item = []
|
48
|
-
item << banner(command, false, subcommand)
|
49
|
-
item << (command.description ? "# #{command.description.gsub(/\s+/m, ' ')}" : "")
|
50
|
-
item
|
51
|
-
end.compact
|
52
|
-
end
|
53
|
-
|
54
146
|
class << self
|
55
147
|
# Hackery.Take the run method away from Thor so that we can redefine it.
|
56
148
|
def is_thor_reserved_word?(word, type)
|
@@ -58,9 +150,10 @@ module Cnvrg
|
|
58
150
|
super
|
59
151
|
end
|
60
152
|
end
|
153
|
+
desc "data", "upload and manage datasets", :hide => true
|
154
|
+
subcommand "data", Data
|
61
155
|
|
62
|
-
desc "", ""
|
63
|
-
method_option :schedule, :type => :string, :aliases => ["--s", "-s"], :default => "leahs"
|
156
|
+
desc "", "", :hide => true
|
64
157
|
|
65
158
|
def test
|
66
159
|
# image_settings = {
|
@@ -78,11 +171,10 @@ module Cnvrg
|
|
78
171
|
# },
|
79
172
|
# },
|
80
173
|
# }
|
81
|
-
container = Docker::Container.get('b4d64bf83f41')
|
82
|
-
s = "/leah/1/2/3/4/5"
|
83
|
-
command = ["/bin/bash","-lc","sed -i 's#c.NotebookApp.base_url = .*#c.NotebookApp.base_url = \"#{s}\"#' /home/ds/.jupyter/jupyter_notebook_config.py"]
|
84
|
-
puts container.exec(command, tty: true)
|
85
|
-
|
174
|
+
# container = Docker::Container.get('b4d64bf83f41')
|
175
|
+
# s = "/leah/1/2/3/4/5"
|
176
|
+
# command = ["/bin/bash","-lc","sed -i 's#c.NotebookApp.base_url = .*#c.NotebookApp.base_url = \"#{s}\"#' /home/ds/.jupyter/jupyter_notebook_config.py"]
|
177
|
+
# puts container.exec(command, tty: true)
|
86
178
|
end
|
87
179
|
|
88
180
|
|
@@ -95,7 +187,7 @@ module Cnvrg
|
|
95
187
|
|
96
188
|
map %w(-v --version) => :version
|
97
189
|
|
98
|
-
desc 'set api url
|
190
|
+
desc 'api', 'set api url, e.g cnvrg --api "https://cnvrg.io/api"'
|
99
191
|
|
100
192
|
def set_api_url(url)
|
101
193
|
home_dir = File.expand_path('~')
|
@@ -111,15 +203,19 @@ module Cnvrg
|
|
111
203
|
end
|
112
204
|
config = YAML.load_file(home_dir+"/.cnvrg/config.yml")
|
113
205
|
owner = config.to_h[:owner]
|
206
|
+
compression_path = "#{File.expand_path('~')}/.cnvrg/tmp"
|
114
207
|
|
115
208
|
say "Setting default api to be: #{url}", Thor::Shell::Color::BLUE
|
116
209
|
if config.empty?
|
117
|
-
config = {owner: "", username: "", version_last_check: get_start_day(), api: url}
|
210
|
+
config = {owner: "", username: "", version_last_check: get_start_day(), api: url,compression_path: compression_path }
|
118
211
|
else
|
119
|
-
|
212
|
+
if !config.to_h[:compression_path].nil?
|
213
|
+
compression_path = config.to_h[:compression_path]
|
214
|
+
end
|
215
|
+
config = {owner: config.to_h[:owner], username: config.to_h[:username], version_last_check: config.to_h[:version_last_check], api: url, compression_path: compression_path}
|
120
216
|
end
|
121
217
|
res = Cnvrg::API.request("/users/#{owner}/custom_api", 'POST', {custom_api: url})
|
122
|
-
if Cnvrg::CLI.is_response_success(res)
|
218
|
+
if Cnvrg::CLI.is_response_success(res,false)
|
123
219
|
|
124
220
|
checks = Helpers.checkmark
|
125
221
|
|
@@ -137,7 +233,7 @@ module Cnvrg
|
|
137
233
|
end
|
138
234
|
end
|
139
235
|
|
140
|
-
desc '', ''
|
236
|
+
desc '', '', :hide => true
|
141
237
|
|
142
238
|
def set_remote_api_url(owner, current_user, url)
|
143
239
|
home_dir = File.expand_path('~')
|
@@ -152,7 +248,9 @@ module Cnvrg
|
|
152
248
|
FileUtils.touch [home_dir+"/.cnvrg/config.yml"]
|
153
249
|
end
|
154
250
|
config = YAML.load_file(home_dir+"/.cnvrg/config.yml")
|
155
|
-
|
251
|
+
|
252
|
+
compression_path = "#{home_dir}/.cnvrg/tmp"
|
253
|
+
config = {owner: owner, username: current_user, version_last_check: get_start_day(), api: url,compression_path:compression_path}
|
156
254
|
File.open(home_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
157
255
|
say "Done"
|
158
256
|
rescue
|
@@ -162,57 +260,108 @@ module Cnvrg
|
|
162
260
|
|
163
261
|
map %w(-api --api) => :set_api_url
|
164
262
|
|
165
|
-
desc '
|
263
|
+
desc 'set_default_owner', 'set default owner'
|
166
264
|
|
167
265
|
def set_default_owner
|
266
|
+
begin
|
267
|
+
path = File.expand_path('~')+"/.cnvrg/config.yml"
|
268
|
+
if !File.exist?(path)
|
269
|
+
say "Couldn't find ~/.cnvrg/config.yml file, please logout and login again", Thor::Shell::Color::RED
|
168
270
|
|
169
|
-
|
170
|
-
|
171
|
-
|
271
|
+
exit(0)
|
272
|
+
end
|
273
|
+
config = YAML.load_file(path)
|
172
274
|
|
173
|
-
|
174
|
-
|
175
|
-
|
275
|
+
username = config.to_h[:username]
|
276
|
+
res = Cnvrg::API.request("/users/#{username}/get_possible_owners", 'GET')
|
277
|
+
if Cnvrg::CLI.is_response_success(res)
|
278
|
+
owner = username
|
279
|
+
result = res["result"]
|
280
|
+
owners = result["owners"]
|
281
|
+
urls = result["urls"]
|
282
|
+
choose_owner = result["username"]
|
283
|
+
if owners.empty?
|
284
|
+
else
|
285
|
+
owners << choose_owner
|
286
|
+
chosen = false
|
287
|
+
while !chosen
|
288
|
+
owners_id = owners.each_with_index.map { |x, i| "#{i+1}. #{x}" }
|
289
|
+
choose_owner = ask("Choose default owner:\n"+owners_id.join("\n")+"\n")
|
290
|
+
|
291
|
+
if choose_owner =~ /[[:digit:]]/
|
292
|
+
ow_index = choose_owner.to_i-1
|
293
|
+
if ow_index<0 or ow_index >= owners.size
|
294
|
+
say "No such owner, please choose again", Thor::Shell::Color::BLUE
|
295
|
+
chosen = false
|
296
|
+
next
|
297
|
+
end
|
298
|
+
choose_owner = owners[choose_owner.to_i-1]
|
299
|
+
chosen = true
|
176
300
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
301
|
+
else
|
302
|
+
|
303
|
+
owners_lower = owners.map { |o| o.downcase }
|
304
|
+
ow_index = owners_lower.index(choose_owner.downcase)
|
305
|
+
if ow_index.nil?
|
306
|
+
say "Could not find owner named #{choose_owner}", Thor::Shell::Color::RED
|
307
|
+
else
|
308
|
+
chosen = true
|
309
|
+
end
|
310
|
+
end
|
185
311
|
|
186
|
-
if owners.empty?
|
187
|
-
else
|
188
|
-
owners << choose_owner
|
189
|
-
chosen = false
|
190
|
-
while !chosen
|
191
|
-
choose_owner = ask("Choose default owner:\n"+owners.join("\n")+"\n")
|
192
|
-
|
193
|
-
owners_lower = owners.map { |o| o.downcase }
|
194
|
-
ow_index = owners_lower.index(choose_owner.downcase)
|
195
|
-
if ow_index.nil?
|
196
|
-
say "Could not find owner named #{choose_owner}", Thor::Shell::Color::RED
|
197
|
-
else
|
198
|
-
chosen = true
|
199
312
|
end
|
313
|
+
|
314
|
+
|
315
|
+
end
|
316
|
+
if set_owner(choose_owner, result["username"], urls[ow_index])
|
317
|
+
say "Setting default owner: #{choose_owner}", Thor::Shell::Color::GREEN
|
318
|
+
else
|
319
|
+
say "Setting default owenr has failed, try to run cnvrg --config-default-owner", Thor::Shell::Color::RED
|
200
320
|
end
|
321
|
+
end
|
322
|
+
rescue SignalException
|
323
|
+
say "\nAborting"
|
324
|
+
exit(1)
|
325
|
+
end
|
326
|
+
end
|
201
327
|
|
328
|
+
desc 'set_compression_path', 'set compression path'
|
329
|
+
method_option :reset, :type => :boolean, :aliases => ["-r","--reset"], :default => false
|
202
330
|
|
331
|
+
def set_compression_path(*compression_path)
|
332
|
+
begin
|
333
|
+
if (compression_path.nil? or compression_path.empty?) and options["reset"]
|
334
|
+
compression_path = ["#{File.expand_path('~')}/.cnvrg/tmp"]
|
203
335
|
end
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
336
|
+
compression_path = compression_path.join(" ")
|
337
|
+
if !Dir.exist? compression_path
|
338
|
+
say "Couldn't find #{compression_path}, please make sure it exist", Thor::Shell::Color::RED
|
339
|
+
exit(0)
|
340
|
+
end
|
341
|
+
|
342
|
+
home_dir = File.expand_path('~')
|
343
|
+
path = "#{home_dir}/.cnvrg/config.yml"
|
344
|
+
if !File.exist?(path)
|
345
|
+
say "Couldn't find ~/.cnvrg/config.yml file, please logout and login again", Thor::Shell::Color::RED
|
346
|
+
|
347
|
+
exit(0)
|
208
348
|
end
|
349
|
+
config = YAML.load_file(path)
|
350
|
+
config_new = {owner: config.to_h[:owner], username: config.to_h[:username],
|
351
|
+
version_last_check: config.to_h[:version_last_check], api: config.to_h[:api], compression_path: compression_path}
|
352
|
+
File.open(home_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config_new.to_yaml }
|
353
|
+
checks = Helpers.checkmark
|
354
|
+
say "#{checks} Done", Thor::Shell::Color::GREEN
|
355
|
+
|
356
|
+
rescue SignalException
|
357
|
+
say "\nAborting"
|
358
|
+
exit(1)
|
209
359
|
end
|
210
360
|
end
|
211
361
|
|
212
|
-
map %w(--set-default-owner) => :set_default_owner
|
213
362
|
|
214
363
|
|
215
|
-
desc 'login', 'Authenticate with cnvrg.io
|
364
|
+
desc 'login', 'Authenticate with cnvrg.io platform'
|
216
365
|
|
217
366
|
def login
|
218
367
|
begin
|
@@ -240,25 +389,46 @@ module Cnvrg
|
|
240
389
|
owners = result["owners"]
|
241
390
|
urls = result["urls"]
|
242
391
|
choose_owner = result["username"]
|
243
|
-
|
392
|
+
ow_index = 0
|
244
393
|
if owners.empty?
|
394
|
+
choose_owner = result["username"]
|
245
395
|
else
|
246
|
-
|
247
|
-
|
248
|
-
while !chosen
|
249
|
-
choose_owner = ask("Choose default owner:\n"+owners.join("\n")+"\n")
|
396
|
+
choose_owner = owners[0]
|
397
|
+
end
|
250
398
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
399
|
+
# if owners.empty?
|
400
|
+
# else
|
401
|
+
# owners << choose_owner
|
402
|
+
# chosen = false
|
403
|
+
# while !chosen
|
404
|
+
# owners_id = owners.each_with_index.map { |x, i| "#{i+1}. #{x}" }
|
405
|
+
# choose_owner = ask("Choose default owner:\n"+owners_id.join("\n")+"\n")
|
406
|
+
#
|
407
|
+
# if choose_owner =~ /[[:digit:]]/
|
408
|
+
# ow_index = choose_owner.to_i-1
|
409
|
+
# if ow_index<0 or ow_index >= owners.size
|
410
|
+
# say "No such owner, please choose again", Thor::Shell::Color::BLUE
|
411
|
+
# chosen = false
|
412
|
+
# next
|
413
|
+
# end
|
414
|
+
# choose_owner = owners[choose_owner.to_i-1]
|
415
|
+
# chosen = true
|
416
|
+
#
|
417
|
+
# else
|
418
|
+
#
|
419
|
+
# owners_lower = owners.map { |o| o.downcase }
|
420
|
+
# ow_index = owners_lower.index(choose_owner.downcase)
|
421
|
+
# if ow_index.nil?
|
422
|
+
# say "Could not find owner named #{choose_owner}", Thor::Shell::Color::RED
|
423
|
+
# else
|
424
|
+
# chosen = true
|
425
|
+
# end
|
426
|
+
# end
|
427
|
+
#
|
428
|
+
# end
|
259
429
|
|
260
430
|
|
261
|
-
end
|
431
|
+
# end
|
262
432
|
|
263
433
|
if set_owner(choose_owner, result["username"], urls[ow_index])
|
264
434
|
say "Setting default owner: #{choose_owner}", Thor::Shell::Color::GREEN
|
@@ -274,6 +444,11 @@ module Cnvrg
|
|
274
444
|
|
275
445
|
exit(1)
|
276
446
|
end
|
447
|
+
rescue
|
448
|
+
|
449
|
+
say "Error Occurred, aborting", Thor::Shell::Color::RED
|
450
|
+
logout()
|
451
|
+
exit(1)
|
277
452
|
rescue SignalException
|
278
453
|
|
279
454
|
say "\nAborting"
|
@@ -303,7 +478,6 @@ module Cnvrg
|
|
303
478
|
|
304
479
|
def me()
|
305
480
|
begin
|
306
|
-
|
307
481
|
verify_logged_in(false)
|
308
482
|
log_start(__method__, args, options)
|
309
483
|
auth = Cnvrg::Auth.new
|
@@ -314,6 +488,7 @@ module Cnvrg
|
|
314
488
|
end
|
315
489
|
|
316
490
|
log_end(0)
|
491
|
+
|
317
492
|
rescue SignalException
|
318
493
|
log_end(-1)
|
319
494
|
|
@@ -324,8 +499,8 @@ module Cnvrg
|
|
324
499
|
|
325
500
|
## Projects
|
326
501
|
desc 'new', 'Create a new cnvrg project'
|
327
|
-
method_option :clean, :type => :boolean, :aliases => ["-c"
|
328
|
-
method_option :docker_image, :type => :string, :aliases => ["-d"
|
502
|
+
method_option :clean, :type => :boolean, :aliases => ["-c"], :default => false
|
503
|
+
method_option :docker_image, :type => :string, :aliases => ["-d"], :default => ""
|
329
504
|
|
330
505
|
def new(project_name)
|
331
506
|
begin
|
@@ -393,8 +568,8 @@ module Cnvrg
|
|
393
568
|
say "created project successfully", Thor::Shell::Color::GREEN
|
394
569
|
say "Linked directory to\t#{@project.url}", Thor::Shell::Color::GREEN
|
395
570
|
rescue => e
|
396
|
-
|
397
|
-
|
571
|
+
log_end(-1, e.message)
|
572
|
+
say "Error occurred, aborting", Thor::Shell::Color::RED
|
398
573
|
if Dir.exist? working_dir
|
399
574
|
|
400
575
|
@project.revert(working_dir)
|
@@ -412,6 +587,7 @@ module Cnvrg
|
|
412
587
|
exit(1)
|
413
588
|
end
|
414
589
|
end
|
590
|
+
|
415
591
|
desc 'set_image', 'set_image for a project'
|
416
592
|
|
417
593
|
def set_image(docker_image)
|
@@ -448,9 +624,10 @@ module Cnvrg
|
|
448
624
|
@image.update_image_activity(nil, nil)
|
449
625
|
|
450
626
|
end
|
451
|
-
|
452
|
-
|
453
|
-
method_option :
|
627
|
+
|
628
|
+
desc 'link', 'Link current directory to a new cnvrg project'
|
629
|
+
method_option :sync, :type => :boolean, :aliases => ["-s"], :default => false
|
630
|
+
method_option :docker_image, :type => :string, :aliases => ["-d"], :default => ""
|
454
631
|
|
455
632
|
def link
|
456
633
|
begin
|
@@ -474,7 +651,7 @@ module Cnvrg
|
|
474
651
|
end
|
475
652
|
working_dir = Dir.getwd
|
476
653
|
owner = CLI.get_owner
|
477
|
-
if Project.link(owner,project_name, docker)
|
654
|
+
if Project.link(owner, project_name, docker)
|
478
655
|
path = Dir.pwd
|
479
656
|
@project = Project.new(path)
|
480
657
|
@project.generate_idx()
|
@@ -531,143 +708,834 @@ module Cnvrg
|
|
531
708
|
exit(1)
|
532
709
|
end
|
533
710
|
end
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
711
|
+
|
712
|
+
desc 'data init', 'Init dataset directory'
|
713
|
+
method_option :public, :type => :boolean, :aliases => ["-p", "--public"], :default => false
|
714
|
+
|
715
|
+
def init_data(public)
|
716
|
+
begin
|
717
|
+
verify_logged_in(false)
|
718
|
+
log_start(__method__, args, options)
|
719
|
+
dataset_name =File.basename(Dir.getwd)
|
720
|
+
if File.directory?(Dir.getwd+"/.cnvrg")
|
721
|
+
config = YAML.load_file("#{Dir.getwd}/.cnvrg/config.yml")
|
722
|
+
say "Directory is already linked to #{config[:dataset_slug]}", Thor::Shell::Color::RED
|
723
|
+
|
724
|
+
exit(0)
|
725
|
+
end
|
726
|
+
say "Init dataset: #{dataset_name}", Thor::Shell::Color::BLUE
|
727
|
+
|
728
|
+
working_dir = Dir.getwd
|
729
|
+
owner = CLI.get_owner
|
730
|
+
if Dataset.init(owner, dataset_name, options["public"])
|
731
|
+
path = Dir.pwd
|
732
|
+
@dataset = Dataset.new(path)
|
733
|
+
|
734
|
+
url = @dataset.url
|
735
|
+
check = Helpers.checkmark
|
736
|
+
say "#{check} Link finished successfully", Thor::Shell::Color::GREEN
|
737
|
+
say "#{dataset_name}'s location is: #{url}\n", Thor::Shell::Color::GREEN
|
738
|
+
log_end(0)
|
739
|
+
|
740
|
+
else
|
741
|
+
log_end(1, "can't create dataset")
|
742
|
+
@dataset.revert(working_dir) unless @dataset.nil?
|
743
|
+
say "Error creating dataset, please contact support.", Thor::Shell::Color::RED
|
744
|
+
exit(0)
|
745
|
+
end
|
746
|
+
rescue SignalException
|
747
|
+
log_end(-1)
|
748
|
+
|
749
|
+
say "\nAborting"
|
750
|
+
exit(1)
|
751
|
+
end
|
541
752
|
end
|
542
753
|
|
543
|
-
desc 'clone', 'Clone
|
544
|
-
method_option :
|
545
|
-
method_option :commit, :type => :string, :aliases => ["-c", "--c"], :default => nil
|
754
|
+
desc 'data clone', 'Clone dataset'
|
755
|
+
method_option :commit, :type => :string, :aliases => ["-c", "--commit"], :default => ""
|
546
756
|
|
547
|
-
def
|
757
|
+
def clone_data(dataset_url)
|
548
758
|
begin
|
549
759
|
verify_logged_in(false)
|
550
760
|
log_start(__method__, args, options)
|
551
|
-
url_parts =
|
552
|
-
project_index = Cnvrg::Helpers.look_for_in_path(
|
761
|
+
url_parts = dataset_url.split("/")
|
762
|
+
project_index = Cnvrg::Helpers.look_for_in_path(dataset_url, "datasets")
|
553
763
|
slug = url_parts[project_index+1]
|
554
764
|
owner = url_parts[project_index-1]
|
555
|
-
|
556
|
-
response = Cnvrg::API.request("users/#{owner}/projects/#{slug}/get_project", 'GET')
|
557
|
-
Cnvrg::CLI.is_response_success(response)
|
558
|
-
response = JSON.parse response["result"]
|
559
|
-
project_name = response["title"]
|
560
|
-
commit_to_clone = options["commit"] || nil
|
561
|
-
|
562
|
-
say "Cloning #{project_name}", Thor::Shell::Color::BLUE
|
563
|
-
clone_resp = false
|
564
|
-
if remote
|
565
|
-
clone_resp = Project.clone_dir_remote(slug, owner, project_name)
|
566
|
-
project_home = Dir.pwd
|
567
|
-
else
|
568
|
-
if (Dir.exists? project_name)
|
569
|
-
say "Error: Conflict with dir #{project_name}", Thor::Shell::Color::RED
|
570
|
-
if no? "Sync to repository anyway? (current data might lost)", Thor::Shell::Color::YELLOW
|
571
|
-
say "Remove dir in order to clone #{project_name}", Thor::Shell::Color::RED
|
572
|
-
log_end(1, "conflict with dir #{project_name}")
|
765
|
+
response = Cnvrg::API.request("users/#{owner}/datasets/#{slug}/clone", 'GET')
|
573
766
|
|
574
|
-
|
575
|
-
|
767
|
+
Cnvrg::CLI.is_response_success(response)
|
768
|
+
dataset_name = response["result"]["name"]
|
769
|
+
if (Dir.exists? dataset_name)
|
770
|
+
say "Error: Conflict with dir #{dataset_name}", Thor::Shell::Color::RED
|
771
|
+
if no? "Sync to repository anyway? (current data might lost)", Thor::Shell::Color::YELLOW
|
772
|
+
say "Remove dir in order to clone #{dataset_name}", Thor::Shell::Color::RED
|
773
|
+
log_end(1, "conflict with dir #{dataset_name}")
|
576
774
|
|
775
|
+
exit(1)
|
577
776
|
end
|
578
|
-
clone_resp = Project.clone_dir(slug, owner, project_name)
|
579
|
-
project_home = Dir.pwd+"/"+project_name
|
580
|
-
|
581
777
|
|
582
778
|
end
|
779
|
+
if Dataset.clone(owner, dataset_name, slug)
|
780
|
+
say "Cloning #{dataset_name}", Thor::Shell::Color::BLUE
|
583
781
|
|
584
|
-
|
585
|
-
|
586
|
-
@
|
587
|
-
|
588
|
-
|
589
|
-
working_dir = project_home
|
590
|
-
docker_image = response["result"]["image"]
|
591
|
-
idx = {commit: response["result"]["commit"], tree: response["result"]["tree"]}
|
592
|
-
File.open(working_dir + "/.cnvrg/idx.yml", "w+") { |f| f.write idx.to_yaml }
|
593
|
-
if !docker_image.nil? and !docker_image.empty? and !remote
|
594
|
-
local_images = Docker::Image.all
|
595
|
-
docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.eql? "#{docker_image}:latest" }.flatten
|
596
|
-
if docker_image_local.size == 0
|
597
|
-
if yes? "Image wasn't found locally, pull image from cnvrg repository?", Thor::Shell::Color::YELLOW
|
598
|
-
image = pull(docker_image)
|
599
|
-
if image
|
600
|
-
say "downloaded image: #{docker_image}"
|
601
|
-
@image = Images.new(working_dir, docker_image)
|
602
|
-
else
|
603
|
-
say "Could not create a new project with docker, image was not found", Thor::Shell::Color::RED
|
604
|
-
@project.revert(working_dir)
|
605
|
-
exit(1)
|
606
|
-
end
|
607
|
-
end
|
782
|
+
commit_to_clone = options["commit"] || nil
|
783
|
+
working_dir = "#{Dir.pwd}/#{dataset_name}"
|
784
|
+
@dataset = Dataset.new(working_dir)
|
785
|
+
@dataset.generate_idx()
|
786
|
+
say "Downloading data", Thor::Shell::Color::BLUE
|
608
787
|
|
609
|
-
elsif docker_image_local.size == 1
|
610
|
-
say "found image: #{docker_image_local[0]}, setting it up..", Thor::Shell::Color::BLUE
|
611
|
-
@image = Images.new(working_dir, docker_image_local[0])
|
612
|
-
elsif docker_image_local.size >1
|
613
|
-
say "found #{docker_image_local.size} images, choose the image name you want to use", Thor::Shell::Color::BLUE
|
614
|
-
image_name = ask "#{docker_image_local.join("\n")}\n", Thor::Shell::Color::BLUE
|
615
|
-
@image = Images.new(working_dir, image_name)
|
616
|
-
end
|
617
788
|
|
618
|
-
|
789
|
+
download_data(false, false, path = working_dir, in_dir=false)
|
619
790
|
|
620
|
-
successful_changes = []
|
621
|
-
say "Downloading files", Thor::Shell::Color::BLUE
|
622
|
-
if !response["result"]["tree"].nil?
|
623
|
-
response["result"]["tree"].each do |f|
|
624
|
-
relative_path = f[0].gsub(/^#{@project.local_path}/, "")
|
625
|
-
if f[0].end_with? "/"
|
626
|
-
# dir
|
627
|
-
if @files.download_dir(f[0], relative_path, project_home)
|
628
|
-
successful_changes << relative_path
|
629
|
-
end
|
630
|
-
else
|
631
|
-
# blob
|
632
|
-
if @files.download_file_s3(f[0], relative_path, project_home)
|
633
|
-
successful_changes << relative_path
|
634
|
-
end
|
635
|
-
end
|
636
|
-
end
|
637
|
-
end
|
638
791
|
|
639
|
-
|
792
|
+
check = Helpers.checkmark
|
793
|
+
say "#{check} Clone finished successfully", Thor::Shell::Color::GREEN
|
640
794
|
log_end(0)
|
641
|
-
else
|
642
|
-
log_end(1, "can't create directory")
|
643
795
|
|
644
|
-
|
645
|
-
|
796
|
+
else
|
797
|
+
log_end(1, "can't create dataset")
|
798
|
+
@dataset.revert(working_dir) unless @dataset.nil?
|
799
|
+
say "Error creating dataset, please contact support.", Thor::Shell::Color::RED
|
800
|
+
exit(0)
|
646
801
|
end
|
647
802
|
rescue SignalException
|
648
803
|
log_end(-1)
|
804
|
+
|
649
805
|
say "\nAborting"
|
650
806
|
exit(1)
|
651
807
|
end
|
652
|
-
|
653
808
|
end
|
654
809
|
|
810
|
+
desc 'init_data_container', 'Init dataset directory', :hide => true
|
811
|
+
method_option :login_content, :type => :string, :aliases => ["-l"], :default => ""
|
655
812
|
|
656
|
-
|
657
|
-
method_option :new_branch, :type => :boolean, :aliases => ["-nb", "--nb"], :desc => "create new branch of commits"
|
658
|
-
|
659
|
-
|
660
|
-
def status
|
813
|
+
def init_data_container(container)
|
661
814
|
begin
|
662
|
-
|
663
|
-
log_start(__method__, args, options)
|
664
|
-
@project = Project.new(get_project_home)
|
665
|
-
new_branch = options["new_branch"] || false
|
815
|
+
login_content = options["login_content"]
|
666
816
|
|
667
|
-
|
817
|
+
container = Docker::Container.get(container)
|
818
|
+
command = ["/bin/bash", "-lc", "sudo echo -e \"#{login_content}\" >/home/ds/.netrc"]
|
819
|
+
container.exec(command, tty: true)
|
820
|
+
command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg"]
|
821
|
+
container.exec(command, tty: true)
|
822
|
+
command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg/tmp"]
|
823
|
+
container.exec(command, tty: true)
|
824
|
+
command = ["/bin/bash", "-lc", "sudo chown -R ds /home/ds/.cnvrg /home/ds/.netrc"]
|
825
|
+
container.exec(command, tty: true)
|
826
|
+
command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
|
827
|
+
container.exec(command, tty: true)
|
828
|
+
|
829
|
+
rescue SignalException
|
830
|
+
log_end(-1)
|
831
|
+
|
832
|
+
say "\nAborting"
|
833
|
+
exit(1)
|
834
|
+
end
|
835
|
+
end
|
836
|
+
|
837
|
+
desc 'data_snap', 'Init dataset directory', :hide => true
|
838
|
+
method_option :public, :type => :boolean, :aliases => ["-p", "--public"], :default => false
|
839
|
+
|
840
|
+
def snap_data
|
841
|
+
begin
|
842
|
+
verify_logged_in(false)
|
843
|
+
log_start(__method__, args, options)
|
844
|
+
|
845
|
+
owner = CLI.get_owner
|
846
|
+
path = Dir.pwd
|
847
|
+
@dataset = Dataset.new(path)
|
848
|
+
|
849
|
+
log_end(0)
|
850
|
+
|
851
|
+
rescue SignalException
|
852
|
+
log_end(-1)
|
853
|
+
|
854
|
+
say "\nAborting"
|
855
|
+
exit(1)
|
856
|
+
end
|
857
|
+
end
|
858
|
+
|
859
|
+
desc 'data_snap', 'Init dataset directory', :hide => true
|
860
|
+
|
861
|
+
def data_init_container(owner, dataset_slug, dataset_name)
|
862
|
+
|
863
|
+
if Dataset.init_container(owner, dataset_slug, dataset_name)
|
864
|
+
|
865
|
+
say "init finished successfully", Thor::Shell::Color::GREEN
|
866
|
+
log_end(0)
|
867
|
+
|
868
|
+
else
|
869
|
+
log_end(1, "can't create dataset")
|
870
|
+
say "error creating dataset, please contact support.", Thor::Shell::Color::RED
|
871
|
+
exit(0)
|
872
|
+
end
|
873
|
+
end
|
874
|
+
|
875
|
+
desc 'data download', 'pull data'
|
876
|
+
method_option :verbose, :type => :boolean, :aliases => ["-v"], :default => false
|
877
|
+
method_option :sync, :type => :boolean, :aliases => ["-s"], :default => false
|
878
|
+
|
879
|
+
def download_data(verbose, sync, path=Dir.pwd, in_dir=true)
|
880
|
+
begin
|
881
|
+
verify_logged_in(in_dir)
|
882
|
+
log_start(__method__, args, options)
|
883
|
+
if path.nil? or path.empty?
|
884
|
+
path = Dir.pwd
|
885
|
+
end
|
886
|
+
dataset_dir = is_cnvrg_dir(path)
|
887
|
+
@dataset = Dataset.new(dataset_dir)
|
888
|
+
|
889
|
+
@files = Cnvrg::Datafiles.new(@dataset.owner, @dataset.slug)
|
890
|
+
new_branch = options["new_branch"] || false
|
891
|
+
|
892
|
+
res = @dataset.compare_idx(new_branch)["result"]
|
893
|
+
|
894
|
+
result = res["tree"]
|
895
|
+
|
896
|
+
commit = res["commit"]
|
897
|
+
if result["updated_on_server"].empty? and result["conflicts"].empty? and result["deleted"].empty?
|
898
|
+
say "Project is up to date", Thor::Shell::Color::GREEN unless (options["sync"] or sync)
|
899
|
+
log_end(0)
|
900
|
+
return true
|
901
|
+
end
|
902
|
+
result = @dataset.downlowd_updated_data(@dataset.last_local_commit)
|
903
|
+
|
904
|
+
delete = result["result"]["delete"]
|
905
|
+
commits = result["result"]["commits"]
|
906
|
+
updated_idx = result["result"]["idx"]
|
907
|
+
commits.each do |c|
|
908
|
+
file_name = @files.download_data_file(c, dataset_dir)
|
909
|
+
|
910
|
+
if file_name.eql? false or file_name.nil?
|
911
|
+
##RETRY
|
912
|
+
next
|
913
|
+
end
|
914
|
+
file_path = "#{dataset_dir}/#{file_name}"
|
915
|
+
success = extarct_tar(file_path, dataset_dir)
|
916
|
+
if !success
|
917
|
+
#TODO: ?
|
918
|
+
end
|
919
|
+
|
920
|
+
FileUtils.rm_rf([file_path])
|
921
|
+
|
922
|
+
end
|
923
|
+
to_delete = []
|
924
|
+
delete.each do |d|
|
925
|
+
to_delete << "#{dataset_dir}/#{d}"
|
926
|
+
end
|
927
|
+
FileUtils.rm_rf(to_delete)
|
928
|
+
|
929
|
+
@dataset.update_idx(updated_idx)
|
930
|
+
|
931
|
+
|
932
|
+
# result["conflicts"].each do |f|
|
933
|
+
# relative_path = f.gsub(/^#{@dataset.local_path}/, "")
|
934
|
+
# if @files.download_file_s3(f, relative_path, dataset_dir, conflict=true)
|
935
|
+
# successful_changes << relative_path
|
936
|
+
# end
|
937
|
+
#
|
938
|
+
# end
|
939
|
+
# update idx with latest commit
|
940
|
+
# @dataset.update_idx_with_commit!(commit)
|
941
|
+
check = Helpers.checkmark()
|
942
|
+
say "#{check} Downloaded changes successfully", Thor::Shell::Color::GREEN
|
943
|
+
|
944
|
+
|
945
|
+
log_end(0)
|
946
|
+
end
|
947
|
+
rescue
|
948
|
+
log_end(-1)
|
949
|
+
|
950
|
+
say "Error occurd, \nAborting", Thor::Shell::Color::BLUE
|
951
|
+
exit(1)
|
952
|
+
rescue SignalException
|
953
|
+
log_end(-1)
|
954
|
+
say "\nAborting", Thor::Shell::Color::BLUE
|
955
|
+
exit(1)
|
956
|
+
end
|
957
|
+
|
958
|
+
|
959
|
+
desc 'upload_data', 'Upload data files', :hide => true
|
960
|
+
method_option :ignore, :type => :array, :aliases => ["-i", "--i"], :desc => "ignore following files"
|
961
|
+
method_option :new_branch, :type => :boolean, :aliases => ["-nb", "--nb"], :desc => "create new branch of commits"
|
962
|
+
method_option :verbose, :type => :boolean, :aliases => ["-v"], :default => false
|
963
|
+
method_option :sync, :type => :boolean, :aliases => ["-s"], :default => false
|
964
|
+
|
965
|
+
def upload_data(sync=false, direct=false)
|
966
|
+
|
967
|
+
begin
|
968
|
+
verify_logged_in(true)
|
969
|
+
log_start(__method__, args, options)
|
970
|
+
dataset_dir = is_cnvrg_dir(Dir.pwd)
|
971
|
+
@dataset = Dataset.new(dataset_dir)
|
972
|
+
|
973
|
+
@files = Cnvrg::Datafiles.new(@dataset.owner, @dataset.slug)
|
974
|
+
ignore = options[:ignore] || []
|
975
|
+
if !@dataset.update_ignore_list(ignore)
|
976
|
+
say "Couldn't append new ignore files to .cnvrgignore", Thor::Shell::Color::YELLOW
|
977
|
+
end
|
978
|
+
result = @dataset.compare_idx(false)
|
979
|
+
|
980
|
+
commit = result["result"]["commit"]
|
981
|
+
if commit != @dataset.last_local_commit and !@dataset.last_local_commit.nil? and !result["result"]["tree"]["updated_on_server"].empty?
|
982
|
+
log_end(0)
|
983
|
+
|
984
|
+
say "Remote server has an updated version, please run `cnvrg download` first, or alternatively: `cnvrg sync`", Thor::Shell::Color::YELLOW
|
985
|
+
exit(1)
|
986
|
+
end
|
987
|
+
|
988
|
+
say "Comparing local changes with remote version:", Thor::Shell::Color::BLUE if options["verbose"]
|
989
|
+
result = result["result"]["tree"]
|
990
|
+
# if result["added"].any? {|x| x.include? ".conflict"} or !result["conflicts"].empty?
|
991
|
+
# all = result["added"].select {|x| x.include? ".conflict"} +result["conflicts"].flatten
|
992
|
+
# if all.size == 1
|
993
|
+
# num = "conflict"
|
994
|
+
# else
|
995
|
+
# num = "conflicts"
|
996
|
+
# end
|
997
|
+
# say "Project contains #{all.size} #{num}:", Thor::Shell::Color::RED
|
998
|
+
# say "#{all.join("\n")}"
|
999
|
+
# say "Please fix #{num}, and retry", Thor::Shell::Color::RED
|
1000
|
+
# exit(1)
|
1001
|
+
#
|
1002
|
+
# end
|
1003
|
+
check = Helpers.checkmark()
|
1004
|
+
|
1005
|
+
if result["added"].empty? and result["updated_on_local"].empty? and result["deleted"].empty?
|
1006
|
+
log_end(0)
|
1007
|
+
say "#{check} Dataset is up to date", Thor::Shell::Color::GREEN unless ((options["sync"] or sync) and !direct)
|
1008
|
+
return true
|
1009
|
+
end
|
1010
|
+
update_count = 0
|
1011
|
+
update_total = result["added"].size + result["updated_on_local"].size + result["deleted"].size
|
1012
|
+
successful_updates = []
|
1013
|
+
successful_deletions = []
|
1014
|
+
if options["verbose"]
|
1015
|
+
if update_total == 1
|
1016
|
+
say "Updating #{update_total} file", Thor::Shell::Color::BLUE
|
1017
|
+
else
|
1018
|
+
say "Updating #{update_total} files", Thor::Shell::Color::BLUE
|
1019
|
+
end
|
1020
|
+
else
|
1021
|
+
say "Syncing files", Thor::Shell::Color::BLUE unless (options["sync"] or sync)
|
1022
|
+
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
# Start commit
|
1026
|
+
|
1027
|
+
commit_sha1 = @files.start_commit(false)["result"]["commit_sha1"]
|
1028
|
+
# upload / update
|
1029
|
+
begin
|
1030
|
+
(result["added"] + result["updated_on_local"]).each do |f|
|
1031
|
+
absolute_path = "#{@dataset.local_path}/#{f}"
|
1032
|
+
relative_path = f.gsub(/^#{@dataset.local_path + "/"}/, "")
|
1033
|
+
if File.directory?(absolute_path)
|
1034
|
+
resDir = @files.create_dir(absolute_path, relative_path, commit_sha1)
|
1035
|
+
if resDir
|
1036
|
+
update_count += 1
|
1037
|
+
successful_updates<< relative_path
|
1038
|
+
end
|
1039
|
+
else
|
1040
|
+
res = @files.upload_file(absolute_path, relative_path, commit_sha1)
|
1041
|
+
|
1042
|
+
if res
|
1043
|
+
update_count += 1
|
1044
|
+
successful_updates<< relative_path
|
1045
|
+
else
|
1046
|
+
@files.rollback_commit(commit_sha1)
|
1047
|
+
log_end(1, "can't upload, Rolling Back all changes")
|
1048
|
+
say "Couldn't upload, Rolling Back all changes.", Thor::Shell::Color::RED
|
1049
|
+
exit(0)
|
1050
|
+
end
|
1051
|
+
end
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
# delete
|
1055
|
+
deleted = update_deleted(result["deleted"])
|
1056
|
+
deleted.each do |f|
|
1057
|
+
relative_path = f.gsub(/^#{@dataset.local_path + "/"}/, "")
|
1058
|
+
if relative_path.end_with?("/")
|
1059
|
+
if @files.delete_dir(f, relative_path, commit_sha1)
|
1060
|
+
# update_count += 1
|
1061
|
+
successful_updates<< relative_path
|
1062
|
+
end
|
1063
|
+
else
|
1064
|
+
if @files.delete_file(f, relative_path, commit_sha1)
|
1065
|
+
# update_count += 1
|
1066
|
+
successful_updates<< relative_path
|
1067
|
+
end
|
1068
|
+
end
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
rescue SignalException
|
1072
|
+
log_end(-1)
|
1073
|
+
@files.rollback_commit(commit_sha1)
|
1074
|
+
say "User aborted, Rolling Back all changes.", Thor::Shell::Color::RED
|
1075
|
+
exit(0)
|
1076
|
+
rescue => e
|
1077
|
+
log_end(-1, e.message)
|
1078
|
+
@files.rollback_commit(commit_sha1)
|
1079
|
+
say "Exception while trying to upload, Rolling back", Thor::Shell::Color::RED
|
1080
|
+
exit(0)
|
1081
|
+
end
|
1082
|
+
if !result["deleted"].nil? and !result["deleted"].empty?
|
1083
|
+
update_count += result["deleted"].size
|
1084
|
+
end
|
1085
|
+
if update_count == update_total
|
1086
|
+
res = @files.end_commit(commit_sha1)
|
1087
|
+
if (Cnvrg::CLI.is_response_success(res, false))
|
1088
|
+
# save idx
|
1089
|
+
begin
|
1090
|
+
@dataset.update_idx_with_files_commits!((successful_deletions+successful_updates), res["result"]["commit_time"])
|
1091
|
+
|
1092
|
+
@dataset.update_idx_with_commit!(commit_sha1)
|
1093
|
+
rescue => e
|
1094
|
+
log_end(-1, e.message)
|
1095
|
+
@files.rollback_commit(commit_sha1)
|
1096
|
+
say "Couldn't commit updates, Rolling Back all changes.", Thor::Shell::Color::RED
|
1097
|
+
exit(1)
|
1098
|
+
|
1099
|
+
end
|
1100
|
+
if options["verbose"]
|
1101
|
+
say "#{check} Done", Thor::Shell::Color::BLUE
|
1102
|
+
if successful_updates.size >0
|
1103
|
+
say "Updated:", Thor::Shell::Color::GREEN
|
1104
|
+
suc = successful_updates.map { |x| x=Helpers.checkmark() +" "+x }
|
1105
|
+
say suc.join("\n"), Thor::Shell::Color::GREEN
|
1106
|
+
end
|
1107
|
+
if successful_deletions.size >0
|
1108
|
+
say "Deleted:", Thor::Shell::Color::GREEN
|
1109
|
+
del = successful_updates.map { |x| x=Helpers.checkmark() +" "+x }
|
1110
|
+
say del.join("\n"), Thor::Shell::Color::GREEN
|
1111
|
+
end
|
1112
|
+
say "Total of #{update_count} / #{update_total} files.", Thor::Shell::Color::GREEN
|
1113
|
+
else
|
1114
|
+
if (options["sync"] or sync) and direct
|
1115
|
+
say "#{check} Syncing dataset completed successfully", Thor::Shell::Color::GREEN
|
1116
|
+
|
1117
|
+
else
|
1118
|
+
say "#{check} Changes were updated successfully", Thor::Shell::Color::GREEN
|
1119
|
+
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
log_end(0)
|
1125
|
+
else
|
1126
|
+
@files.rollback_commit(commit_sha1)
|
1127
|
+
log_end(1, "error. Rolling Back all changes")
|
1128
|
+
say "Error. Rolling Back all changes.", Thor::Shell::Color::RED
|
1129
|
+
end
|
1130
|
+
else
|
1131
|
+
log_end(1, "error. Rolling Back all changes")
|
1132
|
+
say "Error occurd, \nRolling back", Thor::Shell::Color::RED
|
1133
|
+
|
1134
|
+
@files.rollback_commit(commit_sha1)
|
1135
|
+
end
|
1136
|
+
rescue => e
|
1137
|
+
|
1138
|
+
log_end(-1)
|
1139
|
+
|
1140
|
+
say "Error occurd, \nAborting", Thor::Shell::Color::RED
|
1141
|
+
@files.rollback_commit(commit_sha1)
|
1142
|
+
exit(1)
|
1143
|
+
rescue SignalException
|
1144
|
+
log_end(-1)
|
1145
|
+
|
1146
|
+
say "\nAborting", Thor::Shell::Color::BLUE
|
1147
|
+
say "\nRolling back all changes", Thor::Shell::Color::BLUE
|
1148
|
+
@files.rollback_commit(commit_sha1)
|
1149
|
+
exit(1)
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
end
|
1153
|
+
|
1154
|
+
desc 'data upload', 'push data'
|
1155
|
+
method_option :ignore, :type => :array, :aliases => ["-i", "--i"], :desc => "ignore following files"
|
1156
|
+
method_option :verbose, :type => :boolean, :aliases => ["-v"], :default => false
|
1157
|
+
method_option :sync, :type => :boolean, :aliases => ["-s"], :default => false
|
1158
|
+
method_option :no_compression, :type => :boolean, :aliases => ["-nc", "--no_compression"], :default => false
|
1159
|
+
|
1160
|
+
def upload_data_tar(ignore, verbose, sync,no_compression)
|
1161
|
+
|
1162
|
+
begin
|
1163
|
+
verify_logged_in(true)
|
1164
|
+
log_start(__method__, args, options)
|
1165
|
+
dataset_dir = is_cnvrg_dir(Dir.pwd)
|
1166
|
+
|
1167
|
+
@dataset = Dataset.new(dataset_dir)
|
1168
|
+
|
1169
|
+
@files = Cnvrg::Datafiles.new(@dataset.owner, @dataset.slug)
|
1170
|
+
if !@dataset.update_ignore_list(ignore)
|
1171
|
+
say "Couldn't append new ignore files to .cnvrgignore", Thor::Shell::Color::RED
|
1172
|
+
exit(1)
|
1173
|
+
end
|
1174
|
+
say "Checking dataset", Thor::Shell::Color::BLUE
|
1175
|
+
local_idx = @dataset.generate_idx
|
1176
|
+
result = @dataset.compare_idx(false, commit=@dataset.last_local_commit, local_idx= local_idx)
|
1177
|
+
|
1178
|
+
|
1179
|
+
commit = result["result"]["commit"]
|
1180
|
+
if commit != @dataset.last_local_commit and !@dataset.last_local_commit.nil? and !result["result"]["tree"]["updated_on_server"].empty?
|
1181
|
+
log_end(0)
|
1182
|
+
|
1183
|
+
say "Remote server has an updated version, please run `cnvrg data download` first", Thor::Shell::Color::YELLOW
|
1184
|
+
exit(1)
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
say "Comparing local changes with remote version:", Thor::Shell::Color::BLUE if verbose
|
1188
|
+
result = result["result"]["tree"]
|
1189
|
+
check = Helpers.checkmark()
|
1190
|
+
|
1191
|
+
if result["added"].empty? and result["updated_on_local"].empty? and result["deleted"].empty?
|
1192
|
+
log_end(0)
|
1193
|
+
say "#{check} Dataset is up to date", Thor::Shell::Color::GREEN unless (sync)
|
1194
|
+
return true
|
1195
|
+
end
|
1196
|
+
update_count = 0
|
1197
|
+
update_total = result["added"].size + result["updated_on_local"].size + result["deleted"].size
|
1198
|
+
successful_updates = []
|
1199
|
+
successful_deletions = []
|
1200
|
+
|
1201
|
+
# Start commit
|
1202
|
+
res = @files.start_commit(false)["result"]
|
1203
|
+
commit_sha1 =res["commit_sha1"]
|
1204
|
+
commit_time = res["commit_time"]
|
1205
|
+
# upload / update
|
1206
|
+
begin
|
1207
|
+
(result["added"] + result["updated_on_local"]).each do |f|
|
1208
|
+
relative_path = f.gsub(/^#{@dataset.local_path + "/"}/, "")
|
1209
|
+
successful_updates<< relative_path
|
1210
|
+
update_count += 1
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
# delete
|
1214
|
+
deleted = update_deleted(result["deleted"])
|
1215
|
+
deleted.each do |f|
|
1216
|
+
relative_path = f.gsub(/^#{@dataset.local_path + "/"}/, "")
|
1217
|
+
successful_updates<< relative_path
|
1218
|
+
end
|
1219
|
+
@dataset.update_idx_with_files_commits!((successful_deletions+successful_updates), commit_time)
|
1220
|
+
|
1221
|
+
@dataset.update_idx_with_commit!(commit_sha1)
|
1222
|
+
say "Compressing data", Thor::Shell::Color::BLUE
|
1223
|
+
|
1224
|
+
home_dir = File.expand_path('~')
|
1225
|
+
compression_path = get_compression_path
|
1226
|
+
tar_path = "#{compression_path}#{@dataset.slug}_#{commit_sha1}.tar.gz"
|
1227
|
+
tar_files_path = "#{home_dir}/.cnvrg/tmp/#{@dataset.slug}_#{commit_sha1}.txt"
|
1228
|
+
tar_files = (result["added"] + result["updated_on_local"]).join("\n")
|
1229
|
+
File.open(tar_files_path, 'w') { |f| f.write tar_files }
|
1230
|
+
is_tar = create_tar(dataset_dir, tar_path, tar_files_path,no_compression)
|
1231
|
+
if !is_tar
|
1232
|
+
say "ERROR: Couldn't compress data", Thor::Shell::Color::RED
|
1233
|
+
FileUtils.rm_rf([tar_path]) if File.exist? tar_path
|
1234
|
+
FileUtils.rm_rf([tar_files_path]) if File.exist? tar_files_path
|
1235
|
+
@files.rollback_commit(commit_sha1)
|
1236
|
+
say "Rolling Back all changes.", Thor::Shell::Color::RED
|
1237
|
+
exit(1)
|
1238
|
+
end
|
1239
|
+
say "Uploading data", Thor::Shell::Color::BLUE
|
1240
|
+
res = false
|
1241
|
+
res = @files.upload_tar_file(tar_path, tar_path, commit_sha1)
|
1242
|
+
|
1243
|
+
if res
|
1244
|
+
say "Commiting data", Thor::Shell::Color::BLUE
|
1245
|
+
|
1246
|
+
cur_idx = @dataset.get_idx.to_h
|
1247
|
+
|
1248
|
+
res = @files.end_commit_tar(commit_sha1, cur_idx)
|
1249
|
+
if !Cnvrg::CLI.is_response_success(res, false)
|
1250
|
+
FileUtils.rm_rf([tar_files_path]) if File.exist? tar_files_path
|
1251
|
+
FileUtils.rm_rf([tar_path]) if File.exist? tar_path
|
1252
|
+
|
1253
|
+
|
1254
|
+
@files.rollback_commit(commit_sha1)
|
1255
|
+
say "Can't commit, Rolling Back all changes.", Thor::Shell::Color::RED
|
1256
|
+
exit(1)
|
1257
|
+
end
|
1258
|
+
|
1259
|
+
else
|
1260
|
+
FileUtils.rm_rf([tar_files_path]) if File.exist? tar_files_path
|
1261
|
+
FileUtils.rm_rf([tar_path]) if File.exist? tar_path
|
1262
|
+
|
1263
|
+
|
1264
|
+
@files.rollback_commit(commit_sha1)
|
1265
|
+
say "Can't upload, Rolling Back all changes.", Thor::Shell::Color::RED
|
1266
|
+
exit(1)
|
1267
|
+
end
|
1268
|
+
|
1269
|
+
|
1270
|
+
# delete
|
1271
|
+
FileUtils.rm_rf([tar_path, tar_files_path])
|
1272
|
+
|
1273
|
+
rescue SignalException
|
1274
|
+
log_end(-1)
|
1275
|
+
FileUtils.rm_rf([tar_files_path]) if File.exist? tar_files_path
|
1276
|
+
FileUtils.rm_rf([tar_path]) if File.exist? tar_path
|
1277
|
+
|
1278
|
+
|
1279
|
+
@files.rollback_commit(commit_sha1)
|
1280
|
+
say "User aborted, Rolling Back all changes.", Thor::Shell::Color::RED
|
1281
|
+
exit(0)
|
1282
|
+
rescue => e
|
1283
|
+
puts e.message
|
1284
|
+
if !Cnvrg::Helpers.internet_connection?
|
1285
|
+
say "Seems there is no internet connection", Thor::Shell::Color::RED
|
1286
|
+
|
1287
|
+
end
|
1288
|
+
FileUtils.rm_rf([tar_files_path]) if File.exist? tar_files_path
|
1289
|
+
FileUtils.rm_rf([tar_path]) if File.exist? tar_path
|
1290
|
+
|
1291
|
+
log_end(-1, e.message)
|
1292
|
+
@files.rollback_commit(commit_sha1)
|
1293
|
+
say "Exception while trying to upload, Rolling back", Thor::Shell::Color::RED
|
1294
|
+
exit(0)
|
1295
|
+
end
|
1296
|
+
if verbose
|
1297
|
+
say "#{check} Done", Thor::Shell::Color::BLUE
|
1298
|
+
if successful_updates.size >0
|
1299
|
+
say "Updated:", Thor::Shell::Color::GREEN
|
1300
|
+
suc = successful_updates.map { |x| x=Helpers.checkmark() +" "+x }
|
1301
|
+
say suc.join("\n"), Thor::Shell::Color::GREEN
|
1302
|
+
end
|
1303
|
+
if successful_deletions.size >0
|
1304
|
+
say "Deleted:", Thor::Shell::Color::GREEN
|
1305
|
+
del = successful_updates.map { |x| x=Helpers.checkmark() +" "+x }
|
1306
|
+
say del.join("\n"), Thor::Shell::Color::GREEN
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
|
1310
|
+
say "Total of #{update_count} / #{update_total} files.", Thor::Shell::Color::GREEN
|
1311
|
+
else
|
1312
|
+
say "#{check} Changes were updated successfully", Thor::Shell::Color::GREEN
|
1313
|
+
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
|
1317
|
+
rescue => e
|
1318
|
+
log_end(-1, e.message)
|
1319
|
+
|
1320
|
+
|
1321
|
+
say "Error occurd, \nAborting", Thor::Shell::Color::RED
|
1322
|
+
@files.rollback_commit(commit_sha1)
|
1323
|
+
exit(1)
|
1324
|
+
rescue SignalException
|
1325
|
+
log_end(-1)
|
1326
|
+
|
1327
|
+
say "\nAborting", Thor::Shell::Color::BLUE
|
1328
|
+
say "\nRolling back all changes", Thor::Shell::Color::BLUE
|
1329
|
+
@files.rollback_commit(commit_sha1)
|
1330
|
+
exit(1)
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
log_end(0)
|
1334
|
+
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
|
1338
|
+
desc 'unlink', 'Unlink a project from current directory', :hide => true
|
1339
|
+
|
1340
|
+
def create_volume
|
1341
|
+
verify_logged_in(false)
|
1342
|
+
log_start(__method__, args, options)
|
1343
|
+
dataset_dir = is_cnvrg_dir(Dir.pwd)
|
1344
|
+
@dataset = Dataset.new(dataset_dir)
|
1345
|
+
@dataset.create_volume()
|
1346
|
+
|
1347
|
+
end
|
1348
|
+
|
1349
|
+
desc 'data list', 'List all dataset you currently have'
|
1350
|
+
|
1351
|
+
def list_dataset
|
1352
|
+
verify_logged_in(false)
|
1353
|
+
log_start(__method__, args, options)
|
1354
|
+
dataset_dir = is_cnvrg_dir(Dir.pwd)
|
1355
|
+
@dataset = Dataset.new(dataset_dir)
|
1356
|
+
owner = @dataset.owner
|
1357
|
+
if owner.nil? or owner.empty?
|
1358
|
+
owner = CLI.get_owner()
|
1359
|
+
end
|
1360
|
+
result = @dataset.list(owner)
|
1361
|
+
list = result["result"]["list"]
|
1362
|
+
|
1363
|
+
print_table(list)
|
1364
|
+
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
desc 'data commits', 'List all commits for a specific dataset'
|
1368
|
+
|
1369
|
+
def list_dataset_commits()
|
1370
|
+
verify_logged_in(true)
|
1371
|
+
log_start(__method__, args, options)
|
1372
|
+
|
1373
|
+
dataset_dir = is_cnvrg_dir(Dir.pwd)
|
1374
|
+
@dataset = Dataset.new(dataset_dir)
|
1375
|
+
result = @dataset.list_commits()
|
1376
|
+
list = result["result"]["list"]
|
1377
|
+
|
1378
|
+
print_table(list)
|
1379
|
+
|
1380
|
+
end
|
1381
|
+
|
1382
|
+
desc 'commits', 'List all commits for a specific dataset'
|
1383
|
+
|
1384
|
+
def list_commits()
|
1385
|
+
verify_logged_in(true)
|
1386
|
+
log_start(__method__, args, options)
|
1387
|
+
|
1388
|
+
project_dir = is_cnvrg_dir(Dir.pwd)
|
1389
|
+
@project = Project.new(project_dir)
|
1390
|
+
result = @project.list_commits()
|
1391
|
+
list = result["result"]["list"]
|
1392
|
+
|
1393
|
+
print_table(list)
|
1394
|
+
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
|
1398
|
+
desc 'unlink', 'Unlink a project from current directory'
|
1399
|
+
|
1400
|
+
def unlink
|
1401
|
+
verify_logged_in(false)
|
1402
|
+
log_start(__method__, args, options)
|
1403
|
+
working_dir = is_cnvrg_dir()
|
1404
|
+
list_to_del = [working_dir+"/.cnvrgignore", working_dir+"/.cnvrg"]
|
1405
|
+
FileUtils.rm_rf list_to_del
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
desc 'clone', 'Clone project'
|
1409
|
+
method_option :remote, :type => :boolean, :aliases => ["-r", "--r"], :default => false
|
1410
|
+
method_option :commit, :type => :string, :aliases => ["-c", "--c"], :default => nil
|
1411
|
+
|
1412
|
+
def clone(project_url)
|
1413
|
+
begin
|
1414
|
+
verify_logged_in(false)
|
1415
|
+
log_start(__method__, args, options)
|
1416
|
+
url_parts = project_url.split("/")
|
1417
|
+
project_index = Cnvrg::Helpers.look_for_in_path(project_url, "projects")
|
1418
|
+
slug = url_parts[project_index+1]
|
1419
|
+
owner = url_parts[project_index-1]
|
1420
|
+
remote = options["remote"] || false
|
1421
|
+
response = Cnvrg::API.request("users/#{owner}/projects/#{slug}/get_project", 'GET')
|
1422
|
+
Cnvrg::CLI.is_response_success(response)
|
1423
|
+
response = JSON.parse response["result"]
|
1424
|
+
project_name = response["title"]
|
1425
|
+
commit_to_clone = options["commit"] || nil
|
1426
|
+
|
1427
|
+
say "Cloning #{project_name}", Thor::Shell::Color::BLUE
|
1428
|
+
clone_resp = false
|
1429
|
+
if remote
|
1430
|
+
clone_resp = Project.clone_dir_remote(slug, owner, project_name)
|
1431
|
+
project_home = Dir.pwd
|
1432
|
+
else
|
1433
|
+
if (Dir.exists? project_name)
|
1434
|
+
say "Error: Conflict with dir #{project_name}", Thor::Shell::Color::RED
|
1435
|
+
if no? "Sync to repository anyway? (current data might lost)", Thor::Shell::Color::YELLOW
|
1436
|
+
say "Remove dir in order to clone #{project_name}", Thor::Shell::Color::RED
|
1437
|
+
log_end(1, "conflict with dir #{project_name}")
|
1438
|
+
|
1439
|
+
exit(1)
|
1440
|
+
end
|
1441
|
+
|
1442
|
+
end
|
1443
|
+
clone_resp = Project.clone_dir(slug, owner, project_name)
|
1444
|
+
project_home = Dir.pwd+"/"+project_name
|
1445
|
+
|
1446
|
+
|
1447
|
+
end
|
1448
|
+
|
1449
|
+
if clone_resp
|
1450
|
+
@project = Project.new(project_home)
|
1451
|
+
@files = Cnvrg::Files.new(@project.owner, slug)
|
1452
|
+
response = @project.clone(remote, commit_to_clone)
|
1453
|
+
Cnvrg::CLI.is_response_success response
|
1454
|
+
working_dir = project_home
|
1455
|
+
docker_image = response["result"]["image"]
|
1456
|
+
current_commit = response["result"]["commit"]
|
1457
|
+
idx = {commit: response["result"]["commit"], tree: response["result"]["tree"]}
|
1458
|
+
File.open(working_dir + "/.cnvrg/idx.yml", "w+") { |f| f.write idx.to_yaml }
|
1459
|
+
if !docker_image.nil? and !docker_image.empty? and !remote
|
1460
|
+
local_images = Docker::Image.all
|
1461
|
+
docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.eql? "#{docker_image}:latest" }.flatten
|
1462
|
+
if docker_image_local.size == 0
|
1463
|
+
if yes? "Image wasn't found locally, pull image from cnvrg repository?", Thor::Shell::Color::YELLOW
|
1464
|
+
image = pull(docker_image)
|
1465
|
+
if image
|
1466
|
+
say "downloaded image: #{docker_image}"
|
1467
|
+
@image = Images.new(working_dir, docker_image)
|
1468
|
+
else
|
1469
|
+
say "Could not create a new project with docker, image was not found", Thor::Shell::Color::RED
|
1470
|
+
@project.revert(working_dir)
|
1471
|
+
exit(1)
|
1472
|
+
end
|
1473
|
+
end
|
1474
|
+
|
1475
|
+
elsif docker_image_local.size == 1
|
1476
|
+
say "found image: #{docker_image_local[0]}, setting it up..", Thor::Shell::Color::BLUE
|
1477
|
+
@image = Images.new(working_dir, docker_image_local[0])
|
1478
|
+
elsif docker_image_local.size >1
|
1479
|
+
say "found #{docker_image_local.size} images, choose the image name you want to use", Thor::Shell::Color::BLUE
|
1480
|
+
image_name = ask "#{docker_image_local.join("\n")}\n", Thor::Shell::Color::BLUE
|
1481
|
+
@image = Images.new(working_dir, image_name)
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
end
|
1485
|
+
|
1486
|
+
successful_changes = []
|
1487
|
+
say "Downloading files", Thor::Shell::Color::BLUE
|
1488
|
+
if !response["result"]["tree"].nil?
|
1489
|
+
response["result"]["tree"].each do |f|
|
1490
|
+
relative_path = f[0].gsub(/^#{@project.local_path}/, "")
|
1491
|
+
if f[0].end_with? "/"
|
1492
|
+
# dir
|
1493
|
+
if @files.download_dir(f[0], relative_path, project_home)
|
1494
|
+
successful_changes << relative_path
|
1495
|
+
end
|
1496
|
+
else
|
1497
|
+
# blob
|
1498
|
+
|
1499
|
+
if @files.download_file_s3(f[0], relative_path, project_home, commit_sha1=current_commit)
|
1500
|
+
successful_changes << relative_path
|
1501
|
+
end
|
1502
|
+
end
|
1503
|
+
end
|
1504
|
+
end
|
1505
|
+
|
1506
|
+
say "Done.\nDownloaded total of #{successful_changes.size} files", Thor::Shell::Color::GREEN
|
1507
|
+
log_end(0)
|
1508
|
+
else
|
1509
|
+
log_end(1, "can't create directory")
|
1510
|
+
|
1511
|
+
say "Error: Couldn't create directory: #{project_name}", Thor::Shell::Color::RED
|
1512
|
+
exit(1)
|
1513
|
+
end
|
1514
|
+
rescue SignalException
|
1515
|
+
log_end(-1)
|
1516
|
+
say "\nAborting"
|
1517
|
+
exit(1)
|
1518
|
+
end
|
1519
|
+
|
1520
|
+
end
|
1521
|
+
|
1522
|
+
|
1523
|
+
desc 'status', 'Show the working tree status'
|
1524
|
+
method_option :new_branch, :type => :boolean, :aliases => ["-nb", "--nb"], :desc => "create new branch of commits"
|
1525
|
+
|
1526
|
+
|
1527
|
+
def status
|
1528
|
+
begin
|
1529
|
+
verify_logged_in()
|
1530
|
+
log_start(__method__, args, options)
|
1531
|
+
@project = Project.new(get_project_home)
|
1532
|
+
new_branch = options["new_branch"] || false
|
1533
|
+
|
1534
|
+
result = @project.compare_idx(new_branch)["result"]
|
668
1535
|
commit = result["commit"]
|
669
1536
|
result = result["tree"]
|
670
1537
|
say "Comparing local changes with remote version:", Thor::Shell::Color::BLUE
|
1538
|
+
|
671
1539
|
if result["added"].empty? and result["updated_on_local"].empty? and result["updated_on_server"].empty? and result["deleted"].empty? and result["conflicts"].empty?
|
672
1540
|
say "Project is up to date", Thor::Shell::Color::GREEN
|
673
1541
|
log_end(0)
|
@@ -714,14 +1582,36 @@ module Cnvrg
|
|
714
1582
|
end
|
715
1583
|
end
|
716
1584
|
|
1585
|
+
desc '', '', :hide => true
|
1586
|
+
|
1587
|
+
def revert_exp
|
1588
|
+
begin
|
1589
|
+
log_start(__method__, args, options)
|
1590
|
+
@project = Project.new(get_project_home)
|
1591
|
+
|
1592
|
+
result = @project.compare_idx(false)["result"]
|
1593
|
+
result = result["tree"]
|
1594
|
+
if result["added"].size > 0
|
1595
|
+
FileUtils.rm_rf(result["added"])
|
1596
|
+
end
|
1597
|
+
say "Changes were removed successfully", Thor::Shell::Color::GREEN
|
1598
|
+
|
1599
|
+
|
1600
|
+
rescue SignalException
|
1601
|
+
log_end(-1)
|
1602
|
+
say "\nAborting"
|
1603
|
+
exit(1)
|
1604
|
+
end
|
1605
|
+
end
|
1606
|
+
|
717
1607
|
|
718
1608
|
desc 'upload', 'Upload updated files'
|
719
|
-
method_option :ignore, :type => :
|
720
|
-
method_option :new_branch, :type => :boolean, :aliases => ["-nb"
|
721
|
-
method_option :verbose, :type => :boolean, :aliases => ["
|
722
|
-
method_option :sync, :type => :boolean, :aliases => ["
|
1609
|
+
method_option :ignore, :type => :string, :aliases => ["-i"], :desc => "ignore following files", :default => ""
|
1610
|
+
method_option :new_branch, :type => :boolean, :aliases => ["-nb"], :desc => "create new branch of commits"
|
1611
|
+
method_option :verbose, :type => :boolean, :aliases => ["-v"], :default => false
|
1612
|
+
method_option :sync, :type => :boolean, :aliases => ["-s"], :default => false
|
723
1613
|
|
724
|
-
def upload(link=false, sync=false)
|
1614
|
+
def upload(link=false, sync=false, direct=false, ignore_list="")
|
725
1615
|
|
726
1616
|
begin
|
727
1617
|
verify_logged_in(true)
|
@@ -730,12 +1620,30 @@ module Cnvrg
|
|
730
1620
|
@project = Project.new(get_project_home)
|
731
1621
|
|
732
1622
|
@files = Cnvrg::Files.new(@project.owner, @project.slug)
|
733
|
-
ignore = options[:ignore] ||
|
1623
|
+
ignore = options[:ignore] || ""
|
1624
|
+
|
1625
|
+
if ignore.nil? or ignore.empty?
|
1626
|
+
ignore = ignore_list
|
1627
|
+
end
|
1628
|
+
data_ignore = data_dir_include()
|
1629
|
+
if !data_ignore.nil?
|
1630
|
+
if ignore.nil? or ignore.empty?
|
1631
|
+
ignore = data_ignore
|
1632
|
+
else
|
1633
|
+
ignore ="#{ignore},#{data_ignore}"
|
1634
|
+
end
|
1635
|
+
end
|
734
1636
|
if !@project.update_ignore_list(ignore)
|
735
1637
|
say "Couldn't append new ignore files to .cnvrgignore", Thor::Shell::Color::YELLOW
|
736
1638
|
end
|
737
1639
|
new_branch = options["new_branch"] || false
|
738
1640
|
|
1641
|
+
if options["sync"] or sync
|
1642
|
+
new_branch_exp = @project.get_new_branch
|
1643
|
+
if new_branch_exp
|
1644
|
+
new_branch = new_branch_exp
|
1645
|
+
end
|
1646
|
+
end
|
739
1647
|
result = @project.compare_idx(new_branch)
|
740
1648
|
commit = result["result"]["commit"]
|
741
1649
|
if !link
|
@@ -749,9 +1657,23 @@ module Cnvrg
|
|
749
1657
|
say "Comparing local changes with remote version:", Thor::Shell::Color::BLUE if options["verbose"]
|
750
1658
|
end
|
751
1659
|
result = result["result"]["tree"]
|
1660
|
+
# if result["added"].any? {|x| x.include? ".conflict"} or !result["conflicts"].empty?
|
1661
|
+
# all = result["added"].select {|x| x.include? ".conflict"} +result["conflicts"].flatten
|
1662
|
+
# if all.size == 1
|
1663
|
+
# num = "conflict"
|
1664
|
+
# else
|
1665
|
+
# num = "conflicts"
|
1666
|
+
# end
|
1667
|
+
# say "Project contains #{all.size} #{num}:", Thor::Shell::Color::RED
|
1668
|
+
# say "#{all.join("\n")}"
|
1669
|
+
# say "Please fix #{num}, and retry", Thor::Shell::Color::RED
|
1670
|
+
# exit(1)
|
1671
|
+
#
|
1672
|
+
# end
|
1673
|
+
check = Helpers.checkmark()
|
752
1674
|
if result["added"].empty? and result["updated_on_local"].empty? and result["deleted"].empty?
|
753
1675
|
log_end(0)
|
754
|
-
say "Project is up to date", Thor::Shell::Color::GREEN unless options["sync"]
|
1676
|
+
say "#{check} Project is up to date", Thor::Shell::Color::GREEN unless ((options["sync"] or sync) and !direct)
|
755
1677
|
return true
|
756
1678
|
end
|
757
1679
|
update_count = 0
|
@@ -765,7 +1687,7 @@ module Cnvrg
|
|
765
1687
|
say "Updating #{update_total} files", Thor::Shell::Color::BLUE
|
766
1688
|
end
|
767
1689
|
else
|
768
|
-
say "Syncing files", Thor::Shell::Color::BLUE unless options["sync"]
|
1690
|
+
say "Syncing files", Thor::Shell::Color::BLUE unless (options["sync"] or sync)
|
769
1691
|
|
770
1692
|
end
|
771
1693
|
|
@@ -799,21 +1721,21 @@ module Cnvrg
|
|
799
1721
|
end
|
800
1722
|
|
801
1723
|
# delete
|
802
|
-
result["deleted"]
|
1724
|
+
deleted = update_deleted(result["deleted"])
|
1725
|
+
deleted.each do |f|
|
803
1726
|
relative_path = f.gsub(/^#{@project.local_path + "/"}/, "")
|
804
1727
|
if relative_path.end_with?("/")
|
805
1728
|
if @files.delete_dir(f, relative_path, commit_sha1)
|
806
|
-
update_count += 1
|
1729
|
+
# update_count += 1
|
807
1730
|
successful_updates<< relative_path
|
808
1731
|
end
|
809
1732
|
else
|
810
1733
|
if @files.delete_file(f, relative_path, commit_sha1)
|
811
|
-
update_count += 1
|
1734
|
+
# update_count += 1
|
812
1735
|
successful_updates<< relative_path
|
813
1736
|
end
|
814
1737
|
end
|
815
1738
|
end
|
816
|
-
log_end(0)
|
817
1739
|
|
818
1740
|
rescue SignalException
|
819
1741
|
log_end(-1)
|
@@ -821,11 +1743,14 @@ module Cnvrg
|
|
821
1743
|
say "User aborted, Rolling Back all changes.", Thor::Shell::Color::RED
|
822
1744
|
exit(0)
|
823
1745
|
rescue => e
|
824
|
-
log_end(1, e.message)
|
1746
|
+
log_end(-1, e.message)
|
825
1747
|
@files.rollback_commit(commit_sha1)
|
826
1748
|
say "Exception while trying to upload, Rolling back", Thor::Shell::Color::RED
|
827
1749
|
exit(0)
|
828
1750
|
end
|
1751
|
+
if !result["deleted"].nil? and !result["deleted"].empty?
|
1752
|
+
update_count += result["deleted"].size
|
1753
|
+
end
|
829
1754
|
if update_count == update_total
|
830
1755
|
res = @files.end_commit(commit_sha1)
|
831
1756
|
if (Cnvrg::CLI.is_response_success(res, false))
|
@@ -835,7 +1760,7 @@ module Cnvrg
|
|
835
1760
|
|
836
1761
|
@project.update_idx_with_commit!(commit_sha1)
|
837
1762
|
rescue => e
|
838
|
-
log_end(1, e.message)
|
1763
|
+
log_end(-1, e.message)
|
839
1764
|
@files.rollback_commit(commit_sha1)
|
840
1765
|
say "Couldn't commit updates, Rolling Back all changes.", Thor::Shell::Color::RED
|
841
1766
|
exit(1)
|
@@ -845,7 +1770,6 @@ module Cnvrg
|
|
845
1770
|
if image and image.is_docker
|
846
1771
|
image.update_image_activity(commit_sha1, nil)
|
847
1772
|
end
|
848
|
-
check = Helpers.checkmark()
|
849
1773
|
|
850
1774
|
if options["verbose"]
|
851
1775
|
say "#{check} Done", Thor::Shell::Color::BLUE
|
@@ -861,7 +1785,13 @@ module Cnvrg
|
|
861
1785
|
end
|
862
1786
|
say "Total of #{update_count} / #{update_total} files.", Thor::Shell::Color::GREEN
|
863
1787
|
else
|
864
|
-
|
1788
|
+
if (options["sync"] or sync) and direct
|
1789
|
+
say "#{check} Syncing project completed successfully", Thor::Shell::Color::GREEN
|
1790
|
+
|
1791
|
+
else
|
1792
|
+
say "#{check} Changes were updated successfully", Thor::Shell::Color::GREEN
|
1793
|
+
|
1794
|
+
end
|
865
1795
|
|
866
1796
|
end
|
867
1797
|
|
@@ -873,13 +1803,14 @@ module Cnvrg
|
|
873
1803
|
end
|
874
1804
|
else
|
875
1805
|
log_end(1, "error. Rolling Back all changes")
|
1806
|
+
say "Error occurd, \nRolling back", Thor::Shell::Color::RED
|
876
1807
|
|
877
1808
|
@files.rollback_commit(commit_sha1)
|
878
1809
|
end
|
879
|
-
rescue
|
1810
|
+
rescue => e
|
880
1811
|
log_end(-1)
|
881
1812
|
|
882
|
-
say "Error occurd, \nAborting", Thor::Shell::Color::
|
1813
|
+
say "Error occurd, \nAborting", Thor::Shell::Color::RED
|
883
1814
|
@files.rollback_commit(commit_sha1)
|
884
1815
|
exit(1)
|
885
1816
|
rescue SignalException
|
@@ -894,27 +1825,57 @@ module Cnvrg
|
|
894
1825
|
end
|
895
1826
|
|
896
1827
|
desc 'download', 'Download updated files'
|
897
|
-
method_option :new_branch, :type => :boolean, :aliases => ["-nb"
|
898
|
-
method_option :verbose, :type => :boolean, :aliases => ["
|
899
|
-
method_option :sync, :type => :boolean, :aliases => ["
|
1828
|
+
method_option :new_branch, :type => :boolean, :aliases => ["-nb"], :desc => "create new branch of commits"
|
1829
|
+
method_option :verbose, :type => :boolean, :aliases => ["-v"], :default => false
|
1830
|
+
method_option :sync, :type => :boolean, :aliases => ["-s"], :default => false
|
1831
|
+
method_option :ignore, :type => :string, :aliases => ["-i"], :desc => "ignore following files", :default => ""
|
900
1832
|
|
901
|
-
def download
|
1833
|
+
def download(sync=false, ignore_list="")
|
902
1834
|
begin
|
903
1835
|
verify_logged_in(true)
|
904
1836
|
log_start(__method__, args, options)
|
905
1837
|
project_home = get_project_home
|
906
1838
|
@project = Project.new(project_home)
|
907
1839
|
@files = Cnvrg::Files.new(@project.owner, @project.slug)
|
1840
|
+
ignore = options[:ignore] || ""
|
1841
|
+
if ignore.nil? or ignore.empty?
|
1842
|
+
ignore = ignore_list
|
1843
|
+
end
|
1844
|
+
data_ignore = data_dir_include()
|
1845
|
+
if !data_ignore.nil?
|
1846
|
+
if ignore.nil? or ignore.empty?
|
1847
|
+
ignore = data_ignore
|
1848
|
+
else
|
1849
|
+
ignore ="#{ignore},#{data_ignore}"
|
1850
|
+
end
|
1851
|
+
end
|
1852
|
+
if !@project.update_ignore_list(ignore)
|
1853
|
+
say "Couldn't append new ignore files to .cnvrgignore", Thor::Shell::Color::YELLOW
|
1854
|
+
end
|
908
1855
|
new_branch = options["new_branch"] || false
|
909
1856
|
|
910
1857
|
res = @project.compare_idx(new_branch)["result"]
|
1858
|
+
|
911
1859
|
result = res["tree"]
|
1860
|
+
|
912
1861
|
commit = res["commit"]
|
913
|
-
if result["updated_on_server"].empty? and result["conflicts"] and result["deleted"].empty?
|
914
|
-
say "Project is up to date", Thor::Shell::Color::GREEN unless options["sync"]
|
1862
|
+
if result["updated_on_server"].empty? and result["conflicts"].empty? and result["deleted"].empty?
|
1863
|
+
say "Project is up to date", Thor::Shell::Color::GREEN unless (options["sync"] or sync)
|
915
1864
|
log_end(0)
|
916
1865
|
return true
|
917
1866
|
end
|
1867
|
+
# if result["added"].any? {|x| x.include? ".conflict"} or !result["conflicts"].empty?
|
1868
|
+
# all = result["added"].select {|x| x.include? ".conflict"} +result["conflicts"].flatten
|
1869
|
+
# if all.size == 1
|
1870
|
+
# num = "1 conflict"
|
1871
|
+
# else
|
1872
|
+
# num = "#{result["conflicts"].size} conflicts"
|
1873
|
+
# end
|
1874
|
+
# say "Project contains #{num}:", Thor::Shell::Color::RED
|
1875
|
+
# say "#{all.join("\n")}"
|
1876
|
+
# say "Please fix them, and retry", Thor::Shell::Color::RED
|
1877
|
+
# exit(1)
|
1878
|
+
# end
|
918
1879
|
update_count = 0
|
919
1880
|
update_total = result["updated_on_server"].size + result["conflicts"].size
|
920
1881
|
|
@@ -936,7 +1897,7 @@ module Cnvrg
|
|
936
1897
|
|
937
1898
|
result["conflicts"].each do |f|
|
938
1899
|
relative_path = f.gsub(/^#{@project.local_path}/, "")
|
939
|
-
if @files.download_file_s3(f, relative_path, project_home, conflict=true)
|
1900
|
+
if @files.download_file_s3(f, relative_path, project_home, commit_sha1=nil, conflict=true)
|
940
1901
|
successful_changes << relative_path
|
941
1902
|
end
|
942
1903
|
|
@@ -967,12 +1928,35 @@ module Cnvrg
|
|
967
1928
|
say successful_changes.join("\n"), Thor::Shell::Color::GREEN
|
968
1929
|
say "Total of #{successful_changes.size} / #{update_total} files.", Thor::Shell::Color::GREEN
|
969
1930
|
else
|
970
|
-
say "#{check} Downloaded changes successfully", Thor::Shell::Color::GREEN
|
1931
|
+
say "#{check} Downloaded changes successfully", Thor::Shell::Color::GREEN unless (sync or options["sync"])
|
971
1932
|
end
|
972
1933
|
|
973
1934
|
|
974
1935
|
log_end(0)
|
975
1936
|
end
|
1937
|
+
rescue => e
|
1938
|
+
log_end(-1)
|
1939
|
+
|
1940
|
+
say "Error occurd, \nAborting", Thor::Shell::Color::BLUE
|
1941
|
+
if successful_changes.nil?
|
1942
|
+
exit(1)
|
1943
|
+
end
|
1944
|
+
successful_changes.each do |f|
|
1945
|
+
|
1946
|
+
abs_path = "#{@project.local_path}/#{f}"
|
1947
|
+
filename = File.basename abs_path
|
1948
|
+
say "revoking #{filename}"
|
1949
|
+
if result["conflicts"].include? f
|
1950
|
+
@files.revoke_download_file(abs_path, f, filename, true)
|
1951
|
+
elsif result["updated_on_server"].include? f
|
1952
|
+
if File.directory? abs_path
|
1953
|
+
@files.revoke_download_dir(abs_path, f, project_home)
|
1954
|
+
else
|
1955
|
+
@files.revoke_download_file(project_home, abs_path, filename)
|
1956
|
+
end
|
1957
|
+
end
|
1958
|
+
end
|
1959
|
+
exit(1)
|
976
1960
|
rescue SignalException
|
977
1961
|
log_end(-1)
|
978
1962
|
say "\nAborting", Thor::Shell::Color::BLUE
|
@@ -1026,6 +2010,7 @@ module Cnvrg
|
|
1026
2010
|
if !response["result"]["tree"].nil?
|
1027
2011
|
idx = {commit: response["result"]["commit"], tree: response["result"]["tree"]}
|
1028
2012
|
File.open(project_home + "/.cnvrg/idx.yml", "w+") { |f| f.write idx.to_yaml }
|
2013
|
+
current_tree = Dir.entries(".").reject { |file| file.start_with? '.' or file.eql? "__init__.py" or file.eql? "uwsgi.ini" }
|
1029
2014
|
|
1030
2015
|
response["result"]["tree"].each do |f|
|
1031
2016
|
relative_path = f[0].gsub(/^#{@project.local_path}/, "")
|
@@ -1037,7 +2022,7 @@ module Cnvrg
|
|
1037
2022
|
end
|
1038
2023
|
else
|
1039
2024
|
# blob
|
1040
|
-
if @files.download_file_s3(f[0], relative_path, project_home)
|
2025
|
+
if @files.download_file_s3(f[0], relative_path, project_home, commit_sha1=commit_sha1)
|
1041
2026
|
current_tree.delete(relative_path)
|
1042
2027
|
|
1043
2028
|
successful_changes << relative_path
|
@@ -1055,43 +2040,100 @@ module Cnvrg
|
|
1055
2040
|
end
|
1056
2041
|
|
1057
2042
|
|
2043
|
+
desc 'data_jump', 'jump to specific commit', :hide => true
|
2044
|
+
|
2045
|
+
def data_jump(*commit_sha1)
|
2046
|
+
begin
|
2047
|
+
verify_logged_in()
|
2048
|
+
log_start(__method__, args, options)
|
2049
|
+
dataset_dir = is_cnvrg_dir(Dir.pwd)
|
2050
|
+
@dataset = Dataset.new(dataset_dir)
|
2051
|
+
|
2052
|
+
@files = Cnvrg::Datafiles.new(@dataset.owner, @dataset.slug)
|
2053
|
+
if commit_sha1.nil? or commit_sha1.empty?
|
2054
|
+
commit_sha1 = @dataset.last_local_commit
|
2055
|
+
end
|
2056
|
+
response = @dataset.compare_commits(commit_sha1)
|
2057
|
+
successful_changes = []
|
2058
|
+
if !response["result"]["status"].nil?
|
2059
|
+
idx = {commit: response["result"]["commit"], tree: response["result"]["tree"]}
|
2060
|
+
File.open(dataset_dir + "/.cnvrg/idx.yml", "w+") { |f| f.write idx.to_yaml }
|
2061
|
+
status = response["result"]["status"]
|
2062
|
+
(status["delete"]).each do |f|
|
2063
|
+
relative_path = f[0].gsub(/^#{@dataset.local_path}/, "")
|
2064
|
+
FileUtils.rm_rf(relative_path)
|
2065
|
+
end
|
2066
|
+
# current_tree = Dir.entries(".").reject { |file| file.start_with? '.' }
|
2067
|
+
(status["dirs"]).each do |f|
|
2068
|
+
relative_path = f[0].gsub(/^#{@dataset.local_path}/, "")
|
2069
|
+
# dir
|
2070
|
+
if @files.download_dir(dataset_dir, relative_path)
|
2071
|
+
# current_tree.delete(relative_path[0, relative_path.size-1])
|
2072
|
+
successful_changes << relative_path
|
2073
|
+
end
|
2074
|
+
end
|
2075
|
+
(status["download"]).each do |f|
|
2076
|
+
relative_path = f["name"].gsub(/^#{@dataset.local_path}/, "")
|
2077
|
+
# dir
|
2078
|
+
if @files.download_file_s3(f["name"], relative_path, dataset_dir, f["sha1"])
|
2079
|
+
successful_changes << relative_path
|
2080
|
+
end
|
2081
|
+
end
|
2082
|
+
|
2083
|
+
|
2084
|
+
say "Done. Jumped completed successfully", Thor::Shell::Color::GREEN
|
2085
|
+
log_end(0)
|
2086
|
+
end
|
2087
|
+
|
2088
|
+
rescue SignalException
|
2089
|
+
log_end(-1)
|
2090
|
+
exi(1)
|
2091
|
+
end
|
2092
|
+
end
|
2093
|
+
|
1058
2094
|
desc 'sync', 'Sync with remote server'
|
1059
|
-
method_option :new_branch, :type => :boolean, :aliases => ["
|
1060
|
-
method_option :verbose, :type => :boolean, :aliases => ["
|
2095
|
+
method_option :new_branch, :type => :boolean, :aliases => ["-nb"], :desc => "create new branch of commits"
|
2096
|
+
method_option :verbose, :type => :boolean, :aliases => ["-v"], :default => false
|
2097
|
+
method_option :ignore, :type => :string, :aliases => ["-i", "--ignore"], :default => ""
|
1061
2098
|
|
1062
|
-
def sync
|
2099
|
+
def sync(direct=true)
|
2100
|
+
verify_logged_in(true) if direct
|
1063
2101
|
if options["verbose"]
|
1064
|
-
|
2102
|
+
say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE
|
1065
2103
|
else
|
1066
2104
|
say 'Syncing project', Thor::Shell::Color::BLUE
|
1067
2105
|
end
|
1068
2106
|
|
1069
2107
|
|
1070
|
-
invoke :download, [], :new_branch => options["new_branch"], :verbose => options["verbose"], :sync=>true
|
1071
|
-
invoke :upload, [], :new_branch => options["new_branch"], :verbose => options["verbose"]
|
1072
|
-
|
2108
|
+
invoke :download, [], :new_branch => options["new_branch"], :verbose => options["verbose"], :sync => true
|
2109
|
+
invoke :upload, [link=false, sync=true, direct=direct], :new_branch => options["new_branch"], :verbose => options["verbose"], :sync => true,
|
2110
|
+
:ignore => options[:ignore]
|
1073
2111
|
|
1074
|
-
say "#{check} Syncing project completed successfully", Thor::Shell::Color::GREEN
|
1075
2112
|
|
1076
2113
|
end
|
1077
2114
|
|
1078
2115
|
|
1079
2116
|
desc 'run cmd', 'Runs an experiment'
|
1080
|
-
method_option :local, :type => :boolean, :aliases => ["
|
1081
|
-
method_option :small, :type => :boolean, :aliases => ["
|
1082
|
-
method_option :medium, :type => :boolean, :aliases => ["--
|
1083
|
-
method_option :large, :type => :boolean, :aliases => ["
|
2117
|
+
method_option :local, :type => :boolean, :aliases => ["-l", "--local"], :default => false
|
2118
|
+
method_option :small, :type => :boolean, :aliases => ["-sm", "--small"], :default => false
|
2119
|
+
method_option :medium, :type => :boolean, :aliases => ["-md", "--medium"], :default => false
|
2120
|
+
method_option :large, :type => :boolean, :aliases => ["-lg", "--large"], :default => false
|
1084
2121
|
method_option :gpu, :type => :boolean, :aliases => ["--gpu"], :default => false
|
1085
|
-
method_option :gpuxl, :type => :boolean, :aliases => ["--
|
1086
|
-
method_option :
|
1087
|
-
method_option :
|
1088
|
-
method_option :
|
2122
|
+
method_option :gpuxl, :type => :boolean, :aliases => ["--gpuxl"], :default => false
|
2123
|
+
method_option :gpuxxl, :type => :boolean, :aliases => ["--gpuxxl"], :default => false
|
2124
|
+
method_option :sync_before, :type => :boolean, :aliases => ["-sb", "--sync_before"], :default => true
|
2125
|
+
method_option :sync_after, :type => :boolean, :aliases => ["-sa", "--sync_after"], :default => true
|
2126
|
+
method_option :title, :type => :string, :aliases => ["-t", "--title"], :default => ""
|
1089
2127
|
method_option :log, :type => :boolean, :aliases => ["--log"], :default => false
|
1090
|
-
method_option :email_notification, :type => :boolean, :aliases => ["
|
1091
|
-
method_option :upload_output, :type => :string, :aliases => ["
|
1092
|
-
method_option :commit, :type => :string, :aliases => ["
|
1093
|
-
method_option :schedule, :type => :string, :aliases => ["
|
1094
|
-
method_option :image, :type => :string, :aliases => ["
|
2128
|
+
method_option :email_notification, :type => :boolean, :aliases => ["-en", "--email_notification"], :default => false
|
2129
|
+
method_option :upload_output, :type => :string, :aliases => ["-uo", "--upload_output"], :default => ""
|
2130
|
+
method_option :commit, :type => :string, :aliases => ["-c", "--commit"], :default => ""
|
2131
|
+
method_option :schedule, :type => :string, :aliases => ["-s", "--schedule"], :default => ""
|
2132
|
+
method_option :image, :type => :string, :aliases => ["-i", "--image"], :default => ""
|
2133
|
+
method_option :grid, :type => :string, :aliases => ["-g", "--grid"], :default => ""
|
2134
|
+
method_option :data, :type => :string, :aliases => ["-d", "--data"], :default => ""
|
2135
|
+
method_option :data_commit, :type => :string, :aliases => ["--data_commit"], :default => ""
|
2136
|
+
method_option :ignore, :type => :string, :aliases => ["-i", "--ignore"], :desc => "ignore following files", :default => ""
|
1095
2137
|
|
1096
2138
|
def run(*cmd)
|
1097
2139
|
sync_before = options["sync_before"]
|
@@ -1104,38 +2146,73 @@ module Cnvrg
|
|
1104
2146
|
local = options["local"]
|
1105
2147
|
schedule = options["schedule"]
|
1106
2148
|
image = options["image"]
|
2149
|
+
grid = options["grid"]
|
2150
|
+
data = options["data"]
|
2151
|
+
data_commit = options["data_commit"]
|
2152
|
+
ignore = options["ignore"]
|
2153
|
+
options_hash = Hash[options]
|
2154
|
+
real_options = []
|
2155
|
+
options_hash.each do |o|
|
2156
|
+
real_options << o if (!o[1].eql? "" and !["small", "medium", "large", "gpu", "gpuxl", "gpuxxl"].include? o[0])
|
2157
|
+
end
|
1107
2158
|
if local
|
1108
2159
|
invoke :exec, [cmd], :sync_before => sync_before, :sync_after => sync_after, :title => title,
|
1109
|
-
:log => log, :email_notification => email_notification, :upload_output => upload_output,
|
2160
|
+
:log => log, :email_notification => email_notification, :upload_output => upload_output,
|
2161
|
+
:commit => commit, :image => image, :data => data, :data_commit => data_commit, :ignore => ignore
|
1110
2162
|
return
|
1111
2163
|
else
|
1112
|
-
|
2164
|
+
real_options.delete(["local", false])
|
2165
|
+
instances = {"small" => options["small"], "medium" => options["medium"], "large" => options["large"],
|
2166
|
+
"gpu" => options["gpu"], "gpuxl" => options["gpuxl"], "gpuxxl" => options["gpuxxl"]}
|
1113
2167
|
instance_type = get_instance_type(instances)
|
2168
|
+
if !instance_type.nil? and !instance_type.empty?
|
2169
|
+
real_options << ["machine_type", instance_type]
|
2170
|
+
end
|
2171
|
+
exec_options = real_options.map { |x| "--#{x[0]}=#{x[1]}" }.flatten.join(" ")
|
2172
|
+
cmd_to_exec = "#{exec_options} #{cmd.join(" ")}"
|
1114
2173
|
invoke :exec_remote, [cmd], :sync_before => sync_before, :sync_after => sync_after, :title => title, :machine_type => instance_type,
|
1115
|
-
:schedule => schedule, :log => log, :email_notification => email_notification, :upload_output => upload_output, :commit => commit,
|
2174
|
+
:schedule => schedule, :log => log, :email_notification => email_notification, :upload_output => upload_output, :commit => commit,
|
2175
|
+
:image => image, :grid => grid, :data => data, :data_commit => data_commit, :ignore => ignore
|
1116
2176
|
return
|
1117
2177
|
end
|
1118
|
-
end
|
1119
2178
|
|
2179
|
+
# if local
|
2180
|
+
#
|
2181
|
+
# else
|
1120
2182
|
|
1121
|
-
desc '', ''
|
1122
|
-
method_option :sync_before, :type => :boolean, :aliases => ["-sb", "--sb"], :default => true
|
1123
|
-
method_option :sync_after, :type => :boolean, :aliases => ["-sa", "--sa"], :default => true
|
1124
|
-
method_option :title, :type => :string, :aliases => ["-t", "--t"], :default => ""
|
1125
|
-
method_option :log, :type => :boolean, :aliases => ["-l", "--l"], :default => false
|
1126
|
-
method_option :email_notification, :type => :boolean, :aliases => ["-en", "--en"], :default => false
|
1127
|
-
method_option :upload_output, :type => :string, :aliases => ["--uo", "-uo"], :default => ""
|
1128
|
-
method_option :commit, :type => :string, :aliases => ["--c", "-c"], :default => ""
|
1129
|
-
method_option :image, :type => :string, :aliases => ["--i"], :default => ""
|
1130
|
-
method_option :indocker, :type => :boolean, :default => false
|
1131
2183
|
|
2184
|
+
# invoke :exec_remote, [cmd_to_exec.split(" ")], :sync_before => sync_before, :sync_after => sync_after, :title => title, :machine_type => instance_type,
|
2185
|
+
# :schedule => schedule, :log => log, :email_notification => email_notification, :upload_output => upload_output, :commit => commit,
|
2186
|
+
# :image => image, :grid => grid, :data => data, :data_commit => data_commit, :ignore => ignore
|
2187
|
+
# return
|
2188
|
+
# end
|
2189
|
+
end
|
2190
|
+
|
2191
|
+
|
2192
|
+
desc '', '', :hide => true
|
2193
|
+
method_option :sync_before, :type => :boolean, :aliases => ["-sb,--sync_before"], :default => true
|
2194
|
+
method_option :sync_after, :type => :boolean, :aliases => ["-sa,--sync_after"], :default => true
|
2195
|
+
method_option :title, :type => :string, :aliases => ["-t", "--title"], :default => ""
|
2196
|
+
method_option :log, :type => :boolean, :aliases => ["--log"], :default => false
|
2197
|
+
method_option :email_notification, :type => :boolean, :aliases => ["-en,--email_notification"], :default => false
|
2198
|
+
method_option :upload_output, :type => :string, :aliases => ["-uo,--upload_output"], :default => ""
|
2199
|
+
method_option :commit, :type => :string, :aliases => ["-c", "--commit"], :default => ""
|
2200
|
+
method_option :image, :type => :string, :aliases => ["-i", "--image"], :default => ""
|
2201
|
+
method_option :indocker, :type => :boolean, :aliases => ["--indocker"], :default => false
|
2202
|
+
method_option :data, :type => :string, :aliases => ["-d", "--data"], :default => ""
|
2203
|
+
method_option :data_commit, :type => :string, :aliases => ["-dc", "--data_commit"], :default => ""
|
2204
|
+
method_option :ignore, :type => :string, :aliases => ["-i", "--ignore"], :desc => "ignore following files", :default => ""
|
2205
|
+
method_option :remote, :type => :boolean, :aliases => ["--remote"], :default => false
|
2206
|
+
method_option :gpu, :type => :boolean, :aliases => ["--gpu"], :default => false
|
1132
2207
|
def exec(*cmd)
|
2208
|
+
|
1133
2209
|
log = []
|
1134
2210
|
cpu_average =0
|
1135
2211
|
memory_average = 0
|
1136
2212
|
verify_logged_in(true)
|
1137
2213
|
log_start(__method__, args, options)
|
1138
|
-
working_dir =
|
2214
|
+
working_dir = is_cnvrg_dir
|
2215
|
+
script_path = get_cmd_path_in_dir(working_dir, Dir.pwd)
|
1139
2216
|
|
1140
2217
|
|
1141
2218
|
sync_before = options["sync_before"]
|
@@ -1143,11 +2220,14 @@ module Cnvrg
|
|
1143
2220
|
print_log = options["log"]
|
1144
2221
|
title = options["title"]
|
1145
2222
|
commit = options["commit"] || nil
|
1146
|
-
image = options["image"]
|
1147
|
-
indocker = options["indocker"]
|
2223
|
+
image = options["image"] || nil
|
2224
|
+
indocker = options["indocker"] || false
|
2225
|
+
ignore = options[:ignore] || ""
|
2226
|
+
|
1148
2227
|
|
1149
2228
|
email_notification = options["email_notification"]
|
1150
2229
|
upload_output = options["upload_output"]
|
2230
|
+
upload_output = "1m" if upload_output.nil? or upload_output.empty?
|
1151
2231
|
time_to_upload = calc_output_time(upload_output)
|
1152
2232
|
project_home = get_project_home
|
1153
2233
|
@project = Project.new(project_home)
|
@@ -1159,7 +2239,8 @@ module Cnvrg
|
|
1159
2239
|
else
|
1160
2240
|
if sync_before
|
1161
2241
|
# Sync before run
|
1162
|
-
|
2242
|
+
|
2243
|
+
invoke :sync, [false], :new_branch => is_new_branch, :ignore => ignore
|
1163
2244
|
end
|
1164
2245
|
end
|
1165
2246
|
#set image for the project
|
@@ -1167,40 +2248,46 @@ module Cnvrg
|
|
1167
2248
|
invoke :set_image, [image]
|
1168
2249
|
end
|
1169
2250
|
if !indocker
|
1170
|
-
|
2251
|
+
image_proj = is_project_with_docker(working_dir)
|
1171
2252
|
|
1172
2253
|
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
2254
|
+
if image_proj and image_proj.is_docker
|
2255
|
+
container= image_proj.get_container
|
2256
|
+
if !container
|
2257
|
+
say "Couldn't create container with image #{image_proj.image_name}:#{image_proj.image_tag}", Thor::Shell::Color::RED
|
2258
|
+
exit(1)
|
2259
|
+
end
|
1179
2260
|
|
1180
2261
|
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
2262
|
+
exec_args = args.flatten.join(" ")
|
2263
|
+
options_hash = Hash[options]
|
2264
|
+
options_hash.except!("image", "indocker")
|
2265
|
+
exec_options = options_hash.map { |x| "--#{x[0]}=#{x[1]}" }.flatten.join(" ")
|
2266
|
+
command_to_run = copy_args.join(" ")
|
2267
|
+
command = ["/bin/bash", "-lc", "cnvrg exec --indocker #{exec_options} #{command_to_run} #{exec_args}"]
|
2268
|
+
puts container.exec(command, tty: true)
|
2269
|
+
container.stop()
|
2270
|
+
exit(0)
|
2271
|
+
end
|
1190
2272
|
end
|
2273
|
+
remote = options["remote"]
|
2274
|
+
if remote
|
2275
|
+
docker_id = `cat /etc/hostname`
|
2276
|
+
docker_id = docker_id.strip()
|
1191
2277
|
end
|
2278
|
+
is_on_gpu = options["gpu"]
|
1192
2279
|
start_commit = @project.last_local_commit
|
1193
2280
|
cmd = cmd.join("\s")
|
1194
2281
|
|
1195
|
-
say "Running: #{cmd}\n", Thor::Shell::Color::BLUE
|
1196
|
-
|
1197
2282
|
@exp = Experiment.new(@project.owner, @project.slug)
|
1198
2283
|
|
1199
2284
|
platform = RUBY_PLATFORM
|
1200
2285
|
machine_name = Socket.gethostname
|
1201
2286
|
begin
|
1202
|
-
machine_activity = @exp.get_machine_activity(
|
1203
|
-
@exp.start(cmd, platform, machine_name, start_commit, title, email_notification, machine_activity)
|
2287
|
+
machine_activity = @exp.get_machine_activity(working_dir)
|
2288
|
+
@exp.start(cmd, platform, machine_name, start_commit, title, email_notification, machine_activity, script_path)
|
2289
|
+
say "Experiment's live results: #{Cnvrg::Helpers.remote_url}/#{@project.owner}/projects/#{@project.slug}/experiments/#{@exp.slug}", Thor::Shell::Color::GREEN
|
2290
|
+
say "Running: #{cmd}\n", Thor::Shell::Color::BLUE
|
1204
2291
|
unless @exp.slug.nil?
|
1205
2292
|
real = Time.now
|
1206
2293
|
exp_success = true
|
@@ -1212,19 +2299,34 @@ module Cnvrg
|
|
1212
2299
|
begin
|
1213
2300
|
stdout.each do |line|
|
1214
2301
|
cur_time = Time.now
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
2302
|
+
if remote
|
2303
|
+
stats = usage_metrics_in_docker(docker_id)
|
2304
|
+
cpu = stats[0]
|
2305
|
+
memory = stats[1]
|
2306
|
+
else
|
2307
|
+
memory = memory_usage()
|
2308
|
+
cpu = cpu_usage()
|
2309
|
+
end
|
2310
|
+
|
1219
2311
|
memory_total << memory.to_f
|
1220
2312
|
cpu_total << cpu.to_f
|
1221
2313
|
real_time= Time.now-real
|
1222
2314
|
|
1223
|
-
cur_log = {time: cur_time,
|
2315
|
+
cur_log = { time: cur_time,
|
1224
2316
|
message: line,
|
1225
2317
|
type: "stdout",
|
1226
|
-
real: real_time
|
1227
|
-
|
2318
|
+
real: real_time,
|
2319
|
+
cpu: cpu,
|
2320
|
+
memory: memory
|
2321
|
+
}
|
2322
|
+
if is_on_gpu
|
2323
|
+
gpu_stats = gpu_util
|
2324
|
+
gpu_utilization = gpu_stats[0]
|
2325
|
+
gpu_memory_util = gpu_stats[1]
|
2326
|
+
cur_log.merge!(gpu_util:gpu_utilization,gpu_memory_util:gpu_memory_util)
|
2327
|
+
end
|
2328
|
+
|
2329
|
+
if print_log
|
1228
2330
|
puts cur_log
|
1229
2331
|
end
|
1230
2332
|
log << cur_log
|
@@ -1233,8 +2335,8 @@ module Cnvrg
|
|
1233
2335
|
if time_to_upload !=0
|
1234
2336
|
if time_to_upload <= Time.now - start_loop
|
1235
2337
|
#upload current log
|
1236
|
-
cpu_average = cpu_total.inject(0) { |sum, el| sum + el }.to_f / cpu_total.size
|
1237
|
-
memory_average = memory_total.inject(0) { |sum, el| sum + el }.to_f / memory_total.size
|
2338
|
+
# cpu_average = cpu_total.inject(0) { |sum, el| sum + el }.to_f / cpu_total.size
|
2339
|
+
# memory_average = memory_total.inject(0) { |sum, el| sum + el }.to_f / memory_total.size
|
1238
2340
|
|
1239
2341
|
@exp.upload_temp_log(log, cpu_average, memory_average)
|
1240
2342
|
log = []
|
@@ -1258,8 +2360,7 @@ module Cnvrg
|
|
1258
2360
|
end
|
1259
2361
|
|
1260
2362
|
rescue Errno::EIO => e
|
1261
|
-
|
1262
|
-
# break
|
2363
|
+
# break
|
1263
2364
|
rescue Errno::ENOENT
|
1264
2365
|
log_end(1, "command #{cmd} isn't valid")
|
1265
2366
|
|
@@ -1271,8 +2372,11 @@ module Cnvrg
|
|
1271
2372
|
exp_success = false
|
1272
2373
|
say "The process exited!", Thor::Shell::Color::RED
|
1273
2374
|
rescue => e
|
1274
|
-
|
1275
|
-
|
2375
|
+
log_end(-1, e.message)
|
2376
|
+
res = @exp.end(log, 1, start_commit, cpu_average, memory_average)
|
2377
|
+
|
2378
|
+
say "Error occurred,aborting", Thor::Shell::Color::RED
|
2379
|
+
exit(0)
|
1276
2380
|
end
|
1277
2381
|
::Process.wait pid
|
1278
2382
|
cpu_average = cpu_total.inject(0) { |sum, el| sum + el }.to_f / cpu_total.size
|
@@ -1283,7 +2387,7 @@ module Cnvrg
|
|
1283
2387
|
end
|
1284
2388
|
if !exp_success
|
1285
2389
|
if !Cnvrg::Helpers.internet_connection?
|
1286
|
-
wait_offline = agree "Seems like you're offline, wait until
|
2390
|
+
wait_offline = agree "Seems like you're offline, wait until you're back online?", Thor::Shell::Color::YELLOW
|
1287
2391
|
if wait_offline
|
1288
2392
|
say "Waiting until your'e online..", Thor::Shell::Color::BLUE
|
1289
2393
|
while !Cnvrg::Helpers.internet_connection?
|
@@ -1306,23 +2410,21 @@ module Cnvrg
|
|
1306
2410
|
end
|
1307
2411
|
if sync_after
|
1308
2412
|
# Sync after run
|
1309
|
-
if !commit.nil?
|
1310
|
-
invoke :sync, [], :new_branch => true
|
1311
2413
|
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
2414
|
+
|
2415
|
+
download(sync=true, ignore_list=ignore)
|
2416
|
+
upload(link=false, sync=true, direct=false, ignore_list=ignore)
|
2417
|
+
|
1315
2418
|
end
|
1316
2419
|
end_commit = @project.last_local_commit
|
1317
2420
|
|
1318
2421
|
res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
|
1319
2422
|
check = Helpers.checkmark()
|
1320
|
-
say "#{check} Done. Experiment's
|
2423
|
+
say "#{check} Done. Experiment's results were updated!", Thor::Shell::Color::GREEN
|
1321
2424
|
log_end(0)
|
1322
2425
|
end
|
1323
2426
|
rescue => e
|
1324
|
-
|
1325
|
-
log_end(1, e.message)
|
2427
|
+
log_end(-1, e.message)
|
1326
2428
|
if container
|
1327
2429
|
container.stop()
|
1328
2430
|
end
|
@@ -1349,7 +2451,7 @@ module Cnvrg
|
|
1349
2451
|
end
|
1350
2452
|
end
|
1351
2453
|
|
1352
|
-
desc '', ''
|
2454
|
+
desc '', '', :hide => true
|
1353
2455
|
method_option :sync_before, :type => :boolean, :aliases => ["-sb", "--sb"], :default => true
|
1354
2456
|
method_option :sync_after, :type => :boolean, :aliases => ["-sa", "--sa"], :default => true
|
1355
2457
|
method_option :title, :type => :string, :aliases => ["-t", "--t"], :default => ""
|
@@ -1388,7 +2490,7 @@ module Cnvrg
|
|
1388
2490
|
machine_name = Socket.gethostname
|
1389
2491
|
begin
|
1390
2492
|
|
1391
|
-
@exp.start(cmd, platform, machine_name, start_commit, title, email_notification, machine_activity)
|
2493
|
+
@exp.start(cmd, platform, machine_name, start_commit, title, email_notification, machine_activity, Dir.pwd)
|
1392
2494
|
unless @exp.slug.nil?
|
1393
2495
|
real = Time.now
|
1394
2496
|
exp_success = true
|
@@ -1458,7 +2560,9 @@ module Cnvrg
|
|
1458
2560
|
exp_success = false
|
1459
2561
|
say "The process exited!", Thor::Shell::Color::RED
|
1460
2562
|
rescue => e
|
1461
|
-
log_end(1, e.message)
|
2563
|
+
log_end(-1, e.message)
|
2564
|
+
say "Error occurred, aborting", Thor::Shell::Color::RED
|
2565
|
+
exit(0)
|
1462
2566
|
end
|
1463
2567
|
::Process.wait pid
|
1464
2568
|
cpu_average = cpu_total.inject(0) { |sum, el| sum + el }.to_f / cpu_total.size
|
@@ -1508,7 +2612,7 @@ module Cnvrg
|
|
1508
2612
|
log_end(0)
|
1509
2613
|
end
|
1510
2614
|
rescue => e
|
1511
|
-
log_end(1, e.message)
|
2615
|
+
log_end(-1, e.message)
|
1512
2616
|
say "Couldn't run #{cmd}, check your input parameters", Thor::Shell::Color::RED
|
1513
2617
|
exit(1)
|
1514
2618
|
end
|
@@ -1532,23 +2636,33 @@ module Cnvrg
|
|
1532
2636
|
end
|
1533
2637
|
end
|
1534
2638
|
|
1535
|
-
desc '', ''
|
1536
|
-
method_option :sync_before, :type => :boolean, :aliases => ["-sb", "--
|
1537
|
-
method_option :sync_after, :type => :boolean, :aliases => ["-sa", "--
|
1538
|
-
method_option :title, :type => :string, :aliases => ["-t", "--
|
1539
|
-
method_option :log, :type => :boolean, :aliases => ["
|
1540
|
-
method_option :email_notification, :type => :boolean, :aliases => ["-en", "--
|
1541
|
-
method_option :upload_output, :type => :string, :aliases => ["
|
1542
|
-
method_option :machine_type, :type => :string, :
|
1543
|
-
method_option :schedule, :type => :string, :aliases => ["
|
1544
|
-
method_option :commit, :type => :string, :aliases => ["
|
1545
|
-
method_option :image, :type => :string, :aliases => ["
|
2639
|
+
desc '', '', :hide => true
|
2640
|
+
method_option :sync_before, :type => :boolean, :aliases => ["-sb", "--sync_before"], :default => true
|
2641
|
+
method_option :sync_after, :type => :boolean, :aliases => ["-sa", "--sync_after"], :default => true
|
2642
|
+
method_option :title, :type => :string, :aliases => ["-t", "--title"], :default => ""
|
2643
|
+
method_option :log, :type => :boolean, :aliases => ["--log"], :default => false
|
2644
|
+
method_option :email_notification, :type => :boolean, :aliases => ["-en", "--email_notification"], :default => false
|
2645
|
+
method_option :upload_output, :type => :string, :aliases => ["-uo", "--upload_output"], :default => ""
|
2646
|
+
method_option :machine_type, :type => :string, :default => ""
|
2647
|
+
method_option :schedule, :type => :string, :aliases => ["-s", "--schedule"], :default => ""
|
2648
|
+
method_option :commit, :type => :string, :aliases => ["-c, --commit"], :default => nil
|
2649
|
+
method_option :image, :type => :string, :aliases => ["-i", "--image"], :default => ""
|
2650
|
+
method_option :grid, :type => :string, :aliases => ["-g", "--grid"], :default => ""
|
2651
|
+
method_option :data, :type => :string, :aliases => ["-d", "--data"], :default => ""
|
2652
|
+
method_option :data_commit, :type => :string, :aliases => ["--data_commit"], :default => ""
|
2653
|
+
method_option :ignore, :type => :string, :aliases => ["-i", "--ignore"], :desc => "ignore following files", :default => ""
|
1546
2654
|
|
1547
2655
|
def exec_remote(*cmd)
|
1548
2656
|
verify_logged_in(true)
|
1549
2657
|
log_start(__method__, args, options)
|
1550
2658
|
working_dir = is_cnvrg_dir
|
2659
|
+
path_to_cmd = get_cmd_path_in_dir(working_dir, Dir.pwd)
|
2660
|
+
|
1551
2661
|
begin
|
2662
|
+
grid = options["grid"] || nil
|
2663
|
+
data = options["data"] || nil
|
2664
|
+
data_commit = options["data_commit"] || nil
|
2665
|
+
sync_before = options["sync_before"]
|
1552
2666
|
|
1553
2667
|
instance_type = options["machine_type"] || nil
|
1554
2668
|
schedule = options["schedule"] || ""
|
@@ -1570,10 +2684,22 @@ module Cnvrg
|
|
1570
2684
|
new_time = new_time[0, new_time.size-6] #remove timezone
|
1571
2685
|
schedule = "at #{new_time}"
|
1572
2686
|
end
|
2687
|
+
upload_output = options["upload_output"]
|
2688
|
+
time_to_upload = calc_output_time(upload_output)
|
2689
|
+
if time_to_upload==0 or time_to_upload==-1
|
2690
|
+
upload_output_option = "--upload_output=1m"
|
2691
|
+
else
|
2692
|
+
upload_output_option = "--upload_output=#{upload_output}"
|
2693
|
+
end
|
2694
|
+
remote = "--remote=true"
|
2695
|
+
if !instance_type.nil? and instance_type.include? "gpu"
|
2696
|
+
remote= "#{remote} --gpu=true"
|
2697
|
+
end
|
2698
|
+
|
1573
2699
|
options_hash = Hash[options]
|
1574
|
-
options_hash.except!("schedule", "machine_type", "image")
|
2700
|
+
options_hash.except!("schedule", "machine_type", "image", "upload_output", "grid", "data", "data_commit", "local", "small", "medium", "large", "gpu", "gpuxl", "gpuxxl")
|
1575
2701
|
exec_options = options_hash.map { |x| "--#{x[0]}=#{x[1]}" }.flatten.join(" ")
|
1576
|
-
command = "#{exec_options}
|
2702
|
+
command = "#{exec_options} #{remote} #{upload_output_option} #{cmd.flatten.join(" ")}"
|
1577
2703
|
commit_to_run = options["commit"] || nil
|
1578
2704
|
if !schedule.nil? and !schedule.empty?
|
1579
2705
|
|
@@ -1584,19 +2710,20 @@ module Cnvrg
|
|
1584
2710
|
choose_image = options["image"]
|
1585
2711
|
|
1586
2712
|
if !choose_image.nil? and !choose_image.empty?
|
1587
|
-
invoke :set_image,[choose_image]
|
2713
|
+
invoke :set_image, [choose_image]
|
1588
2714
|
end
|
1589
2715
|
image = is_project_with_docker(working_dir)
|
1590
2716
|
if !image or !image.is_docker
|
1591
2717
|
# say "Couldn't find image related to project", Thor::Shell::Color::RED
|
1592
|
-
|
2718
|
+
|
2719
|
+
image_slug = "cnvrg"
|
1593
2720
|
if instance_type.eql? "gpu" or instance_type.eql? "gpuxl"
|
1594
|
-
|
2721
|
+
image_slug = "cnvrg_gpu"
|
1595
2722
|
end
|
1596
2723
|
# default = yes? "use #{default_image_name} default image?", Thor::Shell::Color::YELLOW
|
1597
2724
|
# if default
|
1598
|
-
|
1599
|
-
|
2725
|
+
# image = Images.new(working_dir, default_image_name)
|
2726
|
+
# image_slug = image.image_slug
|
1600
2727
|
# else
|
1601
2728
|
# exit(0)
|
1602
2729
|
# end
|
@@ -1604,16 +2731,27 @@ module Cnvrg
|
|
1604
2731
|
image_slug = image.image_slug
|
1605
2732
|
end
|
1606
2733
|
|
2734
|
+
invoke :sync, [false], [] if sync_before
|
2735
|
+
|
1607
2736
|
|
2737
|
+
if command.include? "'"
|
2738
|
+
oc = command.to_enum(:scan, /'/).map { Regexp.last_match }
|
2739
|
+
pairs = oc.enum_for(:each_slice, 2).to_a
|
2740
|
+
pairs.each_with_index do |p,i|
|
2741
|
+
add=0
|
2742
|
+
if i!=0
|
2743
|
+
add=2*i
|
2744
|
+
end
|
2745
|
+
total_loc = command[p[0].offset(0)[0]+add..p[1].offset(0)[0]+add]
|
2746
|
+
command[p[0].offset(0)[0]+add..p[1].offset(0)[0]+add] = "\"#{total_loc}\""
|
2747
|
+
end
|
1608
2748
|
|
1609
|
-
invoke :sync, [], []
|
1610
2749
|
|
2750
|
+
end
|
1611
2751
|
say "Running remote experiment", Thor::Shell::Color::BLUE
|
1612
2752
|
exp = Experiment.new(project.owner, project.slug)
|
1613
|
-
|
1614
|
-
res = exp.exec_remote(command, commit_to_run, instance_type, image_slug, schedule, local_timestamp)
|
2753
|
+
res = exp.exec_remote(command, commit_to_run, instance_type, image_slug, schedule, local_timestamp, grid, path_to_cmd, data, data_commit)
|
1615
2754
|
if Cnvrg::CLI.is_response_success(res)
|
1616
|
-
|
1617
2755
|
# if res["result"]["machine"] == -1
|
1618
2756
|
# say "There are no available machines", Thor::Shell::Color::BLUE
|
1619
2757
|
# create = yes? "create new machine?", Thor::Shell::Color::YELLOW
|
@@ -1645,7 +2783,13 @@ module Cnvrg
|
|
1645
2783
|
# end
|
1646
2784
|
# else
|
1647
2785
|
check = Helpers.checkmark()
|
1648
|
-
|
2786
|
+
str = "#{check} Experiment's is on: #{Cnvrg::Helpers.remote_url}/#{project.owner}/projects/#{project.slug}/experiments/#{res["result"]["exp_url"]}"
|
2787
|
+
|
2788
|
+
if res["result"]["grid"]
|
2789
|
+
str = "Running grid search. #{Cnvrg::Helpers.remote_url}/#{project.owner}/projects/#{project.slug}/experiments?grid=#{res["result"]["exp_url"]} "
|
2790
|
+
end
|
2791
|
+
|
2792
|
+
say str, Thor::Shell::Color::GREEN
|
1649
2793
|
|
1650
2794
|
exit(0)
|
1651
2795
|
# end
|
@@ -1665,21 +2809,30 @@ module Cnvrg
|
|
1665
2809
|
end
|
1666
2810
|
|
1667
2811
|
desc 'deploy', 'Deploys model to production'
|
1668
|
-
method_option :
|
1669
|
-
method_option :
|
1670
|
-
method_option :
|
2812
|
+
method_option :small, :type => :boolean, :aliases => ["-sm", "--small"], :default => false
|
2813
|
+
method_option :medium, :type => :boolean, :aliases => ["-md", "--medium"], :default => false
|
2814
|
+
method_option :large, :type => :boolean, :aliases => ["-lg", "--large"], :default => false
|
2815
|
+
method_option :gpu, :type => :boolean, :aliases => ["--gpu"], :default => false
|
2816
|
+
method_option :gpuxl, :type => :boolean, :aliases => ["--gpuxl"], :default => false
|
2817
|
+
method_option :gpuxxl, :type => :boolean, :aliases => ["--gpuxxl"], :default => false
|
2818
|
+
method_option :schedule, :type => :string, :aliases => ["--schedule", "-s"], :default => ""
|
2819
|
+
|
2820
|
+
method_option :commit, :type => :string, :aliases => ["--commit", "-c"], :default => ""
|
2821
|
+
method_option :workers, :type => :string, :aliases => ["--workers", "-w"], :default => ""
|
2822
|
+
method_option :file_as_input, :type => :boolean, :aliases => ["--input", "-i"], :default => false
|
1671
2823
|
|
1672
2824
|
def deploy(file_to_run, function)
|
1673
2825
|
verify_logged_in(true)
|
1674
2826
|
log_start(__method__, args, options)
|
1675
2827
|
working_dir = is_cnvrg_dir
|
1676
2828
|
begin
|
2829
|
+
instances = {"small" => options["small"], "medium" => options["medium"], "large" => options["large"],
|
2830
|
+
"gpu" => options["gpu"], "gpuxl" => options["gpuxl"], "gpuxxl" => options["gpuxxl"]}
|
2831
|
+
instance_type = get_instance_type(instances)
|
1677
2832
|
|
1678
|
-
instance_type = options["machine_type"] || nil
|
1679
2833
|
schedule = options["schedule"] || ""
|
1680
2834
|
|
1681
2835
|
|
1682
|
-
|
1683
2836
|
if !schedule.nil? and !schedule.empty?
|
1684
2837
|
|
1685
2838
|
local_timestamp = get_schedule_date
|
@@ -1688,26 +2841,34 @@ module Cnvrg
|
|
1688
2841
|
project = Project.new(working_dir)
|
1689
2842
|
commit_to_run = options["commit"] || nil
|
1690
2843
|
|
2844
|
+
workers = options["workers"] || nil
|
2845
|
+
begin
|
2846
|
+
num_workers = workers.to_i
|
2847
|
+
rescue
|
2848
|
+
say "Number of workers should be a number between 1 to 10", Thor::Shell::Color::RED
|
2849
|
+
exit(1)
|
2850
|
+
end
|
2851
|
+
file_as_input = options["file_as_input"] || false
|
2852
|
+
|
1691
2853
|
|
1692
2854
|
image = is_project_with_docker(working_dir)
|
1693
2855
|
if !image or !image.is_docker
|
1694
|
-
say "Couldn't find image related to project", Thor::Shell::Color::RED
|
1695
|
-
default = yes? "use cnvrg default image?", Thor::Shell::Color::YELLOW
|
1696
|
-
if default
|
1697
|
-
|
1698
|
-
|
1699
|
-
else
|
1700
|
-
|
1701
|
-
end
|
2856
|
+
# say "Couldn't find image related to project", Thor::Shell::Color::RED
|
2857
|
+
# default = yes? "use cnvrg default image?", Thor::Shell::Color::YELLOW
|
2858
|
+
# if default
|
2859
|
+
image = Images.new(working_dir, "cnvrg")
|
2860
|
+
image_slug = image.image_slug
|
2861
|
+
# else
|
2862
|
+
# exit(0)
|
2863
|
+
# end
|
1702
2864
|
else
|
1703
2865
|
image_slug = image.image_slug
|
1704
2866
|
end
|
1705
2867
|
|
1706
2868
|
|
2869
|
+
invoke :sync, [false], []
|
1707
2870
|
|
1708
|
-
|
1709
|
-
|
1710
|
-
res = project.deploy(file_to_run, function, nil, commit_to_run, instance_type, image_slug, schedule, local_timestamp)
|
2871
|
+
res = project.deploy(file_to_run, function, nil, commit_to_run, instance_type, image_slug, schedule, local_timestamp, num_workers, file_as_input)
|
1711
2872
|
|
1712
2873
|
if Cnvrg::CLI.is_response_success(res)
|
1713
2874
|
|
@@ -1763,27 +2924,37 @@ module Cnvrg
|
|
1763
2924
|
|
1764
2925
|
method_option :kernel, :type => :string, :aliases => ["--k", "-k"], :default => ""
|
1765
2926
|
method_option :notebook_dir, :type => :string, :aliases => ["-n", "--n"], :default => "", :desc => "relative path to notebook dir from current directory"
|
1766
|
-
method_option :local, :type => :boolean, :aliases => ["
|
1767
|
-
method_option :small, :type => :boolean, :aliases => ["
|
1768
|
-
method_option :medium, :type => :boolean, :aliases => ["--
|
1769
|
-
method_option :large, :type => :boolean, :aliases => ["
|
2927
|
+
method_option :local, :type => :boolean, :aliases => ["-l"], :default => false
|
2928
|
+
method_option :small, :type => :boolean, :aliases => ["-sm", "--small"], :default => false
|
2929
|
+
method_option :medium, :type => :boolean, :aliases => ["-md", "--medium"], :default => false
|
2930
|
+
method_option :large, :type => :boolean, :aliases => ["-lg", "--large"], :default => false
|
1770
2931
|
method_option :gpu, :type => :boolean, :aliases => ["--gpu"], :default => false
|
1771
|
-
method_option :gpuxl, :type => :boolean, :aliases => ["--
|
1772
|
-
|
2932
|
+
method_option :gpuxl, :type => :boolean, :aliases => ["--gpuxl"], :default => false
|
2933
|
+
method_option :gpuxxl, :type => :boolean, :aliases => ["--gpuxxl"], :default => false
|
2934
|
+
method_option :image, :type => :string, :aliases => ["-i", "--image"], :default => ""
|
2935
|
+
method_option :data, :type => :string, :aliases => ["-d", "--data"], :default => ""
|
2936
|
+
method_option :data_commit, :type => :string, :aliases => ["--data_commit"], :default => ""
|
2937
|
+
|
1773
2938
|
|
1774
|
-
|
2939
|
+
desc 'notebook', 'starts a notebook session remotely or locally'
|
2940
|
+
|
2941
|
+
def notebook
|
1775
2942
|
local = options["local"]
|
1776
2943
|
notebook_dir = options["notebook_dir"]
|
1777
2944
|
kernel = options["kernel"]
|
1778
|
-
|
2945
|
+
image = options["image"]
|
2946
|
+
data = options["data"]
|
2947
|
+
data_commit = options["data_commit"]
|
1779
2948
|
if local
|
1780
|
-
invoke :run_notebook, [], :notebook_dir => notebook_dir, :remote => false, :kernel => kernel
|
2949
|
+
invoke :run_notebook, [], :notebook_dir => notebook_dir, :remote => false, :kernel => kernel, :image => image
|
1781
2950
|
return
|
1782
2951
|
else
|
1783
|
-
instances = {"small" => options["small"], "medium" => options["medium"], "large" => options["large"],
|
2952
|
+
instances = {"small" => options["small"], "medium" => options["medium"], "large" => options["large"],
|
2953
|
+
"gpu" => options["gpu"], "gpuxl" => options["gpuxl"], "gpuxxl" => options["gpuxxl"]}
|
1784
2954
|
instance_type = get_instance_type(instances)
|
1785
2955
|
|
1786
|
-
invoke :remote_notebook, [], :notebook_dir => notebook_dir, :kernel => kernel, :machine_type => instance_type
|
2956
|
+
invoke :remote_notebook, [], :notebook_dir => notebook_dir, :kernel => kernel, :machine_type => instance_type, :image => image,
|
2957
|
+
:data => data, :data_commit => data_commit
|
1787
2958
|
return
|
1788
2959
|
|
1789
2960
|
end
|
@@ -1792,10 +2963,12 @@ module Cnvrg
|
|
1792
2963
|
end
|
1793
2964
|
|
1794
2965
|
desc 'remote_notebook', 'run notebook server on remote server'
|
1795
|
-
method_option :notebook_dir, :type => :string, :aliases => ["-n"
|
1796
|
-
method_option :machine_type, :type => :string, :
|
1797
|
-
method_option :kernel, :type => :string, :aliases => ["--
|
1798
|
-
method_option :image, :type => :string, :aliases => ["
|
2966
|
+
method_option :notebook_dir, :type => :string, :aliases => ["-n"], :default => "", :desc => "relative path to notebook dir from current directory"
|
2967
|
+
method_option :machine_type, :type => :string, :default => ""
|
2968
|
+
method_option :kernel, :type => :string, :aliases => ["--kernel", "-k"], :default => ""
|
2969
|
+
method_option :image, :type => :string, :aliases => ["-i"], :default => ""
|
2970
|
+
method_option :data, :type => :string, :aliases => ["-d", "--data"], :default => ""
|
2971
|
+
method_option :data_commit, :type => :string, :aliases => ["--data_commit"], :default => ""
|
1799
2972
|
|
1800
2973
|
|
1801
2974
|
def remote_notebook()
|
@@ -1807,13 +2980,15 @@ module Cnvrg
|
|
1807
2980
|
notebook_dir = options["notebook_dir"]
|
1808
2981
|
instance_type = options["machine_type"] || nil
|
1809
2982
|
kernel = options["kernel"] || nil
|
2983
|
+
data = options["data"]
|
2984
|
+
data_commit = options["data_commit"]
|
1810
2985
|
|
1811
2986
|
|
1812
2987
|
begin
|
1813
2988
|
choose_image = options["image"]
|
1814
2989
|
|
1815
2990
|
if !choose_image.nil? and !choose_image.empty?
|
1816
|
-
invoke :set_image,[choose_image]
|
2991
|
+
invoke :set_image, [choose_image]
|
1817
2992
|
end
|
1818
2993
|
@image = is_project_with_docker(working_dir)
|
1819
2994
|
if !@image or !@image.is_docker
|
@@ -1824,17 +2999,16 @@ module Cnvrg
|
|
1824
2999
|
end
|
1825
3000
|
# default = yes? "use #{default_image_name} default image?", Thor::Shell::Color::YELLOW
|
1826
3001
|
# if default
|
1827
|
-
|
3002
|
+
@image = Images.new(working_dir, default_image_name)
|
1828
3003
|
# else
|
1829
3004
|
# exit(0)
|
1830
3005
|
# end
|
1831
3006
|
end
|
1832
3007
|
|
1833
|
-
invoke :sync, [], []
|
1834
|
-
|
3008
|
+
invoke :sync, [false], []
|
1835
3009
|
|
1836
3010
|
|
1837
|
-
res = @image.remote_notebook(notebook_dir, instance_type, kernel)
|
3011
|
+
res = @image.remote_notebook(notebook_dir, instance_type, kernel, data, data_commit)
|
1838
3012
|
if Cnvrg::CLI.is_response_success(res)
|
1839
3013
|
if res["result"]["machine"] == -1
|
1840
3014
|
say "There are no available machines", Thor::Shell::Color::BLUE
|
@@ -1873,7 +3047,7 @@ module Cnvrg
|
|
1873
3047
|
note_url = res["result"]["notebook_url"]
|
1874
3048
|
@image.set_note_url(note_url)
|
1875
3049
|
check = Helpers.checkmark()
|
1876
|
-
say "#{check} Notebook is on: #{Cnvrg::Helpers.remote_url}/#{@
|
3050
|
+
say "#{check} Notebook is on: #{Cnvrg::Helpers.remote_url}/#{@image.owner}/projects/#{@image.project_slug}/notebook_sessions/show/#{note_url}", Thor::Shell::Color::GREEN
|
1877
3051
|
# Launchy.open(url)
|
1878
3052
|
|
1879
3053
|
exit(0)
|
@@ -1941,9 +3115,8 @@ module Cnvrg
|
|
1941
3115
|
|
1942
3116
|
end
|
1943
3117
|
rescue => e
|
1944
|
-
|
1945
|
-
|
1946
|
-
say "Error occurd, Aborting"
|
3118
|
+
log_end(-1, e.message)
|
3119
|
+
say "Error occurred, aborting", Thor::Shell::Color::RED
|
1947
3120
|
if container
|
1948
3121
|
container.stop()
|
1949
3122
|
end
|
@@ -2004,9 +3177,8 @@ module Cnvrg
|
|
2004
3177
|
end
|
2005
3178
|
end
|
2006
3179
|
rescue => e
|
2007
|
-
|
2008
|
-
|
2009
|
-
say "Error occurd, Aborting"
|
3180
|
+
log_end(-1, e.message)
|
3181
|
+
say "Error occurred, aborting"
|
2010
3182
|
if container
|
2011
3183
|
container.stop()
|
2012
3184
|
end
|
@@ -2023,6 +3195,7 @@ module Cnvrg
|
|
2023
3195
|
method_option :remote, :type => :boolean, :aliases => ["-r", "--r"], :default => false, :desc => "run on remote machine"
|
2024
3196
|
method_option :kernel, :type => :string, :aliases => ["-k", "--k"], :default => "", :desc => "default kernel"
|
2025
3197
|
method_option :verbose, :type => :boolean, :aliases => ["--v"], :default => false
|
3198
|
+
method_option :image, :type => :string, :aliases => ["-i"], :default => ""
|
2026
3199
|
|
2027
3200
|
def run_notebook
|
2028
3201
|
|
@@ -2036,7 +3209,7 @@ module Cnvrg
|
|
2036
3209
|
notebook_dir = options["notebook_dir"]
|
2037
3210
|
remote = options["remote"] || false
|
2038
3211
|
kernel = options["kernel"] || ""
|
2039
|
-
|
3212
|
+
notebooks_pid = nil
|
2040
3213
|
|
2041
3214
|
if notebook_dir.empty?
|
2042
3215
|
notebook_dir = project_dir
|
@@ -2044,107 +3217,148 @@ module Cnvrg
|
|
2044
3217
|
|
2045
3218
|
notebook_dir = project_dir+ notebook_dir
|
2046
3219
|
end
|
2047
|
-
|
2048
|
-
image = is_project_with_docker(Dir.pwd)
|
2049
|
-
if image and image.is_docker and !remote
|
2050
|
-
container= image.get_container
|
2051
|
-
if !container
|
3220
|
+
choose_image = options["image"]
|
2052
3221
|
|
2053
|
-
|
3222
|
+
if !choose_image.nil? and !choose_image.empty?
|
3223
|
+
invoke :set_image, [choose_image]
|
3224
|
+
end
|
3225
|
+
|
3226
|
+
image = is_project_with_docker(Dir.pwd)
|
3227
|
+
if !image
|
3228
|
+
jupyter_installed = `which jupyter`
|
3229
|
+
if !$?.success?
|
3230
|
+
say "Could not find jupyter, Is it installed?", Thor::Shell::Color::RED
|
2054
3231
|
exit(1)
|
2055
3232
|
end
|
2056
|
-
else
|
2057
|
-
say "Project is not configured with any image", Thor::Shell::Color::RED
|
2058
|
-
exit(1)
|
2059
3233
|
|
2060
|
-
end
|
2061
|
-
if options["verbose"]
|
2062
|
-
say "Syncing project before running", Thor::Shell::Color::BLUE
|
2063
|
-
say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE
|
2064
|
-
end
|
2065
|
-
@project = Project.new(project_dir)
|
2066
3234
|
|
2067
|
-
|
3235
|
+
cmd = "jupyter-notebook --port=8888"
|
3236
|
+
PTY.spawn(cmd) do |stdout, stdin, pid, stderr|
|
3237
|
+
begin
|
3238
|
+
notebooks_pid = pid
|
3239
|
+
stdout.each do |line|
|
3240
|
+
puts line
|
3241
|
+
|
3242
|
+
end
|
3243
|
+
|
3244
|
+
rescue Errno::EIO => e
|
3245
|
+
# break
|
3246
|
+
rescue Errno::ENOENT
|
3247
|
+
log_end(1, "command #{cmd} isn't valid")
|
3248
|
+
|
3249
|
+
|
3250
|
+
say "command \"#{cmd}\" couldn't be executed, verify command is valid", Thor::Shell::Color::RED
|
3251
|
+
rescue PTY::ChildExited
|
3252
|
+
log_end(1, "proccess exited")
|
3253
|
+
say "The process exited!", Thor::Shell::Color::RED
|
3254
|
+
rescue => e
|
3255
|
+
log_end(-1, e.message)
|
3256
|
+
say "Error occurred,aborting", Thor::Shell::Color::RED
|
3257
|
+
exit(0)
|
3258
|
+
|
3259
|
+
end
|
3260
|
+
|
2068
3261
|
|
2069
|
-
if (note_slug=image.note_slug)
|
2070
|
-
say "There is a running notebook session in: https://cnvrg.io/#{@project.owner}/projects/#{@project.slug}/notebook_sessions/show/#{note_slug}", Thor::Shell::Color::BLUE
|
2071
|
-
new = yes? "Create a new session?", Thor::Shell::Color::YELLOW
|
2072
|
-
if !new
|
2073
|
-
exit(0)
|
2074
3262
|
end
|
2075
3263
|
|
2076
3264
|
end
|
2077
|
-
invoke :sync, [], :verbose => options["verbose"]
|
2078
|
-
say "Done Syncing", Thor::Shell::Color::BLUE if options["verbose"]
|
2079
|
-
#replace url
|
2080
|
-
base_url = get_base_url()
|
2081
3265
|
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
3266
|
+
if image and image.is_docker and !remote
|
3267
|
+
container= image.get_container
|
3268
|
+
if !container
|
3269
|
+
say "Couldn't start docker container", Thor::Shell::Color::RED
|
3270
|
+
exit(1)
|
2087
3271
|
|
2088
|
-
|
2089
|
-
port = image.container_port()
|
3272
|
+
end
|
2090
3273
|
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
3274
|
+
if options["verbose"]
|
3275
|
+
say "Syncing project before running", Thor::Shell::Color::BLUE
|
3276
|
+
say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE
|
3277
|
+
end
|
3278
|
+
@project = Project.new(project_dir)
|
3279
|
+
|
3280
|
+
start_commit = @project.last_local_commit
|
3281
|
+
|
3282
|
+
if (note_slug=image.note_slug)
|
3283
|
+
say "There is a running notebook session in: https://cnvrg.io/#{@project.owner}/projects/#{@project.slug}/notebook_sessions/show/#{note_slug}", Thor::Shell::Color::BLUE
|
3284
|
+
new = yes? "Create a new session?", Thor::Shell::Color::YELLOW
|
3285
|
+
if !new
|
3286
|
+
exit(0)
|
3287
|
+
end
|
3288
|
+
|
3289
|
+
end
|
3290
|
+
invoke :sync, [false], :verbose => options["verbose"]
|
3291
|
+
say "Done Syncing", Thor::Shell::Color::BLUE if options["verbose"]
|
3292
|
+
#replace url
|
3293
|
+
base_url = get_base_url()
|
3294
|
+
|
3295
|
+
local_url = "/#{@project.owner}/projects/#{@project.slug}/notebook_sessions/view/local"
|
3296
|
+
command = ["/bin/bash", "-lc", "sed -i 's#c.NotebookApp.base_url = .*#c.NotebookApp.base_url = \"#{local_url}\"#' /home/ds/.jupyter/jupyter_notebook_config.py"]
|
3297
|
+
container.exec(command, tty: true)
|
3298
|
+
container.stop()
|
3299
|
+
container.start()
|
3300
|
+
sleep(7)
|
3301
|
+
@note = Experiment.new(@project.owner, @project.slug)
|
3302
|
+
port = image.container_port()
|
3303
|
+
|
3304
|
+
command = ["/bin/bash", "-lc", "jupyter notebook list"]
|
3305
|
+
list = container.exec(command, tty: true)[0]
|
3306
|
+
if list.empty? or list.nil?
|
3307
|
+
say "Couldn't start notebook server", Thor::Shell::Color::RED
|
3308
|
+
log_end(1, "can't start notebook server")
|
3309
|
+
exit(1)
|
3310
|
+
end
|
2098
3311
|
|
2099
|
-
|
2100
|
-
|
3312
|
+
result = ""
|
3313
|
+
list.each do |r|
|
3314
|
+
if r.include? "http"
|
3315
|
+
result = r
|
3316
|
+
end
|
3317
|
+
end
|
3318
|
+
token = result.to_s.split("::")[0].to_s.match(/(token=)(.+)\s/)[2]
|
2101
3319
|
|
2102
|
-
|
3320
|
+
# machine_activity = @note.get_machine_activity(project_dir)
|
2103
3321
|
|
2104
3322
|
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
3323
|
+
slug = @note.start_notebook_session(kernel, start_commit, token, port, false, notebook_dir)
|
3324
|
+
image.set_note_url(slug)
|
3325
|
+
note_url = "http://localhost:#{port}/#{@project.owner}/projects/#{@project.slug}/notebook_sessions/view/local/?token=#{token}"
|
2108
3326
|
|
2109
3327
|
|
2110
|
-
|
2111
|
-
|
3328
|
+
if !note_url.empty?
|
3329
|
+
check = Helpers.checkmark()
|
2112
3330
|
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
|
2117
|
-
|
2118
|
-
|
3331
|
+
say "#{check} Notebook server started successfully", Thor::Shell::Color::GREEN
|
3332
|
+
Launchy.open(note_url)
|
3333
|
+
else
|
3334
|
+
say "Couldn't start notebook server", Thor::Shell::Color::RED
|
3335
|
+
log_end(1, "can't start notebook server")
|
3336
|
+
exit(1)
|
3337
|
+
end
|
2119
3338
|
end
|
2120
3339
|
|
2121
|
-
|
2122
|
-
# logs = `#{jup} --no-browser --ip=0.0.0.0 --notebook-dir=#{notebook_dir}`
|
2123
|
-
# url = URI.extract(logs).reject { |x| x if !x.include? "http" }.uniq![0]
|
2124
|
-
# if !url.empty?
|
2125
|
-
# check = Helpers.checkmark()
|
2126
|
-
#
|
2127
|
-
# say "#{check} Notebook server started successfully, view notebook in url: #{url}", Thor::Shell::Color::GREEN
|
2128
|
-
# log_end(0)
|
2129
|
-
# else
|
2130
|
-
# say "Couldn't start notebook server", Thor::Shell::Color::RED
|
2131
|
-
# log_end(1, "can't start notebook server")
|
2132
|
-
# exit(1)
|
2133
|
-
# end
|
3340
|
+
|
2134
3341
|
rescue => e
|
2135
|
-
log_end(-1)
|
2136
|
-
puts e
|
3342
|
+
log_end(-1, e.message)
|
2137
3343
|
say "Error occurd, aborting", Thor::Shell::Color::RED
|
2138
3344
|
if container
|
2139
3345
|
container.stop()
|
2140
3346
|
end
|
2141
3347
|
rescue SignalException
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
3348
|
+
if !notebooks_pid.nil?
|
3349
|
+
::Process.kill(0, notebooks_pid)
|
3350
|
+
say "#{check} Notebook has stopped successfully", Thor::Shell::Color::GREEN
|
3351
|
+
|
3352
|
+
|
3353
|
+
invoke :sync, [false], []
|
3354
|
+
else
|
3355
|
+
log_end(-1)
|
3356
|
+
|
3357
|
+
if container
|
3358
|
+
container.stop()
|
3359
|
+
end
|
2145
3360
|
end
|
2146
|
-
|
2147
|
-
exit(1)
|
3361
|
+
|
2148
3362
|
end
|
2149
3363
|
|
2150
3364
|
|
@@ -2165,7 +3379,7 @@ module Cnvrg
|
|
2165
3379
|
|
2166
3380
|
|
2167
3381
|
say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE if options["verbose"]
|
2168
|
-
invoke :sync, [], :verbose => options["verbose"]
|
3382
|
+
invoke :sync, [false], :verbose => options["verbose"]
|
2169
3383
|
|
2170
3384
|
say "Done Syncing", Thor::Shell::Color::BLUE if options["verbose"]
|
2171
3385
|
|
@@ -2210,8 +3424,7 @@ module Cnvrg
|
|
2210
3424
|
exit(0)
|
2211
3425
|
end
|
2212
3426
|
rescue => e
|
2213
|
-
|
2214
|
-
log_end(-1)
|
3427
|
+
log_end(-1, e.message)
|
2215
3428
|
say "Error occurd, aborting"
|
2216
3429
|
if container
|
2217
3430
|
container.stop()
|
@@ -2261,8 +3474,7 @@ module Cnvrg
|
|
2261
3474
|
|
2262
3475
|
log_end(0)
|
2263
3476
|
rescue => e
|
2264
|
-
log_end(-1)
|
2265
|
-
puts e
|
3477
|
+
log_end(-1, e.message)
|
2266
3478
|
say "Error occurd, aborting"
|
2267
3479
|
if container
|
2268
3480
|
container.stop()
|
@@ -2325,14 +3537,12 @@ module Cnvrg
|
|
2325
3537
|
|
2326
3538
|
log_end(0)
|
2327
3539
|
rescue => e
|
2328
|
-
log_end(-1)
|
2329
|
-
puts e
|
3540
|
+
log_end(-1, e.message)
|
2330
3541
|
say "Error occurd, aborting"
|
2331
3542
|
if container
|
2332
3543
|
container.stop()
|
2333
3544
|
end
|
2334
3545
|
rescue SignalException
|
2335
|
-
log_End(-1)
|
2336
3546
|
if container
|
2337
3547
|
container.stop()
|
2338
3548
|
end
|
@@ -2341,7 +3551,100 @@ module Cnvrg
|
|
2341
3551
|
end
|
2342
3552
|
|
2343
3553
|
end
|
2344
|
-
|
3554
|
+
|
3555
|
+
method_option :small, :type => :boolean, :aliases => ["-sm", "--small"], :default => false
|
3556
|
+
method_option :medium, :type => :boolean, :aliases => ["-md", "--medium"], :default => false
|
3557
|
+
method_option :large, :type => :boolean, :aliases => ["-lg", "--large"], :default => false
|
3558
|
+
method_option :gpu, :type => :boolean, :aliases => ["--gpu"], :default => false
|
3559
|
+
method_option :gpuxl, :type => :boolean, :aliases => ["--gpuxl"], :default => false
|
3560
|
+
method_option :gpuxxl, :type => :boolean, :aliases => ["--gpuxxl"], :default => false
|
3561
|
+
method_option :image, :type => :string, :aliases => ["-i","--image"], :default => ""
|
3562
|
+
method_option :public, :type => :boolean, :aliases => ["-p","--public"], :default => false
|
3563
|
+
method_option :base, :type => :boolean, :aliases => ["-b","--base"], :default => false
|
3564
|
+
method_option :python3, :type => :boolean, :aliases => ["--python3"], :default => false
|
3565
|
+
|
3566
|
+
desc 'create_custom_image', 'run commands inside containers', :hide=>true
|
3567
|
+
|
3568
|
+
def create_custom_image(image_name)
|
3569
|
+
begin
|
3570
|
+
verify_logged_in(false)
|
3571
|
+
log_start(__method__, args, options)
|
3572
|
+
instances = {"small" => options["small"], "medium" => options["medium"], "large" => options["large"],
|
3573
|
+
"gpu" => options["gpu"], "gpuxl" => options["gpuxl"], "gpuxxl" => options["gpuxxl"]}
|
3574
|
+
instance_type = get_instance_type(instances)
|
3575
|
+
image_extend = options["image"]
|
3576
|
+
public = options["public"]
|
3577
|
+
base = options["base"]
|
3578
|
+
python3 = options["python3"]
|
3579
|
+
owner = CLI.get_owner
|
3580
|
+
checks = Helpers.checkmark()
|
3581
|
+
|
3582
|
+
say "Creating machine for custom image, this may take a few moments...", Thor::Shell::Color::BLUE
|
3583
|
+
|
3584
|
+
resp = Images.create_new_custom_image(instance_type,owner,image_name,public,base,image_extend,python3)
|
3585
|
+
if Cnvrg::CLI.is_response_success(resp,false)
|
3586
|
+
image_slug = resp["result"]["slug"]
|
3587
|
+
container = resp["result"]["machine_c"]
|
3588
|
+
say "#{checks} Created image and machine successfully", Thor::Shell::Color::GREEN
|
3589
|
+
say "Connecting to machine", Thor::Shell::Color::BLUE
|
3590
|
+
ssh = Ssh.new(resp)
|
3591
|
+
if !ssh.is_ssh
|
3592
|
+
say "Couldn't connect to machine,aborting", Thor::Shell::Color::RED
|
3593
|
+
Images.revoke_custom_new_image(owner, image_slug)
|
3594
|
+
log_end(-1,"Couldn't connect to machine,aborting")
|
3595
|
+
end
|
3596
|
+
say "run command until ctrl + c initiates", Thor::Shell::Color::BLUE
|
3597
|
+
begin
|
3598
|
+
|
3599
|
+
while true
|
3600
|
+
command = ask("$>")
|
3601
|
+
puts ssh.exec_command(command)
|
3602
|
+
end
|
3603
|
+
|
3604
|
+
rescue SignalException
|
3605
|
+
say "Commiting Image..", Thor::Shell::Color::BLUE
|
3606
|
+
|
3607
|
+
end
|
3608
|
+
resp = Images.commit_custom_image(owner,image_slug)
|
3609
|
+
if Cnvrg::CLI.is_response_success(resp,false)
|
3610
|
+
say "#{checks} Image commited successfuly, email will be sent when image is ready", Thor::Shell::Color::GREEN
|
3611
|
+
end
|
3612
|
+
if ssh
|
3613
|
+
ssh.close_ssh()
|
3614
|
+
end
|
3615
|
+
|
3616
|
+
|
3617
|
+
|
3618
|
+
|
3619
|
+
|
3620
|
+
|
3621
|
+
|
3622
|
+
end
|
3623
|
+
rescue =>e
|
3624
|
+
puts e
|
3625
|
+
if image_slug
|
3626
|
+
Images.revoke_custom_new_image(owner, image_slug)
|
3627
|
+
end
|
3628
|
+
if ssh
|
3629
|
+
ssh.close_ssh()
|
3630
|
+
end
|
3631
|
+
|
3632
|
+
|
3633
|
+
rescue SignalException
|
3634
|
+
if image_slug
|
3635
|
+
Images.revoke_custom_new_image(owner, image_slug)
|
3636
|
+
end
|
3637
|
+
if ssh
|
3638
|
+
ssh.close_ssh
|
3639
|
+
end
|
3640
|
+
say "\nAborting"
|
3641
|
+
exit(1)
|
3642
|
+
end
|
3643
|
+
|
3644
|
+
end
|
3645
|
+
|
3646
|
+
|
3647
|
+
desc 'build', 'run commands inside containers'
|
2345
3648
|
method_option :install, :type => :string, :aliases => ["--i"], :default => nil, :desc => "Install from the given instructions file"
|
2346
3649
|
|
2347
3650
|
def build(*cmd)
|
@@ -2352,10 +3655,10 @@ module Cnvrg
|
|
2352
3655
|
working_dir = is_cnvrg_dir
|
2353
3656
|
install_file = options["install"] || nil
|
2354
3657
|
if !install_file.nil?
|
2355
|
-
commands = File.open(install_file).read.chop.gsub!("\n",",").split(",")
|
3658
|
+
commands = File.open(install_file).read.chop.gsub!("\n", ",").split(",")
|
2356
3659
|
|
2357
3660
|
else
|
2358
|
-
commands
|
3661
|
+
commands = [cmd.join(" ")]
|
2359
3662
|
end
|
2360
3663
|
|
2361
3664
|
|
@@ -2373,25 +3676,25 @@ module Cnvrg
|
|
2373
3676
|
|
2374
3677
|
end
|
2375
3678
|
commands.each do |c|
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2381
|
-
|
3679
|
+
if c.include? "pip"
|
3680
|
+
c.sub("pip", "/opt/ds/bin/pip")
|
3681
|
+
end
|
3682
|
+
if c.include? "pip3"
|
3683
|
+
c.sub("pip3", "/opt/ds3/bin/pip3")
|
3684
|
+
end
|
2382
3685
|
|
2383
|
-
|
2384
|
-
|
2385
|
-
|
2386
|
-
|
2387
|
-
|
2388
|
-
|
2389
|
-
|
3686
|
+
say "Running #{c}", Thor::Shell::Color::BLUE
|
3687
|
+
command = ["/bin/bash", "-lc", "#{c}"]
|
3688
|
+
res = container.exec(command, tty: false)
|
3689
|
+
if res[2] != 0
|
3690
|
+
say "Could not run command: #{c}, #{res[1][0]}", Thor::Shell::Color::RED
|
3691
|
+
container.stop()
|
3692
|
+
log_end(0)
|
2390
3693
|
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
2394
|
-
|
3694
|
+
exit(1)
|
3695
|
+
end
|
3696
|
+
say res[0].join("\n")
|
3697
|
+
image.store_image_build_commands(working_dir, c)
|
2395
3698
|
end
|
2396
3699
|
|
2397
3700
|
checks = Helpers.checkmark()
|
@@ -2402,8 +3705,7 @@ module Cnvrg
|
|
2402
3705
|
|
2403
3706
|
log_end(0)
|
2404
3707
|
rescue => e
|
2405
|
-
log_end(-1)
|
2406
|
-
puts e
|
3708
|
+
log_end(-1, e.message)
|
2407
3709
|
say "Error occurd, aborting", Thor::Shell::Color::RED
|
2408
3710
|
if container
|
2409
3711
|
container.stop()
|
@@ -2452,8 +3754,9 @@ module Cnvrg
|
|
2452
3754
|
log_end(0)
|
2453
3755
|
return new_image.id
|
2454
3756
|
rescue => e
|
2455
|
-
|
2456
|
-
|
3757
|
+
log_end(-1, e.message)
|
3758
|
+
say "\nError occurred,aborting"
|
3759
|
+
exit(1)
|
2457
3760
|
rescue SignalException
|
2458
3761
|
log_end(-1)
|
2459
3762
|
say "\nAborting"
|
@@ -2496,7 +3799,7 @@ module Cnvrg
|
|
2496
3799
|
|
2497
3800
|
end
|
2498
3801
|
|
2499
|
-
desc 'push
|
3802
|
+
desc 'push', 'push image to cnvrg repository'
|
2500
3803
|
|
2501
3804
|
def push(*name)
|
2502
3805
|
verify_logged_in(true)
|
@@ -2514,22 +3817,24 @@ module Cnvrg
|
|
2514
3817
|
end
|
2515
3818
|
if !name.nil? and !name.empty?
|
2516
3819
|
if name.include? " "
|
2517
|
-
name.gsub!(" ","_")
|
3820
|
+
name.gsub!(" ", "_")
|
2518
3821
|
end
|
2519
3822
|
end
|
2520
|
-
stored_commands = File.open(working_dir+"/.cnvrg/custom_image.txt").read.chop.gsub("\n",",")
|
3823
|
+
stored_commands = File.open(working_dir+"/.cnvrg/custom_image.txt").read.chop.gsub("\n", ",")
|
2521
3824
|
if stored_commands.nil? or stored_commands.empty?
|
2522
3825
|
say "Nothing to push", Thor::Shell::Color::BLUE
|
2523
3826
|
exit(0)
|
2524
3827
|
end
|
2525
3828
|
|
2526
3829
|
say "Pushing new image", Thor::Shell::Color::BLUE
|
2527
|
-
if image.create_custom_image(name,working_dir,stored_commands)
|
3830
|
+
if image.create_custom_image(name, working_dir, stored_commands)
|
2528
3831
|
|
2529
3832
|
say "Image was updated successfully", Thor::Shell::Color::GREEN
|
2530
3833
|
end
|
2531
3834
|
rescue => e
|
2532
|
-
|
3835
|
+
log_end(-1, e.message)
|
3836
|
+
say "error occurred, aborting"
|
3837
|
+
|
2533
3838
|
end
|
2534
3839
|
end
|
2535
3840
|
|
@@ -2591,8 +3896,8 @@ module Cnvrg
|
|
2591
3896
|
exit(1)
|
2592
3897
|
end
|
2593
3898
|
rescue => e
|
2594
|
-
|
2595
|
-
|
3899
|
+
log_end(-1, e.message)
|
3900
|
+
say "Couldn't upload image file for: #{image_name}", Thor::Shell::Color::RED
|
2596
3901
|
rescue SignalException
|
2597
3902
|
log_end(-1)
|
2598
3903
|
|
@@ -2601,7 +3906,7 @@ module Cnvrg
|
|
2601
3906
|
end
|
2602
3907
|
end
|
2603
3908
|
|
2604
|
-
desc '', ''
|
3909
|
+
desc '', '', :hide => true
|
2605
3910
|
|
2606
3911
|
def upload_log()
|
2607
3912
|
log_path = '/home/ds/app/uwsgi.log'
|
@@ -2610,28 +3915,32 @@ module Cnvrg
|
|
2610
3915
|
|
2611
3916
|
end
|
2612
3917
|
|
2613
|
-
desc '', ''
|
3918
|
+
desc '', '', :hide => true
|
2614
3919
|
|
2615
3920
|
def exec_container(container_id, *cmd)
|
2616
3921
|
container = Docker::Container.get(container_id)
|
2617
3922
|
container.start()
|
2618
3923
|
cnvrg_command = cmd.join(" ")
|
2619
3924
|
command = ["/bin/bash", "-lc", "#{cnvrg_command}"]
|
2620
|
-
res = container.exec(command, tty: true,wait:5400)[0]
|
3925
|
+
res = container.exec(command, tty: true, wait: 5400)[0]
|
2621
3926
|
say res
|
2622
|
-
|
2623
3927
|
end
|
2624
3928
|
|
2625
|
-
desc '', ''
|
3929
|
+
desc '', '', :hide => true
|
2626
3930
|
|
2627
3931
|
def port_container(container_id)
|
2628
3932
|
container = Docker::Container.get(container_id)
|
2629
3933
|
say container.json["HostConfig"]["PortBindings"]["8888/tcp"][0]["HostPort"]
|
3934
|
+
end
|
2630
3935
|
|
3936
|
+
desc '', '', :hide => true
|
2631
3937
|
|
3938
|
+
def tensor_port_container(container_id)
|
3939
|
+
container = Docker::Container.get(container_id)
|
3940
|
+
say container.json["HostConfig"]["PortBindings"]["6006/tcp"][0]["HostPort"]
|
2632
3941
|
end
|
2633
3942
|
|
2634
|
-
desc '', ''
|
3943
|
+
desc '', '', :hide => true
|
2635
3944
|
|
2636
3945
|
def stop_container(container_id)
|
2637
3946
|
container = Docker::Container.get(container_id)
|
@@ -2640,13 +3949,13 @@ module Cnvrg
|
|
2640
3949
|
|
2641
3950
|
end
|
2642
3951
|
|
2643
|
-
desc '', ''
|
2644
|
-
method_option :login, :type => :string, :aliases => ["-l"
|
2645
|
-
method_option :app_dir, :type => :string, :aliases => ["-d"
|
2646
|
-
method_option :cmd, :type => :string, :aliases => ["-c"
|
3952
|
+
desc '', '', :hide => true
|
3953
|
+
method_option :login, :type => :string, :aliases => ["-l"], :default => ""
|
3954
|
+
method_option :app_dir, :type => :string, :aliases => ["-d"], :default => "/home/ds/notebooks"
|
3955
|
+
method_option :cmd, :type => :string, :aliases => ["-c"], :default => "/usr/local/cnvrg/run_ipython.sh"
|
2647
3956
|
|
2648
3957
|
|
2649
|
-
def config_remote(image_name, port=7654)
|
3958
|
+
def config_remote(image_name, port=7654, tensport=6006)
|
2650
3959
|
local_images = Docker::Image.all
|
2651
3960
|
|
2652
3961
|
docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.eql? "#{image_name}:latest" }.flatten
|
@@ -2659,20 +3968,25 @@ module Cnvrg
|
|
2659
3968
|
login_content = options["login"]
|
2660
3969
|
app_dir = options["app_dir"]
|
2661
3970
|
cmd= options["cmd"]
|
3971
|
+
volume_from = options["volume"]
|
2662
3972
|
|
2663
3973
|
image_settings = {
|
2664
3974
|
'Image' => "#{image_name}:latest",
|
2665
|
-
|
3975
|
+
|
2666
3976
|
'Cmd' => cmd,
|
2667
3977
|
'WorkingDir' => app_dir,
|
2668
3978
|
'ExposedPorts' => {
|
2669
3979
|
'8888/tcp' => {},
|
2670
3980
|
},
|
2671
3981
|
'HostConfig' => {
|
3982
|
+
'Binds'=> ["/var/run/docker.sock:/var/run/docker.sock","/usr/bin/docker:/usr/bin/docker" ],
|
2672
3983
|
'PortBindings' => {
|
2673
3984
|
'8888/tcp' => [
|
2674
3985
|
{'HostPort' => "#{port}", 'HostIp' => 'localhost'}
|
2675
3986
|
],
|
3987
|
+
'6006/tcp' => [
|
3988
|
+
{'HostPort' => "#{tensport}", 'HostIp' => 'localhost'}
|
3989
|
+
],
|
2676
3990
|
},
|
2677
3991
|
},
|
2678
3992
|
}
|
@@ -2680,21 +3994,104 @@ module Cnvrg
|
|
2680
3994
|
container.start()
|
2681
3995
|
command = ["/bin/bash", "-lc", "sudo echo -e \"#{login_content}\" >/home/ds/.netrc"]
|
2682
3996
|
container.exec(command, tty: true)
|
2683
|
-
command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg"]
|
3997
|
+
# command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg"]
|
3998
|
+
# container.exec(command, tty: true)
|
3999
|
+
# command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg/tmp"]
|
4000
|
+
# container.exec(command, tty: true)
|
4001
|
+
command = ["/bin/bash", "-lc", "sudo chown -R ds:ds /home/ds/.netrc"]
|
2684
4002
|
container.exec(command, tty: true)
|
2685
|
-
command = ["/bin/bash", "-lc", "
|
4003
|
+
command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
|
2686
4004
|
container.exec(command, tty: true)
|
2687
|
-
|
4005
|
+
say "#{container.id}:#{port}##{tensport}"
|
4006
|
+
rescue => e
|
4007
|
+
puts e
|
4008
|
+
if e.message.include? "is not running"
|
4009
|
+
return config_remote(image_name, port-1, tensport-1)
|
4010
|
+
end
|
4011
|
+
|
4012
|
+
if container
|
4013
|
+
container.kill()
|
4014
|
+
end
|
4015
|
+
return false
|
4016
|
+
end
|
4017
|
+
end
|
4018
|
+
|
4019
|
+
|
4020
|
+
desc '', '', :hide => true
|
4021
|
+
method_option :login, :type => :string, :aliases => ["-l"], :default => ""
|
4022
|
+
|
4023
|
+
def config_netrc(container)
|
4024
|
+
|
4025
|
+
login_content = options["login"]
|
4026
|
+
|
4027
|
+
container = Docker::Container.get(container)
|
4028
|
+
command = ["/bin/bash", "-lc", "sudo echo -e \"#{login_content}\" >/home/ds/.netrc"]
|
4029
|
+
container.exec(command, tty: true)
|
4030
|
+
command = ["/bin/bash", "-lc", "sudo chown -R ds:ds /home/ds/.netrc"]
|
4031
|
+
container.exec(command, tty: true)
|
4032
|
+
command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
|
4033
|
+
container.exec(command, tty: true)
|
4034
|
+
say "OK"
|
4035
|
+
|
4036
|
+
end
|
4037
|
+
|
4038
|
+
desc '', '', :hide => true
|
4039
|
+
method_option :login, :type => :string, :aliases => ["-l", "--l"], :default => ""
|
4040
|
+
method_option :app_dir, :type => :string, :aliases => ["-d", "--d"], :default => "/home/ds/notebooks"
|
4041
|
+
method_option :cmd, :type => :string, :aliases => ["-c", "--c"], :default => "/usr/local/cnvrg/run_ipython.sh"
|
4042
|
+
|
4043
|
+
|
4044
|
+
def config_remote_gpu(image_name, port=7654, tensport=6006)
|
4045
|
+
local_images = Docker::Image.all
|
4046
|
+
|
4047
|
+
docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.eql? "#{image_name}:latest" }.flatten
|
4048
|
+
if docker_image_local.empty?
|
4049
|
+
say "no image"
|
4050
|
+
exit(1)
|
4051
|
+
end
|
4052
|
+
|
4053
|
+
begin
|
4054
|
+
login_content = options["login"]
|
4055
|
+
app_dir = options["app_dir"]
|
4056
|
+
cmd= options["cmd"]
|
4057
|
+
|
4058
|
+
# image_settings = {
|
4059
|
+
# 'Image' => "#{image_name}:latest",
|
4060
|
+
# 'User' => 'ds',
|
4061
|
+
# 'Cmd' => cmd,
|
4062
|
+
# 'WorkingDir' => app_dir,
|
4063
|
+
# 'ExposedPorts' => {
|
4064
|
+
# '8888/tcp' => {},
|
4065
|
+
# },
|
4066
|
+
# 'HostConfig' => {
|
4067
|
+
# 'PortBindings' => {
|
4068
|
+
# '8888/tcp' => [
|
4069
|
+
# {'HostPort' => "#{port}", 'HostIp' => 'localhost'}
|
4070
|
+
# ],
|
4071
|
+
# '6006/tcp' => [
|
4072
|
+
# {'HostPort' => "6006", 'HostIp' => 'localhost'}
|
4073
|
+
# ],
|
4074
|
+
# },
|
4075
|
+
# },
|
4076
|
+
# }
|
4077
|
+
|
4078
|
+
container_id = `nvidia-docker run -itd -p #{port}:8888 -p #{tensport}:6006 -w #{app_dir} -v /usr/bin/nvidia-smi:/usr/bin/nvidia-smi -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker #{image_name}:latest #{cmd} `
|
4079
|
+
container_id = container_id.gsub("\n", "")
|
4080
|
+
container = Docker::Container.get(container_id)
|
4081
|
+
# container.start()
|
4082
|
+
command = ["/bin/bash", "-lc", "sudo echo -e \"#{login_content}\" >/home/ds/.netrc"]
|
4083
|
+
container.exec(command, tty: true)
|
4084
|
+
command = ["/bin/bash", "-lc", "sudo chown -R ds:ds /home/ds/.netrc"]
|
2688
4085
|
container.exec(command, tty: true)
|
2689
4086
|
command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
|
2690
4087
|
container.exec(command, tty: true)
|
2691
|
-
say "#{container.id}:#{port}"
|
4088
|
+
say "#{container.id}:#{port}##{tensport}"
|
2692
4089
|
rescue => e
|
2693
4090
|
if e.message.include? "is not running"
|
2694
|
-
|
4091
|
+
puts "running asgain with: #{port-1} #{tensport-1}"
|
4092
|
+
return config_remote_gpu(image_name, port-1, tensport-1)
|
2695
4093
|
end
|
2696
|
-
|
2697
|
-
puts e
|
4094
|
+
|
2698
4095
|
if container
|
2699
4096
|
container.kill()
|
2700
4097
|
end
|
@@ -2702,8 +4099,8 @@ module Cnvrg
|
|
2702
4099
|
end
|
2703
4100
|
end
|
2704
4101
|
|
2705
|
-
desc '', ''
|
2706
|
-
method_option :login, :type => :string, :aliases => ["-l"
|
4102
|
+
desc '', '', :hide => true
|
4103
|
+
method_option :login, :type => :string, :aliases => ["-l"], :default => ""
|
2707
4104
|
|
2708
4105
|
def config_flask_remote(image_name, port=80)
|
2709
4106
|
local_images = Docker::Image.all
|
@@ -2736,21 +4133,54 @@ module Cnvrg
|
|
2736
4133
|
container.start()
|
2737
4134
|
command = ["/bin/bash", "-lc", "sudo echo -e \"#{login_content}\" >/home/ds/.netrc"]
|
2738
4135
|
container.exec(command, tty: true)
|
2739
|
-
command = ["/bin/bash", "-lc", "
|
4136
|
+
command = ["/bin/bash", "-lc", "sudo chown -R ds:ds /home/ds/.netrc"]
|
2740
4137
|
container.exec(command, tty: true)
|
2741
|
-
command = ["/bin/bash", "-lc", "
|
4138
|
+
command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
|
2742
4139
|
container.exec(command, tty: true)
|
2743
|
-
|
4140
|
+
say "#{container.id}:#{port}"
|
4141
|
+
rescue => e
|
4142
|
+
pus e
|
4143
|
+
if e.message.include? "is not running"
|
4144
|
+
return "port is taken"
|
4145
|
+
end
|
4146
|
+
puts "error"
|
4147
|
+
if container
|
4148
|
+
container.kill()
|
4149
|
+
end
|
4150
|
+
return false
|
4151
|
+
end
|
4152
|
+
end
|
4153
|
+
|
4154
|
+
desc '', '', :hide => true
|
4155
|
+
method_option :login, :type => :string, :aliases => ["-l"], :default => ""
|
4156
|
+
|
4157
|
+
def config_flask_remote_gpu(image_name, port=80)
|
4158
|
+
local_images = Docker::Image.all
|
4159
|
+
|
4160
|
+
docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.eql? "#{image_name}:latest" }.flatten
|
4161
|
+
if docker_image_local.empty?
|
4162
|
+
say "no image"
|
4163
|
+
exit(1)
|
4164
|
+
end
|
4165
|
+
|
4166
|
+
begin
|
4167
|
+
login_content = options["login"]
|
4168
|
+
container_id = `nvidia-docker run -itd -p 80:80 -w /home/ds/app #{image_name}:latest /usr/local/cnvrg/start_super.sh`
|
4169
|
+
container_id = container_id.gsub("\n", "")
|
4170
|
+
container = Docker::Container.get(container_id)
|
4171
|
+
command = ["/bin/bash", "-lc", "sudo echo -e \"#{login_content}\" >/home/ds/.netrc"]
|
4172
|
+
container.exec(command, tty: true)
|
4173
|
+
command = ["/bin/bash", "-lc", "sudo chown -R ds:ds /home/ds/.netrc"]
|
2744
4174
|
container.exec(command, tty: true)
|
2745
4175
|
command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
|
2746
4176
|
container.exec(command, tty: true)
|
2747
4177
|
say "#{container.id}:#{port}"
|
2748
4178
|
rescue => e
|
4179
|
+
puts e
|
2749
4180
|
if e.message.include? "is not running"
|
2750
4181
|
return "port is taken"
|
2751
4182
|
end
|
2752
4183
|
puts "error"
|
2753
|
-
puts e
|
2754
4184
|
if container
|
2755
4185
|
container.kill()
|
2756
4186
|
end
|
@@ -2758,7 +4188,7 @@ module Cnvrg
|
|
2758
4188
|
end
|
2759
4189
|
end
|
2760
4190
|
|
2761
|
-
desc '', ''
|
4191
|
+
desc '', '', :hide => true
|
2762
4192
|
|
2763
4193
|
def upload_cnvrg_image(image_name)
|
2764
4194
|
verify_logged_in(false)
|
@@ -2768,12 +4198,12 @@ module Cnvrg
|
|
2768
4198
|
|
2769
4199
|
path = File.expand_path('~')+"/.cnvrg/tmp/#{image_name}.zip"
|
2770
4200
|
@files = Cnvrg::Files.new("", "")
|
2771
|
-
python_arr = Cnvrg::Images.get_installed_packages("python")
|
2772
|
-
py = python_arr.join(",") unless python_arr.nil? or python_arr.empty?
|
2773
|
-
system_arr = Cnvrg::Images.get_installed_packages("system")
|
2774
|
-
sys = system_arr.join(",") unless system_arr.nil? or system_arr.empty?
|
4201
|
+
# python_arr = Cnvrg::Images.get_installed_packages("python")
|
4202
|
+
# py = python_arr.join(",") unless python_arr.nil? or python_arr.empty?
|
4203
|
+
# system_arr = Cnvrg::Images.get_installed_packages("system")
|
4204
|
+
# sys = system_arr.join(",") unless system_arr.nil? or system_arr.empty?
|
2775
4205
|
# bash_history = Cnvrg::Images.get_bash_history
|
2776
|
-
res = @files.upload_image(path, image_name, owner, true, true,
|
4206
|
+
res = @files.upload_image(path, image_name, owner, true, true, "", "", "", "Image made by cnvrg.io team", "")
|
2777
4207
|
|
2778
4208
|
end
|
2779
4209
|
|
@@ -2819,7 +4249,7 @@ module Cnvrg
|
|
2819
4249
|
end
|
2820
4250
|
end
|
2821
4251
|
|
2822
|
-
desc '', ''
|
4252
|
+
desc '', '', :hide => true
|
2823
4253
|
|
2824
4254
|
def download_image(image_name, image_slug)
|
2825
4255
|
begin
|
@@ -2845,8 +4275,6 @@ module Cnvrg
|
|
2845
4275
|
end
|
2846
4276
|
end
|
2847
4277
|
|
2848
|
-
|
2849
|
-
|
2850
4278
|
return dir_path
|
2851
4279
|
|
2852
4280
|
else
|
@@ -2880,13 +4308,13 @@ module Cnvrg
|
|
2880
4308
|
owner = Cnvrg::CLI.get_owner()
|
2881
4309
|
res = Cnvrg::API.request("users/#{owner}/images/list", 'GET')
|
2882
4310
|
if Cnvrg::CLI.is_response_success(res)
|
2883
|
-
printf "%-20s %-20s %-30s %-20s %-20s\n", "name", "project",
|
4311
|
+
printf "%-20s %-20s %-30s %-20s %-20s\n", "name", "project", "created by", "is_public", "last updated"
|
2884
4312
|
res["result"]["images"].each do |u|
|
2885
4313
|
time = Time.parse(u["created_at"])
|
2886
4314
|
update_at = get_local_time(time)
|
2887
4315
|
created_by = u["created_by"]
|
2888
4316
|
|
2889
|
-
printf "%-20s %-20s %-30s %-20s %-20s\n", u["name"], u["project"],
|
4317
|
+
printf "%-20s %-20s %-30s %-20s %-20s\n", u["name"], u["project"], created_by, u["is_public"], update_at
|
2890
4318
|
end
|
2891
4319
|
end
|
2892
4320
|
log_end(0)
|
@@ -2968,7 +4396,7 @@ module Cnvrg
|
|
2968
4396
|
|
2969
4397
|
desc 'pull_image', 'downloads and loads an image'
|
2970
4398
|
|
2971
|
-
def
|
4399
|
+
def pull_image(image_name)
|
2972
4400
|
begin
|
2973
4401
|
verify_logged_in(false)
|
2974
4402
|
log_start(__method__, args, options)
|
@@ -2981,8 +4409,18 @@ module Cnvrg
|
|
2981
4409
|
path = download_image(image_name, image["slug"])
|
2982
4410
|
if path
|
2983
4411
|
say "Building image", Thor::Shell::Color::BLUE
|
2984
|
-
Docker.options[:read_timeout]=
|
2985
|
-
image = Docker::Image.build_from_dir(path, {'dockerfile' => 'Dockerfile', 't' => "#{image_name}:
|
4412
|
+
Docker.options[:read_timeout]=216000
|
4413
|
+
image = Docker::Image.build_from_dir(path, {'dockerfile' => 'Dockerfile.cpu', 't' => "#{image_name}:latest"}) do |v|
|
4414
|
+
begin
|
4415
|
+
if (log = JSON.parse(v)) && log.has_key?("stream")
|
4416
|
+
next if log["stream"].starts_with? "Step"
|
4417
|
+
$stdout.puts log["stream"]
|
4418
|
+
end
|
4419
|
+
rescue
|
4420
|
+
end
|
4421
|
+
|
4422
|
+
end
|
4423
|
+
|
2986
4424
|
if not image.nil?
|
2987
4425
|
FileUtils.rm_rf(path)
|
2988
4426
|
checks = Helpers.checkmark()
|
@@ -2991,11 +4429,13 @@ module Cnvrg
|
|
2991
4429
|
return image
|
2992
4430
|
log_end(0)
|
2993
4431
|
else
|
4432
|
+
|
2994
4433
|
say "Could not build image", Thor::Shell::Color::RED
|
2995
4434
|
log_end(1, "Could build image")
|
2996
4435
|
return false
|
2997
4436
|
end
|
2998
4437
|
else
|
4438
|
+
|
2999
4439
|
say "Could not download image", Thor::Shell::Color::RED
|
3000
4440
|
log_end(1, "Could build image")
|
3001
4441
|
return false
|
@@ -3023,7 +4463,9 @@ module Cnvrg
|
|
3023
4463
|
#
|
3024
4464
|
# end
|
3025
4465
|
# end
|
3026
|
-
rescue
|
4466
|
+
rescue => e
|
4467
|
+
|
4468
|
+
|
3027
4469
|
say "Couldn't build image", Thor::Shell::Color::RED
|
3028
4470
|
|
3029
4471
|
rescue SignalException
|
@@ -3130,7 +4572,12 @@ module Cnvrg
|
|
3130
4572
|
if url.nil? or url.empty?
|
3131
4573
|
url = "https://cnvrg.io/api"
|
3132
4574
|
end
|
3133
|
-
config =
|
4575
|
+
config = YAML.load_file(home_dir+"/.cnvrg/config.yml")
|
4576
|
+
compression_path = "#{home_dir}/.cnvrg/tmp"
|
4577
|
+
if config and !config.nil? and !config.empty? and !config.to_h[:compression_path].nil?
|
4578
|
+
compression_path = config.to_h[:compression_path]
|
4579
|
+
end
|
4580
|
+
config = {owner: owner, username: username, version_last_check: get_start_day(), api: url,compression_path:compression_path}
|
3134
4581
|
|
3135
4582
|
File.open(home_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
3136
4583
|
return true
|
@@ -3184,7 +4631,7 @@ module Cnvrg
|
|
3184
4631
|
|
3185
4632
|
def log_end(exit_status=0, error=nil)
|
3186
4633
|
begin
|
3187
|
-
if exit_status
|
4634
|
+
if exit_status != 0
|
3188
4635
|
$LOG.error exit_status: exit_status, error: error
|
3189
4636
|
else
|
3190
4637
|
$LOG.info exit_status: exit_status
|
@@ -3196,7 +4643,6 @@ module Cnvrg
|
|
3196
4643
|
def self.is_response_success(response, should_exit=true)
|
3197
4644
|
if response.nil?
|
3198
4645
|
if !Cnvrg::Helpers.internet_connection?
|
3199
|
-
# Cnvrg::CLI.log_end(1,"no internet connection")
|
3200
4646
|
say("<%= color('Error:You seems to be offline', RED) %>")
|
3201
4647
|
else
|
3202
4648
|
say("<%= color('Error', RED) %>")
|
@@ -3231,12 +4677,26 @@ module Cnvrg
|
|
3231
4677
|
return owner
|
3232
4678
|
end
|
3233
4679
|
end
|
4680
|
+
|
3234
4681
|
def get_base_url
|
3235
4682
|
home_dir = File.expand_path('~')
|
3236
4683
|
|
3237
4684
|
config = YAML.load_file(home_dir+ "/.cnvrg/config.yml")
|
3238
4685
|
api = config.to_h[:api]
|
3239
|
-
return api.gsub!("/api","")
|
4686
|
+
return api.gsub!("/api", "")
|
4687
|
+
end
|
4688
|
+
def get_compression_path
|
4689
|
+
home_dir = File.expand_path('~')
|
4690
|
+
|
4691
|
+
config = YAML.load_file(home_dir+ "/.cnvrg/config.yml")
|
4692
|
+
compression_path = config.to_h[:compression_path]
|
4693
|
+
if compression_path.nil?
|
4694
|
+
compression_path = "#{home_dir}/.cnvrg/tmp/"
|
4695
|
+
end
|
4696
|
+
if !compression_path.ends_with? "/"
|
4697
|
+
compression_path = compression_path + "/"
|
4698
|
+
end
|
4699
|
+
return compression_path
|
3240
4700
|
end
|
3241
4701
|
|
3242
4702
|
def get_project_home
|
@@ -3290,7 +4750,6 @@ module Cnvrg
|
|
3290
4750
|
end
|
3291
4751
|
$LOG = LogStashLogger.new(type: :file, path: logfile, sync: true)
|
3292
4752
|
rescue => e
|
3293
|
-
# puts e
|
3294
4753
|
end
|
3295
4754
|
end
|
3296
4755
|
|
@@ -3318,6 +4777,9 @@ module Cnvrg
|
|
3318
4777
|
|
3319
4778
|
config = YAML.load_file(File.expand_path('~')+"/.cnvrg/config.yml")
|
3320
4779
|
version_date = config.to_h[:version_last_check]
|
4780
|
+
if version_date.nil?
|
4781
|
+
version_date = get_start_day()
|
4782
|
+
end
|
3321
4783
|
next_day = get_start_day+ 86399
|
3322
4784
|
if not (version_date..next_day).cover?(Time.now)
|
3323
4785
|
if should_update_version()
|
@@ -3343,11 +4805,15 @@ module Cnvrg
|
|
3343
4805
|
def is_cnvrg_dir(dir=Dir.pwd)
|
3344
4806
|
current_dir = dir
|
3345
4807
|
home_dir = File.expand_path('~')
|
4808
|
+
if current_dir.eql? home_dir
|
4809
|
+
return false
|
4810
|
+
end
|
3346
4811
|
is_cnvrg = Dir.exist? current_dir+"/.cnvrg"
|
3347
4812
|
until is_cnvrg == true
|
3348
4813
|
current_dir = File.expand_path("..", current_dir)
|
3349
4814
|
is_cnvrg = Dir.exist? current_dir+"/.cnvrg"
|
3350
|
-
if File.expand_path("..", current_dir).eql? home_dir
|
4815
|
+
if ((File.expand_path("..", current_dir).eql? home_dir) or current_dir.eql? home_dir or current_dir.eql? "/") and !is_cnvrg
|
4816
|
+
is_cnvrg = false
|
3351
4817
|
break
|
3352
4818
|
end
|
3353
4819
|
end
|
@@ -3358,6 +4824,19 @@ module Cnvrg
|
|
3358
4824
|
end
|
3359
4825
|
end
|
3360
4826
|
|
4827
|
+
def data_dir_include()
|
4828
|
+
all_dirs = Dir.glob("**/*/", File::FNM_DOTMATCH)
|
4829
|
+
all_dirs.flatten!
|
4830
|
+
all_dirs.each do |a|
|
4831
|
+
if a.include? "/.cnvrg"
|
4832
|
+
ignore = File.dirname(a)
|
4833
|
+
return ignore
|
4834
|
+
end
|
4835
|
+
end
|
4836
|
+
return nil
|
4837
|
+
|
4838
|
+
end
|
4839
|
+
|
3361
4840
|
def verify_software_installed(software)
|
3362
4841
|
begin
|
3363
4842
|
install_url = Cnvrg::CLI::INSTALLATION_URLS[software.to_sym]
|
@@ -3533,8 +5012,151 @@ module Cnvrg
|
|
3533
5012
|
|
3534
5013
|
end
|
3535
5014
|
|
5015
|
+
def update_deleted(deleted)
|
5016
|
+
final = []
|
5017
|
+
deleted.each do |d|
|
5018
|
+
all_subs = d.split("/")
|
5019
|
+
to_add = true
|
5020
|
+
value = all_subs[0]
|
5021
|
+
all_subs.each_with_index do |a, i|
|
5022
|
+
if final.include? value+"/"
|
5023
|
+
to_add = false
|
5024
|
+
break
|
5025
|
+
end
|
5026
|
+
value = value+"/"+all_subs[i+1] if i <all_subs.size-1
|
5027
|
+
end
|
5028
|
+
final << d if to_add
|
5029
|
+
|
5030
|
+
|
5031
|
+
end
|
5032
|
+
|
5033
|
+
|
5034
|
+
return final
|
5035
|
+
end
|
5036
|
+
|
5037
|
+
def get_cmd_path_in_dir(main_dir, sub_dir)
|
5038
|
+
first = Pathname.new main_dir
|
5039
|
+
second = Pathname.new sub_dir
|
5040
|
+
relative = second.relative_path_from first
|
5041
|
+
if relative.eql? "."
|
5042
|
+
return ""
|
5043
|
+
else
|
5044
|
+
return relative
|
5045
|
+
end
|
5046
|
+
end
|
5047
|
+
|
5048
|
+
def create_tar(path_in, path_out, tar_files,no_compression=false)
|
5049
|
+
#The cd is meant for cases when running cnvrg data uplaod not in the main folder
|
5050
|
+
begin
|
5051
|
+
if no_compression
|
5052
|
+
`cd #{path_in} && tar -cf #{path_out} -T #{tar_files}`
|
5053
|
+
else
|
5054
|
+
`cd #{path_in} && tar -czf #{path_out} -T #{tar_files}`
|
5055
|
+
end
|
5056
|
+
rescue => e
|
5057
|
+
puts "Exception while compressing data: #{e.message}"
|
5058
|
+
end
|
5059
|
+
|
5060
|
+
return $?.success?
|
5061
|
+
end
|
5062
|
+
|
5063
|
+
def extarct_tar(file_path, dir_path)
|
5064
|
+
`tar -xvf #{file_path} -C #{dir_path} > /dev/null 2>&1`
|
5065
|
+
return $?.success?
|
5066
|
+
end
|
5067
|
+
def cpu_usage
|
5068
|
+
cpu_usage = 0.0
|
5069
|
+
begin
|
5070
|
+
cpu = `top b -n 2 -d 2 |grep %Cpu |tail -1 |awk '{print $2+$3}'`
|
5071
|
+
if !cpu.nil?
|
5072
|
+
cpu_usage = cpu.to_f
|
5073
|
+
end
|
5074
|
+
rescue
|
5075
|
+
cpu_usage = 0.0
|
5076
|
+
end
|
5077
|
+
|
5078
|
+
return cpu_usage
|
5079
|
+
end
|
5080
|
+
def memory_usage
|
5081
|
+
prec = 0.0
|
5082
|
+
begin
|
5083
|
+
used = `free -mt |grep Mem: |awk '{print $3}'`
|
5084
|
+
total = `free -mt |grep Mem: |awk '{print $2}'`
|
5085
|
+
|
5086
|
+
used_f = used.to_f if !used.nil?
|
5087
|
+
total_f = total.to_f if !total.nil?
|
5088
|
+
prec = (used_f / total_f)*100
|
5089
|
+
prec = prec.round(2)
|
5090
|
+
rescue
|
5091
|
+
prec = 0.0
|
5092
|
+
end
|
5093
|
+
return prec
|
5094
|
+
|
5095
|
+
|
5096
|
+
end
|
5097
|
+
def gpu_util
|
5098
|
+
gpu = [0.0, 0.0]
|
5099
|
+
begin
|
5100
|
+
gpu_stats = `nvidia-smi --query-gpu=utilization.gpu,utilization.memory --format=csv |tail -1`
|
5101
|
+
|
5102
|
+
if !gpu_stats.nil?
|
5103
|
+
gpu = gpu_stats.strip
|
5104
|
+
gpu = gpu_stats.gsub!("%","").split(",")
|
5105
|
+
gpu[0] = gpu[0].to_f
|
5106
|
+
gpu[1] = gpu[1].to_f
|
5107
|
+
return gpu
|
5108
|
+
end
|
5109
|
+
|
5110
|
+
rescue
|
5111
|
+
return gpu
|
5112
|
+
end
|
5113
|
+
|
5114
|
+
|
5115
|
+
end
|
5116
|
+
def usage_metrics_in_docker(docker_id)
|
5117
|
+
res = [0.0,0.0]
|
5118
|
+
begin
|
5119
|
+
if docker_id.nil?
|
5120
|
+
docker_id = `cat /etc/hostname`
|
5121
|
+
end
|
5122
|
+
stats = `sudo docker stats #{docker_id} --no-stream --format "{{.CPUPerc}},{{.MemPerc}},{{.BlockIO}}"`
|
5123
|
+
if !stats.nil?
|
5124
|
+
conv = stats.split(",")
|
5125
|
+
cpu = conv[0].gsub!("%","").to_f
|
5126
|
+
memory = conv[1].gsub!("%","").to_f
|
5127
|
+
res = [cpu,memory]
|
5128
|
+
return res
|
5129
|
+
end
|
5130
|
+
rescue
|
5131
|
+
return res
|
5132
|
+
end
|
5133
|
+
|
5134
|
+
|
5135
|
+
|
5136
|
+
end
|
5137
|
+
|
5138
|
+
def with_progress_bar
|
5139
|
+
not_done = true
|
5140
|
+
upload_progress_bar = ProgressBar.create(:title => "Upload progress",
|
5141
|
+
:format => '%a <%B> %p%% %t',
|
5142
|
+
:starting_at => 0,
|
5143
|
+
:total => 600)
|
5144
|
+
pb = Thread.new do
|
5145
|
+
while not_done do
|
5146
|
+
upload_progress_bar.increment
|
5147
|
+
sleep(1)
|
5148
|
+
|
5149
|
+
end
|
5150
|
+
end
|
3536
5151
|
|
5152
|
+
yield.tap do # After yielding to the block, save the return value
|
5153
|
+
not_done = false # Tell the thread to exit, cleaning up after itself…
|
5154
|
+
pb.join # …and wait for it to do so.
|
5155
|
+
end
|
5156
|
+
end
|
3537
5157
|
end
|
5158
|
+
|
5159
|
+
|
3538
5160
|
end
|
3539
5161
|
end
|
3540
5162
|
|