class Kitchen::Provisioner::Dsc

Attributes

tmp_dir[RW]

Public Instance Methods

create_sandbox() click to toggle source
Calls superclass method
# File lib/kitchen/provisioner/dsc.rb, line 64
def create_sandbox
  super
  info("Staging DSC Resource Modules for copy to the SUT")
  if powershell_module?
    prepare_resource_style_directory
  else
    prepare_repo_style_directory
  end
  info("Staging DSC configuration script for copy to the SUT")
  prepare_configuration_script
end
finalize_config!(instance) click to toggle source
Calls superclass method
# File lib/kitchen/provisioner/dsc.rb, line 40
def finalize_config!(instance)
  config[:dsc_local_configuration_manager] = lcm.lcm_config
  super(instance)
end
init_command() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 56
      def init_command
        script = <<~EOH
          #{setup_config_directory_script}
          #{install_module_script if install_modules?}
        EOH
        wrap_powershell_code(script)
      end
install_command() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 45
      def install_command
        full_lcm_configuration_script = <<-EOH
        #{lcm.lcm_configuration_script}

        $null = SetupLCM
        Set-DscLocalConfigurationManager -Path ./SetupLCM | out-null
        EOH

        wrap_powershell_code(full_lcm_configuration_script)
      end
prepare_command() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 76
      def prepare_command
        info("Moving DSC Resources onto PSModulePath")
        scripts = <<-EOH

        if (Test-Path (join-path #{config[:root_path]} 'modules'))
        {
          dir ( join-path #{config[:root_path]} 'modules/*') -directory |
          copy-item -destination $env:programfiles/windowspowershell/modules/ -recurse -force
        }

        $ConfigurationScriptPath = Join-path #{config[:root_path]} #{sandboxed_configuration_script}
        if (-not (test-path $ConfigurationScriptPath))
        {
          throw "Failed to find $ConfigurationScriptPath"
        }
        invoke-expression (get-content $ConfigurationScriptPath -raw)

        EOH
        ensure_array(config[:configuration_name]).each do |configuration|
          info("Generating the MOF script for the configuration #{configuration}")
          stage_resources_and_generate_mof_script = <<-EOH

            if(Test-Path c:/configurations/#{configuration})
            {
                Remove-Item -Recurse -Force c:/configurations/#{configuration}
            }

            $Error.clear()

            if (-not (test-path 'c:/configurations'))
            {
              mkdir 'c:/configurations' | out-null
            }

            if (-not (get-command #{configuration}))
            {
              throw "Failed to create a configuration command #{configuration}"
            }

            #{configuration_data_assignment unless config[:configuration_data].nil?}

            try{
              $null = #{configuration} -outputpath c:/configurations/#{configuration} #{"-configurationdata $" + configuration_data_variable}
            }
            catch{
            }

            if($Error -ne $null)
            {
              $Error[-1]
              exit 1
            }

          EOH
          scripts << stage_resources_and_generate_mof_script
        end
        debug("Shelling out: #{scripts}")
        wrap_powershell_code(scripts)
      end
run_command() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 136
      def run_command
        config[:retry_on_exit_code] = [35] if config[:retry_on_exit_code].empty?
        config[:max_retries] = 3 if config[:max_retries] == 1
        scripts = ""
        ensure_array(config[:configuration_name]).each do |configuration|
          info("Running the configuration #{configuration}")
          run_configuration_script = <<-EOH
            $job = start-dscconfiguration -Path c:/configurations/#{configuration} -force
            $job | wait-job
            $verbose_output = $job.childjobs[0].verbose
            $verbose_output
            if ($verbose_output -match 'A reboot is required to progress further. Please reboot the system.') {
              "A reboot is required to continue."
              shutdown /r /t 15
              exit 35
            }
            $dsc_errors = $job.childjobs[0].Error
            if ($dsc_errors -ne $null) {
              $dsc_errors
              exit 1
            }
          EOH
          scripts << run_configuration_script
        end
        debug("Shelling out: #{scripts}")
        wrap_powershell_code(scripts)
      end

Private Instance Methods

configuration_data_assignment() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 238
def configuration_data_assignment
  "$" + configuration_data_variable + " = " + ps_hash(config[:configuration_data])
end
configuration_data_variable() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 234
def configuration_data_variable
  config[:configuration_data_variable].nil? ? "ConfigurationData" : config[:configuration_data_variable]
end
ensure_array(thing) click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 322
def ensure_array(thing)
  if thing.is_a?(Array)
    thing
  else
    [thing]
  end
end
install_module_script() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 219
      def install_module_script
        return if config[:modules_from_gallery].nil?

        <<-EOH
  #{nuget_force_bootstrap}
  #{register_psmodule_repository}
  #{powershell_modules.join("\n")}
        EOH
      end
install_modules?() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 229
def install_modules?
  config[:dsc_local_configuration_manager_version] == "wmf5" &&
    !config[:modules_from_gallery].nil?
end
lcm() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 166
def lcm
  @lcm ||= begin
    lcm_version = config[:dsc_local_configuration_manager_version]
    lcm_config = config[:dsc_local_configuration_manager]
    DscLcmConfiguration::Factory.create(lcm_version, lcm_config)
  end
end
list_files(path) click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 251
def list_files(path)
  base_directory_content = Dir.glob(File.join(path, "*"))
  nested_directory_content = Dir.glob(File.join(path, "*/**/*"))
  all_directory_content = [base_directory_content, nested_directory_content].flatten

  ignore_files = ["Gemfile", "Gemfile.lock", "README.md", "LICENSE.txt"]
  all_directory_content.reject do |f|
    debug("Enumerating #{f}")
    ignore_files.include?(File.basename(f)) || File.directory?(f)
  end
end
module_name() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 263
def module_name
  File.basename(config[:kitchen_root])
end
nuget_force_bootstrap() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 198
def nuget_force_bootstrap
  return unless config[:nuget_force_bootstrap]

  info("Bootstrapping the nuget package provider for PowerShell PackageManagement.")
  "install-packageprovider nuget -force -forcebootstrap | out-null"
end
pad(depth = 0) click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 296
def pad(depth = 0)
  " " * depth
end
powershell_module?() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 246
def powershell_module?
  module_metadata_file = File.join(config[:kitchen_root], "#{module_name}.psd1")
  File.exist?(module_metadata_file)
end
powershell_module_params(module_specification_hash) click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 178
def powershell_module_params(module_specification_hash)
  keys = module_specification_hash.keys.reject { |k| k.to_s.casecmp("force") == 0 }
  unless keys.any? { |k| k.to_s.downcase == "repository" }
    keys.push(:repository)
    module_specification_hash[:repository] = psmodule_repository_name
  end
  keys.map { |key| "-#{key} #{module_specification_hash[key]}" }.join(" ")
end
powershell_modules() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 187
def powershell_modules
  Array(config[:modules_from_gallery]).map do |powershell_module|
    params = if powershell_module.is_a? Hash
               powershell_module_params(powershell_module)
             else
               "-name '#{powershell_module}' -Repository #{psmodule_repository_name}"
             end
    "install-module #{params} -force | out-null"
  end
end
prepare_configuration_script() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 313
def prepare_configuration_script
  configuration_script_file = File.join(config[:configuration_script_folder], config[:configuration_script])
  configuration_script_path = File.join(config[:kitchen_root], configuration_script_file)
  sandbox_configuration_script_path = File.join(sandbox_path, sandboxed_configuration_script)
  FileUtils.mkdir_p(File.dirname(sandbox_configuration_script_path))
  debug("Moving #{configuration_script_path} to #{sandbox_configuration_script_path}")
  FileUtils.cp(configuration_script_path, sandbox_configuration_script_path)
end
prepare_repo_style_directory() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 280
def prepare_repo_style_directory
  module_path = File.join(config[:kitchen_root], config[:modules_path])
  sandbox_module_path = File.join(sandbox_path, "modules")

  if Dir.exist?(module_path)
    debug("Moving #{module_path} to #{sandbox_module_path}")
    FileUtils.cp_r(module_path, sandbox_module_path)
  else
    debug("The modules path #{module_path} was not found. Not moving to #{sandbox_module_path}.")
  end
end
prepare_resource_style_directory() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 267
def prepare_resource_style_directory
  sandbox_base_module_path = File.join(sandbox_path, "modules/#{module_name}")

  base = config[:kitchen_root]
  list_files(base).each do |src|
    dest = File.join(sandbox_base_module_path, src.sub("#{base}/", ""))
    FileUtils.mkdir_p(File.dirname(dest))
    debug("Staging #{src} ")
    debug("  at #{dest}")
    FileUtils.cp(src, dest, preserve: true)
  end
end
ps_hash(obj, depth = 0) click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 300
def ps_hash(obj, depth = 0)
  if obj.is_a?(Hash)
    obj.map do |k, v|
      %{#{pad(depth + 2)}#{ps_hash(k)} = #{ps_hash(v, depth + 2)}}
    end.join(";\n").insert(0, "@{\n").insert(-1, "\n#{pad(depth)}}")
  elsif obj.is_a?(Array)
    array_string = obj.map { |v| ps_hash(v, depth + 4) }.join(",")
    "#{pad(depth)}@(\n#{array_string}\n)"
  else
    %{"#{obj}"}
  end
end
psmodule_repository_name() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 205
def psmodule_repository_name
  return "PSGallery" if config[:gallery_name].nil? && config[:gallery_uri].nil?
  return "testing"   if config[:gallery_name].nil?

  config[:gallery_name]
end
register_psmodule_repository() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 212
def register_psmodule_repository
  return if config[:gallery_uri].nil?

  info("Registering a new PowerShellGet Repository - #{psmodule_repository_name}")
  "register-packagesource -providername PowerShellGet -name '#{psmodule_repository_name}' -location '#{config[:gallery_uri]}' -force -trusted"
end
sandboxed_configuration_script() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 292
def sandboxed_configuration_script
  File.join("configuration", config[:configuration_script])
end
setup_config_directory_script() click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 174
def setup_config_directory_script
  "mkdir (split-path (join-path #{config[:root_path]} #{sandboxed_configuration_script})) -force | out-null"
end
wrap_powershell_code(code) click to toggle source
# File lib/kitchen/provisioner/dsc.rb, line 242
def wrap_powershell_code(code)
  wrap_shell_code(["$ProgressPreference = 'SilentlyContinue';", code].join("\n"))
end