mortar 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Mortar Development Framework
2
2
 
3
- Mortar is a platform as a service for Hadoop. With Mortar, you can run jobs on Hadoop using Apache Pig and Python without any special training.
3
+ [Mortar](http://www.mortardata.com/) is a platform as a service for Hadoop. With Mortar, you can run jobs on Hadoop using Apache Pig and Python without any special training.
4
4
 
5
5
  The Mortar Development Framework lets you develop Mortar Hadoop jobs directly on your local computer without installing any Hadoop libraries. Lots more info can be found on the [Mortar help site](http://help.mortardata.com).
6
6
 
@@ -37,4 +37,23 @@ class Mortar::Command::Clusters < Mortar::Command::Base
37
37
  end
38
38
 
39
39
  end
40
+
41
+ # clusters: stop CLUSTER_ID
42
+ #
43
+ # Stop a running cluster.
44
+ #
45
+ def stop
46
+ cluster_id = shift_argument
47
+ unless cluster_id
48
+ error("Usage: mortar clusters:stop CLUSTER_ID\nMust specify CLUSTER_ID.")
49
+ end
50
+
51
+ response = api.stop_cluster(cluster_id) .body
52
+
53
+ if response['message'].nil?
54
+ display("Stopping cluster #{cluster_id}.")
55
+ else
56
+ display(response['message'])
57
+ end
58
+ end
40
59
  end
@@ -40,9 +40,12 @@ class Mortar::Command::Illustrate < Mortar::Command::Base
40
40
  pigscript_name = shift_argument
41
41
  alias_name = shift_argument
42
42
  skip_pruning = options[:skippruning] ||= false
43
+
44
+ # TODO: When illustrating without alias works, remove the `&& alias_name` to re-enable the feature on CLI
43
45
  unless pigscript_name && alias_name
44
46
  error("Usage: mortar illustrate PIGSCRIPT ALIAS\nMust specify PIGSCRIPT and ALIAS.")
45
47
  end
48
+
46
49
  validate_arguments!
47
50
  validate_git_based_project!
48
51
  pigscript = validate_pigscript!(pigscript_name)
@@ -60,6 +60,7 @@ class Mortar::Command::Jobs < Mortar::Command::Base
60
60
  # -1, --singlejobcluster # Stop the cluster after job completes. (Default: false—-cluster can be used for other jobs, and will shut down after 1 hour of inactivity)
61
61
  # -p, --parameter NAME=VALUE # Set a pig parameter value in your script.
62
62
  # -f, --param-file PARAMFILE # Load pig parameter values from a file.
63
+ # -d, --donotnotify # Don't send an email on job completion. (Default: false--an email will be sent to you once the job completes)
63
64
  #
64
65
  #Examples:
65
66
  #
@@ -74,7 +75,8 @@ class Mortar::Command::Jobs < Mortar::Command::Base
74
75
  validate_arguments!
75
76
 
76
77
  unless options[:clusterid] || options[:clustersize]
77
- error("Please provide either the --clustersize option to run job on a new cluster, or --clusterid to run on an existing one.")
78
+ options[:clustersize] = 2
79
+ display("Defaulting to running job on new cluster of size 2")
78
80
  end
79
81
 
80
82
  if options[:clusterid]
@@ -88,6 +90,7 @@ class Mortar::Command::Jobs < Mortar::Command::Base
88
90
  validate_git_based_project!
89
91
  pigscript = validate_pigscript!(pigscript_name)
90
92
  git_ref = create_and_push_snapshot_branch(git, project)
93
+ notify_on_job_finish = ! options[:donotnotify]
91
94
 
92
95
  # post job to API
93
96
  response = action("Requesting job execution") do
@@ -96,11 +99,13 @@ class Mortar::Command::Jobs < Mortar::Command::Base
96
99
  keepalive = ! options[:singlejobcluster]
97
100
  api.post_job_new_cluster(project.name, pigscript.name, git_ref, cluster_size,
98
101
  :parameters => pig_parameters,
99
- :keepalive => keepalive).body
102
+ :keepalive => keepalive,
103
+ :notify_on_job_finish => notify_on_job_finish).body
100
104
  else
101
105
  cluster_id = options[:clusterid]
102
106
  api.post_job_existing_cluster(project.name, pigscript.name, git_ref, cluster_id,
103
- :parameters => pig_parameters).body
107
+ :parameters => pig_parameters,
108
+ :notify_on_job_finish => notify_on_job_finish).body
104
109
  end
105
110
  end
106
111
 
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * <%= script_name %>
3
- *
4
- * Required parameters:
5
- *
6
- * - INPUT_PATH Input path for script data (e.g. s3n://hawk-example-data/tutorial/excite.log.bz2)
7
- * - OUTPUT_PATH Output path for script data (e.g. s3n://my-output-bucket/<%= script_name %>)
8
3
  */
4
+
5
+ /**
6
+ * Parameters - set default values here; you can override with -p on the command-line.
7
+ */
8
+
9
+ <%= '%default'%> INPUT_PATH 's3n://hawk-example-data/tutorial/excite.log.bz2'
10
+ <%= '%default'%> OUTPUT_PATH 's3n://my-output-bucket/$MORTAR_EMAIL_S3_ESCAPED/<%= script_name %>'
9
11
 
10
12
  <% if not options[:skip_udf] %>
11
13
  /**
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * <%= project_name %>
3
- *
4
- * Required parameters:
5
- *
6
- * - INPUT_PATH Input path for script data (e.g. s3n://hawk-example-data/tutorial/excite.log.bz2)
7
- * - OUTPUT_PATH Output path for script data (e.g. s3n://my-output-bucket/<%= project_name %>)
8
3
  */
4
+
5
+ /**
6
+ * Parameters - set default values here; you can override with -p on the command-line.
7
+ */
8
+
9
+ <%= '%default'%> INPUT_PATH 's3n://hawk-example-data/tutorial/excite.log.bz2'
10
+ <%= '%default'%> OUTPUT_PATH 's3n://my-output-bucket/$MORTAR_EMAIL_S3_ESCAPED/<%= project_name %>'
9
11
 
10
12
  /**
11
13
  * User-Defined Functions (UDFs)
@@ -16,5 +16,5 @@
16
16
 
17
17
  module Mortar
18
18
  # see http://semver.org/
19
- VERSION = "0.4.4"
19
+ VERSION = "0.5.0"
20
20
  end
@@ -56,5 +56,28 @@ There are no running or recent clusters
56
56
  STDOUT
57
57
  end
58
58
  end
59
+
60
+ context("stop") do
61
+ it "Stops a running cluster with default message" do
62
+ cluster_id = "1234abcd"
63
+ mock(Mortar::Auth.api).stop_cluster(cluster_id) {Excon::Response.new(:body => {"success" => true})}
64
+
65
+ stderr, stdout = execute("clusters:stop #{cluster_id}")
66
+ stdout.should == <<-STDOUT
67
+ Stopping cluster #{cluster_id}.
68
+ STDOUT
69
+ end
70
+
71
+ it "Stops a running cluster with server message" do
72
+ cluster_id = "1234abcd"
73
+ message = "some awesome message"
74
+ mock(Mortar::Auth.api).stop_cluster(cluster_id) {Excon::Response.new(:body => {"success" => true, "message" => message})}
75
+
76
+ stderr, stdout = execute("clusters:stop #{cluster_id}")
77
+ stdout.should == "#{message}\n"
78
+ end
79
+ end
80
+
59
81
  end
82
+
60
83
  end
@@ -48,7 +48,8 @@ module Mortar::Command
48
48
 
49
49
  mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
50
50
  :parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
51
- :keepalive => false) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
51
+ :keepalive => false,
52
+ :notify_on_job_finish => true) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
52
53
 
53
54
  write_file(File.join(p.pigscripts_path, "my_script.pig"))
54
55
  stderr, stdout = execute("jobs:run my_script -1 --clustersize 5 -p FIRST_PARAM=FOO -p SECOND_PARAM=BAR", p, @git)
@@ -79,7 +80,8 @@ STDOUT
79
80
 
80
81
  mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
81
82
  :parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
82
- :keepalive => true) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
83
+ :keepalive => true,
84
+ :notify_on_job_finish => true) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
83
85
 
84
86
  write_file(File.join(p.pigscripts_path, "my_script.pig"))
85
87
  stderr, stdout = execute("jobs:run my_script --clustersize 5 -p FIRST_PARAM=FOO -p SECOND_PARAM=BAR", p, @git)
@@ -101,6 +103,39 @@ STDOUT
101
103
  end
102
104
  end
103
105
 
106
+ it "runs a job with no cluster defined" do
107
+ with_git_initialized_project do |p|
108
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
109
+ job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
110
+ cluster_size = 2
111
+
112
+ mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
113
+ :parameters => [],
114
+ :keepalive => true,
115
+ :notify_on_job_finish => true) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
116
+
117
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
118
+ stderr, stdout = execute("jobs:run my_script ", p, @git)
119
+ stdout.should == <<-STDOUT
120
+ Defaulting to running job on new cluster of size 2
121
+ Taking code snapshot... done
122
+ Sending code snapshot to Mortar... done
123
+ Requesting job execution... done
124
+ job_id: c571a8c7f76a4fd4a67c103d753e2dd5
125
+
126
+ Job status can be viewed on the web at:
127
+
128
+ http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5
129
+
130
+ Or by running:
131
+
132
+ mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5 --poll
133
+
134
+ STDOUT
135
+
136
+ end
137
+ end
138
+
104
139
  it "runs a job on an existing cluster" do
105
140
  with_git_initialized_project do |p|
106
141
  # stub api requests
@@ -108,10 +143,10 @@ STDOUT
108
143
  job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
109
144
  cluster_id = "e2790e7e8c7d48e39157238d58191346"
110
145
 
111
- mock(Mortar::Auth.api).post_job_existing_cluster("myproject", "my_script", is_a(String), cluster_id, :parameters => []) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
146
+ mock(Mortar::Auth.api).post_job_existing_cluster("myproject", "my_script", is_a(String), cluster_id, :parameters => [], :notify_on_job_finish => false) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
112
147
 
113
148
  write_file(File.join(p.pigscripts_path, "my_script.pig"))
114
- stderr, stdout = execute("jobs:run my_script --clusterid e2790e7e8c7d48e39157238d58191346", p, @git)
149
+ stderr, stdout = execute("jobs:run my_script --clusterid e2790e7e8c7d48e39157238d58191346 -d", p, @git)
115
150
  stdout.should == <<-STDOUT
116
151
  Taking code snapshot... done
117
152
  Sending code snapshot to Mortar... done
@@ -138,7 +173,8 @@ STDOUT
138
173
 
139
174
  mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
140
175
  :parameters => match_array([{"name" => "FIRST", "value" => "FOO"}, {"name" => "SECOND", "value" => "BAR"}, {"name" => "THIRD", "value" => "BEAR\n"}]),
141
- :keepalive => true) {Excon::Response.new(:body => {"job_id" => job_id})}
176
+ :keepalive => true,
177
+ :notify_on_job_finish => true) {Excon::Response.new(:body => {"job_id" => job_id})}
142
178
 
143
179
  write_file(File.join(p.pigscripts_path, "my_script.pig"))
144
180
 
@@ -162,7 +198,8 @@ PARAMS
162
198
 
163
199
  mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
164
200
  :parameters => match_array([{"name" => "FIRST", "value" => "FOO"}, {"name" => "SECOND", "value" => "BAR"}, {"name" => "THIRD", "value" => "BEAR\n"}]),
165
- :keepalive => true) {Excon::Response.new(:body => {"job_id" => job_id})}
201
+ :keepalive => true,
202
+ :notify_on_job_finish => true) {Excon::Response.new(:body => {"job_id" => job_id})}
166
203
 
167
204
  write_file(File.join(p.pigscripts_path, "my_script.pig"))
168
205
 
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: 7
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
9
- - 4
10
- version: 0.4.4
8
+ - 5
9
+ - 0
10
+ version: 0.5.0
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: 2012-11-28 00:00:00 Z
18
+ date: 2013-01-17 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: mortar-api-ruby
@@ -25,12 +25,12 @@ dependencies:
25
25
  requirements:
26
26
  - - ~>
27
27
  - !ruby/object:Gem::Version
28
- hash: 13
28
+ hash: 11
29
29
  segments:
30
30
  - 0
31
- - 4
32
- - 1
33
- version: 0.4.1
31
+ - 5
32
+ - 0
33
+ version: 0.5.0
34
34
  type: :runtime
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency