class ChefApply::Startup
Constants
- T
Attributes
argv[R]
Public Class Methods
new(argv)
click to toggle source
# File lib/chef_apply/startup.rb, line 28 def initialize(argv) @term_init = false @argv = argv.clone # Enable CLI output via Terminal. This comes first because other startup steps may # need to output to the terminal. init_terminal end
Public Instance Methods
create_default_config()
click to toggle source
# File lib/chef_apply/startup.rb, line 114 def create_default_config UI::Terminal.output T.creating_config(Config.default_location) UI::Terminal.output "" FileUtils.mkdir_p(Config::WS_BASE_PATH) FileUtils.touch(Config.default_location) end
custom_config_path()
click to toggle source
Look for a user-supplied config path by manually parsing the option. Note that we can't use Mixlib::CLI for this. To ensure that ChefApply::CLI
initializes with correct option defaults, we need to have configuraton loaded before initializing it.
# File lib/chef_apply/startup.rb, line 172 def custom_config_path argv.each_with_index do |arg, index| if arg == "--config-path" || arg == "-c" next_arg = argv[index + 1] raise ConfigPathNotProvided.new if next_arg.nil? raise ConfigPathInvalid.new(next_arg) unless File.file?(next_arg) && File.readable?(next_arg) return next_arg end end nil end
first_run_tasks()
click to toggle source
# File lib/chef_apply/startup.rb, line 107 def first_run_tasks return if Dir.exist?(Config::WS_BASE_PATH) create_default_config setup_telemetry end
init_terminal()
click to toggle source
# File lib/chef_apply/startup.rb, line 94 def init_terminal UI::Terminal.init($stdout) end
load_config()
click to toggle source
# File lib/chef_apply/startup.rb, line 162 def load_config path = custom_config_path Config.custom_location(path) unless path.nil? Config.load end
run(enforce_license: false)
click to toggle source
# File lib/chef_apply/startup.rb, line 36 def run(enforce_license: false) # This component is not supported in ChefDK; an exception will be raised # if running in that context. verify_not_in_chefdk # Some tasks we do only once in an installation: first_run_tasks # Call this every time, so that if we add or change ~/.chef-workstation # directory structure, we can be sure that it exists. Even with a # custom configuration, the .chef-workstation directory and subdirs # are required. setup_workstation_user_directories # Customize behavior of Ruby and any gems around error handling setup_error_handling # Startup tasks that may change behavior based on configuration value # must be run after load_config load_config # Init logging using log level out of config setup_logging # Begin upload of previous session telemetry. (If telemetry is not enabled, # in config the uploader will clean up previous session(s) without sending) start_telemeter_upload # Launch the actual Chef Apply behavior start_chef_apply(enforce_license: enforce_license) # NOTE: Because these exceptions occur outside of the # CLI handling, they won't be tracked in telemtry. # We can revisit this once the pending error handling rework # is underway. rescue ConfigPathInvalid => e UI::Terminal.output(T.error.bad_config_file(e.path)) rescue ConfigPathNotProvided UI::Terminal.output(T.error.missing_config_path) rescue UnsupportedInstallation UI::Terminal.output(T.error.unsupported_installation) rescue Mixlib::Config::UnknownConfigOptionError => e # Ideally we'd update the exception in mixlib to include # a field with the faulty value, line number, and nested context - # it's less fragile than depending on text parsing, which # is what we'll do for now. if e.message =~ /.*unsupported config value (.*)[.]+$/ # TODO - levenshteinian distance to figure out # what they may have meant instead. UI::Terminal.output(T.error.invalid_config_key($1, Config.location)) else # Safety net in case the error text changes from under us. UI::Terminal.output(T.error.unknown_config_error(e.message, Config.location)) end rescue Tomlrb::ParseError => e UI::Terminal.output(T.error.unknown_config_error(e.message, Config.location)) end
setup_error_handling()
click to toggle source
# File lib/chef_apply/startup.rb, line 151 def setup_error_handling # In Ruby 2.5+ threads print out to stdout when they raise an exception. This is an agressive # attempt to ensure debugging information is not lost, but in our case it is not necessary # because we handle all the errors ourself. So we disable this to keep output clean. # See https://ruby-doc.org/core-2.5.0/Thread.html#method-c-report_on_exception # # We set this globally so that it applies to all threads we create - we never want any non-UI thread # to render error output to the terminal. Thread.report_on_exception = false end
setup_logging()
click to toggle source
# File lib/chef_apply/startup.rb, line 185 def setup_logging ChefApply::Log.setup(Config.log.location, Config.log.level.to_sym) ChefApply::Log.info("Initialized logger") ChefConfig.logger = ChefApply::Log # Setting the config isn't enough, we need to ensure the logger is # initialized with our existing stream or automatic initialization # will still go to stdout instead of the log file we opened. Chef::Log.init(ChefApply::Log.stream) Chef::Log.level = ChefApply::Log.level end
setup_telemetry()
click to toggle source
# File lib/chef_apply/startup.rb, line 121 def setup_telemetry require "securerandom" unless defined?(SecureRandom) installation_id = SecureRandom.uuid File.write(Config.telemetry_installation_identifier_file, installation_id) # Tell the user we're anonymously tracking, give brief opt-out # and a link to detailed information. UI::Terminal.output T.telemetry_enabled(Config.location) UI::Terminal.output "" end
setup_workstation_user_directories()
click to toggle source
# File lib/chef_apply/startup.rb, line 143 def setup_workstation_user_directories # Note that none of these paths are customizable in config, so # it's safe to do before we load config. FileUtils.mkdir_p(Config::WS_BASE_PATH) FileUtils.mkdir_p(Config.base_log_directory) FileUtils.mkdir_p(Config.telemetry_path) end
start_chef_apply(enforce_license: false)
click to toggle source
# File lib/chef_apply/startup.rb, line 197 def start_chef_apply(enforce_license: false) require_relative "cli" ChefApply::CLI.new(@argv).run(enforce_license: enforce_license) end
start_telemeter_upload()
click to toggle source
# File lib/chef_apply/startup.rb, line 132 def start_telemeter_upload cfg = { enabled: Config.telemetry[:enabled], dev_mode: Config.telemetry[:dev_mode], payload_dir: Config.telemetry_path, installation_identifier_file: Config.telemetry_installation_identifier_file, session_file: Config.telemetry_session_file, } Chef::Telemeter.setup(cfg) end
verify_not_in_chefdk()
click to toggle source
Verify that chef-run gem is not executing out of ChefDK by checking the runtime path of this file.
NOTE: This is imperfect - someone could theoretically install chefdk to a path other than the default.
# File lib/chef_apply/startup.rb, line 103 def verify_not_in_chefdk raise UnsupportedInstallation.new if script_path =~ /chefdk/ end
Private Instance Methods
script_path()
click to toggle source
# File lib/chef_apply/startup.rb, line 204 def script_path __dir__ end