cnvrg 0.0.145 → 0.0.146

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.
@@ -0,0 +1,26 @@
1
+ require 'thor'
2
+
3
+ class SubCommandBase < Thor
4
+ def self.banner(command, namespace = nil, subcommand = false)
5
+ "#{basename} #{subcommand_prefix} #{command.usage}"
6
+ end
7
+
8
+ def self.subcommand_prefix
9
+ self.name.gsub(%r{.*::}, '').gsub(%r{^[A-Z]}) { |match| match[0].downcase }.gsub(%r{[A-Z]}) { |match| "-#{match[0].downcase}" }
10
+ end
11
+ end
12
+ module Cnvrg
13
+ class Data < SubCommandBase
14
+ desc "init", "init data folder"
15
+
16
+ def init
17
+ puts "im in init"
18
+ end
19
+ desc "upload", "upload data folder"
20
+
21
+ def upload
22
+ puts "im in upload"
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,376 @@
1
+ require 'mimemagic'
2
+ require 'aws-sdk'
3
+ require 'URLcrypt'
4
+
5
+ module Cnvrg
6
+ class Datafiles
7
+
8
+ LARGE_FILE=1024*1024*5
9
+ attr_reader :base_resource
10
+
11
+ def initialize(owner, dataset_slug)
12
+ @dataset_slug = dataset_slug
13
+ @owner = owner
14
+ @base_resource = "users/#{owner}/datasets/#{dataset_slug}/"
15
+ end
16
+
17
+ def upload_file(absolute_path, relative_path, commit_sha1)
18
+ file_name = File.basename relative_path
19
+ file_size = File.size(absolute_path).to_f
20
+ mime_type = MimeMagic.by_path(absolute_path)
21
+ content_type = !(mime_type.nil? or mime_type.text?) ? mime_type.type : "text/plain"
22
+ upload_resp = Cnvrg::API.request(@base_resource + "upload_file", 'POST_FILE', {absolute_path: absolute_path, relative_path: relative_path,
23
+ commit_sha1: commit_sha1, file_name: file_name,
24
+ file_size: file_size, file_content_type: content_type})
25
+ if Cnvrg::CLI.is_response_success(upload_resp, false)
26
+ path = upload_resp["result"]["path"]
27
+ if file_size.to_f>= Cnvrg::Files::LARGE_FILE.to_f
28
+ s3_res = upload_large_files_s3(upload_resp, absolute_path)
29
+ else
30
+ s3_res = upload_small_files_s3(path, absolute_path, content_type)
31
+ end
32
+ if s3_res
33
+ Cnvrg::API.request(@base_resource + "update_s3", 'POST', {path: path, commit_id: upload_resp["result"]["commit_id"],
34
+ blob_id: upload_resp["result"]["id"]})
35
+ return true
36
+ end
37
+ end
38
+ return false
39
+ end
40
+ def upload_log_file(absolute_path, relative_path,log_date)
41
+ file_name = File.basename relative_path
42
+ file_size = File.size(absolute_path).to_f
43
+ content_type = "text/x-log"
44
+ upload_resp = Cnvrg::API.request("/users/#{@owner}/" + "upload_cli_log", 'POST_FILE', {absolute_path: absolute_path, relative_path: relative_path,
45
+ file_name: file_name,log_date:log_date,
46
+ file_size: file_size, file_content_type: content_type})
47
+ if Cnvrg::CLI.is_response_success(upload_resp, false)
48
+ path = upload_resp["result"]["path"]
49
+ s3_res = upload_small_files_s3(path, absolute_path, "text/plain")
50
+ end
51
+ if s3_res
52
+ return true
53
+ end
54
+ return false
55
+
56
+ end
57
+ def upload_exec_file(absolute_path,image_name,commit_id)
58
+ file_name = File.basename absolute_path
59
+ file_size = File.size(absolute_path).to_f
60
+ content_type = "application/zip"
61
+ begin
62
+ upload_resp = Cnvrg::API.request("users/#{@owner}/images/" + "upload_config", 'POST_FILE', {relative_path: absolute_path,
63
+ file_name: file_name,
64
+ image_name:image_name,
65
+ file_size: file_size,
66
+ file_content_type: content_type,
67
+ project_slug: @project_slug,
68
+ commit_id:commit_id})
69
+ # puts upload_resp
70
+ if Cnvrg::CLI.is_response_success(upload_resp, false)
71
+ if upload_resp["result"]["image"] == -1
72
+ return -1
73
+ end
74
+ path = upload_resp["result"]["path"]
75
+ s3_res = upload_small_files_s3(path, absolute_path, content_type)
76
+
77
+ end
78
+ if s3_res
79
+ return upload_resp["result"]["id"]
80
+ end
81
+ return false
82
+ rescue SignalException
83
+
84
+ say "\nAborting"
85
+ exit(1)
86
+ end
87
+
88
+ end
89
+
90
+
91
+
92
+ def upload_image(absolute_path, image_name, owner, is_public, is_base,dpkg,libraries,bash,message,commit_id)
93
+ file_name = File.basename absolute_path
94
+ file_size = File.size(absolute_path).to_f
95
+ if is_base
96
+
97
+ content_type = "application/zip"
98
+ else
99
+ content_type = "application/gzip"
100
+ end
101
+ begin
102
+ upload_resp = Cnvrg::API.request("users/#{owner}/images/" + "upload_cnvrg", 'POST_FILE', {relative_path: absolute_path,
103
+ file_name: file_name,
104
+ image_name: image_name,
105
+ file_size: file_size,
106
+ file_content_type: content_type,
107
+ is_public: is_public,
108
+ project_slug: @project_slug,
109
+ commit_id:commit_id ,
110
+ dpkg: dpkg,
111
+ py2: libraries,
112
+ py3: libraries,
113
+
114
+ bash_history: bash,
115
+ commit_message:message,
116
+ is_base: is_base})
117
+ # puts upload_resp
118
+ if Cnvrg::CLI.is_response_success(upload_resp, false)
119
+ path = upload_resp["result"]["path"]
120
+ s3_res = upload_small_files_s3(path, absolute_path, content_type)
121
+ if s3_res
122
+ commit_resp = Cnvrg::API.request("users/#{owner}/images/#{upload_resp["result"]["id"]}/" + "commit", 'GET')
123
+ if Cnvrg::CLI.is_response_success(commit_resp, false)
124
+ return commit_resp["result"]["image"]
125
+ else
126
+ return false
127
+ end
128
+
129
+ end
130
+ end
131
+ return false
132
+ rescue =>e
133
+ end
134
+
135
+ end
136
+ def upload_cnvrg_image(absolute_path, image_name, owner, is_public, is_base,dpkg,libraries,bash,message)
137
+ file_name = File.basename absolute_path
138
+ file_size = File.size(absolute_path).to_f
139
+ if is_base
140
+
141
+ content_type = "application/zip"
142
+ else
143
+ content_type = "application/gzip"
144
+ end
145
+ begin
146
+ upload_resp = Cnvrg::API.request("users/#{owner}/images/" + "upload_cnvrg", 'POST_FILE', {relative_path: absolute_path,
147
+ file_name: file_name,
148
+ image_name: image_name,
149
+ file_size: file_size,
150
+ file_content_type: content_type,
151
+ is_public: is_public,
152
+ dpkg: dpkg,
153
+ libraries: libraries,
154
+ bash_history: bash,
155
+ commit_message:message,
156
+ is_base: is_base})
157
+ # puts upload_resp
158
+ if Cnvrg::CLI.is_response_success(upload_resp, false)
159
+ path = upload_resp["result"]["path"]
160
+ s3_res = upload_small_files_s3(path, absolute_path, content_type)
161
+ if s3_res
162
+ commit_resp = Cnvrg::API.request("users/#{owner}/images/#{upload_resp["result"]["id"]}/" + "commit", 'GET')
163
+ if Cnvrg::CLI.is_response_success(commit_resp, false)
164
+ return commit_resp["result"]["image"]
165
+ else
166
+ return false
167
+ end
168
+
169
+ end
170
+ end
171
+ return false
172
+ rescue =>e
173
+ end
174
+
175
+ end
176
+
177
+ def download_image(file_path_to_store, image_slug, owner)
178
+
179
+
180
+ download_resp = Cnvrg::API.request("users/#{owner}/images/#{image_slug}/" + "download", 'GET')
181
+ path = download_resp["result"]["path"]
182
+
183
+ if Cnvrg::CLI.is_response_success(download_resp, false)
184
+ begin
185
+ open(file_path_to_store, 'wb') do |file|
186
+ file << open(path).read
187
+ end
188
+
189
+ return true
190
+ rescue => e
191
+ return false
192
+ end
193
+
194
+ return true
195
+ else
196
+ return false
197
+ end
198
+
199
+
200
+ end
201
+
202
+ def upload_large_files_s3(upload_resp, file_path)
203
+ begin
204
+ sts_path = upload_resp["result"]["path_sts"]
205
+ uri = URI.parse(sts_path)
206
+ http_object = Net::HTTP.new(uri.host, uri.port)
207
+ http_object.use_ssl = true if uri.scheme == 'https'
208
+ request = Net::HTTP::Get.new(sts_path)
209
+
210
+ body = ""
211
+ http_object.start do |http|
212
+ response = http.request request
213
+ body = response.read_body
214
+ end
215
+ URLcrypt::key = [body].pack('H*')
216
+ puts "file_size: #{File.size(file_path).to_f}"
217
+ puts "start_time: #{Time.now}"
218
+ s3 = Aws::S3::Resource.new(
219
+ :access_key_id => URLcrypt.decrypt(upload_resp["result"]["sts_a"]),
220
+ :secret_access_key => URLcrypt.decrypt(upload_resp["result"]["sts_s"]),
221
+ :session_token => URLcrypt.decrypt(upload_resp["result"]["sts_st"]),
222
+ :region => URLcrypt.decrypt(upload_resp["result"]["region"]))
223
+ resp = s3.bucket(URLcrypt.decrypt(upload_resp["result"]["bucket"])).
224
+ object(upload_resp["result"]["path"]+"/"+File.basename(file_path)).
225
+ upload_file(file_path,{:use_accelerate_endpoint=>true})
226
+ puts "end_time: #{Time.now}"
227
+
228
+ return resp
229
+ rescue =>e
230
+ puts e
231
+ return false
232
+
233
+ end
234
+ return true
235
+
236
+ end
237
+
238
+ def upload_small_files_s3(url_path, file_path, content_type)
239
+ url = URI.parse(url_path)
240
+ file = File.open(file_path, "rb")
241
+ body = file.read
242
+ begin
243
+ Net::HTTP.start(url.host) do |http|
244
+ http.send_request("PUT", url.request_uri, body, {
245
+ "content-type" => content_type,
246
+ })
247
+ end
248
+ return true
249
+ rescue Interrupt
250
+ return false
251
+ rescue
252
+ return false
253
+ end
254
+ end
255
+
256
+ def upload_url(file_path)
257
+ response = Cnvrg::API.request(@base_resource + "upload_url", 'POST', {file_s3_path: file_path})
258
+ if Cnvrg::CLI.is_response_success(response, false)
259
+ return response
260
+ else
261
+ return nil
262
+ end
263
+
264
+ end
265
+
266
+ def delete_file(absolute_path, relative_path, commit_sha1)
267
+ response = Cnvrg::API.request(@base_resource + "delete_file", 'DELETE', {absolute_path: absolute_path, relative_path: relative_path, commit_sha1: commit_sha1})
268
+ return Cnvrg::CLI.is_response_success(response, false)
269
+ end
270
+
271
+ def delete_dir(absolute_path, relative_path, commit_sha1)
272
+ response = Cnvrg::API.request(@base_resource + "delete_dir", 'DELETE', {absolute_path: absolute_path, relative_path: relative_path, commit_sha1: commit_sha1})
273
+ return Cnvrg::CLI.is_response_success(response, false)
274
+ end
275
+
276
+ def create_dir(absolute_path, relative_path, commit_sha1)
277
+ response = Cnvrg::API.request(@base_resource + "create_dir", 'POST', {absolute_path: absolute_path, relative_path: relative_path, commit_sha1: commit_sha1})
278
+ return Cnvrg::CLI.is_response_success(response, false)
279
+ end
280
+ def download_file_s3(absolute_path, relative_path, project_home, conflict=false)
281
+ begin
282
+ res = Cnvrg::API.request(@base_resource + "download_file", 'POST', {absolute_path: absolute_path, relative_path: relative_path})
283
+ Cnvrg::CLI.is_response_success(res, false)
284
+ if res["result"]
285
+ download_resp = res
286
+ filename = download_resp["result"]["filename"]
287
+
288
+ absolute_path += ".conflict" if conflict
289
+ sts_path = download_resp["result"]["path_sts"]
290
+ uri = URI.parse(sts_path)
291
+ http_object = Net::HTTP.new(uri.host, uri.port)
292
+ http_object.use_ssl = true if uri.scheme == 'https'
293
+ request = Net::HTTP::Get.new(sts_path)
294
+
295
+ body = ""
296
+ http_object.start do |http|
297
+ response = http.request request
298
+ body = response.read_body
299
+ end
300
+ URLcrypt::key = [body].pack('H*')
301
+ s3 = Aws::S3::Client.new(
302
+ :access_key_id => URLcrypt.decrypt(download_resp["result"]["sts_a"]),
303
+ :secret_access_key => URLcrypt.decrypt(download_resp["result"]["sts_s"]),
304
+ :session_token => URLcrypt.decrypt(download_resp["result"]["sts_st"]),
305
+ :region => URLcrypt.decrypt(download_resp["result"]["region"]))
306
+ File.open(project_home+"/"+absolute_path, 'wb') do |file|
307
+ resp = s3.get_object({ bucket:URLcrypt.decrypt(download_resp["result"]["bucket"]),
308
+ key:URLcrypt.decrypt(download_resp["result"]["key"])}, target: file)
309
+ end
310
+ return true
311
+ end
312
+
313
+ rescue =>e
314
+ return false
315
+
316
+ end
317
+ end
318
+ def download_file(absolute_path, relative_path, project_home, conflict=false)
319
+ res = Cnvrg::API.request(@base_resource + "download_file", 'POST', {absolute_path: absolute_path, relative_path: relative_path})
320
+ Cnvrg::CLI.is_response_success(res, false)
321
+ if res["result"]
322
+ res = res["result"]
323
+ return false if res["link"].empty? or res["filename"].empty?
324
+ filename = res["filename"]
325
+ file_location = absolute_path.gsub(/#{filename}\/?$/, "")
326
+
327
+ FileUtils.mkdir_p project_home + "/" + file_location
328
+ filename += ".conflict" if conflict
329
+
330
+ File.open("#{project_home}/#{file_location}/#{filename}", "wb") do |file|
331
+ file.write open(res["link"]).read
332
+ end
333
+ else
334
+ return false
335
+ end
336
+ return true
337
+ end
338
+
339
+ def download_dir(absolute_path, relative_path, project_home)
340
+ FileUtils.mkdir_p("#{project_home}/#{absolute_path}")
341
+ end
342
+ def revoke_download_dir(absolute_path, relative_path, project_home)
343
+ puts FileUtils.rmtree("#{absolute_path}")
344
+ end
345
+
346
+ def revoke_download_file(project_home,absolute_path,filename,conflict=false)
347
+ begin
348
+ file_location = absolute_path.gsub(/#{filename}\/?$/, "")
349
+
350
+ filename += ".conflict" if conflict
351
+ FileUtils.remove("#{file_location}/#{filename}")
352
+ return true
353
+ rescue
354
+ return false
355
+ end
356
+ end
357
+
358
+ def start_commit(new_branch)
359
+
360
+ response = Cnvrg::API.request("#{base_resource}/commit/start", 'POST', {dataset_slug: @dataset_slug,new_branch:false,
361
+ username: @owner})
362
+ Cnvrg::CLI.is_response_success(response)
363
+ return response
364
+ end
365
+
366
+ def end_commit(commit_sha1)
367
+ response = Cnvrg::API.request("#{base_resource}/commit/end", 'POST', {commit_sha1: commit_sha1})
368
+ return response
369
+ end
370
+
371
+ def rollback_commit(commit_sha1)
372
+ response = Cnvrg::API.request("#{base_resource}/commit/rollback", 'POST', {commit_sha1: commit_sha1})
373
+ Cnvrg::CLI.is_response_success(response, false)
374
+ end
375
+ end
376
+ end
@@ -0,0 +1,196 @@
1
+ require 'fileutils'
2
+ module Cnvrg
3
+ class Dataset
4
+ attr_reader :slug, :owner, :title, :local_path, :working_dir
5
+
6
+ RemoteURL ||= "https://cnvrg.io"
7
+
8
+ def initialize(project_home)
9
+ begin
10
+ config = YAML.load_file(project_home+"/.cnvrg/config.yml")
11
+ @local_path = project_home
12
+ @title = config[:dataset_name]
13
+ @slug = config[:dataset_slug]
14
+ @owner = config[:owner]
15
+ @working_dir = project_home
16
+ rescue => e
17
+ end
18
+
19
+ end
20
+
21
+
22
+ def last_local_commit
23
+ idx = YAML.load_file(@local_path + "/.cnvrg/idx.yml")
24
+ return idx[:commit]
25
+ end
26
+
27
+ def url
28
+ url = Cnvrg::Helpers.remote_url
29
+ "#{url}/#{self.owner}/projects/#{self.slug}"
30
+ end
31
+
32
+ def update_ignore_list(new_ignore)
33
+ if new_ignore.empty?
34
+ return true
35
+ end
36
+ begin
37
+ File.open(self.local_path+"/.cnvrgignore", "a+") do |f|
38
+ new_ignore.each do |i|
39
+ f.puts("#{i}\n")
40
+ end
41
+ end
42
+ return true
43
+ rescue
44
+ return false
45
+ end
46
+ end
47
+
48
+ def get_ignore_list
49
+ ignore_list = []
50
+ File.open(self.local_path+"/.cnvrgignore", "r").each_line do |line|
51
+ line = line.strip
52
+ if line.start_with? "#"
53
+ next
54
+ end
55
+ if line.end_with? "/"
56
+ ignore_list << line.chop
57
+ sub_dirs = Dir.glob("#{line}/**/*").each { |x| x.gsub!("//", "/") }
58
+ ignore_list << sub_dirs.flatten
59
+ else
60
+ ignore_list << line
61
+ end
62
+ end
63
+ return ignore_list.flatten
64
+
65
+ end
66
+
67
+
68
+ def self.init(owner, dataset_name, is_public=false)
69
+ list_dirs = [".cnvrg"
70
+ ]
71
+ list_files = [
72
+ ".cnvrgignore",
73
+ ".cnvrg/config.yml"
74
+ ]
75
+
76
+ cnvrgignore = Helpers.cnvrgignore_content
77
+ begin
78
+ response = Cnvrg::API.request("cli/create_dataset", 'POST', {title: dataset_name, owner: owner, is_public: is_public})
79
+ Cnvrg::CLI.is_response_success(response)
80
+ response = JSON.parse response["result"]
81
+ dataset_slug = response["slug"]
82
+
83
+ config = {dataset_name: dataset_name,
84
+ dataset_slug: dataset_slug,
85
+ owner: owner}
86
+ FileUtils.mkdir_p list_dirs
87
+ FileUtils.touch list_files
88
+ File.open(".cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
89
+ File.open(".cnvrgignore", "w+") { |f| f.write cnvrgignore } unless File.exist? ".cnvrgignore"
90
+ rescue => e
91
+
92
+ return false
93
+ end
94
+ return true
95
+ end
96
+
97
+
98
+ def get_idx
99
+ YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
100
+ end
101
+ def url
102
+ url = Cnvrg::Helpers.remote_url
103
+ "#{url}/#{self.owner}/datsets/#{self.slug}"
104
+ end
105
+ def generate_idx
106
+ if File.exists? "#{self.local_path}/.cnvrg/idx.yml"
107
+ old_idx = YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
108
+ else
109
+ old_idx = nil
110
+ end
111
+
112
+ tree_idx = Hash.new(0)
113
+
114
+ list = Dir.glob("#{self.local_path}/**/**", File::FNM_DOTMATCH).reject { |x| (x =~ /\/\.{1,2}$/) or (x =~ /^#{self.local_path}\/\.cnvrg\/*/) }
115
+ list_ignore = self.get_ignore_list()
116
+ list.each do |e|
117
+ label = e.gsub(self.local_path + "/", "")
118
+ if File.directory? e
119
+ if list_ignore.include? label
120
+ next
121
+ end
122
+ tree_idx[label+"/"] = nil
123
+ else
124
+ if list_ignore.include? label
125
+ next
126
+ end
127
+ sha1 = Digest::SHA1.file(e).hexdigest
128
+ if old_idx.nil? or old_idx.to_h[:tree].nil?
129
+ tree_idx[label] = {sha1: sha1, commit_time: nil}
130
+ elsif old_idx[:tree][label].nil? or old_idx[:tree][label][:sha1] != sha1
131
+ tree_idx[label] = {sha1: sha1, commit_time: nil}
132
+ else
133
+ tree_idx[label] = old_idx[:tree][label]
134
+ end
135
+ end
136
+ end
137
+
138
+ idx = {commit: old_idx.to_h[:commit], tree: tree_idx}
139
+
140
+ File.open("#{self.local_path}/.cnvrg/idx.yml", 'w') { |f| f.write idx.to_yaml }
141
+ return YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
142
+ end
143
+ def create_volume
144
+ response = Cnvrg::API.request("users/#{self.owner}/datasets/#{self.slug}/volumes/create", 'POST')
145
+ CLI.is_response_success(response)
146
+ return response
147
+ end
148
+
149
+ def compare_idx(new_branch, commit=last_local_commit)
150
+
151
+ local_idx = self.generate_idx
152
+ response = Cnvrg::API.request("users/#{self.owner}/datasets/#{self.slug}/status", 'POST', {idx: local_idx, new_branch: new_branch, current_commit: commit})
153
+ CLI.is_response_success(response)
154
+ return response
155
+ end
156
+
157
+ def compare_commit(commit)
158
+ if commit.nil? or commit.empty?
159
+ commit = last_local_commit
160
+ end
161
+ response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/commit/compare", 'POST', {current_commit: commit})
162
+ CLI.is_response_success(response)
163
+ update_is_new_branch(response["result"]["new_branch"])
164
+ return response["result"]["new_branch"]
165
+ end
166
+
167
+ def update_idx_with_files_commits!(files, commit_time)
168
+
169
+ idx_hash = YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
170
+ files.each do |path|
171
+ idx_hash[:tree].to_h[path].to_h[:commit_time] = commit_time
172
+ end
173
+ File.open("#{self.local_path}/.cnvrg/idx.yml", 'w') { |f| f.write idx_hash.to_yaml }
174
+
175
+ return true
176
+ end
177
+
178
+
179
+ def update_idx_with_commit!(commit)
180
+ idx_hash = YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
181
+ idx_hash[:commit] = commit
182
+
183
+ File.open("#{self.local_path}/.cnvrg/idx.yml", 'w') { |f| f.write idx_hash.to_yaml }
184
+ return true
185
+ end
186
+
187
+ def revert(working_dir)
188
+ FileUtils.rm_rf working_dir
189
+ # response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/revert", 'GET')
190
+ # CLI.is_response_success(response)
191
+
192
+
193
+ end
194
+
195
+ end
196
+ end