Class: ChefApply::Startup
- Inherits:
- 
      Object
      
        - Object
- ChefApply::Startup
 
- Defined in:
- lib/chef_apply/startup.rb
Defined Under Namespace
Classes: ConfigPathInvalid, ConfigPathNotProvided, UnsupportedInstallation
Constant Summary collapse
Instance Attribute Summary collapse
- 
  
    
      #argv  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute argv. 
Instance Method Summary collapse
- #create_default_config ⇒ Object
- 
  
    
      #custom_config_path  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Look for a user-supplied config path by manually parsing the option. 
- #first_run_tasks ⇒ Object
- #init_terminal ⇒ Object
- 
  
    
      #initialize(argv)  ⇒ Startup 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    A new instance of Startup. 
- #load_config ⇒ Object
- #run(enforce_license: false) ⇒ Object
- #setup_error_handling ⇒ Object
- #setup_logging ⇒ Object
- #setup_telemetry ⇒ Object
- #setup_workstation_user_directories ⇒ Object
- #start_chef_apply(enforce_license: false) ⇒ Object
- #start_telemeter_upload ⇒ Object
- 
  
    
      #verify_not_in_chefdk  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Verify that chef-run gem is not executing out of ChefDK by checking the runtime path of this file. 
Constructor Details
#initialize(argv) ⇒ Startup
Returns a new instance of Startup.
| 28 29 30 31 32 33 34 | # 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 | 
Instance Attribute Details
#argv ⇒ Object (readonly)
Returns the value of attribute argv.
| 25 26 27 | # File 'lib/chef_apply/startup.rb', line 25 def argv @argv end | 
Instance Method Details
#create_default_config ⇒ Object
| 114 115 116 117 118 119 | # 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 ⇒ Object
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 configuration loaded before initializing it.
| 172 173 174 175 176 177 178 179 180 181 182 183 | # 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 ⇒ Object
| 107 108 109 110 111 112 | # 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 ⇒ Object
| 94 95 96 | # File 'lib/chef_apply/startup.rb', line 94 def init_terminal UI::Terminal.init($stdout) end | 
#load_config ⇒ Object
| 162 163 164 165 166 | # 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) ⇒ Object
| 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | # 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 sub-dirs # 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 telemetry. # 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. =~ /.*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., Config.location)) end rescue Tomlrb::ParseError => e UI::Terminal.output(T.error.unknown_config_error(e., Config.location)) end | 
#setup_error_handling ⇒ Object
| 151 152 153 154 155 156 157 158 159 160 | # 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 aggressive # 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 ⇒ Object
| 185 186 187 188 189 190 191 192 193 194 195 | # 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 ⇒ Object
| 121 122 123 124 125 126 127 128 129 130 | # 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 ⇒ Object
| 143 144 145 146 147 148 149 | # 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) ⇒ Object
| 197 198 199 200 | # 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 ⇒ Object
| 132 133 134 135 136 137 138 139 140 141 | # 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 ⇒ Object
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.
| 103 104 105 | # File 'lib/chef_apply/startup.rb', line 103 def verify_not_in_chefdk raise UnsupportedInstallation.new if script_path =~ /chefdk/ end |