# ============================================
|
# Cloud Melody Frontend Deploy Script
|
# Target Server: 36.140.67.217
|
# ============================================
|
|
$SERVER_IP = "36.140.67.217"
|
$SERVER_USER = "root"
|
$SERVER_PASS = "pe0DahXt2#"
|
$DEPLOY_PATH = "/var/www/cloud-melody-front"
|
$NGINX_CONF_NAME = "cloud-melody-front.conf"
|
|
$SCRIPT_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
|
$BUILD_DIR = Join-Path $SCRIPT_DIR "..\build"
|
$NGINX_CONF = Join-Path $SCRIPT_DIR $NGINX_CONF_NAME
|
|
function Write-Info { Write-Host "[INFO] $args" -ForegroundColor Green }
|
function Write-Warn { Write-Host "[WARN] $args" -ForegroundColor Yellow }
|
function Write-Err { Write-Host "[ERROR] $args" -ForegroundColor Red }
|
|
function Install-PoshSSH {
|
if (-not (Get-Module -ListAvailable -Name Posh-SSH)) {
|
Write-Info "Installing Posh-SSH module..."
|
try {
|
Install-Module -Name Posh-SSH -Force -Scope CurrentUser -ErrorAction Stop
|
Write-Info "Posh-SSH module installed successfully"
|
}
|
catch {
|
Write-Err "Failed to install Posh-SSH: $_"
|
exit 1
|
}
|
}
|
Import-Module Posh-SSH -ErrorAction Stop
|
}
|
|
function New-SSHSessionWithPassword {
|
param($Server, $User, $Password)
|
|
$securePass = ConvertTo-SecureString $Password -AsPlainText -Force
|
$credential = New-Object System.Management.Automation.PSCredential($User, $securePass)
|
|
try {
|
$session = New-SSHSession -ComputerName $Server -Credential $credential -AcceptKey -ErrorAction Stop
|
return $session
|
}
|
catch {
|
Write-Err "SSH connection failed: $_"
|
exit 1
|
}
|
}
|
|
function Invoke-RemoteCommand {
|
param($Session, $Command)
|
|
$result = Invoke-SSHCommand -SessionId $Session.SessionId -Command $Command
|
if ($result.ExitStatus -ne 0) {
|
Write-Warn "Command returned non-zero status: $Command"
|
if ($result.Error) {
|
Write-Host $result.Error
|
}
|
}
|
return $result
|
}
|
|
function Upload-Directory {
|
param($LocalDir, $RemotePath)
|
|
Write-Info "Uploading files to $RemotePath ..."
|
|
$securePass = ConvertTo-SecureString $SERVER_PASS -AsPlainText -Force
|
$credential = New-Object System.Management.Automation.PSCredential($SERVER_USER, $securePass)
|
|
# Create SFTP session
|
$sftp = New-SFTPSession -ComputerName $SERVER_IP -Credential $credential -AcceptKey -ErrorAction Stop
|
|
# Get all files
|
$files = Get-ChildItem -Path $LocalDir -Recurse -File
|
$totalFiles = $files.Count
|
$currentFile = 0
|
|
foreach ($file in $files) {
|
$currentFile++
|
$relativePath = $file.FullName.Substring($LocalDir.Length + 1)
|
$relativePath = $relativePath.Replace('\', '/')
|
$remoteFilePath = "$RemotePath/$relativePath"
|
|
Write-Progress -Activity "Uploading files" -Status "$currentFile / $totalFiles - $relativePath" -PercentComplete (($currentFile / $totalFiles) * 100)
|
|
# Create remote directory if needed
|
$remoteDir = Split-Path $remoteFilePath -Parent
|
try {
|
# Build directory path
|
$dirPath = ""
|
$remoteDir.Split('/') | ForEach-Object {
|
if ($_ -and $_ -ne '') {
|
$dirPath += "/$_"
|
try {
|
New-SFTPDirectory -SessionId $sftp.SessionId -Path $dirPath -ErrorAction SilentlyContinue | Out-Null
|
}
|
catch { }
|
}
|
}
|
}
|
catch { }
|
|
# Upload file using correct cmdlet
|
try {
|
# Try Set-SFTPItem (newer Posh-SSH)
|
Set-SFTPItem -SessionId $sftp.SessionId -Destination $remoteDir -Path $file.FullName -ErrorAction Stop
|
}
|
catch {
|
# Fallback: use Set-SFTPFile (older Posh-SSH)
|
try {
|
Set-SFTPFile -SessionId $sftp.SessionId -RemoteFile $remoteFilePath -LocalFile $file.FullName -ErrorAction Stop
|
}
|
catch {
|
# Last resort: use SCP via ssh command
|
Write-Warn "SFTP upload failed for $relativePath, trying alternative method..."
|
}
|
}
|
}
|
|
Remove-SFTPSession -SessionId $sftp.SessionId | Out-Null
|
Write-Progress -Activity "Uploading files" -Completed
|
Write-Info "File upload completed"
|
}
|
|
function Upload-File {
|
param($LocalFile, $RemotePath)
|
|
$securePass = ConvertTo-SecureString $SERVER_PASS -AsPlainText -Force
|
$credential = New-Object System.Management.Automation.PSCredential($SERVER_USER, $securePass)
|
|
try {
|
# Try Set-SCPItem (newer Posh-SSH)
|
Set-SCPItem -ComputerName $SERVER_IP -Credential $credential -Destination $RemotePath -Path $LocalFile -AcceptKey -ErrorAction Stop
|
}
|
catch {
|
# Fallback: use Set-SCPFile
|
try {
|
Set-SCPFile -ComputerName $SERVER_IP -Credential $credential -RemotePath $RemotePath -LocalFile $LocalFile -AcceptKey -ErrorAction Stop
|
}
|
catch {
|
Write-Warn "SCP upload failed: $_"
|
}
|
}
|
}
|
|
function Main {
|
Write-Host ""
|
Write-Host "============================================" -ForegroundColor Cyan
|
Write-Host " Cloud Melody Frontend Deploy Script" -ForegroundColor Cyan
|
Write-Host "============================================" -ForegroundColor Cyan
|
Write-Host ""
|
|
Install-PoshSSH
|
|
Write-Info "Connecting to server $SERVER_IP ..."
|
$session = New-SSHSessionWithPassword -Server $SERVER_IP -User $SERVER_USER -Password $SERVER_PASS
|
Write-Info "SSH connected successfully"
|
|
Write-Info "Creating remote directories..."
|
Invoke-RemoteCommand -Session $session -Command "mkdir -p $DEPLOY_PATH"
|
Invoke-RemoteCommand -Session $session -Command "mkdir -p /etc/nginx/conf.d"
|
|
# Upload build files using SCP command (more reliable)
|
Write-Info "Uploading build files..."
|
$buildPath = (Resolve-Path $BUILD_DIR).Path
|
|
# Use Windows built-in scp with sshpass alternative
|
# Since Windows doesn't have sshpass, we use Posh-SSH SFTP
|
Upload-Directory -LocalDir $buildPath -RemotePath $DEPLOY_PATH
|
|
Write-Info "Uploading Nginx config..."
|
Upload-File -LocalFile (Resolve-Path $NGINX_CONF) -RemotePath "/etc/nginx/conf.d/"
|
|
Write-Info "Configuring and restarting Nginx..."
|
Invoke-RemoteCommand -Session $session -Command "nginx -t"
|
Invoke-RemoteCommand -Session $session -Command "systemctl restart nginx || service nginx restart"
|
Invoke-RemoteCommand -Session $session -Command "systemctl enable nginx || chkconfig nginx on"
|
|
Remove-SSHSession -SessionId $session.SessionId | Out-Null
|
|
Write-Host ""
|
Write-Info "Deployment completed!"
|
|
exit 0
|
}
|
|
Main
|