mortar 0.15.27 → 0.15.28
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.
data/lib/mortar/command/jobs.rb
CHANGED
@@ -208,9 +208,8 @@ class Mortar::Command::Jobs < Mortar::Command::Base
|
|
208
208
|
error("Usage: mortar jobs:status JOB_ID\nMust specify JOB_ID.")
|
209
209
|
end
|
210
210
|
validate_arguments!
|
211
|
-
|
212
|
-
|
213
|
-
def display_job_status(job_status)
|
211
|
+
|
212
|
+
def pig_job_display_entries(job_status)
|
214
213
|
job_display_entries = {
|
215
214
|
"status" => job_status["status_description"],
|
216
215
|
"cluster_id" => job_status["cluster_id"],
|
@@ -220,18 +219,35 @@ class Mortar::Command::Jobs < Mortar::Command::Base
|
|
220
219
|
"job running for" => job_status["duration"],
|
221
220
|
"job run with parameters" => job_status["parameters"],
|
222
221
|
}
|
222
|
+
end
|
223
223
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
job_status["error"]["help"] = error_context
|
229
|
-
end
|
230
|
-
job_status["error"].each_pair do |key, value|
|
231
|
-
job_display_entries["error - #{key}"] = value
|
232
|
-
end
|
224
|
+
def luigi_job_display_entries(job_status)
|
225
|
+
status = job_status['status_description']
|
226
|
+
if !job_status['status_detail_description'].nil?
|
227
|
+
status += " - #{job_status['status_detail_description']}"
|
233
228
|
end
|
234
|
-
|
229
|
+
|
230
|
+
job_display_entries = {
|
231
|
+
"status" => status,
|
232
|
+
"job submitted at" => job_status["start_timestamp"],
|
233
|
+
"job began running at" => job_status["running_timestamp"],
|
234
|
+
"job finished at" => job_status["stop_timestamp"],
|
235
|
+
"job running for" => job_status["duration"],
|
236
|
+
"job run with parameters" => job_status["parameters"],
|
237
|
+
}
|
238
|
+
end
|
239
|
+
|
240
|
+
def add_pig_job_fields(job_status, job_display_entries)
|
241
|
+
if job_status["outputs"] && job_status["outputs"].length > 0
|
242
|
+
job_display_entries["outputs"] = Hash.new { |h,k| h[k] = [] }
|
243
|
+
job_status["outputs"].select{|o| o["alias"]}.collect{ |output|
|
244
|
+
output_hash = {}
|
245
|
+
output_hash["location"] = output["location"] if output["location"]
|
246
|
+
output_hash["records"] = output["records"] if output["records"]
|
247
|
+
[output['alias'], output_hash]
|
248
|
+
}.each{ |k,v| job_display_entries["outputs"][k] << v }
|
249
|
+
end
|
250
|
+
|
235
251
|
if job_status["num_hadoop_jobs"] && job_status["num_hadoop_jobs_succeeded"]
|
236
252
|
job_display_entries["progress"] = "#{job_status["progress"]}%"
|
237
253
|
job_display_entries["hadoop jobs complete"] =
|
@@ -241,24 +257,28 @@ class Mortar::Command::Jobs < Mortar::Command::Base
|
|
241
257
|
else
|
242
258
|
job_display_entries["progress"] = "#{job_status["progress"]}%"
|
243
259
|
end
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
260
|
+
end
|
261
|
+
|
262
|
+
# Inner function to display the hash table when the job is complte
|
263
|
+
def display_job_status(job_status)
|
264
|
+
if (job_status['job_type'] == Mortar::API::Jobs::JOB_TYPE_LUIGI)
|
265
|
+
job_display_entries = luigi_job_display_entries(job_status)
|
266
|
+
else
|
267
|
+
job_display_entries = pig_job_display_entries(job_status)
|
268
|
+
add_pig_job_fields(job_status, job_display_entries)
|
253
269
|
end
|
254
270
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
271
|
+
unless job_status["error"].nil? || job_status["error"]["message"].nil?
|
272
|
+
error_context = get_error_message_context(job_status["error"]["message"])
|
273
|
+
unless error_context == ""
|
274
|
+
job_status["error"]["help"] = error_context
|
275
|
+
end
|
276
|
+
job_status["error"].each_pair do |key, value|
|
277
|
+
job_display_entries["error - #{key}"] = value
|
278
|
+
end
|
259
279
|
end
|
260
280
|
|
261
|
-
styled_header("#{job_status["
|
281
|
+
styled_header("#{job_status["display_name"]} (job_id: #{job_status["job_id"]})")
|
262
282
|
styled_hash(job_display_entries)
|
263
283
|
end
|
264
284
|
|
@@ -274,8 +294,8 @@ class Mortar::Command::Jobs < Mortar::Command::Base
|
|
274
294
|
break
|
275
295
|
end
|
276
296
|
|
277
|
-
# If
|
278
|
-
if job_status["status_code"] == Mortar::API::Jobs::STATUS_RUNNING && job_status["num_hadoop_jobs"]
|
297
|
+
# If not a Luigi job and job is running show the progress bar
|
298
|
+
if job_status['job_type'] != Mortar::API::Jobs::JOB_TYPE_LUIGI and job_status["status_code"] == Mortar::API::Jobs::STATUS_RUNNING && job_status["num_hadoop_jobs"]
|
279
299
|
progressbar = "=" + ("=" * (job_status["progress"].to_i / 5)) + ">"
|
280
300
|
|
281
301
|
if job_status["num_hadoop_jobs"] && job_status["num_hadoop_jobs_succeeded"]
|
@@ -285,7 +305,7 @@ class Mortar::Command::Jobs < Mortar::Command::Base
|
|
285
305
|
|
286
306
|
printf("\r[#{spinner(ticks)}] Status: [%-22s] %s%% Complete (%s MapReduce jobs finished)", progressbar, job_status["progress"], hadoop_jobs_ratio_complete)
|
287
307
|
|
288
|
-
elsif job_status["status_code"] == Mortar::API::Jobs::STATUS_RUNNING
|
308
|
+
elsif job_status['job_type'] != Mortar::API::Jobs::JOB_TYPE_LUIGI and job_status["status_code"] == Mortar::API::Jobs::STATUS_RUNNING
|
289
309
|
jobs_complete = '%0.2f' % job_status["num_hadoop_jobs_succeeded"]
|
290
310
|
printf("\r[#{spinner(ticks)}] #{jobs_complete} MapReduce Jobs complete.")
|
291
311
|
|
@@ -295,6 +315,9 @@ class Mortar::Command::Jobs < Mortar::Command::Base
|
|
295
315
|
if !job_status['status_details'].nil?
|
296
316
|
job_display_status += " - #{job_status['status_details']}"
|
297
317
|
end
|
318
|
+
if !job_status['status_detail_description'].nil?
|
319
|
+
job_display_status += " - #{job_status['status_detail_description']}"
|
320
|
+
end
|
298
321
|
redisplay("[#{spinner(ticks)}] Status: #{job_display_status}")
|
299
322
|
end
|
300
323
|
end
|
@@ -20,11 +20,11 @@ from mortar.luigi import mortartask
|
|
20
20
|
https://help.mortardata.com/technologies/luigi
|
21
21
|
|
22
22
|
To Run:
|
23
|
-
mortar luigi luigiscripts/<%=
|
24
|
-
|
23
|
+
mortar luigi luigiscripts/<%= project_name %>_luigi.py \
|
24
|
+
--output-base-path "s3://mortar-example-output-data/<your_username_here>/<%= project_name %>"
|
25
25
|
"""
|
26
26
|
|
27
|
-
MORTAR_PROJECT = '<%=
|
27
|
+
MORTAR_PROJECT = '<%= project_name %>'
|
28
28
|
|
29
29
|
# helper function
|
30
30
|
def create_full_path(base_path, sub_path):
|
@@ -97,7 +97,7 @@ class RunMyExamplePigScript(mortartask.MortarProjectPigscriptTask):
|
|
97
97
|
"""
|
98
98
|
Name of Pig script to run.
|
99
99
|
"""
|
100
|
-
return '<%=
|
100
|
+
return '<%= project_name %>'
|
101
101
|
|
102
102
|
|
103
103
|
class ShutdownClusters(mortartask.MortarClusterShutdownTask):
|
@@ -131,4 +131,4 @@ if __name__ == "__main__":
|
|
131
131
|
need to be run should be called in the main method. In this case ShutdownClusters
|
132
132
|
is being called.
|
133
133
|
"""
|
134
|
-
luigi.run(main_task_cls= ShutdownClusters)
|
134
|
+
luigi.run(main_task_cls= ShutdownClusters)
|
data/lib/mortar/version.rb
CHANGED
@@ -568,6 +568,7 @@ STDERR
|
|
568
568
|
mock(Mortar::Auth.api).get_job(job_id) {Excon::Response.new(:body => {"job_id" => job_id,
|
569
569
|
"pigscript_name" => pigscript_name,
|
570
570
|
"project_name" => project_name,
|
571
|
+
"display_name" => "#{project_name}: #{pigscript_name}",
|
571
572
|
"status_code" => status_code,
|
572
573
|
"status_description" => "Success",
|
573
574
|
"progress" => progress,
|
@@ -621,6 +622,7 @@ STDOUT
|
|
621
622
|
mock(Mortar::Auth.api).get_job(job_id) {Excon::Response.new(:body => {"job_id" => job_id,
|
622
623
|
"pigscript_name" => pigscript_name,
|
623
624
|
"project_name" => project_name,
|
625
|
+
"display_name" => "#{project_name}: #{pigscript_name}",
|
624
626
|
"status_code" => status_code,
|
625
627
|
"status_description" => "Running",
|
626
628
|
"progress" => progress,
|
@@ -668,6 +670,7 @@ STDOUT
|
|
668
670
|
mock(Mortar::Auth.api).get_job(job_id) {Excon::Response.new(:body => {"job_id" => job_id,
|
669
671
|
"pigscript_name" => pigscript_name,
|
670
672
|
"project_name" => project_name,
|
673
|
+
"display_name" => "#{project_name}: #{pigscript_name}",
|
671
674
|
"status_code" => status_code,
|
672
675
|
"status_description" => "Execution error",
|
673
676
|
"progress" => progress,
|
@@ -719,6 +722,7 @@ STDOUT
|
|
719
722
|
mock(Mortar::Auth.api).get_job(job_id).returns(Excon::Response.new(:body => {"job_id" => job_id,
|
720
723
|
"controlscript_name" => controlscript_name,
|
721
724
|
"project_name" => project_name,
|
725
|
+
"display_name" => "#{project_name}: #{controlscript_name}",
|
722
726
|
"status_code" => status_code,
|
723
727
|
"status_description" => "Execution error",
|
724
728
|
"progress" => progress,
|
@@ -744,6 +748,7 @@ STDOUT
|
|
744
748
|
mock(Mortar::Auth.api).get_job(job_id).returns(Excon::Response.new(:body => {"job_id" => job_id,
|
745
749
|
"controlscript_name" => controlscript_name,
|
746
750
|
"project_name" => project_name,
|
751
|
+
"display_name" => "#{project_name}: #{controlscript_name}",
|
747
752
|
"status_code" => status_code,
|
748
753
|
"status_description" => "Success",
|
749
754
|
"progress" => progress,
|
@@ -798,6 +803,7 @@ STDOUT
|
|
798
803
|
mock(Mortar::Auth.api).get_job(job_id).returns(Excon::Response.new(:body => {"job_id" => job_id,
|
799
804
|
"pigscript_name" => pigscript_name,
|
800
805
|
"project_name" => project_name,
|
806
|
+
"display_name" => "#{project_name}: #{pigscript_name}",
|
801
807
|
"status_code" => status_code,
|
802
808
|
"status_description" => "Execution error",
|
803
809
|
"progress" => progress,
|
@@ -824,6 +830,7 @@ STDOUT
|
|
824
830
|
mock(Mortar::Auth.api).get_job(job_id).returns(Excon::Response.new(:body => {"job_id" => job_id,
|
825
831
|
"pigscript_name" => pigscript_name,
|
826
832
|
"project_name" => project_name,
|
833
|
+
"display_name" => "#{project_name}: #{pigscript_name}",
|
827
834
|
"status_code" => status_code,
|
828
835
|
"status_description" => "Success",
|
829
836
|
"progress" => progress,
|
@@ -862,28 +869,97 @@ STDOUT
|
|
862
869
|
end
|
863
870
|
end
|
864
871
|
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
872
|
+
it "gets status for a running pipeline job using polling" do
|
873
|
+
#{"project_name"=>"jkarn-mortar-recsys", "status_code"=>"finished", "status_detail_description"=>"Success", "status_detail"=>"success", "duration"=>"< 1 min", "status_description"=>"Finished", "script_variables"=>[], "start_timestamp"=>"2014-10-03T12:34:40.994000+00:00", "display_name"=>"jkarn-mortar-recsys: simple-retail-generate-signals", "job_id"=>"542e97cea40a865ab7000dfe", "request_timestamp"=>"2014-10-03T12:34:22.439000+00:00", "luigiscript_name"=>"simple-retail-generate-signals", "job_type"=>"luigi", "error"=>nil, "git_ref"=>"015690ad2c951c67366e36847be59646d441c5b1", "stop_timestamp"=>"2014-10-03T12:35:20.241000+00:00"}
|
874
|
+
with_git_initialized_project do |p|
|
875
|
+
job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
|
876
|
+
luigiscript_name = "my_luigi_script"
|
877
|
+
project_name = "myproject"
|
878
|
+
display_name = "#{project_name}: #{luigiscript_name}"
|
879
|
+
status_code = Mortar::API::Jobs::LUIGI_JOB_STATUS__STARTING
|
880
|
+
status_description = "#{status_code} description"
|
881
|
+
status_detail = nil
|
882
|
+
status_detail_description = "#{status_detail} description"
|
883
|
+
start_timestamp = "2012-02-28T03:35:42.831000+00:00"
|
884
|
+
stop_timestamp = "2012-02-28T03:44:52.613000+00:00"
|
885
|
+
running_timestamp = "2012-02-28T03:41:52.613000+00:00"
|
886
|
+
duration = "< 1 min"
|
869
887
|
|
870
|
-
|
871
|
-
|
872
|
-
|
888
|
+
mock(Mortar::Auth.api).get_job(job_id).returns(Excon::Response.new(:body => {"job_id" => job_id,
|
889
|
+
"project_name"=>project_name,
|
890
|
+
"status_code"=>status_code,
|
891
|
+
"status_detail_description"=>status_detail_description,
|
892
|
+
"status_detail"=>status_detail,
|
893
|
+
"duration"=>duration,
|
894
|
+
"status_description"=>status_description,
|
895
|
+
"script_variables"=>[],
|
896
|
+
"start_timestamp"=>start_timestamp,
|
897
|
+
"display_name"=>display_name,
|
898
|
+
"job_id"=>job_id,
|
899
|
+
"request_timestamp"=>running_timestamp,
|
900
|
+
"luigiscript_name"=>luigiscript_name,
|
901
|
+
"job_type"=>Mortar::API::Jobs::JOB_TYPE_LUIGI,
|
902
|
+
"error"=>nil,
|
903
|
+
"git_ref"=>"015690ad2c951c67366e36847be59646d441c5b1",
|
904
|
+
"stop_timestamp"=>stop_timestamp
|
905
|
+
}))
|
906
|
+
|
907
|
+
status_code = Mortar::API::Jobs::LUIGI_JOB_STATUS__FINISHED
|
908
|
+
status_detail = "success"
|
909
|
+
|
910
|
+
status_description = "#{status_code} description"
|
911
|
+
status_detail_description = "#{status_detail} description"
|
912
|
+
|
913
|
+
mock(Mortar::Auth.api).get_job(job_id).returns(Excon::Response.new(:body => {"job_id" => job_id,
|
914
|
+
"project_name"=>project_name,
|
915
|
+
"status_code"=>status_code,
|
916
|
+
"status_detail_description"=>"#{status_detail} description",
|
917
|
+
"status_detail"=>status_detail,
|
918
|
+
"duration"=>duration,
|
919
|
+
"status_description"=>"#{status_code} description",
|
920
|
+
"script_variables"=>[],
|
921
|
+
"start_timestamp"=>start_timestamp,
|
922
|
+
"display_name"=>display_name,
|
923
|
+
"job_id"=>job_id,
|
924
|
+
"request_timestamp"=>running_timestamp,
|
925
|
+
"luigiscript_name"=>luigiscript_name,
|
926
|
+
"job_type"=>Mortar::API::Jobs::JOB_TYPE_LUIGI,
|
927
|
+
"error"=>nil,
|
928
|
+
"git_ref"=>"015690ad2c951c67366e36847be59646d441c5b1",
|
929
|
+
"stop_timestamp"=>stop_timestamp
|
930
|
+
}))
|
931
|
+
stderr, stdout = execute("jobs:status c571a8c7f76a4fd4a67c103d753e2dd5 -p --polling_interval 0.05", p, @git)
|
932
|
+
stdout.should == <<-STDOUT
|
933
|
+
\r\e[0K[/] Status: starting description - description\r\e[0K=== #{display_name} (job_id: #{job_id})
|
934
|
+
job finished at: #{stop_timestamp}
|
935
|
+
job running for: #{duration}
|
936
|
+
job submitted at: #{start_timestamp}
|
937
|
+
status: #{status_description} - #{status_detail_description}
|
873
938
|
STDOUT
|
874
939
|
end
|
940
|
+
end
|
941
|
+
end
|
875
942
|
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
943
|
+
context("stop") do
|
944
|
+
it "Stops a running job with default message" do
|
945
|
+
job_id = "1234abcd"
|
946
|
+
mock(Mortar::Auth.api).stop_job(job_id) {Excon::Response.new(:body => {"success" => true})}
|
880
947
|
|
881
|
-
|
882
|
-
|
883
|
-
|
948
|
+
stderr, stdout = execute("jobs:stop #{job_id}")
|
949
|
+
stdout.should == <<-STDOUT
|
950
|
+
Stopping job #{job_id}.
|
951
|
+
STDOUT
|
952
|
+
end
|
884
953
|
|
954
|
+
it "Stops a running job with server message" do
|
955
|
+
job_id = "1234abcd"
|
956
|
+
message = "some awesome message"
|
957
|
+
mock(Mortar::Auth.api).stop_job(job_id) {Excon::Response.new(:body => {"success" => true, "message" => message})}
|
885
958
|
|
959
|
+
stderr, stdout = execute("jobs:stop #{job_id}")
|
960
|
+
stdout.should == "#{message}\n"
|
886
961
|
end
|
962
|
+
|
887
963
|
end
|
888
964
|
end
|
889
965
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mortar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 15
|
9
|
-
-
|
10
|
-
version: 0.15.
|
9
|
+
- 28
|
10
|
+
version: 0.15.28
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Mortar Data
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2014-10-
|
18
|
+
date: 2014-10-07 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rdoc
|
@@ -41,12 +41,12 @@ dependencies:
|
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
43
43
|
- !ruby/object:Gem::Version
|
44
|
-
hash:
|
44
|
+
hash: 45
|
45
45
|
segments:
|
46
46
|
- 0
|
47
47
|
- 8
|
48
|
-
-
|
49
|
-
version: 0.8.
|
48
|
+
- 9
|
49
|
+
version: 0.8.9
|
50
50
|
type: :runtime
|
51
51
|
version_requirements: *id002
|
52
52
|
- !ruby/object:Gem::Dependency
|