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.
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' # sha1
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 'pry'
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', '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
- config = {owner: config.to_h[:owner], username: config.to_h[:username], version_last_check: config.to_h[:version_last_check], api: url}
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
- config = {owner: owner, username: current_user, version_last_check: get_start_day(), api: url}
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 'set default owner', 'set default owner'
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
- path = File.expand_path('~')+"/.cnvrg/config.yml"
170
- if !File.exist?(path)
171
- say "Couldn't find ~/.cnvrg/config.yml file, please logout and login again", Thor::Shell::Color::RED
271
+ exit(0)
272
+ end
273
+ config = YAML.load_file(path)
172
274
 
173
- exit(0)
174
- end
175
- config = YAML.load_file(path)
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
- username = config.to_h[:username]
178
- res = Cnvrg::API.request("/users/#{username}/get_possible_owners", 'GET')
179
- if Cnvrg::CLI.is_response_success(res)
180
- owner = username
181
- result = res["result"]
182
- owners = result["owners"]
183
- urls = result["urls"]
184
- choose_owner = result["username"]
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
- if set_owner(owner, username,urls[ow_index])
205
- say "Setting default owner: #{owner}", Thor::Shell::Color::GREEN
206
- else
207
- say "Setting default owenr has failed, try to run cnvrg --config-default-owner", Thor::Shell::Color::RED
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 and store credentials'
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
- owners << choose_owner
247
- chosen = false
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
- owners_lower = owners.map { |o| o.downcase }
252
- ow_index = owners_lower.index(choose_owner.downcase)
253
- if ow_index.nil?
254
- say "Could not find owner named #{choose_owner}", Thor::Shell::Color::RED
255
- else
256
- chosen = true
257
- end
258
- end
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", "--c"], :default => false
328
- method_option :docker_image, :type => :string, :aliases => ["-d", "--d"], :default => ""
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
- puts e
397
- log_end(-1)
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
- desc 'link', 'Link current directory to a cnvrg project'
452
- method_option :sync, :type => :boolean, :aliases => ["-s", "--s"], :default => true
453
- method_option :docker_image, :type => :string, :aliases => ["-d", "--d"], :default => ""
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
- desc 'unlink','Unlink a porject'
535
- def unlink
536
- verify_logged_in(false)
537
- log_start(__method__, args, options)
538
- working_dir = is_cnvrg_dir()
539
- list_to_del = [working_dir+"/.cnvrgignore",working_dir+"/.cnvrg"]
540
- FileUtils.rm_rf list_to_del
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 a project'
544
- method_option :remote, :type => :boolean, :aliases => ["-r", "--r"], :default => false
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 clone(project_url)
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 = project_url.split("/")
552
- project_index = Cnvrg::Helpers.look_for_in_path(project_url, "projects")
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
- remote = options["remote"] || false
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
- exit(1)
575
- end
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
- if clone_resp
585
- @project = Project.new(project_home)
586
- @files = Cnvrg::Files.new(@project.owner, slug)
587
- response = @project.clone(remote, commit_to_clone)
588
- Cnvrg::CLI.is_response_success response
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
- end
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
- say "Done.\nDownloaded total of #{successful_changes.size} files", Thor::Shell::Color::GREEN
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
- say "Error: Couldn't create directory: #{project_name}", Thor::Shell::Color::RED
645
- exit(1)
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
- desc 'status', 'Show the working tree status'
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
- verify_logged_in()
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
- result = @project.compare_idx(new_branch)["result"]
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 => :array, :aliases => ["-i", "--i"], :desc => "ignore following files"
720
- method_option :new_branch, :type => :boolean, :aliases => ["-nb", "--nb"], :desc => "create new branch of commits"
721
- method_option :verbose, :type => :boolean, :aliases => ["--v"], :default => false
722
- method_option :sync, :type => :boolean, :aliases => ["--v"], :default => false
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"].each do |f|
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
- say "#{check} Changes were updated successfully", Thor::Shell::Color::GREEN unless options["sync"]
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::BLUE
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", "--nb"], :desc => "create new branch of commits"
898
- method_option :verbose, :type => :boolean, :aliases => ["--v"], :default => false
899
- method_option :sync, :type => :boolean, :aliases => ["--v"], :default => false
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 => ["--nb"], :desc => "create new branch of commits"
1060
- method_option :verbose, :type => :boolean, :aliases => ["--v"], :default => false
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
- say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE
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"],:sync=>true
1072
- check = Helpers.checkmark()
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 => ["--l"], :default => false
1081
- method_option :small, :type => :boolean, :aliases => ["--sm"], :default => false
1082
- method_option :medium, :type => :boolean, :aliases => ["--med"], :default => false
1083
- method_option :large, :type => :boolean, :aliases => ["--lg"], :default => false
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 => ["--gxl"], :default => false
1086
- method_option :sync_before, :type => :boolean, :aliases => ["--sb"], :default => true
1087
- method_option :sync_after, :type => :boolean, :aliases => ["--sa"], :default => true
1088
- method_option :title, :type => :string, :aliases => ["--t"], :default => ""
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 => ["--en"], :default => false
1091
- method_option :upload_output, :type => :string, :aliases => ["--uo"], :default => ""
1092
- method_option :commit, :type => :string, :aliases => ["--c"], :default => ""
1093
- method_option :schedule, :type => :string, :aliases => ["--s"], :default => ""
1094
- method_option :image, :type => :string, :aliases => ["--i"], :default => ""
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, :commit => commit, :image => image
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
- instances = {"small" => options["small"], "medium" => options["medium"], "large" => options["large"], "gpu" => options["gpu"], "gpuxl" => options["gpuxl"]}
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, :image =>image
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 = Dir.pwd
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"] || nil
1147
- indocker = options["indocker"] || false
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
- invoke :sync, [], :new_branch => is_new_branch
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
- image_proj = is_project_with_docker(working_dir)
2251
+ image_proj = is_project_with_docker(working_dir)
1171
2252
 
1172
2253
 
1173
- if image_proj and image_proj.is_docker
1174
- container= image_proj.get_container
1175
- if !container
1176
- say "Couldn't create container with image #{image_proj.image_name}:#{image_proj.image_tag}", Thor::Shell::Color::RED
1177
- exit(1)
1178
- end
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
- exec_args = args.flatten.join(" ")
1182
- options_hash = Hash[options]
1183
- options_hash.except!("image", "indocker")
1184
- exec_options = options_hash.map { |x| "--#{x[0]}=#{x[1]}" }.flatten.join(" ")
1185
- command_to_run = cmd.join(" ")
1186
- command = ["/bin/bash", "-lc", "cnvrg exec --indocker #{exec_options} #{command_to_run} #{exec_args}"]
1187
- puts container.exec(command, tty: true)
1188
- container.stop()
1189
- exit(0)
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(Dir.pwd)
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
- monitor = %x{ps aux|awk '{print $2,$3,$4}'|grep #{pid} }
1216
- monitor_by = monitor.split(" ")
1217
- memory = monitor_by[2]
1218
- cpu = monitor_by[1]
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
- if print_log
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
- puts e
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
- puts e
1275
- log_end(1, e.message)
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 your'e back online?", Thor::Shell::Color::YELLOW
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
- else
1313
- invoke :sync, [], :new_branch => true
1314
- end
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 result: #{Cnvrg::Helpers.remote_url}/#{@project.owner}/projects/#{@project.slug}/experiments/#{@exp.slug}", Thor::Shell::Color::GREEN
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
- puts e
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", "--sb"], :default => true
1537
- method_option :sync_after, :type => :boolean, :aliases => ["-sa", "--sa"], :default => true
1538
- method_option :title, :type => :string, :aliases => ["-t", "--t"], :default => ""
1539
- method_option :log, :type => :boolean, :aliases => ["-l", "--l"], :default => false
1540
- method_option :email_notification, :type => :boolean, :aliases => ["-en", "--en"], :default => false
1541
- method_option :upload_output, :type => :string, :aliases => ["--uo", "-uo"], :default => ""
1542
- method_option :machine_type, :type => :string, :aliases => ["--i", "-i"], :default => ""
1543
- method_option :schedule, :type => :string, :aliases => ["--s", "-s"], :default => ""
1544
- method_option :commit, :type => :string, :aliases => ["--c", "-c"], :default => nil
1545
- method_option :image, :type => :string, :aliases => ["--i"], :default => ""
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} --uo=1m #{cmd.flatten.join(" ")}"
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
- default_image_name = "cnvrg"
2718
+
2719
+ image_slug = "cnvrg"
1593
2720
  if instance_type.eql? "gpu" or instance_type.eql? "gpuxl"
1594
- default_image_name = "cnvrg-gpu"
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
- image = Images.new(working_dir, default_image_name)
1599
- image_slug = image.image_slug
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
- say "#{check} Experiment's is on: #{Cnvrg::Helpers.remote_url}/#{project.owner}/projects/#{project.slug}/experiments/#{res["result"]["exp_url"]}", Thor::Shell::Color::GREEN
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 :machine_type, :type => :string, :aliases => ["--i", "-i"], :default => ""
1669
- method_option :schedule, :type => :string, :aliases => ["--s", "-s"], :default => ""
1670
- method_option :commit, :type => :string, :aliases => ["--c", "-c"], :default => ""
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
- image = Images.new(working_dir, "cnvrg")
1698
- image_slug = image.image_slug
1699
- else
1700
- exit(0)
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
- invoke :sync, [], []
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 => ["--l"], :default => false
1767
- method_option :small, :type => :boolean, :aliases => ["--sm"], :default => false
1768
- method_option :medium, :type => :boolean, :aliases => ["--med"], :default => false
1769
- method_option :large, :type => :boolean, :aliases => ["--lg"], :default => false
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 => ["--gxl"], :default => false
1772
- desc 'starts a notebook session', 'starts a notebook session remotely or locally'
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
- def notebook()
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"], "gpu" => options["gpu"], "gpuxl" => options["gpuxl"]}
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", "--n"], :default => "", :desc => "relative path to notebook dir from current directory"
1796
- method_option :machine_type, :type => :string, :aliases => ["--i", "-i"], :default => ""
1797
- method_option :kernel, :type => :string, :aliases => ["--k", "-k"], :default => ""
1798
- method_option :image, :type => :string, :aliases => ["--i"], :default => ""
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
- @image = Images.new(working_dir, default_image_name)
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}/#{@project.owner}/projects/#{@project.slug}/notebook_sessions/show/#{note_url}", Thor::Shell::Color::GREEN
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
- puts e
1945
- log_end(-1)
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
- puts e
2008
- log_end(-1)
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
- say "Linking notebook directory to: #{File.basename notebook_dir}", Thor::Shell::Color::BLUE
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
- say "Couldn't create container with image #{image.image_name}:#{image.image_tag}", Thor::Shell::Color::RED
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
- start_commit = @project.last_local_commit
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
- local_url = "/#{@project.owner}/projects/#{@project.slug}/notebook_sessions/view/local"
2083
- command = ["/bin/bash","-lc","sed -i 's#c.NotebookApp.base_url = .*#c.NotebookApp.base_url = \"#{local_url}\"#' /home/ds/.jupyter/jupyter_notebook_config.py"]
2084
- container.exec(command, tty: true)
2085
- container.stop()
2086
- container.start()
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
- @note = Experiment.new(@project.owner, @project.slug)
2089
- port = image.container_port()
3272
+ end
2090
3273
 
2091
- command = ["/bin/bash", "-lc", "jupyter notebook list"]
2092
- list = container.exec(command, tty: true)[0]
2093
- if list.empty? or list.nil?
2094
- say "Couldn't start notebook server", Thor::Shell::Color::RED
2095
- log_end(1, "can't start notebook server")
2096
- exit(1)
2097
- end
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
- url = list[list.size-1].split(" ::")
2100
- token = url[0][(url[0].index("=")+1)..-1]
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
- # machine_activity = @note.get_machine_activity(project_dir)
3320
+ # machine_activity = @note.get_machine_activity(project_dir)
2103
3321
 
2104
3322
 
2105
- slug = @note.start_notebook_session(kernel, start_commit, token, port, false, notebook_dir)
2106
- image.set_note_url(slug)
2107
- note_url = "http://localhost:#{port}/#{@project.owner}/projects/#{@project.slug}/notebook_sessions/view/local/?token=#{token}"
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
- if !note_url.empty?
2111
- check = Helpers.checkmark()
3328
+ if !note_url.empty?
3329
+ check = Helpers.checkmark()
2112
3330
 
2113
- say "#{check} Notebook server started successfully", Thor::Shell::Color::GREEN
2114
- Launchy.open(note_url)
2115
- else
2116
- say "Couldn't start notebook server", Thor::Shell::Color::RED
2117
- log_end(1, "can't start notebook server")
2118
- exit(1)
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
- # jup =verify_software_installed("jupyter-notebook")
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
- log_end(-1)
2143
- if container
2144
- container.stop()
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
- say "Aborting"
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
- puts e
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
- desc 'run commands inside containers', 'run commands inside containers'
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 = [cmd.join(" ")]
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
- if c.include? "pip"
2377
- c.sub("pip","/opt/ds/bin/pip")
2378
- end
2379
- if c.include? "pip3"
2380
- c.sub("pip3","/opt/ds3/bin/pip3")
2381
- end
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
- say "Running #{c}", Thor::Shell::Color::BLUE
2384
- command = ["/bin/bash", "-lc", "#{c}"]
2385
- res = container.exec(command, tty: false)
2386
- if res[2] != 0
2387
- say "Could not run command: #{c}, #{res[1][0]}" , Thor::Shell::Color::RED
2388
- container.stop()
2389
- log_end(0)
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
- exit(1)
2392
- end
2393
- say res[0].join("\n")
2394
- image.store_image_build_commands(working_dir,c)
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
- puts e
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 image to cnvrg repository', 'push image to cnvrg repository'
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
- puts e
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
- puts e
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", "--l"], :default => ""
2645
- method_option :app_dir, :type => :string, :aliases => ["-d", "--d"], :default => "/home/ds/notebooks"
2646
- method_option :cmd, :type => :string, :aliases => ["-c", "--c"], :default => "/usr/local/cnvrg/run_ipython.sh"
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
- 'User' => 'ds',
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", "mkdir /home/ds/.cnvrg/tmp"]
4003
+ command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
2686
4004
  container.exec(command, tty: true)
2687
- command = ["/bin/bash", "-lc", "sudo chown -R ds /home/ds/.cnvrg /home/ds/.netrc"]
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
- return config_remote(image_name, port-1)
4091
+ puts "running asgain with: #{port-1} #{tensport-1}"
4092
+ return config_remote_gpu(image_name, port-1, tensport-1)
2695
4093
  end
2696
- puts "error"
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", "--l"], :default => ""
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", "mkdir /home/ds/.cnvrg"]
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", "mkdir /home/ds/.cnvrg/tmp"]
4138
+ command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
2742
4139
  container.exec(command, tty: true)
2743
- command = ["/bin/bash", "-lc", "sudo chown -R ds /home/ds/.cnvrg /home/ds/.netrc"]
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, sys, py, "", "Image made by cnvrg.io team", "")
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", "created by", "is_public", "last updated"
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"], created_by, u["is_public"], update_at
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 pull(image_name)
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]=1200
2985
- image = Docker::Image.build_from_dir(path, {'dockerfile' => 'Dockerfile', 't' => "#{image_name}:lastest"})
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 = {owner: owner, username: username, version_last_check: get_start_day(), api: url}
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==1
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