larrow-runner 0.0.1 → 0.0.2

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/lib/larrow/runner.rb CHANGED
@@ -1,5 +1,5 @@
1
- require 'active_support/deprecation'
2
1
  require 'active_support/core_ext/hash'
2
+ require 'active_support/core_ext/string'
3
3
 
4
4
  require "larrow/runner/version"
5
5
  require 'larrow/runner/logger'
@@ -18,8 +18,8 @@ module Larrow
18
18
  end
19
19
  # global options
20
20
  RunOption = {}.with_indifferent_access
21
- # cloud wrapper
22
- Cloud = Session.load_cloud
21
+ # default resource file path
22
+ ResourcePath = '.larrow.resource'
23
23
  end
24
24
  end
25
25
 
@@ -8,7 +8,11 @@ You can save it as .larrow.yml on the project root folder.
8
8
  EOF
9
9
  def dump url
10
10
  vcs = Vcs.detect url
11
- configuration = vcs.configuration false
11
+ configuration = Manifest.configuration(
12
+ vcs,
13
+ ignore_base_scripts: true,
14
+ ignore_larrow: true
15
+ )
12
16
  puts configuration.dump
13
17
  end
14
18
 
@@ -1 +1,2 @@
1
- ExecutionError = Class.new StandardError
1
+ ExecutionError = Class.new StandardError
2
+ InvalidConfigFile = Class.new StandardError
@@ -7,7 +7,7 @@ module Larrow::Runner
7
7
  # logger.level(3).title 'hello'
8
8
  # logger.level(3).detail 'hello'
9
9
  class Logger
10
- def initialize logger, level:nil, color:'magenta'
10
+ def initialize logger, level:nil, color:'green'
11
11
  @inner_logger = if logger.is_a? ::Logger
12
12
  logger
13
13
  else
@@ -44,7 +44,7 @@ module Larrow::Runner
44
44
  end
45
45
 
46
46
  def detail msg
47
- color('green').info msg
47
+ color('magenta').info msg
48
48
  end
49
49
 
50
50
  def err msg
@@ -45,6 +45,11 @@ module Larrow::Runner
45
45
 
46
46
  def handle_exception
47
47
  yield
48
+ rescue InvalidConfigFile => e
49
+ data = eval(e.message)
50
+ url = "https://github.com/fsword/larrow-runner/wiki/#{data[:wiki]}"
51
+ RunLogger.err "invalid config file: #{data[:file]}"
52
+ RunLogger.level(1).err "see: #{url}"
48
53
  rescue => e
49
54
  RunOption[:keep] = true if e.is_a?(ExecutionError)
50
55
  if e.is_a?(ExecutionError) && !debug?
@@ -88,7 +93,7 @@ module Larrow::Runner
88
93
 
89
94
  def self.resource
90
95
  resource_iterator do |clazz, array|
91
- RunLogger.detail clazz.name.split("::").last
96
+ RunLogger.info clazz.name.split("::").last
92
97
  clazz.show array, 1
93
98
  end
94
99
  end
@@ -101,14 +106,16 @@ module Larrow::Runner
101
106
  end
102
107
 
103
108
  def self.resource_iterator
104
- resource = YAML.load(File.read '.larrow.resource') rescue nil
105
- return if resource.nil?
109
+ RunLogger.title "load resource from #{ResourcePath}"
110
+ resource = YAML.load(File.read ResourcePath) rescue {}
111
+
106
112
  resource.each_pair do |k,array|
107
113
  case k
108
114
  when :nodes
109
115
  yield Model::Node, array
110
116
  end
111
117
  end
118
+ RunLogger.detail "no resource on the file" if resource.empty?
112
119
  end
113
120
  end
114
121
  end
@@ -13,11 +13,22 @@ module Larrow
13
13
 
14
14
  extend self
15
15
 
16
- def configuration source_accessor
17
- [ Larrow, Travis, Blank ].each do |clazz|
18
- configuration = clazz.new(source_accessor).load
19
- return configuration if configuration
16
+ # options:
17
+ # :ignore_larrow : do not try to use larrow adapter
18
+ # :ignore_base_scripts : do not merge base scripts
19
+ def configuration source_accessor, options={}
20
+ adapters = [Travis, Blank]
21
+ adapters.unshift Larrow unless options[:ignore_larrow]
22
+
23
+ configuration = adapters.each do |clazz|
24
+ c = clazz.new(source_accessor).load
25
+ break c if c
26
+ end
27
+
28
+ unless options[:ignore_base_scripts]
29
+ add_base_scripts(configuration, source_accessor)
20
30
  end
31
+ configuration
21
32
  end
22
33
 
23
34
  def add_base_scripts configuration,source_accessor
@@ -1,31 +1,33 @@
1
- module Larrow::Runner::Manifest
2
- class Larrow < BaseLoader
3
- def config_file
4
- source_accessor.larrow_file || '.larrow.yml'
5
- end
6
-
7
- # TODO manifest validation
8
- def parse content
9
- data = YAML.load(content).with_indifferent_access
10
- if data.is_a? Array # stages as a Array
11
- # TODO
12
- elsif data.is_a? Hash # steps as a Hash
13
- configuration.image = data[:image]
14
- Configuration::DEFINED_GROUPS[:custom].each do |title|
15
- v = data[title]
16
- build_step title,v if v
1
+ module Larrow::Runner
2
+ module Manifest
3
+ class Larrow < BaseLoader
4
+ def config_file
5
+ source_accessor.larrow_file || '.larrow.yml'
6
+ end
7
+
8
+ # TODO manifest validation
9
+ def parse content
10
+ data = YAML.load(content).with_indifferent_access
11
+ if data.is_a? Array # stages as a Array
12
+ # TODO
13
+ elsif data.is_a? Hash # steps as a Hash
14
+ configuration.image = data[:image]
15
+ Configuration::DEFINED_GROUPS[:custom].each do |title|
16
+ v = data[title]
17
+ build_step title,v if v
18
+ end
17
19
  end
18
20
  end
19
- end
20
-
21
- def build_step title, lines
22
- source_dir = if title == :init
23
- nil
24
- else
25
- configuration.source_dir
26
- end
27
- scripts = lines.map{|s| Script.new s, base_dir: source_dir}
28
- configuration.put_to_step title, scripts
21
+
22
+ def build_step title, lines
23
+ source_dir = if title == :init
24
+ nil
25
+ else
26
+ configuration.source_dir
27
+ end
28
+ scripts = lines.map{|s| Script.new s, base_dir: source_dir}
29
+ configuration.put_to_step title, scripts
30
+ end
29
31
  end
30
32
  end
31
33
  end
@@ -1,43 +1,44 @@
1
1
  require 'yaml'
2
2
 
3
- module Larrow::Runner::Manifest
4
- class Travis < BaseLoader
5
- CONFIG_FILE='.travis.yml'
6
- attr_accessor :data
7
-
8
- def parse content
9
- self.data = YAML.load(content).with_indifferent_access
10
- build_language
11
- map_step :prepare, :before_script
12
- map_step :functional_test, :script
13
- end
14
-
15
- def map_step title, travis_title
16
- source_dir = configuration.source_dir
17
- scripts = (data[travis_title] || []).map do |cmd|
18
- Script.new cmd, base_dir: source_dir
3
+ module Larrow::Runner
4
+ module Manifest
5
+ class Travis < BaseLoader
6
+ CONFIG_FILE='.travis.yml'
7
+ attr_accessor :data
8
+
9
+ def parse content
10
+ self.data = YAML.load(content).with_indifferent_access
11
+ build_language
12
+ map_step :prepare, :before_script
13
+ map_step :functional_test, :script
14
+ end
15
+
16
+ def map_step title, travis_title
17
+ source_dir = configuration.source_dir
18
+ scripts = (data[travis_title] || []).map do |cmd|
19
+ Script.new cmd, base_dir: source_dir
20
+ end
21
+ return nil if scripts.empty?
22
+
23
+ configuration.put_to_step title, scripts
24
+ end
25
+
26
+ def build_language
27
+ return if data[:language].nil?
28
+ clazz = eval data[:language].camelize
29
+ clazz.fulfill(data,configuration)
19
30
  end
20
- return nil if scripts.empty?
21
-
22
- configuration.put_to_step title, scripts
23
- end
24
-
25
- def build_language
26
- return if data[:language].nil?
27
- clazz = eval data[:language].camelize
28
- clazz.fulfill(data,configuration)
29
31
  end
30
- end
31
- class Erlang
32
- TEMPLATE_PATH='/opt/install/erlang/%s'
33
- def self.fulfill data, configuration
34
- revision = case data[:otp_release].last
35
- when /R15/ then 'R15B03'
36
- when /R16/ then 'R16B03'
37
- when /17/ then '17.1'
38
- end rescue '17'
39
- install_dir = sprintf(TEMPLATE_PATH,revision.downcase)
40
- lines = <<-EOF
32
+ class Erlang
33
+ TEMPLATE_PATH='/opt/install/erlang/%s'
34
+ def self.fulfill data, configuration
35
+ revision = case data[:otp_release].last
36
+ when /R15/ then 'R15B03'
37
+ when /R16/ then 'R16B03'
38
+ when /17/ then '17.1'
39
+ end rescue '17'
40
+ install_dir = sprintf(TEMPLATE_PATH,revision.downcase)
41
+ lines = <<-EOF
41
42
  echo '-s' >> .curlrc
42
43
  curl https://raw.githubusercontent.com/spawngrid/kerl/master/kerl -o /usr/local/bin/kerl
43
44
  chmod a+x /usr/local/bin/kerl
@@ -45,29 +46,29 @@ kerl update releases
45
46
  kerl build #{revision} #{revision}
46
47
  kerl install #{revision} #{install_dir}
47
48
  echo 'source #{install_dir}/activate' >> $HOME/.bashrc
48
- EOF
49
- lines.split(/\n/).each do |line|
50
- s = Script.new line
51
- configuration.put_to_step :init, s
49
+ EOF
50
+ lines.split(/\n/).each do |line|
51
+ s = Script.new line
52
+ configuration.put_to_step :init, s
53
+ end
52
54
  end
53
55
  end
54
- end
55
-
56
- class Ruby
57
- def self.fulfill data, configuration
58
- return unless data[:rvm] # only rvm is supported for ruby
59
- version = data[:rvm].last
60
- lines = <<-EOF
56
+
57
+ class Ruby
58
+ def self.fulfill data, configuration
59
+ return unless data[:rvm] # only rvm is supported for ruby
60
+ version = data[:rvm].last
61
+ lines = <<-EOF
61
62
  echo '-s' >> .curlrc
62
63
  curl -sSL https://get.rvm.io | bash -s stable
63
64
  echo 'source /etc/profile.d/rvm.sh' >> .bashrc
64
65
  rvm install #{version}
65
- EOF
66
- lines.split(/\n/).each do |line|
67
- s = Script.new line
68
- configuration.put_to_step :init, s
66
+ EOF
67
+ lines.split(/\n/).each do |line|
68
+ s = Script.new line
69
+ configuration.put_to_step :init, s
70
+ end
69
71
  end
70
72
  end
71
73
  end
72
74
  end
73
-
@@ -1,21 +1,23 @@
1
- module Larrow::Runner::Manifest
2
- class BaseLoader
3
- attr_accessor :source_accessor,:configuration
4
- def initialize source_accessor
5
- self.source_accessor = source_accessor
6
- end
1
+ module Larrow::Runner
2
+ module Manifest
3
+ class BaseLoader
4
+ attr_accessor :source_accessor,:configuration
5
+ def initialize source_accessor
6
+ self.source_accessor = source_accessor
7
+ end
7
8
 
8
- def load
9
- content = source_accessor.get config_file
10
- return nil if content.nil?
9
+ def load
10
+ content = source_accessor.get config_file
11
+ return nil if content.nil?
11
12
 
12
- self.configuration = Configuration.new
13
- parse content
14
- self.configuration
15
- end
16
-
17
- def config_file
18
- self.class.const_get('CONFIG_FILE')
13
+ self.configuration = Configuration.new
14
+ parse content
15
+ self.configuration
16
+ end
17
+
18
+ def config_file
19
+ self.class.const_get('CONFIG_FILE')
20
+ end
19
21
  end
20
22
  end
21
23
  end
@@ -1,126 +1,128 @@
1
- module Larrow::Runner::Manifest
2
- # The top of manifest model which store Steps information
3
- class Configuration
4
- DEFINED_GROUPS = {
5
- all:[
6
- :init,
7
- :source_sync, #inner step
8
- :prepare,
9
- :compile, :unit_test,
10
- :before_install, #inner_step
11
- :install, :functional_test,
12
- :before_start, #inner_step
13
- :start, :integration_test,
14
- :after_start, :complete #inner_step
15
- ],
16
- custom: [
17
- :init,
18
- :prepare,
19
- :compile, :unit_test,
20
- :install, :functional_test,
21
- :start, :integration_test,
22
- ],
23
- deploy: [
24
- :init,:source_sync,:prepare,
25
- :compile,:before_install,:install,
26
- :before_start,:start,:after_start,
27
- :complete
28
- ],
29
- image: [:init]
30
- }
31
-
32
- attr_accessor :steps, :image, :source_dir
33
- def initialize
34
- self.steps = {}
35
- self.source_dir = '$HOME/source'
36
- end
37
-
38
- def put_to_step title, *scripts
39
- steps[title] ||= CmdStep.new(nil, title)
40
- steps[title].scripts += scripts.flatten
41
- self
42
- end
43
-
44
- def insert_to_step title, *scripts
45
- steps[title] ||= CmdStep.new(nil, title)
46
- steps[title].scripts.unshift *scripts.flatten
47
- self
48
- end
49
-
50
- def add_source_sync source_accessor
51
- steps[:source_sync] = FunctionStep.new(:source_sync) do |node|
52
- source_accessor.update_source node,source_dir
1
+ module Larrow::Runner
2
+ module Manifest
3
+ # The top of manifest model which store Steps information
4
+ class Configuration
5
+ DEFINED_GROUPS = {
6
+ all:[
7
+ :init,
8
+ :source_sync, #inner step
9
+ :prepare,
10
+ :compile, :unit_test,
11
+ :before_install, #inner_step
12
+ :install, :functional_test,
13
+ :before_start, #inner_step
14
+ :start, :integration_test,
15
+ :after_start, :complete #inner_step
16
+ ],
17
+ custom: [
18
+ :init,
19
+ :prepare,
20
+ :compile, :unit_test,
21
+ :install, :functional_test,
22
+ :start, :integration_test,
23
+ ],
24
+ deploy: [
25
+ :init,:source_sync,:prepare,
26
+ :compile,:before_install,:install,
27
+ :before_start,:start,:after_start,
28
+ :complete
29
+ ],
30
+ image: [:init]
31
+ }
32
+
33
+ attr_accessor :steps, :image, :source_dir
34
+ def initialize
35
+ self.steps = {}
36
+ self.source_dir = '$HOME/source'
53
37
  end
54
- end
55
-
56
- def steps_for type
57
- groups = DEFINED_GROUPS[type]
58
- # ignore init when image id is specified
59
- groups = groups - [:init] if image
60
- groups.each do |title|
61
- yield steps[title] if steps[title]
38
+
39
+ def put_to_step title, *scripts
40
+ steps[title] ||= CmdStep.new(nil, title)
41
+ steps[title].scripts += scripts.flatten
42
+ self
62
43
  end
63
- end
64
-
65
- def dump
66
- data = DEFINED_GROUPS[:all].reduce({}) do |sum,title|
67
- next sum if steps[title].nil?
68
- scripts_data = steps[title].scripts.map(&:dump).compact
69
- sum.update title.to_s => scripts_data
44
+
45
+ def insert_to_step title, *scripts
46
+ steps[title] ||= CmdStep.new(nil, title)
47
+ steps[title].scripts.unshift *scripts.flatten
48
+ self
70
49
  end
71
- YAML.dump data
72
- end
73
- end
74
-
75
- # Describe a set of scripts to accomplish a specific goal
76
- class CmdStep
77
- attr_accessor :scripts, :title
78
- def initialize scripts, title
79
- self.scripts = scripts || []
80
- self.title = title
81
- end
82
-
83
- def run_on node
84
- scripts.each do |script|
85
- node.execute script.actual_command, base_dir: script.base_dir
50
+
51
+ def add_source_sync source_accessor
52
+ steps[:source_sync] = FunctionStep.new(:source_sync) do |node|
53
+ source_accessor.update_source node,source_dir
54
+ end
55
+ end
56
+
57
+ def steps_for type
58
+ groups = DEFINED_GROUPS[type]
59
+ # ignore init when image id is specified
60
+ groups = groups - [:init] if image
61
+ groups.each do |title|
62
+ yield steps[title] if steps[title]
63
+ end
64
+ end
65
+
66
+ def dump
67
+ data = DEFINED_GROUPS[:all].reduce({}) do |sum,title|
68
+ next sum if steps[title].nil?
69
+ scripts_data = steps[title].scripts.map(&:dump).compact
70
+ sum.update title.to_s => scripts_data
71
+ end
72
+ YAML.dump data
86
73
  end
87
74
  end
88
- end
89
-
90
- # An abstract step which bind business logic with block
91
- # This class designed for some typically service,eg:
92
- # * local file folder sync
93
- # * some service invoke
94
- class FunctionStep
95
- attr_accessor :block, :title
96
- def initialize title, &block
97
- self.title = title
98
- self.block = block
99
- end
100
-
101
- def run_on node
102
- block.call node
103
- end
104
- end
105
-
106
- # store the real command line
107
- # :cannt_fail used to declare `non-zero retcode of current script will be fail`
108
- class Script
109
- attr_accessor :cmd, :base_dir, :args, :cannt_fail
110
- def initialize cmd, base_dir:nil, args:{}, cannt_fail: true
111
- self.cmd = cmd
112
- self.args = args
113
- self.cannt_fail = cannt_fail
114
- self.base_dir = base_dir
75
+
76
+ # Describe a set of scripts to accomplish a specific goal
77
+ class CmdStep
78
+ attr_accessor :scripts, :title
79
+ def initialize scripts, title
80
+ self.scripts = scripts || []
81
+ self.title = title
82
+ end
83
+
84
+ def run_on node
85
+ scripts.each do |script|
86
+ node.execute script.actual_command, base_dir: script.base_dir
87
+ end
88
+ end
115
89
  end
116
-
117
- def actual_command
118
- sprintf(cmd, args)
90
+
91
+ # An abstract step which bind business logic with block
92
+ # This class designed for some typically service,eg:
93
+ # * local file folder sync
94
+ # * some service invoke
95
+ class FunctionStep
96
+ attr_accessor :block, :title
97
+ def initialize title, &block
98
+ self.title = title
99
+ self.block = block
100
+ end
101
+
102
+ def run_on node
103
+ block.call node
104
+ end
119
105
  end
120
-
121
- def dump
122
- return nil if cmd.empty?
123
- cmd
106
+
107
+ # store the real command line
108
+ # :cannt_fail used to declare `non-zero retcode of current script will be fail`
109
+ class Script
110
+ attr_accessor :cmd, :base_dir, :args, :cannt_fail
111
+ def initialize cmd, base_dir:nil, args:{}, cannt_fail: true
112
+ self.cmd = cmd
113
+ self.args = args
114
+ self.cannt_fail = cannt_fail
115
+ self.base_dir = base_dir
116
+ end
117
+
118
+ def actual_command
119
+ sprintf(cmd, args)
120
+ end
121
+
122
+ def dump
123
+ return nil if cmd.empty?
124
+ cmd
125
+ end
124
126
  end
125
127
  end
126
128
  end