masamune 0.11.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.
Files changed (185) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +54 -0
  4. data/Rakefile +15 -0
  5. data/bin/masamune-elastic-mapreduce +4 -0
  6. data/bin/masamune-hive +4 -0
  7. data/bin/masamune-psql +4 -0
  8. data/bin/masamune-shell +4 -0
  9. data/lib/masamune.rb +56 -0
  10. data/lib/masamune/accumulate.rb +60 -0
  11. data/lib/masamune/actions.rb +38 -0
  12. data/lib/masamune/actions/data_flow.rb +131 -0
  13. data/lib/masamune/actions/date_parse.rb +75 -0
  14. data/lib/masamune/actions/elastic_mapreduce.rb +68 -0
  15. data/lib/masamune/actions/execute.rb +52 -0
  16. data/lib/masamune/actions/filesystem.rb +37 -0
  17. data/lib/masamune/actions/hadoop_filesystem.rb +40 -0
  18. data/lib/masamune/actions/hadoop_streaming.rb +41 -0
  19. data/lib/masamune/actions/hive.rb +74 -0
  20. data/lib/masamune/actions/postgres.rb +76 -0
  21. data/lib/masamune/actions/postgres_admin.rb +34 -0
  22. data/lib/masamune/actions/s3cmd.rb +44 -0
  23. data/lib/masamune/actions/transform.rb +89 -0
  24. data/lib/masamune/after_initialize_callbacks.rb +55 -0
  25. data/lib/masamune/cached_filesystem.rb +110 -0
  26. data/lib/masamune/commands.rb +37 -0
  27. data/lib/masamune/commands/elastic_mapreduce.rb +119 -0
  28. data/lib/masamune/commands/hadoop_filesystem.rb +57 -0
  29. data/lib/masamune/commands/hadoop_streaming.rb +116 -0
  30. data/lib/masamune/commands/hive.rb +178 -0
  31. data/lib/masamune/commands/interactive.rb +37 -0
  32. data/lib/masamune/commands/postgres.rb +128 -0
  33. data/lib/masamune/commands/postgres_admin.rb +72 -0
  34. data/lib/masamune/commands/postgres_common.rb +33 -0
  35. data/lib/masamune/commands/retry_with_backoff.rb +60 -0
  36. data/lib/masamune/commands/s3cmd.rb +70 -0
  37. data/lib/masamune/commands/shell.rb +202 -0
  38. data/lib/masamune/configuration.rb +195 -0
  39. data/lib/masamune/data_plan.rb +31 -0
  40. data/lib/masamune/data_plan/builder.rb +66 -0
  41. data/lib/masamune/data_plan/elem.rb +190 -0
  42. data/lib/masamune/data_plan/engine.rb +162 -0
  43. data/lib/masamune/data_plan/rule.rb +292 -0
  44. data/lib/masamune/data_plan/set.rb +176 -0
  45. data/lib/masamune/environment.rb +164 -0
  46. data/lib/masamune/filesystem.rb +567 -0
  47. data/lib/masamune/has_environment.rb +40 -0
  48. data/lib/masamune/helpers.rb +27 -0
  49. data/lib/masamune/helpers/postgres.rb +84 -0
  50. data/lib/masamune/io.rb +33 -0
  51. data/lib/masamune/last_element.rb +53 -0
  52. data/lib/masamune/method_logger.rb +41 -0
  53. data/lib/masamune/multi_io.rb +39 -0
  54. data/lib/masamune/schema.rb +36 -0
  55. data/lib/masamune/schema/catalog.rb +233 -0
  56. data/lib/masamune/schema/column.rb +527 -0
  57. data/lib/masamune/schema/dimension.rb +133 -0
  58. data/lib/masamune/schema/event.rb +121 -0
  59. data/lib/masamune/schema/fact.rb +133 -0
  60. data/lib/masamune/schema/map.rb +265 -0
  61. data/lib/masamune/schema/row.rb +133 -0
  62. data/lib/masamune/schema/store.rb +115 -0
  63. data/lib/masamune/schema/table.rb +308 -0
  64. data/lib/masamune/schema/table_reference.rb +76 -0
  65. data/lib/masamune/spec_helper.rb +23 -0
  66. data/lib/masamune/string_format.rb +34 -0
  67. data/lib/masamune/tasks/elastic_mapreduce_thor.rb +60 -0
  68. data/lib/masamune/tasks/hive_thor.rb +55 -0
  69. data/lib/masamune/tasks/postgres_thor.rb +47 -0
  70. data/lib/masamune/tasks/shell_thor.rb +63 -0
  71. data/lib/masamune/template.rb +77 -0
  72. data/lib/masamune/thor.rb +186 -0
  73. data/lib/masamune/thor_loader.rb +38 -0
  74. data/lib/masamune/topological_hash.rb +34 -0
  75. data/lib/masamune/transform.rb +47 -0
  76. data/lib/masamune/transform/bulk_upsert.psql.erb +64 -0
  77. data/lib/masamune/transform/bulk_upsert.rb +52 -0
  78. data/lib/masamune/transform/consolidate_dimension.rb +54 -0
  79. data/lib/masamune/transform/deduplicate_dimension.psql.erb +52 -0
  80. data/lib/masamune/transform/deduplicate_dimension.rb +53 -0
  81. data/lib/masamune/transform/define_event_view.hql.erb +51 -0
  82. data/lib/masamune/transform/define_event_view.rb +60 -0
  83. data/lib/masamune/transform/define_index.psql.erb +34 -0
  84. data/lib/masamune/transform/define_schema.hql.erb +23 -0
  85. data/lib/masamune/transform/define_schema.psql.erb +79 -0
  86. data/lib/masamune/transform/define_schema.rb +56 -0
  87. data/lib/masamune/transform/define_table.hql.erb +34 -0
  88. data/lib/masamune/transform/define_table.psql.erb +95 -0
  89. data/lib/masamune/transform/define_table.rb +40 -0
  90. data/lib/masamune/transform/define_unique.psql.erb +30 -0
  91. data/lib/masamune/transform/insert_reference_values.psql.erb +43 -0
  92. data/lib/masamune/transform/insert_reference_values.rb +64 -0
  93. data/lib/masamune/transform/load_dimension.rb +47 -0
  94. data/lib/masamune/transform/load_fact.rb +45 -0
  95. data/lib/masamune/transform/operator.rb +96 -0
  96. data/lib/masamune/transform/relabel_dimension.psql.erb +76 -0
  97. data/lib/masamune/transform/relabel_dimension.rb +39 -0
  98. data/lib/masamune/transform/rollup_fact.psql.erb +79 -0
  99. data/lib/masamune/transform/rollup_fact.rb +149 -0
  100. data/lib/masamune/transform/snapshot_dimension.psql.erb +75 -0
  101. data/lib/masamune/transform/snapshot_dimension.rb +74 -0
  102. data/lib/masamune/transform/stage_dimension.psql.erb +39 -0
  103. data/lib/masamune/transform/stage_dimension.rb +83 -0
  104. data/lib/masamune/transform/stage_fact.psql.erb +80 -0
  105. data/lib/masamune/transform/stage_fact.rb +111 -0
  106. data/lib/masamune/version.rb +25 -0
  107. data/spec/fixtures/aggregate.sql.erb +25 -0
  108. data/spec/fixtures/comment.sql.erb +27 -0
  109. data/spec/fixtures/invalid.sql.erb +23 -0
  110. data/spec/fixtures/relative.sql.erb +23 -0
  111. data/spec/fixtures/simple.sql.erb +28 -0
  112. data/spec/fixtures/whitespace.sql.erb +30 -0
  113. data/spec/masamune/actions/elastic_mapreduce_spec.rb +108 -0
  114. data/spec/masamune/actions/execute_spec.rb +50 -0
  115. data/spec/masamune/actions/hadoop_filesystem_spec.rb +44 -0
  116. data/spec/masamune/actions/hadoop_streaming_spec.rb +74 -0
  117. data/spec/masamune/actions/hive_spec.rb +117 -0
  118. data/spec/masamune/actions/postgres_admin_spec.rb +58 -0
  119. data/spec/masamune/actions/postgres_spec.rb +134 -0
  120. data/spec/masamune/actions/s3cmd_spec.rb +44 -0
  121. data/spec/masamune/actions/transform_spec.rb +144 -0
  122. data/spec/masamune/after_initialization_callbacks_spec.rb +61 -0
  123. data/spec/masamune/cached_filesystem_spec.rb +167 -0
  124. data/spec/masamune/commands/hadoop_filesystem_spec.rb +50 -0
  125. data/spec/masamune/commands/hadoop_streaming_spec.rb +106 -0
  126. data/spec/masamune/commands/hive_spec.rb +117 -0
  127. data/spec/masamune/commands/postgres_admin_spec.rb +69 -0
  128. data/spec/masamune/commands/postgres_spec.rb +100 -0
  129. data/spec/masamune/commands/retry_with_backoff_spec.rb +116 -0
  130. data/spec/masamune/commands/s3cmd_spec.rb +50 -0
  131. data/spec/masamune/commands/shell_spec.rb +101 -0
  132. data/spec/masamune/configuration_spec.rb +102 -0
  133. data/spec/masamune/data_plan/builder_spec.rb +91 -0
  134. data/spec/masamune/data_plan/elem_spec.rb +102 -0
  135. data/spec/masamune/data_plan/engine_spec.rb +356 -0
  136. data/spec/masamune/data_plan/rule_spec.rb +407 -0
  137. data/spec/masamune/data_plan/set_spec.rb +517 -0
  138. data/spec/masamune/environment_spec.rb +65 -0
  139. data/spec/masamune/filesystem_spec.rb +1421 -0
  140. data/spec/masamune/helpers/postgres_spec.rb +95 -0
  141. data/spec/masamune/schema/catalog_spec.rb +613 -0
  142. data/spec/masamune/schema/column_spec.rb +696 -0
  143. data/spec/masamune/schema/dimension_spec.rb +137 -0
  144. data/spec/masamune/schema/event_spec.rb +75 -0
  145. data/spec/masamune/schema/fact_spec.rb +117 -0
  146. data/spec/masamune/schema/map_spec.rb +593 -0
  147. data/spec/masamune/schema/row_spec.rb +28 -0
  148. data/spec/masamune/schema/store_spec.rb +49 -0
  149. data/spec/masamune/schema/table_spec.rb +395 -0
  150. data/spec/masamune/string_format_spec.rb +60 -0
  151. data/spec/masamune/tasks/elastic_mapreduce_thor_spec.rb +57 -0
  152. data/spec/masamune/tasks/hive_thor_spec.rb +75 -0
  153. data/spec/masamune/tasks/postgres_thor_spec.rb +42 -0
  154. data/spec/masamune/tasks/shell_thor_spec.rb +51 -0
  155. data/spec/masamune/template_spec.rb +77 -0
  156. data/spec/masamune/thor_spec.rb +238 -0
  157. data/spec/masamune/transform/bulk_upsert.dimension_spec.rb +200 -0
  158. data/spec/masamune/transform/consolidate_dimension_spec.rb +62 -0
  159. data/spec/masamune/transform/deduplicate_dimension_spec.rb +84 -0
  160. data/spec/masamune/transform/define_event_view_spec.rb +84 -0
  161. data/spec/masamune/transform/define_schema_spec.rb +83 -0
  162. data/spec/masamune/transform/define_table.dimension_spec.rb +306 -0
  163. data/spec/masamune/transform/define_table.fact_spec.rb +291 -0
  164. data/spec/masamune/transform/define_table.table_spec.rb +525 -0
  165. data/spec/masamune/transform/insert_reference_values.dimension_spec.rb +111 -0
  166. data/spec/masamune/transform/insert_reference_values.fact_spec.rb +149 -0
  167. data/spec/masamune/transform/load_dimension_spec.rb +76 -0
  168. data/spec/masamune/transform/load_fact_spec.rb +89 -0
  169. data/spec/masamune/transform/relabel_dimension_spec.rb +102 -0
  170. data/spec/masamune/transform/rollup_fact_spec.rb +333 -0
  171. data/spec/masamune/transform/snapshot_dimension_spec.rb +103 -0
  172. data/spec/masamune/transform/stage_dimension_spec.rb +115 -0
  173. data/spec/masamune/transform/stage_fact_spec.rb +204 -0
  174. data/spec/masamune_spec.rb +32 -0
  175. data/spec/spec_helper.rb +41 -0
  176. data/spec/support/masamune/example_group.rb +36 -0
  177. data/spec/support/masamune/mock_command.rb +99 -0
  178. data/spec/support/masamune/mock_delegate.rb +51 -0
  179. data/spec/support/masamune/mock_filesystem.rb +96 -0
  180. data/spec/support/masamune/thor_mute.rb +35 -0
  181. data/spec/support/rspec/example/action_example_group.rb +34 -0
  182. data/spec/support/rspec/example/task_example_group.rb +80 -0
  183. data/spec/support/rspec/example/transform_example_group.rb +36 -0
  184. data/spec/support/shared_examples/postgres_common_examples.rb +53 -0
  185. metadata +462 -0
@@ -0,0 +1,89 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'active_support/concern'
24
+
25
+ require 'masamune/actions/postgres'
26
+
27
+ require 'masamune/transform/load_dimension'
28
+ require 'masamune/transform/consolidate_dimension'
29
+ require 'masamune/transform/relabel_dimension'
30
+ require 'masamune/transform/load_fact'
31
+ require 'masamune/transform/rollup_fact'
32
+
33
+ module Masamune::Actions
34
+ module Transform
35
+ extend ActiveSupport::Concern
36
+ extend Forwardable
37
+
38
+ include Masamune::Actions::Postgres
39
+
40
+ # FIXME should eventually be able to include Transform directly instead of through wrapper
41
+ class Wrapper
42
+ extend Masamune::Transform::LoadDimension
43
+ extend Masamune::Transform::ConsolidateDimension
44
+ extend Masamune::Transform::RelabelDimension
45
+ extend Masamune::Transform::LoadFact
46
+ extend Masamune::Transform::RollupFact
47
+ end
48
+
49
+ FILE_MODE = 0777 - File.umask
50
+
51
+ def load_dimension(source_files, source, target)
52
+ output = Tempfile.new('masamune')
53
+ FileUtils.chmod(FILE_MODE, output.path)
54
+
55
+ if source.respond_to?(:map) and map = source.map(to: target)
56
+ result = map.apply(source_files, output)
57
+ else
58
+ output = source_files
59
+ result = source
60
+ end
61
+
62
+ transform = Wrapper.load_dimension(output, result, target)
63
+ logger.debug(File.read(output)) if (source.debug || map.debug)
64
+ postgres file: transform.to_file, debug: (source.debug || target.debug || map.debug)
65
+ ensure
66
+ output.unlink
67
+ end
68
+
69
+ def consolidate_dimension(target)
70
+ transform = Wrapper.consolidate_dimension(target)
71
+ postgres file: transform.to_file, debug: target.debug
72
+ end
73
+
74
+ def relabel_dimension(target)
75
+ transform = Wrapper.relabel_dimension(target)
76
+ postgres file: transform.to_file, debug: target.debug
77
+ end
78
+
79
+ def load_fact(source_files, source, target, date)
80
+ transform = Wrapper.load_fact(source_files, source, target, date)
81
+ postgres file: transform.to_file, debug: (source.debug || target.debug)
82
+ end
83
+
84
+ def rollup_fact(source, target, date)
85
+ transform = Wrapper.rollup_fact(source, target, date)
86
+ postgres file: transform.to_file, debug: (source.debug || target.debug)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,55 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'active_support/concern'
24
+
25
+ module Masamune
26
+ module AfterInitializeCallbacks
27
+ extend ActiveSupport::Concern
28
+
29
+ PRIORITY =
30
+ {
31
+ first: 20,
32
+ early: 10,
33
+ default: 0,
34
+ later: -10,
35
+ final: -20
36
+ }
37
+
38
+ module ClassMethods
39
+ # Callbacks registered with the highest priority are executed first, ties are broken by callback registration order
40
+ def after_initialize(priority = :default, &block)
41
+ @after_initialize ||= Hash.new { |h,k| h[k] = [] }
42
+ @after_initialize[PRIORITY.fetch(priority, 0)] << block
43
+ end
44
+
45
+ def after_initialize_invoke(*a)
46
+ @after_initialize ||= Hash.new { |h,k| h[k] = [] }
47
+ @after_initialize.sort.reverse.each { |p, x| x.each { |y| y.call(*a) } }
48
+ end
49
+ end
50
+
51
+ def after_initialize_invoke(*a)
52
+ self.class.after_initialize_invoke(self, *a)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,110 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Masamune
24
+ class CachedFilesystem < SimpleDelegator
25
+ include Masamune::Accumulate
26
+
27
+ def initialize(filesystem)
28
+ super filesystem
29
+ @filesystem = filesystem
30
+ clear!
31
+ end
32
+
33
+ def clear!
34
+ @cache = Hash.new { |h,k| h[k] = Set.new }
35
+ end
36
+
37
+ def exists?(file)
38
+ @cache.key?(file) || glob(file).include?(file) || @cache.key?(file)
39
+ end
40
+
41
+ def glob(file_or_glob, &block)
42
+ glob_stat(file_or_glob) do |entry|
43
+ yield entry.name unless entry.name == dirname(file_or_glob)
44
+ end
45
+ end
46
+ method_accumulate :glob
47
+
48
+ def stat(file_or_dir)
49
+ raise ArgumentError, 'cannot contain wildcard' if file_or_dir.include?('*')
50
+ result = Set.new
51
+ glob_stat(file_or_dir) do |entry|
52
+ result << entry
53
+ end
54
+ result += @cache[file_or_dir]
55
+ return unless result.any?
56
+ return result.first if result.size == 1
57
+ max_time = result.map { |stat| stat.try(:mtime) }.compact.max
58
+ sum_size = result.map { |stat| stat.try(:size) }.compact.reduce(:+)
59
+ OpenStruct.new(name: file_or_dir, mtime: max_time, size: sum_size)
60
+ end
61
+
62
+ # FIXME cache eviction policy can be more precise
63
+ [:touch!, :mkdir!, :copy_file_to_file, :copy_file_to_dir, :copy_dir, :remove_file, :remove_dir, :move_file_to_file, :move_file_to_dir, :move_dir, :write].each do |method|
64
+ define_method(method) do |*args|
65
+ clear!
66
+ @filesystem.send(method, *args)
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ MAX_DEPTH = 10
73
+ CACHE_DEPTH = 1
74
+ EMPTY_SET = Set.new
75
+
76
+ def glob_stat(file_or_glob, options = {}, &block)
77
+ return if file_or_glob.blank?
78
+ return if root_path?(file_or_glob)
79
+ depth = options.fetch(:depth, 0)
80
+ return if depth > MAX_DEPTH || depth > CACHE_DEPTH
81
+
82
+ glob_stat(dirname(file_or_glob), depth: depth + 1, &block)
83
+
84
+ dirname = dirname(file_or_glob)
85
+ unless @cache.key?(dirname)
86
+ pattern = root_path?(dirname) ? file_or_glob : File.join(dirname, '*')
87
+ @filesystem.glob_stat(pattern) do |entry|
88
+ recursive_paths(dirname, entry.name) do |path|
89
+ @cache[path] << entry
90
+ end
91
+ end
92
+ end
93
+ @cache[dirname] ||= EMPTY_SET
94
+
95
+ file_regexp = glob_to_regexp(file_or_glob)
96
+ @cache[dirname].each do |entry|
97
+ yield entry if entry.name =~ file_regexp
98
+ end if depth == 0
99
+ end
100
+
101
+ def recursive_paths(root, path, options = {}, &block)
102
+ depth = options.fetch(:depth, 0)
103
+ return if depth > MAX_DEPTH
104
+ return if root == path
105
+ yield path
106
+ yield dirname(path)
107
+ recursive_paths(root, dirname(path), depth: depth + 1, &block)
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,37 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Masamune
24
+ module Commands
25
+ require 'masamune/commands/hive'
26
+ require 'masamune/commands/s3cmd'
27
+ require 'masamune/commands/hadoop_streaming'
28
+ require 'masamune/commands/hadoop_filesystem'
29
+ require 'masamune/commands/elastic_mapreduce'
30
+ require 'masamune/commands/postgres_common'
31
+ require 'masamune/commands/postgres'
32
+ require 'masamune/commands/postgres_admin'
33
+ require 'masamune/commands/interactive'
34
+ require 'masamune/commands/shell'
35
+ require 'masamune/commands/retry_with_backoff'
36
+ end
37
+ end
@@ -0,0 +1,119 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'delegate'
24
+
25
+ require 'masamune/actions/execute'
26
+
27
+ module Masamune::Commands
28
+ class ElasticMapReduce < SimpleDelegator
29
+ include Masamune::Actions::Execute
30
+
31
+ DEFAULT_ATTRIBUTES =
32
+ {
33
+ :path => 'elastic-mapreduce',
34
+ :options => [],
35
+ :extra => [],
36
+ :jobflow => nil,
37
+ :input => nil,
38
+ }
39
+
40
+ def initialize(delegate, attrs = {})
41
+ super delegate
42
+ @delegate = delegate
43
+ DEFAULT_ATTRIBUTES.merge(configuration.elastic_mapreduce).merge(attrs).each do |name, value|
44
+ instance_variable_set("@#{name}", value)
45
+ end
46
+ end
47
+
48
+ def interactive?
49
+ if @delegate.respond_to?(:interactive?)
50
+ @delegate.interactive?
51
+ elsif @extra.any?
52
+ true
53
+ else
54
+ @input == nil
55
+ end
56
+ end
57
+
58
+ def stdin
59
+ if @delegate.respond_to?(:stdin)
60
+ @delegate.stdin
61
+ elsif @input
62
+ @stdin ||= StringIO.new(@input)
63
+ end
64
+ end
65
+
66
+ def elastic_mapreduce_command
67
+ args = []
68
+ args << @path
69
+ args << @options.map(&:to_a)
70
+ args << ['--jobflow', @jobflow] if @jobflow
71
+ args.flatten
72
+ end
73
+
74
+ def ssh_args
75
+ args = []
76
+ args << elastic_mapreduce_command
77
+ args << '--ssh'
78
+ args << 'exit'
79
+ args.flatten
80
+ end
81
+
82
+ # Use elastic-mapreduce to translate jobflow into raw ssh command
83
+ def ssh_command
84
+ @ssh_command ||= begin
85
+ result = nil
86
+ execute(*ssh_args, fail_fast: true, safe: true) do |line|
87
+ if line =~ /exit\Z/
88
+ result = line.sub(/ exit\Z/, '').split(' ')
89
+ else
90
+ logger.error(line)
91
+ end
92
+ end
93
+ result
94
+ end
95
+ end
96
+
97
+ def command_args
98
+ args = []
99
+ args << (ssh_command? ? ssh_command : elastic_mapreduce_command)
100
+ args << @extra
101
+ args << @delegate.command_args if @delegate.respond_to?(:command_args)
102
+ args.flatten
103
+ end
104
+
105
+ def handle_stdout(line, line_no)
106
+ if line_no == 0 && line =~ /\Assh/
107
+ @delegate.handle_stderr(line, line_no) if @delegate.respond_to?(:handle_stderr)
108
+ else
109
+ @delegate.handle_stdout(line, line_no) if @delegate.respond_to?(:handle_stdout)
110
+ end
111
+ end
112
+
113
+ private
114
+
115
+ def ssh_command?
116
+ @delegate.respond_to?(:command_args) || @input.present?
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,57 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2014-2015, VMware, Inc. All Rights Reserved.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'delegate'
24
+
25
+ module Masamune::Commands
26
+ class HadoopFilesystem < SimpleDelegator
27
+ DEFAULT_ATTRIBUTES =
28
+ {
29
+ :path => 'hadoop',
30
+ :options => [],
31
+ :extra => [],
32
+ :block => nil,
33
+ :print => false
34
+ }
35
+
36
+ def initialize(delegate, attrs = {})
37
+ super delegate
38
+ DEFAULT_ATTRIBUTES.merge(configuration.hadoop_filesystem).merge(attrs).each do |name, value|
39
+ instance_variable_set("@#{name}", value)
40
+ end
41
+ end
42
+
43
+ def command_args
44
+ args = []
45
+ args << @path
46
+ args << 'fs'
47
+ args << @options.map(&:to_a)
48
+ args << @extra
49
+ args.flatten
50
+ end
51
+
52
+ def handle_stdout(line, line_no)
53
+ @block.call(line) if @block
54
+ console(line) if @print
55
+ end
56
+ end
57
+ end