Question

Over the past week I've been trying to address Chef COOK-1172 without much success. I'm trying to install SQL Server 2008 R2 Developer Edition (in my case) through Vagrant using the Chef-Solo provisioner.

I've been able to reproduce the issue outside of Chef by going directly through the Ruby WinRM gem and then fix it using a custom PowerShell script which uses the passed along credentials to start the setup.exe process on the guest Windows vagrant box. In other words, WinRM gem invokes a remote PS script which starts the SQL Server setup.exe under the specified credentials, and this works.

However, running the same exact script through chef-solo on the guest fails with with an InvalidOperationException: Unable to generate a temporary class.

The Ruby script and the embedded PowerShell script I'm using for testing, which is invoked from my OS X host:

require 'winrm'

endpoint = 'http://localhost:5985/wsman'
user = password = 'vagrant'
ps = <<EOH

function ps-runas ([String] $cmd, [String] $arguments)
{
  Write-Host "ps-runas cmd: $cmd"
  Write-Host "ps-runas args: $arguments"

  $secpasswd = ConvertTo-SecureString "vagrant" -AsPlainText -Force

  $process = New-Object System.Diagnostics.Process
  $setup = $process.StartInfo
  $setup.FileName = $cmd
  $setup.Arguments = $arguments
  $setup.UserName = "vagrant"
  $setup.Password = $secpasswd
  $setup.Verb = "runas"
  $setup.UseShellExecute = $false
  $setup.RedirectStandardError = $true
  $setup.RedirectStandardOutput = $true
  $setup.RedirectStandardInput = $false

  # Hook into the standard output and error stream events
  $errEvent = Register-ObjectEvent -InputObj $process `
    -Event "ErrorDataReceived" `
    -Action `
    {
        param
        (
            [System.Object] $sender,
            [System.Diagnostics.DataReceivedEventArgs] $e
        )
        Write-Host $e.Data
    }
  $outEvent = Register-ObjectEvent -InputObj $process `
    -Event "OutputDataReceived" `
    -Action `
    {
        param
        (
            [System.Object] $sender,
            [System.Diagnostics.DataReceivedEventArgs] $e
        )
        Write-Host $e.Data
    }

  Write-Host "ps-runas starting: $cmd"

  if (!$process.Start())
  {
    Write-Error "Failed to start $cmd"
  }

  $process.BeginOutputReadLine()
  $process.BeginErrorReadLine()

  # Wait until process exit
  $process.WaitForExit()

  $process.CancelOutputRead()
  $process.CancelErrorRead()
  $process.Close()
}

EOH

cmd = ps

# Fails - Running through chef-solo fails - cannot compile a serialization assembly
cmd << "ps-runas \"c:\\opscode\\chef\\bin\\chef-solo.bat\" \"-c c:\\tmp\\vagrant-chef-1\\solo.rb -j c:\\tmp\\vagrant-chef-1\\dna.json\""

# Succeeds - Running setup directly works
#cmd << "ps-runas \"c:\\vagrant\\sql2008r2\\setup.exe\" \"/Q /ConfigurationFile=c:\\vagrant\\ConfigurationFile.ini\""

winrm = WinRM::WinRMWebService.new(endpoint, :plaintext, :user => user, :pass => password, :basic_auth_only => true)
winrm.set_timeout(60*20)

winrm.powershell(cmd) do |stdout, stderr|
  STDOUT.print stdout
  STDERR.print stderr
end

puts 'Done!'

From the sql installation logs:

013-03-03 22:44:50 Slp: Exception type: Microsoft.SqlServer.Chainer.Infrastructure.ChainerInfrastructureException
2013-03-03 22:44:50 Slp:     Message: 
2013-03-03 22:44:50 Slp:         Unable to generate a temporary class (result=1).
2013-03-03 22:44:50 Slp:         error CS0583: Internal Compiler Error (0xc0000017 at address 000007FEFD00AA7D): likely culprit is 'IMPORT'.
2013-03-03 22:44:50 Slp:         error CS0584: Internal Compiler Error: stage 'IMPORT' symbol 'System.Xml.Serialization.XmlSerializationReader'
2013-03-03 22:44:50 Slp:         error CS0584: Internal Compiler Error: stage 'IMPORT' symbol 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderClusterNodesStatusPublicConfigObject'
2013-03-03 22:44:50 Slp:         error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderClusterNodesStatusPublicConfigObject'
2013-03-03 22:44:50 Slp:         error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft.Xml.Serialization.GeneratedAssembly'
2013-03-03 22:44:50 Slp:         error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft.Xml.Serialization'
2013-03-03 22:44:50 Slp:         error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft.Xml'
2013-03-03 22:44:50 Slp:         error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft'
2013-03-03 22:44:50 Slp:         error CS0584: Internal Compiler Error: stage 'PREPARE' symbol '<global namespace>'
2013-03-03 22:44:50 Slp:         error CS0586: Internal Compiler Error: stage 'PREPARE'
2013-03-03 22:44:50 Slp:         error CS0587: Internal Compiler Error: stage 'PREPARE'
2013-03-03 22:44:50 Slp:         error CS0587: Internal Compiler Error: stage 'BEGIN'
2013-03-03 22:44:50 Slp:         
2013-03-03 22:44:50 Slp:     Stack: 
2013-03-03 22:44:50 Slp:         at Microsoft.SqlServer.Chainer.Infrastructure.DataStoreService.DeserializeObject(String rootPath, Type type, String elementXPath)
2013-03-03 22:44:50 Slp:         at Microsoft.SqlServer.Chainer.Infrastructure.DataStoreService.DeserializeObject(String rootPath, Type type)
2013-03-03 22:44:50 Slp:         at Microsoft.SqlServer.Configuration.SetupExtension.FinalCalculateSettingsAction.ExecuteAction(String actionId)
2013-03-03 22:44:50 Slp:         at Microsoft.SqlServer.Chainer.Infrastructure.Action.Execute(String actionId, TextWriter errorStream)
2013-03-03 22:44:50 Slp:         at Microsoft.SqlServer.Setup.Chainer.Workflow.ActionInvocation.ExecuteActionHelper(TextWriter statusStream, ISequencedAction actionToRun)
2013-03-03 22:44:50 Slp:     Inner exception type: System.InvalidOperationException
2013-03-03 22:44:50 Slp:         Message: 
2013-03-03 22:44:50 Slp:                 Unable to generate a temporary class (result=1).
2013-03-03 22:44:50 Slp:                 error CS0583: Internal Compiler Error (0xc0000017 at address 000007FEFD00AA7D): likely culprit is 'IMPORT'.
2013-03-03 22:44:50 Slp:                 error CS0584: Internal Compiler Error: stage 'IMPORT' symbol 'System.Xml.Serialization.XmlSerializationReader'
2013-03-03 22:44:50 Slp:                 error CS0584: Internal Compiler Error: stage 'IMPORT' symbol 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderClusterNodesStatusPublicConfigObject'
2013-03-03 22:44:50 Slp:                 error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderClusterNodesStatusPublicConfigObject'
2013-03-03 22:44:50 Slp:                 error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft.Xml.Serialization.GeneratedAssembly'
2013-03-03 22:44:50 Slp:                 error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft.Xml.Serialization'
2013-03-03 22:44:50 Slp:                 error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft.Xml'
2013-03-03 22:44:50 Slp:                 error CS0584: Internal Compiler Error: stage 'PREPARE' symbol 'Microsoft'
2013-03-03 22:44:50 Slp:                 error CS0584: Internal Compiler Error: stage 'PREPARE' symbol '<global namespace>'
2013-03-03 22:44:50 Slp:                 error CS0586: Internal Compiler Error: stage 'PREPARE'
2013-03-03 22:44:50 Slp:                 error CS0587: Internal Compiler Error: stage 'PREPARE'
2013-03-03 22:44:50 Slp:                 error CS0587: Internal Compiler Error: stage 'BEGIN'
2013-03-03 22:44:50 Slp:                 
2013-03-03 22:44:50 Slp:         Stack: 
2013-03-03 22:44:50 Slp:                 at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence)
2013-03-03 22:44:50 Slp:                 at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies)
2013-03-03 22:44:50 Slp:                 at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
2013-03-03 22:44:50 Slp:                 at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
2013-03-03 22:44:50 Slp:                 at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
2013-03-03 22:44:50 Slp:                 at Microsoft.SqlServer.Chainer.Infrastructure.DataStoreService.DeserializeObject(String rootPath, Type type, String elementXPath)

My first suspicion is that I'm running into some sort of permission problem with my temp directory, but I've tried running ProcMon and haven't found any ACCESS DENIED results while running setup. Additionally, I'm explicitly running as a local administrator (vagrant) because of the PowerShell script and UAC is turned off.

Was it helpful?

Solution

I could potentially list a lot of things I did to track this down, but in the end I discovered the failure wasn't specific to running the installer through Chef, or even Ruby. Essentially it would error out any time I used another process to install SQL Server through WinRM, even PowerShell which would produce an OutOfMemoryException in the installer logs.

This ultimately led me to wonder what was different about executing the installer through WinRM. Then I had a thought. If I were Microsoft I'd probably have some enterprisey features around WinRM that limited that attack surface on a server. Apparently WinRM has a feature called Quota Management.

In short, modifying the local group policy of my Windows guest VM fixed the problem and I was finally able to successfully install SQL Server through WinRM and Chef (with my above PS script). Here are the settings I used:

Console Root | Local Computer Policy | Computer Configuration | Administrative Templates | Windows Components | Windows Remote Shell

  • MaxConcurrentUsers: 100
  • MaxMemoryPerShellMB: 0
  • MaxProcessesPerShell: 0
  • MaxShellsPerUser: 0

OTHER TIPS

I also had this issue installing sql server over DSC on server 2016 (and probably older versions)

You can also set this option via powershell directly:

set-item WSMan:\localhost\Shell\MaxMemoryPerShellMB 2048

From that ticket Chef COOK-1172, Julian C. Dunn [Chef] added a comment

We believe this is now fixed by Microsoft in the following hotfix, which will restore WinRM's respecting of MaxMemoryPerShellMB: http://support.microsoft.com/kb/2842230

Unfortunately, this does not work for me. I am still having the same issue.

Having spent many days now chasing this, I have found that the root cause, in my case, was that when I included any kind of password in the unattend file, it failed when installing through WinRM.

This can be resolved by using CredSSP

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top