mortar 0.4.4 → 0.5.0

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/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