cnvrg 1.6.33 → 1.9.6

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,31 @@
1
+ module Cnvrg
2
+ class ConnectJobSsh
3
+ def initialize(job_id)
4
+ home_dir = File.expand_path('~')
5
+ config = YAML.load_file(home_dir+"/.cnvrg/config.yml")
6
+ @owner = config.to_h[:owner]
7
+ @job_id = job_id
8
+ rescue => e
9
+ @owner = ""
10
+ Cnvrg::Logger.log_info("cnvrg is not configured")
11
+ end
12
+
13
+ def start(username, password)
14
+ Cnvrg::API_V2.request("#{@owner}/job_ssh/#{@job_id}/start" , 'POST', {username: username, password: password})
15
+ end
16
+
17
+ def status()
18
+ Cnvrg::API_V2.request("#{@owner}/job_ssh/#{@job_id}/status" , 'GET', nil)
19
+ end
20
+
21
+ def run_portforward_command(pod_name, port, kubeconfig, namespace)
22
+ command = "kubectl"
23
+ if kubeconfig.present?
24
+ command = "kubectl --kubeconfig=#{kubeconfig}"
25
+ end
26
+ bashCommand = "#{command} -n #{namespace} port-forward #{pod_name} #{port}:22"
27
+ puts("\nrunning command #{bashCommand}")
28
+ `#{bashCommand}`
29
+ end
30
+ end
31
+ end
@@ -128,6 +128,7 @@ module Cnvrg
128
128
  message = options["message"]
129
129
  cli.sync_data_new(new_branch, force, verbose, commit, all_files, tags, parallel, chunk_size, init, message)
130
130
  end
131
+
131
132
  desc 'data download', 'Download files from remote server'
132
133
  method_option :new_branch, :type => :boolean, :aliases => ["-nb"], :desc => "create new branch of commits", :default => false
133
134
  method_option :verbose, :type => :boolean, :aliases => ["-v"], :default => false
@@ -151,27 +152,52 @@ module Cnvrg
151
152
  method_option :read, :type => :boolean, :aliases => ["-r", "--read"], :default => false
152
153
  method_option :remote, :type => :boolean, :aliases => ["-h", "--remote"], :default => false
153
154
  method_option :relative, :type => :boolean, :aliases => ["-rel", "--relative"], :default => false
154
-
155
+ method_option :flatten, :type => :boolean, :aliases => ["-f", "--flatten"], :default => false
156
+ method_option :soft, :type => :boolean, :aliases => ["-s", "--soft"], :default => false, :hide => true
155
157
  def clone(dataset_url)
156
- #test
157
158
  cli = Cnvrg::CLI.new()
158
159
  only_tree =options[:only_tree]
159
160
  commit =options[:commit]
160
161
  query =options[:query]
161
162
  read = options[:read]
162
163
  remote = options[:remote]
163
- cli.clone_data(dataset_url, only_tree=only_tree,commit=commit, query=query, read=read, remote=remote, relative: options[:relative])
164
+ soft = options[:soft]
165
+ flatten = options[:flatten]
166
+ cli.clone_data(
167
+ dataset_url,
168
+ only_tree=only_tree,
169
+ commit=commit,
170
+ query=query,
171
+ read=read,
172
+ remote=remote,
173
+ flatten: flatten,
174
+ relative: options[:relative],
175
+ soft: soft
176
+ )
164
177
  end
165
178
 
166
179
  desc 'data verify DATASETS_TITLES', 'verify datasets', :hide => true
167
- method_option :timeout, :type => :numeric, :aliases => ["-t", "--timeout"], :desc => "Time to wait before returning final answer", :default => 15
168
-
180
+ method_option :timeout, :type => :numeric, :aliases => ["-t", "--timeout"], :desc => "Time to wait before returning final answer", :default => nil
169
181
  def verify(*dataset_titles)
170
182
  cli = Cnvrg::CLI.new()
171
183
  timeout =options[:timeout]
172
184
  cli.verify_datasets(dataset_titles, timeout)
173
185
  end
174
186
 
187
+ desc 'data scan', 'lookup datasets', :hide => true
188
+ def scan()
189
+ cli = Cnvrg::CLI.new()
190
+ cli.scan_datasets()
191
+ end
192
+
193
+ desc "data block DATASET_TITLES", 'verifying that datasets exists', hide: true
194
+ def block(*dataset_slugs)
195
+ not_verified = true
196
+ while not_verified
197
+ not_verified = dataset_slugs.select{|slug| not Dataset.verify_dataset(slug)}.present?
198
+ end
199
+ end
200
+
175
201
  desc 'data set --url=DATASET_URL', 'Set dataset url to other url'
176
202
  method_option :url, :type => :string, :aliases => ["--url"], :default => ''
177
203
  def set
@@ -186,19 +212,48 @@ module Cnvrg
186
212
  desc 'data put DATASET_URL FILES_PREFIX', 'Upload selected files from local dataset directory to remote server'
187
213
  method_option :dir, :type => :string, :aliases => ["-d", "--dir"], :default => ''
188
214
  method_option :commit, :type => :string, :aliases => ["-c", "--commit"], :default => ''
215
+ method_option :force, :type => :boolean, :aliases => ["-f","--force"], :default => false
216
+ method_option :threads, :type => :numeric, :aliases => ["-t","--threads"], :default => 15
217
+ method_option :chunk_size, :type => :numeric, :aliases => ["-cs","--chunk"], :default => 1000
218
+ method_option :message, :type => :string, :aliases => ["--message"], :desc => "create commit with message", :default => nil
189
219
  def put(dataset_url, *files)
190
220
  cli = Cnvrg::CLI.new()
191
221
  dir = options[:dir]
222
+ force = options["force"]
192
223
  commit = options[:commit]
193
- cli.data_put(dataset_url, files: files, dir: dir, commit: commit)
224
+ message = options[:message]
225
+ threads = options[:threads]
226
+ chunk_size = options[:chunk_size]
227
+ cli.data_put(
228
+ dataset_url,
229
+ files: files,
230
+ dir: dir,
231
+ commit: commit,
232
+ force: force,
233
+ threads: threads,
234
+ chunk_size: chunk_size,
235
+ message: message
236
+ )
237
+ end
238
+
239
+ desc 'data rm DATASET_URL FILES_PREFIX', 'Delete selected files from remote server'
240
+ method_option :message, :type => :string, :aliases => ["--message"], :desc => "create commit with message", :default => nil
241
+ def rm(dataset_url, *regex_list)
242
+ cli = Cnvrg::CLI.new()
243
+ message = options[:message]
244
+ cli.data_rm(dataset_url, regex_list: regex_list, message: message)
194
245
  end
195
246
 
196
247
  desc 'data clone_query --query=QUERY_SLUG DATASET_URL', 'Clone dataset with specific query'
197
248
  method_option :query, :type => :string, :aliases => ["-q", "--query"], :default => nil
249
+ method_option :soft, :type => :boolean, :aliases => ["-s", "--soft"], :default => false, :hide => true
250
+ method_option :flatten, :type => :boolean, :aliases => ["-f", "--flatten"], :default => false
198
251
  def clone_query(dataset_url)
199
252
  cli = Cnvrg::CLI.new()
200
- query =options[:query]
201
- cli.clone_data_query(dataset_url,query=query)
253
+ query = options[:query]
254
+ flatten = options[:flatten]
255
+ soft =options[:soft]
256
+ cli.clone_data_query(dataset_url,query=query, flatten, soft: soft)
202
257
  end
203
258
 
204
259
  desc 'data delete DATASET_SLUG', 'Delete dataset'
@@ -214,12 +269,13 @@ module Cnvrg
214
269
  cli.list_dataset()
215
270
 
216
271
  end
217
- desc 'data commits', 'List all commits for a current dataset'
218
272
 
219
- def commits()
273
+ desc 'data commits URL/SLUG', 'List all commits for a given dataset'
274
+ method_option :commit_sha1, :type => :string, :aliases => ["-c", "--commit"], :default => nil
275
+ def commits(dataset_url)
220
276
  cli = Cnvrg::CLI.new()
221
- cli.list_dataset_commits()
222
-
277
+ commit_sha1 = options[:commit_sha1]
278
+ cli.list_dataset_commits(dataset_url, commit_sha1:commit_sha1)
223
279
  end
224
280
 
225
281
  desc 'data files DATASET_URL', 'Show list of dataset files'
@@ -20,6 +20,15 @@ module Cnvrg
20
20
  @dataset = dataset
21
21
  @base_resource = "users/#{owner}/datasets/#{dataset_slug}/"
22
22
  @downloader = @dataset.get_storage_client
23
+ @token_issue_time = Time.current
24
+ end
25
+
26
+ def refresh_storage_token
27
+ current_time = Time.current
28
+ if current_time - @token_issue_time > 1.hours
29
+ @downloader = @dataset.get_storage_client
30
+ @token_issue_time = Time.current
31
+ end
23
32
  end
24
33
 
25
34
  def check_file_sha1(filename, org_sha1, tag: 'conflict')
@@ -46,6 +55,26 @@ module Cnvrg
46
55
  paths.map{|p| p.gsub(/^\.\//, '')}
47
56
  end
48
57
 
58
+ def get_files_and_folders(paths)
59
+ files_and_folders = {}
60
+ paths.each do |file|
61
+ if File.exists? file
62
+ if File.directory? file
63
+ Dir.glob("#{file}/**/*").select do |f|
64
+ files_and_folders["#{f}/"] = "folder" if File.directory? f
65
+ files_and_folders[f] = "file" if File.file? f
66
+ end
67
+ files_and_folders["#{file}/"] = "folder"
68
+ else
69
+ files_and_folders[file] = "file"
70
+ end
71
+ next
72
+ end
73
+ raise SignalException.new(1, "Cant find file #{file}") unless File.exists? "#{Dir.pwd}/#{file}"
74
+ end
75
+ return files_and_folders
76
+ end
77
+
49
78
  def check_files_sha1(files, resolver, tag)
50
79
  conflicts = 0
51
80
  files.each do |file|
@@ -101,22 +130,41 @@ module Cnvrg
101
130
  end
102
131
  end
103
132
 
104
-
133
+ # This is for backwards compatibility only and should be removed in future versions:
105
134
  def put_commit(commit_sha1)
106
- response = Cnvrg::API.request("#{@base_resource}/commit/latest", 'PUT', {commit_sha1: commit_sha1})
135
+ response = Cnvrg::API.request(
136
+ "#{@base_resource}/commit/latest",
137
+ 'PUT',
138
+ {
139
+ commit_sha1: commit_sha1,
140
+ ignore: true # tells the new server to ignore this api call since its coming from the new CLI
141
+ }
142
+ )
107
143
  if response.present?
108
144
  msg = response['result']
109
145
  else
110
- msg = "Cant save changes in the dataset"
146
+ msg = "Can't save changes in the dataset"
111
147
  end
112
148
 
113
149
  Cnvrg::Result.new(Cnvrg::CLI.is_response_success(response, false), msg)
114
150
  end
115
151
 
152
+ def create_progressbar(title, total)
153
+ return ProgressBar.create(
154
+ :title => title,
155
+ :progress_mark => '=',
156
+ :format => "%b>>%i| %p%% %t",
157
+ :starting_at => 0,
158
+ :total => total,
159
+ :autofinish => true
160
+ )
161
+ end
162
+
116
163
 
117
164
  def upload_multiple_files(commit_sha1, tree, threads: ParallelThreads, force: false, new_branch: false, prefix: '', partial_commit: nil, total: nil)
118
165
  begin
119
166
  Cnvrg::Logger.log_info("Sending Upload Files request")
167
+ refresh_storage_token
120
168
  error = nil
121
169
  upload_resp = nil
122
170
  10.times do
@@ -148,6 +196,9 @@ module Cnvrg
148
196
  end
149
197
 
150
198
  files = results['files']
199
+
200
+ progressbar.progress += tree.keys.length - files.length if progressbar.present?
201
+ progress_semaphore = Mutex.new
151
202
  upload_error_files = []
152
203
  @temp_upload_progressbar.progress += tree.keys.length - files.length if @temp_upload_progressbar.present?
153
204
  Parallel.map((files.keys), in_threads: threads) do |k|
@@ -159,8 +210,9 @@ module Cnvrg
159
210
  tree.except!(k)
160
211
  Cnvrg::Logger.log_error_message("Error while upload single file #{o["path"]}")
161
212
  end
162
- @temp_upload_progressbar.progress += 1 if @temp_upload_progressbar.present?
213
+ progress_semaphore.synchronize { progressbar.progress += 1 if progressbar.present? }
163
214
  end
215
+
164
216
  blob_ids = files.values.map {|f| f['bv_id']}
165
217
  if blob_ids.present?
166
218
  dirs = tree.keys.select {|k| tree[k].nil?} || []
@@ -180,17 +232,231 @@ module Cnvrg
180
232
  end
181
233
  end
182
234
 
183
- def upload_single_file(file)
235
+ def delete_multiple_files(commit_sha1, regex_list)
236
+ begin
237
+ Cnvrg::Logger.log_info("Sending Delete Files request")
238
+ resp = Cnvrg::API.request(
239
+ @base_resource + "delete_files",
240
+ 'POST_JSON',
241
+ {
242
+ commit_sha1: commit_sha1,
243
+ regex_list: regex_list,
244
+ }
245
+ )
246
+ unless Cnvrg::CLI.is_response_success(resp, false)
247
+ Cnvrg::Logger.log_method(bind: binding)
248
+ raise Exception.new("Got an error message from server, #{resp.try(:fetch, "message")}")
249
+ end
250
+ Cnvrg::Logger.log_info("Delete Files request Successful")
251
+ return resp["files"], resp["folders"], resp["job_id"]
252
+ rescue => e
253
+ Cnvrg::Logger.log_method(bind: binding)
254
+ Cnvrg::Logger.log_error(e)
255
+ raise e
256
+ end
257
+ end
258
+
259
+ def delete_file_chunk(commit_sha1, regex_list, chunk_size, offset)
260
+ begin
261
+ resp = Cnvrg::API.request(
262
+ @base_resource + "delete_files_by_chunk",
263
+ 'POST_JSON',
264
+ {
265
+ commit_sha1: commit_sha1,
266
+ regex_list: regex_list,
267
+ chunk_size: chunk_size,
268
+ offset: offset
269
+ }
270
+ )
271
+ unless Cnvrg::CLI.is_response_success(resp, false)
272
+ Cnvrg::Logger.log_method(bind: binding)
273
+ raise Exception.new("Got an error message from server, #{resp.try(:fetch, "message")}")
274
+ end
275
+ return resp["total_changes"]
276
+ rescue => e
277
+ Cnvrg::Logger.log_method(bind: binding)
278
+ Cnvrg::Logger.log_error(e)
279
+ raise e
280
+ end
281
+ end
282
+
283
+ def get_delete_progress(commit_sha1, job_id)
284
+ begin
285
+ resp = Cnvrg::API.request(
286
+ @base_resource + "get_delete_progress",
287
+ 'POST_JSON',
288
+ {
289
+ commit_sha1: commit_sha1,
290
+ job_id: job_id
291
+ }
292
+ )
293
+ unless Cnvrg::CLI.is_response_success(resp, false)
294
+ Cnvrg::Logger.log_method(bind: binding)
295
+ raise Exception.new("Got an error message from server, #{resp.try(:fetch, "message")}")
296
+ end
297
+ return resp["total_deleted"]
298
+ rescue => e
299
+ Cnvrg::Logger.log_method(bind: binding)
300
+ Cnvrg::Logger.log_error(e)
301
+ raise e
302
+ end
303
+ end
304
+
305
+ def request_upload_files(commit_sha1, tree, force, new_branch, partial_commit)
306
+ retry_count = 0
307
+ loop do
308
+ upload_resp = Cnvrg::API.request(@base_resource + "upload_files", 'POST_JSON', {
309
+ commit_sha1: commit_sha1,
310
+ tree: tree,
311
+ force: force,
312
+ is_branch: new_branch,
313
+ partial_commit: partial_commit
314
+ })
315
+ if not (Cnvrg::CLI.is_response_success(upload_resp, false))
316
+ #Cnvrg::Logger.log_method(bind: binding)
317
+ retry_count += 1
318
+
319
+ puts "Failed request upload files: #{Time.current}"
320
+ puts upload_resp
321
+
322
+ if retry_count > 5
323
+ raise Exception.new("Got an error message from server, #{upload_resp.try(:fetch, "message")}")
324
+ end
325
+ sleep 5
326
+ next
327
+ end
328
+ return upload_resp['result'].with_indifferent_access
329
+ end
330
+
331
+ end
332
+
333
+ def upload_multiple_files_optimized(files, commit_sha1, threads: ParallelThreads, chunk_size: 1000, force: false, new_branch: false, prefix: '', partial_commit: nil)
334
+ cli = CLI.new
335
+ cli.log_message("Using #{threads} threads with chunk size of #{chunk_size}.", Thor::Shell::Color::GREEN)
336
+
337
+ progressbar = create_progressbar("Upload Progress", files.size)
338
+ cli = CLI.new
339
+
340
+ # Vars to handle the parallelism
341
+ progress_mutex = Mutex.new
342
+ file_queue = Queue.new
343
+ progress_queue = Queue.new
344
+ worker_threads = []
345
+
346
+ # Vars to keep track of uploaded files and directories
347
+ dirs = []
348
+ uploaded_files = []
349
+
350
+ begin
351
+ # Init working threads that handle the upload of the files:
352
+ threads.times do |i|
353
+ worker_threads[i] = Thread.new do
354
+ # wait for file_queue.close to break the loop
355
+ while file = file_queue.deq
356
+ success = upload_single_file(cli, file)
357
+ file[:success] = success
358
+ if not success
359
+ cli.log_message("Error while uploading file: #{file[:absolute_path]}", Thor::Shell::Color::RED)
360
+ Cnvrg::Logger.log_error_message("Error while upload single file #{file["path"]}")
361
+ end
362
+ progress_queue << file
363
+ end
364
+ end
365
+ end
366
+
367
+ # init the thread that handles the file upload progress and saving them in the server
368
+ progress_thread = Thread.new do
369
+ loop do
370
+ file = progress_queue.deq(non_block: true) rescue nil # to prevent deadlocks
371
+ unless file.nil?
372
+ progress_mutex.synchronize {
373
+ progressbar.progress += 1
374
+ uploaded_files.append(file) if file[:success]
375
+ }
376
+
377
+ if uploaded_files.size == chunk_size or progressbar.finished?
378
+ refresh_storage_token
379
+ # puts "progress: #{progress_queue.length}"
380
+ # puts "files: #{file_queue.length}"
381
+ Cnvrg::Logger.info("Sending Upload files save")
382
+ blob_ids = uploaded_files.map {|f| f['bv_id']}
383
+ upload_resp = Cnvrg::API.request(@base_resource + "upload_files_save", "POST", {commit: commit_sha1, blob_ids: blob_ids, dirs: dirs})
384
+ unless Cnvrg::CLI.is_response_success(upload_resp, false)
385
+ Cnvrg::Logger.log_method(bind: binding)
386
+ raise Exception.new("Got an error message from server, #{upload_resp.try(:fetch, "message")}")
387
+ end
388
+ # cli.log_message("Saved file chunk to server", Thor::Shell::Color::GREEN)
389
+ uploaded_files = []
390
+ dirs = []
391
+ end
392
+ else
393
+ sleep(0.1)
394
+ end
395
+
396
+ if progressbar.finished?
397
+ # puts "finished"
398
+ file_queue.close()
399
+ progress_queue.close()
400
+ Thread.exit
401
+ end
402
+ end
403
+ end
404
+
405
+ file_chunks = files.each_slice(chunk_size).to_a
406
+ # Fetch the required files from the server:
407
+ Parallel.map((file_chunks), in_threads: 10) do |files_chunk|
408
+
409
+ tree = @dataset.generate_chunked_idx(files_chunk, prefix: prefix)
410
+ results = request_upload_files(commit_sha1, tree, force, new_branch, partial_commit)
411
+
412
+ # puts "Got #{results['files'].size} files to upload from #{files_chunk.size} files"
413
+
414
+ if results['files'].blank?
415
+ progress_mutex.synchronize { progressbar.progress += tree.keys.length }
416
+ next
417
+ end
418
+
419
+ # Handle directories:
420
+ new_dirs = tree.keys.select {|k| tree[k].nil?}
421
+ dirs += new_dirs
422
+
423
+ files_to_upload = results['files']
424
+ progress_mutex.synchronize {
425
+ progressbar.progress += tree.keys.length - files_to_upload.length
426
+ }
427
+
428
+ files_to_upload.keys.each do |key|
429
+ while file_queue.size > 5000
430
+ sleep(0.1)
431
+ end
432
+ file_queue.push tree[key].merge(files_to_upload[key])
433
+ end
434
+ end
435
+
436
+ progress_thread.join()
437
+ worker_threads.each(&:join)
438
+
439
+ rescue => e
440
+ puts e
441
+ Cnvrg::Logger.log_method(bind: binding)
442
+ Cnvrg::Logger.log_error(e)
443
+ raise e
444
+ end
445
+ end
446
+
447
+ def upload_single_file(cli, file)
448
+ success = false
184
449
  begin
185
450
  file = file.as_json
186
451
  Cnvrg::Logger.log_info("Uploading #{file["absolute_path"]}")
187
452
  @downloader.safe_upload(file["path"], file["absolute_path"])
453
+ success = true
188
454
  Cnvrg::Logger.log_info("#{file["absolute_path"]} uploaded.")
189
455
  rescue => e
190
456
  Cnvrg::Logger.log_error_message("Error while upload single file #{file["path"]}")
191
457
  Cnvrg::Logger.log_error(e)
192
- return false
193
458
  end
459
+ success
194
460
  end
195
461
 
196
462
  def upload_file(absolute_path, relative_path, commit_sha1)
@@ -859,45 +1125,57 @@ module Cnvrg
859
1125
  return false
860
1126
  end
861
1127
  end
1128
+
862
1129
  def revoke_download(tar_files, extracted_files)
863
1130
  begin
864
-
865
1131
  FileUtils.rm_rf(tar_files) unless (tar_files.nil? or tar_files.empty?)
866
1132
  FileUtils.rm_rf(extracted_files) unless (extracted_files.nil? or extracted_files.empty?)
867
-
868
1133
  rescue => e
869
1134
  return false
870
1135
  end
871
-
872
1136
  return true
873
-
874
1137
  end
1138
+
875
1139
  def delete_commit(commit_sha1)
876
1140
  response = Cnvrg::API.request("#{base_resource}/commit/#{commit_sha1}", 'DELETE')
877
1141
  Cnvrg::CLI.is_response_success(response, true)
878
1142
  return response
879
1143
  end
1144
+
880
1145
  def get_commit(commit_sha1)
881
1146
  response = Cnvrg::API.request("#{base_resource}/commit/#{commit_sha1}", 'GET')
882
1147
  Cnvrg::CLI.is_response_success(response, true)
883
1148
  return response
884
1149
  end
885
1150
 
886
- def start_commit(new_branch,force=false,delete_commit=nil, chunks: 0, dataset: @dataset, message:nil)
1151
+ def start_commit(new_branch, force=false, chunks: 0, dataset: @dataset, message:nil)
887
1152
  begin
888
1153
  #if we are pushing with force or to branch we dont need to send current/next commit cause we want to
889
1154
  # create a new commit.
890
1155
  idx = (force || new_branch) ? {} : dataset.get_idx
891
1156
  commit = idx[:commit]
892
1157
  next_commit = idx[:next_commit]
893
- response = Cnvrg::API.request("#{base_resource}/commit/start", 'POST', {dataset_slug: @dataset_slug, new_branch: new_branch,force:force,
894
- username: @owner,current_commit: commit, next_commit: next_commit, total_chunks: chunks, message: message})
895
- Cnvrg::CLI.is_response_success(response, true)
896
- return response
1158
+ response = Cnvrg::API.request(
1159
+ "#{base_resource}/commit/start",
1160
+ 'POST',
1161
+ {
1162
+ dataset_slug: @dataset_slug,
1163
+ new_branch: new_branch,
1164
+ force:force,
1165
+ username: @owner,
1166
+ current_commit: commit,
1167
+ next_commit: next_commit,
1168
+ total_chunks: chunks,
1169
+ message: message
1170
+ }
1171
+ )
1172
+ Cnvrg::CLI.is_response_success(response, true)
1173
+ return response
897
1174
  rescue => e
898
1175
  return false
899
1176
  end
900
1177
  end
1178
+
901
1179
  def last_valid_commit()
902
1180
  begin
903
1181
  #if we are pushing with force or to branch we dont need to send current/next commit cause we want to
@@ -910,15 +1188,24 @@ module Cnvrg
910
1188
  end
911
1189
  end
912
1190
 
913
- def end_commit(commit_sha1,force, success: true, uploaded_files: 0 )
1191
+ def end_commit(commit_sha1, force, success: true, uploaded_files: 0, commit_type: nil)
914
1192
  begin
915
- response = Cnvrg::API.request("#{base_resource}/commit/end", 'POST', {commit_sha1: commit_sha1,force:force, success: success, uploaded_files: uploaded_files})
1193
+ response = Cnvrg::API.request(
1194
+ "#{base_resource}/commit/end",
1195
+ 'POST',
1196
+ {
1197
+ commit_sha1: commit_sha1,
1198
+ force:force,
1199
+ success: success,
1200
+ uploaded_files: uploaded_files,
1201
+ commit_type: commit_type
1202
+ }
1203
+ )
916
1204
  Cnvrg::CLI.is_response_success(response, true)
917
1205
  return response
918
1206
  rescue => e
919
1207
  return false
920
1208
  end
921
-
922
1209
  end
923
1210
 
924
1211
  def end_commit_tar(commit_sha1, cur_idx)
@@ -1001,34 +1288,43 @@ module Cnvrg
1001
1288
  end
1002
1289
  end
1003
1290
 
1004
- def generate_parallel_idx
1005
-
1291
+ def last_valid_commit()
1292
+ begin
1293
+ response = Cnvrg::API.request("#{base_resource}/last_valid_commit", 'GET')
1294
+ Cnvrg::CLI.is_response_success(response, true)
1295
+ return response
1296
+ rescue => e
1297
+ return false
1298
+ end
1006
1299
  end
1007
1300
 
1008
- def download_multiple_files_s3(files, project_home, conflict: false, progressbar: nil, read_only:false)
1301
+ def download_multiple_files_s3(files, project_home, conflict: false, progressbar: nil, read_only:false, flatten: false)
1009
1302
  begin
1303
+ refresh_storage_token
1010
1304
  parallel_options = {
1011
1305
  in_threads: ParallelThreads,
1012
1306
  isolation: true
1013
1307
  }
1014
1308
  Parallel.map(files["keys"], parallel_options) do |f|
1015
1309
  begin
1016
- local_path = @dataset.local_path + '/' + f['name']
1017
- Cnvrg::Logger.log_info("Downloading #{local_path}")
1018
- progressbar.progress += 1 if progressbar.present?
1019
- if local_path.end_with? "/"
1020
- @downloader.mkdir(local_path, recursive: true)
1021
- next
1022
- end
1023
- # blob
1024
- local_path = "#{local_path}.conflict" if conflict
1025
- storage_path = f["path"]
1026
- if File.exists? local_path
1027
- Cnvrg::Logger.log_info("Trying to download #{local_path} but its already exists, skipping..")
1028
- next
1029
- end
1030
- resp = @downloader.download(storage_path, local_path)
1031
- Cnvrg::Logger.log_info("Download #{local_path} success resp: #{resp}")
1310
+ file_path = f['name']
1311
+ file_path = File.basename(f['name']) if flatten
1312
+ local_path = @dataset.local_path + '/' + file_path
1313
+ Cnvrg::Logger.log_info("Downloading #{local_path}")
1314
+ progressbar.progress += 1 if progressbar.present?
1315
+ if local_path.end_with? "/"
1316
+ @downloader.mkdir(local_path, recursive: true)
1317
+ next
1318
+ end
1319
+ # blob
1320
+ local_path = "#{local_path}.conflict" if conflict
1321
+ storage_path = f["path"]
1322
+ if File.exists? local_path
1323
+ Cnvrg::Logger.log_info("Trying to download #{local_path} but its already exists, skipping..")
1324
+ next
1325
+ end
1326
+ resp = @downloader.download(storage_path, local_path)
1327
+ Cnvrg::Logger.log_info("Download #{local_path} success resp: #{resp}")
1032
1328
  rescue => e
1033
1329
  Cnvrg::Logger.log_error(e)
1034
1330
  end