mortar 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,7 +16,7 @@
16
16
 
17
17
  require "mortar/command/base"
18
18
 
19
- ## manage clusters
19
+ # view running and recent clusters
20
20
  #
21
21
  class Mortar::Command::Clusters < Mortar::Command::Base
22
22
 
@@ -28,7 +28,9 @@ class Mortar::Command::Clusters < Mortar::Command::Base
28
28
  #
29
29
  # $ mortar clusters
30
30
  #
31
- #TBD
31
+ #cluster_id Size (# of Nodes) Status Type Start Timestamp Elapsed Time
32
+ #------------------------ ----------------- -------- ----------- --------------- ------------
33
+ #5023ca3ce0c222b7caaa546a 3 Starting Multi - Job
32
34
  #
33
35
  def index
34
36
  validate_arguments!
@@ -17,7 +17,7 @@
17
17
  require "mortar/command/base"
18
18
  require "mortar/snapshot"
19
19
 
20
- # manage pig scripts
20
+ # show data schema for pigscript
21
21
  #
22
22
  class Mortar::Command::Describe < Mortar::Command::Base
23
23
 
@@ -32,9 +32,16 @@ class Mortar::Command::Describe < Mortar::Command::Base
32
32
  #
33
33
  # Examples:
34
34
  #
35
- # $ mortar describe
35
+ # $ mortar describe generate_regression_model_coefficients songs_sample
36
36
  #
37
- # TBD
37
+ #Taking code snapshot... done
38
+ #Sending code snapshot to Mortar... done
39
+ #Starting describe... done
40
+ #
41
+ #Status: Success
42
+ #
43
+ #Results available at https://hawk.mortardata.com/describes/2000cf2e421aa909690000af
44
+ #Opening web browser to show results... done
38
45
  #
39
46
  def index
40
47
  pigscript_name = shift_argument
@@ -20,20 +20,30 @@ require "mortar/generators/pigscript_generator"
20
20
  require "mortar/generators/macro_generator"
21
21
  require "mortar/command/base"
22
22
 
23
- # generate new projects and scaffolding
23
+ # generate mortar code (project, pigscript, python_udf, macro)
24
24
  #
25
25
  class Mortar::Command::Generate < Mortar::Command::Base
26
26
 
27
- # generate:project
27
+ # generate:project [PROJECTNAME]
28
28
  #
29
- # generate new project
29
+ # Generate the files and directory structure necessary for a Mortar project.
30
30
  #
31
31
  #
32
32
  # Examples:
33
33
  #
34
34
  # $ mortar generate:project
35
35
  #
36
- # TBD
36
+ #create README.md
37
+ #create .gitignore
38
+ #create Gemfile
39
+ #create pigscripts
40
+ #create pigscripts/my_new_project.pig
41
+ #create macros
42
+ #create macros/.gitkeep
43
+ #create udfs
44
+ #create udfs/python
45
+ #create udfs/python/my_new_project.py
46
+ # run bundle install
37
47
  #
38
48
  def _project
39
49
  project_name = shift_argument
@@ -49,16 +59,16 @@ class Mortar::Command::Generate < Mortar::Command::Base
49
59
 
50
60
 
51
61
 
52
- # generate:python_udf
62
+ # generate:python_udf [UDFNAME]
53
63
  #
54
- # generate new python user defined function
64
+ # Generate a new python user defined function
55
65
  #
56
66
  #
57
67
  # Examples:
58
68
  #
59
- # $ mortar generate:python_udf UDFNAME
69
+ # $ mortar generate:python_udf my_new_udf
60
70
  #
61
- # TBD
71
+ #create udfs/python/my_new_udf.py
62
72
  #
63
73
  def python_udf
64
74
  udf_name = shift_argument
@@ -70,17 +80,18 @@ class Mortar::Command::Generate < Mortar::Command::Base
70
80
 
71
81
  end
72
82
 
73
- # generate:pigscript
83
+ # generate:pigscript [SCRIPTNAME]
74
84
  #
75
- # generate new pig script
85
+ # Generate new pig script.
76
86
  #
77
87
  # --skip-udf # Create the pig script without a partnered python udf
78
88
  #
79
89
  # Examples:
80
90
  #
81
- # $ mortar generate:pigscript SCRIPTNAME
91
+ # $ mortar generate:pigscript my_new_pigscript
82
92
  #
83
- # TBD
93
+ #create pigscripts/my_new_pigscript.pig
94
+ #create udfs/python/my_new_pigscript.py
84
95
  #
85
96
  def pigscript
86
97
  script_name = shift_argument
@@ -94,16 +105,16 @@ class Mortar::Command::Generate < Mortar::Command::Base
94
105
 
95
106
  end
96
107
 
97
- # generate:macro
108
+ # generate:macro [MACRONAME]
98
109
  #
99
- # generate new macro
110
+ # Generate a new pig macro.
100
111
  #
101
112
  #
102
113
  # Examples:
103
114
  #
104
- # $ mortar generate:macro MACRONAME
115
+ # $ mortar generate:macro my_new_macro
105
116
  #
106
- # TBD
117
+ #create macros/my_new_macro.pig
107
118
  #
108
119
  def macro
109
120
  macro_name = shift_argument
@@ -23,7 +23,7 @@ require "mortar/command/base"
23
23
  #
24
24
  class Mortar::Command::Help < Mortar::Command::Base
25
25
 
26
- PRIMARY_NAMESPACES = []
26
+ PRIMARY_NAMESPACES = %w( auth clusters generate illustrate jobs pigscripts projects )
27
27
 
28
28
  # help [COMMAND]
29
29
  #
@@ -17,7 +17,7 @@
17
17
  require "mortar/command/base"
18
18
  require "mortar/snapshot"
19
19
 
20
- # manage pig scripts
20
+ # sample and show data flowing through a pigscript
21
21
  #
22
22
  class Mortar::Command::Illustrate < Mortar::Command::Base
23
23
 
@@ -32,10 +32,16 @@ class Mortar::Command::Illustrate < Mortar::Command::Base
32
32
  #
33
33
  # Examples:
34
34
  #
35
- # $ mortar illustrate
35
+ # $ mortar illustrate generate_regression_model_coefficients songs_sample
36
36
  #
37
- # TBD
37
+ #Taking code snapshot... done
38
+ #Sending code snapshot to Mortar... done
39
+ #Starting illustrate... done
38
40
  #
41
+ #Status: Success
42
+ #
43
+ #Results available at https://hawk.mortardata.com/illustrates/2000ce2f421aa909680000af
44
+ #Opening web browser to show results... done
39
45
  def index
40
46
  pigscript_name = shift_argument
41
47
  alias_name = shift_argument
@@ -17,7 +17,8 @@
17
17
  require "mortar/command/base"
18
18
  require "mortar/snapshot"
19
19
  require "time"
20
- # manage pig scripts
20
+
21
+ # run and view status of pig jobs (run, status)
21
22
  #
22
23
  class Mortar::Command::Jobs < Mortar::Command::Base
23
24
 
@@ -32,10 +33,12 @@ class Mortar::Command::Jobs < Mortar::Command::Base
32
33
  #
33
34
  # Examples:
34
35
  #
35
- # $ mortar jobs
36
+ # $ mortar jobs -l 2
36
37
  #
37
- # TBD
38
- #
38
+ #job_id script status start_date elapsed_time cluster_size cluster_id
39
+ #------------------------ --------------------- ------- ----------------------------------- ------------ ------------ ------------------------
40
+ #2000cbbba40a860a6f000000 rollup: mock_expanded Success Friday, August 31, 2012, 10:40 AM 2 mins 3 2000cc3cb0c635b7cbff5aaa
41
+ #20009deca40a866cd5000000 rollup: mock_expanded Stopped Thursday, August 30, 2012, 1:08 PM < 1 min 2 2000857ae4b0dd5573da35aa
39
42
  def index
40
43
  options[:limit] ||= '10'
41
44
  options[:skip] ||= '0'
@@ -62,10 +65,20 @@ class Mortar::Command::Jobs < Mortar::Command::Base
62
65
  #
63
66
  #Examples:
64
67
  #
65
- # $ mortar jobs:run
68
+ # $ mortar jobs:run --clustersize 3 geenrate_regression_model_coefficients
66
69
  #
67
- # TBD
70
+ #Taking code snapshot... done
71
+ #Sending code snapshot to Mortar... done
72
+ #Requesting job execution... done
73
+ #job_id: 2000cbbba40a860a6f000000
74
+ #
75
+ #Job status can be viewed on the web at:
76
+ #
77
+ #https://hawk.mortardata.com/jobs/job_detail?job_id=2000cbbba40a860a6f000000
78
+ #
79
+ #Or by running:
68
80
  #
81
+ #mortar jobs:status 2000cbbba40a860a6f000000
69
82
  def run
70
83
  # arguemnts
71
84
  pigscript_name = shift_argument
@@ -124,9 +137,12 @@ class Mortar::Command::Jobs < Mortar::Command::Base
124
137
  #
125
138
  #Examples:
126
139
  #
127
- # $ mortar jobs:status 84f3c86f20034ed4bf5e359120a47f5a
140
+ # $ mortar jobs:status 2000cbbba40a860a6f000000
128
141
  #
129
- # TBD
142
+ #=== songhotness: generate_regression_model_coefficients (job_id: 2000cbbba40a860a6f000000)
143
+ #hadoop jobs complete: 0.00 / 1.00
144
+ #progress: 0%
145
+ #status: Starting Cluster
130
146
  def status
131
147
  job_id = shift_argument
132
148
  unless job_id
@@ -171,4 +187,29 @@ class Mortar::Command::Jobs < Mortar::Command::Base
171
187
  styled_header("#{job_status["project_name"]}: #{job_status["pigscript_name"]} (job_id: #{job_status["job_id"]})")
172
188
  styled_hash(job_display_entries)
173
189
  end
190
+
191
+ # jobs:stop JOB_ID
192
+ #
193
+ # Stop a running job.
194
+ #
195
+ #Examples:
196
+ #
197
+ # $ mortar jobs:stop 2000cbbba40a860a6f000000
198
+ #
199
+ #Stopping job 2000cbbba40a860a6f000000
200
+ def stop
201
+ job_id = shift_argument
202
+ unless job_id
203
+ error("Usage: mortar jobs:stop JOB_ID\nMust specify JOB_ID.")
204
+ end
205
+
206
+ response = api.stop_job(job_id).body
207
+
208
+ #TODO: jkarn - Once all servers have the additional message field we can remove this check.
209
+ if response['message'].nil?
210
+ display("Stopping job #{job_id}.")
211
+ else
212
+ display(response['message'])
213
+ end
214
+ end
174
215
  end
@@ -16,20 +16,21 @@
16
16
 
17
17
  require "mortar/command/base"
18
18
 
19
- # manage pig scripts
19
+ # list available pigscripts
20
20
  #
21
21
  class Mortar::Command::PigScripts < Mortar::Command::Base
22
22
 
23
23
  # pigscripts
24
24
  #
25
- # display the available set of pigscripts
25
+ # Display the available set of pigscripts
26
26
  #
27
27
  #Examples:
28
28
  #
29
29
  # $ mortar pigscripts
30
30
  #
31
- # hourly_top_searchers
32
- # user_engagement
31
+ #=== pigscripts
32
+ #hourly_top_searchers
33
+ #user_engagement
33
34
  #
34
35
  def index
35
36
  # validation
@@ -16,7 +16,7 @@
16
16
 
17
17
  require "mortar/command/base"
18
18
 
19
- ## manage projects
19
+ # manage projects (create, clone)
20
20
  #
21
21
  class Mortar::Command::Projects < Mortar::Command::Base
22
22
 
@@ -71,31 +71,39 @@ class Mortar::Command::Projects < Mortar::Command::Base
71
71
  end
72
72
 
73
73
  project_id = nil
74
- action("Creating project", {:success => "started"}) do
74
+ action("Sending request to create project: #{name}") do
75
75
  project_id = api.post_project(name).body["project_id"]
76
76
  end
77
77
 
78
- last_project_result = nil
79
- while last_project_result.nil? || (! Mortar::API::Projects::STATUSES_COMPLETE.include?(last_project_result["status"]))
80
- sleep polling_interval
81
- current_project_result = api.get_project(project_id).body
82
- if last_project_result.nil? || (last_project_result["status"] != current_project_result["status"])
83
- display(" ... #{current_project_result['status']}")
78
+ project_result = nil
79
+ project_status = nil
80
+ display
81
+ ticking(polling_interval) do |ticks|
82
+ project_result = api.get_project(project_id).body
83
+ project_status = project_result.fetch("status_code", project_result["status"])
84
+ project_description = project_result.fetch("status_description", project_status)
85
+ is_finished = Mortar::API::Projects::STATUSES_COMPLETE.include?(project_status)
86
+
87
+ redisplay("Status: %s %s" % [
88
+ project_description + (is_finished ? "" : "..."),
89
+ is_finished ? " " : spinner(ticks)],
90
+ is_finished) # only display newline on last message
91
+ if is_finished
92
+ display
93
+ break
84
94
  end
85
-
86
- last_project_result = current_project_result
87
95
  end
88
96
 
89
- case last_project_result['status']
97
+ case project_status
90
98
  when Mortar::API::Projects::STATUS_FAILED
91
- error("Project creation failed.\nError message: #{last_project_result['error_message']}")
99
+ error("Project creation failed.\nError message: #{project_result['error_message']}")
92
100
  when Mortar::API::Projects::STATUS_ACTIVE
93
- git.remote_add("mortar", last_project_result['git_url'])
101
+ git.remote_add("mortar", project_result['git_url'])
102
+ display "Your project is ready for use. Type 'mortar help' to see the commands you can perform on the project.\n\n"
94
103
  else
95
- raise RuntimeError, "Unknown project status: #{last_project_result['status']} for project_id: #{project_id}"
104
+ raise RuntimeError, "Unknown project status: #{project_status} for project_id: #{project_id}"
96
105
  end
97
106
 
98
-
99
107
  end
100
108
 
101
109
  # projects:clone PROJECT
@@ -124,5 +132,7 @@ class Mortar::Command::Projects < Mortar::Command::Base
124
132
  end
125
133
 
126
134
  git.clone(project['git_url'], project['name'])
135
+
136
+ display "\nYour project is ready for use. Type 'mortar help' to see the commands you can perform on the project.\n\n"
127
137
  end
128
138
  end
@@ -17,7 +17,7 @@
17
17
  require "mortar/command/base"
18
18
  require "mortar/snapshot"
19
19
 
20
- # manage pig scripts
20
+ # check script syntax
21
21
  #
22
22
  class Mortar::Command::Validate < Mortar::Command::Base
23
23
 
@@ -35,9 +35,15 @@ class Mortar::Command::Validate < Mortar::Command::Base
35
35
  #
36
36
  # Examples:
37
37
  #
38
- # $ mortar validate
38
+ # $ mortar validate generate_regression_model_coefficients
39
39
  #
40
- # TBD
40
+ #Taking code snapshot... done
41
+ #Sending code snapshot to Mortar... done
42
+ #Starting validate... done
43
+ #
44
+ #Status: Success
45
+ #
46
+ #Your script is valid.
41
47
  #
42
48
  def index
43
49
  pigscript_name = shift_argument
@@ -1,8 +1,7 @@
1
- # Weclome to Mortar!
2
-
3
- Copy TK
1
+ # Welcome to Mortar!
4
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. You create your project using the Mortar command-line tool, deploy code using the Git revision control system, and Mortar does the rest.
5
4
 
6
5
  # Getting Started
7
6
 
8
- Copy TK
7
+ For help getting started with Mortar, check out the [Mortar Help](http://preview.help.mortardata.com/) site.
@@ -16,5 +16,5 @@
16
16
 
17
17
  module Mortar
18
18
  # see http://semver.org/
19
- VERSION = "0.1.0"
19
+ VERSION = "0.2.0"
20
20
  end
@@ -357,8 +357,30 @@ status: Execution error
357
357
  STDOUT
358
358
  end
359
359
  end
360
-
361
-
360
+
361
+ context("stop") do
362
+ it "Stops a running job with default message" do
363
+ job_id = "1234abcd"
364
+ mock(Mortar::Auth.api).stop_job(job_id) {Excon::Response.new(:body => {"success" => true})}
365
+
366
+ stderr, stdout = execute("jobs:stop #{job_id}")
367
+ stdout.should == <<-STDOUT
368
+ Stopping job #{job_id}.
369
+ STDOUT
370
+ end
371
+
372
+ it "Stops a running job with server message" do
373
+ job_id = "1234abcd"
374
+ message = "some awesome message"
375
+ mock(Mortar::Auth.api).stop_job(job_id) {Excon::Response.new(:body => {"success" => true, "message" => message})}
376
+
377
+ stderr, stdout = execute("jobs:stop #{job_id}")
378
+ stdout.should == "#{message}\n"
379
+ end
380
+
381
+
382
+ end
383
+
362
384
  end
363
385
  end
364
386
  end
@@ -31,10 +31,10 @@ module Mortar::Command
31
31
 
32
32
  project1 = {'name' => "Project1",
33
33
  'status' => Mortar::API::Projects::STATUS_ACTIVE,
34
- 'git_url' => "git@github.com:mortarcode/Project1"}
34
+ 'git_url' => "git@github.com:mortarcode-dev/Project1"}
35
35
  project2 = {'name' => "Project2",
36
36
  'status' => Mortar::API::Projects::STATUS_ACTIVE,
37
- 'git_url' => "git@github.com:mortarcode/Project2"}
37
+ 'git_url' => "git@github.com:mortarcode-dev/Project2"}
38
38
 
39
39
  context("index") do
40
40
 
@@ -94,10 +94,10 @@ STDERR
94
94
  end
95
95
  end
96
96
 
97
- it "create a new project successfully" do
97
+ it "create a new project successfully - with status" do
98
98
  project_id = "1234abcd1234abcd1234"
99
99
  project_name = "some_new_project"
100
- project_git_url = "git@github.com:mortarcode/#{project_name}"
100
+ project_git_url = "git@github.com:mortarcode-dev/#{project_name}"
101
101
  mock(Mortar::Auth.api).post_project("some_new_project") {Excon::Response.new(:body => {"project_id" => project_id})}
102
102
  mock(Mortar::Auth.api).get_project(project_id).returns(Excon::Response.new(:body => {"status" => Mortar::API::Projects::STATUS_PENDING})).ordered
103
103
  mock(Mortar::Auth.api).get_project(project_id).returns(Excon::Response.new(:body => {"status" => Mortar::API::Projects::STATUS_CREATING})).ordered
@@ -107,10 +107,24 @@ STDERR
107
107
 
108
108
  stderr, stdout = execute("projects:create #{project_name} --polling_interval 0.05", nil, @git)
109
109
  stdout.should == <<-STDOUT
110
- Creating project... started
111
- ... PENDING
112
- ... CREATING
113
- ... ACTIVE
110
+ Sending request to create project: some_new_project... done\n\n\r\e[0KStatus: PENDING... /\r\e[0KStatus: CREATING... -\r\e[0KStatus: ACTIVE \n\nYour project is ready for use. Type 'mortar help' to see the commands you can perform on the project.\n
111
+ STDOUT
112
+ end
113
+
114
+ it "create a new project successfully - with status_code and status_description" do
115
+ project_id = "1234abcd1234abcd1234"
116
+ project_name = "some_new_project"
117
+ project_git_url = "git@github.com:mortarcode-dev/#{project_name}"
118
+ mock(Mortar::Auth.api).post_project("some_new_project") {Excon::Response.new(:body => {"project_id" => project_id})}
119
+ mock(Mortar::Auth.api).get_project(project_id).returns(Excon::Response.new(:body => {"status_description" => "Pending", "status_code" => Mortar::API::Projects::STATUS_PENDING})).ordered
120
+ mock(Mortar::Auth.api).get_project(project_id).returns(Excon::Response.new(:body => {"status_description" => "Creating", "status_code" => Mortar::API::Projects::STATUS_CREATING})).ordered
121
+ mock(Mortar::Auth.api).get_project(project_id).returns(Excon::Response.new(:body => {"status_description" => "Active", "status_code" => Mortar::API::Projects::STATUS_ACTIVE,
122
+ "git_url" => project_git_url})).ordered
123
+ mock(@git).remote_add("mortar", project_git_url)
124
+
125
+ stderr, stdout = execute("projects:create #{project_name} --polling_interval 0.05", nil, @git)
126
+ stdout.should == <<-STDOUT
127
+ Sending request to create project: some_new_project... done\n\n\r\e[0KStatus: Pending... /\r\e[0KStatus: Creating... -\r\e[0KStatus: Active \n\nYour project is ready for use. Type 'mortar help' to see the commands you can perform on the project.\n
114
128
  STDOUT
115
129
  end
116
130
 
@@ -194,7 +194,7 @@ STASH
194
194
 
195
195
  it "finds a single remote" do
196
196
  with_git_initialized_project do |p|
197
- remotes = @git.remotes("mortarcode")
197
+ remotes = @git.remotes("mortarcode-dev")
198
198
  remotes["mortar"].should == p.name
199
199
  end
200
200
  end
data/spec/spec_helper.rb CHANGED
@@ -49,7 +49,7 @@ def execute(command_line, project=nil, git=nil)
49
49
  stub(base).project.returns(project)
50
50
  end
51
51
  end
52
-
52
+
53
53
  # stub git
54
54
  if git
55
55
  # stub out any operations that affect remote resources
@@ -57,6 +57,7 @@ def execute(command_line, project=nil, git=nil)
57
57
 
58
58
  any_instance_of(Mortar::Command::Base) do |base|
59
59
  stub(base).git.returns(git)
60
+ stub(base).git_organization.returns("mortarcode-dev")
60
61
  end
61
62
  end
62
63
 
@@ -190,7 +191,7 @@ def with_git_initialized_project(&block)
190
191
  remote = "mortar"
191
192
  `git add README.txt`
192
193
  `git commit -a -m "First commit"`
193
- `git remote add #{remote} git@github.com:mortarcode/4dbbd83cae8d5bf8a4000000_#{project.name}.git`
194
+ `git remote add #{remote} git@github.com:mortarcode-dev/4dbbd83cae8d5bf8a4000000_#{project.name}.git`
194
195
  project.remote = remote
195
196
  block.call(project)
196
197
  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: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.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-08-30 00:00:00 Z
18
+ date: 2012-08-31 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: 27
28
+ hash: 23
29
29
  segments:
30
30
  - 0
31
- - 1
31
+ - 2
32
32
  - 0
33
- version: 0.1.0
33
+ version: 0.2.0
34
34
  type: :runtime
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency