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) && content.fetch(:enabled, true)
        # 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_disable_scenarioObject



129
130
131
132
# File 'lib/kafo/scenario_manager.rb', line 129

def check_disable_scenario
  scenario = scenario_from_args('--disable-scenario')
  set_scenario_availability(scenario, false) if scenario
end

#check_enable_scenarioObject



124
125
126
127
# File 'lib/kafo/scenario_manager.rb', line 124

def check_enable_scenario
  scenario = scenario_from_args('--enable-scenario')
  set_scenario_availability(scenario, true) if scenario
end

#check_scenario_change(scenario) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/kafo/scenario_manager.rb', line 112

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



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/kafo/scenario_manager.rb', line 146

def confirm_scenario_change(new_scenario)
  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 an existing installation with a 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
  elsif !ARGV.include?('--force') && !KafoConfigure.in_help_mode?
    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
  true
end


198
199
200
201
202
203
204
# File 'lib/kafo/scenario_manager.rb', line 198

def link_last_scenario(config_file)
  link_path = last_scenario_link
  if last_scenario_link
    File.delete(last_scenario_link) if File.symlink?(last_scenario_link)
    File.symlink(File.basename(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



206
207
208
209
210
211
# File 'lib/kafo/scenario_manager.rb', line 206

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



213
214
215
# File 'lib/kafo/scenario_manager.rb', line 213

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


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/kafo/scenario_manager.rb', line 168

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_enabled?(scenario) ⇒ Boolean

Returns:

  • (Boolean)


142
143
144
# File 'lib/kafo/scenario_manager.rb', line 142

def scenario_enabled?(scenario)
  load_configuration(scenario).app[:enabled]
end

#scenario_from_args(arg_name = '--scenario|-S') ⇒ Object



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

def scenario_from_args(arg_name='--scenario|-S')
  # try scenario provided in the args via -S or --scenario
  parsed = ARGV.join(" ").match /(#{arg_name})(\s+|[=]?)(\S+)/
  if parsed
    scenario_file = File.join(config_dir, "#{parsed[3]}.yaml")
    return scenario_file if File.exists?(scenario_file)
    fail_now("Scenario (#{scenario_file}) was not found, can not continue", :unset_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



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/kafo/scenario_manager.rb', line 89

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("No installation scenario was selected, the installer cannot continue.\n" +
      "       Even --help content is dependent on selected scenario.\n" +
      "       Select scenario with --scenario SCENARIO or list available scenarios with --list-scenarios.", :unset_scenario)
  elsif !scenario_enabled?(scenario)
    fail_now("Selected scenario is DISABLED, can not continue.\n" +
      "       Use --list-scenarios to list available options.\n" +
      "       You can also --enable-scenario SCENARIO to make the selected scenario available.", :scenario_error)
  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

#set_scenario_availability(scenario, available) ⇒ Object



134
135
136
137
138
139
140
# File 'lib/kafo/scenario_manager.rb', line 134

def set_scenario_availability(scenario, available)
  cfg = load_configuration(scenario)
  cfg.app[:enabled] = available
  cfg.save_configuration(cfg.app)
  say "Scenario #{File.basename(scenario, ".yaml")} was #{available ? "enabled" : "disabled"}"
  KafoConfigure.exit(0)
end

#show_scenario_diff(prev_scenario, new_scenario) ⇒ Object



105
106
107
108
109
110
# File 'lib/kafo/scenario_manager.rb', line 105

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