class Chef::Util::DSC::LocalConfigurationManager

Public Class Methods

new(node, configuration_path) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 24
def initialize(node, configuration_path)
  @node = node
  @configuration_path = configuration_path
  clear_execution_time
end

Public Instance Methods

last_operation_execution_time_seconds() click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 40
def last_operation_execution_time_seconds
  if @operation_start_time && @operation_end_time
    @operation_end_time - @operation_start_time
  end
end
set_configuration(configuration_document, shellout_flags) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 36
def set_configuration(configuration_document, shellout_flags)
  run_configuration_cmdlet(configuration_document, true, shellout_flags)
end
test_configuration(configuration_document, shellout_flags) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 30
def test_configuration(configuration_document, shellout_flags)
  status = run_configuration_cmdlet(configuration_document, false, shellout_flags)
  log_dsc_exception(status.stderr) unless status.succeeded?
  configuration_update_required?(status.return_value)
end

Private Instance Methods

clear_execution_time() click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 137
def clear_execution_time
  @operation_start_time = nil
  @operation_end_time = nil
end
configuration_document_path() click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 133
def configuration_document_path
  File.join(@configuration_path, "..mof")
end
configuration_update_required?(command_output) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 112
def configuration_update_required?(command_output)
  Chef::Log.trace("DSC: DSC returned the following '-whatif' output from test operation:\n#{command_output}")
  begin
    Parser.parse(command_output, ps_version_gte_5?)
  rescue Chef::Exceptions::LCMParser => e
    Chef::Log.warn("Could not parse LCM output: #{e}")
    [Chef::Util::DSC::ResourceInfo.new("Unknown DSC Resources", true, ["Unknown changes because LCM output was not parsable."])]
  end
end
dsc_module_import_failure?(command_output) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 106
def dsc_module_import_failure?(command_output)
  !! (command_output =~ /\sCimException/ &&
    command_output =~ /ProviderOperationExecutionFailure/ &&
    command_output =~ /\smodule\s+is\s+installed/)
end
end_operation_timing() click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 147
def end_operation_timing
  @operation_end_time = Time.now
end
lcm_command(apply_configuration) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 73
def lcm_command(apply_configuration)
  common_command_prefix = "$ProgressPreference = 'SilentlyContinue';"
  ps4_base_command = "#{common_command_prefix} Start-DscConfiguration -path #{@configuration_path} -wait -erroraction 'stop' -force"
  if apply_configuration
    ps4_base_command
  else
    if ps_version_gte_5?
      "#{common_command_prefix} Test-DscConfiguration -path #{@configuration_path} | format-list"
    else
      ps4_base_command + " -whatif; if (! $?) { exit 1 }"
    end
  end
end
log_dsc_exception(dsc_exception_output) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 91
def log_dsc_exception(dsc_exception_output)
  if whatif_not_supported?(dsc_exception_output)
    # LCM returns an error if any of the resources do not support the opptional What-If
    Chef::Log.warn("Received error while testing configuration due to resource not supporting 'WhatIf'")
  elsif dsc_module_import_failure?(dsc_exception_output)
    Chef::Log.warn("Received error while testing configuration due to a module for an imported resource possibly not being fully installed:\n#{dsc_exception_output.gsub(/\s+/, ' ')}")
  else
    Chef::Log.warn("Received error while testing configuration:\n#{dsc_exception_output.gsub(/\s+/, ' ')}")
  end
end
ps_version_gte_5?() click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 87
def ps_version_gte_5?
  Chef::Platform.supported_powershell_version?(@node, 5)
end
remove_configuration_document() click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 129
def remove_configuration_document
  ::FileUtils.rm(configuration_document_path)
end
run_configuration_cmdlet(configuration_document, apply_configuration, shellout_flags) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 48
def run_configuration_cmdlet(configuration_document, apply_configuration, shellout_flags)
  Chef::Log.trace("DSC: Calling DSC Local Config Manager to #{apply_configuration ? "set" : "test"} configuration document.")

  start_operation_timing
  status = nil

  begin
    save_configuration_document(configuration_document)
    cmdlet = ::Chef::Util::Powershell::Cmdlet.new(@node, lcm_command(apply_configuration))
    if apply_configuration
      status = cmdlet.run!({}, shellout_flags)
    else
      status = cmdlet.run({}, shellout_flags)
    end
  ensure
    end_operation_timing
    remove_configuration_document
    if last_operation_execution_time_seconds
      Chef::Log.trace("DSC: DSC operation completed in #{last_operation_execution_time_seconds} seconds.")
    end
  end
  Chef::Log.trace("DSC: Completed call to DSC Local Config Manager")
  status
end
save_configuration_document(configuration_document) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 122
def save_configuration_document(configuration_document)
  ::FileUtils.mkdir_p(@configuration_path)
  ::File.open(configuration_document_path, "wb") do |file|
    file.write(configuration_document)
  end
end
start_operation_timing() click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 142
def start_operation_timing
  clear_execution_time
  @operation_start_time = Time.now
end
whatif_not_supported?(dsc_exception_output) click to toggle source
# File lib/chef/util/dsc/local_configuration_manager.rb, line 102
def whatif_not_supported?(dsc_exception_output)
  !! (dsc_exception_output.gsub(/[\r\n]+/, "").gsub(/\s+/, " ") =~ /A parameter cannot be found that matches parameter name 'Whatif'/i)
end