cnvrg 0.0.11 → 0.0.14
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 +4 -0
- data/lib/cnvrg.rb +1 -2
- data/lib/cnvrg/Images.rb +347 -0
- data/lib/cnvrg/api.rb +5 -2
- data/lib/cnvrg/cli.rb +2860 -967
- data/lib/cnvrg/experiment.rb +101 -32
- data/lib/cnvrg/files.rb +155 -17
- data/lib/cnvrg/helpers.rb +2 -0
- data/lib/cnvrg/project.rb +279 -205
- data/lib/cnvrg/version.rb +1 -1
- metadata +46 -2
data/lib/cnvrg/experiment.rb
CHANGED
@@ -1,35 +1,104 @@
|
|
1
1
|
module Cnvrg
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
2
|
+
class Experiment
|
3
|
+
attr_reader :slug
|
4
|
+
|
5
|
+
def initialize(owner, project_slug)
|
6
|
+
@project_slug = project_slug
|
7
|
+
@owner = owner
|
8
|
+
@base_resource = "users/#{owner}/projects/#{project_slug}/"
|
9
|
+
@slug = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def start(input, platform, machine_name, start_commit, name, email_notification, machine_activity)
|
13
|
+
res = Cnvrg::API.request(@base_resource + "experiment/start", 'POST',
|
14
|
+
{input: input, platform: platform, machine_name: machine_name, start_commit: start_commit,
|
15
|
+
title: name, email_notification: email_notification, machine_activity: machine_activity})
|
16
|
+
Cnvrg::CLI.is_response_success(res)
|
17
|
+
|
18
|
+
@slug = res.to_h["result"].to_h["slug"]
|
19
|
+
|
20
|
+
return res
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def start_notebook_session(kernel, start_commit, token, port, remote, notebook_path)
|
25
|
+
res = Cnvrg::API.request(@base_resource + "notebook/start_session", 'POST',
|
26
|
+
{kernel: kernel, start_commit: start_commit,
|
27
|
+
token: token, port: port, remote: remote, notebook_path: notebook_path})
|
28
|
+
Cnvrg::CLI.is_response_success(res)
|
29
|
+
|
30
|
+
@slug = res["result"]["id"]
|
31
|
+
|
32
|
+
|
33
|
+
return @slug
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def end_notebook_session(notebook_slug, end_commit)
|
38
|
+
res = Cnvrg::API.request(@base_resource + "notebook/end_session", 'POST',
|
39
|
+
{notebook_slug: notebook_slug, end_commit: end_commit})
|
40
|
+
Cnvrg::CLI.is_response_success(res)
|
41
|
+
|
42
|
+
return res
|
43
|
+
|
44
|
+
end
|
45
|
+
def update_notebook_slug(proj_dir, slug)
|
46
|
+
begin
|
47
|
+
file = proj_dir+"/.cnvrg/notebook_slug"
|
48
|
+
FileUtils.touch file
|
49
|
+
|
50
|
+
File.open(file, "w+") { |f| f.write slug }
|
51
|
+
rescue
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_notebook_slug(proj_dir)
|
57
|
+
begin
|
58
|
+
notebook_slug = File.open(proj_dir + "/.cnvrg/notebook_slug", "rb").read
|
59
|
+
notebook_slug = notebook_slug.gsub("/n", "")
|
60
|
+
notebook_slug = notebook_slug.to_s.strip
|
61
|
+
return notebook_slug
|
62
|
+
rescue
|
63
|
+
return nil
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
end
|
68
|
+
def get_machine_activity(working_dir)
|
69
|
+
begin
|
70
|
+
machine_activity = File.open("/home/ds/notebooks/.cnvrg/machine_activity", "rb").read
|
71
|
+
machine_activity = machine_activity.to_s.strip
|
72
|
+
ma_id = machine_activity.to_i
|
73
|
+
return ma_id
|
74
|
+
rescue
|
75
|
+
return nil
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
def exec_remote(command, commit_to_run, instance_type, image_slug,scheduling_query,local_timestamp)
|
82
|
+
response = Cnvrg::API.request("users/#{@owner}/projects/#{@project_slug}/experiment/remote", 'POST', {command: command, image_slug: image_slug,
|
83
|
+
commit_sha1: commit_to_run,
|
84
|
+
instance_type: instance_type,
|
85
|
+
scheduling_query:scheduling_query,
|
86
|
+
local_timestamp:local_timestamp})
|
87
|
+
return response
|
88
|
+
end
|
89
|
+
|
90
|
+
def upload_temp_log(temp_log, cpu_average, memory_average)
|
91
|
+
response = Cnvrg::API.request(@base_resource + "experiment/upload_temp_log", 'POST', {output: temp_log,
|
92
|
+
exp_slug: @slug, cpu_average: cpu_average,
|
93
|
+
memory_average: memory_average})
|
94
|
+
Cnvrg::CLI.is_response_success(response)
|
95
|
+
end
|
96
|
+
|
97
|
+
def end(output, exit_status, end_commit, cpu_average, memory_average)
|
98
|
+
response = Cnvrg::API.request(@base_resource + "experiment/end", 'POST', {output: output, exp_slug: @slug,
|
99
|
+
exit_status: exit_status, end_commit: end_commit,
|
100
|
+
cpu_average: cpu_average, memory_average: memory_average})
|
101
|
+
Cnvrg::CLI.is_response_success(response)
|
34
102
|
end
|
103
|
+
end
|
35
104
|
end
|
data/lib/cnvrg/files.rb
CHANGED
@@ -54,22 +54,72 @@ module Cnvrg
|
|
54
54
|
return false
|
55
55
|
|
56
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
|
57
83
|
|
58
|
-
|
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)
|
59
93
|
file_name = File.basename absolute_path
|
60
94
|
file_size = File.size(absolute_path).to_f
|
61
|
-
|
95
|
+
if is_base
|
62
96
|
|
97
|
+
content_type = "application/zip"
|
98
|
+
else
|
99
|
+
content_type = "application/gzip"
|
100
|
+
end
|
101
|
+
begin
|
63
102
|
upload_resp = Cnvrg::API.request("users/#{owner}/images/" + "upload", 'POST_FILE', {relative_path: absolute_path,
|
64
|
-
|
65
|
-
|
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
|
+
libraries: libraries,
|
112
|
+
bash_history: bash,
|
113
|
+
commit_message:message,
|
114
|
+
is_base: is_base})
|
66
115
|
# puts upload_resp
|
67
116
|
if Cnvrg::CLI.is_response_success(upload_resp, false)
|
68
|
-
|
117
|
+
path = upload_resp["result"]["path"]
|
118
|
+
s3_res = upload_small_files_s3(path, absolute_path, content_type)
|
69
119
|
if s3_res
|
70
120
|
commit_resp = Cnvrg::API.request("users/#{owner}/images/#{upload_resp["result"]["id"]}/" + "commit", 'GET')
|
71
121
|
if Cnvrg::CLI.is_response_success(commit_resp, false)
|
72
|
-
return
|
122
|
+
return commit_resp["result"]["image"]
|
73
123
|
else
|
74
124
|
return false
|
75
125
|
end
|
@@ -77,6 +127,51 @@ module Cnvrg
|
|
77
127
|
end
|
78
128
|
end
|
79
129
|
return false
|
130
|
+
rescue =>e
|
131
|
+
puts e
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
def upload_cnvrg_image(absolute_path, image_name, owner, is_public, is_base,dpkg,libraries,bash,message)
|
136
|
+
file_name = File.basename absolute_path
|
137
|
+
file_size = File.size(absolute_path).to_f
|
138
|
+
if is_base
|
139
|
+
|
140
|
+
content_type = "application/zip"
|
141
|
+
else
|
142
|
+
content_type = "application/gzip"
|
143
|
+
end
|
144
|
+
begin
|
145
|
+
upload_resp = Cnvrg::API.request("users/#{owner}/images/" + "upload_cnvrg", 'POST_FILE', {relative_path: absolute_path,
|
146
|
+
file_name: file_name,
|
147
|
+
image_name: image_name,
|
148
|
+
file_size: file_size,
|
149
|
+
file_content_type: content_type,
|
150
|
+
is_public: is_public,
|
151
|
+
dpkg: dpkg,
|
152
|
+
libraries: libraries,
|
153
|
+
bash_history: bash,
|
154
|
+
commit_message:message,
|
155
|
+
is_base: is_base})
|
156
|
+
# puts upload_resp
|
157
|
+
if Cnvrg::CLI.is_response_success(upload_resp, false)
|
158
|
+
path = upload_resp["result"]["path"]
|
159
|
+
s3_res = upload_small_files_s3(path, absolute_path, content_type)
|
160
|
+
if s3_res
|
161
|
+
commit_resp = Cnvrg::API.request("users/#{owner}/images/#{upload_resp["result"]["id"]}/" + "commit", 'GET')
|
162
|
+
if Cnvrg::CLI.is_response_success(commit_resp, false)
|
163
|
+
return commit_resp["result"]["image"]
|
164
|
+
else
|
165
|
+
return false
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
170
|
+
return false
|
171
|
+
rescue =>e
|
172
|
+
puts e
|
173
|
+
end
|
174
|
+
|
80
175
|
end
|
81
176
|
|
82
177
|
def download_image(file_path_to_store, image_slug, owner)
|
@@ -86,15 +181,18 @@ module Cnvrg
|
|
86
181
|
path = download_resp["result"]["path"]
|
87
182
|
|
88
183
|
if Cnvrg::CLI.is_response_success(download_resp, false)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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
|
+
puts e
|
192
|
+
return false
|
193
|
+
end
|
194
|
+
|
195
|
+
return true
|
98
196
|
else
|
99
197
|
return false
|
100
198
|
end
|
@@ -109,6 +207,7 @@ module Cnvrg
|
|
109
207
|
http_object = Net::HTTP.new(uri.host, uri.port)
|
110
208
|
http_object.use_ssl = true if uri.scheme == 'https'
|
111
209
|
request = Net::HTTP::Get.new(sts_path)
|
210
|
+
|
112
211
|
body = ""
|
113
212
|
http_object.start do |http|
|
114
213
|
response = http.request request
|
@@ -175,7 +274,46 @@ module Cnvrg
|
|
175
274
|
response = Cnvrg::API.request(@base_resource + "create_dir", 'POST', {absolute_path: absolute_path, relative_path: relative_path, commit_sha1: commit_sha1})
|
176
275
|
return Cnvrg::CLI.is_response_success(response, false)
|
177
276
|
end
|
277
|
+
def download_file_s3(absolute_path, relative_path, project_home, conflict=false)
|
278
|
+
begin
|
279
|
+
res = Cnvrg::API.request(@base_resource + "download_file", 'POST', {absolute_path: absolute_path, relative_path: relative_path})
|
280
|
+
Cnvrg::CLI.is_response_success(res, false)
|
281
|
+
if res["result"]
|
282
|
+
download_resp = res
|
283
|
+
filename = download_resp["result"]["filename"]
|
284
|
+
|
285
|
+
absolute_path += ".conflict" if conflict
|
286
|
+
sts_path = download_resp["result"]["path_sts"]
|
287
|
+
uri = URI.parse(sts_path)
|
288
|
+
http_object = Net::HTTP.new(uri.host, uri.port)
|
289
|
+
http_object.use_ssl = true if uri.scheme == 'https'
|
290
|
+
request = Net::HTTP::Get.new(sts_path)
|
178
291
|
|
292
|
+
body = ""
|
293
|
+
http_object.start do |http|
|
294
|
+
response = http.request request
|
295
|
+
body = response.read_body
|
296
|
+
end
|
297
|
+
URLcrypt::key = [body].pack('H*')
|
298
|
+
s3 = Aws::S3::Client.new(
|
299
|
+
:access_key_id => URLcrypt.decrypt(download_resp["result"]["sts_a"]),
|
300
|
+
:secret_access_key => URLcrypt.decrypt(download_resp["result"]["sts_s"]),
|
301
|
+
:session_token => URLcrypt.decrypt(download_resp["result"]["sts_st"]),
|
302
|
+
:region => URLcrypt.decrypt(download_resp["result"]["region"]))
|
303
|
+
|
304
|
+
File.open(absolute_path, 'wb') do |file|
|
305
|
+
resp = s3.get_object({ bucket:URLcrypt.decrypt(download_resp["result"]["bucket"]),
|
306
|
+
key:URLcrypt.decrypt(download_resp["result"]["key"])}, target: file)
|
307
|
+
end
|
308
|
+
return true
|
309
|
+
end
|
310
|
+
|
311
|
+
rescue =>e
|
312
|
+
puts e
|
313
|
+
return false
|
314
|
+
|
315
|
+
end
|
316
|
+
end
|
179
317
|
def download_file(absolute_path, relative_path, project_home, conflict=false)
|
180
318
|
res = Cnvrg::API.request(@base_resource + "download_file", 'POST', {absolute_path: absolute_path, relative_path: relative_path})
|
181
319
|
Cnvrg::CLI.is_response_success(res, false)
|
@@ -216,9 +354,9 @@ module Cnvrg
|
|
216
354
|
end
|
217
355
|
end
|
218
356
|
|
219
|
-
def start_commit
|
357
|
+
def start_commit(new_branch)
|
220
358
|
|
221
|
-
response = Cnvrg::API.request("#{base_resource}/commit/start", 'POST', {project_slug: @project_slug,
|
359
|
+
response = Cnvrg::API.request("#{base_resource}/commit/start", 'POST', {project_slug: @project_slug,new_branch:new_branch,
|
222
360
|
username: @owner})
|
223
361
|
Cnvrg::CLI.is_response_success(response)
|
224
362
|
return response
|
data/lib/cnvrg/helpers.rb
CHANGED
data/lib/cnvrg/project.rb
CHANGED
@@ -1,238 +1,312 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
|
3
2
|
module Cnvrg
|
4
|
-
|
5
|
-
|
3
|
+
class Project
|
4
|
+
attr_reader :slug, :owner, :title, :local_path
|
6
5
|
|
7
|
-
|
6
|
+
RemoteURL ||= "https://cnvrg.io"
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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[:project_name]
|
13
|
+
@slug = config[:project_slug]
|
14
|
+
@owner = config[:owner]
|
15
|
+
rescue => e
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def last_local_commit
|
22
|
+
idx = YAML.load_file(@local_path + "/.cnvrg/idx.yml")
|
23
|
+
return idx[:commit]
|
24
|
+
end
|
25
|
+
|
26
|
+
def url
|
27
|
+
url = Cnvrg::Helpers.remote_url
|
28
|
+
"#{url}/#{self.owner}/projects/#{self.slug}"
|
29
|
+
end
|
16
30
|
|
31
|
+
def update_ignore_list(new_ignore)
|
32
|
+
if new_ignore.empty?
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
begin
|
36
|
+
File.open(self.local_path+"/.cnvrgignore", "a+") do |f|
|
37
|
+
new_ignore.each do |i|
|
38
|
+
f.puts("#{i}\n")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
return true
|
42
|
+
rescue
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
end
|
17
46
|
|
18
|
-
|
19
|
-
|
20
|
-
|
47
|
+
def get_ignore_list
|
48
|
+
ignore_list = []
|
49
|
+
File.open(self.local_path+"/.cnvrgignore", "r").each_line do |line|
|
50
|
+
line = line.strip
|
51
|
+
if line.start_with? "#"
|
52
|
+
next
|
21
53
|
end
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
54
|
+
if line.end_with? "/"
|
55
|
+
ignore_list << line.chop
|
56
|
+
sub_dirs = Dir.glob("#{line}/**/*").each { |x| x.gsub!("//", "/") }
|
57
|
+
ignore_list << sub_dirs.flatten
|
58
|
+
else
|
59
|
+
ignore_list << line
|
26
60
|
end
|
61
|
+
end
|
62
|
+
return ignore_list.flatten
|
27
63
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
64
|
+
end
|
65
|
+
|
66
|
+
# Create project
|
67
|
+
|
68
|
+
def self.create(project_name, clean, with_docker=false)
|
69
|
+
if clean
|
70
|
+
list_dirs = [project_name, project_name + "/.cnvrg"]
|
71
|
+
else
|
72
|
+
|
73
|
+
list_dirs = [project_name,
|
74
|
+
project_name + "/data",
|
75
|
+
project_name + "/models",
|
76
|
+
project_name + "/notebooks",
|
77
|
+
project_name + "/src",
|
78
|
+
project_name + "/src/visualizations",
|
79
|
+
project_name + "/src/features",
|
80
|
+
project_name + "/.cnvrg"
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
list_files = [
|
86
|
+
project_name + "/README.md",
|
87
|
+
project_name + "/.cnvrgignore",
|
88
|
+
project_name + "/.cnvrg/config.yml"
|
89
|
+
]
|
90
|
+
cnvrgreadme = Helpers.readme_content
|
91
|
+
cnvrgignore = Helpers.cnvrgignore_content
|
92
|
+
|
93
|
+
begin
|
94
|
+
|
95
|
+
owner = Cnvrg::CLI.get_owner()
|
96
|
+
response = Cnvrg::API.request("cli/create_project", 'POST', {title: project_name, owner: owner, is_docker: with_docker})
|
97
|
+
Cnvrg::CLI.is_response_success(response)
|
98
|
+
response = JSON.parse response["result"]
|
99
|
+
project_slug = response["slug"]
|
100
|
+
|
101
|
+
config = {project_name: project_name,
|
102
|
+
project_slug: project_slug,
|
103
|
+
owner: owner,
|
104
|
+
docker: with_docker}
|
105
|
+
FileUtils.mkdir_p list_dirs
|
106
|
+
FileUtils.touch list_files
|
107
|
+
|
108
|
+
File.open(project_name + "/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
109
|
+
File.open(project_name + "/.cnvrgignore", "w+") { |f| f.write cnvrgignore }
|
110
|
+
File.open(project_name + "/README.md", "w+") { |f| f.write cnvrgreadme }
|
111
|
+
rescue
|
112
|
+
return false
|
113
|
+
end
|
114
|
+
return true
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.link(owner, project_name, path=nil, docker=false)
|
118
|
+
list_dirs = [".cnvrg"
|
119
|
+
]
|
120
|
+
list_files = [
|
121
|
+
".cnvrgignore",
|
122
|
+
".cnvrg/config.yml"
|
123
|
+
]
|
124
|
+
|
125
|
+
cnvrgreadme = Helpers.readme_content
|
126
|
+
cnvrgignore = Helpers.cnvrgignore_content
|
127
|
+
begin
|
128
|
+
response = Cnvrg::API.request("cli/create_project", 'POST', {title: project_name, owner: owner, is_docker: docker})
|
129
|
+
Cnvrg::CLI.is_response_success(response)
|
130
|
+
response = JSON.parse response["result"]
|
131
|
+
project_slug = response["slug"]
|
132
|
+
|
133
|
+
config = {project_name: project_name,
|
134
|
+
project_slug: project_slug,
|
135
|
+
owner: owner}
|
136
|
+
FileUtils.mkdir_p list_dirs
|
137
|
+
FileUtils.touch list_files
|
138
|
+
File.open(".cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
139
|
+
File.open(".cnvrgignore", "w+") { |f| f.write cnvrgignore }
|
140
|
+
if !File.exist? "README" and !File.exist? "README.md"
|
141
|
+
FileUtils.touch [ "README.md" ]
|
142
|
+
File.open("README.md", "w+") { |f| f.write cnvrgreadme }
|
143
|
+
end
|
144
|
+
|
145
|
+
rescue => e
|
146
|
+
puts e
|
147
|
+
return false
|
42
148
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
if line.end_with? "/"
|
51
|
-
ignore_list << line.chop
|
52
|
-
sub_dirs = Dir.glob("#{line}/**/*").each{ |x| x.gsub!("//","/") }
|
53
|
-
ignore_list << sub_dirs.flatten
|
54
|
-
else
|
55
|
-
ignore_list << line
|
56
|
-
end
|
57
|
-
end
|
58
|
-
return ignore_list.flatten
|
149
|
+
return true
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.clone_dir(project_slug, project_owner, project_name)
|
153
|
+
list_dirs = [project_name,
|
154
|
+
project_name + "/.cnvrg"
|
155
|
+
]
|
59
156
|
|
157
|
+
|
158
|
+
list_files = [
|
159
|
+
project_name + "/.cnvrg/config.yml",
|
160
|
+
project_name+"/.cnvrgignore",
|
161
|
+
]
|
162
|
+
begin
|
163
|
+
config = {project_name: project_name,
|
164
|
+
project_slug: project_slug,
|
165
|
+
owner: project_owner}
|
166
|
+
FileUtils.mkdir_p list_dirs
|
167
|
+
FileUtils.touch list_files
|
168
|
+
cnvrgignore = Helpers.cnvrgignore_content
|
169
|
+
|
170
|
+
|
171
|
+
File.open(project_name + "/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
172
|
+
File.open(project_name+"/.cnvrgignore", "w+") { |f| f.write cnvrgignore }
|
173
|
+
|
174
|
+
rescue
|
175
|
+
return false
|
60
176
|
end
|
177
|
+
return true
|
178
|
+
end
|
61
179
|
|
62
|
-
|
180
|
+
def self.clone_dir_remote(project_slug, project_owner, project_name)
|
181
|
+
list_dirs = [
|
182
|
+
".cnvrg"
|
183
|
+
]
|
63
184
|
|
64
|
-
def self.create(project_name, path=nil,clean)
|
65
|
-
if clean
|
66
|
-
list_dirs = [project_name, project_name + "/.cnvrg"]
|
67
|
-
else
|
68
185
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
project_name + "/notebooks",
|
73
|
-
project_name + "/src",
|
74
|
-
project_name + "/src/visualizations",
|
75
|
-
project_name + "/src/features",
|
76
|
-
project_name + "/.cnvrg"
|
77
|
-
]
|
78
|
-
end
|
186
|
+
list_files = [
|
187
|
+
".cnvrg/config.yml",
|
188
|
+
".cnvrgignore",
|
79
189
|
|
190
|
+
]
|
191
|
+
begin
|
192
|
+
config = {project_name: project_name,
|
193
|
+
project_slug: project_slug,
|
194
|
+
owner: project_owner}
|
195
|
+
FileUtils.mkdir_p list_dirs
|
196
|
+
FileUtils.touch list_files
|
197
|
+
cnvrgignore = Helpers.cnvrgignore_content
|
80
198
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
cnvrgignore = Helpers.cnvrgignore_content
|
88
|
-
|
89
|
-
begin
|
90
|
-
|
91
|
-
owner = Cnvrg::CLI.get_owner()
|
92
|
-
response = Cnvrg::API.request("cli/create_project", 'POST', { title: project_name, owner:owner })
|
93
|
-
Cnvrg::CLI.is_response_success(response)
|
94
|
-
response = JSON.parse response["result"]
|
95
|
-
project_slug = response["slug"]
|
96
|
-
|
97
|
-
config = { project_name: project_name,
|
98
|
-
project_slug: project_slug,
|
99
|
-
owner: owner }
|
100
|
-
FileUtils.mkdir_p list_dirs
|
101
|
-
FileUtils.touch list_files
|
102
|
-
|
103
|
-
File.open(project_name + "/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
104
|
-
File.open(project_name + "/.cnvrgignore", "w+") { |f| f.write cnvrgignore }
|
105
|
-
File.open(project_name + "/README.md", "w+") { |f| f.write cnvrgreadme }
|
106
|
-
rescue
|
107
|
-
return false
|
108
|
-
end
|
109
|
-
return true
|
199
|
+
|
200
|
+
File.open(".cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
201
|
+
File.open(".cnvrgignore", "w+") { |f| f.write cnvrgignore }
|
202
|
+
|
203
|
+
rescue
|
204
|
+
return false
|
110
205
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
]
|
120
|
-
cnvrgreadme = Helpers.readme_content
|
121
|
-
cnvrgignore = Helpers.cnvrgignore_content
|
122
|
-
begin
|
123
|
-
response = Cnvrg::API.request("cli/create_project", 'POST', { title: project_name })
|
124
|
-
Cnvrg::CLI.is_response_success(response)
|
125
|
-
response = JSON.parse response["result"]
|
126
|
-
project_slug = response["slug"]
|
127
|
-
owner = response["owner"]
|
128
|
-
|
129
|
-
config = { project_name: project_name,
|
130
|
-
project_slug: project_slug,
|
131
|
-
owner: owner }
|
132
|
-
FileUtils.mkdir_p list_dirs
|
133
|
-
FileUtils.touch list_files
|
134
|
-
File.open(".cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
135
|
-
File.open(".cnvrgignore", "w+") { |f| f.write cnvrgignore }
|
136
|
-
File.open("README.md", "w+") { |f| f.write cnvrgreadme }
|
137
|
-
rescue
|
138
|
-
return false
|
139
|
-
end
|
140
|
-
return true
|
206
|
+
return true
|
207
|
+
end
|
208
|
+
|
209
|
+
def generate_idx
|
210
|
+
if File.exists? "#{self.local_path}/.cnvrg/idx.yml"
|
211
|
+
old_idx = YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
|
212
|
+
else
|
213
|
+
old_idx = nil
|
141
214
|
end
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
config = { project_name: project_name,
|
153
|
-
project_slug: project_slug,
|
154
|
-
owner: project_owner}
|
155
|
-
FileUtils.mkdir_p list_dirs
|
156
|
-
FileUtils.touch list_files
|
157
|
-
|
158
|
-
File.open(project_name + "/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
159
|
-
File.open(project_name + "/.cnvrg/idx.yml", "w+") { |f| f.write config.to_yaml }
|
160
|
-
rescue
|
161
|
-
return false
|
215
|
+
|
216
|
+
tree_idx = Hash.new(0)
|
217
|
+
|
218
|
+
list = Dir.glob("#{self.local_path}/**/**", File::FNM_DOTMATCH).reject { |x| (x =~ /\/\.{1,2}$/) or (x =~ /^#{self.local_path}\/\.cnvrg\/*/) }
|
219
|
+
list_ignore = self.get_ignore_list()
|
220
|
+
list.each do |e|
|
221
|
+
label = e.gsub(self.local_path + "/", "")
|
222
|
+
if File.directory? e
|
223
|
+
if list_ignore.include? label
|
224
|
+
next
|
162
225
|
end
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
226
|
+
tree_idx[label+"/"] = nil
|
227
|
+
else
|
228
|
+
if list_ignore.include? label
|
229
|
+
next
|
230
|
+
end
|
231
|
+
sha1 = Digest::SHA1.file(e).hexdigest
|
232
|
+
if old_idx.nil? or old_idx.to_h[:tree].nil?
|
233
|
+
tree_idx[label] = {sha1: sha1, commit_time: nil}
|
234
|
+
elsif old_idx[:tree][label].nil? or old_idx[:tree][label][:sha1] != sha1
|
235
|
+
tree_idx[label] = {sha1: sha1, commit_time: nil}
|
168
236
|
else
|
169
|
-
|
237
|
+
tree_idx[label] = old_idx[:tree][label]
|
170
238
|
end
|
239
|
+
end
|
240
|
+
end
|
171
241
|
|
172
|
-
|
173
|
-
|
174
|
-
list = Dir.glob("#{self.local_path}/**/**", File::FNM_DOTMATCH).reject { |x| (x =~ /\/\.{1,2}$/) or (x =~ /^#{self.local_path}\/\.cnvrg\/*/) }
|
175
|
-
list_ignore = self.get_ignore_list()
|
176
|
-
list.each do |e|
|
177
|
-
label = e.gsub(self.local_path + "/", "")
|
178
|
-
if File.directory? e
|
179
|
-
if list_ignore.include? label
|
180
|
-
next
|
181
|
-
end
|
182
|
-
tree_idx[label+"/"] = nil
|
183
|
-
else
|
184
|
-
if list_ignore.include? label
|
185
|
-
next
|
186
|
-
end
|
187
|
-
sha1 = Digest::SHA1.file(e).hexdigest
|
188
|
-
if old_idx.nil? or old_idx.to_h[:tree].nil?
|
189
|
-
tree_idx[label] = { sha1: sha1, commit_time: nil }
|
190
|
-
elsif old_idx[:tree][label].nil? or old_idx[:tree][label][:sha1] != sha1
|
191
|
-
tree_idx[label] = { sha1: sha1, commit_time: nil }
|
192
|
-
else
|
193
|
-
tree_idx[label] = old_idx[:tree][label]
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
242
|
+
idx = {commit: old_idx.to_h[:commit], tree: tree_idx}
|
197
243
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
return YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
|
202
|
-
end
|
244
|
+
File.open("#{self.local_path}/.cnvrg/idx.yml", 'w') { |f| f.write idx.to_yaml }
|
245
|
+
return YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
|
246
|
+
end
|
203
247
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
def clone
|
208
|
-
response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/clone", 'POST', { project_slug: self.slug})
|
209
|
-
Cnvrg::CLI.is_response_success(response)
|
210
|
-
return response
|
211
|
-
end
|
212
|
-
def compare_idx
|
213
|
-
local_idx = self.generate_idx
|
214
|
-
response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/status", 'POST', { idx: local_idx })
|
215
|
-
CLI.is_response_success(response)
|
216
|
-
return response
|
217
|
-
end
|
218
|
-
def update_idx_with_files_commits!(files, commit_time)
|
248
|
+
def get_idx
|
249
|
+
YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
|
250
|
+
end
|
219
251
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
252
|
+
def clone(remote=0, commit)
|
253
|
+
response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/clone", 'POST', {project_slug: self.slug, remote: remote, commit: commit})
|
254
|
+
return response
|
255
|
+
end
|
256
|
+
|
257
|
+
def compare_idx(new_branch, commit=last_local_commit)
|
258
|
+
|
259
|
+
local_idx = self.generate_idx
|
260
|
+
response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/status", 'POST', {idx: local_idx, new_branch: new_branch, current_commit: commit})
|
261
|
+
CLI.is_response_success(response)
|
262
|
+
return response
|
263
|
+
end
|
225
264
|
|
226
|
-
|
265
|
+
def compare_commit(commit)
|
266
|
+
if commit.nil? or commit.empty?
|
267
|
+
commit = last_local_commit
|
227
268
|
end
|
269
|
+
response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/commit/compare", 'POST', {current_commit: commit})
|
270
|
+
CLI.is_response_success(response)
|
271
|
+
return response["result"]["new_branch"]
|
272
|
+
end
|
228
273
|
|
229
|
-
|
230
|
-
idx_hash = YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
|
231
|
-
idx_hash[:commit] = commit
|
274
|
+
def update_idx_with_files_commits!(files, commit_time)
|
232
275
|
|
233
|
-
|
234
|
-
|
276
|
+
idx_hash = YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
|
277
|
+
files.each do |path|
|
278
|
+
idx_hash[:tree].to_h[path].to_h[:commit_time] = commit_time
|
235
279
|
end
|
280
|
+
File.open("#{self.local_path}/.cnvrg/idx.yml", 'w') { |f| f.write idx_hash.to_yaml }
|
281
|
+
|
282
|
+
return true
|
283
|
+
end
|
284
|
+
|
285
|
+
def deploy(file_to_run, function, input_params, commit_to_run, instance_type, image_slug, scheduling_query, local_timestamp)
|
286
|
+
response = Cnvrg::API.request("users/#{@owner}/projects/#{@slug}/deploy", 'POST', {file_to_run: file_to_run, function: function,
|
287
|
+
image_slug: image_slug, input_params: input_params,
|
288
|
+
commit_sha1: commit_to_run,
|
289
|
+
instance_type: instance_type,
|
290
|
+
scheduling_query: scheduling_query,
|
291
|
+
local_timestamp: local_timestamp})
|
292
|
+
return response
|
293
|
+
end
|
294
|
+
|
295
|
+
def update_idx_with_commit!(commit)
|
296
|
+
idx_hash = YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
|
297
|
+
idx_hash[:commit] = commit
|
298
|
+
|
299
|
+
File.open("#{self.local_path}/.cnvrg/idx.yml", 'w') { |f| f.write idx_hash.to_yaml }
|
300
|
+
return true
|
301
|
+
end
|
302
|
+
|
303
|
+
def revert(working_dir)
|
304
|
+
FileUtils.rm_rf working_dir
|
305
|
+
# response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/revert", 'GET')
|
306
|
+
# CLI.is_response_success(response)
|
307
|
+
|
308
|
+
|
309
|
+
end
|
236
310
|
|
237
311
|
end
|
238
|
-
end
|
312
|
+
end
|