blob: f3936e2851eece7ca0369e2cd2f52ed1610582f7 [file] [log] [blame]
# 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
}