mortar 0.1.0 → 0.2.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.
@@ -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