mortar 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,6 +23,10 @@ class Mortar::Command::Jobs < Mortar::Command::Base
23
23
 
24
24
  include Mortar::Git
25
25
 
26
+ CLUSTER_TYPE__SINGLE_JOB = 'single_job'
27
+ CLUSTER_TYPE__PERSISTENT = 'persistent'
28
+ CLUSTER_TYPE__PERMANENT = 'permanent'
29
+
26
30
  # jobs
27
31
  #
28
32
  # Show recent and running jobs.
@@ -57,6 +61,7 @@ class Mortar::Command::Jobs < Mortar::Command::Base
57
61
  # -c, --clusterid CLUSTERID # Run job on an existing cluster with ID of CLUSTERID (optional)
58
62
  # -s, --clustersize NUMNODES # Run job on a new cluster, with NUMNODES nodes (optional; must be >= 2 if provided)
59
63
  # -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)
64
+ # -2, --permanentcluster # Don't automatically stop the cluster after it has been idle for an hour (Default: false--cluster will be shut down after 1 hour of inactivity)
60
65
  # -p, --parameter NAME=VALUE # Set a pig parameter value in your script.
61
66
  # -f, --param-file PARAMFILE # Load pig parameter values from a file.
62
67
  # -d, --donotnotify # Don't send an email on job completion. (Default: false--an email will be sent to you once the job completes)
@@ -102,7 +107,7 @@ class Mortar::Command::Jobs < Mortar::Command::Base
102
107
  end
103
108
 
104
109
  if options[:clusterid]
105
- [:clustersize, :singlejobcluster].each do |opt|
110
+ [:clustersize, :singlejobcluster, :permanentcluster].each do |opt|
106
111
  unless options[opt].nil?
107
112
  error("Option #{opt.to_s} cannot be set when running a job on an existing cluster (with --clusterid option)")
108
113
  end
@@ -116,11 +121,19 @@ class Mortar::Command::Jobs < Mortar::Command::Base
116
121
  # post job to API
117
122
  response = action("Requesting job execution") do
118
123
  if options[:clustersize]
124
+ if options[:singlejobcluster] && options[:permanentcluster]
125
+ error("Cannot declare cluster as both --singlejobcluster and --permanentcluster")
126
+ end
119
127
  cluster_size = options[:clustersize].to_i
120
- keepalive = ! options[:singlejobcluster]
128
+ cluster_type = CLUSTER_TYPE__PERSISTENT
129
+ if options[:singlejobcluster]
130
+ cluster_type = CLUSTER_TYPE__SINGLE_JOB
131
+ elsif options[:permanentcluster]
132
+ cluster_type = CLUSTER_TYPE__PERMANENT
133
+ end
121
134
  api.post_job_new_cluster(project.name, script.name, git_ref, cluster_size,
122
135
  :parameters => pig_parameters,
123
- :keepalive => keepalive,
136
+ :cluster_type => cluster_type,
124
137
  :notify_on_job_finish => notify_on_job_finish,
125
138
  :is_control_script => is_control_script).body
126
139
  else
@@ -22,7 +22,7 @@ require "mortar/local/jython"
22
22
 
23
23
 
24
24
  class Mortar::Local::Controller
25
- include Mortar::Helpers
25
+ include Mortar::Local::InstallUtil
26
26
 
27
27
  NO_JAVA_ERROR_MESSAGE = <<EOF
28
28
  A suitable java installation could not be found. If you already have java installed
@@ -42,8 +42,8 @@ https://pypi.python.org/pypi/virtualenv
42
42
  EOF
43
43
 
44
44
  NO_AWS_KEYS_ERROR_MESSAGE = <<EOF
45
- Please specify your aws access key via enviroment variable AWS_ACCESS_KEY
46
- and your aws secret key via enviroment variable AWS_SECRET_KEY"
45
+ Please specify your aws access key via environment variable AWS_ACCESS_KEY
46
+ and your aws secret key via environment variable AWS_SECRET_KEY"
47
47
  EOF
48
48
 
49
49
 
@@ -91,6 +91,19 @@ EOF
91
91
 
92
92
  jy = Mortar::Local::Jython.new()
93
93
  jy.install_or_update()
94
+
95
+ ensure_local_install_dir_in_gitignore
96
+ end
97
+
98
+ def ensure_local_install_dir_in_gitignore()
99
+ if File.exists? local_project_gitignore
100
+ open(local_project_gitignore, 'r+') do |gitignore|
101
+ unless gitignore.read().include? local_install_directory_name
102
+ gitignore.seek(0, IO::SEEK_END)
103
+ gitignore.puts local_install_directory_name
104
+ end
105
+ end
106
+ end
94
107
  end
95
108
 
96
109
  # Main entry point for user running a pig script
@@ -28,10 +28,26 @@ module Mortar
28
28
 
29
29
  include Mortar::Helpers
30
30
 
31
- def local_install_directory
31
+ def local_install_directory_name
32
+ ".mortar-local"
33
+ end
34
+
35
+ def project_root
32
36
  # note: assumes that CWD is the project root, is
33
37
  # this a safe assumption?
34
- File.join(Dir.getwd, ".mortar-local")
38
+ Dir.getwd
39
+ end
40
+
41
+ def local_install_directory
42
+ File.join(project_root, local_install_directory_name)
43
+ end
44
+
45
+ def local_pig_logfile
46
+ project_root + "/local-pig.log"
47
+ end
48
+
49
+ def local_project_gitignore
50
+ project_root + "/.gitignore"
35
51
  end
36
52
 
37
53
  def jython_directory
@@ -42,6 +58,10 @@ module Mortar
42
58
  jython_directory + "/cachedir"
43
59
  end
44
60
 
61
+ def gitignore_template_path
62
+ File.expand_path("../../templates/project/gitignore", __FILE__)
63
+ end
64
+
45
65
  # Drops a marker file for an installed package, used
46
66
  # to help determine if updates should be performed
47
67
  def note_install(subdirectory)
@@ -224,6 +224,7 @@ class Mortar::Local::Pig
224
224
  # get it to do something interesting, such as '-f some-file.pig'
225
225
  def run_pig_command(cmd, parameters = nil, jython_output = true)
226
226
  unset_hadoop_env_vars
227
+ delete_local_log_file
227
228
  # Generate the script for running the command, then
228
229
  # write it to a temp script which will be exectued
229
230
  script_text = script_for_command(cmd, parameters)
@@ -243,6 +244,12 @@ class Mortar::Local::Pig
243
244
  ENV['HADOOP_CONF_DIR'] = ''
244
245
  end
245
246
 
247
+ def delete_local_log_file
248
+ if File.exists? local_pig_logfile
249
+ FileUtils.rm local_pig_logfile
250
+ end
251
+ end
252
+
246
253
  # Generates a bash script which sets up the necessary environment and
247
254
  # then runs the pig command
248
255
  def script_for_command(cmd, parameters, jython_output = true)
@@ -278,6 +285,7 @@ class Mortar::Local::Pig
278
285
  opts['fs.s3n.awsAccessKeyId'] = ENV['AWS_ACCESS_KEY']
279
286
  opts['fs.s3n.awsSecretAccessKey'] = ENV['AWS_SECRET_KEY']
280
287
  opts['pig.events.logformat'] = PIG_LOG_FORMAT
288
+ opts['pig.logfile'] = local_pig_logfile
281
289
  opts['python.verbose'] = 'error'
282
290
  opts['jython.output'] = true
283
291
  opts['python.home'] = jython_directory
@@ -16,5 +16,5 @@
16
16
 
17
17
  module Mortar
18
18
  # see http://semver.org/
19
- VERSION = "0.7.2"
19
+ VERSION = "0.7.3"
20
20
  end
@@ -48,7 +48,7 @@ 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,
51
+ :cluster_type => Jobs::CLUSTER_TYPE__SINGLE_JOB,
52
52
  :notify_on_job_finish => true,
53
53
  :is_control_script=> false) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
54
54
 
@@ -71,7 +71,64 @@ Or by running:
71
71
  STDOUT
72
72
  end
73
73
  end
74
-
74
+
75
+ it "handles permanentcluster parameter" do
76
+ with_git_initialized_project do |p|
77
+ # stub api requests
78
+ job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
79
+ job_url = "http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5"
80
+ cluster_size = 5
81
+
82
+ mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
83
+ :parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
84
+ :cluster_type => Jobs::CLUSTER_TYPE__PERMANENT,
85
+ :notify_on_job_finish => true,
86
+ :is_control_script=> false) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
87
+
88
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
89
+ stderr, stdout = execute("jobs:run my_script -2 --clustersize 5 -p FIRST_PARAM=FOO -p SECOND_PARAM=BAR", p, @git)
90
+ stdout.should == <<-STDOUT
91
+ Taking code snapshot... done
92
+ Sending code snapshot to Mortar... done
93
+ Requesting job execution... done
94
+ job_id: c571a8c7f76a4fd4a67c103d753e2dd5
95
+
96
+ Job status can be viewed on the web at:
97
+
98
+ http://127.0.0.1:5000/jobs/job_detail?job_id=c571a8c7f76a4fd4a67c103d753e2dd5
99
+
100
+ Or by running:
101
+
102
+ mortar jobs:status c571a8c7f76a4fd4a67c103d753e2dd5 --poll
103
+
104
+ STDOUT
105
+ end
106
+ end
107
+
108
+
109
+ it "throws error on singlejobcluster and permanentcluster" do
110
+ with_git_initialized_project do |p|
111
+
112
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
113
+ stderr, stdout = execute("jobs:run my_script -2 -1 --clustersize 5 -p FIRST_PARAM=FOO -p SECOND_PARAM=BAR", p, @git)
114
+ stderr.should == <<-STDERR
115
+ ! Cannot declare cluster as both --singlejobcluster and --permanentcluster
116
+ STDERR
117
+ end
118
+ end
119
+
120
+ it "throws error on clusterid and permanentcluster" do
121
+ with_git_initialized_project do |p|
122
+ cluster_id = "e2790e7e8c7d48e39157238d58191346"
123
+
124
+ write_file(File.join(p.pigscripts_path, "my_script.pig"))
125
+ stderr, stdout = execute("jobs:run my_script -2 --clusterid e2790e7e8c7d48e39157238d58191346 -p FIRST_PARAM=FOO -p SECOND_PARAM=BAR", p, @git)
126
+ stderr.should == <<-STDERR
127
+ ! Option permanentcluster cannot be set when running a job on an existing cluster (with --clusterid option)
128
+ STDERR
129
+ end
130
+ end
131
+
75
132
  it "runs a job on a new cluster" do
76
133
  with_git_initialized_project do |p|
77
134
  # stub api requests
@@ -81,7 +138,7 @@ STDOUT
81
138
 
82
139
  mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
83
140
  :parameters => match_array([{"name" => "FIRST_PARAM", "value" => "FOO"}, {"name" => "SECOND_PARAM", "value" => "BAR"}]),
84
- :keepalive => true,
141
+ :cluster_type => Jobs::CLUSTER_TYPE__PERSISTENT,
85
142
  :notify_on_job_finish => true,
86
143
  :is_control_script=>false) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
87
144
 
@@ -146,7 +203,7 @@ STDOUT
146
203
  mock(Mortar::Auth.api).get_clusters() {Excon::Response.new(:body => {'clusters' => []})}
147
204
  mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
148
205
  :parameters => [],
149
- :keepalive => true,
206
+ :cluster_type => Jobs::CLUSTER_TYPE__PERSISTENT,
150
207
  :notify_on_job_finish => true,
151
208
  :is_control_script=>false) {Excon::Response.new(:body => {"job_id" => job_id, "web_job_url" => job_url})}
152
209
 
@@ -262,11 +319,10 @@ STDOUT
262
319
  with_git_initialized_project do |p|
263
320
  job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
264
321
  cluster_size = 5
265
- keepalive = true
266
322
 
267
323
  mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
268
324
  :parameters => match_array([{"name" => "FIRST", "value" => "FOO"}, {"name" => "SECOND", "value" => "BAR"}, {"name" => "THIRD", "value" => "BEAR\n"}]),
269
- :keepalive => true,
325
+ :cluster_type => Jobs::CLUSTER_TYPE__PERSISTENT,
270
326
  :notify_on_job_finish => true,
271
327
  :is_control_script=>false) {Excon::Response.new(:body => {"job_id" => job_id})}
272
328
 
@@ -288,11 +344,10 @@ PARAMS
288
344
  with_git_initialized_project do |p|
289
345
  job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
290
346
  cluster_size = 5
291
- keepalive = true
292
347
 
293
348
  mock(Mortar::Auth.api).post_job_new_cluster("myproject", "my_script", is_a(String), cluster_size,
294
349
  :parameters => match_array([{"name" => "FIRST", "value" => "FOO"}, {"name" => "SECOND", "value" => "BAR"}, {"name" => "THIRD", "value" => "BEAR\n"}]),
295
- :keepalive => true,
350
+ :cluster_type => Jobs::CLUSTER_TYPE__PERSISTENT,
296
351
  :notify_on_job_finish => true,
297
352
  :is_control_script=>false) {Excon::Response.new(:body => {"job_id" => job_id})}
298
353
 
@@ -315,7 +370,6 @@ PARAMS
315
370
  with_git_initialized_project do |p|
316
371
  job_id = "c571a8c7f76a4fd4a67c103d753e2dd5"
317
372
  cluster_size = 5
318
- keepalive = true
319
373
 
320
374
  write_file(File.join(p.pigscripts_path, "my_script.pig"))
321
375
 
@@ -140,6 +140,9 @@ STDERR
140
140
  any_instance_of(Mortar::Local::Jython) do |j|
141
141
  mock(j).install_or_update.returns(true)
142
142
  end
143
+ any_instance_of(Mortar::Local::Controller) do |j|
144
+ mock(j).ensure_local_install_dir_in_gitignore.returns(true)
145
+ end
143
146
  stderr, stdout = execute("local:configure")
144
147
  stderr.should == ""
145
148
  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: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 7
9
- - 2
10
- version: 0.7.2
9
+ - 3
10
+ version: 0.7.3
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: 2013-03-26 00:00:00 Z
18
+ date: 2013-03-29 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: 7
28
+ hash: 1
29
29
  segments:
30
30
  - 0
31
31
  - 6
32
- - 0
33
- version: 0.6.0
32
+ - 3
33
+ version: 0.6.3
34
34
  type: :runtime
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency