Class: Kafo::ScenarioManager

Inherits:
Object
  • Object
show all
Defined in:
lib/kafo/scenario_manager.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, last_scenario_link_name = 'last_scenario.yaml') ⇒ ScenarioManager

Returns a new instance of ScenarioManager.



9
10
11
12
13
# File 'lib/kafo/scenario_manager.rb', line 9

def initialize(config, last_scenario_link_name='last_scenario.yaml')
  @config_dir = File.file?(config) ? File.dirname(config) : config
  @last_scenario_link = File.join(config_dir, last_scenario_link_name)
  @previous_scenario = Pathname.new(last_scenario_link).realpath.to_s if File.exists?(last_scenario_link)
end

Instance Attribute Details

#config_dirObject (readonly)

Returns the value of attribute config_dir.



7
8
9
# File 'lib/kafo/scenario_manager.rb', line 7

def config_dir
  @config_dir
end

Returns the value of attribute last_scenario_link.



7
8
9
# File 'lib/kafo/scenario_manager.rb', line 7

def last_scenario_link
  @last_scenario_link
end

#previous_scenarioObject (readonly)

Returns the value of attribute previous_scenario.



7
8
9
# File 'lib/kafo/scenario_manager.rb', line 7

def previous_scenario
  @previous_scenario
end

Instance Method Details

#available_scenariosObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/kafo/scenario_manager.rb', line 15

def available_scenarios
  # assume that *.yaml file in config_dir that has key :name is scenario definition
  @available_scenarios ||= Dir.glob(File.join(config_dir, '*.yaml')).reject { |f| f =~ /#{last_scenario_link}$/ }.inject({}) do |scns, scn_file|
    begin
      content = YAML.load_file(scn_file)
      if content.is_a?(Hash) && content.has_key?(:answer_file)
        # add scenario name for legacy configs
        content[:name] = File.basename(scn_file, '.yaml') unless content.has_key?(:name)
        scns[scn_file] = content
      end
    rescue Psych::SyntaxError => e
      warn "Warning: #{e}"
    end
    scns
  end
end

#check_scenario_change(scenario) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
# File 'lib/kafo/scenario_manager.rb', line 117

def check_scenario_change(scenario)
  if scenario_changed?(scenario)
    if ARGV.include? '--compare-scenarios'
      show_scenario_diff(@previous_scenario, scenario)
      dump_log_and_exit(0)
    else
      confirm_scenario_change(scenario)
      KafoConfigure.logger.info "Scenario #{scenario} was selected"
    end
  end
end

#configured?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/kafo/scenario_manager.rb', line 75

def configured?
  !!(defined?(CONFIG_DIR) && CONFIG_DIR)
end

#confirm_scenario_change(new_scenario) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/kafo/scenario_manager.rb', line 129

def confirm_scenario_change(new_scenario)
  unless ARGV.include?('--force')
    if (ARGV & ['--interactive', '-i']).any?
      show_scenario_diff(@previous_scenario, new_scenario)

      wizard = KafoWizards.wizard(:cli, 'Confirm installation scenario selection',
        :description => "You are trying to replace existing installation with different scenario. This may lead to unpredictable states. Please confirm that you want to proceed.")
      wizard.entries << wizard.factory.button(:proceed, :label => 'Proceed with selected installation scenario', :default => false)
      wizard.entries << wizard.factory.button(:cancel, :label => 'Cancel Installation', :default => true)
      result = wizard.run
      if result == :cancel
        say 'Installation was cancelled by user'
        dump_log_and_exit(0)
      end
    else
      message = "You are trying to replace existing installation with different scenario. This may lead to unpredictable states. " +
      "Use --force to override. You can use --compare-scenarios to see the differences"
      KafoConfigure.logger.error(message)
      dump_log_and_exit(:scenario_error)
    end
  end
end


182
183
184
185
186
187
188
# File 'lib/kafo/scenario_manager.rb', line 182

def link_last_scenario(config_file)
  link_path = last_scenario_link
  if last_scenario_link
    File.delete(last_scenario_link) if File.exist?(last_scenario_link)
    File.symlink(config_file, last_scenario_link)
  end
end

#list_available_scenariosObject



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/kafo/scenario_manager.rb', line 32

def list_available_scenarios
  say ::HighLine.color("Available scenarios", :info)
  available_scenarios.each do |config_file, content|
    scenario = File.basename(config_file, '.yaml')
    use = (File.expand_path(config_file) == @previous_scenario ? 'INSTALLED' : "use: --scenario #{scenario}")
    say ::HighLine.color("  #{content[:name]} ", :title)
    say "(#{use})"
    say "        " + content[:description] if !content[:description].nil? && !content[:description].empty?
  end
  say "  No available scenarios found in #{config_dir}" if available_scenarios.empty?
  KafoConfigure.exit(0)
end

#load_and_setup_configuration(config_file) ⇒ Object



190
191
192
193
194
195
# File 'lib/kafo/scenario_manager.rb', line 190

def load_and_setup_configuration(config_file)
  conf = load_configuration(config_file)
  conf.preset_defaults_from_puppet
  conf.preset_defaults_from_yaml
  conf
end

#load_configuration(config_file) ⇒ Object



197
198
199
# File 'lib/kafo/scenario_manager.rb', line 197

def load_configuration(config_file)
  Configuration.new(config_file)
end


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/kafo/scenario_manager.rb', line 152

def print_scenario_diff(prev_conf, new_conf)
  missing = new_conf.params_missing(prev_conf)
  changed = new_conf.params_changed(prev_conf)

  say "\n" + ::HighLine.color("Overview of modules used in the scenarios (#{prev_conf.app[:name]} -> #{new_conf.app[:name]}):", :title)
  modules = Hash.new { |h, k| h[k] = {} }
  modules = prev_conf.modules.inject(modules) { |mods, mod| mods[mod.name][:prev] = mod.enabled?; mods }
  modules = new_conf.modules.inject(modules) { |mods, mod| mods[mod.name][:new] = mod.enabled?; mods }
  printables = { "" => 'N/A', 'true' => 'ENABLED', 'false' => 'DISABLED' }
  modules.each do |mod, status|
    module_line = "%-50s: %-09s -> %s" % [mod, printables[status[:prev].to_s], printables[status[:new].to_s]]
    # highlight modules that will be disabled
    module_line = ::HighLine.color(module_line, :important) if status[:prev] == true && (status[:new] == false || status[:new].nil?)
    say module_line
  end

  say "\n" + ::HighLine.color("Defaults that will be updated with values from previous installation:", :title)
  if changed.empty?
    say "  No values will be updated from previous scenario"
  else
    changed.each { |param| say "  #{param.module.class_name}::#{param.name}: #{param.value} -> #{prev_conf.param(param.module.class_name, param.name).value}" }
  end
  say "\n" + ::HighLine.color("Values from previous installation that will be lost by scenario change:", :title)
  if missing.empty?
    say "  No values from previous installation will be lost"
  else
    missing.each { |param| say "  #{param.module.class_name}::#{param.name}: #{param.value}\n" }
  end
end

#scenario_changed?(scenario) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
73
# File 'lib/kafo/scenario_manager.rb', line 70

def scenario_changed?(scenario)
  scenario = Pathname.new(scenario).realpath.to_s if File.symlink?(scenario)
  !!previous_scenario && scenario != previous_scenario
end

#scenario_from_argsObject



79
80
81
82
83
84
85
86
87
88
# File 'lib/kafo/scenario_manager.rb', line 79

def scenario_from_args
  # try scenario provided in the args via -S or --scenario
  parsed = ARGV.join(" ").match /(--scenario|-S)(\s+|[=]?)(\S+)/
  if parsed
    scenario_file = File.join(config_dir, "#{parsed[3]}.yaml")
    return scenario_file if File.exists?(scenario_file)
    KafoConfigure.logger.fatal "Scenario (#{scenario_file}) was not found, can not continue"
    KafoConfigure.exit(:unknown_scenario)
  end
end

#scenario_selection_wizardObject



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/kafo/scenario_manager.rb', line 45

def scenario_selection_wizard
  wizard = KafoWizards.wizard(:cli, 'Select installation scenario',
    :description => "Please select one of the pre-set installation scenarios. You can customize your setup later during the installation.")
  f = wizard.factory
  available_scenarios.keys.each do |scn|
    label = available_scenarios[scn][:name].to_s
    label += ": #{available_scenarios[scn][:description]}" if available_scenarios[scn][:description]
    wizard.entries << f.button(scn, :label => label, :default => true)
  end
  wizard.entries << f.button(:cancel, :label => 'Cancel Installation', :default => false)
  wizard
end

#select_scenarioObject



90
91
92
93
94
95
96
97
98
# File 'lib/kafo/scenario_manager.rb', line 90

def select_scenario
  scenario = scenario_from_args || previous_scenario ||
    (available_scenarios.keys.count == 1 && available_scenarios.keys.first) ||
    select_scenario_interactively
  if scenario.nil?
    fail_now("Scenario was not selected, can not continue. Use --list-scenarios to list available options.", :unknown_scenario)
  end
  scenario
end

#select_scenario_interactivelyObject



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/kafo/scenario_manager.rb', line 58

def select_scenario_interactively
  # let the user select if in interactive mode
  if (ARGV & ['--interactive', '-i']).any?
    res = scenario_selection_wizard.run
    if res == :cancel
      say 'Installation was cancelled by user'
      KafoConfigure.exit(0)
    end
    res
  end
end

#show_scenario_diff(prev_scenario, new_scenario) ⇒ Object



110
111
112
113
114
115
# File 'lib/kafo/scenario_manager.rb', line 110

def show_scenario_diff(prev_scenario, new_scenario)
  say ::HighLine.color("Scenarios are being compared, that may take a while...", :info)
  prev_conf = load_and_setup_configuration(prev_scenario)
  new_conf = load_and_setup_configuration(new_scenario)
  print_scenario_diff(prev_conf, new_conf)
end