cnvrg 0.0.11 → 0.0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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
+