kafo 0.7.6 → 0.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 35bc59bbfe6e1ff266439493be2e8c8342c6a2d9
4
- data.tar.gz: e3dd61d73c8799f13d66f5774c03d3b84d7a7196
3
+ metadata.gz: 6bce70ac2eb5590a3268fc61fa1d5b26eec0a231
4
+ data.tar.gz: 6c68b15f3208c75fd702601f5059c355d3e98383
5
5
  SHA512:
6
- metadata.gz: 7f4247cd5325ec3c2b78008e92f9cc3e6b149f04a44280e619f8025b688387766a18228652acc47588a14e69652f3d3fdd072ec18d820f505ea963920e6647bc
7
- data.tar.gz: 14109f9b4d7de650e88c601ea1b247b4eb85979b1445d39740fa80d023e75d764e844c73cd11fdba5c32301490c51615f96952f2d16688a3e9bfbeba3dd917eb
6
+ metadata.gz: a749d272c84c6a4ff863c9c67438e3f1e046b5949d4e4c491032d533d05fabe5f31c52e672bccd6d3c444bf056ca636894c878fcaf9dc0c745161a039a34f17a
7
+ data.tar.gz: 54587849902f34872edc974a28fa11a63adb20f5000dd7086b534d325681fb1af69b0fef0eaf11d7116a81496826d20240b6f8746a7e623fb5aa4c188f3fb256
data/README.md CHANGED
@@ -190,6 +190,25 @@ disable saving answer by passing a ```--dont-save-answers``` argument (or -d for
190
190
 
191
191
  Note that running ```--noop``` implies ```--dont-save-answers```.
192
192
 
193
+ ## Executing Puppet with multiple versions
194
+
195
+ Kafo calls the `puppet` binary during an installer run to both compute default
196
+ parameter values and perform the actual installer changes. This relies on
197
+ `puppet` being in the PATH environment variable or as fallback, in
198
+ `/opt/puppetlabs/bin`.
199
+
200
+ When using Puppet via a Gemfile, Bundler should set up PATH to point at the
201
+ gem version. If using a system/packaged version, it will typically find and
202
+ execute /usr/bin/puppet from the regular PATH.
203
+
204
+ When using an AIO/PC1 packaged version of Puppet, other versions of Puppet from
205
+ PATH will be preferred if they exist, so they should either be removed or PATH
206
+ set to prefer /opt/puppetlabs/bin, i.e. `export PATH=/opt/puppetlabs/bin:$PATH`.
207
+ Debug logs from Kafo should indicate the full path of the binary used.
208
+
209
+ Note that Kafo parsers supports specific versions of Puppet, and may require
210
+ extra modules (such as puppet-strings on Puppet 4+) to parse manifests.
211
+
193
212
  ## Parameters prefixes
194
213
 
195
214
  As a default every module parameter is prefixed by the module name.
@@ -317,6 +336,13 @@ Sample migration adding new module could look like as follows:
317
336
  EOF
318
337
  ```
319
338
 
339
+ The migration can also call `facts`, which returns a hash of symbol fact names to values (from
340
+ Facter), to help determine new parameter values.
341
+
342
+ ```ruby
343
+ answers['module']['foo'] = 'bar' if facts[:osfamily] == 'Debian'
344
+ ```
345
+
320
346
  ### Enabling/disabling scenarios
321
347
 
322
348
  Scenarios that are deprecated or wanted to be hidden on the system can be disabled with:
@@ -631,11 +657,13 @@ If you use "params_path" for this purpose, "params_name" is ignored.
631
657
  ## Validations
632
658
 
633
659
  If you specify validations of parameters in your init.pp manifest they
634
- will be replaced with your values even before puppet is run. In order to do this
660
+ will be replaced with your values even before Puppet is run. In order to do this
635
661
  you must follow a few rules however:
636
662
 
637
663
  * you must use standard validation functions (e.g. validate_array, validate_re, ...)
638
- * you must have stdlib in modules directory
664
+
665
+ These functions are re-implemented in Kafo from common stdlib functions, so please
666
+ contribute any missing ones.
639
667
 
640
668
  ## Enabling or disabling module
641
669
 
@@ -85,7 +85,7 @@ module Kafo
85
85
  end
86
86
 
87
87
  def modules
88
- @modules ||= @data.keys.map { |mod| PuppetModule.new(mod, KafoParsers::PuppetModuleParser, self).parse }.sort
88
+ @modules ||= @data.keys.map { |mod| PuppetModule.new(mod, PuppetModule.find_parser, self).parse }.sort
89
89
  end
90
90
 
91
91
  def root_dir
@@ -109,7 +109,7 @@ module Kafo
109
109
  end
110
110
 
111
111
  def add_module(name)
112
- mod = PuppetModule.new(name, KafoParsers::PuppetModuleParser, self).parse
112
+ mod = PuppetModule.new(name, PuppetModule.find_parser, self).parse
113
113
  unless modules.map(&:name).include?(mod.name)
114
114
  mod.enable
115
115
  @modules << mod
@@ -233,16 +233,8 @@ module Kafo
233
233
  File.join(app[:log_dir], app[:log_name])
234
234
  end
235
235
 
236
- def log_files_pattern
237
- log_file.sub(/(\.log)\Z/i) { |suffix| "{.[0-9]*,}#{suffix}" }
238
- end
239
-
240
- def log_files
241
- Dir.glob(log_files_pattern)
242
- end
243
-
244
236
  def log_exists?
245
- log_files.any? { |f| File.size(f) > 0 }
237
+ File.exists?(log_file) && File.size(log_file) > 0
246
238
  end
247
239
 
248
240
  def answers
@@ -259,7 +251,6 @@ module Kafo
259
251
  migrations.store_applied
260
252
  @logger.info("#{migrations.migrations.count} migration/s were applied. Updated configuration was saved.")
261
253
  end
262
- migrations.migrations.count
263
254
  end
264
255
 
265
256
  def migrations_dir
@@ -6,6 +6,9 @@ module Kafo
6
6
  class ConditionError < StandardError
7
7
  end
8
8
 
9
+ class ParserError < StandardError
10
+ end
11
+
9
12
  class TypeError < StandardError
10
13
  end
11
14
  end
@@ -57,9 +57,9 @@ module Kafo
57
57
  setup_config(config_file)
58
58
 
59
59
  self.class.hooking.execute(:pre_migrations)
60
- reload_config
61
- applied_total = self.class.config.run_migrations
62
- request_config_reload if applied_total > 0
60
+
61
+ # run migrations
62
+ self.class.config.run_migrations
63
63
 
64
64
  if ARGV.include?('--migrations-only')
65
65
  self.class.verbose = (ARGV.include?('--verbose') || ARGV.include?('-v'))
@@ -68,7 +68,13 @@ module Kafo
68
68
  self.class.exit(0)
69
69
  end
70
70
 
71
- reload_config
71
+ # reload config
72
+ if @config_reload_requested
73
+ scenario_manager = setup_scenario_manager
74
+ self.class.scenario_manager = scenario_manager
75
+ setup_config(self.class.config_file)
76
+ self.class.logger.info('Installer configuration was reloaded')
77
+ end
72
78
 
73
79
  if scenario_manager.configured?
74
80
  scenario_manager.check_scenario_change(self.class.config_file)
@@ -235,16 +241,6 @@ module Kafo
235
241
  self.class.hooking.kafo = self
236
242
  end
237
243
 
238
- def reload_config
239
- if @config_reload_requested
240
- scenario_manager = setup_scenario_manager
241
- self.class.scenario_manager = scenario_manager
242
- setup_config(self.class.config_file)
243
- self.class.logger.info('Installer configuration was reloaded')
244
- @config_reload_requested = false
245
- end
246
- end
247
-
248
244
  def setup_scenario_manager
249
245
  ScenarioManager.new((defined?(CONFIG_DIR) && CONFIG_DIR) || (defined?(CONFIG_FILE) && CONFIG_FILE))
250
246
  end
data/lib/kafo/logger.rb CHANGED
@@ -105,7 +105,7 @@ module Kafo
105
105
 
106
106
  def self.dump_buffer(buffer)
107
107
  buffer.each do |log|
108
- self.loggers.each { |logger| logger.send log[0], *([log[1]].flatten(1)), &log[2] }
108
+ self.loggers.each { |logger| logger.send log[0], *log[1], &log[2] }
109
109
  end
110
110
  buffer.clear
111
111
  end
@@ -17,5 +17,21 @@ module Kafo
17
17
  def logger
18
18
  KafoConfigure.logger
19
19
  end
20
+
21
+ def facts
22
+ self.class.facts
23
+ end
24
+
25
+ private
26
+
27
+ def self.facts
28
+ @facts ||= begin
29
+ YAML.load(`#{facter_path} --yaml`).inject({}) { |facts,(k,v)| facts.update(k.to_sym => v) }
30
+ end
31
+ end
32
+
33
+ def self.facter_path
34
+ @facter_path ||= PuppetCommand.search_puppet_path('facter')
35
+ end
20
36
  end
21
37
  end
data/lib/kafo/param.rb CHANGED
@@ -73,24 +73,20 @@ module Kafo
73
73
  end
74
74
 
75
75
  def valid?
76
- validations = self.module.validations(self)
77
76
  # we get validations that can also run on other arguments, we need to take only current param
78
77
  # also we want to clone validations so we don't interfere
79
- validations.map! do |v|
80
- v = v.clone
81
- if v.name == 'validate_re'
82
- # validate_re does not take more variables as arguments, instead we need to pass all arguments
83
- args = v.arguments
78
+ validations = self.module.validations(self).map do |v|
79
+ # These functions do not take more variables as arguments, instead we need to pass all arguments
80
+ if v.name == 'validate_re' || v.name == 'validate_integer'
81
+ args = v.arguments.to_a
84
82
  else
85
83
  args = v.arguments.select { |a| a.to_s == "$#{self.name}" }
86
84
  end
87
- v.arguments = Puppet::Parser::AST::ASTArray.new :children => args
88
- v
85
+ {:name => v.name, :arguments => interpret_validation_args(args)}
89
86
  end
90
87
 
91
- validator = Validator.new([self])
92
- validations.map! { |v| v.evaluate(validator) }
93
- validations.all?
88
+ validator = Validator.new
89
+ validations.all? { |v| validator.send(v[:name], v[:arguments]) }
94
90
  end
95
91
 
96
92
  # To be overwritten in children
@@ -119,6 +115,24 @@ module Kafo
119
115
  def evaluate_condition(context = [])
120
116
  Condition.new(condition, context).evaluate
121
117
  end
118
+
119
+ def interpret_validation_args(args)
120
+ args.map do |arg|
121
+ if arg.to_s == "$#{self.name}"
122
+ self.value
123
+ elsif arg.class.name == 'Puppet::Parser::AST::ASTArray'
124
+ interpret_validation_args(arg.to_a)
125
+ elsif arg.class.name == 'Puppet::Parser::AST::Concat'
126
+ interpret_validation_args(arg.value).join
127
+ elsif arg.respond_to? :value
128
+ arg.value
129
+ else
130
+ arg
131
+ end
132
+ end.map do |arg|
133
+ arg == :undef ? nil : arg
134
+ end
135
+ end
122
136
  end
123
137
  end
124
138
 
@@ -13,6 +13,7 @@ module Kafo
13
13
  @lines = 0
14
14
  @all_lines = 0
15
15
  @total = :unknown
16
+ @term_width = HighLine::SystemExtensions.terminal_size[0]
16
17
  @bar = PowerBar.new
17
18
  @bar.settings.tty.infinite.template.main = infinite_template
18
19
  @bar.settings.tty.finite.template.main = finite_template
@@ -5,7 +5,8 @@ module Kafo
5
5
  private
6
6
 
7
7
  def finite_template
8
- 'Installing'.ljust(22) + ' ${<msg>} [${<percent>%}] [${<bar>}]'
8
+ 'Installing'.ljust(22) + ' ${<msg>} [${<percent>%}]' +
9
+ (@term_width >= 83 ? ' [${<bar>}]' : '')
9
10
  end
10
11
 
11
12
  def infinite_template
@@ -16,7 +16,7 @@ module Kafo
16
16
  'Installing'.ljust(22) +
17
17
  ANSI::Code.yellow { ' ${<msg>}' } +
18
18
  ANSI::Code.green { ' [${<percent>%}]' } +
19
- ' [${<bar>}]'
19
+ (@term_width >= 83 ? ' [${<bar>}]' : '')
20
20
  end
21
21
 
22
22
  def infinite_template
@@ -25,7 +25,7 @@ module Kafo
25
25
  "echo '$kafo_config_file=\"#{@configuration.config_file}\" #{custom_answer_file} #{add_progress} #{@command}'",
26
26
  '|',
27
27
  "RUBYLIB=#{["#{@configuration.gem_root}/modules", ::ENV['RUBYLIB']].join(File::PATH_SEPARATOR)}",
28
- "puppet apply #{@options.join(' ')} #{@suffix}",
28
+ "#{puppet_path} apply #{@options.join(' ')} #{@suffix}",
29
29
  ].join(' ')
30
30
  @logger.debug result
31
31
  result
@@ -36,6 +36,13 @@ module Kafo
36
36
  self
37
37
  end
38
38
 
39
+ def self.search_puppet_path(bin_name)
40
+ bin_path = (::ENV['PATH'].split(File::PATH_SEPARATOR) + ['/opt/puppetlabs/bin']).find do |path|
41
+ File.executable?(File.join(path, bin_name))
42
+ end
43
+ File.join([bin_path, bin_name].compact)
44
+ end
45
+
39
46
  private
40
47
 
41
48
  def modules_path
@@ -44,5 +51,9 @@ module Kafo
44
51
  @configuration.kafo_modules_dir,
45
52
  ].flatten.join(':')
46
53
  end
54
+
55
+ def puppet_path
56
+ @puppet_path ||= self.class.search_puppet_path('puppet')
57
+ end
47
58
  end
48
59
  end
@@ -2,7 +2,7 @@
2
2
  require 'kafo/param'
3
3
  require 'kafo/param_builder'
4
4
  require 'kafo/parser_cache_reader'
5
- require 'kafo_parsers/puppet_module_parser'
5
+ require 'kafo_parsers/parsers'
6
6
  require 'kafo/validator'
7
7
 
8
8
  module Kafo
@@ -12,7 +12,21 @@ module Kafo
12
12
  attr_reader :name, :identifier, :params, :dir_name, :class_name, :manifest_name, :manifest_path,
13
13
  :groups, :params_path, :params_class_name, :configuration, :raw_data
14
14
 
15
- def initialize(identifier, parser = KafoParsers::PuppetModuleParser, configuration = KafoConfigure.config)
15
+ def self.find_parser
16
+ @parser ||= begin
17
+ logger = KafoConfigure.logger
18
+ parser = KafoParsers::Parsers.find_available(:logger => logger)
19
+ if parser
20
+ logger.debug "Using Puppet module parser #{parser}"
21
+ parser
22
+ else
23
+ logger.debug "No available Puppet module parser found"
24
+ :none # prevent continually re-checking
25
+ end
26
+ end
27
+ end
28
+
29
+ def initialize(identifier, parser = self.class.find_parser, configuration = KafoConfigure.config)
16
30
  @identifier = identifier
17
31
  @configuration = configuration
18
32
  @name = get_name
@@ -49,9 +63,15 @@ module Kafo
49
63
  end
50
64
 
51
65
  def parse(builder_klass = ParamBuilder)
52
- @params = []
53
- @raw_data = @parser_cache.get(identifier, manifest_path) if @parser_cache
54
- @raw_data ||= @parser.parse(manifest_path)
66
+ @raw_data = @parser_cache.get(identifier, manifest_path) if @parser_cache
67
+ if @raw_data.nil?
68
+ if @parser.nil? || @parser == :none
69
+ raise ParserError.new("No Puppet module parser is installed and no cache of the file #{manifest_path} is available. Please check debug logs and install optional dependencies for the parser.")
70
+ else
71
+ @raw_data = @parser.parse(manifest_path)
72
+ end
73
+ end
74
+
55
75
  builder = builder_klass.new(self, @raw_data)
56
76
  @validations = @raw_data[:validations]
57
77
 
@@ -91,13 +91,10 @@ module Kafo
91
91
  (available_scenarios.keys.count == 1 && available_scenarios.keys.first) ||
92
92
  select_scenario_interactively
93
93
  if scenario.nil?
94
- fail_now("No installation scenario was selected, the installer can not continue.\n" +
95
- " Even --help content is dependent on selected scenario.\n" +
96
- " Select scenario with --scenario SCENARIO or list available scenarios with --list-scenarios.", :unknown_scenario)
94
+ fail_now("Scenario was not selected, can not continue. Use --list-scenarios to list available options.", :unknown_scenario)
97
95
  elsif !scenario_enabled?(scenario)
98
- fail_now("Selected scenario is DISABLED, can not continue.\n" +
99
- " Use --list-scenarios to list available options.\n" +
100
- " You can also --enable-scenario SCENARIO to make the selected scenario available.", :scenario_error)
96
+ fail_now("Selected scenario is DISABLED, can not continue. Use --list-scenarios to list available options." \
97
+ " You can also --enable-scenario SCENARIO to make the selected scenario available.", :scenario_error)
101
98
  end
102
99
  scenario
103
100
  end
@@ -2,79 +2,112 @@
2
2
  module Kafo
3
3
  class Validator
4
4
 
5
- def self.prepare_functions
6
- return true if @reset || !Puppet::Parser::Functions.respond_to?(:reset)
7
- Puppet::Parser::Functions.reset
8
- @reset = true
5
+ def initialize
6
+ @logger = KafoConfigure.logger
9
7
  end
10
8
 
11
- def initialize(params)
12
- self.class.prepare_functions
13
- definitions = KafoConfigure.module_dirs.map do |dir|
14
- validate_files = dir + '/*/lib/puppet/parser/functions/validate_*.rb'
15
- is_function_files = dir + '/*/lib/puppet/parser/functions/is_*.rb'
16
- Dir.glob(validate_files) + Dir.glob(is_function_files)
17
- end.flatten
18
-
19
- definitions.each do |file|
20
- require File.expand_path(file)
9
+ def validate_absolute_path(args)
10
+ args.each do |arg|
11
+ unless arg.to_s.start_with?('/')
12
+ @logger.error "#{arg.inspect} is not an absolute path."
13
+ return false
14
+ end
21
15
  end
16
+ return true
17
+ end
22
18
 
23
- @params = params
24
- @logger = KafoConfigure.logger
19
+ def validate_array(args)
20
+ args.each do |arg|
21
+ unless arg.is_a?(Array)
22
+ @logger.error "#{arg.inspect} is not a valid array."
23
+ return false
24
+ end
25
+ end
26
+ return true
27
+ end
25
28
 
26
- @cache ||= Hash.new do |hash, key|
27
- @logger.debug "Looked for #{key}"
28
- param = @params.select { |p| p.name == key.to_s }.first
29
- hash[key] = param.nil? ? nil : param.value
29
+ def validate_bool(args)
30
+ args.each do |arg|
31
+ unless arg.is_a?(TrueClass) || arg.is_a?(FalseClass)
32
+ @logger.error "#{arg.inspect} is not a valid boolean."
33
+ return false
34
+ end
30
35
  end
36
+ return true
31
37
  end
32
38
 
33
- def lookupvar(name, options = {})
34
- @cache[name]
39
+ def validate_hash(args)
40
+ args.each do |arg|
41
+ unless arg.is_a?(Hash)
42
+ @logger.error "#{arg.inspect} is not a valid hash."
43
+ return false
44
+ end
45
+ end
46
+ return true
35
47
  end
36
48
 
37
- # for puppet >= 3
38
- def include?(value)
39
- true
49
+ def validate_integer(args)
50
+ value = args[0]
51
+ max = args[1]
52
+ min = args[2]
53
+ int = Integer(value.to_s)
54
+ if min && int < min.to_i
55
+ @logger.error "#{value} must be at least #{min}."
56
+ return false
57
+ end
58
+ if max && int > max.to_i
59
+ @logger.error "#{value} must be less than #{max}."
60
+ return false
61
+ end
62
+ return true
63
+ rescue TypeError, ArgumentError
64
+ @logger.error "#{value.inspect} is not a valid integer."
65
+ return false
40
66
  end
41
67
 
42
- # for puppet >= 3
43
- def [](value, *args)
44
- lookupvar(value)
68
+ # Non-standard validation is from theforeman/foreman_proxy module
69
+ def validate_listen_on(args)
70
+ valid_values = ['http', 'https', 'both']
71
+ args.each do |arg|
72
+ unless valid_values.include?(arg)
73
+ @logger.error "#{arg.inspect} is not a valid value. Valid values are: #{valid_values.join(", ")}"
74
+ return false
75
+ end
76
+ end
77
+ return true
45
78
  end
46
79
 
47
- def method_missing(method, *args, &block)
48
- method.to_s =~ /^function_(.*)$/
49
- super unless $1
50
- super unless Puppet::Parser::Functions.function($1)
51
- # In odd circumstances, this might not end up defined by the previous
52
- # method, so we might as well be certain.
53
- if engine.respond_to? method
54
- @logger.debug "calling #{method.inspect} with #{args.inspect}"
55
- engine.send(method, *args)
56
- true
80
+ def validate_re(args)
81
+ value = args[0]
82
+ regexes = args[1]
83
+ regexes = [regexes] unless regexes.is_a?(Array)
84
+ message = args[2] || "#{value.inspect} does not match the accepted inputs: #{regexes.join(", ")}"
85
+
86
+ if regexes.any? { |rx| value =~ Regexp.compile(rx) }
87
+ return true
57
88
  else
58
- raise Puppet::DevError, "Function #{$1} not defined despite being loaded!"
89
+ @logger.error message
90
+ return false
59
91
  end
60
- rescue Puppet::ParseError => e
61
- @logger.error e.message
62
- return false
63
92
  end
64
93
 
65
- private
66
-
67
- def engine
68
- @engine ||= begin
69
- klass = Class.new
70
- env = Puppet::PUPPETVERSION.start_with?('2.') ? nil : lookup_current_environment
71
- klass.send :include, Puppet::Parser::Functions.environment_module(env)
72
- klass.new
94
+ def validate_string(args)
95
+ args.each do |arg|
96
+ unless arg.is_a?(String)
97
+ @logger.error "#{arg.inspect} is not a valid string."
98
+ return false
99
+ end
73
100
  end
101
+ return true
74
102
  end
75
103
 
76
- def lookup_current_environment
77
- @current_environment ||= Puppet.respond_to?(:lookup) ? Puppet.lookup(:current_environment) : Puppet::Node::Environment.current
104
+ def method_missing(method, *args, &block)
105
+ if method.to_s.start_with?('validate_')
106
+ @logger.debug "Skipping validation with #{method} as it's not implemented in Kafo"
107
+ return true
108
+ else
109
+ super
110
+ end
78
111
  end
79
112
  end
80
113
  end
data/lib/kafo/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # encoding: UTF-8
2
2
  module Kafo
3
- VERSION = "0.7.6"
3
+ VERSION = "0.8.0"
4
4
  end
@@ -6,7 +6,7 @@ module Puppet::Parser::Functions
6
6
  options<< false if Puppet::PUPPETVERSION.start_with?('2.6')
7
7
  data = args.map do |arg|
8
8
  found_value = lookupvar(arg, *options)
9
- [arg, found_value.nil? ? arg : found_value]
9
+ [arg, found_value]
10
10
  end
11
11
  data = Hash[data]
12
12
 
@@ -9,7 +9,7 @@ module Puppet::Parser::Functions
9
9
  if value.is_a?(Hash)
10
10
  data[key] = function_convert([value])
11
11
  else
12
- data[key] = value.nil? ? :undef : value
12
+ data[key] = value unless value.nil?
13
13
  end
14
14
  end
15
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kafo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.6
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marek Hulan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-20 00:00:00.000000000 Z
11
+ date: 2016-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: 0.1.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: '0'
124
+ version: 0.1.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: puppet
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -129,7 +129,7 @@ dependencies:
129
129
  - - "<"
130
130
  - !ruby/object:Gem::Version
131
131
  version: 4.0.0
132
- type: :runtime
132
+ type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
@@ -297,9 +297,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
297
297
  version: '0'
298
298
  requirements: []
299
299
  rubyforge_project:
300
- rubygems_version: 2.2.0
300
+ rubygems_version: 2.4.5
301
301
  signing_key:
302
302
  specification_version: 4
303
303
  summary: If you write puppet modules for installing your software, you can use kafo
304
304
  to create powerful installer
305
305
  test_files: []
306
+ has_rdoc: