cnvrg 1.4.8 → 1.4.9
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 +4 -4
- data/cnvrg.gemspec +1 -0
- data/lib/cnvrg/cli.rb +55 -16
- data/lib/cnvrg/cli/flow.rb +5 -13
- data/lib/cnvrg/data.rb +9 -4
- data/lib/cnvrg/dataset.rb +46 -2
- data/lib/cnvrg/downloader/clients/s3_client.rb +40 -4
- data/lib/cnvrg/flow.rb +20 -10
- data/lib/cnvrg/project.rb +1 -2
- data/lib/cnvrg/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8139db865f88ce341ad6bf2330c622f995cb2b8ef6d581e2c45f817bbbfad8a3
|
|
4
|
+
data.tar.gz: 8bee4a637a7d39bb38fd19a5bf68b9f0bee00fa39d7fac4d4293b9cf6750d477
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee28520a8afaeb9551e8ab8762f46bc1f0171450032d858e04b0b42f4223a2377c854d004ed9228db94938812bb4ac4f9f5d2a989e9243fb992a160fc867d5d9
|
|
7
|
+
data.tar.gz: 860fc186eb8828bfe450ba84670c0b7e3913ff0662d4cc266e15b692386f39881bfefded59b6844c6efd380fd8926baa8ccc116301a22997355056af50b9030d
|
data/cnvrg.gemspec
CHANGED
data/lib/cnvrg/cli.rb
CHANGED
|
@@ -488,14 +488,18 @@ module Cnvrg
|
|
|
488
488
|
job_type, job_id = ENV['CNVRG_JOB_TYPE'], ENV['CNVRG_JOB_ID']
|
|
489
489
|
machine_activity = @project.get_machine_activity
|
|
490
490
|
|
|
491
|
+
notify_thread = Thread.new do
|
|
492
|
+
res = @project.send_restart_request(job_type: job_type, job_id: job_id, ma_id: machine_activity)
|
|
493
|
+
while res.blank?
|
|
494
|
+
res = @project.send_restart_request(job_type: job_type, job_id: job_id, ma_id: machine_activity)
|
|
495
|
+
sleep(10)
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
491
499
|
sync_force = job_type == "NotebookSession" ? false : true
|
|
492
500
|
upload(false, false, true, '', true, sync_force , ENV['CNVRG_OUTPUT_DIR'], job_type, job_id)
|
|
493
501
|
log_message('Spot instance is going to be terminated', Thor::Shell::Color::YELLOW)
|
|
494
|
-
|
|
495
|
-
while res.blank?
|
|
496
|
-
res = @project.send_restart_request(job_type: job_type, job_id: job_id, ma_id: machine_activity)
|
|
497
|
-
sleep(10)
|
|
498
|
-
end
|
|
502
|
+
notify_thread.join
|
|
499
503
|
end
|
|
500
504
|
|
|
501
505
|
|
|
@@ -594,6 +598,20 @@ module Cnvrg
|
|
|
594
598
|
|
|
595
599
|
def me()
|
|
596
600
|
begin
|
|
601
|
+
|
|
602
|
+
home_dir = File.expand_path('~')
|
|
603
|
+
config = YAML.load_file(home_dir+"/.cnvrg/config.yml")
|
|
604
|
+
|
|
605
|
+
api = config[:api]
|
|
606
|
+
verify_ssl = config[:verify_ssl]
|
|
607
|
+
if api.present?
|
|
608
|
+
log_message("API: #{api}", Thor::Shell::Color::BLUE)
|
|
609
|
+
end
|
|
610
|
+
if verify_ssl.present?
|
|
611
|
+
log_message("SSL Verification: #{verify_ssl}", Thor::Shell::Color::BLUE)
|
|
612
|
+
end
|
|
613
|
+
log_message("Logs file located at: #{$LOG.device.io.path}", Thor::Shell::Color::BLUE)
|
|
614
|
+
|
|
597
615
|
verify_logged_in(false)
|
|
598
616
|
log_start(__method__, args, options)
|
|
599
617
|
auth = Cnvrg::Auth.new
|
|
@@ -610,6 +628,25 @@ module Cnvrg
|
|
|
610
628
|
end
|
|
611
629
|
end
|
|
612
630
|
|
|
631
|
+
desc 'logs', 'Prints cnvrg cli logs file to screen'
|
|
632
|
+
method_option :lines, :type => :numeric, :aliases => ["-l","-n","--lines"], :default => nil
|
|
633
|
+
def logs()
|
|
634
|
+
begin
|
|
635
|
+
lines = options["lines"]
|
|
636
|
+
if lines.present?
|
|
637
|
+
puts open($LOG.device.io.path).readlines.last(lines)
|
|
638
|
+
else
|
|
639
|
+
puts open($LOG.device.io.path).readlines.last(100)
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
rescue SignalException
|
|
644
|
+
say "\nAborting", Thor::Shell::Color::RED
|
|
645
|
+
exit(1)
|
|
646
|
+
end
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
|
|
613
650
|
## Projects
|
|
614
651
|
desc 'new', 'Create a new cnvrg project'
|
|
615
652
|
method_option :clean, :type => :boolean, :aliases => ["-c"], :default => false
|
|
@@ -836,23 +873,22 @@ module Cnvrg
|
|
|
836
873
|
project_index = Cnvrg::Helpers.look_for_in_path(dataset_url, "datasets")
|
|
837
874
|
slug = url_parts[project_index + 1]
|
|
838
875
|
owner = url_parts[project_index - 1]
|
|
839
|
-
|
|
840
|
-
|
|
876
|
+
@dataset = Dataset.new(dataset_url: dataset_url)
|
|
877
|
+
response = {}
|
|
878
|
+
response["result"] = @dataset.get_dataset(commit: commit, query: query)
|
|
841
879
|
dataset_name = response["result"]["name"]
|
|
842
880
|
dataset_home = Dir.pwd+"/"+dataset_name
|
|
843
|
-
if !remote and (Dir.exists? dataset_name)
|
|
844
|
-
log_message("Error: Conflict with dir #{dataset_name}", Thor::Shell::Color::RED)
|
|
845
|
-
if no? "Sync to repository anyway? (current data might lost)", Thor::Shell::Color::YELLOW
|
|
846
|
-
log_message("Remove dir in order to clone #{dataset_name}", Thor::Shell::Color::RED)
|
|
847
|
-
exit(1)
|
|
848
|
-
end
|
|
849
|
-
end
|
|
850
881
|
check = Helpers.checkmark
|
|
851
|
-
if
|
|
882
|
+
if @dataset.init_home
|
|
852
883
|
log_message("Cloning #{dataset_name}", Thor::Shell::Color::BLUE)
|
|
853
|
-
@files = Cnvrg::Datafiles.new(owner, slug, dataset:
|
|
884
|
+
@files = Cnvrg::Datafiles.new(owner, slug, dataset: @dataset)
|
|
854
885
|
log_message("Downloading files", Thor::Shell::Color::BLUE)
|
|
886
|
+
if @dataset.softlinked?
|
|
887
|
+
return @dataset.download_softlink
|
|
888
|
+
end
|
|
889
|
+
|
|
855
890
|
if only_tree
|
|
891
|
+
|
|
856
892
|
success = Dataset.clone_tree(commit: commit, dataset_home: dataset_home)
|
|
857
893
|
return if success
|
|
858
894
|
end
|
|
@@ -888,6 +924,9 @@ module Cnvrg
|
|
|
888
924
|
log_message("Error: Couldn't create directory: #{dataset_name}", Thor::Shell::Color::RED)
|
|
889
925
|
exit(1)
|
|
890
926
|
end
|
|
927
|
+
rescue Interrupt
|
|
928
|
+
say "\nAborting", Thor::Shell::Color::RED
|
|
929
|
+
exit(1)
|
|
891
930
|
rescue SignalException
|
|
892
931
|
say "\nAborting", Thor::Shell::Color::RED
|
|
893
932
|
exit(1)
|
data/lib/cnvrg/cli/flow.rb
CHANGED
|
@@ -34,23 +34,15 @@ module Cnvrg
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
desc "flow run", "run a flow file"
|
|
37
|
-
|
|
38
|
-
def run(path)
|
|
37
|
+
def run(flow_slug)
|
|
39
38
|
unless @curr_dir.present?
|
|
40
39
|
@cli.log_message("Cant run this command because you are not in project directory", Thor::Color::RED)
|
|
41
40
|
return false
|
|
42
41
|
end
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
rescue => e
|
|
48
|
-
@cli.log_message("Cant run the flow, please run 'cnvrg flow verify #{path}' to check it", Thor::Color::RED)
|
|
49
|
-
@cli.log_error(e)
|
|
50
|
-
return
|
|
51
|
-
end
|
|
52
|
-
check = Cnvrg::Helpers.checkmark
|
|
53
|
-
@cli.log_message("#{check} The flow is running, you can track the status in: #{url}", Thor::Color::GREEN)
|
|
42
|
+
@flow = Cnvrg::Flows.new(flow_slug)
|
|
43
|
+
resp = @flow.run
|
|
44
|
+
flow_version_href = resp["flow_version"]["href"]
|
|
45
|
+
Cnvrg::CLI.log_message("Flow Live results: #{flow_version_href}")
|
|
54
46
|
true
|
|
55
47
|
end
|
|
56
48
|
|
data/lib/cnvrg/data.rb
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require 'thread/pool'
|
|
2
|
+
require 'thread/future'
|
|
3
|
+
|
|
1
4
|
class SubCommandBase < Thor
|
|
2
5
|
def self.banner(command, namespace = nil, subcommand = false)
|
|
3
6
|
"#{basename} #{command.usage}"
|
|
@@ -188,14 +191,16 @@ module Cnvrg
|
|
|
188
191
|
end
|
|
189
192
|
|
|
190
193
|
|
|
191
|
-
desc 'data
|
|
192
|
-
def test
|
|
194
|
+
desc 'data test', 'test client'
|
|
195
|
+
def test(data_url)
|
|
193
196
|
cli = Cnvrg::CLI.new
|
|
194
197
|
cli.verify_logged_in(true)
|
|
195
198
|
cli.log_start(__method__, args, options)
|
|
196
|
-
|
|
197
|
-
@dataset = Project.new(dataset_dir)
|
|
199
|
+
@dataset = Dataset.new(dataset_url: data_url)
|
|
198
200
|
resp = @dataset.get_storage_client
|
|
201
|
+
@dataset.init_home(remote: false)
|
|
202
|
+
@dataset.download_softlink
|
|
203
|
+
|
|
199
204
|
end
|
|
200
205
|
|
|
201
206
|
end
|
data/lib/cnvrg/dataset.rb
CHANGED
|
@@ -28,6 +28,52 @@ module Cnvrg
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
def init_home(remote: false)
|
|
32
|
+
dataset_home = Dir.pwd+"/"+@slug
|
|
33
|
+
if !remote and (Dir.exists? dataset_home)
|
|
34
|
+
Cnvrg::CLI.log_message("Error: Conflict with dir #{@slug}", Thor::Shell::Color::RED)
|
|
35
|
+
if Thor::Shell::Basic.new.no? "Sync to repository anyway? (current data might lost)", Thor::Shell::Color::YELLOW
|
|
36
|
+
Cnvrg::CLI.log_message("Remove dir in order to clone #{@slug}", Thor::Shell::Color::RED)
|
|
37
|
+
exit(1)
|
|
38
|
+
end
|
|
39
|
+
FileUtils.rm_rf(dataset_home)
|
|
40
|
+
end
|
|
41
|
+
# if Dataset.clone(owner, dataset_name, slug, remote)
|
|
42
|
+
Dataset.clone(@owner, @slug, @slug, remote)
|
|
43
|
+
@local_path = dataset_home
|
|
44
|
+
Cnvrg::CLI.log_message('')
|
|
45
|
+
true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def get_dataset(commit: nil, query: nil)
|
|
49
|
+
if @dataset_call
|
|
50
|
+
return @dataset_call
|
|
51
|
+
end
|
|
52
|
+
response = Cnvrg::API.request("users/#{owner}/datasets/#{slug}/clone", 'POST',{ commit: commit, query:query})
|
|
53
|
+
Cnvrg::CLI.is_response_success(response,true)
|
|
54
|
+
@dataset_call = response["result"]
|
|
55
|
+
@dataset_call
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def softlinked?
|
|
59
|
+
get_dataset["dataset_type"] == "soft_link_dataset"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def download_softlink
|
|
64
|
+
@storage = self.get_storage_client
|
|
65
|
+
@progressbar = ProgressBar.create(:title => "Download Progress",
|
|
66
|
+
:progress_mark => '=',
|
|
67
|
+
:format => "%b%i| %c Files downloaded",
|
|
68
|
+
:starting_at => 0,
|
|
69
|
+
:total => nil,
|
|
70
|
+
:autofinish => true)
|
|
71
|
+
@storage.cp(get_dataset["bucket_prefix"], @local_path, progress: @progressbar)
|
|
72
|
+
@progressbar.finish
|
|
73
|
+
Cnvrg::CLI.log_message("#{Cnvrg::Helpers.checkmark} Clone finished successfully", Thor::Shell::Color::GREEN)
|
|
74
|
+
write_success
|
|
75
|
+
end
|
|
76
|
+
|
|
31
77
|
|
|
32
78
|
def get_storage_client
|
|
33
79
|
response = Cnvrg::API.request("users/#{@owner}/datasets/#{@slug}/client", 'GET')
|
|
@@ -754,8 +800,6 @@ module Cnvrg
|
|
|
754
800
|
FileUtils.rm_rf working_dir
|
|
755
801
|
# response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/revert", 'GET')
|
|
756
802
|
# CLI.is_response_success(response)
|
|
757
|
-
|
|
758
|
-
|
|
759
803
|
end
|
|
760
804
|
|
|
761
805
|
end
|
|
@@ -34,15 +34,17 @@ module Cnvrg
|
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def download(storage_path, local_path)
|
|
37
|
+
def download(storage_path, local_path, decrypt: true)
|
|
38
38
|
prepare_download(local_path)
|
|
39
|
-
storage_path = Cnvrg::Helpers.decrypt(@key, @iv, storage_path)
|
|
39
|
+
storage_path = Cnvrg::Helpers.decrypt(@key, @iv, storage_path) if decrypt
|
|
40
40
|
resp = nil
|
|
41
41
|
File.open(local_path, 'w+') do |file|
|
|
42
|
-
resp = @client.get_object({bucket: @bucket_name,
|
|
43
|
-
key: storage_path}, target: file)
|
|
42
|
+
resp = @client.get_object({bucket: @bucket_name, key: storage_path}, target: file)
|
|
44
43
|
end
|
|
45
44
|
resp
|
|
45
|
+
rescue => e
|
|
46
|
+
p e.message
|
|
47
|
+
p e.backtrace
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
def upload(storage_path, local_path)
|
|
@@ -51,6 +53,40 @@ module Cnvrg
|
|
|
51
53
|
o = @bucket.object(storage_path)
|
|
52
54
|
o.upload_file(local_path, @upload_options)
|
|
53
55
|
end
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def cp(prefix, local_path, progress: nil)
|
|
59
|
+
files = []
|
|
60
|
+
files_thread = Thread.new do
|
|
61
|
+
current_marker = nil
|
|
62
|
+
while true
|
|
63
|
+
batch_files = @bucket.objects(prefix: prefix, marker: current_marker).first(500)
|
|
64
|
+
batch_files = batch_files.to_a
|
|
65
|
+
break if batch_files.size === 0
|
|
66
|
+
files += batch_files
|
|
67
|
+
current_marker = batch_files.last.key
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
thread_pool = Thread.pool(Cnvrg::Helpers.parallel_threads)
|
|
71
|
+
while true
|
|
72
|
+
while files.present?
|
|
73
|
+
Thread.future thread_pool do
|
|
74
|
+
f = files.pop
|
|
75
|
+
cutted_key = cut_prefix(prefix, f.key)
|
|
76
|
+
dest_path = File.join(local_path, cutted_key)
|
|
77
|
+
download(f.key, dest_path, decrypt: false)
|
|
78
|
+
progress.increment
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
break if files.size == 0 and files_thread.status == false
|
|
82
|
+
sleep(1)
|
|
83
|
+
end
|
|
84
|
+
thread_pool.wait(:done)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def cut_prefix(prefix, file)
|
|
88
|
+
file.gsub(prefix, '').gsub(/^\/*/, '')
|
|
89
|
+
end
|
|
54
90
|
end
|
|
55
91
|
end
|
|
56
92
|
end
|
data/lib/cnvrg/flow.rb
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
module Cnvrg
|
|
2
2
|
class Flows
|
|
3
|
-
def initialize(
|
|
4
|
-
@project = Cnvrg::Project.new(
|
|
5
|
-
@
|
|
3
|
+
def initialize(flow_slug)
|
|
4
|
+
@project = Cnvrg::Project.new(Cnvrg::CLI.get_project_home)
|
|
5
|
+
@flow_slug = flow_slug
|
|
6
6
|
@tasks = {}
|
|
7
7
|
@relations = {}
|
|
8
8
|
@title = nil
|
|
9
9
|
@slug = nil
|
|
10
10
|
@base_resource = @project.base_resource + "flows"
|
|
11
11
|
|
|
12
|
-
self.reload_flow
|
|
12
|
+
# self.reload_flow
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def self.create_flow(path, flow)
|
|
@@ -50,15 +50,25 @@ module Cnvrg
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
|
|
53
54
|
def run
|
|
54
|
-
resp = Cnvrg::API.request(@base_resource, 'POST'
|
|
55
|
-
Cnvrg::CLI.is_response_success(resp
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return url
|
|
55
|
+
resp = Cnvrg::API.request("#{@base_resource}/#{@flow_slug}/run", 'POST')
|
|
56
|
+
if Cnvrg::CLI.is_response_success(resp)
|
|
57
|
+
return resp
|
|
58
|
+
end
|
|
59
|
+
Cnvrg::CLI.log_message("Cant run flow #{@flow_slug}")
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
### in use for yaml file
|
|
63
|
+
# def run
|
|
64
|
+
# resp = Cnvrg::API.request(@base_resource, 'POST', {data: to_api})
|
|
65
|
+
# Cnvrg::CLI.is_response_success(resp, true)
|
|
66
|
+
# flow_slug = resp['result']['flow']
|
|
67
|
+
# self.set_flow_slug(flow_slug)
|
|
68
|
+
# url = Cnvrg::Helpers.remote_url + resp['result']['url']
|
|
69
|
+
# return url
|
|
70
|
+
# end
|
|
71
|
+
|
|
62
72
|
|
|
63
73
|
private
|
|
64
74
|
def to_api
|
data/lib/cnvrg/project.rb
CHANGED
data/lib/cnvrg/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cnvrg
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.4.
|
|
4
|
+
version: 1.4.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yochay Ettun
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2019-
|
|
13
|
+
date: 2019-06-25 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: bundler
|
|
@@ -372,6 +372,20 @@ dependencies:
|
|
|
372
372
|
- - ">="
|
|
373
373
|
- !ruby/object:Gem::Version
|
|
374
374
|
version: '0'
|
|
375
|
+
- !ruby/object:Gem::Dependency
|
|
376
|
+
name: thread
|
|
377
|
+
requirement: !ruby/object:Gem::Requirement
|
|
378
|
+
requirements:
|
|
379
|
+
- - ">="
|
|
380
|
+
- !ruby/object:Gem::Version
|
|
381
|
+
version: '0'
|
|
382
|
+
type: :runtime
|
|
383
|
+
prerelease: false
|
|
384
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
385
|
+
requirements:
|
|
386
|
+
- - ">="
|
|
387
|
+
- !ruby/object:Gem::Version
|
|
388
|
+
version: '0'
|
|
375
389
|
description: A CLI tool for interacting with cnvrg.io.
|
|
376
390
|
email:
|
|
377
391
|
- info@cnvrg.io
|