lono 7.1.0 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +3 -1
  3. data/.cody/acceptance.sh +2 -0
  4. data/.cody/buildspec.yml +3 -0
  5. data/.cody/project.rb +1 -1
  6. data/CHANGELOG.md +5 -0
  7. data/lib/lono/cli.rb +12 -0
  8. data/lib/lono/configset/combiner.rb +1 -1
  9. data/lib/lono/configset/meta/dsl.rb +1 -1
  10. data/lib/lono/configset/preparer.rb +5 -5
  11. data/lib/lono/configset/register/base.rb +2 -1
  12. data/lib/lono/configset/register/dsl.rb +2 -3
  13. data/lib/lono/configset/resolver.rb +1 -0
  14. data/lib/lono/extension.rb +9 -0
  15. data/lib/lono/extension/helper.rb +13 -0
  16. data/lib/lono/extension/list.rb +39 -0
  17. data/lib/lono/extension/new.rb +72 -0
  18. data/lib/lono/extensions.rb +18 -0
  19. data/lib/lono/extensions/dsl.rb +11 -0
  20. data/lib/lono/extensions/loader.rb +32 -0
  21. data/lib/lono/extensions/preparer.rb +23 -0
  22. data/lib/lono/extensions/register.rb +15 -0
  23. data/lib/lono/finder/base.rb +3 -3
  24. data/lib/lono/finder/extension.rb +11 -0
  25. data/lib/lono/help/user_data.md +0 -1
  26. data/lib/lono/jade.rb +24 -17
  27. data/lib/lono/jade/circular.rb +1 -1
  28. data/lib/lono/{configset/materializer/jade.rb → jade/materializer.rb} +3 -3
  29. data/lib/lono/{configset → jade}/materializer/final.rb +1 -1
  30. data/lib/lono/{configset → jade}/materializer/gems_builder.rb +3 -3
  31. data/lib/lono/{configset → jade}/materializer/source.rb +1 -1
  32. data/lib/lono/jade/registry.rb +55 -0
  33. data/lib/lono/template/context.rb +1 -2
  34. data/lib/lono/template/context/loader.rb +19 -13
  35. data/lib/lono/template/context/loader/load_files.rb +24 -0
  36. data/lib/lono/template/helper.rb +0 -42
  37. data/lib/lono/template/strategy/common/helpers.rb +44 -0
  38. data/lib/lono/template/strategy/dsl.rb +3 -8
  39. data/lib/lono/template/strategy/dsl/builder.rb +12 -17
  40. data/lib/lono/template/strategy/dsl/builder/helpers.rb +2 -0
  41. data/lib/lono/template/strategy/dsl/builder/helpers/file_helper.rb +2 -2
  42. data/lib/lono/template/strategy/dsl/builder/syntax.rb +2 -1
  43. data/lib/lono/template/strategy/dsl/builder/syntax/extend_with.rb +9 -0
  44. data/lib/lono/template/strategy/dsl/builder/{section/extensions.rb → syntax/parameter_group.rb} +2 -2
  45. data/lib/lono/version.rb +1 -1
  46. data/lib/templates/extension/%extension_name%.gemspec.tt +45 -0
  47. data/lib/templates/extension/.gitignore +17 -0
  48. data/lib/templates/extension/.rspec +3 -0
  49. data/lib/templates/extension/CHANGELOG.md +7 -0
  50. data/lib/templates/extension/Gemfile.tt +4 -0
  51. data/lib/templates/extension/Rakefile.tt +9 -0
  52. data/lib/templates/extension/lib/%extension_name%.rb.tt +5 -0
  53. data/lib/templates/extension/lib/%extension_name%/helpers/mappings.rb.tt +24 -0
  54. data/lib/templates/extension/lib/%extension_name%/helpers/outputs.rb.tt +7 -0
  55. data/lib/templates/extension/lib/%extension_name%/helpers/parameters.rb.tt +10 -0
  56. data/lib/templates/extension/lib/%extension_name%/helpers/resources/resource.rb.tt +4 -0
  57. data/lib/templates/extension/lib/%extension_name%/helpers/variables.rb.tt +6 -0
  58. data/lib/templates/extension/lib/%extension_name%/version.rb.tt +3 -0
  59. data/lib/templates/extension/spec/spec_helper.rb.tt +29 -0
  60. data/lono.gemspec +1 -0
  61. metadata +49 -8
  62. data/lib/lono/configset/registry.rb +0 -34
@@ -0,0 +1,11 @@
1
+ module Lono::Finder
2
+ class Extension < Base
3
+ def type
4
+ "extension"
5
+ end
6
+
7
+ def detection_path
8
+ "lib/*/helpers"
9
+ end
10
+ end
11
+ end
@@ -30,7 +30,6 @@ Running `lono user_data bootstrap` produces:
30
30
  aws s3 cp s3://mybucket/path/to/folder/development/scripts/scripts-93b8b29b.tgz /opt/
31
31
  cd /opt
32
32
  tar zxf /opt/scripts-93b8b29b.tgz
33
- chmod -R a+x /opt/scripts
34
33
  chown -R ec2-user:ec2-user /opt/scripts
35
34
 
36
35
  SCRIPTS=/opt/scripts
data/lib/lono/jade.rb CHANGED
@@ -2,10 +2,6 @@ module Lono
2
2
  class Jade
3
3
  include Circular
4
4
  extend Memoist
5
- class_attribute :tracked
6
- self.tracked = []
7
- class_attribute :downloaded
8
- self.downloaded = []
9
5
 
10
6
  delegate :source_type, to: :jadespec
11
7
 
@@ -18,7 +14,6 @@ module Lono
18
14
  @materialized = false
19
15
  @resolved = false
20
16
  @depends_ons = []
21
- self.class.tracked << self
22
17
  end
23
18
 
24
19
  def repo
@@ -34,7 +29,9 @@ module Lono
34
29
 
35
30
  def dependencies
36
31
  @depends_ons.map do |registry|
37
- Lono::Jade.new(registry.depends_on, registry.parent.type, registry)
32
+ jade = Lono::Jade.new(registry.depends_on, registry.parent.type, registry) # not same sig as register_configset?
33
+ Lono::Jade::Registry.tracked_configsets << jade
34
+ jade
38
35
  end
39
36
  end
40
37
 
@@ -56,7 +53,12 @@ module Lono
56
53
  return nil unless @jadespec
57
54
  if @jadespec.source_type == "materialized"
58
55
  # possible "duplicated" jade instances with same name but will uniq in final materialized Gemfile
59
- self.class.downloaded << self
56
+ case @jadespec.lono_type
57
+ when "configset"
58
+ Lono::Jade::Registry.downloaded_configsets << self
59
+ when "extension"
60
+ Lono::Jade::Registry.downloaded_extensions << self
61
+ end
60
62
  end
61
63
  evaluate_meta_rb
62
64
  @jadespec
@@ -66,18 +68,23 @@ module Lono
66
68
  # Must return config to set @jadespec in materialize
67
69
  # Only allow download of Lono::Blueprint::Configset::Jade
68
70
  # Other configsets should be configured in project Gemfile.
71
+ #
72
+ # Cases:
73
+ #
74
+ # 1a) blueprint/configset top-level - download
75
+ # 1b) blueprint/configset depends_on - download
76
+ # 2a) configset top-level - dont download, will report to user with validate_all!
77
+ # 2b) configset depends_on - download
78
+ # 3) extension - download
79
+ #
69
80
  def download
70
81
  return if finder.find(@name, local_only: true) # no need to download because locally found
71
- # 4 cases:
72
- # 1a) blueprint/configset top-level - download
73
- # 1b) blueprint/configset depends_on - download
74
- # 2a) configset top-level - dont download, will report to user with validate_all!
75
- # 2b) configset depends_on - download
76
- return unless %w[blueprint/configset configset].include?(@type) # TODO: support materializing nested blueprints later
77
- # only download jades that came from depends_on
78
- return unless @registry.parent || @type == "blueprint/configset"
79
- jade = Lono::Configset::Materializer::Jade.new(self)
80
- jade.build
82
+ return unless %w[blueprint/configset configset extension].include?(@type)
83
+ # Comment out. Unsure if this complexity is worth it. Always download jades.
84
+ # Only download jades that came from depends_on
85
+ # return unless @registry.parent || %w[blueprint/configset extension].include?(@type)
86
+ materializer = Materializer.new(self)
87
+ materializer.build
81
88
  end
82
89
  memoize :download
83
90
 
@@ -4,7 +4,7 @@ class Lono::Jade
4
4
  circular = circular_dependency?
5
5
  return unless circular
6
6
 
7
- puts "ERROR: configset circular dependency detected".color(:red)
7
+ puts "ERROR: jade circular dependency detected".color(:red)
8
8
  puts "circular dependency: #{parent_names.join(" => ")}"
9
9
  exit 1
10
10
  end
@@ -1,7 +1,7 @@
1
1
  require "bundler"
2
2
 
3
- module Lono::Configset::Materializer
4
- class Jade
3
+ class Lono::Jade
4
+ class Materializer
5
5
  extend Memoist
6
6
 
7
7
  def initialize(jade)
@@ -9,7 +9,7 @@ module Lono::Configset::Materializer
9
9
  end
10
10
 
11
11
  def build
12
- GemsBuilder.new(@jade).build
12
+ Materializer::GemsBuilder.new(@jade).build
13
13
  end
14
14
  end
15
15
  end
@@ -1,4 +1,4 @@
1
- module Lono::Configset::Materializer
1
+ class Lono::Jade::Materializer
2
2
  class Final
3
3
  def build(jades)
4
4
  return if jades.empty?
@@ -1,12 +1,12 @@
1
1
  require 'open3'
2
2
 
3
- module Lono::Configset::Materializer
3
+ class Lono::Jade::Materializer
4
4
  class GemsBuilder
5
5
  extend Memoist
6
6
 
7
7
  def initialize(*jades)
8
8
  @jades = jades.flatten
9
- @build_root = "#{Lono.root}/tmp/configsets"
9
+ @build_root = "#{Lono.root}/tmp/jades"
10
10
  end
11
11
 
12
12
  def build
@@ -51,7 +51,7 @@ module Lono::Configset::Materializer
51
51
  puts stdout
52
52
  puts stderr
53
53
  if stderr.include?("correct access rights")
54
- puts "Are you sure you have access to the git repo?".color(:yellow)
54
+ puts "Are you sure you have access to the git repo and the repo exists?".color(:yellow)
55
55
  end
56
56
  exit 1
57
57
  end
@@ -1,4 +1,4 @@
1
- module Lono::Configset::Materializer
1
+ class Lono::Jade::Materializer
2
2
  class Source
3
3
  def initialize(lono_settings=nil)
4
4
  @lono_settings = lono_settings || Lono::Setting.new.data
@@ -0,0 +1,55 @@
1
+ class Lono::Jade
2
+ class Registry
3
+ attr_reader :args, :options
4
+ attr_accessor :caller_line, :parent, :depends_on
5
+ def initialize(args, options)
6
+ @args, @options = args, options
7
+ end
8
+
9
+ def name
10
+ @args.first
11
+ end
12
+
13
+ def gem_options
14
+ options = @options.dup
15
+ # Delete special options that is not supported by bundler Gemfile
16
+ options.delete(:repo)
17
+ options.delete(:resource) # configset
18
+ options.delete(:vars) # configset
19
+ options
20
+ end
21
+
22
+ # configset
23
+ def resource
24
+ @options[:resource]
25
+ end
26
+
27
+ def resource=(v)
28
+ @options[:resource] = v
29
+ end
30
+
31
+ def vars
32
+ options[:vars] || {}
33
+ end
34
+
35
+ class_attribute :tracked_configsets, default: []
36
+ class_attribute :downloaded_configsets, default: []
37
+ class_attribute :tracked_extensions, default: []
38
+ class_attribute :downloaded_extensions, default: []
39
+
40
+ class << self
41
+ def register_configset(args, options)
42
+ registry = new(args, options)
43
+ jade = Lono::Jade.new(registry.name, 'configset', registry)
44
+ self.tracked_configsets << jade
45
+ registry
46
+ end
47
+
48
+ def register_extension(args, options)
49
+ registry = new(args, options)
50
+ self.tracked_extensions << registry
51
+ registry
52
+ end
53
+ end
54
+ end
55
+ end
@@ -9,8 +9,7 @@ class Lono::Template
9
9
 
10
10
  def initialize(options={})
11
11
  super
12
- load_variables
13
- load_project_helpers
12
+ load_context
14
13
  end
15
14
 
16
15
  # Take a hash and makes them instance variables in the current scope.
@@ -1,6 +1,20 @@
1
1
  class Lono::Template::Context
2
2
  module Loader
3
+ include LoadFiles
4
+
3
5
  private
6
+ # Not using Lono::Template::Context because that works differently.
7
+ # That is used to load a context object that is passed to RenderMePretty's context.
8
+ # So that we can load context for params files and erb templates.
9
+ #
10
+ # In this case builder is actually the dsl context.
11
+ # We want to load variables and helpers into this builder context directly.
12
+ # This loads additional context. It looks very similar to Lono::Template::Context
13
+ def load_context
14
+ load_variables
15
+ load_helpers
16
+ end
17
+
4
18
  # Variables in base.rb are overridden by their environment specific variables
5
19
  # file. Example, file LONO_ENV=development:
6
20
  #
@@ -27,20 +41,12 @@ class Lono::Template::Context
27
41
  end
28
42
 
29
43
  # Load custom helper methods from project
30
- def load_project_helpers
31
- Dir.glob("#{Lono.config.helpers_path}/**/*.rb").each do |path|
32
- filename = path.sub("#{Lono.config.helpers_path}/",'').sub('.rb','')
33
- module_name = filename.camelize
44
+ def load_helpers
45
+ load_project_helpers # project helpers will override extension helpers
46
+ end
34
47
 
35
- # Prepend a period so require works LONO_ROOT is set to a relative path
36
- # without a period.
37
- #
38
- # Example: LONO_ROOT=tmp/lono_project
39
- first_char = path[0..0]
40
- path = "./#{path}" unless %w[. /].include?(first_char)
41
- require path
42
- self.class.send :include, module_name.constantize
43
- end
48
+ def load_project_helpers
49
+ load_files(Lono.config.helpers_path)
44
50
  end
45
51
  end
46
52
  end
@@ -0,0 +1,24 @@
1
+ module Lono::Template::Context::Loader
2
+ module LoadFiles
3
+ # Load custom helper methods from project
4
+ def load_files(root)
5
+ paths = Dir.glob("#{root}/**/*.rb")
6
+ paths.sort_by! { |p| p.size } # so namespaces are loaded first
7
+ paths.each do |path|
8
+ # lib = gem extensions
9
+ # app = project extensions
10
+ filename = path.sub(%r{.*/lib/},'').sub(%r{.*/app/helpers/},'').sub('.rb','')
11
+ module_name = filename.camelize
12
+
13
+ # Prepend a period so require works LONO_ROOT is set to a relative path without a period.
14
+ #
15
+ # Example: LONO_ROOT=tmp/lono_project
16
+ first_char = path[0..0]
17
+ path = "./#{path}" unless %w[. /].include?(first_char)
18
+
19
+ require path
20
+ self.class.send :include, module_name.constantize
21
+ end
22
+ end
23
+ end
24
+ end
@@ -7,44 +7,6 @@ require "aws-sdk-core"
7
7
  #
8
8
  # Lono::Template::Context.new(blueprint, @options)
9
9
  module Lono::Template::Helper
10
- # Bash code that is meant to included in user-data
11
- def extract_scripts(options={})
12
- settings = setting.data["extract_scripts"] || {}
13
- options = settings.merge(options)
14
- # defaults also here in case they are removed from settings
15
- to = options[:to] || "/opt"
16
- user = options[:as] || "ec2-user"
17
-
18
- if Dir.glob("#{Lono.config.scripts_path}/*").empty?
19
- puts "WARN: you are using the extract_scripts helper method but you do not have any app/scripts.".color(:yellow)
20
- calling_line = caller[0].split(':')[0..1].join(':')
21
- puts "Called from: #{calling_line}"
22
- return ""
23
- end
24
-
25
- <<-BASH_CODE
26
- # Generated from the lono extract_scripts helper.
27
- # Downloads scripts from s3, extract them, and setup.
28
- mkdir -p #{to}
29
- aws s3 cp #{scripts_s3_path} #{to}/
30
- (
31
- cd #{to}
32
- tar zxf #{to}/#{scripts_name}
33
- chmod -R a+x #{to}/scripts
34
- chown -R #{user}:#{user} #{to}/scripts
35
- )
36
- BASH_CODE
37
- end
38
-
39
- def scripts_name
40
- File.basename(scripts_s3_path)
41
- end
42
-
43
- def scripts_s3_path
44
- upload = Lono::Script::Upload.new(@options)
45
- upload.s3_dest
46
- end
47
-
48
10
  def template_s3_path(template_name)
49
11
  # high jacking Upload for useful s3_https_url method
50
12
  template_path = "output/#{@blueprint}/templates/#{template_name}.yml"
@@ -188,8 +150,4 @@ private
188
150
 
189
151
  path # original path if this point is reached
190
152
  end
191
-
192
- def setting
193
- @setting ||= Lono::Setting.new
194
- end
195
153
  end
@@ -0,0 +1,44 @@
1
+ module Lono::Template::Strategy::Common
2
+ module Helpers
3
+ # Bash code that is meant to included in user-data
4
+ def extract_scripts(options={})
5
+ settings = setting.data["extract_scripts"] || {}
6
+ options = settings.merge(options)
7
+ # defaults also here in case they are removed from settings
8
+ to = options[:to] || "/opt"
9
+ user = options[:as] || "ec2-user"
10
+
11
+ if Dir.glob("#{Lono.config.scripts_path}/*").empty?
12
+ puts "WARN: you are using the extract_scripts helper method but you do not have any app/scripts.".color(:yellow)
13
+ calling_line = caller[0].split(':')[0..1].join(':')
14
+ puts "Called from: #{calling_line}"
15
+ return ""
16
+ end
17
+
18
+ <<~BASH_CODE
19
+ # Generated from the lono extract_scripts helper.
20
+ # Downloads scripts from s3, extract them, and setup.
21
+ mkdir -p #{to}
22
+ aws s3 cp #{scripts_s3_path} #{to}/
23
+ (
24
+ cd #{to}
25
+ tar zxf #{to}/#{scripts_name}
26
+ chown -R #{user}:#{user} #{to}/scripts
27
+ )
28
+ BASH_CODE
29
+ end
30
+
31
+ def scripts_name
32
+ File.basename(scripts_s3_path)
33
+ end
34
+
35
+ def scripts_s3_path
36
+ upload = Lono::Script::Upload.new(@options)
37
+ upload.s3_dest
38
+ end
39
+
40
+ def setting
41
+ @setting ||= Lono::Setting.new
42
+ end
43
+ end
44
+ end
@@ -1,18 +1,13 @@
1
1
  module Lono::Template::Strategy
2
2
  class Dsl < Base
3
3
  attr_reader :results
4
- def initialize(options={})
5
- super
6
- end
7
-
8
4
  def run
9
5
  puts "Generating CloudFormation templates for blueprint #{@blueprint.color(:green)}:" unless @options[:quiet]
10
- template_path = "#{Lono.config.templates_path}/#{@template}.rb"
11
- build_template(template_path)
6
+ build_template
12
7
  end
13
8
 
14
- def build_template(path)
15
- builder = Builder.new(path, @blueprint, @options)
9
+ def build_template
10
+ builder = Builder.new(@options)
16
11
  builder.build
17
12
  end
18
13
  end
@@ -6,22 +6,29 @@ class Lono::Template::Strategy::Dsl
6
6
  include Syntax
7
7
  extend Memoist
8
8
 
9
- def initialize(path, blueprint, options={})
10
- @path, @blueprint, @options = path, blueprint, options
11
- @template = @path.sub("#{Lono.config.templates_path}/",'').sub(/\.rb$/,'')
9
+ def initialize(options={})
10
+ @options = options
11
+ @stack, @blueprint, @template, @param = Lono::Conventions.new(options).values
12
+ @template_path = "#{Lono.config.templates_path}/#{@template}.rb"
12
13
  @parameters = [] # registry
13
14
  @cfn = {}
14
15
  end
15
16
 
16
17
  def build
17
- load_context
18
- evaluate_template_path(@path) # modifies @cfn
18
+ load_extensions # load_extensions before project helpers
19
+ load_context # variables and project helpers
20
+ evaluate_template_path(@template_path) # modifies @cfn
19
21
  finalize
20
22
  to_yaml
21
23
  write_output
22
24
  @cfn
23
25
  end
24
26
 
27
+ # load_extensions and evaluate extend_with methods earlier than load_context so project helpers can override extensions
28
+ def load_extensions # evaluates extend_with
29
+ Lono::Extensions::Preparer.new(@options).run
30
+ end
31
+
25
32
  def finalize
26
33
  o = @options.merge(parameters: @parameters)
27
34
  @cfn = Finalizer.new(@cfn, o).run
@@ -46,17 +53,5 @@ class Lono::Template::Strategy::Dsl
46
53
  puts " #{pretty_path}"
47
54
  end
48
55
  end
49
-
50
- # Not using Lono::Template::Context because that works differently.
51
- # That is used to load a context object that is passed to RenderMePretty's context.
52
- # So that we can load context for params files and erb templates.
53
- #
54
- # In this case builder is actually the dsl context.
55
- # We want to load variables and helpers into this builder context directly.
56
- # This loads additional context. It looks very similar to Lono::Template::Context
57
- def load_context
58
- load_variables
59
- load_project_helpers
60
- end
61
56
  end
62
57
  end