ambari-agent/conf/windows/createservice.ps1 (178 lines of code) (raw):

# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License param( [String] [Parameter(Mandatory=$true )] $username, [String] [Parameter(Mandatory=$true )] $password, [String] [Parameter(Mandatory=$true )] $servicename, [String] [Parameter(Mandatory=$true )] $hdpResourcesDir, [String] [Parameter(Mandatory=$true )] $servicecmdpath ) function Invoke-Cmd ($command) { Write-Output $command $out = cmd.exe /C "$command" 2>&1 Write-Output $out return $out } function Invoke-CmdChk ($command) { Write-Output $command $out = cmd.exe /C "$command" 2>&1 Write-Output $out if (-not ($LastExitCode -eq 0)) { throw "Command `"$out`" failed with exit code $LastExitCode " } return $out } ### Stops and deletes the Hadoop service. function StopAndDeleteHadoopService( [String] [Parameter( Position=0, Mandatory=$true )] $service ) { Write-Output "Stopping $service" $s = Get-Service $service -ErrorAction SilentlyContinue if( $s -ne $null ) { Stop-Service $service $cmd = "sc.exe delete $service" Invoke-Cmd $cmd } } # Convenience method for processing command-line credential objects # Assumes $credentialsHash is a hash with one of the following being true: # - keys "username" and "password"/"passwordBase64" are set to strings # - key "credentialFilePath" is set to the path of a serialized PSCredential object function Get-HadoopUserCredentials($credentialsHash) { Write-Output "Using provided credentials for username $($credentialsHash["username"])" | Out-Null $username = $credentialsHash["username"] if($username -notlike "*\*") { $username = "$ENV:COMPUTERNAME\$username" } $securePassword = $credentialsHash["password"] | ConvertTo-SecureString -AsPlainText -Force $creds = New-Object System.Management.Automation.PSCredential $username, $securePassword return $creds } ### Creates and configures the service. function CreateAndConfigureHadoopService( [String] [Parameter( Position=0, Mandatory=$true )] $service, [String] [Parameter( Position=1, Mandatory=$true )] $hdpResourcesDir, [String] [Parameter( Position=2, Mandatory=$true )] $serviceBinDir, [String] [Parameter( Position=3, Mandatory=$true )] $servicecmdpath, [System.Management.Automation.PSCredential] [Parameter( Position=4, Mandatory=$true )] $serviceCredential ) { if ( -not ( Get-Service "$service" -ErrorAction SilentlyContinue ) ) { Write-Output "Creating service `"$service`" as $serviceBinDir\$service.exe" $xcopyServiceHost_cmd = "copy /Y `"$hdpResourcesDir\namenode.exe`" `"$serviceBinDir\$service.exe`"" Invoke-CmdChk $xcopyServiceHost_cmd #HadoopServiceHost.exe will write to this log but does not create it #Creating the event log needs to be done from an elevated process, so we do it here if( -not ([Diagnostics.EventLog]::SourceExists( "$service" ))) { [Diagnostics.EventLog]::CreateEventSource( "$service", "" ) } Write-Output "Adding service $service" if ($serviceCredential.Password.get_Length() -ne 0) { $s = New-Service -Name "$service" -BinaryPathName "$serviceBinDir\$service.exe" -Credential $serviceCredential -DisplayName "Apache Hadoop $service" if ( $s -eq $null ) { throw "CreateAndConfigureHadoopService: Service `"$service`" creation failed" } } else { # Separately handle case when password is not provided # this path is used for creating services that run under (AD) Managed Service Account # for them password is not provided and in that case service cannot be created using New-Service commandlet $serviceUserName = $serviceCredential.UserName $cred = $serviceCredential.UserName.Split("\") # Throw exception if domain is not specified if (($cred.Length -lt 2) -or ($cred[0] -eq ".")) { throw "Environment is not AD or domain is not specified" } $cmd="$ENV:WINDIR\system32\sc.exe create `"$service`" binPath= `"$serviceBinDir\$service.exe`" obj= $serviceUserName DisplayName= `"Apache Hadoop $service`" " try { Invoke-CmdChk $cmd } catch { throw "CreateAndConfigureHadoopService: Service `"$service`" creation failed" } } $cmd="$ENV:WINDIR\system32\sc.exe failure $service reset= 30 actions= restart/5000" Invoke-CmdChk $cmd $cmd="$ENV:WINDIR\system32\sc.exe config $service start= demand" Invoke-CmdChk $cmd Write-Output "Creating service config ${serviceBinDir}\$service.xml" $cmd = "$servicecmdpath --service $service > `"$serviceBinDir\$service.xml`"" Invoke-CmdChk $cmd } else { Write-Output "Service `"$service`" already exists, Removing `"$service`"" StopAndDeleteHadoopService $service CreateAndConfigureHadoopService $service $hdpResourcesDir $serviceBinDir $servicecmdpath $serviceCredential } } try { Write-Output "Creating credential object" ### ### Create the Credential object from the given username and password or the provided credentials file ### $serviceCredential = Get-HadoopUserCredentials -credentialsHash @{"username" = $username; "password" = $password} $username = $serviceCredential.UserName Write-Output "Username: $username" Write-Output "Creating service $service" ### ### Create Service ### CreateAndConfigureHadoopService $servicename $hdpResourcesDir $hdpResourcesDir $servicecmdpath $serviceCredential Write-Output "Done" } catch { Write-Output "Failure" exit 1 }