crowbar/crowbar-core

View on GitHub
chef/cookbooks/provisioner/files/default/crowbar_join.ps1

Summary

Maintainability
Test Coverage
Function ExecCommand($command) {
    $r = [regex]::match($command, "([^\s]+)\s+(.+)")
    if ($r.Success) {    
        $filename = $r.Groups[1].Value
        $arguments = $r.Groups[2].Value
    }
    else {
        $filename = $command
        $arguments = $null
    }
    Write-Host "Filename: $filename"
    Write-Host "Arguments: $arguments"

    $process = New-Object System.Diagnostics.Process;
    $process.StartInfo.UseShellExecute = $false
    $process.StartInfo.RedirectStandardOutput = $true
    $process.StartInfo.RedirectStandardError = $true
    $process.StartInfo.CreateNoWindow = $true
    $process.StartInfo.FileName = $filename
    $process.StartInfo.Arguments = $arguments
    $started = $process.Start()
    
    $out = $process.StandardOutput.ReadToEnd()
    $err = $process.StandardError.ReadToEnd()
    $process.WaitForExit()
    
    return ($process.ExitCode, $out, $err)
}


function postState(){
  Param(
    [string]$uri,
    [string]$key,
    [string]$name,
    [string]$state
  )
  # $cmd = 'C:\Crowbar\curl.exe -o "c:\Crowbar\Logs\'+$name+'-'+$state+'.json" --connect-timeout 60 -S -L -X POST --data-binary "{ \`"name\`": \`"'+$name+'\`", \`"state\`": \`"'+$state+'\`" }" -H "Accept: application/json" -H "Content-Type: application/json" --max-time 240 -u "'+$key+'" --digest --anyauth "'+$uri+'/crowbar/crowbar/1.0/transition/default"'
  $cmd = 'C:\Crowbar\curl.exe -o "c:\Crowbar\Logs\'+$name+'-'+$state+'.json" --connect-timeout 60 -S -L -X POST --data-binary "{ \"name\": \"'+$name+'\", \"state\": \"'+$state+'\" }" -H "Accept: application/json" -H "Content-Type: application/json" --max-time 240 -u "'+$key+'" --digest --anyauth "'+$uri+'/crowbar/crowbar/1.0/transition/default"'
  $ret=ExecCommand $cmd
  $exitcode=$ret[0]
  Add-Content -Path "c:\Crowbar\Logs\$name-$state.json" -Value $ret[1]
  Add-Content -Path "c:\Crowbar\Logs\$name-$state.log" -Value "$(Get-Date): $cmd returned with code $exitcode."
}

function syncTime(){
  Param(
    [string]$address
  )
  # See http://support.microsoft.com/kb/816042
  w32tm /register
  $s = Get-Service w32time
  if ($s.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running)
  {
    $s.Stop()
  }

  net start w32time 
  w32tm /config "/manualpeerlist:$address,0x8" /syncfromflags:MANUAL /reliable:yes /update
  w32tm /resync
  <#
  w32tm /register
  $s = Get-Service w32time

  if ($s.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running)
  {
    $s.Stop()
  }
  # net time /setsntp:$ntpServer
  
  $timeRoot = "HKLM:\SYSTEM\CurrentControlSet\services\W32Time"
  $ntpServer = "$address,0x1"
  Set-ItemProperty -path "$timeroot\parameters" -name type -Value "NTP"
  Set-ItemProperty -path "$timeroot\parameters" -name NtpServer -Value $ntpServer
  Set-ItemProperty -path "$timeroot\config" -name AnnounceFlags -Value 5
  Set-ItemProperty -path "$timeroot\config" -name MaxPosPhaseCorrection -Value 1800
  Set-ItemProperty -path "$timeroot\config" -name MaxNegPhaseCorrection -Value 1800
  Set-ItemProperty -path "$timeroot\TimeProviders\NtpServer" -name Enabled -Value 1
  Set-ItemProperty -path "$timeroot\TimeProviders\NtpClient" -name SpecialPollInterval -Value 900
  $s.Start()
  #>
  <#
  Register-WmiEvent -Query `
    "select * from __InstanceModificationEvent within 5 where targetinstance isa 'win32_service'" `
  -SourceIdentifier stopped
  Stop-Service -Name w32Time
  Wait-Event -SourceIdentifier stopped
  Start-Service -Name w32Time
  Unregister-Event -SourceIdentifier stopped
  Remove-Event -SourceIdentifier stopped
  #>
  #w32tm /resync /rediscover
}



$CrowbarKey=(Get-ItemProperty "HKLM:\SOFTWARE\Crowbar" -Name Key).Key 
$CrowbarIP=(Get-ItemProperty "HKLM:\SOFTWARE\Crowbar" -Name Address).Address 
$CrowbarUri= "http://"+$CrowbarIP
$CrowbarMain="C:\Crowbar"
$CrowbarLogsFolder="$CrowbarMain\Logs"
$CrowbarLogFile="$CrowbarLogsFolder\crowbar.log"

$ChefClientMSI="chef-client-11.4.4-2.windows.msi"
$ChefFolder="C:/chef"

$ChefServerURL="`'http://"+$CrowbarIP+":4000`'"
$ChefServerCertificate="$ChefFolder/validation.pem"
$ChefClientCertificate="$ChefFolder/client.pem"
$ChefConfigFile="$ChefFolder/client.rb"
$ChefCacheLocation="$ChefFolder/cache"
$ChefBackupLocation="$ChefFolder/backup"
$ChefExec="C:\opscode\chef\bin\chef-client.bat"

if (!(Test-Path -path "c:\Crowbar\Logs")) {New-Item "c:\Crowbar\Logs" -Type Directory}
if (!(Test-Path -path $ChefFolder)) {New-Item $ChefFolder -Type Directory}
$hostname=hostname

$s = Get-Service chef-client -ErrorAction SilentlyContinue
if ($s)
{
  if ($s.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running)
  {
    $s.Stop()
  }
}
Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Syncing time."
syncTime $CrowbarIP

Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Setting crowbar state to readying"
postState $CrowbarUri $CrowbarKey "$hostname" "readying"
$finalState="ready"

# for chef 10.18.2-2: $chef_reg_key="HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{A6ED465C-9C62-4EC2-A9A0-C133C67AC5FC}"
# for chef 11.4.4-2
Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Checking if chef-client is installed"
$chef_reg_key="HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{FCC87F22-4EE4-4D12-BBCC-E17ACCD47A81}"
if (-not (Test-Path -Path $chef_reg_key))
{
  Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Starting chef-client installation"
  # Start-Process -FilePath msiexec -ArgumentList "/i `"$CrowbarMain\$ChefClientMSI`" /qn /l*v `"$CrowbarLogsFolder\chef_install.log`" ADDLOCAL=ChefClientFeature,ChefServiceFeature" -wait
  Start-Process -FilePath msiexec -ArgumentList "/i `"$CrowbarMain\$ChefClientMSI`" /qn /l*v `"$CrowbarLogsFolder\chef_install.log`"" -wait
  Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Setting the service state to manual"
  Set-Service -Name chef-client -StartupType Manual
}
Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Checking if validation certificate is available"
if (-not (Test-Path -Path $ChefServerCertificate))
{
  Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Download validation certificate from the chef server"
  Invoke-WebRequest -Uri ("http://"+$CrowbarIP+":8091/validation.pem").ToString() -OutFile ($ChefServerCertificate+"get").ToString()
  Get-Content ($ChefServerCertificate+"get").ToString() | Set-Content $ChefServerCertificate
  Remove-Item ($ChefServerCertificate+"get").ToString()
}

Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Checking if chef config file is created"
if (-not (Test-Path -Path $ChefConfigFile))
{
  $hostname = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties().HostName
  $domain = (Get-ItemProperty "HKLM:\SOFTWARE\Crowbar" -Name Domain).Domain
  Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Creating chef config file"
  Add-Content $ChefConfigFile "log_level :debug"
  Add-Content $ChefConfigFile ("node_name `""+$hostname+"."+$domain+"`"").ToString()
  Add-Content $ChefConfigFile ("log_location `""+$CrowbarLogsFolder.Replace("\","/")+"/chef_client.log`"").ToString()
  Add-Content $ChefConfigFile "chef_server_url $ChefServerURL"
  Add-Content $ChefConfigFile "validation_key `"$ChefServerCertificate`""
  Add-Content $ChefConfigFile "client_key `"$ChefClientCertificate`""
  Add-Content $ChefConfigFile "file_cache_path `"$ChefCacheLocation`""
  Add-Content $ChefConfigFile "file_backup_path `"$ChefBackupLocation`""
  Add-Content $ChefConfigFile "cache_options ({:path=>`"$ChefCacheLocation/checksums`", :skip_expires=>true})"
}

Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Syncing time"
syncTime $CrowbarIP
Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Executing chef-client"
$ret=ExecCommand "$ChefExec"
Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value "$(Get-Date): $ChefExec finished first run with exitcode $exitcode"
Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value $ret[1]
Add-Content -Path "$CrowbarLogsFolder\chef_err.log" -Value $ret[2]
Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Executing chef-client"
$ret=ExecCommand "$ChefExec"
$exitcode=$ret[0]
Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value "$(Get-Date): $ChefExec finished second run with exitcode $exitcode"
Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value $ret[1]
Add-Content -Path "$CrowbarLogsFolder\chef_err.log" -Value $ret[2]
if ($exitcode -ne "0")
{
  Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Setting crowbar state to recovering"
  postState $CrowbarUri $CrowbarKey "$hostname" "recovering"
  Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Syncing time"
  syncTime $CrowbarIP
  Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Removing chef cache"
  Remove-Item "$ChefCacheLocation/*" -Recurse
  Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Executing chef-client"
  $ret=ExecCommand "$ChefExec"
  $exitcode=$ret[0]
  Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value "$(Get-Date): $ChefExec finished third run with exitcode $exitcode"
  Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value $ret[1]
  Add-Content -Path "$CrowbarLogsFolder\chef_err.log" -Value $ret[2]
  if ($exitcode -ne "0")
  {
    Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Syncing time"
    syncTime $CrowbarIP
    Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Removing chef cache"
    Remove-Item "$ChefCacheLocation/*" -Recurse
    Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Removing chef-client certificate"
    Remove-Item $ChefClientCertificate
    Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Setting crowbar state to installed"
    postState $CrowbarUri $CrowbarKey "$hostname" "installed"
    Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Executing chef-client"
    $ret=ExecCommand "$ChefExec"
    $exitcode=$ret[0]
    Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value "$(Get-Date): $ChefExec finished fourth run with exitcode $exitcode"
    Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value $ret[1]
    Add-Content -Path "$CrowbarLogsFolder\chef_err.log" -Value $ret[2]
    if ($exitcode -ne "0")
    {
      Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value "$(Get-Date):  System set in `"problem`" state."
      $finalState="problem"
    }
    else
    {
      Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Setting crowbar state to $finalState"
      postState $CrowbarUri $CrowbarKey "$hostname" "$finalState"
      Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Executing chef-client"
      $ret=ExecCommand "$ChefExec"
      $exitcode=$ret[0]
      Add-Content -Path "$CrowbarLogsFolder\chef.log" -Value "$(Get-Date): $ChefExec finished fifth run with exitcode $exitcode"
      Add-Content -Path "$CrowbarLogsFolder\chef_err.log" -Value $ret[2]
    }
  }
}

Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Setting crowbar state to $finalState"
postState $CrowbarUri $CrowbarKey "$hostname" "$finalState"

#if ($finalState -eq "ready")
#{
  #Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Checking if the chef-client service is not running"
  #$s = Get-Service chef-client
  #if ($s.Status -ne [System.ServiceProcess.ServiceControllerStatus]::Running)
  #{
    #Add-Content -Path "$CrowbarLogFile" -Value "$(Get-Date): Starting the chef-client service"
    #$s.Start()
  #}
#}