shdsbilling/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/execute.ps1

351 lines
12 KiB
PowerShell

<#
run.ps1 executes the agent
#>
$ErrorActionPreference = 'Stop'
$WarningPreference = 'SilentlyContinue'
$VerbosePreference = 'SilentlyContinue'
$DebugPreference = 'SilentlyContinue'
$InformationPreference = 'SilentlyContinue'
Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1"
function Get-Address
{
param(
[parameter(Mandatory = $false)] [string]$Addr
)
if (-not $Addr) {
return ""
}
# If given address is a network interface on the system, retrieve configured IP on that interface (only the first configured IP is taken)
try {
$getAdapterJson = wins.exe cli net get --name $Addr
if ($?) {
$namedNetwork = $getAdapterJson | ConvertTo-JsonObj
if ($namedNetwork) {
return $namedNetwork.AddressCIDR -replace "/32",""
}
}
} catch {}
# Repair the container route for `169.254.169.254` before cloud provider query
$actualGateway = $(route.exe print 0.0.0.0 | Where-Object {$_ -match '0\.0\.0\.0.*[a-z]'} | Select-Object -First 1 | ForEach-Object {($_ -replace '0\.0\.0\.0|[a-z]|\s+',' ').Trim() -split ' '} | Select-Object -First 1)
$expectedGateway = $(route.exe print 169.254.169.254 | Where-Object {$_ -match '169\.254\.169\.254'} | Select-Object -First 1 | ForEach-Object {($_ -replace '169\.254\.169\.254|255\.255\.255\.255|[a-z]|\s+',' ').Trim() -split ' '} | Select-Object -First 1)
if ($actualGateway -ne $expectedGateway) {
$errMsg = $(route.exe add 169.254.169.254 MASK 255.255.255.255 $actualGateway METRIC 1)
if (-not $?) {
Log-Error "Could not repair contain route for using cloud provider"
}
}
# Loop through cloud provider options to get IP from metadata, if not found return given value
switch ($Addr)
{
"awslocal" {
return $(curl.exe -s "http://169.254.169.254/latest/meta-data/local-ipv4")
}
"awspublic" {
return $(curl.exe -s "http://169.254.169.254/latest/meta-data/public-ipv4")
}
"doprivate" {
return $(curl.exe -s "http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address")
}
"dopublic" {
return $(curl.exe -s "http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address")
}
"azprivate" {
return $(curl.exe -s -H "Metadata:true" "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress?api-version=2017-08-01&format=text")
}
"azpublic" {
return $(curl.exe -s -H "Metadata:true" "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text")
}
"gceinternal" {
return $(curl.exe -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip?alt=json")
}
"gceexternal" {
return $(curl.exe -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip?alt=json")
}
"packetlocal" {
return $(curl.exe -s "https://metadata.packet.net/2009-04-04/meta-data/local-ipv4")
}
"packetpublic" {
return $(curl.exe -s "https://metadata.packet.net/2009-04-04/meta-data/public-ipv4")
}
"ipify" {
return $(curl.exe -s "https://api.ipify.org")
}
}
return $Addr
}
# required envs
Set-Env -Key "DOCKER_HOST" -Value "npipe:////./pipe/docker_engine"
Set-Env -Key "CATTLE_ROLE" -Value "worker"
# clean up
$CLUSTER_CLEANUP = Get-Env -Key "CLUSTER_CLEANUP"
if ($CLUSTER_CLEANUP -eq "true")
{
Start-Process -NoNewWindow -Wait -FilePath "c:\etc\rancher\agent.exe"
exit 0
}
# init parameters
$CATTLE_SERVER = Get-Env -Key "CATTLE_SERVER"
$CATTLE_TOKEN = Get-Env -Key "CATTLE_TOKEN"
$CATTLE_NODE_NAME = Get-Env -Key "CATTLE_NODE_NAME"
$CATTLE_ADDRESS = Get-Env -Key "CATTLE_ADDRESS"
$CATTLE_INTERNAL_ADDRESS = Get-Env -Key "CATTLE_INTERNAL_ADDRESS"
$CATTLE_CA_CHECKSUM = Get-Env -Key "CATTLE_CA_CHECKSUM"
$CATTLE_NODE_LABEL = @()
$CATTLE_NODE_TAINTS = @()
# parse arguments
$vals = $null
for ($i = $args.Length; $i -ge 0; $i--)
{
$arg = $args[$i]
switch -regex ($arg)
{
'^(-d|--debug)$' {
Set-Env -Key "CATTLE_DEBUG" -Value "true"
$vals = $null
}
'^(-s|--server)$' {
$CATTLE_SERVER = ($vals | Select-Object -First 1)
$vals = $null
}
'^(-t|--token)$' {
$CATTLE_TOKEN = ($vals | Select-Object -First 1)
$vals = $null
}
'^(-c|--ca-checksum)$' {
$CATTLE_CA_CHECKSUM = ($vals | Select-Object -First 1)
$vals = $null
}
'^(-all|--all-roles)$' {
$vals = $null
}
'^(-e|--etcd)$' {
$vals = $null
}
'^(-w|--worker)$' {
$vals = $null
}
'^(-p|--controlplane)$' {
$vals = $null
}
'^(-r|--node-name)$' {
$CATTLE_NODE_NAME = ($vals | Select-Object -First 1)
$vals = $null
}
'^(-n|--no-register)$' {
Set-Env -Key "CATTLE_AGENT_CONNECT" -Value "true"
$vals = $null
}
'^(-a|--address)$' {
$CATTLE_ADDRESS = ($vals | Select-Object -First 1)
$vals = $null
}
'^(-i|--internal-address)$' {
$CATTLE_INTERNAL_ADDRESS = ($vals | Select-Object -First 1)
$vals = $null
}
'^(-l|--label)$' {
if ($vals) {
$CATTLE_NODE_LABEL += $vals
}
$vals = $null
}
'^(-o|--only-write-certs)$' {
Set-Env -Key "CATTLE_WRITE_CERT_ONLY" -Value "true"
$vals = $null
}
'^--taints$' {
if ($vals) {
$CATTLE_NODE_TAINTS += $vals
}
$vals = $null
}
default {
if ($vals) {
$vals = ,$arg + $vals
} else {
$vals = @($arg)
}
}
}
}
# use the register token to request wins server
if (Test-Path -PathType Leaf -Path "c:\cattle-credentials\token")
{
$token = Get-Content -Path "c:\cattle-credentials\token" -Raw -ErrorAction Ignore
Set-Env -Key "WINS_AUTH_TOKEN" -Value $token
}
# check docker npipe
$CATTLE_CLUSTER = Get-Env -Key "CATTLE_CLUSTER"
if ($CATTLE_CLUSTER -ne "true")
{
$dockerNPipe = Get-ChildItem //./pipe/ -ErrorAction Ignore | ? Name -eq "docker_engine"
if (-not $dockerNPipe) {
Log-Warn "Default docker named pipe is not found"
Log-Warn "Please bind mount in the docker named pipe to //./pipe/docker_engine if docker errors occur"
Log-Warn "example: docker run -v //./pipe/custom_docker_named_pipe://./pipe/docker_engine ..."
}
}
# get address
$CATTLE_ADDRESS = Get-Address -Addr $CATTLE_ADDRESS
$CATTLE_INTERNAL_ADDRESS = Get-Address -Addr $CATTLE_INTERNAL_ADDRESS
# get default network metadata when nodeName or address is blank
if ((-not $CATTLE_NODE_NAME) -or (-not $CATTLE_ADDRESS))
{
$getAdapterJson = wins.exe cli net get
if ($?) {
$defaultNetwork = $getAdapterJson | ConvertTo-JsonObj
if ($defaultNetwork) {
if (-not $CATTLE_NODE_NAME) {
$CATTLE_NODE_NAME = $defaultNetwork.HostName
$CATTLE_NODE_NAME = $CATTLE_NODE_NAME.ToLower()
}
if (-not $CATTLE_ADDRESS) {
$CATTLE_ADDRESS = $defaultNetwork.AddressCIDR -replace "/32",""
}
} else {
Log-Warn "Could not convert '$getAdapterJson' to json object"
}
} else {
Log-Warn "Could not get host network metadata: $getAdapterJson"
}
}
# check token and address
$CATTLE_K8S_MANAGED = Get-Env -Key "CATTLE_K8S_MANAGED"
if ($CATTLE_K8S_MANAGED -ne "true")
{
if (-not $CATTLE_TOKEN) {
Log-Fatal "--token is a required option"
}
if (-not $CATTLE_ADDRESS) {
Log-Fatal "--address is a required option"
}
}
# check rancher server address
if (-not $CATTLE_SERVER)
{
Log-Fatal "--server is a required option"
}
# check rancher server
try
{
curl.exe --insecure -s -fL "$CATTLE_SERVER/ping" | Out-Null
if ($?) {
Log-Info "$CATTLE_SERVER is accessible"
} else {
Log-Fatal "$CATTLE_SERVER is not accessible"
}
}
catch
{
Log-Fatal "$CATTLE_SERVER is not accessible: $($_.Exception.Message)"
}
# download cattle server CA
if ($CATTLE_CA_CHECKSUM)
{
$sslCertDir = Get-Env -Key "SSL_CERT_DIR"
$server = $CATTLE_SERVER
$caChecksum = $CATTLE_CA_CHECKSUM
$temp = New-TemporaryFile
$cacerts = $null
try {
$cacerts = $(curl.exe --insecure -s -fL "$server/v3/settings/cacerts" | ConvertTo-JsonObj).value
} catch {}
if (-not $cacerts) {
Log-Fatal "Could not get cattle server CA from $server"
}
$cacerts + "`n" | Out-File -NoNewline -Encoding ascii -FilePath $temp.FullName
$tempHasher = Get-FileHash -LiteralPath $temp.FullName -Algorithm SHA256
if ($tempHasher.Hash.ToLower() -ne $caChecksum.ToLower()) {
$temp.Delete()
Log-Fatal "Actual cattle server CA checksum is $($tempHasher.Hash.ToLower()), $server/v3/settings/cacerts does not match $($caChecksum.ToLower())"
}
Remove-Item -Force -Recurse -Path "$sslCertDir\serverca" -ErrorAction Ignore
New-Item -Force -ItemType Directory -Path $sslCertDir -ErrorAction Ignore | Out-Null
$temp.MoveTo("$sslCertDir\serverca")
# import the self-signed certificate
$caBytes = $null
Get-Content "$sslCertDir\serverca" | % {
if ($_ -match '-+BEGIN CERTIFICATE-+') {
$caBytes = @()
} elseif ($_ -match '-+END CERTIFICATE-+') {
$caTemp = New-TemporaryFile
$caString = [Convert]::ToBase64String($caBytes)
Set-Content -Value $caString -Path $caTemp.FullName
certoc.exe -addstore root $caTemp.FullName | Out-Null
if (-not $?) {
$caTemp.Delete()
Log-Fatal "Failed to import rancher server certificates to Root"
}
$caTemp.Delete()
} else {
$caBytes += [Convert]::FromBase64String($_)
}
}
$CATTLE_SERVER_HOSTNAME = ([System.Uri]"$server").Host
$CATTLE_SERVER_HOSTNAME_WITH_PORT = ([System.Uri]"$server").Authority
# windows path could not allow colons
$CATTLE_SERVER_HOSTNAME_WITH_PORT = $CATTLE_SERVER_HOSTNAME_WITH_PORT -replace ":", ""
$dockerCertsPath = "c:\etc\docker\certs.d\$CATTLE_SERVER_HOSTNAME_WITH_PORT"
New-Item -Force -ItemType Directory -Path $dockerCertsPath -ErrorAction Ignore | Out-Null
Copy-Item -Force -Path "$sslCertDir\serverca" -Destination "$dockerCertsPath\ca.crt" -ErrorAction Ignore
}
# add labels
$getVersionJson = wins.exe cli host get-version
if ($?) {
$windowsCurrentVersion = $getVersionJson | ConvertTo-JsonObj
if ($windowsCurrentVersion) {
$versionTag = "$($windowsCurrentVersion.CurrentMajorVersionNumber).$($windowsCurrentVersion.CurrentMinorVersionNumber).$($windowsCurrentVersion.CurrentBuildNumber).$($windowsCurrentVersion.UBR)"
$CATTLE_NODE_LABEL += @("rke.cattle.io/windows-version=$versionTag")
$CATTLE_NODE_LABEL += @("rke.cattle.io/windows-release-id=$($windowsCurrentVersion.ReleaseId)")
$CATTLE_NODE_LABEL += @("rke.cattle.io/windows-major-version=$($windowsCurrentVersion.CurrentMajorVersionNumber)")
$CATTLE_NODE_LABEL += @("rke.cattle.io/windows-minor-version=$($windowsCurrentVersion.CurrentMinorVersionNumber)")
$CATTLE_NODE_LABEL += @("rke.cattle.io/windows-kernel-version=$($windowsCurrentVersion.BuildLabEx)")
$CATTLE_NODE_LABEL += @("rke.cattle.io/windows-build=$($windowsCurrentVersion.CurrentBuild)")
} else {
Log-Warn "Could not convert Windows Current Version JSON '$getVersionJson' to object"
}
} else {
Log-Warn "Could not get host version: $getVersionJson"
}
# set environment variables
Set-Env -Key "CATTLE_SERVER" -Value $CATTLE_SERVER
Set-Env -Key "CATTLE_TOKEN" -Value $CATTLE_TOKEN
Set-Env -Key "CATTLE_ADDRESS" -Val $CATTLE_ADDRESS
Set-Env -Key "CATTLE_INTERNAL_ADDRESS" -Val $CATTLE_INTERNAL_ADDRESS
Set-Env -Key "CATTLE_NODE_NAME" -Value $CATTLE_NODE_NAME
Set-Env -Key "CATTLE_NODE_LABEL" -Value $($CATTLE_NODE_LABEL -join ",")
Set-Env -Key "CATTLE_NODE_TAINTS" -Value $($CATTLE_NODE_TAINTS -join ",")
# upgrade wins.exe
Transfer-File -Src c:\Windows\wins.exe -Dst c:\etc\rancher\wins\wins.exe
Start-Process -NoNewWindow -Wait -FilePath "c:\etc\rancher\agent.exe"