parts/k8s/kuberneteswindowsfunctions.ps1 (251 lines of code) (raw):

# This filter removes null characters (\0) which are captured in nssm.exe output when logged through powershell filter RemoveNulls { $_ -replace '\0', '' } filter Timestamp { "$(Get-Date -Format o): $_" } function Write-Log($message) { $msg = $message | Timestamp Write-Output $msg } function DownloadFileOverHttp { Param( [Parameter(Mandatory = $true)][string] $Url, [Parameter(Mandatory = $true)][string] $DestinationPath ) # First check to see if a file with the same name is already cached on the VHD $fileName = [IO.Path]::GetFileName($Url) $search = @() if (Test-Path $global:CacheDir) { $search = [IO.Directory]::GetFiles($global:CacheDir, $fileName, [IO.SearchOption]::AllDirectories) } if ($search.Count -ne 0) { Write-Log "Using cached version of $fileName - Copying file from $($search[0]) to $DestinationPath" Copy-Item -Path $search[0] -Destination $DestinationPath -Force } else { $secureProtocols = @() $insecureProtocols = @([System.Net.SecurityProtocolType]::SystemDefault, [System.Net.SecurityProtocolType]::Ssl3) foreach ($protocol in [System.Enum]::GetValues([System.Net.SecurityProtocolType])) { if ($insecureProtocols -notcontains $protocol) { $secureProtocols += $protocol } } [System.Net.ServicePointManager]::SecurityProtocol = $secureProtocols $oldProgressPreference = $ProgressPreference $ProgressPreference = 'SilentlyContinue' try { $args = @{Uri=$Url; Method="Get"; OutFile=$DestinationPath} Retry-Command -Command "Invoke-RestMethod" -Args $args -Retries 5 -RetryDelaySeconds 10 } catch { throw "Fail in downloading $Url. Error: $_" } $ProgressPreference = $oldProgressPreference Write-Log "Downloaded file to $DestinationPath" } } function Get-ProvisioningScripts { Write-Log "Getting provisioning scripts" DownloadFileOverHttp -Url $global:ProvisioningScriptsPackageUrl -DestinationPath 'c:\k\provisioningscripts.zip' Expand-Archive -Path 'c:\k\provisioningscripts.zip' -DestinationPath 'c:\k' -Force Remove-Item -Path 'c:\k\provisioningscripts.zip' -Force } function Get-WindowsVersion { $systemInfo = Get-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion" return "$($systemInfo.CurrentBuildNumber).$($systemInfo.UBR)" } function Get-CniVersion { switch ($global:NetworkPlugin) { "azure" { if ($global:VNetCNIPluginsURL -match "(v[0-9`.]+).(zip|tar)") { return $matches[1] } else { return "" } break; } default { return "" } } } function Get-InstanceMetadataServiceTelemetry { $keys = @{ } try { # Write-Log "Querying instance metadata service..." # Note: 2019-04-30 is latest api available in all clouds $metadata = Invoke-RestMethod -Headers @{"Metadata" = "true" } -URI "http://169.254.169.254/metadata/instance?api-version=2019-04-30" -Method get # Write-Log ($metadata | ConvertTo-Json) $keys.Add("vm_size", $metadata.compute.vmSize) } catch { Write-Log "Error querying instance metadata service." } return $keys } # https://stackoverflow.com/a/34559554/697126 function New-TemporaryDirectory { $parent = [System.IO.Path]::GetTempPath() [string] $name = [System.Guid]::NewGuid() New-Item -ItemType Directory -Path (Join-Path $parent $name) } function Initialize-DataDirectories { # Some of the Kubernetes tests that were designed for Linux try to mount /tmp into a pod # On Windows, Go translates to c:\tmp. If that path doesn't exist, then some node tests fail $requiredPaths = 'c:\tmp' $requiredPaths | ForEach-Object { if (-Not (Test-Path $_)) { New-Item -ItemType Directory -Path $_ } } } function Retry-Command { Param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string] $Command, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][hashtable] $Args, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][int] $Retries, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][int] $RetryDelaySeconds ) for ($i = 0; ; ) { try { return & $Command @Args } catch { $i++ if ($i -ge $Retries) { throw $_ } Start-Sleep $RetryDelaySeconds } } } function Invoke-Executable { Param( [string] $Executable, [string[]] $ArgList, [int[]] $AllowedExitCodes = @(0), [int] $Retries = 1, [int] $RetryDelaySeconds = 1 ) for ($i = 0; $i -lt $Retries; $i++) { Write-Log "Running $Executable $ArgList ..." & $Executable $ArgList if ($LASTEXITCODE -notin $AllowedExitCodes) { Write-Log "$Executable returned unsuccessfully with exit code $LASTEXITCODE" Start-Sleep -Seconds $RetryDelaySeconds continue } else { Write-Log "$Executable returned successfully" return } } throw "Exhausted retries for $Executable $ArgList" } function Get-LogCollectionScripts { Write-Log "Getting various log collect scripts and depencencies" mkdir 'c:\k\debug' DownloadFileOverHttp -Url 'https://github.com/Azure/aks-engine-azurestack/raw/master/scripts/collect-windows-logs.ps1' -DestinationPath 'c:\k\debug\collect-windows-logs.ps1' DownloadFileOverHttp -Url 'https://github.com/microsoft/SDN/raw/master/Kubernetes/windows/debug/collectlogs.ps1' -DestinationPath 'c:\k\debug\collectlogs.ps1' DownloadFileOverHttp -Url 'https://github.com/microsoft/SDN/raw/master/Kubernetes/windows/debug/dumpVfpPolicies.ps1' -DestinationPath 'c:\k\debug\dumpVfpPolicies.ps1' DownloadFileOverHttp -Url 'https://github.com/microsoft/SDN/raw/master/Kubernetes/windows/debug/portReservationTest.ps1' -DestinationPath 'c:\k\debug\portReservationTest.ps1' DownloadFileOverHttp -Url 'https://github.com/microsoft/SDN/raw/master/Kubernetes/windows/debug/starthnstrace.cmd' -DestinationPath 'c:\k\debug\starthnstrace.cmd' DownloadFileOverHttp -Url 'https://github.com/microsoft/SDN/raw/master/Kubernetes/windows/debug/startpacketcapture.cmd' -DestinationPath 'c:\k\debug\startpacketcapture.cmd' DownloadFileOverHttp -Url 'https://github.com/microsoft/SDN/raw/master/Kubernetes/windows/debug/stoppacketcapture.cmd' -DestinationPath 'c:\k\debug\stoppacketcapture.cmd' DownloadFileOverHttp -Url 'https://github.com/Microsoft/SDN/raw/master/Kubernetes/windows/debug/VFP.psm1' -DestinationPath 'c:\k\debug\VFP.psm1' DownloadFileOverHttp -Url 'https://github.com/microsoft/SDN/raw/master/Kubernetes/windows/helper.psm1' -DestinationPath 'c:\k\debug\helper.psm1' DownloadFileOverHttp -Url 'https://github.com/microsoft/SDN/raw/master/Kubernetes/windows/hns.v2.psm1' -DestinationPath 'c:\k\debug\hns.v2.psm1' } function Register-LogsCleanupScriptTask { Write-Log "Creating a scheduled task to run windowslogscleanup.ps1" $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File `"c:\k\windowslogscleanup.ps1`"" $principal = New-ScheduledTaskPrincipal -UserId SYSTEM -LogonType ServiceAccount -RunLevel Highest $trigger = New-JobTrigger -Daily -At "00:00" -DaysInterval 1 $definition = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Description "log-cleanup-task" Register-ScheduledTask -TaskName "log-cleanup-task" -InputObject $definition } function Register-NodeResetScriptTask { Write-Log "Creating a startup task to run windowsnodereset.ps1" $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File `"c:\k\windowsnodereset.ps1`"" $principal = New-ScheduledTaskPrincipal -UserId SYSTEM -LogonType ServiceAccount -RunLevel Highest $trigger = New-JobTrigger -AtStartup -RandomDelay 00:00:05 $definition = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Description "k8s-restart-job" Register-ScheduledTask -TaskName "k8s-restart-job" -InputObject $definition } # TODO ksubrmnn parameterize this fully function Write-KubeClusterConfig { param( [Parameter(Mandatory = $true)][string] $MasterIP, [Parameter(Mandatory = $true)][string] $KubeDnsServiceIp ) $Global:ClusterConfiguration = [PSCustomObject]@{ } $Global:ClusterConfiguration | Add-Member -MemberType NoteProperty -Name Cri -Value @{ Name = "containerd"; Images = @{ # e.g. "mcr.microsoft.com/oss/kubernetes/pause:3.8" "Pause" = $global:WindowsPauseImageURL } } $Global:ClusterConfiguration | Add-Member -MemberType NoteProperty -Name Cni -Value @{ Name = $global:NetworkPlugin; Plugin = @{ Name = "bridge"; }; } $Global:ClusterConfiguration | Add-Member -MemberType NoteProperty -Name Csi -Value @{ EnableProxy = $global:EnableCsiProxy } $Global:ClusterConfiguration | Add-Member -MemberType NoteProperty -Name Kubernetes -Value @{ Source = @{ Release = $global:KubeBinariesVersion; }; ControlPlane = @{ IpAddress = $MasterIP; Username = "azureuser" MasterSubnet = $global:MasterSubnet }; Network = @{ ServiceCidr = $global:KubeServiceCIDR; ClusterCidr = $global:KubeClusterCIDR; DnsIp = $KubeDnsServiceIp }; Kubelet = @{ NodeLabels = $global:KubeletNodeLabels; ConfigArgs = $global:KubeletConfigArgs }; Kubeproxy = @{ FeatureGates = $global:KubeproxyFeatureGates }; } $Global:ClusterConfiguration | Add-Member -MemberType NoteProperty -Name Install -Value @{ Destination = "c:\k"; } $Global:ClusterConfiguration | ConvertTo-Json -Depth 10 | Out-File -FilePath $global:KubeClusterConfigPath } function Assert-FileExists { Param( [Parameter(Mandatory = $true, Position = 0)][string] $Filename ) if (-Not (Test-Path $Filename)) { throw "$Filename does not exist" } } function Update-DefenderPreferences { Add-MpPreference -ExclusionProcess "c:\k\kubelet.exe" if ($global:EnableCsiProxy) { Add-MpPreference -ExclusionProcess "c:\k\csi-proxy.exe" } Add-MpPreference -ExclusionProcess "c:\program files\containerd\containerd.exe" }