cnvrg 0.0.11 → 0.0.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 745fd9b806d9e5d46b4ba24212e06f5a426447f3
4
- data.tar.gz: c950e20258da5c1243765572b6b7f4c93d0cad1a
3
+ metadata.gz: 8432cc00ad72f6d67385219a55b548742775175c
4
+ data.tar.gz: d2c199857e991d8b09976342528c18b148c42b34
5
5
  SHA512:
6
- metadata.gz: f60cd3a8cbb4d9bb6c53beac4faf0b76d5db9db469e4474dabe36787985b7d601a07d0029dcb797b7ede238ec2fa3e96beaaa56497b39fc05380dd05f54981fb
7
- data.tar.gz: 6587fe66cf021518dc9249a3c0eb936ccfb126b51b6b6cc605d1e44b09cbee30b55bb590cc7420bec05951077d63f452bb9a88a7466a78bd1281d51ccd334b1f
6
+ metadata.gz: ce22716700dc44b4deb39b3ecc9ed7dd3ee23ad7eae084c26fea82735cb11deff753697b3460e39968fabc89a4c8c126da065876b5a9d5a076a3a4c95d40a31d
7
+ data.tar.gz: 17626311afe8004d692b0e76abff3ed81fc8f24cd5a7a144e06a41f8cee9f0f2611642a1090f77b1d98649ed5c4447ea52ef31699fcfe0c8814967f0ac1bac9d
data/cnvrg.gemspec CHANGED
@@ -35,7 +35,11 @@ Gem::Specification.new do |spec|
35
35
  spec.add_runtime_dependency 'sucker_punch', '~> 2.0'
36
36
  spec.add_runtime_dependency 'urlcrypt', '~> 0.1.1'
37
37
  spec.add_runtime_dependency 'logstash-logger'
38
+ spec.add_runtime_dependency 'launchy'
38
39
  spec.add_runtime_dependency 'docker-api'
40
+ spec.add_runtime_dependency 'rubyzip'
41
+ spec.add_runtime_dependency 'activesupport'
42
+
39
43
 
40
44
  end
41
45
 
data/lib/cnvrg.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  require 'rubygems'
2
- require 'thor'
3
-
4
2
  require 'cnvrg/version'
5
3
  require 'cnvrg/cli'
4
+ require 'thor'
6
5
 
7
6
 
8
7
  module Cnvrg
@@ -0,0 +1,372 @@
1
+ require 'fileutils'
2
+ require 'cnvrg/files'
3
+ require 'docker'
4
+ require 'pry'
5
+
6
+ module Cnvrg
7
+ class Images
8
+ attr_reader :image_name, :image_tag, :is_docker, :project_slug, :commit_id, :owner, :port, :image_slug
9
+
10
+
11
+ def initialize(working_dir, image_name="")
12
+ begin
13
+ config = YAML.load_file(working_dir+"/.cnvrg/config.yml")
14
+ idx = YAML.load_file(working_dir + "/.cnvrg/idx.yml")
15
+
16
+ @working_dir = working_dir
17
+ @commit_id =idx[:commit]
18
+ @project_title = config[:project_name]
19
+ @project_slug = config[:project_slug]
20
+ @owner = config[:owner]
21
+ @is_docker = config[:docker]
22
+ if image_name.empty?
23
+ @image_name = config[:image_base]
24
+ @image_tag = config[:image_tag]
25
+ @image_slug = find_image()
26
+
27
+ else
28
+
29
+ @image_name = image_name
30
+ if !@image_name.nil? and !@image_name.empty?
31
+ if image_name.include? ":"
32
+ @image_name = image_name[0, image_name.index(":")]
33
+ @image_tag = image_name[image_name.index(":")+1, image_name.size]
34
+ else
35
+ @image_name = image_name
36
+ @image_tag = "lastest"
37
+ end
38
+
39
+ end
40
+ @image_slug = find_image(false)
41
+ update_image_activity(@commit_id, nil)
42
+ config = {project_name: config[:project_name],
43
+ project_slug: config[:project_slug],
44
+ owner: config[:owner],
45
+ docker: true, image_base: @image_name, image_tag: @image_tag, image_slug: image_slug}
46
+ File.open(working_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
47
+ end
48
+
49
+ rescue => e
50
+ puts e
51
+ end
52
+
53
+ end
54
+
55
+ def is_container_exist()
56
+ config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
57
+ if config[:container].nil?
58
+ return false
59
+ end
60
+ return config[:container]
61
+ end
62
+
63
+ def container_port()
64
+ config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
65
+ if config[:container].nil?
66
+ return false
67
+ else
68
+ return config[:port]
69
+ end
70
+ end
71
+
72
+ def self.image_exist(owner, image_name)
73
+
74
+ image_res = Cnvrg::API.request("users/#{owner}/images/" + "find", 'POST', {image_name: image_name})
75
+
76
+ if Cnvrg::CLI.is_response_success(image_res)
77
+ image= image_res["result"]["image"]
78
+ return image
79
+ else
80
+ return false
81
+
82
+ end
83
+ end
84
+ def store_image_build_commands(working_dir, cmd)
85
+ begin
86
+ custom_image_file = working_dir+"/.cnvrg/custom_image.txt"
87
+ if !File.exist? custom_image_file
88
+ FileUtils.touch [custom_image_file]
89
+ end
90
+ File.open(custom_image_file, 'a' ) do |f|
91
+ f.puts cmd
92
+ end
93
+ rescue
94
+ end
95
+
96
+
97
+ end
98
+
99
+ def create_custom_image(new_image_name,working_dir,stored_commands)
100
+
101
+ python2_arr = get_installed_packages("python2")
102
+ py2 = python2_arr.join(",") unless python2_arr.nil? or python2_arr.empty?
103
+ python3_arr = get_installed_packages("python3")
104
+ py3 = python3_arr.join(",") unless python3_arr.nil? or python3_arr.empty?
105
+ system_arr = get_installed_packages("system")
106
+ sys = system_arr.join(",") unless system_arr.nil? or system_arr.empty?
107
+
108
+ response = Cnvrg::API.request("users/#{@owner}/projects/#{@project_slug}/images/push", 'POST', {image_slug: @image_slug, py2: py2,py3:py3,
109
+ dpkg: sys, new_image_name: new_image_name,
110
+ run_commands:stored_commands})
111
+ if Cnvrg::CLI.is_response_success(response) and !response["result"]["slug"].nil?
112
+ container = get_container()
113
+ name = response["result"]["name"]
114
+ container = get_container()
115
+ container.commit({repo:name,tag:"latest"})
116
+ update_image(name+":latest", container, response["result"]["slug"])
117
+ File.truncate(working_dir+"/.cnvrg/custom_image.txt", 0)
118
+
119
+ end
120
+
121
+ return true
122
+
123
+ end
124
+
125
+ def update_image(image_name, container, image_slug)
126
+ config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
127
+ @image_name = image_name
128
+ if !@image_name.nil? and !@image_name.empty?
129
+ @image_name = image_name[0, image_name.index(":")]
130
+ @image_tag = image_name[image_name.index(":")+1, image_name.size]
131
+ end
132
+ config = {project_name: config[:project_name],
133
+ project_slug: config[:project_slug],
134
+ owner: config[:owner],
135
+ docker: true, image_base: @image_name, image_tag: @image_tag, container: container.id, image_slug: image_slug}
136
+
137
+ File.open(@working_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
138
+ end
139
+
140
+ def get_container(stop=false)
141
+ begin
142
+ container_id=is_container_exist()
143
+
144
+ if !container_id
145
+ return create_container()
146
+ else
147
+ container = Docker::Container.get(container_id)
148
+ status = container.json["State"]["Status"]
149
+
150
+ if status == "running"
151
+ return container
152
+ else
153
+ if stop
154
+ return false
155
+ end
156
+ res = container.start()
157
+ if res.info["State"]["Status"].eql? "exited" and res.info["State"]["Error"].include? "port is already allocated"
158
+ return create_container()
159
+ end
160
+ return container
161
+ end
162
+ end
163
+ rescue => e
164
+ if e.message.include? "No such container"
165
+
166
+ return create_container()
167
+ else
168
+ return false
169
+ end
170
+ end
171
+
172
+ end
173
+
174
+ def create_container(port=7654, is_remote=false)
175
+ begin
176
+ image_settings = {
177
+ 'Image' => "#{@image_name}:#{@image_tag}",
178
+ 'User' => 'ds',
179
+ 'Cmd' => '/home/ds/run_ipython.sh',
180
+ 'ExposedPorts' => {
181
+ '8888/tcp' => {},
182
+ },
183
+ 'HostConfig' => {
184
+ 'Binds' => ["#{@working_dir}:/home/ds/notebooks"],
185
+ 'PortBindings' => {
186
+ '8888/tcp' => [
187
+ {'HostPort' => "#{port}", 'HostIp' => 'localhost'}
188
+ ],
189
+ },
190
+ },
191
+ }
192
+ # if !is_remote
193
+ # image_settings['HostConfig'].merge!({ 'Binds' => ["#{@working_dir}:/home/ds/notebooks"]})
194
+ # end
195
+ container = Docker::Container.create(image_settings)
196
+ container.start()
197
+ netrc = File.open(File.expand_path('~')+"/.netrc", "rb")
198
+ netrc_content = netrc.read
199
+ container.store_file("/home/ds/.netrc", netrc_content)
200
+ command = ["/bin/bash", "-lc", "sudo chmod 600 /home/ds/.netrc"]
201
+ p = container.exec(command, tty: true)
202
+ command = ["/bin/bash", "-lc", "sudo chown -R ds /home/ds/.netrc"]
203
+ p = container.exec(command, tty: true)
204
+ command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg"]
205
+ container.exec(command, tty: true)
206
+ command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg/tmp"]
207
+ container.exec(command, tty: true)
208
+ config = File.open(File.expand_path('~')+"/.cnvrg/config.yml", "rb")
209
+ config_content = config.read
210
+ container.store_file("/home/ds/.cnvrg/config.yml", config_content)
211
+ command = ["/bin/bash", "-lc", "sudo chown -R ds /home/ds/.cnvrg"]
212
+ container.exec(command, tty: true)
213
+ # Libraries instlled
214
+ save_installed_libraries(container)
215
+ config = {project_name: @project_name,
216
+ project_slug: @project_slug,
217
+ owner: @owner,
218
+ docker: true, image_base: @image_name, image_tag: @image_tag, container: container.id, port: port, image_slug: @image_slug}
219
+
220
+ File.open(@working_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
221
+
222
+
223
+ return container
224
+
225
+
226
+ rescue => e
227
+ if e.message.include? "is not running"
228
+ return create_container(port-1)
229
+ end
230
+ puts e
231
+ return false
232
+ rescue SignalException
233
+
234
+ say "\nAborting", Thor::Shell::Color::RED
235
+ exit(1)
236
+ end
237
+
238
+
239
+ end
240
+
241
+ def save_installed_libraries(container)
242
+ begin
243
+ command = ['/bin/bash', '-lc', '/opt/ds/bin/pip freeze']
244
+ pip = container.exec(command, tty: true)[0]
245
+ command = ["/bin/bash", "-lc", "dpkg -l | grep '^ii' | awk '{print $2\"==\"$3}'"]
246
+ dpkg = container.exec(command, tty: true)[0]
247
+ File.open(@working_dir+"/.cnvrg/pip_base.txt", "w+") { |f| f.write pip }
248
+ File.open(@working_dir+"/.cnvrg/dpkg_base.txt", "w+") { |f| f.write dpkg }
249
+ rescue => e
250
+ puts e
251
+ end
252
+
253
+
254
+ end
255
+
256
+ def remote_notebook(notebook_path, instance_type, kernel)
257
+ response = Cnvrg::API.request("users/#{@owner}/images/#{@image_slug}/remote_notebook", 'POST', {dir: notebook_path,
258
+ project_slug: @project_slug,
259
+ instance_type: instance_type,
260
+ kernel: kernel})
261
+ return response
262
+ end
263
+
264
+ def get_installed_packages(repo)
265
+ container = get_container()
266
+ case repo
267
+ when "python2"
268
+ command = ['/bin/bash', '-lc', '/opt/ds/bin/pip freeze']
269
+ when "python3"
270
+ command = ['/bin/bash', '-lc', '/opt/ds3/bin/pip3 freeze']
271
+ when "system"
272
+ command = ["/bin/bash", "-lc", "dpkg -l | grep '^ii' | awk '{print $2\"==\"$3}'"]
273
+ end
274
+
275
+ libs = container.exec(command, tty: true)[0]
276
+ libs_arr = libs.join("").split("\r\n")
277
+ return libs_arr
278
+
279
+ end
280
+
281
+ def get_bash_history
282
+ container = get_container()
283
+ command = ["/bin/bash", "-lc", "cat /home/ds/.bash_history"]
284
+ history = container.exec(command, tty: true)[0][0]
285
+ if history.include? "No such file"
286
+ history = ""
287
+ end
288
+ return history
289
+ end
290
+
291
+
292
+ def get_image_state
293
+ python_arr = self.get_installed_packages("python")
294
+ py = python_arr.join(",") unless python_arr.nil? or python_arr.empty?
295
+ system_arr = self.get_installed_packages("system")
296
+ sys = system_arr.join(",") unless system_arr.nil? or system_arr.empty?
297
+ # bash_history = self.get_bash_history
298
+ diff = [py, sys]
299
+
300
+ end
301
+
302
+ def find_image(update=true)
303
+ config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
304
+ image_slug = config[:image_slug]
305
+ if image_slug.nil? or image_slug.empty?
306
+ image_res = Cnvrg::API.request("users/#{@owner}/images/" + "find", 'POST', {image_name: @image_name})
307
+
308
+ if Cnvrg::CLI.is_response_success(image_res)
309
+ image_slug = image_res["result"]["image"]["slug"]
310
+ update_slug(image_slug) unless !update
311
+ return image_slug
312
+ end
313
+ else
314
+ return image_slug
315
+
316
+ end
317
+ end
318
+
319
+ def set_note_url(note_slug)
320
+ config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
321
+ config[:notebook_slug] = note_slug
322
+ File.open(@working_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
323
+ end
324
+ def note_slug
325
+ config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
326
+ note_slug = config[:notebook_slug]
327
+ if note_slug.nil? or note_slug.empty?
328
+ return false
329
+ else
330
+ return note_slug
331
+ end
332
+ end
333
+ def remove_note_slug
334
+ config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
335
+ config[:notebook_slug] = ""
336
+ File.open(@working_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
337
+
338
+ end
339
+
340
+
341
+ def update_slug(slug)
342
+ config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
343
+ config[:image_slug] = slug
344
+ File.open(@working_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
345
+ end
346
+
347
+ def new_machine(instance_type)
348
+ title = "#{instance_type} auto created by cli"
349
+ response = Cnvrg::API.request("users/#{@owner}/machines/new", 'POST', {machine_name: title, instance_type: instance_type})
350
+ return Cnvrg::CLI.is_response_success(response)
351
+
352
+ end
353
+
354
+ def update_image_activity(commit, exp_slug)
355
+ response = Cnvrg::API.request("users/#{@owner}/images/#{@image_slug}/update_activity", 'POST', {commit: commit, project_slug: @project_slug, experiment: exp_slug})
356
+ return Cnvrg::CLI.is_response_success(response)
357
+ end
358
+
359
+ def handle_image_activity
360
+ home_dir = File.expand_path('~')
361
+ zip_dir = "#{home_dir}/.cnvrg/tmp/config.zip"
362
+ compress = `zip -j #{zip_dir} #{home_dir}/.netrc #{home_dir}/.cnvrg/config.yml`
363
+ @files = Cnvrg::Files.new(@owner, @project_slug)
364
+ res_id = @files.upload_exec_file(zip_dir, @image_name, @commit_id)
365
+ FileUtils.remove zip_dir
366
+ return res_id
367
+ end
368
+
369
+
370
+ end
371
+
372
+ end
data/lib/cnvrg/api.rb CHANGED
@@ -80,10 +80,12 @@ module Cnvrg
80
80
  # what if windows?
81
81
  # data[:file] = Faraday::UploadIO.new(data[:absolute_path], content_type)
82
82
  file_base = File.basename(data[:relative_path])
83
- temp_path = File.expand_path('~')+"/.cnvrg/tmp/#{file_base}"
83
+ temp_path = File.expand_path('~')+"/.cnvrg/tmp_files/#{file_base}"
84
84
  FileUtils.touch(temp_path)
85
85
  data[:file] = Faraday::UploadIO.new("#{temp_path}", "plain/text")
86
+
86
87
  response = conn.post "#{endpoint_uri}/#{resource}", data
88
+
87
89
  FileUtils.rm(temp_path)
88
90
 
89
91
  if parse_request == true
@@ -101,7 +103,8 @@ module Cnvrg
101
103
  end
102
104
  else
103
105
  end
104
- rescue
106
+ rescue => e
107
+ puts e
105
108
  return nil
106
109
  end
107
110
 
data/lib/cnvrg/cli.rb CHANGED
@@ -17,10 +17,19 @@ require 'cnvrg/auth'
17
17
  require 'cnvrg/project'
18
18
  require 'cnvrg/files'
19
19
  require 'cnvrg/experiment'
20
+ require 'cnvrg/Images'
20
21
  require 'etc'
21
22
  require 'logstash-logger'
22
23
  require 'cnvrg/job'
23
24
  require 'docker'
25
+ require 'launchy'
26
+ require 'socket'
27
+ require 'timeout'
28
+ require 'fileutils'
29
+ require 'zip'
30
+ require 'active_support/all'
31
+ require 'thor'
32
+ require 'pry'
24
33
 
25
34
  # DEV VERSION
26
35
  #
@@ -28,23 +37,62 @@ module Cnvrg
28
37
  class CLI < Thor
29
38
 
30
39
  INSTALLATION_URLS = {docker: "https://docs.docker.com/engine/installation/", jupyter: "http://jupyter.readthedocs.io/en/latest/install.html"}
31
- desc 'test', 'Prints cnvrg current version'
40
+ IP="localhost"
41
+ 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
+ class << self
55
+ # Hackery.Take the run method away from Thor so that we can redefine it.
56
+ def is_thor_reserved_word?(word, type)
57
+ return false if word == "run"
58
+ super
59
+ end
60
+ end
61
+
62
+ desc "", ""
63
+ method_option :schedule, :type => :string, :aliases => ["--s", "-s"], :default => "leahs"
32
64
 
33
65
  def test
34
- verify_software_installed("docker")
35
- container = Docker::Container.create( 'Image' => 'cnvrgio/python2')
36
- # container = Docker::Container.create("1e4e23560813")
37
- container.start
38
- puts container.exec(['bash'], stdin: StringIO.new("python --version"))
66
+ # image_settings = {
67
+ # 'Image' => "cnvrg:latest",
68
+ # 'User' => 'ds',
69
+ # 'Cmd' => '/home/ds/run_ipython.sh',
70
+ # 'ExposedPorts' => {
71
+ # '80/tcp' => {},
72
+ # },
73
+ # 'HostConfig' => {
74
+ # 'PortBindings' => {
75
+ # '80/tcp' => [
76
+ # {'HostPort' => "7654", 'HostIp' => 'localhost'}
77
+ # ],
78
+ # },
79
+ # },
80
+ # }
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)
39
85
 
40
86
  end
41
87
 
88
+
42
89
  desc 'version', 'Prints cnvrg current version'
43
90
 
44
91
  def version
45
92
  puts Cnvrg::VERSION
46
93
 
47
94
  end
95
+
48
96
  map %w(-v --version) => :version
49
97
 
50
98
  desc 'set api url', 'set api url'
@@ -62,22 +110,56 @@ module Cnvrg
62
110
  FileUtils.touch [home_dir+"/.cnvrg/config.yml"]
63
111
  end
64
112
  config = YAML.load_file(home_dir+"/.cnvrg/config.yml")
113
+ owner = config.to_h[:owner]
114
+
65
115
  say "Setting default api to be: #{url}", Thor::Shell::Color::BLUE
66
116
  if config.empty?
67
117
  config = {owner: "", username: "", version_last_check: get_start_day(), api: url}
68
118
  else
69
119
  config = {owner: config.to_h[:owner], username: config.to_h[:username], version_last_check: config.to_h[:version_last_check], api: url}
70
120
  end
71
- checks = Helpers.checkmark
121
+ res = Cnvrg::API.request("/users/#{owner}/custom_api", 'POST', {custom_api: url})
122
+ if Cnvrg::CLI.is_response_success(res)
72
123
 
124
+ checks = Helpers.checkmark
125
+
126
+
127
+ File.open(home_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
128
+ say "#{checks} Done", Thor::Shell::Color::GREEN
129
+ else
130
+ say "Couldn't set default api, contact help@cnvrg.io", Thor::Shell::Color::RED
131
+ exit(1)
132
+
133
+ end
73
134
 
74
- File.open(home_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
75
- say "#{checks} Done", Thor::Shell::Color::GREEN
76
135
  rescue
77
136
  say "Couldn't set default api, contact help@cnvrg.io", Thor::Shell::Color::RED
78
137
  end
79
138
  end
80
139
 
140
+ desc '', ''
141
+
142
+ def set_remote_api_url(owner, current_user, url)
143
+ home_dir = File.expand_path('~')
144
+ if !url.end_with? "/api"
145
+ url = url+"/api"
146
+ end
147
+ begin
148
+ if !File.directory? home_dir+"/.cnvrg"
149
+ FileUtils.mkdir_p([home_dir+"/.cnvrg", home_dir+"/.cnvrg/tmp"])
150
+ end
151
+ if !File.exist?(home_dir+"/.cnvrg/config.yml")
152
+ FileUtils.touch [home_dir+"/.cnvrg/config.yml"]
153
+ end
154
+ config = YAML.load_file(home_dir+"/.cnvrg/config.yml")
155
+ config = {owner: owner, username: current_user, version_last_check: get_start_day(), api: url}
156
+ File.open(home_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
157
+ say "Done"
158
+ rescue
159
+ say "ERROR", Thor::Shell::Color::RED
160
+ end
161
+ end
162
+
81
163
  map %w(-api --api) => :set_api_url
82
164
 
83
165
  desc 'set default owner', 'set default owner'
@@ -97,11 +179,29 @@ module Cnvrg
97
179
  if Cnvrg::CLI.is_response_success(res)
98
180
  owner = username
99
181
  result = res["result"]
100
- if result["owners"].size > 1
101
- owner = ask("Choose default owner:\n"+result["owners"].join("\n")+"\n")
182
+ owners = result["owners"]
183
+ urls = result["urls"]
184
+ choose_owner = result["username"]
185
+
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
+ end
200
+ end
201
+
102
202
 
103
203
  end
104
- if set_owner(owner, username)
204
+ if set_owner(owner, username,urls[ow_index])
105
205
  say "Setting default owner: #{owner}", Thor::Shell::Color::GREEN
106
206
  else
107
207
  say "Setting default owenr has failed, try to run cnvrg --config-default-owner", Thor::Shell::Color::RED
@@ -138,6 +238,7 @@ module Cnvrg
138
238
 
139
239
  say "Authenticated successfully as #{@email}", Thor::Shell::Color::GREEN
140
240
  owners = result["owners"]
241
+ urls = result["urls"]
141
242
  choose_owner = result["username"]
142
243
 
143
244
  if owners.empty?
@@ -145,18 +246,21 @@ module Cnvrg
145
246
  owners << choose_owner
146
247
  chosen = false
147
248
  while !chosen
148
- choose_owner = ask("Choose default owner:\n"+owners.join("\n")+"\n")
149
- owners_lower = owners.map{|o| o.downcase}
150
- if !owners_lower.include? choose_owner.downcase
151
- say "Could not find owner named #{choose_owner}", Thor::Shell::Color::RED
152
- else
153
- chosen = true
154
- end
249
+ choose_owner = ask("Choose default owner:\n"+owners.join("\n")+"\n")
250
+
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
155
258
  end
156
259
 
157
260
 
158
261
  end
159
- if set_owner(choose_owner, result["username"])
262
+
263
+ if set_owner(choose_owner, result["username"], urls[ow_index])
160
264
  say "Setting default owner: #{choose_owner}", Thor::Shell::Color::GREEN
161
265
 
162
266
  else
@@ -172,7 +276,7 @@ module Cnvrg
172
276
  end
173
277
  rescue SignalException
174
278
 
175
- say "/nAborting"
279
+ say "\nAborting"
176
280
  logout()
177
281
  exit(1)
178
282
  end
@@ -188,7 +292,7 @@ module Cnvrg
188
292
  netrc.save
189
293
  say "Logged out successfully.\n", Thor::Shell::Color::GREEN
190
294
  rescue SignalException
191
- say "/nAborting"
295
+ say "\nAborting"
192
296
  exit(1)
193
297
  end
194
298
 
@@ -201,7 +305,7 @@ module Cnvrg
201
305
  begin
202
306
 
203
307
  verify_logged_in(false)
204
- log_start(__method__,args,options)
308
+ log_start(__method__, args, options)
205
309
  auth = Cnvrg::Auth.new
206
310
  if (email = auth.get_email)
207
311
  say "Logged in as: #{email}", Thor::Shell::Color::GREEN
@@ -213,13 +317,12 @@ module Cnvrg
213
317
  rescue SignalException
214
318
  log_end(-1)
215
319
 
216
- say "/nAborting"
320
+ say "\nAborting"
217
321
  exit(1)
218
322
  end
219
323
  end
220
324
 
221
325
  ## Projects
222
-
223
326
  desc 'new', 'Create a new cnvrg project'
224
327
  method_option :clean, :type => :boolean, :aliases => ["-c", "--c"], :default => false
225
328
  method_option :docker_image, :type => :string, :aliases => ["-d", "--d"], :default => ""
@@ -227,142 +330,296 @@ module Cnvrg
227
330
  def new(project_name)
228
331
  begin
229
332
  verify_logged_in(false)
230
- log_start(__method__,args,options)
333
+ log_start(__method__, args, options)
231
334
  clean = options["clean"]
232
335
  docker_image = options["docker_image"]
336
+ working_dir = Dir.pwd + "/" + project_name
337
+ docker = false
233
338
  if !docker_image.nil? and !docker_image.empty?
234
- # local_images = Docker::Image.all
235
- # docker_image_local = local_images.map{|x| x.info["RepoTags"]}.select{|y| y[0].include? docker_image}.flatten
236
- # if docker_image_local.size == 0
237
- # if yes? "Image wasn't found locally, pull image from cnvrg repository?"
238
- # image = pull_image(docker_image)
239
- # if image
240
- # say "downloaded image: #{docker_image_local[0]}, creating a container.."
241
- # @container = Docker::Container.create('Image' => '#{docker_image_local[0]}')
242
- # if @container.nil?
243
- # say "could not create container with image #{docker_image_local[0]}"
244
- # end
245
- # end
246
- # else
247
- # say "Could not create a new project with docker, image was not found", Thor::Shell::Color::RED
248
- # exit(1)
249
- #
250
- # end
251
- # elsif docker_image_local.size == 1
252
- # say "found image: #{docker_image_local[0]}, creating a container.."
253
- # @container = Docker::Container.create('Image' => '#{docker_image_local[0]}')
254
- # if @container.nil?
255
- # say "could not create container with image #{docker_image_local[0]}"
256
- # end
257
- #
258
- # end
339
+ docker = true
259
340
  end
260
341
  say "Creating #{project_name}", Thor::Shell::Color::BLUE
261
342
  if Dir.exists? project_name or File.exists? project_name
262
343
  say "Conflict with dir/file #{project_name}", Thor::Shell::Color::RED
263
- log_end(1,"conflict with dir/file #{project_name}")
344
+ log_end(1, "conflict with dir/file #{project_name}")
264
345
  exit(1)
265
- end
266
346
 
267
- if Project.create(project_name, clean)
347
+ end
348
+ if Project.create(project_name, clean, with_docker=docker)
268
349
  path = Dir.pwd + "/" + project_name
269
350
  @project = Project.new(path)
270
351
  @project.generate_idx
352
+ if docker
353
+ local_images = Docker::Image.all
354
+ docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.include? docker_image }.flatten
355
+ if docker_image_local.size == 0
356
+
357
+ if yes? "Image wasn't found locally, pull image from cnvrg repository?", Thor::Shell::Color::YELLOW
358
+ image = pull(docker_image)
359
+ if image
360
+ say "downloaded image: #{docker_image}"
361
+ @image = Images.new(working_dir, docker_image)
362
+ else
363
+ say "Could not create a new project with docker, image was not found", Thor::Shell::Color::RED
364
+ @project.revert(working_dir)
365
+ exit(1)
366
+ end
367
+ else
368
+ say "Could not create a new project with docker, image was not found", Thor::Shell::Color::RED
369
+ @project.revert(working_dir)
370
+ exit(1)
371
+
372
+ end
373
+ elsif docker_image_local.size == 1
374
+ say "found image: #{docker_image_local[0]}, setting it up..", Thor::Shell::Color::BLUE
375
+ @image = Images.new(working_dir, docker_image_local[0])
376
+ elsif docker_image_local.size >1
377
+ say "found #{docker_image_local.size} images, choose the image name you want to use", Thor::Shell::Color::BLUE
378
+ image_name = ask "#{docker_image_local.join("\n")}\n", Thor::Shell::Color::BLUE
379
+ image_name = image_name.strip
380
+ @image = Images.new(working_dir, image_name)
381
+ end
382
+ @image.update_image_activity(nil, nil)
383
+
384
+ end
271
385
  else
272
386
  say "Error creating project, please contact support.", Thor::Shell::Color::RED
273
- log_end(1,"can't create project #{project_name}")
387
+ @project.revert(working_dir)
388
+ log_end(1, "can't create project #{project_name}")
274
389
 
275
390
  exit(0)
276
391
  end
277
392
 
278
- say "created\t\tproject's tree", Thor::Shell::Color::GREEN
279
- say "created\t\tproject's config", Thor::Shell::Color::GREEN
393
+ say "created project successfully", Thor::Shell::Color::GREEN
280
394
  say "Linked directory to\t#{@project.url}", Thor::Shell::Color::GREEN
395
+ rescue => e
396
+ puts e
397
+ log_end(-1)
398
+ if Dir.exist? working_dir
399
+
400
+ @project.revert(working_dir)
401
+ end
402
+
403
+ exit(1)
281
404
 
282
405
  rescue SignalException
283
406
  log_end(-1)
407
+ if Dir.exist? working_dir
284
408
 
285
- say "/nAborting"
409
+ @project.revert(working_dir)
410
+ end
411
+ say "\nAborting"
286
412
  exit(1)
287
413
  end
288
414
  end
415
+ desc 'set_image', 'set_image for a project'
416
+
417
+ def set_image(docker_image)
418
+ verify_logged_in(false)
419
+ log_start(__method__, args, options)
420
+ working_dir = is_cnvrg_dir
421
+ local_images = Docker::Image.all
422
+ docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.include? docker_image }.flatten
423
+ if docker_image_local.size == 0
424
+
425
+ if yes? "Image wasn't found locally, pull image from cnvrg repository?", Thor::Shell::Color::YELLOW
426
+ image = pull(docker_image)
427
+ if image
428
+ say "downloaded image: #{docker_image}"
429
+ @image = Images.new(working_dir, docker_image)
430
+ else
431
+ say "Could not set image, image was not found", Thor::Shell::Color::RED
432
+ exit(1)
433
+ end
434
+ else
435
+ say "Could nset image, image was not found", Thor::Shell::Color::RED
436
+ exit(1)
289
437
 
438
+ end
439
+ elsif docker_image_local.size == 1
440
+ say "found image: #{docker_image_local[0]}, setting it up..", Thor::Shell::Color::BLUE
441
+ @image = Images.new(working_dir, docker_image_local[0])
442
+ elsif docker_image_local.size >1
443
+ say "found #{docker_image_local.size} images, choose the image name you want to use", Thor::Shell::Color::BLUE
444
+ image_name = ask "#{docker_image_local.join("\n")}\n", Thor::Shell::Color::BLUE
445
+ image_name = image_name.strip
446
+ @image = Images.new(working_dir, image_name)
447
+ end
448
+ @image.update_image_activity(nil, nil)
290
449
 
450
+ 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 => ""
291
454
 
292
- desc 'link', 'Link current directory to a cnvrg project'
293
- method_option :sync, :type => :boolean, :aliases => ["-s", "--s"], :default => true
455
+ def link
456
+ begin
457
+ verify_logged_in(false)
458
+ log_start(__method__, args, options)
459
+ docker_image = options["docker_image"]
460
+ if !docker_image.nil? and !docker_image.empty?
461
+ docker = true
462
+ else
463
+ docker = false
464
+ end
294
465
 
295
- def link
296
- begin
297
- verify_logged_in(false)
298
- log_start(__method__,args,options)
466
+ sync = options["sync"]
467
+ project_name =File.basename(Dir.getwd)
468
+ say "Linking #{project_name}", Thor::Shell::Color::BLUE
469
+ if File.directory?(Dir.getwd+"/.cnvrg")
470
+ config = YAML.load_file("#{Dir.getwd}/.cnvrg/config.yml")
471
+ say "Directory is already linked to #{config[:project_slug]}", Thor::Shell::Color::RED
299
472
 
300
- sync = options["sync"]
301
- project_name =File.basename(Dir.getwd)
302
- say "Linking #{project_name}", Thor::Shell::Color::BLUE
303
- if File.directory?(Dir.getwd+"/.cnvrg")
304
- config = YAML.load_file("#{Dir.getwd}/.cnvrg/config.yml")
305
- say "Directory is already linked to #{config[:project_slug]}", Thor::Shell::Color::RED
473
+ exit(0)
474
+ end
475
+ working_dir = Dir.getwd
476
+ owner = CLI.get_owner
477
+ if Project.link(owner,project_name, docker)
478
+ path = Dir.pwd
479
+ @project = Project.new(path)
480
+ @project.generate_idx()
481
+ if docker
482
+ local_images = Docker::Image.all
483
+ docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.include? docker_image }.flatten
484
+ if docker_image_local.size == 0
485
+ if yes? "Image wasn't found locally, pull image from cnvrg repository?", Thor::Shell::Color::YELLOW
486
+ image = pull(docker_image)
487
+ if image
488
+ say "downloaded image: #{docker_image}"
489
+ @image = Images.new(working_dir, docker_image)
490
+ else
491
+ say "Could not create a new project with docker, image was not found", Thor::Shell::Color::RED
492
+ @project.revert(working_dir)
493
+ exit(1)
494
+ end
495
+ else
496
+ say "Could not create a new project with docker, image was not found", Thor::Shell::Color::RED
497
+ @project.revert(working_dir)
498
+ exit(1)
306
499
 
307
- exit(0)
308
- end
309
- if Project.link(project_name)
310
- path = Dir.pwd
311
- @project = Project.new(path)
312
- @project.generate_idx()
313
- if sync
314
- upload(true)
500
+ end
501
+ elsif docker_image_local.size == 1
502
+ say "found image: #{docker_image_local[0]}, setting it up..", Thor::Shell::Color::BLUE
503
+ @image = Images.new(working_dir, docker_image_local[0])
504
+ elsif docker_image_local.size >1
505
+ say "found #{docker_image_local.size} images, choose the image name you want to use", Thor::Shell::Color::BLUE
506
+ image_name = ask "#{docker_image_local.join("\n")}\n", Thor::Shell::Color::BLUE
507
+ @image = Images.new(working_dir, image_name)
315
508
  end
509
+ end
510
+ if sync
511
+ say "Syncing project", Thor::Shell::Color::BLUE
512
+ upload(true)
513
+ end
316
514
 
317
- url = @project.url
318
- say "#{project_name}'s location is: #{url}\n", Thor::Shell::Color::BLUE
319
- log_end(0)
515
+ url = @project.url
516
+ check = Helpers.checkmark
517
+ say "#{check} Link finished successfully", Thor::Shell::Color::GREEN
518
+ say "#{project_name}'s location is: #{url}\n", Thor::Shell::Color::GREEN
519
+ log_end(0)
520
+
521
+ else
522
+ log_end(1, "can't link project")
523
+ @project.revert(working_dir) unless @project.nil?
524
+ say "Error linking project, please contact support.", Thor::Shell::Color::RED
525
+ exit(0)
526
+ end
527
+ rescue SignalException
528
+ log_end(-1)
529
+
530
+ say "\nAborting"
531
+ exit(1)
532
+ end
533
+ 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
541
+ end
542
+
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
546
+
547
+ def clone(project_url)
548
+ begin
549
+ verify_logged_in(false)
550
+ log_start(__method__, args, options)
551
+ url_parts = project_url.split("/")
552
+ project_index = Cnvrg::Helpers.look_for_in_path(project_url, "projects")
553
+ slug = url_parts[project_index+1]
554
+ 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}")
573
+
574
+ exit(1)
575
+ end
320
576
 
321
- else
322
- log_end(1,"can't link project")
323
- say "Error linking project, please contact support.", Thor::Shell::Color::RED
324
- exit(0)
325
577
  end
326
- rescue SignalException
327
- log_end(-1)
578
+ clone_resp = Project.clone_dir(slug, owner, project_name)
579
+ project_home = Dir.pwd+"/"+project_name
580
+
328
581
 
329
- say "/nAborting"
330
- exit(1)
331
582
  end
332
- end
333
583
 
334
- desc 'clone', 'Clone a project'
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
608
+
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
335
617
 
336
- def clone(project_url)
337
- begin
338
- verify_logged_in(false)
339
- log_start(__method__,args,options)
340
- url_parts = project_url.split("/")
341
- project_index = Cnvrg::Helpers.look_for_in_path(project_url, "projects")
342
- slug = url_parts[project_index+1]
343
- owner = url_parts[project_index-1]
344
- response = Cnvrg::API.request("users/#{owner}/projects/#{slug}/get_project", 'GET')
345
- Cnvrg::CLI.is_response_success(response)
346
- response = JSON.parse response["result"]
347
- project_name = response["title"]
348
- say "Cloning #{project_name}", Thor::Shell::Color::BLUE
349
- if Dir.exists? project_name or File.exists? project_name
350
- log_end(1,"conflict with dir/file #{project_name}")
351
-
352
- say "Error: Conflict with dir/file #{project_name}", Thor::Shell::Color::RED
353
- exit(1)
354
618
  end
355
619
 
356
- if Project.clone_dir(slug, owner, project_name)
357
- project_home = Dir.pwd+"/"+project_name
358
- @project = Project.new(project_home)
359
- @files = Cnvrg::Files.new(@project.owner, slug)
360
- response = @project.clone
361
- Cnvrg::CLI.is_response_success response
362
- idx = {commit: response["result"]["commit"], tree: response["result"]["tree"]}
363
- File.open(project_name + "/.cnvrg/idx.yml", "w+") { |f| f.write idx.to_yaml }
364
- successful_changes = []
365
- say "Downloading files", Thor::Shell::Color::BLUE
620
+ successful_changes = []
621
+ say "Downloading files", Thor::Shell::Color::BLUE
622
+ if !response["result"]["tree"].nil?
366
623
  response["result"]["tree"].each do |f|
367
624
  relative_path = f[0].gsub(/^#{@project.local_path}/, "")
368
625
  if f[0].end_with? "/"
@@ -372,202 +629,226 @@ module Cnvrg
372
629
  end
373
630
  else
374
631
  # blob
375
- if @files.download_file(f[0], relative_path, project_home)
632
+ if @files.download_file_s3(f[0], relative_path, project_home)
376
633
  successful_changes << relative_path
377
634
  end
378
635
  end
379
636
  end
380
- say "Done.\nDownloaded total of #{successful_changes.size} files", Thor::Shell::Color::GREEN
381
- log_end(0)
382
- else
383
- log_end(1,"can't create directory")
384
-
385
- say "Error: Couldn't create directory: #{project_name}", Thor::Shell::Color::RED
386
- exit(1)
387
637
  end
388
- rescue SignalException
389
- log_end(-1)
390
- say "/nAborting"
638
+
639
+ say "Done.\nDownloaded total of #{successful_changes.size} files", Thor::Shell::Color::GREEN
640
+ log_end(0)
641
+ else
642
+ log_end(1, "can't create directory")
643
+
644
+ say "Error: Couldn't create directory: #{project_name}", Thor::Shell::Color::RED
391
645
  exit(1)
392
646
  end
393
-
647
+ rescue SignalException
648
+ log_end(-1)
649
+ say "\nAborting"
650
+ exit(1)
394
651
  end
395
652
 
396
- desc 'status', 'Show the working tree status'
397
- def status
398
- begin
399
- verify_logged_in()
400
- log_start(__method__,args,options)
401
- @project = Project.new(get_project_home)
402
- result = @project.compare_idx["result"]
403
- commit = result["commit"]
404
- result = result["tree"]
405
- say "Comparing local changes with remote version:", Thor::Shell::Color::BLUE
406
- if result["added"].empty? and result["updated_on_local"].empty? and result["updated_on_server"].empty? and result["deleted"].empty? and result["conflicts"].empty?
407
- say "Project is up to date", Thor::Shell::Color::GREEN
408
- log_end(0)
409
- return true
410
- end
411
- if result["added"].size > 0
412
- say "Added files:\n", Thor::Shell::Color::BLUE
413
- result["added"].each do |a|
414
- say "\t\tA:\t#{a}", Thor::Shell::Color::GREEN
415
- end
653
+ end
654
+
655
+
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
661
+ 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
666
+
667
+ result = @project.compare_idx(new_branch)["result"]
668
+ commit = result["commit"]
669
+ result = result["tree"]
670
+ say "Comparing local changes with remote version:", Thor::Shell::Color::BLUE
671
+ 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
+ say "Project is up to date", Thor::Shell::Color::GREEN
673
+ log_end(0)
674
+ return true
675
+ end
676
+ if result["added"].size > 0
677
+ say "Added files:\n", Thor::Shell::Color::BLUE
678
+ result["added"].each do |a|
679
+ say "\t\tA:\t#{a}", Thor::Shell::Color::GREEN
416
680
  end
681
+ end
417
682
 
418
- if result["deleted"].size > 0
419
- say "Deleted files:\n", Thor::Shell::Color::BLUE
420
- result["deleted"].each do |a|
421
- say "\t\tD:\t#{a}", Thor::Shell::Color::GREEN
422
- end
683
+ if result["deleted"].size > 0
684
+ say "Deleted files:\n", Thor::Shell::Color::BLUE
685
+ result["deleted"].each do |a|
686
+ say "\t\tD:\t#{a}", Thor::Shell::Color::GREEN
423
687
  end
424
- if result["updated_on_local"].size > 0
425
- say "Local changes:\n", Thor::Shell::Color::BLUE
426
- result["updated_on_local"].each do |a|
427
- say "\t\tM:\t#{a}", Thor::Shell::Color::GREEN
428
- end
688
+ end
689
+ if result["updated_on_local"].size > 0
690
+ say "Local changes:\n", Thor::Shell::Color::BLUE
691
+ result["updated_on_local"].each do |a|
692
+ say "\t\tM:\t#{a}", Thor::Shell::Color::GREEN
429
693
  end
694
+ end
430
695
 
431
- if result["updated_on_server"].size > 0
432
- say "Remote changes:\n", Thor::Shell::Color::BLUE
433
- result["updated_on_server"].each do |a|
434
- say "\t\tM:\t#{a}", Thor::Shell::Color::GREEN
435
- end
696
+ if result["updated_on_server"].size > 0
697
+ say "Remote changes:\n", Thor::Shell::Color::BLUE
698
+ result["updated_on_server"].each do |a|
699
+ say "\t\tM:\t#{a}", Thor::Shell::Color::GREEN
436
700
  end
701
+ end
437
702
 
438
- if result["conflicts"].size > 0
439
- say "Conflicted changes:\n", Thor::Shell::Color::BLUE
440
- result["conflicts"].each do |a|
441
- say "\t\tC:\t#{a}", Thor::Shell::Color::RED
442
- end
703
+ if result["conflicts"].size > 0
704
+ say "Conflicted changes:\n", Thor::Shell::Color::BLUE
705
+ result["conflicts"].each do |a|
706
+ say "\t\tC:\t#{a}", Thor::Shell::Color::RED
443
707
  end
444
- log_end(0)
445
- rescue SignalException
446
- log_end(-1)
447
- say "/nAborting"
448
- exit(1)
449
708
  end
709
+ log_end(0)
710
+ rescue SignalException
711
+ log_end(-1)
712
+ say "\nAborting"
713
+ exit(1)
450
714
  end
715
+ end
451
716
 
452
717
 
453
- desc 'upload', 'Upload updated files'
454
- method_option :ignore, :type => :array, :aliases => ["-i", "--i"], :desc => "ignore following files"
718
+ 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
455
723
 
456
- def upload(link=false, sync=false)
724
+ def upload(link=false, sync=false)
457
725
 
458
- begin
459
- verify_logged_in()
460
- log_start(__method__,args,options)
726
+ begin
727
+ verify_logged_in(true)
728
+ log_start(__method__, args, options)
461
729
 
462
- @project = Project.new(get_project_home)
730
+ @project = Project.new(get_project_home)
463
731
 
464
- @files = Cnvrg::Files.new(@project.owner, @project.slug)
465
- ignore = options[:ignore] || []
466
- if !@project.update_ignore_list(ignore)
467
- say "Couldn't append new ignore files to .cnvrgignore", Thor::Shell::Color::YELLOW
468
- end
469
- result = @project.compare_idx
470
- commit = result["result"]["commit"]
471
- if !link
472
- if commit != @project.last_local_commit and !@project.last_local_commit.nil? and !result["result"]["tree"]["updated_on_server"].empty?
473
- log_end(0)
732
+ @files = Cnvrg::Files.new(@project.owner, @project.slug)
733
+ ignore = options[:ignore] || []
734
+ if !@project.update_ignore_list(ignore)
735
+ say "Couldn't append new ignore files to .cnvrgignore", Thor::Shell::Color::YELLOW
736
+ end
737
+ new_branch = options["new_branch"] || false
474
738
 
475
- say "Remote server has an updated version, please run `cnvrg download` first, or alternatively: `cnvrg sync`", Thor::Shell::Color::YELLOW
476
- exit(1)
477
- end
478
- say "Comparing local changes with remote version:", Thor::Shell::Color::BLUE
479
- end
480
- result = result["result"]["tree"]
481
- if result["added"].empty? and result["updated_on_local"].empty? and result["deleted"].empty?
739
+ result = @project.compare_idx(new_branch)
740
+ commit = result["result"]["commit"]
741
+ if !link
742
+ if commit != @project.last_local_commit and !@project.last_local_commit.nil? and !result["result"]["tree"]["updated_on_server"].empty?
482
743
  log_end(0)
483
- say "Project is up to date", Thor::Shell::Color::GREEN
484
- return true
744
+
745
+ say "Remote server has an updated version, please run `cnvrg download` first, or alternatively: `cnvrg sync`", Thor::Shell::Color::YELLOW
746
+ exit(1)
485
747
  end
486
- update_count = 0
487
- update_total = result["added"].size + result["updated_on_local"].size + result["deleted"].size
488
- successful_updates = []
489
- successful_deletions = []
748
+
749
+ say "Comparing local changes with remote version:", Thor::Shell::Color::BLUE if options["verbose"]
750
+ end
751
+ result = result["result"]["tree"]
752
+ if result["added"].empty? and result["updated_on_local"].empty? and result["deleted"].empty?
753
+ log_end(0)
754
+ say "Project is up to date", Thor::Shell::Color::GREEN unless options["sync"]
755
+ return true
756
+ end
757
+ update_count = 0
758
+ update_total = result["added"].size + result["updated_on_local"].size + result["deleted"].size
759
+ successful_updates = []
760
+ successful_deletions = []
761
+ if options["verbose"]
490
762
  if update_total == 1
491
763
  say "Updating #{update_total} file", Thor::Shell::Color::BLUE
492
764
  else
493
765
  say "Updating #{update_total} files", Thor::Shell::Color::BLUE
494
766
  end
767
+ else
768
+ say "Syncing files", Thor::Shell::Color::BLUE unless options["sync"]
495
769
 
496
- # Start commit
770
+ end
497
771
 
498
- commit_sha1 = @files.start_commit["result"]["commit_sha1"]
772
+ # Start commit
499
773
 
500
- # upload / update
501
- begin
502
- (result["added"] + result["updated_on_local"]).each do |f|
503
- puts f
504
- absolute_path = "#{@project.local_path}/#{f}"
505
- relative_path = f.gsub(/^#{@project.local_path + "/"}/, "")
506
- if File.directory?(absolute_path)
507
- resDir = @files.create_dir(absolute_path, relative_path, commit_sha1)
508
- if resDir
509
- update_count += 1
510
- successful_updates<< relative_path
511
- end
774
+ commit_sha1 = @files.start_commit(new_branch)["result"]["commit_sha1"]
775
+
776
+ # upload / update
777
+ begin
778
+ (result["added"] + result["updated_on_local"]).each do |f|
779
+ absolute_path = "#{@project.local_path}/#{f}"
780
+ relative_path = f.gsub(/^#{@project.local_path + "/"}/, "")
781
+ if File.directory?(absolute_path)
782
+ resDir = @files.create_dir(absolute_path, relative_path, commit_sha1)
783
+ if resDir
784
+ update_count += 1
785
+ successful_updates<< relative_path
786
+ end
787
+ else
788
+ res = @files.upload_file(absolute_path, relative_path, commit_sha1)
789
+ if res
790
+ update_count += 1
791
+ successful_updates<< relative_path
512
792
  else
513
- res = @files.upload_file(absolute_path, relative_path, commit_sha1)
514
- if res
515
- update_count += 1
516
- successful_updates<< relative_path
517
- else
518
- @files.rollback_commit(commit_sha1)
519
- log_end(1,"can't upload, Rolling Back all changes")
520
- say "Couldn't upload, Rolling Back all changes.", Thor::Shell::Color::RED
521
- exit(0)
522
- end
793
+ @files.rollback_commit(commit_sha1)
794
+ log_end(1, "can't upload, Rolling Back all changes")
795
+ say "Couldn't upload, Rolling Back all changes.", Thor::Shell::Color::RED
796
+ exit(0)
523
797
  end
524
798
  end
799
+ end
525
800
 
526
- # delete
527
- result["deleted"].each do |f|
528
- relative_path = f.gsub(/^#{@project.local_path + "/"}/, "")
529
- if relative_path.end_with?("/")
530
- if @files.delete_dir(f, relative_path, commit_sha1)
531
- update_count += 1
532
- successful_updates<< relative_path
533
- end
534
- else
535
- if @files.delete_file(f, relative_path, commit_sha1)
536
- update_count += 1
537
- successful_updates<< relative_path
538
- end
801
+ # delete
802
+ result["deleted"].each do |f|
803
+ relative_path = f.gsub(/^#{@project.local_path + "/"}/, "")
804
+ if relative_path.end_with?("/")
805
+ if @files.delete_dir(f, relative_path, commit_sha1)
806
+ update_count += 1
807
+ successful_updates<< relative_path
808
+ end
809
+ else
810
+ if @files.delete_file(f, relative_path, commit_sha1)
811
+ update_count += 1
812
+ successful_updates<< relative_path
539
813
  end
540
814
  end
541
- log_end(0)
542
-
543
- rescue SignalException
544
- log_end(-1)
545
- @files.rollback_commit(commit_sha1)
546
- say "User aborted, Rolling Back all changes.", Thor::Shell::Color::RED
547
- exit(0)
548
- rescue => e
549
- log_end(1,e.message)
550
- @files.rollback_commit(commit_sha1)
551
- say "Exception while trying to upload, Rolling back", Thor::Shell::Color::RED
552
- exit(0)
553
815
  end
554
- if update_count == update_total
555
- res = @files.end_commit(commit_sha1)
556
- if (Cnvrg::CLI.is_response_success(res, false))
557
- # save idx
558
- begin
559
- @project.update_idx_with_files_commits!((successful_deletions+successful_updates), res["result"]["commit_time"])
816
+ log_end(0)
560
817
 
561
- @project.update_idx_with_commit!(commit_sha1)
562
- rescue => e
563
- log_end(1,e.message)
564
- @files.rollback_commit(commit_sha1)
565
- say "Couldn't commit updates, Rolling Back all changes.", Thor::Shell::Color::RED
566
- exit(1)
818
+ rescue SignalException
819
+ log_end(-1)
820
+ @files.rollback_commit(commit_sha1)
821
+ say "User aborted, Rolling Back all changes.", Thor::Shell::Color::RED
822
+ exit(0)
823
+ rescue => e
824
+ log_end(1, e.message)
825
+ @files.rollback_commit(commit_sha1)
826
+ say "Exception while trying to upload, Rolling back", Thor::Shell::Color::RED
827
+ exit(0)
828
+ end
829
+ if update_count == update_total
830
+ res = @files.end_commit(commit_sha1)
831
+ if (Cnvrg::CLI.is_response_success(res, false))
832
+ # save idx
833
+ begin
834
+ @project.update_idx_with_files_commits!((successful_deletions+successful_updates), res["result"]["commit_time"])
835
+
836
+ @project.update_idx_with_commit!(commit_sha1)
837
+ rescue => e
838
+ log_end(1, e.message)
839
+ @files.rollback_commit(commit_sha1)
840
+ say "Couldn't commit updates, Rolling Back all changes.", Thor::Shell::Color::RED
841
+ exit(1)
567
842
 
568
- end
843
+ end
844
+ image = is_project_with_docker(Dir.pwd)
845
+ if image and image.is_docker
846
+ image.update_image_activity(commit_sha1, nil)
847
+ end
848
+ check = Helpers.checkmark()
569
849
 
570
- say "Done", Thor::Shell::Color::BLUE
850
+ if options["verbose"]
851
+ say "#{check} Done", Thor::Shell::Color::BLUE
571
852
  if successful_updates.size >0
572
853
  say "Updated:", Thor::Shell::Color::GREEN
573
854
  suc = successful_updates.map { |x| x=Helpers.checkmark() +" "+x }
@@ -579,832 +860,2413 @@ module Cnvrg
579
860
  say del.join("\n"), Thor::Shell::Color::GREEN
580
861
  end
581
862
  say "Total of #{update_count} / #{update_total} files.", Thor::Shell::Color::GREEN
582
- log_end(0)
583
863
  else
584
- @files.rollback_commit(commit_sha1)
585
- log_end(1, "error. Rolling Back all changes")
586
- say "Error. Rolling Back all changes.", Thor::Shell::Color::RED
864
+ say "#{check} Changes were updated successfully", Thor::Shell::Color::GREEN unless options["sync"]
865
+
587
866
  end
588
- else
589
- log_end(1, "error. Rolling Back all changes")
590
867
 
868
+ log_end(0)
869
+ else
591
870
  @files.rollback_commit(commit_sha1)
871
+ log_end(1, "error. Rolling Back all changes")
872
+ say "Error. Rolling Back all changes.", Thor::Shell::Color::RED
592
873
  end
593
- rescue SignalException
594
- log_end(-1)
874
+ else
875
+ log_end(1, "error. Rolling Back all changes")
595
876
 
596
- say "\nAborting",Thor::Shell::Color::BLUE
597
- say "\nRolling back all changes",Thor::Shell::Color::BLUE
598
877
  @files.rollback_commit(commit_sha1)
599
- exit(1)
600
878
  end
879
+ rescue
880
+ log_end(-1)
881
+
882
+ say "Error occurd, \nAborting", Thor::Shell::Color::BLUE
883
+ @files.rollback_commit(commit_sha1)
884
+ exit(1)
885
+ rescue SignalException
886
+ log_end(-1)
601
887
 
888
+ say "\nAborting", Thor::Shell::Color::BLUE
889
+ say "\nRolling back all changes", Thor::Shell::Color::BLUE
890
+ @files.rollback_commit(commit_sha1)
891
+ exit(1)
602
892
  end
603
893
 
604
- desc 'download', 'Download updated files'
894
+ end
605
895
 
606
- def download
607
- begin
608
- verify_logged_in()
609
- log_start(__method__,args,options)
610
- project_home = get_project_home
611
- @project = Project.new(project_home)
612
- @files = Cnvrg::Files.new(@project.owner, @project.slug)
896
+ 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
613
900
 
614
- res = @project.compare_idx["result"]
615
- result = res["tree"]
616
- commit = res["commit"]
617
- if result["updated_on_server"].empty? and result["conflicts"] and result["deleted"].empty?
618
- say "Project is up to date", Thor::Shell::Color::GREEN
619
- log_end(0)
620
- return true
621
- end
622
- update_count = 0
623
- update_total = result["updated_on_server"].size + result["conflicts"].size
901
+ def download
902
+ begin
903
+ verify_logged_in(true)
904
+ log_start(__method__, args, options)
905
+ project_home = get_project_home
906
+ @project = Project.new(project_home)
907
+ @files = Cnvrg::Files.new(@project.owner, @project.slug)
908
+ new_branch = options["new_branch"] || false
909
+
910
+ res = @project.compare_idx(new_branch)["result"]
911
+ result = res["tree"]
912
+ 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"]
915
+ log_end(0)
916
+ return true
917
+ end
918
+ update_count = 0
919
+ update_total = result["updated_on_server"].size + result["conflicts"].size
624
920
 
625
- successful_changes = []
626
- if update_total ==1
627
- say "Downloading #{update_total} file", Thor::Shell::Color::BLUE
628
- else
629
- say "Downloading #{update_total} files", Thor::Shell::Color::BLUE
630
921
 
631
- end
922
+ successful_changes = []
923
+ if update_total ==1
924
+ say "Downloading #{update_total} file", Thor::Shell::Color::BLUE unless options["sync"]
925
+ elsif update_total == 0
926
+ say "Project is up to date", Thor::Shell::Color::GREEN unless options["sync"]
927
+ log_end(0)
928
+ return true
929
+ elsif options["verbose"]
930
+ say "Downloading #{update_total} files", Thor::Shell::Color::BLUE
931
+ else
932
+ say "Syncing files", Thor::Shell::Color::BLUE unless options["sync"]
632
933
 
633
- result["conflicts"].each do |f|
634
- relative_path = f.gsub(/^#{@project.local_path}/, "")
635
- if @files.download_file(f, relative_path, project_home, conflict=true)
636
- successful_changes << relative_path
637
- end
638
934
 
935
+ end
936
+
937
+ result["conflicts"].each do |f|
938
+ relative_path = f.gsub(/^#{@project.local_path}/, "")
939
+ if @files.download_file_s3(f, relative_path, project_home, conflict=true)
940
+ successful_changes << relative_path
639
941
  end
640
- result["updated_on_server"].each do |f|
641
- relative_path = f.gsub(/^#{@project.local_path}/, "")
642
- if f.end_with? "/"
643
- # dir
644
- if @files.download_dir(f, relative_path, project_home)
645
- successful_changes << relative_path
646
942
 
647
- end
648
- else
649
- # blob
650
- if @files.download_file(f, relative_path, project_home)
651
- successful_changes << relative_path
652
- end
653
- end
943
+ end
944
+ result["updated_on_server"].each do |f|
945
+ relative_path = f.gsub(/^#{@project.local_path}/, "")
946
+ if f.end_with? "/"
947
+ # dir
948
+ if @files.download_dir(f, relative_path, project_home)
949
+ successful_changes << relative_path
654
950
 
951
+ end
952
+ else
953
+ # blob
954
+ if @files.download_file_s3(f, relative_path, project_home)
955
+ successful_changes << relative_path
956
+ end
655
957
  end
656
- if update_total == successful_changes.size
657
- # update idx with latest commit
658
- @project.update_idx_with_commit!(commit)
659
958
 
660
- say "Done. Downloaded:", Thor::Shell::Color::GREEN
959
+ end
960
+ if update_total == successful_changes.size
961
+ # update idx with latest commit
962
+ @project.update_idx_with_commit!(commit)
963
+ check = Helpers.checkmark()
964
+
965
+ if options["verbose"]
966
+ say "#{check} Done, Downloaded:", Thor::Shell::Color::GREEN
661
967
  say successful_changes.join("\n"), Thor::Shell::Color::GREEN
662
968
  say "Total of #{successful_changes.size} / #{update_total} files.", Thor::Shell::Color::GREEN
663
- log_end(0)
969
+ else
970
+ say "#{check} Downloaded changes successfully", Thor::Shell::Color::GREEN
664
971
  end
665
- rescue SignalException
666
- log_end(-1)
667
- say "\nAborting", Thor::Shell::Color::BLUE
668
- if successful_changes.nil?
669
- exit(1)
972
+
973
+
974
+ log_end(0)
975
+ end
976
+ rescue SignalException
977
+ log_end(-1)
978
+ say "\nAborting", Thor::Shell::Color::BLUE
979
+ if successful_changes.nil?
980
+ exit(1)
981
+ end
982
+ successful_changes.each do |f|
983
+
984
+ abs_path = "#{@project.local_path}/#{f}"
985
+ filename = File.basename abs_path
986
+ say "revoking #{filename}"
987
+ if result["conflicts"].include? f
988
+ @files.revoke_download_file(abs_path, f, filename, true)
989
+ elsif result["updated_on_server"].include? f
990
+ if File.directory? abs_path
991
+ @files.revoke_download_dir(abs_path, f, project_home)
992
+ else
993
+ @files.revoke_download_file(project_home, abs_path, filename)
994
+ end
670
995
  end
671
- successful_changes.each do |f|
996
+ end
997
+ exit(1)
998
+ end
999
+ end
672
1000
 
673
- abs_path = "#{@project.local_path}/#{f}"
674
- filename = File.basename abs_path
675
- say "revoking #{filename}"
676
- if result["conflicts"].include? f
677
- @files.revoke_download_file(abs_path,f,filename,true)
678
- elsif result["updated_on_server"].include? f
679
- if File.directory? abs_path
680
- @files.revoke_download_dir(abs_path,f,project_home)
681
- else
682
- @files.revoke_download_file(project_home,abs_path,filename)
1001
+
1002
+ desc 'jump', 'jump to specific commit'
1003
+
1004
+ def jump(commit_sha1)
1005
+ begin
1006
+ verify_logged_in()
1007
+ log_start(__method__, args, options)
1008
+ project_home = get_project_home
1009
+ @project = Project.new(project_home)
1010
+ # say "Syncing existing project tree before jumping", Thor::Shell::Color::BLUE
1011
+ current_commit = @project.last_local_commit
1012
+ # if current_commit.eql? commit_sha1
1013
+ # say "Project is Updated", Thor::Shell::Color::GREEN
1014
+ # return
1015
+ # end
1016
+ @files = Cnvrg::Files.new(@project.owner, @project.slug)
1017
+ #
1018
+ # say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE
1019
+ #
1020
+ # download()
1021
+ # upload()
1022
+ # say "Done Syncing", Thor::Shell::Color::BLUE
1023
+
1024
+ response = @project.clone(false, commit_sha1)
1025
+ successful_changes = []
1026
+ if !response["result"]["tree"].nil?
1027
+ idx = {commit: response["result"]["commit"], tree: response["result"]["tree"]}
1028
+ File.open(project_home + "/.cnvrg/idx.yml", "w+") { |f| f.write idx.to_yaml }
1029
+
1030
+ response["result"]["tree"].each do |f|
1031
+ relative_path = f[0].gsub(/^#{@project.local_path}/, "")
1032
+ if f[0].end_with? "/"
1033
+ # dir
1034
+ if @files.download_dir(f[0], relative_path, project_home)
1035
+ current_tree.delete(relative_path[0, relative_path.size-1])
1036
+ successful_changes << relative_path
1037
+ end
1038
+ else
1039
+ # blob
1040
+ if @files.download_file_s3(f[0], relative_path, project_home)
1041
+ current_tree.delete(relative_path)
1042
+
1043
+ successful_changes << relative_path
683
1044
  end
684
1045
  end
685
1046
  end
686
- exit(1)
687
1047
  end
1048
+ FileUtils.rm_rf(current_tree)
1049
+ say "Done. Jumped completed successfully", Thor::Shell::Color::GREEN
1050
+ log_end(0)
1051
+ rescue SignalException
1052
+ log_end(-1)
1053
+ exi(1)
688
1054
  end
1055
+ end
689
1056
 
690
1057
 
691
- desc 'sync', 'Sync with remote server'
692
-
693
- def sync
694
- say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE
695
- invoke :download
696
- invoke :upload
697
- end
698
-
699
- # desc 'random', 'random'
700
- # def random
701
- # say "Fun trivia game for taking a recess :-)", Thor::Shell::Color::BLUE
702
- # subject = ask("Pick a subject\n1.NBA\n2.American History\n3.Data Science\n")
703
- # file = "ds.txt"
704
- # case subject
705
- # when "1"
706
- # file = "nba.txt"
707
- # when "2"
708
- # file = "ah.txt"
709
- # when "3"
710
- # file = "ds.txt"
711
- # end
712
- # line = File.readlines(file).sample
713
- # q = line[0,line.index('?')+1]
714
- # a = line[line.index('?')+1,line.size]
715
- # answer = ask(q+"/n")
716
- #
717
- #
718
- #
719
- # end
720
- # Run
721
- #
722
- desc 'exec CMD', 'Execute a process'
723
- method_option :sync_before, :type => :boolean, :aliases => ["-sb", "--sb"], :default => true
724
- method_option :sync_after, :type => :boolean, :aliases => ["-sa", "--sa"], :default => true
725
- method_option :title, :type => :string, :aliases => ["-t", "--t"], :default => ""
726
- method_option :log, :type => :boolean, :aliases => ["-l", "--l"], :default => false
727
- method_option :email_notification, :type => :boolean, :aliases => ["-en", "--en"], :default => false
728
- method_option :upload_output, :type => :string, :aliases => ["--uo", "-uo"], :default => ""
729
-
730
- def exec(*cmd)
731
- # LogJob.perform_async(cmd,options)
732
- #
733
- log = []
734
- cpu_average =0
735
- memory_average = 0
736
- verify_logged_in()
737
- log_start(__method__,args,options)
738
- project_home = get_project_home
739
- @project = Project.new(project_home)
740
- sync_before = options["sync_before"]
741
- sync_after = options["sync_after"]
742
- print_log = options["log"]
743
- title = options["title"]
744
- email_notification = options["email_notification"]
745
- upload_output = options["upload_output"]
746
- time_to_upload = calc_output_time(upload_output)
1058
+ 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
747
1061
 
748
- begin
749
- if sync_before
750
- # Sync before run
751
- say "Syncing project before running", Thor::Shell::Color::BLUE
752
- say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE
1062
+ def sync
1063
+ if options["verbose"]
1064
+ say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE
1065
+ else
1066
+ say 'Syncing project', Thor::Shell::Color::BLUE
1067
+ end
753
1068
 
754
- download()
755
- upload()
756
- say "Done Syncing", Thor::Shell::Color::BLUE
757
- end
758
1069
 
759
- start_commit = @project.last_local_commit
760
- cmd = cmd.join("\s")
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()
761
1073
 
762
- say "Running: #{cmd}\n", Thor::Shell::Color::BLUE
1074
+ say "#{check} Syncing project completed successfully", Thor::Shell::Color::GREEN
763
1075
 
764
- @exp = Experiment.new(@project.owner, @project.slug)
1076
+ end
765
1077
 
766
- platform = RUBY_PLATFORM
767
- machine_name = Socket.gethostname
768
- begin
769
1078
 
770
- @exp.start(cmd, platform, machine_name, start_commit, title, email_notification)
771
- unless @exp.slug.nil?
772
- real = Time.now
773
- exp_success = true
774
- memory_total = []
775
- cpu_total = []
776
- start_loop = Time.now
777
- begin
778
- PTY.spawn(cmd) do |stdout, stdin, pid, stderr|
779
- begin
780
- stdout.each do |line|
781
- cur_time = Time.now
782
- monitor = %x{ps aux|awk '{print $2,$3,$4}'|grep #{pid} }
783
- monitor_by = monitor.split(" ")
784
- memory = monitor_by[2]
785
- cpu = monitor_by[1]
786
- memory_total << memory.to_f
787
- cpu_total << cpu.to_f
788
- real_time= Time.now-real
789
-
790
- cur_log = {time: cur_time,
791
- message: line,
792
- type: "stdout",
793
- real: real_time}
794
- if print_log
795
- puts cur_log
796
- end
797
- log << cur_log
1079
+ 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
1084
+ 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 => ""
1089
+ 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 => ""
1095
+
1096
+ def run(*cmd)
1097
+ sync_before = options["sync_before"]
1098
+ sync_after = options["sync_after"]
1099
+ log = options["log"]
1100
+ title = options["title"]
1101
+ commit = options["commit"] || nil
1102
+ email_notification = options["email_notification"]
1103
+ upload_output = options["upload_output"]
1104
+ local = options["local"]
1105
+ schedule = options["schedule"]
1106
+ image = options["image"]
1107
+ if local
1108
+ 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
1110
+ return
1111
+ else
1112
+ instances = {"small" => options["small"], "medium" => options["medium"], "large" => options["large"], "gpu" => options["gpu"], "gpuxl" => options["gpuxl"]}
1113
+ instance_type = get_instance_type(instances)
1114
+ 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
1116
+ return
1117
+ end
1118
+ end
1119
+
798
1120
 
799
- begin
800
- if time_to_upload !=0
801
- if time_to_upload <= Time.now - start_loop
802
- #upload current log
803
- cpu_average = cpu_total.inject(0) { |sum, el| sum + el }.to_f / cpu_total.size
804
- memory_average = memory_total.inject(0) { |sum, el| sum + el }.to_f / memory_total.size
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
+
1132
+ def exec(*cmd)
1133
+ log = []
1134
+ cpu_average =0
1135
+ memory_average = 0
1136
+ verify_logged_in(true)
1137
+ log_start(__method__, args, options)
1138
+ working_dir = Dir.pwd
1139
+
1140
+
1141
+ sync_before = options["sync_before"]
1142
+ sync_after = options["sync_after"]
1143
+ print_log = options["log"]
1144
+ title = options["title"]
1145
+ commit = options["commit"] || nil
1146
+ image = options["image"] || nil
1147
+ indocker = options["indocker"] || false
1148
+
1149
+ email_notification = options["email_notification"]
1150
+ upload_output = options["upload_output"]
1151
+ time_to_upload = calc_output_time(upload_output)
1152
+ project_home = get_project_home
1153
+ @project = Project.new(project_home)
1154
+
1155
+ is_new_branch = @project.compare_commit(commit)
1156
+ begin
1157
+ if !commit.nil? and !commit.empty?
1158
+ invoke :jump, [commit], []
1159
+ else
1160
+ if sync_before
1161
+ # Sync before run
1162
+ invoke :sync, [], :new_branch => is_new_branch
1163
+ end
1164
+ end
1165
+ #set image for the project
1166
+ if !image.nil? and !image.empty?
1167
+ invoke :set_image, [image]
1168
+ end
1169
+ if !indocker
1170
+ image_proj = is_project_with_docker(working_dir)
805
1171
 
806
- @exp.upload_temp_log(log, cpu_average, memory_average)
807
- log = []
808
- start_loop = Time.now
809
- end
810
1172
 
811
- end
812
- rescue
813
- say "Failed to upload ongoing results, continuing with experiment", Thor::Shell::Color::YELLOW
814
- end
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
815
1179
 
816
- end
817
1180
 
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)
1190
+ end
1191
+ end
1192
+ start_commit = @project.last_local_commit
1193
+ cmd = cmd.join("\s")
1194
+
1195
+ say "Running: #{cmd}\n", Thor::Shell::Color::BLUE
818
1196
 
819
- if stderr
1197
+ @exp = Experiment.new(@project.owner, @project.slug)
820
1198
 
821
- stderr.each do |err|
1199
+ platform = RUBY_PLATFORM
1200
+ machine_name = Socket.gethostname
1201
+ begin
1202
+ machine_activity = @exp.get_machine_activity(Dir.pwd)
1203
+ @exp.start(cmd, platform, machine_name, start_commit, title, email_notification, machine_activity)
1204
+ unless @exp.slug.nil?
1205
+ real = Time.now
1206
+ exp_success = true
1207
+ memory_total = []
1208
+ cpu_total = []
1209
+ start_loop = Time.now
1210
+ begin
1211
+ PTY.spawn(cmd) do |stdout, stdin, pid, stderr|
1212
+ begin
1213
+ stdout.each do |line|
1214
+ 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]
1219
+ memory_total << memory.to_f
1220
+ cpu_total << cpu.to_f
1221
+ real_time= Time.now-real
1222
+
1223
+ cur_log = {time: cur_time,
1224
+ message: line,
1225
+ type: "stdout",
1226
+ real: real_time}
1227
+ if print_log
1228
+ puts cur_log
1229
+ end
1230
+ log << cur_log
1231
+
1232
+ begin
1233
+ if time_to_upload !=0
1234
+ if time_to_upload <= Time.now - start_loop
1235
+ #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
1238
+
1239
+ @exp.upload_temp_log(log, cpu_average, memory_average)
1240
+ log = []
1241
+ start_loop = Time.now
1242
+ end
822
1243
 
823
- log << {time: Time.now, message: err, type: "stderr"}
824
1244
  end
1245
+ rescue
1246
+ say "Failed to upload ongoing results, continuing with experiment", Thor::Shell::Color::YELLOW
825
1247
  end
826
1248
 
827
- rescue Errno::EIO => e
828
- break
829
- rescue Errno::ENOENT
830
- log_end(1, "command #{cmd} isn't valid")
1249
+ end
1250
+
831
1251
 
832
- exp_success = false
1252
+ if stderr
833
1253
 
834
- say "command \"#{cmd}\" couldn't be executed, verify command is valid", Thor::Shell::Color::RED
835
- rescue PTY::ChildExited
836
- log_end(1, "proccess exited")
837
- exp_success = false
838
- say "The process exited!", Thor::Shell::Color::RED
839
- rescue => e
840
- log_end(1,e.message)
841
- end
842
- ::Process.wait pid
843
- cpu_average = cpu_total.inject(0) { |sum, el| sum + el }.to_f / cpu_total.size
844
- memory_average = memory_total.inject(0) { |sum, el| sum + el }.to_f / memory_total.size
845
- exit_status = $?.exitstatus
846
- if $?.exitstatus != 0
847
- exp_success = false
1254
+ stderr.each do |err|
1255
+
1256
+ log << {time: Time.now, message: err, type: "stderr"}
1257
+ end
848
1258
  end
849
- if !exp_success
850
- if !Cnvrg::Helpers.internet_connection?
851
- wait_offline = agree "Seems like you're offline, wait until your'e back online?",limited_to: ['y', 'n'], default: 'n'
852
- if wait_offline
853
- say "Waiting until your'e online..", Thor::Shell::Color::BLUE
854
- while !Cnvrg::Helpers.internet_connection?
855
- end
856
- exit_status = 0
857
- else
858
- say "Experiment has failed, your'e computer is offline", Thor::Shell::Color::RED
859
- log_end(1,"experiment has failed,computer is offline")
860
- exit(0)
1259
+
1260
+ rescue Errno::EIO => e
1261
+ puts e
1262
+ # break
1263
+ rescue Errno::ENOENT
1264
+ log_end(1, "command #{cmd} isn't valid")
1265
+
1266
+ exp_success = false
1267
+
1268
+ say "command \"#{cmd}\" couldn't be executed, verify command is valid", Thor::Shell::Color::RED
1269
+ rescue PTY::ChildExited
1270
+ log_end(1, "proccess exited")
1271
+ exp_success = false
1272
+ say "The process exited!", Thor::Shell::Color::RED
1273
+ rescue => e
1274
+ puts e
1275
+ log_end(1, e.message)
1276
+ end
1277
+ ::Process.wait pid
1278
+ cpu_average = cpu_total.inject(0) { |sum, el| sum + el }.to_f / cpu_total.size
1279
+ memory_average = memory_total.inject(0) { |sum, el| sum + el }.to_f / memory_total.size
1280
+ exit_status = $?.exitstatus
1281
+ if $?.exitstatus != 0
1282
+ exp_success = false
1283
+ end
1284
+ if !exp_success
1285
+ if !Cnvrg::Helpers.internet_connection?
1286
+ wait_offline = agree "Seems like you're offline, wait until your'e back online?", Thor::Shell::Color::YELLOW
1287
+ if wait_offline
1288
+ say "Waiting until your'e online..", Thor::Shell::Color::BLUE
1289
+ while !Cnvrg::Helpers.internet_connection?
861
1290
  end
1291
+ exit_status = 0
862
1292
  else
1293
+ say "Experiment has failed, your'e computer is offline", Thor::Shell::Color::RED
1294
+ log_end(1, "experiment has failed,computer is offline")
1295
+ exit(0)
1296
+ end
1297
+ else
863
1298
 
864
1299
  end_commit = @project.last_local_commit
865
1300
  res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
866
1301
  say "Experiment has failed, look at the log for more details or run cnvrg exec --log", Thor::Shell::Color::RED
867
- log_end(1,"experiment has failed")
1302
+ log_end(1, "experiment has failed")
868
1303
  exit(0)
869
- end
870
-
871
- end
872
- if sync_after
873
- say "Syncing project after running", Thor::Shell::Color::BLUE
874
- # Sync after run
875
- download()
876
- upload()
877
- say "Done Syncing", Thor::Shell::Color::BLUE
878
1304
  end
879
- end_commit = @project.last_local_commit
880
1305
 
881
- res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
882
- check = Helpers.checkmark()
883
- say "#{check} Done. Experiment's result: #{Cnvrg::Helpers.remote_url}/#{@project.owner}/projects/#{@project.slug}/experiments/#{@exp.slug}", Thor::Shell::Color::GREEN
884
- log_end(0)
885
1306
  end
886
- rescue =>e
887
- log_end(1,e.message)
888
- say "Couldn't run #{cmd}, check your input parameters", Thor::Shell::Color::RED
889
- exit(1)
890
- end
1307
+ if sync_after
1308
+ # Sync after run
1309
+ if !commit.nil?
1310
+ invoke :sync, [], :new_branch => true
891
1311
 
1312
+ else
1313
+ invoke :sync, [], :new_branch => true
1314
+ end
1315
+ end
1316
+ end_commit = @project.last_local_commit
892
1317
 
1318
+ res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
1319
+ 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
1321
+ log_end(0)
1322
+ end
1323
+ rescue => e
1324
+ puts e
1325
+ log_end(1, e.message)
1326
+ if container
1327
+ container.stop()
1328
+ end
1329
+ say "Couldn't run #{cmd}, check your input parameters", Thor::Shell::Color::RED
1330
+ exit(1)
893
1331
  end
894
1332
 
1333
+
895
1334
  end
896
- rescue SignalException
897
- exit_status = -1
898
- log_end(-1)
899
- end_commit = @project.last_local_commit
900
1335
 
901
- res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
902
- say "\nAborting"
1336
+ end
1337
+ rescue SignalException
1338
+ exit_status = -1
1339
+ log_end(-1)
1340
+ end_commit = @project.last_local_commit
903
1341
 
904
- exit(1)
1342
+ res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
1343
+ if container
1344
+ container.stop()
905
1345
  end
1346
+ say "\nAborting"
1347
+
1348
+ exit(1)
906
1349
  end
1350
+ end
1351
+
1352
+ desc '', ''
1353
+ method_option :sync_before, :type => :boolean, :aliases => ["-sb", "--sb"], :default => true
1354
+ method_option :sync_after, :type => :boolean, :aliases => ["-sa", "--sa"], :default => true
1355
+ method_option :title, :type => :string, :aliases => ["-t", "--t"], :default => ""
1356
+ method_option :log, :type => :boolean, :aliases => ["-l", "--l"], :default => false
1357
+ method_option :email_notification, :type => :boolean, :aliases => ["-en", "--en"], :default => false
1358
+ method_option :upload_output, :type => :string, :aliases => ["--uo", "-uo"], :default => ""
1359
+
1360
+ def exec_docker(*cmd)
1361
+ log = []
1362
+ cpu_average =0
1363
+ memory_average = 0
1364
+ verify_logged_in()
1365
+ log_start(__method__, args, options)
1366
+ project_home = "/home/ds/notebooks"
1367
+ @project = Project.new(project_home)
1368
+ sync_before = options["sync_before"]
1369
+ sync_after = options["sync_after"]
1370
+ print_log = options["log"]
1371
+ title = options["title"]
1372
+ email_notification = options["email_notification"]
1373
+ upload_output = options["upload_output"]
1374
+ time_to_upload = calc_output_time(upload_output)
1375
+ @image = is_project_with_docker(project_home)
907
1376
 
908
- desc 'run_notebook', 'Starts a new notebook environment'
909
- method_option :notebook_dir, :type => :string, :aliases => ["-n", "--n"], :default => "", :desc => "relative path to notebook dir from current directory"
910
- method_option :docker, :type => :boolean, :aliases => ["-d", "--d"], :default => true
911
- method_option :image_name, :type => :string, :aliases => ["-i", "--i"], :default => ""
912
1377
 
913
- def run_notebook
1378
+ begin
1379
+ start_commit = @project.last_local_commit
1380
+ cmd = cmd.join("\s")
1381
+
1382
+ say "Running: #{cmd}\n", Thor::Shell::Color::BLUE
914
1383
 
1384
+ @exp = Experiment.new(@project.owner, @project.slug)
1385
+ machine_activity = @exp.get_machine_activity(project_home)
1386
+
1387
+ platform = RUBY_PLATFORM
1388
+ machine_name = Socket.gethostname
915
1389
  begin
916
- verify_logged_in(false)
917
- log_start(__method__,args,options)
918
- cur_path = Dir.pwd
919
- notebook_dir = options["notebook_dir"]
920
- if notebook_dir.empty?
921
- notebook_dir = cur_path
922
- else
923
- notebook_dir = cur_path+ notebook_dir
924
- end
925
- say "Linking notebook directory to: #{notebook_dir}", Thor::Shell::Color::BLUE
926
- docker = options["docker"]
927
- try_again = true
928
1390
 
1391
+ @exp.start(cmd, platform, machine_name, start_commit, title, email_notification, machine_activity)
1392
+ unless @exp.slug.nil?
1393
+ real = Time.now
1394
+ exp_success = true
1395
+ memory_total = []
1396
+ cpu_total = []
1397
+ start_loop = Time.now
1398
+ begin
1399
+ PTY.spawn(cmd) do |stdout, stdin, pid, stderr|
1400
+ begin
1401
+ stdout.each do |line|
1402
+ cur_time = Time.now
1403
+ monitor = %x{ps aux|awk '{print $2,$3,$4}'|grep #{pid} }
1404
+ monitor_by = monitor.split(" ")
1405
+ memory = monitor_by[2]
1406
+ cpu = monitor_by[1]
1407
+ memory_total << memory.to_f
1408
+ cpu_total << cpu.to_f
1409
+ real_time= Time.now-real
1410
+
1411
+ cur_log = {time: cur_time,
1412
+ message: line,
1413
+ type: "stdout",
1414
+ real: real_time}
1415
+ if print_log
1416
+ puts cur_log
1417
+ end
1418
+ log << cur_log
1419
+
1420
+ begin
1421
+ if time_to_upload !=0
1422
+ if time_to_upload <= Time.now - start_loop
1423
+ #upload current log
1424
+ cpu_average = cpu_total.inject(0) { |sum, el| sum + el }.to_f / cpu_total.size
1425
+ memory_average = memory_total.inject(0) { |sum, el| sum + el }.to_f / memory_total.size
1426
+
1427
+ @exp.upload_temp_log(log, cpu_average, memory_average)
1428
+ log = []
1429
+ start_loop = Time.now
1430
+ end
929
1431
 
930
- if docker
931
- docker_path = verify_software_installed("docker")
932
- image_name = options["image_name"]
933
- if image_name.empty?
934
- images_list = `#{docker_path} images`
935
- if images_list.empty? or images_list.nil?
936
- say "you don't have any images to run", Thor::Shell::Color::BLUE
937
- else
938
- say "Choose image name to run as a container\n", Thor::Shell::Color::BLUE
939
- say images_list
940
- image_name = ask("\nwhat is the image name?\n")
941
- end
1432
+ end
1433
+ rescue
1434
+ say "Failed to upload ongoing results, continuing with experiment", Thor::Shell::Color::YELLOW
1435
+ end
1436
+
1437
+ end
942
1438
 
943
- end
944
- while (try_again) do
945
- run_docker = `#{docker_path} run -d -p 8888:8888 -v #{notebook_dir}:/home/ds/notebooks -t -i #{image_name} 2>&1`
946
- if !run_docker.match(/[a-z0-9]{64}/).nil? and !run_docker.include? "Error"
947
- container_id = get_container_id()
948
- sleep(3)
949
- logs = `docker logs #{container_id}`
950
- url = URI.extract(logs).reject { |x| x if !x.include? "http" }.uniq![0]
951
- if !url.empty?
952
- check = Helpers.checkmark()
953
-
954
- say "#{check} Notebook server started successfully, view notebook in url: #{url}", Thor::Shell::Color::GREEN
955
- try_again= false
956
- else
957
- say "Couldn't start notebook server", Thor::Shell::Color::RED
958
- log_end(1, "can't start notebook server")
959
- exit(1)
960
- end
961
1439
 
962
- elsif run_docker.include? "port is already allocated"
963
- say "Couldn't start notebook with port 8888, port is taken", Thor::Shell::Color::RED
964
- port_container = `#{docker_path} ps |grep 8888 |awk '{print $1}'`.strip!
965
- stop = agree "There is another running notebook server: #{port_container}, do you want to stop it?", limited_to: ['y', 'n'], default: 'y'
966
- if stop == "y"
967
- did_stop = system("#{docker_path} stop #{port_container}")
968
- if !did_stop
969
- say "Couldn't stop notebook server: #{port_container}", Thor::Shell::Color::RED
970
- log_end(1,"can't stop notebook server")
971
- exit(1)
1440
+ if stderr
972
1441
 
1442
+ stderr.each do |err|
1443
+
1444
+ log << {time: Time.now, message: err, type: "stderr"}
1445
+ end
973
1446
  end
974
- else
975
- logs = `#{docker_path} logs #{port_container}`
976
- url = URI.extract(logs).reject { |x| x if !x.include? "http" }.uniq![0]
977
- say "Done, your notebook server is: #{url}", Thor::Shell::Color::BLUE
978
- log_end(0)
979
- exit(1)
1447
+
1448
+ rescue Errno::EIO => e
1449
+ break
1450
+ rescue Errno::ENOENT
1451
+ log_end(1, "command #{cmd} isn't valid")
1452
+
1453
+ exp_success = false
1454
+
1455
+ say "command \"#{cmd}\" couldn't be executed, verify command is valid", Thor::Shell::Color::RED
1456
+ rescue PTY::ChildExited
1457
+ log_end(1, "proccess exited")
1458
+ exp_success = false
1459
+ say "The process exited!", Thor::Shell::Color::RED
1460
+ rescue => e
1461
+ log_end(1, e.message)
980
1462
  end
981
- else
982
- log_end(1, "can;t start notebook server")
983
- say "Couldn't start notebook server", Thor::Shell::Color::RED
984
- exit(1)
1463
+ ::Process.wait pid
1464
+ cpu_average = cpu_total.inject(0) { |sum, el| sum + el }.to_f / cpu_total.size
1465
+ memory_average = memory_total.inject(0) { |sum, el| sum + el }.to_f / memory_total.size
1466
+ exit_status = $?.exitstatus
1467
+ if $?.exitstatus != 0
1468
+ exp_success = false
1469
+ end
1470
+ if !exp_success
1471
+ if !Cnvrg::Helpers.internet_connection?
1472
+ wait_offline = agree "Seems like you're offline, wait until your'e back online?", Thor::Shell::Color::YELLOW
1473
+ if wait_offline
1474
+ say "Waiting until your'e online..", Thor::Shell::Color::BLUE
1475
+ while !Cnvrg::Helpers.internet_connection?
1476
+ end
1477
+ exit_status = 0
1478
+ else
1479
+ say "Experiment has failed, your'e computer is offline", Thor::Shell::Color::RED
1480
+ log_end(1, "experiment has failed,computer is offline")
1481
+ exit(0)
1482
+ end
1483
+ else
1484
+
1485
+ end_commit = @project.last_local_commit
1486
+ res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
1487
+ @image.update_image_activity(@project.last_local_commit, @exp.slug)
1488
+ say "Experiment has failed, look at the log for more details or run cnvrg exec --log", Thor::Shell::Color::RED
1489
+ log_end(1, "experiment has failed")
1490
+ exit(0)
1491
+ end
1492
+
1493
+ end
1494
+ if sync_after
1495
+ say "Syncing project after running", Thor::Shell::Color::BLUE
1496
+ # Sync after run
1497
+ download()
1498
+ upload()
1499
+ say "Done Syncing", Thor::Shell::Color::BLUE
1500
+ end
1501
+ end_commit = @project.last_local_commit
985
1502
 
1503
+ res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
1504
+ @image.update_image_activity(@project.last_local_commit, @exp.slug)
1505
+
1506
+ check = Helpers.checkmark()
1507
+ say "#{check} Done. Experiment's result: #{Cnvrg::Helpers.remote_url}/#{@project.owner}/projects/#{@project.slug}/experiments/#{@exp.slug}", Thor::Shell::Color::GREEN
1508
+ log_end(0)
986
1509
  end
987
- end
988
- else
989
- jup =verify_software_installed("jupyter-notebook")
990
- logs = `#{jup} --no-browser --ip=0.0.0.0 --notebook-dir=#{notebook_dir}`
991
- url = URI.extract(logs).reject { |x| x if !x.include? "http" }.uniq![0]
992
- if !url.empty?
993
- check = Helpers.checkmark()
994
-
995
- say "#{check} Notebook server started successfully, view notebook in url: #{url}", Thor::Shell::Color::GREEN
996
- log_end(0)
997
- else
998
- say "Couldn't start notebook server", Thor::Shell::Color::RED
999
- log_end(1,"can't start notebook server")
1510
+ rescue => e
1511
+ log_end(1, e.message)
1512
+ say "Couldn't run #{cmd}, check your input parameters", Thor::Shell::Color::RED
1000
1513
  exit(1)
1001
1514
  end
1002
1515
 
1516
+
1003
1517
  end
1004
- rescue SignalException
1005
- log_end(-1)
1006
- say "Aborting"
1007
- exit(1)
1518
+
1519
+ end
1520
+ rescue SignalException
1521
+ exit_status = -1
1522
+ log_end(-1)
1523
+ end_commit = @project.last_local_commit
1524
+ if !@exp.nil?
1525
+
1526
+ res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
1008
1527
  end
1009
1528
 
1529
+ say "\nAborting"
1010
1530
 
1531
+ exit(1)
1011
1532
  end
1533
+ end
1012
1534
 
1013
- desc 'install_notebook_libraries', 'Starts a new notebook environment'
1014
- method_option :commit_name, :type => :string, :aliases => ["-c", "--c"], :default => "", :desc => "commit changes to notebook server when finished"
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 => ""
1546
+
1547
+ def exec_remote(*cmd)
1548
+ verify_logged_in(true)
1549
+ log_start(__method__, args, options)
1550
+ working_dir = is_cnvrg_dir
1551
+ begin
1015
1552
 
1016
- def install_notebook_libraries
1017
- begin
1018
- verify_logged_in(false)
1019
- log_start(__method__,args,options)
1020
- docker_path = verify_software_installed("docker")
1021
- container_id = get_container_id
1022
- say "Opening shell in notebook server\nYou can run pip install [library] to install more tools\ntype exit to finish", Thor::Shell::Color::BLUE
1023
- system("#{docker_path} exec -it #{container_id} bash")
1024
- commit_name = options["commit_name"]
1025
- if !commit_name.empty?
1026
- return commit_notebook(commit_name)
1553
+ instance_type = options["machine_type"] || nil
1554
+ schedule = options["schedule"] || ""
1555
+ if schedule.start_with? 'in'
1556
+ time = schedule.split(" ")
1557
+
1558
+ local = Time.now.localtime
1559
+ if time[2].downcase().start_with? "min"
1560
+ new = local + (time[1].to_i * 60)
1561
+ elsif time[2].downcase().start_with? "hours"
1562
+ new = local + (time[1].to_i * 3600)
1563
+ elsif time[2].downcase().start_with? "days"
1564
+ new = local + (time[1].to_i * 3600 * 24)
1565
+ else
1566
+ say "Could not undersatnd when to schedule experiment", Thor::Shell::Color::RED
1567
+ exit(1)
1027
1568
  end
1028
- rescue SignalException
1029
- log_End(-1)
1030
- say "/nAborting"
1031
- exit(1)
1569
+ new_time = new.to_s
1570
+ new_time = new_time[0, new_time.size-6] #remove timezone
1571
+ schedule = "at #{new_time}"
1572
+ end
1573
+ options_hash = Hash[options]
1574
+ options_hash.except!("schedule", "machine_type", "image")
1575
+ exec_options = options_hash.map { |x| "--#{x[0]}=#{x[1]}" }.flatten.join(" ")
1576
+ command = "#{exec_options} --uo=1m #{cmd.flatten.join(" ")}"
1577
+ commit_to_run = options["commit"] || nil
1578
+ if !schedule.nil? and !schedule.empty?
1579
+
1580
+ local_timestamp = get_schedule_date
1581
+
1582
+ end
1583
+ project = Project.new(working_dir)
1584
+ choose_image = options["image"]
1585
+
1586
+ if !choose_image.nil? and !choose_image.empty?
1587
+ invoke :set_image,[choose_image]
1588
+ end
1589
+ image = is_project_with_docker(working_dir)
1590
+ if !image or !image.is_docker
1591
+ # say "Couldn't find image related to project", Thor::Shell::Color::RED
1592
+ default_image_name = "cnvrg"
1593
+ if instance_type.eql? "gpu" or instance_type.eql? "gpuxl"
1594
+ default_image_name = "cnvrg-gpu"
1595
+ end
1596
+ # default = yes? "use #{default_image_name} default image?", Thor::Shell::Color::YELLOW
1597
+ # if default
1598
+ image = Images.new(working_dir, default_image_name)
1599
+ image_slug = image.image_slug
1600
+ # else
1601
+ # exit(0)
1602
+ # end
1603
+ else
1604
+ image_slug = image.image_slug
1605
+ end
1606
+
1607
+
1608
+
1609
+ invoke :sync, [], []
1610
+
1611
+ say "Running remote experiment", Thor::Shell::Color::BLUE
1612
+ exp = Experiment.new(project.owner, project.slug)
1613
+
1614
+ res = exp.exec_remote(command, commit_to_run, instance_type, image_slug, schedule, local_timestamp)
1615
+ if Cnvrg::CLI.is_response_success(res)
1616
+
1617
+ # if res["result"]["machine"] == -1
1618
+ # say "There are no available machines", Thor::Shell::Color::BLUE
1619
+ # create = yes? "create new machine?", Thor::Shell::Color::YELLOW
1620
+ # if create
1621
+ # res = Cnvrg::API.request("users/#{image.owner}/machines/list", 'GET')
1622
+ # if Cnvrg::CLI.is_response_success(res)
1623
+ # instance_type = machine_options(res["result"]["aws_options"])
1624
+ # if @image.new_machine(instance_type)
1625
+ # say "Running remote experiment", Thor::Shell::Color::BLUE
1626
+ #
1627
+ # # res = image.exec_remote(exec_args, exec_options, project.last_local_commit)
1628
+ # # if Cnvrg::CLI.is_response_success(res)
1629
+ #
1630
+ # check = Helpers.checkmark()
1631
+ # say "#{check} Finished successfuly", Thor::Shell::Color::GREEN
1632
+ # exit(0)
1633
+ # # end
1634
+ # end
1635
+ # else
1636
+ # say "No machines are avilable", Thor::Shell::Color::RED
1637
+ # exit(0)
1638
+ # end
1639
+ #
1640
+ #
1641
+ # else
1642
+ # say "Can't execute command on remote machine with local image", Thor::Shell::Color::RED
1643
+ # exit(1)
1644
+ #
1645
+ # end
1646
+ # else
1647
+ 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
1649
+
1650
+ exit(0)
1651
+ # end
1032
1652
  end
1033
1653
 
1654
+
1655
+ rescue SignalException
1656
+ exit_status = -1
1657
+ log_end(-1)
1658
+ end_commit = project.last_local_commit
1659
+
1660
+ res = @exp.end(log, exit_status, end_commit, "", "")
1661
+ say "\nAborting"
1662
+
1663
+ exit(1)
1664
+ end
1665
+ end
1666
+
1667
+ 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 => ""
1671
+
1672
+ def deploy(file_to_run, function)
1673
+ verify_logged_in(true)
1674
+ log_start(__method__, args, options)
1675
+ working_dir = is_cnvrg_dir
1676
+ begin
1677
+
1678
+ instance_type = options["machine_type"] || nil
1679
+ schedule = options["schedule"] || ""
1680
+
1681
+
1682
+
1683
+ if !schedule.nil? and !schedule.empty?
1684
+
1685
+ local_timestamp = get_schedule_date
1686
+
1687
+ end
1688
+ project = Project.new(working_dir)
1689
+ commit_to_run = options["commit"] || nil
1690
+
1691
+
1692
+ image = is_project_with_docker(working_dir)
1693
+ 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
1702
+ else
1703
+ image_slug = image.image_slug
1704
+ end
1705
+
1706
+
1707
+
1708
+ invoke :sync, [], []
1709
+
1710
+ res = project.deploy(file_to_run, function, nil, commit_to_run, instance_type, image_slug, schedule, local_timestamp)
1711
+
1712
+ if Cnvrg::CLI.is_response_success(res)
1713
+
1714
+ # if res["result"]["machine"] == -1
1715
+ # say "There are no available machines", Thor::Shell::Color::BLUE
1716
+ # create = yes? "create new machine?", Thor::Shell::Color::YELLOW
1717
+ # if create
1718
+ # res = Cnvrg::API.request("users/#{image.owner}/machines/list", 'GET')
1719
+ # if Cnvrg::CLI.is_response_success(res)
1720
+ # instance_type = machine_options(res["result"]["aws_options"])
1721
+ # if @image.new_machine(instance_type)
1722
+ # say "Running remote experiment", Thor::Shell::Color::BLUE
1723
+ #
1724
+ # # res = image.exec_remote(exec_args, exec_options, project.last_local_commit)
1725
+ # # if Cnvrg::CLI.is_response_success(res)
1726
+ #
1727
+ # check = Helpers.checkmark()
1728
+ # say "#{check} Finished successfuly", Thor::Shell::Color::GREEN
1729
+ # exit(0)
1730
+ # # end
1731
+ # end
1732
+ # else
1733
+ # say "No machines are avilable", Thor::Shell::Color::RED
1734
+ # exit(0)
1735
+ # end
1736
+ #
1737
+ #
1738
+ # else
1739
+ # say "Can't execute command on remote machine with local image", Thor::Shell::Color::RED
1740
+ # exit(1)
1741
+ #
1742
+ # end
1743
+ # else
1744
+ check = Helpers.checkmark()
1745
+ say "#{check} Deployment process is on: #{Cnvrg::Helpers.remote_url}/#{project.owner}/projects/#{project.slug}/deploys/show/#{res["result"]["deploy_slug"]}", Thor::Shell::Color::GREEN
1746
+
1747
+ exit(0)
1748
+ # end
1749
+ end
1750
+
1751
+
1752
+ rescue SignalException
1753
+ exit_status = -1
1754
+ log_end(-1)
1755
+ end_commit = project.last_local_commit
1756
+
1757
+ res = @exp.end(log, exit_status, end_commit, "", "")
1758
+ say "\nAborting"
1759
+
1760
+ exit(1)
1761
+ end
1762
+ end
1763
+
1764
+ method_option :kernel, :type => :string, :aliases => ["--k", "-k"], :default => ""
1765
+ 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
1770
+ 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'
1773
+
1774
+ def notebook()
1775
+ local = options["local"]
1776
+ notebook_dir = options["notebook_dir"]
1777
+ kernel = options["kernel"]
1778
+
1779
+ if local
1780
+ invoke :run_notebook, [], :notebook_dir => notebook_dir, :remote => false, :kernel => kernel
1781
+ return
1782
+ else
1783
+ instances = {"small" => options["small"], "medium" => options["medium"], "large" => options["large"], "gpu" => options["gpu"], "gpuxl" => options["gpuxl"]}
1784
+ instance_type = get_instance_type(instances)
1785
+
1786
+ invoke :remote_notebook, [], :notebook_dir => notebook_dir, :kernel => kernel, :machine_type => instance_type
1787
+ return
1788
+
1789
+ end
1790
+
1791
+
1792
+ end
1793
+
1794
+ 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 => ""
1799
+
1800
+
1801
+ def remote_notebook()
1802
+ verify_logged_in(true)
1803
+ log_start(__method__, args, options)
1804
+ verify_software_installed("docker")
1805
+
1806
+ working_dir = is_cnvrg_dir()
1807
+ notebook_dir = options["notebook_dir"]
1808
+ instance_type = options["machine_type"] || nil
1809
+ kernel = options["kernel"] || nil
1810
+
1811
+
1812
+ begin
1813
+ choose_image = options["image"]
1814
+
1815
+ if !choose_image.nil? and !choose_image.empty?
1816
+ invoke :set_image,[choose_image]
1817
+ end
1818
+ @image = is_project_with_docker(working_dir)
1819
+ if !@image or !@image.is_docker
1820
+ # say "Couldn't find image related to project", Thor::Shell::Color::RED
1821
+ default_image_name = "cnvrg"
1822
+ if instance_type.eql? "gpu" or instance_type.eql? "gpuxl"
1823
+ default_image_name = "cnvrg-gpu"
1824
+ end
1825
+ # default = yes? "use #{default_image_name} default image?", Thor::Shell::Color::YELLOW
1826
+ # if default
1827
+ @image = Images.new(working_dir, default_image_name)
1828
+ # else
1829
+ # exit(0)
1830
+ # end
1831
+ end
1832
+
1833
+ invoke :sync, [], []
1834
+
1835
+
1836
+
1837
+ res = @image.remote_notebook(notebook_dir, instance_type, kernel)
1838
+ if Cnvrg::CLI.is_response_success(res)
1839
+ if res["result"]["machine"] == -1
1840
+ say "There are no available machines", Thor::Shell::Color::BLUE
1841
+ create = yes? "create new machine?", Thor::Shell::Color::YELLOW
1842
+ if create
1843
+ res = Cnvrg::API.request("users/#{@image.owner}/machines/list", 'GET')
1844
+ if Cnvrg::CLI.is_response_success(res)
1845
+ instance_type = machine_options(res["result"]["aws_options"])
1846
+ if @image.new_machine(instance_type)
1847
+ res = @image.remote_notebook(notebook_dir, instance_type, kernel)
1848
+ if Cnvrg::CLI.is_response_success(res)
1849
+ url = res["result"]["url"]
1850
+ if !url.nil? and !url.empty?
1851
+ check = Helpers.checkmark()
1852
+
1853
+ say "#{check} Notebook server started successfully", Thor::Shell::Color::GREEN
1854
+ Launchy.open(url)
1855
+ else
1856
+ say "Couldn't run notebook server", Thor::Shell::Color::RED
1857
+ end
1858
+ exit(0)
1859
+ end
1860
+ end
1861
+ else
1862
+ say "No machines are avilable", Thor::Shell::Color::RED
1863
+ exit(0)
1864
+ end
1865
+
1866
+
1867
+ else
1868
+ say "Can't execute command on remote machine with local image", Thor::Shell::Color::RED
1869
+ exit(1)
1870
+
1871
+ end
1872
+ else
1873
+ note_url = res["result"]["notebook_url"]
1874
+ @image.set_note_url(note_url)
1875
+ 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
1877
+ # Launchy.open(url)
1878
+
1879
+ exit(0)
1880
+ end
1881
+ end
1882
+
1883
+
1884
+ rescue SignalException
1885
+ exit_status = -1
1886
+ log_end(-1)
1887
+ end_commit = @project.last_local_commit
1888
+
1889
+ res = @exp.end(log, exit_status, end_commit, cpu_average, memory_average)
1890
+ say "\nAborting"
1891
+
1892
+ exit(1)
1893
+ end
1894
+ end
1895
+
1896
+ desc 'search_libraries', 'search if libraries installed'
1897
+
1898
+ def search_libraries(library)
1899
+ begin
1900
+ verify_logged_in(true)
1901
+ log_start(__method__, args, options)
1902
+ verify_software_installed("docker")
1903
+ project_dir = is_cnvrg_dir()
1904
+
1905
+ image = is_project_with_docker(project_dir)
1906
+ if image and image.is_docker
1907
+ container= image.get_container
1908
+ if !container
1909
+ say "Couldn't create container with image #{image.image_name}:#{image.image_tag}", Thor::Shell::Color::RED
1910
+ exit(1)
1911
+ end
1912
+ else
1913
+ say "Project is not configured with any image", Thor::Shell::Color::RED
1914
+ exit(1)
1915
+
1916
+ end
1917
+
1918
+ say "Searching for #{library}", Thor::Shell::Color::BLUE
1919
+ pip_arr = image.get_installed_packages("python")
1920
+ pip_arr = pip_arr.map(&:downcase)
1921
+ check = Helpers.checkmark()
1922
+ if !(p = pip_arr.map { |x| x.split("==")[0] }.index(library.downcase)).nil?
1923
+
1924
+ say "#{check} Found it!", Thor::Shell::Color::GREEN
1925
+
1926
+
1927
+ printf "%-40s %-30s\n", "#{pip_arr[p].split("==")[0]}", "#{pip_arr[p].split("==")[1]}"
1928
+
1929
+ else
1930
+ dpkg_arr = image.get_installed_packages("system")
1931
+ dpkg_arr = dpkg_arr.map(&:downcase)
1932
+ if !(p = dpkg_arr.map { |x| x.split("==")[0] }.index(library.downcase)).nil?
1933
+ say "#{check} Found!", Thor::Shell::Color::GREEN
1934
+
1935
+ printf "%-40s %-30s\n", "#{dpkg_arr[p].split("==")[0]}", "#{dpkg_arr[p].split("==")[1]}"
1936
+ else
1937
+ say "Couldn't find #{library}, run cnvrg install_libraries to install", Thor::Shell::Color::RED
1938
+ exit(1)
1939
+ end
1940
+
1941
+
1942
+ end
1943
+ rescue => e
1944
+ puts e
1945
+ log_end(-1)
1946
+ say "Error occurd, Aborting"
1947
+ if container
1948
+ container.stop()
1949
+ end
1950
+ rescue SignalException
1951
+ log_end(-1)
1952
+ if container
1953
+ container.stop()
1954
+ end
1955
+ say "Aborting"
1956
+ exit(1)
1957
+ end
1958
+ end
1959
+
1960
+ desc 'show_libraries', 'show system libraries installed'
1961
+ method_option :system, :type => :boolean, :aliases => ["-s", "--s"], :default => false, :desc => "show also system libraries installed"
1962
+
1963
+ def show_libraries
1964
+ begin
1965
+ verify_logged_in(true)
1966
+ log_start(__method__, args, options)
1967
+ verify_software_installed("docker")
1968
+ system = options["system"] || false
1969
+
1970
+
1971
+ project_dir = is_cnvrg_dir()
1972
+
1973
+ image = is_project_with_docker(project_dir)
1974
+ if image and image.is_docker
1975
+ container = image.get_container
1976
+ if !container
1977
+ say "Couldn't create container with image #{image.image_name}:#{image.image_tag}", Thor::Shell::Color::RED
1978
+ exit(1)
1979
+ end
1980
+ else
1981
+ say "Project is not configured with any image", Thor::Shell::Color::RED
1982
+ exit(1)
1983
+
1984
+ end
1985
+
1986
+ say "Showing python installed libraries", Thor::Shell::Color::BLUE
1987
+ pip_arr = image.get_installed_packages("python")
1988
+ printf "%-40s %-30s\n", "name", "version"
1989
+ printf "%-40s %-30s\n", "====", "======="
1990
+
1991
+ pip_arr.each do |p|
1992
+
1993
+ printf "%-40s %-30s\n", "#{p.split("==")[0]}", "#{p.split("==")[1]}"
1994
+ end
1995
+ if system
1996
+
1997
+ say "Showing system installed libraries", Thor::Shell::Color::BLUE
1998
+ dpkg_arr = image.get_installed_packages("system")
1999
+ printf "%-40s %-30s\n", "name", "version"
2000
+ printf "%-40s %-30s\n", "====", "======="
2001
+ dpkg_arr.each do |p|
2002
+ printf "%-40s %-30s\n", "#{p.split("==")[0]}", "#{p.split("==")[1]}"
2003
+
2004
+ end
2005
+ end
2006
+ rescue => e
2007
+ puts e
2008
+ log_end(-1)
2009
+ say "Error occurd, Aborting"
2010
+ if container
2011
+ container.stop()
2012
+ end
2013
+ rescue SignalException
2014
+ log_end(-1)
2015
+ say "Aborting"
2016
+ exit(1)
2017
+ end
2018
+ end
2019
+
2020
+
2021
+ desc 'run_notebook', 'Starts a new notebook environment'
2022
+ method_option :notebook_dir, :type => :string, :aliases => ["-n", "--n"], :default => "", :desc => "relative path to notebook dir from current directory"
2023
+ method_option :remote, :type => :boolean, :aliases => ["-r", "--r"], :default => false, :desc => "run on remote machine"
2024
+ method_option :kernel, :type => :string, :aliases => ["-k", "--k"], :default => "", :desc => "default kernel"
2025
+ method_option :verbose, :type => :boolean, :aliases => ["--v"], :default => false
2026
+
2027
+ def run_notebook
2028
+
2029
+ begin
2030
+ verify_logged_in(true)
2031
+ log_start(__method__, args, options)
2032
+ verify_software_installed("docker")
2033
+
2034
+ project_dir = is_cnvrg_dir()
2035
+
2036
+ notebook_dir = options["notebook_dir"]
2037
+ remote = options["remote"] || false
2038
+ kernel = options["kernel"] || ""
2039
+
2040
+
2041
+ if notebook_dir.empty?
2042
+ notebook_dir = project_dir
2043
+ else
2044
+
2045
+ notebook_dir = project_dir+ notebook_dir
2046
+ 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
2052
+
2053
+ say "Couldn't create container with image #{image.image_name}:#{image.image_tag}", Thor::Shell::Color::RED
2054
+ exit(1)
2055
+ end
2056
+ else
2057
+ say "Project is not configured with any image", Thor::Shell::Color::RED
2058
+ exit(1)
2059
+
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
+
2067
+ start_commit = @project.last_local_commit
2068
+
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
+ end
2075
+
2076
+ 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
+
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()
2087
+
2088
+ @note = Experiment.new(@project.owner, @project.slug)
2089
+ port = image.container_port()
2090
+
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
2098
+
2099
+ url = list[list.size-1].split(" ::")
2100
+ token = url[0][(url[0].index("=")+1)..-1]
2101
+
2102
+ # machine_activity = @note.get_machine_activity(project_dir)
2103
+
2104
+
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}"
2108
+
2109
+
2110
+ if !note_url.empty?
2111
+ check = Helpers.checkmark()
2112
+
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)
2119
+ end
2120
+
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
2134
+ rescue => e
2135
+ log_end(-1)
2136
+ puts e
2137
+ say "Error occurd, aborting", Thor::Shell::Color::RED
2138
+ if container
2139
+ container.stop()
2140
+ end
2141
+ rescue SignalException
2142
+ log_end(-1)
2143
+ if container
2144
+ container.stop()
2145
+ end
2146
+ say "Aborting"
2147
+ exit(1)
2148
+ end
2149
+
2150
+
2151
+ end
2152
+
2153
+ desc 'notebook_stop', 'Starts a new notebook environment'
2154
+ method_option :notebook_dir, :type => :string, :aliases => ["-n", "--n"], :default => "", :desc => "relative path to notebook dir from current directory"
2155
+ method_option :remote, :type => :boolean, :aliases => ["-r", "--r"], :default => false, :desc => "run on remote machine"
2156
+ method_option :verbose, :type => :boolean, :aliases => ["--v"], :default => false
2157
+
2158
+ def notebook_stop
2159
+ begin
2160
+ verify_logged_in(true)
2161
+ log_start(__method__, args, options)
2162
+ verify_software_installed("docker")
2163
+ remote = options["remote"] || false
2164
+ project_dir = is_cnvrg_dir()
2165
+
2166
+
2167
+ say 'Checking for new updates from remote version', Thor::Shell::Color::BLUE if options["verbose"]
2168
+ invoke :sync, [], :verbose => options["verbose"]
2169
+
2170
+ say "Done Syncing", Thor::Shell::Color::BLUE if options["verbose"]
2171
+
2172
+
2173
+ @project = Project.new(project_dir)
2174
+
2175
+ end_commit = @project.last_local_commit
2176
+
2177
+ @note = Experiment.new(@project.owner, @project.slug)
2178
+
2179
+ slug = get_note_url(project_dir)
2180
+ @note.end_notebook_session(slug, end_commit)
2181
+
2182
+
2183
+ image = is_project_with_docker(Dir.pwd)
2184
+ if image and image.is_docker and !remote
2185
+ container = image.get_container(true)
2186
+ if !container
2187
+ check = Helpers.checkmark()
2188
+
2189
+ say "#{check} Notebook server stopped successfully", Thor::Shell::Color::GREEN
2190
+ exit(0)
2191
+ end
2192
+
2193
+
2194
+ say "Stopping notebook server...", Thor::Shell::Color::BLUE
2195
+
2196
+ check = Helpers.checkmark()
2197
+ image.remove_note_slug()
2198
+ container.stop()
2199
+
2200
+ say "#{check} Notebook server stopped successfully", Thor::Shell::Color::GREEN
2201
+ log_end(0)
2202
+
2203
+ exit(0)
2204
+ elsif remote
2205
+ say "Stopping notebook server...", Thor::Shell::Color::BLUE
2206
+ check = Helpers.checkmark()
2207
+
2208
+ say "#{check} Notebook server stopped successfully", Thor::Shell::Color::GREEN
2209
+ log_end(0)
2210
+ exit(0)
2211
+ end
2212
+ rescue => e
2213
+ puts e
2214
+ log_end(-1)
2215
+ say "Error occurd, aborting"
2216
+ if container
2217
+ container.stop()
2218
+ end
2219
+ rescue SignalException
2220
+ log_end(-1)
2221
+ say "Aborting"
2222
+ exit(1)
2223
+ end
2224
+
2225
+
2226
+ end
2227
+
2228
+
2229
+ desc 'install_system_libraries', 'Install libraries'
2230
+
2231
+ def install_system_libraries(*command_to_run)
2232
+ begin
2233
+ verify_logged_in(false)
2234
+ log_start(__method__, args, options)
2235
+ verify_software_installed("docker")
2236
+ image = is_project_with_docker(Dir.pwd)
2237
+ if image and image.is_docker
2238
+ container = image.get_container
2239
+ if !container
2240
+
2241
+ say "Couldn't create container with image #{image.image_name}:#{image.image_tag}", Thor::Shell::Color::RED
2242
+ exit(1)
2243
+ end
2244
+ else
2245
+ say "Project is not configured with any image", Thor::Shell::Color::RED
2246
+ exit(1)
2247
+
2248
+ end
2249
+
2250
+ command_to_run = command_to_run.join(" ")
2251
+ say "Running #{command_to_run} in container", Thor::Shell::Color::BLUE
2252
+ command = ["/bin/bash", "-lc", "#{command_to_run}"]
2253
+ res = container.exec(command, tty: false)
2254
+ say res[0].join("\n")
2255
+ checks = Helpers.checkmark()
2256
+ say "Updating image", Thor::Shell::Color::BLUE
2257
+
2258
+ image.create_custom_image("")
2259
+ say "#{checks} Done, installing libraries completed", Thor::Shell::Color::GREEN
2260
+ container.stop()
2261
+
2262
+ log_end(0)
2263
+ rescue => e
2264
+ log_end(-1)
2265
+ puts e
2266
+ say "Error occurd, aborting"
2267
+ if container
2268
+ container.stop()
2269
+ end
2270
+ rescue SignalException
2271
+ log_End(-1)
2272
+ if container
2273
+ container.stop()
2274
+ end
2275
+ say "\nAborting"
2276
+ exit(1)
2277
+ end
2278
+
2279
+ end
2280
+
2281
+ desc 'install_libraries', 'Install libraries'
2282
+ method_option :requirement, :type => :string, :aliases => ["-r", "--r"], :default => "", :desc => "Install from the given requirements file"
2283
+
2284
+ def install_python_libraries(*lib)
2285
+ begin
2286
+ verify_logged_in(false)
2287
+ log_start(__method__, args, options)
2288
+ verify_software_installed("docker")
2289
+ image = is_project_with_docker(Dir.pwd)
2290
+ if image and image.is_docker
2291
+ container = image.get_container
2292
+ if !container
2293
+
2294
+ say "Couldn't create container with image #{image.image_name}:#{image.image_tag}", Thor::Shell::Color::RED
2295
+ exit(1)
2296
+ end
2297
+ else
2298
+ say "Project is not configured with any image", Thor::Shell::Color::RED
2299
+ exit(1)
2300
+
2301
+ end
2302
+ req_file = options["requirement"] || nil
2303
+ if lib.nil? and not req_file.nil?
2304
+ if not File.exist? req_file
2305
+ say "Couldn't find #{req_file}", Thor::Shell::Color::RED
2306
+ exit(1)
2307
+
2308
+ end
2309
+ command_to_run = "pip install -r #{req_file}"
2310
+
2311
+ else
2312
+ command_to_run = lib.join(" ")
2313
+
2314
+ end
2315
+ say "Running #{command_to_run} in container", Thor::Shell::Color::BLUE
2316
+ command = ["/bin/bash", "-lc", "#{command_to_run}"]
2317
+ res = container.exec(command, tty: false)
2318
+ say res[0].join("\n")
2319
+ checks = Helpers.checkmark()
2320
+ say "Updating image", Thor::Shell::Color::BLUE
2321
+
2322
+ image.create_custom_image("")
2323
+ say "#{checks} Done, installing libraries completed", Thor::Shell::Color::GREEN
2324
+ container.stop()
2325
+
2326
+ log_end(0)
2327
+ rescue => e
2328
+ log_end(-1)
2329
+ puts e
2330
+ say "Error occurd, aborting"
2331
+ if container
2332
+ container.stop()
2333
+ end
2334
+ rescue SignalException
2335
+ log_End(-1)
2336
+ if container
2337
+ container.stop()
2338
+ end
2339
+ say "\nAborting"
2340
+ exit(1)
2341
+ end
2342
+
2343
+ end
2344
+ desc 'run commands inside containers', 'run commands inside containers'
2345
+ method_option :install, :type => :string, :aliases => ["--i"], :default => nil, :desc => "Install from the given instructions file"
2346
+
2347
+ def build(*cmd)
2348
+ begin
2349
+ verify_logged_in(false)
2350
+ log_start(__method__, args, options)
2351
+ verify_software_installed("docker")
2352
+ working_dir = is_cnvrg_dir
2353
+ install_file = options["install"] || nil
2354
+ if !install_file.nil?
2355
+ commands = File.open(install_file).read.chop.gsub!("\n",",").split(",")
2356
+
2357
+ else
2358
+ commands = [cmd.join(" ")]
2359
+ end
2360
+
2361
+
2362
+ image = is_project_with_docker(working_dir)
2363
+ if image and image.is_docker
2364
+ container = image.get_container
2365
+ if !container
2366
+
2367
+ say "Couldn't create container with image #{image.image_name}:#{image.image_tag}", Thor::Shell::Color::RED
2368
+ exit(1)
2369
+ end
2370
+ else
2371
+ say "Project is not configured with any image", Thor::Shell::Color::RED
2372
+ exit(1)
2373
+
2374
+ end
2375
+ 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
2382
+
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)
2390
+
2391
+ exit(1)
2392
+ end
2393
+ say res[0].join("\n")
2394
+ image.store_image_build_commands(working_dir,c)
2395
+ end
2396
+
2397
+ checks = Helpers.checkmark()
2398
+ say "Updating image", Thor::Shell::Color::BLUE
2399
+ # image.create_custom_image("",working_dir)
2400
+ container.stop()
2401
+ say "#{checks} Done", Thor::Shell::Color::GREEN
2402
+
2403
+ log_end(0)
2404
+ rescue => e
2405
+ log_end(-1)
2406
+ puts e
2407
+ say "Error occurd, aborting", Thor::Shell::Color::RED
2408
+ if container
2409
+ container.stop()
2410
+ end
2411
+ rescue SignalException
2412
+ log_End(-1)
2413
+ if container
2414
+ container.stop()
2415
+ end
2416
+ say "\nAborting"
2417
+ exit(1)
2418
+ end
2419
+
2420
+ end
2421
+
2422
+ desc 'commit_notebook', 'commit notebook changes to create a new notebook image'
2423
+
2424
+ def commit_image
2425
+ verify_logged_in(true)
2426
+ log_start(__method__, args, options)
2427
+ verify_software_installed("docker")
2428
+
2429
+ begin
2430
+ image = is_project_with_docker(Dir.pwd)
2431
+ if image and image.is_docker
2432
+ container= image.get_container
2433
+ if !container
2434
+
2435
+ say "Couldn't create container with image #{image.image_name}:#{image.image_tag}", Thor::Shell::Color::RED
2436
+ exit(1)
2437
+ end
2438
+ else
2439
+ say "Project is not configured with any image", Thor::Shell::Color::RED
2440
+ exit(1)
2441
+
2442
+ end
2443
+ project_home = get_project_home
2444
+ @project = Project.new(project_home)
2445
+ last_local_commit = @project.last_local_commit
2446
+ say "Commiting container into image", Thor::Shell::Color::BLUE
2447
+ new_image_name = "#{@project.slug}#{last_local_commit}:latest"
2448
+ image.update_image(new_image_name, container)
2449
+ new_image = container.commit('repo' => "#{@project.slug}#{last_local_commit}", 'tag' => "lastest")
2450
+ checks = Helpers.checkmark()
2451
+ say "#{checks} Done, image was updated", Thor::Shell::Color::GREEN
2452
+ log_end(0)
2453
+ return new_image.id
2454
+ rescue => e
2455
+ puts e
2456
+
2457
+ rescue SignalException
2458
+ log_end(-1)
2459
+ say "\nAborting"
2460
+ exit(1)
2461
+ end
2462
+ end
2463
+
2464
+ desc 'sync_image', 'sync current container into image, and push it to cnvrg repository'
2465
+ method_option :is_public, :type => :boolean, :aliases => ["-p", "--p"], :default => false, :desc => "is public"
2466
+ method_option :is_base, :type => :boolean, :aliases => ["-b", "--b"], :default => false, :desc => "is base for others images"
2467
+ method_option :message, :type => :string, :aliases => ["-m", "--m"], :default => "", :desc => "commit message for this image"
2468
+
2469
+ def sync_image(docker=false)
2470
+ verify_logged_in(true)
2471
+ log_start(__method__, args, options)
2472
+ verify_software_installed("docker")
2473
+ is_public = options["is_public"] || false
2474
+ is_base = options["is_base"] || false
2475
+ message = options["message"] || ""
2476
+ image_id = commit_image
2477
+
2478
+ if docker
2479
+ message = "before running experiment"
2480
+ image = is_project_with_docker(Dir.pwd)
2481
+ if image and image.is_docker
2482
+ container = image.get_container
2483
+ if !container
2484
+
2485
+ upload_image(image_id, is_public, is_base, message)
2486
+ else
2487
+ command = ["/bin/bash", "-lc", "cnvrg upload_image #{image_id} #{is_public} #{is_base} #{message}"]
2488
+ puts "Running in contianer"
2489
+ container.exec(command, detach: false)
2490
+ end
2491
+ end
2492
+
2493
+ else
2494
+ upload_image(image_id, is_public, is_base, message)
2495
+ end
2496
+
2497
+ end
2498
+
2499
+ desc 'push image to cnvrg repository', 'push image to cnvrg repository'
2500
+
2501
+ def push(*name)
2502
+ verify_logged_in(true)
2503
+ log_start(__method__, args, options)
2504
+ working_dir = is_cnvrg_dir()
2505
+ if !name.empty? and name == "cnvrg"
2506
+ say "can't create image with the name cnvrg", Thor::Shell::Color::RED
2507
+ exit(1)
2508
+ end
2509
+ begin
2510
+ image = is_project_with_docker(working_dir)
2511
+ if !image or !image.is_docker
2512
+ say "Couldn't find image related to project", Thor::Shell::Color::RED
2513
+ exit(0)
2514
+ end
2515
+ if !name.nil? and !name.empty?
2516
+ if name.include? " "
2517
+ name.gsub!(" ","_")
2518
+ end
2519
+ end
2520
+ stored_commands = File.open(working_dir+"/.cnvrg/custom_image.txt").read.chop.gsub("\n",",")
2521
+ if stored_commands.nil? or stored_commands.empty?
2522
+ say "Nothing to push", Thor::Shell::Color::BLUE
2523
+ exit(0)
2524
+ end
2525
+
2526
+ say "Pushing new image", Thor::Shell::Color::BLUE
2527
+ if image.create_custom_image(name,working_dir,stored_commands)
2528
+
2529
+ say "Image was updated successfully", Thor::Shell::Color::GREEN
2530
+ end
2531
+ rescue => e
2532
+ puts e
2533
+ end
2534
+ end
2535
+
2536
+
2537
+ desc 'upload_image', 'commit notebook changes to create a new notebook image'
2538
+
2539
+ def upload_image(image_id, is_public, is_base, *message)
2540
+ verify_logged_in(true)
2541
+ log_start(__method__, args, options)
2542
+ verify_software_installed("docker")
2543
+ image = Docker::Image.get(image_id)
2544
+ project_home = get_project_home
2545
+ @project = Project.new(project_home)
2546
+ last_local_commit = @project.last_local_commit
2547
+ image_name = @project.slug+"#{last_local_commit}"
2548
+ path = File.expand_path('~')+"/.cnvrg/tmp/#{image_name}.tar"
2549
+ owner = Cnvrg::CLI.get_owner()
2550
+ if !message.nil? or !message.empty?
2551
+ message = message.join(" ")
2552
+ end
2553
+
2554
+ say "Saving image's current state", Thor::Shell::Color::BLUE
2555
+ image.save(path)
2556
+
2557
+ begin
2558
+ say "Compressing image file to upload", Thor::Shell::Color::BLUE
2559
+ gzipRes = system("gzip -f #{path}")
2560
+ if !gzipRes
2561
+ log_End(1, "can't create gz file from image")
2562
+
2563
+ say "Couldn't create tar file from image", Thor::Shell::Color::RED
2564
+ exit(1)
2565
+ end
2566
+ path = path+".gz"
2567
+ @files = Cnvrg::Files.new(owner, "")
2568
+
2569
+ exit_status = $?.exitstatus
2570
+ if exit_status == 0
2571
+ say "Uploading image file", Thor::Shell::Color::BLUE
2572
+
2573
+ diff =container_changes(Dir.pwd)
2574
+ res = @files.upload_image(path, image_name, owner, is_public, is_base, diff[1], diff[0], diff[2], message, image.commit_id)
2575
+ if res
2576
+ File.delete(path)
2577
+ image_loc = is_project_with_docker(Dir.pwd)
2578
+ image_loc.update_slug(res["result"]["id"])
2579
+
2580
+ checks = Helpers.checkmark()
2581
+ say "#{checks} Done", Thor::Shell::Color::GREEN
2582
+ log_end(0)
2583
+ else
2584
+ say "Couldn't upload image", Thor::Shell::Color::RED
2585
+ log_end(1, "can't create upload imag")
2586
+
2587
+ end
2588
+ else
2589
+ say "Couldn't create image file for: #{image_name}", Thor::Shell::Color::RED
2590
+ log_end(1, "can't create upload imag")
2591
+ exit(1)
2592
+ end
2593
+ rescue => e
2594
+ puts e
2595
+
2596
+ rescue SignalException
2597
+ log_end(-1)
2598
+
2599
+ say "Couldn't upload image file for: #{image_name}", Thor::Shell::Color::RED
2600
+ exit(1)
2601
+ end
2602
+ end
2603
+
2604
+ desc '', ''
2605
+
2606
+ def upload_log()
2607
+ log_path = '/home/ds/app/uwsgi.log'
2608
+ loglines = File.new(log_path).readlines
2609
+ logs = loglines.select { |x| x.start_with? "cnvrg_app:" }.collect { |x| x.strip }
2610
+
2611
+ end
2612
+
2613
+ desc '', ''
2614
+
2615
+ def exec_container(container_id, *cmd)
2616
+ container = Docker::Container.get(container_id)
2617
+ container.start()
2618
+ cnvrg_command = cmd.join(" ")
2619
+ command = ["/bin/bash", "-lc", "#{cnvrg_command}"]
2620
+ res = container.exec(command, tty: true,wait:5400)[0]
2621
+ say res
2622
+
2623
+ end
2624
+
2625
+ desc '', ''
2626
+
2627
+ def port_container(container_id)
2628
+ container = Docker::Container.get(container_id)
2629
+ say container.json["HostConfig"]["PortBindings"]["8888/tcp"][0]["HostPort"]
2630
+
2631
+
2632
+ end
2633
+
2634
+ desc '', ''
2635
+
2636
+ def stop_container(container_id)
2637
+ container = Docker::Container.get(container_id)
2638
+ container.stop()
2639
+ container.remove()
2640
+
2641
+ end
2642
+
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"
2647
+
2648
+
2649
+ def config_remote(image_name, port=7654)
2650
+ local_images = Docker::Image.all
2651
+
2652
+ docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.eql? "#{image_name}:latest" }.flatten
2653
+ if docker_image_local.empty?
2654
+ say "no image"
2655
+ exit(1)
2656
+ end
2657
+
2658
+ begin
2659
+ login_content = options["login"]
2660
+ app_dir = options["app_dir"]
2661
+ cmd= options["cmd"]
2662
+
2663
+ image_settings = {
2664
+ 'Image' => "#{image_name}:latest",
2665
+ 'User' => 'ds',
2666
+ 'Cmd' => cmd,
2667
+ 'WorkingDir' => app_dir,
2668
+ 'ExposedPorts' => {
2669
+ '8888/tcp' => {},
2670
+ },
2671
+ 'HostConfig' => {
2672
+ 'PortBindings' => {
2673
+ '8888/tcp' => [
2674
+ {'HostPort' => "#{port}", 'HostIp' => 'localhost'}
2675
+ ],
2676
+ },
2677
+ },
2678
+ }
2679
+ container = Docker::Container.create(image_settings)
2680
+ container.start()
2681
+ command = ["/bin/bash", "-lc", "sudo echo -e \"#{login_content}\" >/home/ds/.netrc"]
2682
+ container.exec(command, tty: true)
2683
+ command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg"]
2684
+ container.exec(command, tty: true)
2685
+ command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg/tmp"]
2686
+ container.exec(command, tty: true)
2687
+ command = ["/bin/bash", "-lc", "sudo chown -R ds /home/ds/.cnvrg /home/ds/.netrc"]
2688
+ container.exec(command, tty: true)
2689
+ command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
2690
+ container.exec(command, tty: true)
2691
+ say "#{container.id}:#{port}"
2692
+ rescue => e
2693
+ if e.message.include? "is not running"
2694
+ return config_remote(image_name, port-1)
2695
+ end
2696
+ puts "error"
2697
+ puts e
2698
+ if container
2699
+ container.kill()
2700
+ end
2701
+ return false
2702
+ end
2703
+ end
2704
+
2705
+ desc '', ''
2706
+ method_option :login, :type => :string, :aliases => ["-l", "--l"], :default => ""
2707
+
2708
+ def config_flask_remote(image_name, port=80)
2709
+ local_images = Docker::Image.all
2710
+
2711
+ docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.eql? "#{image_name}:latest" }.flatten
2712
+ if docker_image_local.empty?
2713
+ say "no image"
2714
+ exit(1)
2715
+ end
2716
+
2717
+ begin
2718
+ login_content = options["login"]
2719
+ image_settings = {
2720
+ 'Image' => "#{image_name}:latest",
2721
+ 'User' => 'ds',
2722
+ 'Cmd' => '/usr/local/cnvrg/start_super.sh',
2723
+ 'WorkingDir' => '/home/ds/app',
2724
+ 'ExposedPorts' => {
2725
+ '80/tcp' => {},
2726
+ },
2727
+ 'HostConfig' => {
2728
+ 'PortBindings' => {
2729
+ '80/tcp' => [
2730
+ {'HostPort' => "#{port}", 'HostIp' => 'localhost'}
2731
+ ],
2732
+ },
2733
+ },
2734
+ }
2735
+ container = Docker::Container.create(image_settings)
2736
+ container.start()
2737
+ command = ["/bin/bash", "-lc", "sudo echo -e \"#{login_content}\" >/home/ds/.netrc"]
2738
+ container.exec(command, tty: true)
2739
+ command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg"]
2740
+ container.exec(command, tty: true)
2741
+ command = ["/bin/bash", "-lc", "mkdir /home/ds/.cnvrg/tmp"]
2742
+ container.exec(command, tty: true)
2743
+ command = ["/bin/bash", "-lc", "sudo chown -R ds /home/ds/.cnvrg /home/ds/.netrc"]
2744
+ container.exec(command, tty: true)
2745
+ command = ["/bin/bash", "-lc", "sudo chmod 0600 /home/ds/.netrc"]
2746
+ container.exec(command, tty: true)
2747
+ say "#{container.id}:#{port}"
2748
+ rescue => e
2749
+ if e.message.include? "is not running"
2750
+ return "port is taken"
2751
+ end
2752
+ puts "error"
2753
+ puts e
2754
+ if container
2755
+ container.kill()
2756
+ end
2757
+ return false
2758
+ end
2759
+ end
2760
+
2761
+ desc '', ''
2762
+
2763
+ def upload_cnvrg_image(image_name)
2764
+ verify_logged_in(false)
2765
+ log_start(__method__, args, options)
2766
+ verify_software_installed("docker")
2767
+ owner = Cnvrg::CLI.get_owner()
2768
+
2769
+ path = File.expand_path('~')+"/.cnvrg/tmp/#{image_name}.zip"
2770
+ @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?
2775
+ # 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", "")
2777
+
2778
+ end
2779
+
2780
+
2781
+ desc '', ''
2782
+
2783
+ def download_built_image(image_name, image_slug)
2784
+ begin
2785
+ verify_logged_in(false)
2786
+ log_start(__method__, args, options)
2787
+ owner = Cnvrg::CLI.get_owner()
2788
+ path = File.expand_path('~')+"/.cnvrg/tmp/#{image_name}.tar.gz"
2789
+ @files = Cnvrg::Files.new(owner, "")
2790
+
2791
+ say "Downloading image file", Thor::Shell::Color::BLUE
2792
+ begin
2793
+ if @files.download_image(path, image_slug, owner)
2794
+ gzipRes = system("gunzip -f #{path}")
2795
+ if !gzipRes
2796
+ log_End(1, "can't unzip gz file from image")
2797
+
2798
+ say "Couldn't create tar file from image", Thor::Shell::Color::RED
2799
+ exit(1)
2800
+ else
2801
+ path = path.gsub(".gz", "")
2802
+ return path
2803
+ end
2804
+
2805
+ else
2806
+ say "Couldn't download image #{image_name}", Thor::Shell::Color::RED
2807
+ log_end(1, "can't download image")
2808
+ return false
2809
+ end
2810
+ rescue Interrupt
2811
+ log_end(-1)
2812
+ say "The user has exited to process, aborting", Thor::Shell::Color::BLUE
2813
+ exit(1)
2814
+ end
2815
+ rescue SignalException
2816
+ log_end(-1)
2817
+ say "\nAborting"
2818
+ exit(1)
2819
+ end
2820
+ end
2821
+
2822
+ desc '', ''
2823
+
2824
+ def download_image(image_name, image_slug)
2825
+ begin
2826
+ verify_logged_in(false)
2827
+ log_start(__method__, args, options)
2828
+ owner = Cnvrg::CLI.get_owner()
2829
+ path = File.expand_path('~')+"/.cnvrg/tmp/#{image_name}.zip"
2830
+ @files = Cnvrg::Files.new(owner, "")
2831
+
2832
+ say "Downloading image file", Thor::Shell::Color::BLUE
2833
+ begin
2834
+ if @files.download_image(path, image_slug, owner)
2835
+
2836
+ dir_path = File.expand_path('~')+"/.cnvrg/tmp/#{image_name}"
2837
+ FileUtils.rm_rf([dir_path])
2838
+
2839
+ Zip::File.open(path) do |zip_file|
2840
+ zip_file.each do |entry|
2841
+
2842
+ f_path=File.join(dir_path, entry.name)
2843
+ FileUtils.mkdir_p(File.dirname(f_path))
2844
+ zip_file.extract(entry, f_path)
2845
+ end
2846
+ end
2847
+
2848
+
2849
+
2850
+ return dir_path
2851
+
2852
+ else
2853
+ say "Couldn't download image #{image_name}", Thor::Shell::Color::RED
2854
+ log_end(1, "can't download image")
2855
+ return false
2856
+ end
2857
+ rescue Interrupt
2858
+ log_end(-1)
2859
+ say "The user has exited to process, aborting", Thor::Shell::Color::BLUE
2860
+ exit(1)
2861
+ end
2862
+ rescue SignalException
2863
+ log_end(-1)
2864
+ say "\nAborting"
2865
+ exit(1)
2866
+ ensure
2867
+ if !path.nil?
2868
+ FileUtils.rm(path)
2869
+ end
2870
+ end
2871
+ end
2872
+
2873
+
2874
+ desc 'list_images', 'lists all custom images you can pull'
2875
+
2876
+ def list_images
2877
+ begin
2878
+ verify_logged_in(false)
2879
+ log_start(__method__, args, options)
2880
+ owner = Cnvrg::CLI.get_owner()
2881
+ res = Cnvrg::API.request("users/#{owner}/images/list", 'GET')
2882
+ if Cnvrg::CLI.is_response_success(res)
2883
+ printf "%-20s %-20s %-30s %-20s %-20s\n", "name", "project", "created by", "is_public", "last updated"
2884
+ res["result"]["images"].each do |u|
2885
+ time = Time.parse(u["created_at"])
2886
+ update_at = get_local_time(time)
2887
+ created_by = u["created_by"]
2888
+
2889
+ printf "%-20s %-20s %-30s %-20s %-20s\n", u["name"], u["project"], created_by, u["is_public"], update_at
2890
+ end
2891
+ end
2892
+ log_end(0)
2893
+ return res["result"]["images"]
2894
+ rescue SignalException
2895
+ log_end(-1)
2896
+ say "\nAborting"
2897
+ exit(1)
2898
+ end
2899
+
2900
+
2901
+ end
2902
+
2903
+ desc 'list_machines', 'lists all machines belong to your organization'
2904
+
2905
+ def list_machines
2906
+ begin
2907
+ verify_logged_in(false)
2908
+ log_start(__method__, args, options)
2909
+ owner = Cnvrg::CLI.get_owner()
2910
+ res = Cnvrg::API.request("users/#{owner}/machines/list", 'GET')
2911
+ if Cnvrg::CLI.is_response_success(res)
2912
+ printf "%-20s %-20s %-20s\n", "name", "created by", "last_used"
2913
+ res["result"]["machines"].each do |u|
2914
+ time = Time.parse(u["last_used"])
2915
+ update_at = get_local_time(time)
2916
+ printf "%-20s %-20s %-20s\n", u["name"], u["created_by"], update_at
2917
+ end
2918
+ end
2919
+ log_end(0)
2920
+ return res["result"]["images"]
2921
+ rescue SignalException
2922
+ log_end(-1)
2923
+ say "\nAborting"
2924
+ exit(1)
1034
2925
  end
1035
2926
 
1036
- desc 'commit_notebook', 'commit notebook changes to create a new notebook image'
1037
2927
 
1038
- def commit_notebook(notebook_image_name)
1039
- verify_logged_in(false)
1040
- log_start(__method__,args,options)
1041
- begin
1042
- docker_path = verify_software_installed("docker")
1043
-
1044
- container_id = get_container_id
1045
- owner = Cnvrg::CLI.get_owner()
1046
- say "Commiting notebook changes to: #{notebook_image_name}", Thor::Shell::Color::BLUE
2928
+ end
1047
2929
 
1048
- commit_res = system("#{docker_path} commit #{container_id} #{notebook_image_name}")
1049
- if commit_res
1050
- checker = Helpers.checkmark()
1051
- log_end(0)
1052
- say "#{checker} Done.", Thor::Shell::Color::GREEN
1053
- else
1054
- log_End(1,"can't commit new notebook image")
1055
- say "Couldn't commit new notebook image ", Thor::Shell::Color::RED
2930
+ desc 'get_machine', 'create new aws machine'
1056
2931
 
2932
+ def get_machine()
2933
+ begin
2934
+ verify_logged_in(true)
2935
+ log_start(__method__, args, options)
2936
+ owner = Cnvrg::CLI.get_owner()
2937
+ working_dir = is_cnvrg_dir
2938
+ @image = Images.new(working_dir)
2939
+ if @image.nil? or !@image.is_docker
2940
+ say "Couldn't find image related to this project", Thor::Shell::Color::RED
2941
+ exit(0)
2942
+ end
2943
+ res = Cnvrg::API.request("users/#{owner}/machines/list", 'GET')
2944
+ if Cnvrg::CLI.is_response_success(res)
2945
+ if res["result"]["machines"].empty?
2946
+ create = yes? "No machines available, create new machine?", Thor::Shell::Color::YELLOW
2947
+ if create
2948
+ instance_type = machine_options(res["result"]["aws_options"])
2949
+ else
2950
+ exit(0)
2951
+ end
2952
+ end
2953
+ printf "%-20s %-20s %-20s\n", "name", "created by", "last_used", "instance_type"
2954
+ res["result"]["machines"].each do |u|
2955
+ time = Time.parse(u["last_used"])
2956
+ update_at = get_local_time(time)
2957
+ printf "%-20s %-20s %-20s\n", u["name"], u["created_by"], update_at, u["instance type"]
1057
2958
  end
1058
- rescue SignalException
1059
- log_end(-1)
1060
- say "/nAborting"
1061
- exit(1)
1062
2959
  end
2960
+
2961
+ rescue SignalException
2962
+ log_end(-1)
2963
+ say "\nAborting"
2964
+ exit(1)
1063
2965
  end
2966
+ end
2967
+
1064
2968
 
1065
- desc 'upload_notebook', 'commit notebook changes to create a new notebook image'
2969
+ desc 'pull_image', 'downloads and loads an image'
1066
2970
 
1067
- def upload_image(image_name)
2971
+ def pull(image_name)
2972
+ begin
1068
2973
  verify_logged_in(false)
1069
- log_start(__method__,args,options)
1070
- docker_path = verify_software_installed("docker")
2974
+ log_start(__method__, args, options)
1071
2975
  owner = Cnvrg::CLI.get_owner()
1072
- # verify image exist
1073
- images = `#{docker_path} images |grep #{image_name}`
1074
- if images.empty?
1075
- say "Couldn't find any images named: #{image_name}", Thor::Shell::Color::RED
2976
+ image = Cnvrg::Images.image_exist(owner, image_name)
2977
+ if !image
2978
+ say "Couldn't find image in cnvrg repository", Thor::Shell::Color::RED
1076
2979
  exit(1)
1077
2980
  end
1078
- path = File.expand_path('~')+"/.cnvrg/#{owner}_#{image_name}.tar"
1079
- begin
1080
- say "Creating image file to upload", Thor::Shell::Color::BLUE
1081
- if !(File.exist? path or File.exist? path+"gz")
1082
- saveRes = system("#{docker_path} save #{image_name}>#{path}")
1083
- if !saveRes
1084
- log_End(1, "can't create tar file from image")
1085
- say "Couldn't create tar file from image", Thor::Shell::Color::RED
1086
- exit(1)
1087
- end
1088
- gzipRes = system("gzip -f #{path}")
1089
- if !gzipRes
1090
- log_End(1, "can't create tar file from image")
1091
-
1092
- say "Couldn't create tar file from image", Thor::Shell::Color::RED
1093
- exit(1)
1094
- end
1095
- end
1096
-
1097
- path = path+".gz"
1098
- @files = Cnvrg::Files.new(owner, "")
1099
-
1100
- exit_status = $?.exitstatus
1101
- if exit_status == 0
1102
- say "Uploading image file", Thor::Shell::Color::BLUE
1103
- res = @files.upload_image(path, image_name, owner)
1104
- if res
1105
- File.delete(path)
1106
- checks = Helpers.checkmark()
1107
- say "#{checks} Done", Thor::Shell::Color::GREEN
1108
- log_end(0)
1109
- else
1110
- say "Couldn't upload image", Thor::Shell::Color::RED
1111
- log_end(1, "can't create upload imag")
1112
-
1113
- end
2981
+ path = download_image(image_name, image["slug"])
2982
+ if path
2983
+ 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"})
2986
+ if not image.nil?
2987
+ FileUtils.rm_rf(path)
2988
+ checks = Helpers.checkmark()
2989
+ say "#{checks} Image built successfully", Thor::Shell::Color::GREEN
2990
+ log_end(0)
2991
+ return image
2992
+ log_end(0)
1114
2993
  else
1115
- say "Couldn't create image file for: #{image_name}", Thor::Shell::Color::RED
1116
- log_end(1, "can't create upload imag")
1117
- exit(1)
2994
+ say "Could not build image", Thor::Shell::Color::RED
2995
+ log_end(1, "Could build image")
2996
+ return false
1118
2997
  end
1119
- rescue SignalException
1120
- log_end(-1)
2998
+ else
2999
+ say "Could not download image", Thor::Shell::Color::RED
3000
+ log_end(1, "Could build image")
3001
+ return false
1121
3002
 
1122
- say "Couldn't upload image file for: #{image_name}", Thor::Shell::Color::RED
1123
- exit(1)
1124
- end
1125
3003
 
3004
+ end
1126
3005
 
1127
- end
3006
+ # else
3007
+ # path = download_image(image_name,image["slug"])
3008
+ # if path
3009
+ # image = Docker::Image.import(path)
3010
+ # image.tag('repo' => image_name, 'tag' => 'latest')
3011
+ # if not image.nil?
3012
+ # say "Finished downloading image, cleaning up..", Thor::Shell::Color::GREEN
3013
+ # FileUtils.rm(path)
3014
+ # checks = Helpers.checkmark()
3015
+ # say "#{checks} Done", Thor::Shell::Color::GREEN
3016
+ # log_end(0)
3017
+ # return image
3018
+ # log_end(0)
3019
+ # else
3020
+ # say "Could not download image", Thor::Shell::Color::RED
3021
+ # return false
3022
+ # end
3023
+ #
3024
+ # end
3025
+ # end
3026
+ rescue
3027
+ say "Couldn't build image", Thor::Shell::Color::RED
1128
3028
 
1129
- desc 'download_image', 'commit notebook changes to create a new notebook image'
3029
+ rescue SignalException
3030
+ say "\nAborting"
3031
+ log_end(-1)
3032
+ exit(1)
3033
+ ensure
3034
+ if path
3035
+ FileUtils.rm_rf(path)
1130
3036
 
1131
- def download_image(image_name)
1132
- begin
1133
- verify_logged_in(false)
1134
- log_start(__method__,args,options)
1135
- owner = Cnvrg::CLI.get_owner()
3037
+ end
3038
+ end
1136
3039
 
1137
- notebooks_res = Cnvrg::API.request("users/#{owner}/images/" + "find", 'POST', {image_name: image_name})
1138
3040
 
1139
- if Cnvrg::CLI.is_response_success(notebooks_res)
3041
+ end
1140
3042
 
1141
- images = notebooks_res["result"]["images"]
1142
- if images.empty?
1143
- say "Couldn't find any image with name: #{image_name}", Thor::Shell::Color::RED
1144
- exit(1)
1145
- elsif images.size == 1
1146
- image_id = images[0]["slug"]
1147
- else
1148
- printf "%-20s %-20s %-30s %-20s\n", "name", "version", "last updated", "created by"
1149
- images.each_with_index do |u, i|
1150
- time = Time.parse(u["updated_at"])
1151
- update_at = get_local_time(time)
1152
- version = u["version"] || "v1"
1153
- created_by = u["image_file_name"][/^[^\_]*/]
1154
- printf "%-20s %-20s %-30s %-20s\n", u["name"], version, update_at, created_by
1155
- end
1156
- choice = ask("Which version to download for #{image_name}?")
1157
- images.each do |u|
1158
- if u["version"] == choice
1159
- image_id = u["slug"]
1160
- end
3043
+ desc 'set_image', 'set image to a porject'
1161
3044
 
1162
- end
3045
+ def set_image(docker_image)
3046
+ verify_logged_in(true)
3047
+ log_start(__method__, args, options)
3048
+ working_dir = is_cnvrg_dir
3049
+ project = Project.new(working_dir)
1163
3050
 
1164
- end
1165
- end
1166
- path = Dir.pwd+"/#{image_name}.tar.gz"
1167
- @files = Cnvrg::Files.new(owner, "")
3051
+ local_images = Docker::Image.all
3052
+ docker_image_local = local_images.map { |x| x.info["RepoTags"] }.flatten.select { |y| y.include? docker_image }.flatten
3053
+ if docker_image_local.size == 0
1168
3054
 
1169
- say "Downloading image file", Thor::Shell::Color::BLUE
1170
- begin
1171
- image_path = @files.download_image(path, image_id, owner)
1172
- return image_path
1173
- # if res
1174
- # checks = Helpers.checkmark()
1175
- # say "#{checks} Done", Thor::Shell::Color::GREEN
1176
- # log_end(0)
1177
- # return true
1178
- # else
1179
- # say "Couldn't download image #{image_name}", Thor::Shell::Color::RED
1180
- # log_end(1,"can't download image")
1181
- # return false
1182
- # end
1183
- rescue Interrupt
1184
- log_end(-1)
1185
- say "The user has exited to process, aborting", Thor::Shell::Color::BLUE
3055
+ if yes? "Image wasn't found locally, pull image from cnvrg repository?", Thor::Shell::Color::YELLOW
3056
+ image = pull(docker_image)
3057
+ if image
3058
+ say "downloaded image: #{docker_image}"
3059
+ @image = Images.new(working_dir, docker_image)
3060
+ else
3061
+ say "Could not create a new project with docker, image was not found", Thor::Shell::Color::RED
1186
3062
  exit(1)
1187
3063
  end
1188
- rescue SignalException
1189
- log_end(-1)
1190
- say "/nAborting"
3064
+ else
3065
+ say "Could not create a new project with docker, image was not found", Thor::Shell::Color::RED
1191
3066
  exit(1)
3067
+
1192
3068
  end
3069
+ elsif docker_image_local.size == 1
3070
+ say "found image: #{docker_image_local[0]}, setting it up..", Thor::Shell::Color::BLUE
3071
+ @image = Images.new(working_dir, docker_image_local[0])
3072
+ elsif docker_image_local.size >1
3073
+ say "found #{docker_image_local.size} images, choose the image name you want to use", Thor::Shell::Color::BLUE
3074
+ image_name = ask "#{docker_image_local.join("\n")}\n", Thor::Shell::Color::BLUE
3075
+ image_name = image_name.strip
3076
+ @image = Images.new(working_dir, image_name)
1193
3077
  end
3078
+ @image.update_image_activity(project.last_local_commit, nil)
3079
+ end
1194
3080
 
1195
3081
 
1196
- desc 'list_images', 'lists all custom images you can pull'
3082
+ no_tasks do
3083
+ def get_instance_type(instances)
3084
+ machines = instances.map { |x| x }.select { |y| y[1] }
3085
+ if machines.size == 1
3086
+ instance_type = machines[0][0]
3087
+ elsif machines.size > 1
1197
3088
 
1198
- def list_images
1199
- begin
1200
- verify_logged_in(false)
1201
- log_start(__method__,args,options)
1202
- owner = Cnvrg::CLI.get_owner()
1203
- res = Cnvrg::API.request("users/#{owner}/images/list", 'GET')
1204
- if Cnvrg::CLI.is_response_success(res)
1205
- printf "%-20s %-20s %-30s %-20s\n", "name", "version", "last updated", "created by"
1206
- res["result"]["images"].each do |u|
1207
- time = Time.parse(u["updated_at"])
1208
- update_at = get_local_time(time)
1209
- version = u["version"] || "v1"
1210
- created_by = u["image_file_name"][/^[^\_]*/]
3089
+ values = instances.map { |x| x[0] }
3090
+ machines_str = "#{machines.map { |x| " " +x[0] }.flatten.join(" or")}"
1211
3091
 
1212
- printf "%-20s %-20s %-30s %-20s\n", u["name"], version, update_at, created_by
3092
+ instance_type = ask ("You can't choose more than 1 machine,either:#{machines_str}")
3093
+ instance_type = values.select { |x| x.eql? instance_type }
3094
+ if instance_type.empty?
3095
+ instance_type = nil
3096
+ else
3097
+ instance_type = instance_type[0]
1213
3098
  end
3099
+ else
3100
+ instance_type = nil
1214
3101
  end
1215
- log_end(0)
1216
- return res["result"]["images"]
1217
- rescue SignalException
1218
- log_end(-1)
1219
- say "/nAborting"
1220
- exit(1)
1221
- end
3102
+ return instance_type
3103
+ end
1222
3104
 
3105
+ def get_image(dir)
3106
+ project_dir = is_cnvrg_dir(dir)
3107
+ if !project_dir
3108
+ return false
3109
+ else
3110
+ project_config = YAML.load_file(project_dir+"/.cnvrg/config.yml")
3111
+ if project_config.to_h[:docker]
3112
+ project_config.to_h[:image_base]
3113
+ else
3114
+ false
3115
+ end
3116
+ end
1223
3117
 
1224
3118
  end
1225
3119
 
3120
+ def set_owner(owner, username, url)
3121
+ home_dir = File.expand_path('~')
1226
3122
 
1227
- desc 'pull_image', 'downloads and loads a custom image'
1228
- def pull_image(image_name)
1229
3123
  begin
1230
- verify_logged_in(false)
1231
- log_start(__method__,args,options)
1232
-
1233
- path = download_image(image_name)
1234
- if path
1235
- image = Docker::Image.import(path)
1236
- if not image.nil?
1237
- return image
1238
- log_end(0)
1239
- else
1240
- say "Could not download image", Thor::Shell::Color::RED
1241
- log_end(1,loadRes)
1242
- retunr false
1243
- end
1244
-
3124
+ if !File.directory? home_dir+"/.cnvrg"
3125
+ FileUtils.mkdir_p([home_dir+"/.cnvrg", home_dir+"/.cnvrg/tmp"])
1245
3126
  end
1246
- rescue SignalException
1247
- say "\nAborting"
1248
- log_end(-1)
1249
- exit(1)
3127
+ if !File.exist?(home_dir+"/.cnvrg/config.yml")
3128
+ FileUtils.touch [home_dir+"/.cnvrg/config.yml"]
3129
+ end
3130
+ if url.nil? or url.empty?
3131
+ url = "https://cnvrg.io/api"
3132
+ end
3133
+ config = {owner: owner, username: username, version_last_check: get_start_day(), api: url}
3134
+
3135
+ File.open(home_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
3136
+ return true
3137
+ rescue
3138
+ return false
1250
3139
  end
1251
3140
 
1252
3141
  end
1253
3142
 
1254
- no_tasks do
1255
- def get_container_id
1256
- docker_path = verify_software_installed("docker")
3143
+ def get_start_day
3144
+ time = Time.now
3145
+ return Time.new(time.year, time.month, time.day)
3146
+ end
1257
3147
 
1258
- container_id = `#{docker_path} ps --quiet --last=1 --filter status=running`.strip!
1259
- if container_id.empty?
1260
- say "Couldn't find a running notebook server, execute run_notebook", Thor::Shell::Color::RED
1261
- exit(1)
1262
- end
1263
- return container_id
3148
+ def calc_output_time(upload_output)
3149
+ if upload_output.nil? or upload_output.empty?
3150
+ return 0
3151
+ end
3152
+ time = upload_output.split(/(\d+)/).reject(&:empty?).map { |x| x.strip }
3153
+ if time.size!=2
3154
+ upload_output = ask("upload_output should be {number}{s/m/h/d} i.e. 5m (5 minutes), 1h (1 hour)\nre-enter value for upload_output")
3155
+ return calc_output_time(upload_output)
3156
+ end
3157
+ if time[0] == "0"
3158
+ return -1
3159
+ end
3160
+ case time[1].downcase
3161
+ when "s"
3162
+ return time[0].to_f
3163
+ when "m"
3164
+ return time[0].to_f*60
3165
+ when "h"
3166
+ return time[0].to_f*3600
3167
+ when "d"
3168
+ return time[0].to_f*24*3600
3169
+ else
3170
+ upload_output = ask("upload_output should be {number}{s/m/h/d} i.e. 5m (5 minutes), 1h (1 hour)\n re-enter value for upload_output")
3171
+ calc_output_time(upload_output)
1264
3172
  end
1265
3173
 
1266
- def set_owner(owner, username)
1267
- home_dir = File.expand_path('~')
1268
-
1269
- begin
1270
- if !File.directory? home_dir+"/.cnvrg"
1271
- FileUtils.mkdir_p([home_dir+"/.cnvrg", home_dir+"/.cnvrg/tmp"])
1272
- end
1273
- if !File.exist?(home_dir+"/.cnvrg/config.yml")
1274
- FileUtils.touch [home_dir+"/.cnvrg/config.yml"]
1275
- end
1276
- config = YAML.load_file(home_dir+"/.cnvrg/config.yml")
1277
- if !config or config.empty?
1278
- config = {owner: owner, username: username, version_last_check: get_start_day(), api: "https://cnvrg.io/api"}
1279
- else
1280
- config = {owner: owner, username: username, version_last_check: get_start_day(), api: config.to_h[:api]}
1281
- end
1282
-
1283
- File.open(home_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
1284
- return true
1285
- rescue
1286
- return false
1287
- end
3174
+ end
1288
3175
 
3176
+ def log_start(command, args="", options={})
3177
+ begin
3178
+ $LOG.info "----"
3179
+ $LOG.info ruby_version: RUBY_VERSION, os: Cnvrg::Helpers.os(), cli_version: Cnvrg::VERSION
3180
+ $LOG.info command: command, args: args, options: options
3181
+ rescue
1289
3182
  end
3183
+ end
1290
3184
 
1291
- def get_start_day
1292
- time = Time.now
1293
- return Time.new(time.year, time.month, time.day)
3185
+ def log_end(exit_status=0, error=nil)
3186
+ begin
3187
+ if exit_status==1
3188
+ $LOG.error exit_status: exit_status, error: error
3189
+ else
3190
+ $LOG.info exit_status: exit_status
3191
+ end
3192
+ rescue
1294
3193
  end
3194
+ end
1295
3195
 
1296
- def calc_output_time(upload_output)
1297
- if upload_output.nil? or upload_output.empty?
1298
- return 0
1299
- end
1300
- time = upload_output.split(/(\d+)/).reject(&:empty?).map { |x| x.strip }
1301
- if time.size!=2
1302
- upload_output = ask("upload_output should be {number}{s/m/h/d} i.e. 5m (5 minutes), 1h (1 hour)\nre-enter value for upload_output")
1303
- return calc_output_time(upload_output)
1304
- end
1305
- if time[0] == "0"
1306
- return -1
3196
+ def self.is_response_success(response, should_exit=true)
3197
+ if response.nil?
3198
+ if !Cnvrg::Helpers.internet_connection?
3199
+ # Cnvrg::CLI.log_end(1,"no internet connection")
3200
+ say("<%= color('Error:You seems to be offline', RED) %>")
3201
+ else
3202
+ say("<%= color('Error', RED) %>")
1307
3203
  end
1308
- case time[1].downcase
1309
- when "s"
1310
- return time[0].to_f
1311
- when "m"
1312
- return time[0].to_f*60
1313
- when "h"
1314
- return time[0].to_f*3600
1315
- when "d"
1316
- return time[0].to_f*24*3600
1317
- else
1318
- upload_output = ask("upload_output should be {number}{s/m/h/d} i.e. 5m (5 minutes), 1h (1 hour)\n re-enter value for upload_output")
1319
- calc_output_time(upload_output)
3204
+ elsif response["status"]!= 200
3205
+ error = response['message']
3206
+ # Cnvrg::CLI.log_end(1, error)
3207
+ if response["status"] == 500
3208
+ say("<%= color('Server Error', RED) %>")
3209
+ else
3210
+ say("<%= color('Error:#{error}', RED) %>")
1320
3211
  end
1321
3212
 
1322
- end
1323
- def log_start(command,args="", options={})
1324
- begin
1325
- $LOG.info "----"
1326
- $LOG.info ruby_version: RUBY_VERSION, os: Cnvrg::Helpers.os(), cli_version:Cnvrg::VERSION
1327
- $LOG.info command:command,args:args,options:options
1328
- rescue
1329
- end
1330
- end
1331
- def log_end(exit_status=0, error=nil)
1332
- begin
1333
- if exit_status==1
1334
- $LOG.error exit_status:exit_status, error:error
1335
- else
1336
- $LOG.info exit_status:exit_status
1337
- end
1338
- rescue
3213
+ if should_exit
3214
+ exit(1)
3215
+ else
3216
+ return false
1339
3217
  end
1340
3218
  end
3219
+ return true
3220
+ end
1341
3221
 
1342
- def self.is_response_success(response, should_exit=true)
1343
- if response.nil?
1344
- if !Cnvrg::Helpers.internet_connection?
1345
- # Cnvrg::CLI.log_end(1,"no internet connection")
1346
- say("<%= color('Error:You seems to be offline', RED) %>")
1347
- else
1348
- say("<%= color('Error', RED) %>")
1349
- end
1350
- elsif response["status"]!= 200
1351
- error = response['message']
1352
- # Cnvrg::CLI.log_end(1, error)
1353
- if response["status"] == 500
1354
- say("<%= color('Server Error', RED) %>")
1355
- else
1356
- say("<%= color('Error:#{error}', RED) %>")
1357
- end
3222
+ def self.get_owner
3223
+ home_dir = File.expand_path('~')
1358
3224
 
1359
- if should_exit
1360
- exit(1)
1361
- else
1362
- return false
1363
- end
1364
- end
1365
- return true
3225
+ config = YAML.load_file(home_dir+ "/.cnvrg/config.yml")
3226
+ owner = config.to_h[:owner]
3227
+ if owner.empty?
3228
+ invoke :set_default_owner, [], []
3229
+ return get_owner()
3230
+ else
3231
+ return owner
1366
3232
  end
3233
+ end
3234
+ def get_base_url
3235
+ home_dir = File.expand_path('~')
1367
3236
 
1368
- def self.get_owner
1369
- home_dir = File.expand_path('~')
1370
-
1371
- config = YAML.load_file(home_dir+ "/.cnvrg/config.yml")
1372
- owner = config.to_h[:owner]
1373
- if owner.empty?
1374
- invoke :set_default_owner
1375
- return get_owner()
1376
- else
1377
- return owner
1378
- end
1379
- end
3237
+ config = YAML.load_file(home_dir+ "/.cnvrg/config.yml")
3238
+ api = config.to_h[:api]
3239
+ return api.gsub!("/api","")
3240
+ end
1380
3241
 
1381
- def get_project_home
1382
- absolute_path = Dir.pwd
1383
- dirs = absolute_path.split("/")
1384
- dirs.pop while not Dir.exists?("#{dirs.join("/")}/.cnvrg") and dirs.size != 0
3242
+ def get_project_home
3243
+ absolute_path = Dir.pwd
3244
+ dirs = absolute_path.split("/")
3245
+ dirs.pop while not Dir.exists?("#{dirs.join("/")}/.cnvrg") and dirs.size != 0
1385
3246
 
1386
- if dirs.size == 0
1387
- say "Couldn't find cnvrg directory. Please start a new project", Thor::Shell::Color::RED
1388
- exit(1)
1389
- end
1390
- return dirs.join("/")
3247
+ if dirs.size == 0
3248
+ say "Couldn't find cnvrg directory. Please start a new project", Thor::Shell::Color::RED
3249
+ exit(1)
1391
3250
  end
3251
+ return dirs.join("/")
3252
+ end
1392
3253
 
1393
- def should_update_version
1394
- res = Cnvrg::API.request("/cli/version", 'GET')
1395
- if Cnvrg::CLI.is_response_success(res, false)
1396
- updated_version = res["result"]["version"]
1397
- if updated_version != Cnvrg::VERSION
1398
- return true
1399
- else
1400
- return false
1401
- end
3254
+ def should_update_version
3255
+ res = Cnvrg::API.request("/cli/version", 'GET')
3256
+ if Cnvrg::CLI.is_response_success(res, false)
3257
+ updated_version = res["result"]["version"]
3258
+ if updated_version != Cnvrg::VERSION
3259
+ return true
1402
3260
  else
1403
3261
  return false
1404
3262
  end
3263
+ else
3264
+ return false
1405
3265
  end
1406
- def log_handler
1407
- begin
3266
+ end
3267
+
3268
+ def log_handler
3269
+ begin
1408
3270
  date = DateTime.now.strftime("%m_%d_%Y")
1409
3271
  logfile = File.expand_path('~') +"/.cnvrg/log_#{date}.log"
1410
3272
  if !File.exist? logfile
@@ -1421,63 +3283,83 @@ module Cnvrg
1421
3283
  count+=1
1422
3284
  end
1423
3285
  @files = Cnvrg::Files.new(Cnvrg::CLI.get_owner, "")
1424
- @files.upload_log_file(logfile_old,"log_#{date}.log",yesterday)
3286
+ @files.upload_log_file(logfile_old, "log_#{date}.log", yesterday)
1425
3287
  FileUtils.remove logfile_old
1426
3288
 
1427
3289
 
1428
3290
  end
1429
- $LOG = LogStashLogger.new(type: :file, path: logfile, sync: true)
1430
- rescue => e
1431
- # puts e
1432
- end
3291
+ $LOG = LogStashLogger.new(type: :file, path: logfile, sync: true)
3292
+ rescue => e
3293
+ # puts e
1433
3294
  end
3295
+ end
1434
3296
 
1435
3297
 
3298
+ def verify_logged_in(in_dir=true)
3299
+ log_handler()
3300
+ auth = Cnvrg::Auth.new
3301
+ unless auth.is_logged_in?
3302
+ say 'You\'re not logged in', Thor::Shell::Color::RED
3303
+ say 'Please log in via `cnvrg login`', Thor::Shell::Color::BLUE
3304
+ exit(1)
3305
+ end
1436
3306
 
1437
- def verify_logged_in(in_dir=true)
1438
- log_handler()
1439
- auth = Cnvrg::Auth.new
1440
- unless auth.is_logged_in?
1441
- say 'You\'re not logged in', Thor::Shell::Color::RED
1442
- say 'Please log in via `cnvrg login`', Thor::Shell::Color::YELLOW
1443
- exit(1)
1444
- end
1445
-
1446
- if !Helpers.internet_connection?
1447
- wait_offline = agree "Seems like you're offline, wait until your' back online?",limited_to: ['y', 'n'], default: 'n'
1448
- if wait_offline
1449
- say "Waiting until your'e online..", Thor::Shell::Color::BLUE
1450
- while !Cnvrg::Helpers.internet_connection?
1451
- end
1452
- else
1453
- say "you seem to be offline, please check your internet connection", Thor::Shell::Color::RED
1454
- exit(0)
1455
- end
3307
+ if !Helpers.internet_connection?
3308
+ wait_offline = agree "Seems like you're offline, wait until your'e back online?", Thor::Shell::Color::YELLOW
3309
+ if wait_offline
3310
+ say "Waiting until your'e online..", Thor::Shell::Color::BLUE
3311
+ while !Cnvrg::Helpers.internet_connection?
3312
+ end
3313
+ else
3314
+ say "you seem to be offline, please check your internet connection", Thor::Shell::Color::RED
3315
+ exit(0)
1456
3316
  end
3317
+ end
1457
3318
 
1458
- config = YAML.load_file(File.expand_path('~')+"/.cnvrg/config.yml")
1459
- version_date = config.to_h[:version_last_check]
1460
- next_day = get_start_day+ 86399
1461
- if not (version_date..next_day).cover?(Time.now)
1462
- if should_update_version()
1463
- say "There is a new version, run gem update cnvrg", Thor::Shell::Color::BLUE
1464
- end
3319
+ config = YAML.load_file(File.expand_path('~')+"/.cnvrg/config.yml")
3320
+ version_date = config.to_h[:version_last_check]
3321
+ next_day = get_start_day+ 86399
3322
+ if not (version_date..next_day).cover?(Time.now)
3323
+ if should_update_version()
3324
+ say "There is a new version, run gem update cnvrg", Thor::Shell::Color::BLUE
1465
3325
  end
3326
+ end
1466
3327
  if in_dir
1467
- current_dir = Dir.pwd
1468
- if not Dir.exist? current_dir+"/.cnvrg"
1469
- say "You're not in a cnvrg project directory",Thor::Shell::Color::RED
3328
+ is_cnvrg = is_cnvrg_dir
3329
+ if !is_cnvrg
3330
+ say "You're not in a cnvrg project directory", Thor::Shell::Color::RED
1470
3331
  exit(0)
1471
-
1472
3332
  end
3333
+
1473
3334
  end
3335
+ #verify tmp dirs exist
3336
+ home_dir = File.expand_path('~')
3337
+
3338
+ FileUtils.mkdir_p([home_dir+"/.cnvrg", home_dir+"/.cnvrg/tmp", home_dir+"/.cnvrg/tmp_files"])
1474
3339
 
1475
3340
 
3341
+ end
1476
3342
 
3343
+ def is_cnvrg_dir(dir=Dir.pwd)
3344
+ current_dir = dir
3345
+ home_dir = File.expand_path('~')
3346
+ is_cnvrg = Dir.exist? current_dir+"/.cnvrg"
3347
+ until is_cnvrg == true
3348
+ current_dir = File.expand_path("..", current_dir)
3349
+ is_cnvrg = Dir.exist? current_dir+"/.cnvrg"
3350
+ if File.expand_path("..", current_dir).eql? home_dir
3351
+ break
3352
+ end
1477
3353
  end
3354
+ if is_cnvrg
3355
+ return current_dir
3356
+ else
3357
+ return false
3358
+ end
3359
+ end
1478
3360
 
1479
- def verify_software_installed(software)
1480
- begin
3361
+ def verify_software_installed(software)
3362
+ begin
1481
3363
  install_url = Cnvrg::CLI::INSTALLATION_URLS[software.to_sym]
1482
3364
  installed = `which #{software}`
1483
3365
  if installed.empty? or installed.nil?
@@ -1496,29 +3378,164 @@ module Cnvrg
1496
3378
  #TODO: change here
1497
3379
  say "docker isn't running. run:\ndocker-machine start default 2>/dev/null & eval `docker-machine env default`", Thor::Shell::Color::BLUE
1498
3380
  exit(1)
1499
- end
3381
+ end
1500
3382
  end
1501
3383
  end
1502
3384
 
1503
- return installed
1504
- rescue
1505
- exit(1)
3385
+ return true
3386
+ rescue
3387
+ exit(1)
3388
+ end
3389
+
3390
+ end
3391
+
3392
+ def get_local_time(time_to_update)
3393
+ local = Time.now.localtime
3394
+ gmt_offset = local.gmt_offset
3395
+ new_time =time_to_update +gmt_offset
3396
+ return new_time.to_s.gsub("UTC", "")
3397
+
3398
+ end
3399
+
3400
+
3401
+ def is_project_with_docker(dir)
3402
+ project_dir = is_cnvrg_dir(dir)
3403
+ if !project_dir
3404
+ return false
3405
+ else
3406
+ project_config = YAML.load_file(project_dir+"/.cnvrg/config.yml")
3407
+ if project_config.to_h[:docker]
3408
+ image = Images.new(project_dir)
3409
+ return image
3410
+ else
3411
+ false
3412
+ end
3413
+ end
3414
+
3415
+
3416
+ end
3417
+
3418
+ def machine_options(aws_options)
3419
+ begin
3420
+ say "Choose type of machine:", Thor::Shell::Color::BLUE
3421
+ printf "%-20s %-20s %-30s\n", "type", "details", "options"
3422
+ all_options = []
3423
+ aws_options.each do |a|
3424
+ all_options << a["options"].flatten
3425
+ options = a["options"].join(" ")
3426
+ printf "%-20s %-20s %-30s\n", a["type"], a["details"], options
3427
+ end
3428
+ all_options.flatten!
3429
+ instance_type = ask "which type of machine?", Thor::Shell::Color::YELLOW
3430
+ count = 0
3431
+ while !all_options.include? instance_type and count <4
3432
+ say "Couldn't find #{instance_type}", Thor::Shell::Color::RED
3433
+ instance_type = ask "which type of machine?", Thor::Shell::Color::YELLOW
3434
+ count+=1
1506
3435
  end
3436
+ return instance_type
3437
+ rescue
3438
+ return false
3439
+ rescue SignalException
3440
+ say "\nAborting"
3441
+ Exit(0)
3442
+ end
3443
+
1507
3444
 
3445
+ end
3446
+
3447
+ def container_changes(dir)
3448
+ container_id = is_project_with_docker(dir)
3449
+ if not container_id
3450
+ return false
1508
3451
  end
3452
+ container = Docker::Container.get(container_id)
3453
+ command = ['/bin/bash', '-lc', '/opt/ds/bin/pip freeze']
3454
+ pip = container.exec(command, tty: true)[0]
3455
+ command = ["/bin/bash", "-lc", "dpkg -l"]
3456
+ dpkg = container.exec(command, tty: true)[0]
3457
+ command = ["/bin/bash", "-lc", "cat /home/ds/.bash_history"]
3458
+ history = container.exec(command, tty: true)[0]
3459
+ diff = [pip, dpkg, history]
3460
+ return diff
3461
+ # File.open(dir+"/.cnvrg/pip_#{date}.txt", "w+") { |f| f.write pip }
3462
+ # File.open(dir+"/.cnvrg/dpkg_#{date}.txt", "w+") { |f| f.write dpkg }
3463
+ # File.open(dir+"/.cnvrg/history_#{date}.txt", "w+") { |f| f.write history }
3464
+ #
3465
+ # pip_new = pip[0].split("\r\n")
3466
+ # pip_base_file =JSON.parse(File.open( dir+"/.cnvrg/pip_base.txt","rb").read)
3467
+ # pip_base = pip_base_file[0].split("\r\n")
3468
+ #
3469
+ # pip_diff = pip_new - pip_base
3470
+ # if pip_diff.empty?
3471
+ # puts "pip is same"
3472
+ # else
3473
+ # puts pip_diff
3474
+ # end
3475
+ # dpkg_new = dpkg[0].split("\r\n")
3476
+ # dpkg_base_file =JSON.parse(File.open( dir+"/.cnvrg/dpkg_base.txt","rb").read)
3477
+ # dpkg_base = dpkg_base_file[0].split("\r\n")
3478
+ #
3479
+ # dpkg_diff = dpkg_new - dpkg_base
3480
+ # if dpkg_diff.empty?
3481
+ # puts "dpkg is same"
3482
+ # else
3483
+ # puts dpkg_diff
3484
+ # end
3485
+ # puts history
3486
+ end
1509
3487
 
1510
- def get_local_time(time_to_update)
1511
- local = Time.now.localtime
1512
- gmt_offset = local.gmt_offset
1513
- new_time =time_to_update +gmt_offset
1514
- return new_time.to_s.gsub("UTC", "")
3488
+ def is_port_taken(ip=Cnvrg::CLI::IP, port=Cnvrg::CLI::PORT, seconds=1)
3489
+ Timeout::timeout(seconds) do
3490
+ begin
3491
+ TCPSocket.new(ip, port).close
3492
+ true
3493
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
3494
+ false
3495
+ end
3496
+ end
3497
+ rescue Timeout::Error
3498
+ false
3499
+ end
3500
+
3501
+ def image_activity(image)
3502
+ res = image.handle_image_activity()
3503
+ if res == -1
3504
+ #image is not known
3505
+ say "Images #{image.image_name} is not known", Thor::Shell::Color::YELLOW
3506
+ to_sync = yes? "Sync image?", Thor::Shell::Color::YELLOW
3507
+ if to_sync
3508
+ sync_image()
3509
+ res = image.handle_image_activity()
3510
+ return res
3511
+ else
3512
+ return false
3513
+ end
1515
3514
 
1516
3515
  end
3516
+ return res
3517
+
3518
+ end
1517
3519
 
3520
+ def get_note_url(working_dir)
3521
+ config = YAML.load_file(working_dir+"/.cnvrg/config.yml")
3522
+ return config[:notebook_slug]
1518
3523
 
1519
3524
  end
1520
- end
1521
3525
 
3526
+ def get_schedule_date()
3527
+
3528
+ local = Time.now.localtime
3529
+ # gmt_offset = local.gmt_offset
3530
+ new_time =(local).to_s
3531
+ new_time = new_time[0, new_time.size-6] #remove timezone
3532
+ return new_time
3533
+
3534
+ end
1522
3535
 
1523
3536
 
3537
+ end
3538
+ end
1524
3539
  end
3540
+
3541
+