diff --git a/server/scripts/update.ps1 b/server/scripts/update.ps1 index 6ae1377..0160c6e 100644 --- a/server/scripts/update.ps1 +++ b/server/scripts/update.ps1 @@ -1,14 +1,245 @@ -$serverDataFile = "..\services\server\utils\serverData.json" +param ( + [string]$server, + [string]$token, + [string]$location, + [string]$devFolder, + [string]$serverIP, + [string]$build, + [string]$type, + [string]$username, + [string]$admpass, + [string]$obslst, + [string]$obsBuild +) +# Convert the plain-text password to a SecureString +$securePass = ConvertTo-SecureString $admpass -AsPlainText -Force +$credentials = New-Object System.Management.Automation.PSCredential($username, $securePass) -$jsonContent = Get-Content -Path $serverDataFile -Raw +# lets get the version of the app we are updating +$pkgFile = "$devFolder\package.json" +$package = Get-Content -Path $pkgFile -Raw | ConvertFrom-Json -# Convert the JSON content to a PowerShell object -$jsonObject = $jsonContent | ConvertFrom-Json +$version = "$($package.version)-$($package.admConfig.build -1)" -# Access the data in the JSON object -$servers = $jsonObject.servers +# Checking to make sure the server is up and online +Write-Output "Checking if $($token) is online to update." +$pingResult = Test-Connection -ComputerName $serverIP -Count 2 -Quiet +if (-not $pingResult) { + Write-Output "Server $($server) $($serverIP) is NOT reachable. Exiting script." + exit 1 # Terminate the script with a non-zero exit code +} +Write-Output "Server $($server) ($serverIP) is online." -Write-Host $servers \ No newline at end of file +# get the file name we want to grab + +$buildZip = "lstv2-$version.zip" + +if (-Not (Test-Path -Path "$($build)\$($buildZip)")) { + Write-Host "Build is missing from the build folder." + Write-host $buildZip + exit +} + +Write-Host "---------------Starting the update Process----------------------------------" +Write-Host "File to be copied over is $buildZip" +Write-Host "Coping files to $($server)" +$destination = "\\$($server)\$($location)" -replace ":", "$" +Write-Host $destination +Write-Host "Forcing the removal of the mapped drive." +Get-PSDrive -Name "z" -ErrorAction SilentlyContinue | Remove-PSDrive -Force + +# Create a mapped drive with credentials using New-PSDrive for the current session + +try { + + New-PSDrive -Name "z" -PSProvider FileSystem -Root $destination -Credential $credentials + + # Create the update folder if it doesn't exist + if (-not (Test-Path -Path $destination)) { + New-Item -ItemType Directory -Path $destination -Force + } + + # Copying files to the server + Write-Host "Copying files to $($server)" + Copy-Item -Path "$($build)\$($buildZip)" -Destination "z:\" -Recurse -Force + Write-Host "Files copied to $($server)" +} catch { + Write-Host "Error: $_" +} finally { + # Remove the mapped drive after copying + if (Get-PSDrive -Name "z" -ErrorAction SilentlyContinue) { + Write-Host "Removing mapped drive..." + Remove-PSDrive -Name "z" + } +} + +write-Host $extractedFolderPath = "$server\$location$(if ($token -eq "usiow2") { "_2" })" + +# The script that runs inside the plant. +$plantFunness = { + param ($server, $token, $location, $buildFile, $buildLoc, $obslst, $obsBuild) + + $localPath = $location -replace '\$', ':' + $serverFile = "$($localPath)\$buildFile" + $serverPath = "$($localPath)" + + Write-Host "In the plant we go!!!!!" + Write-Host "Unzipping the folder..." + + $extractedFolderPath = $serverPath + + # Extract the files to the build path + try { + # Expand the archive + Expand-Archive -Path $serverFile -DestinationPath $extractedFolderPath -Force + + # Delete the zip file after extraction + Write-Host "Deleting the zip file..." + Remove-Item -Path $serverFile -Force + } catch { + Write-Host "Error: $_" + exit 1 # Exit with a non-zero code if there's an error + } + + Write-Host "-----------------------Dealing with LSTv1 Stuff ------------------------------------" + try { + # Expand the archive + Expand-Archive -Path "$($localPath)\$($obsBuild)" -DestinationPath $obslst -Force + + # Delete the zip file after extraction + Write-Host "Deleting the zip file..." + Remove-Item -Path "$($localPath)\$($obsBuild)" -Force + } catch { + Write-Host "Error: $_" + exit 1 # Exit with a non-zero code if there's an error + } + + ############################################################################ + Write-Host "Stopping the services to do the updates, pkgs and db changes." + + Write-Host "Stopping services to update" + $serviceGateway = "LST-Gateway$(if ($token -eq "usiow2") { "_2" })" + $serviceAuth = "LST-Auth$(if ($token -eq "usiow2") { "_2" })" + $serviceSystem = "LST-System$(if ($token -eq "usiow2") { "_2" })" + $serviceApp = "LST-App$(if ($token -eq "usiow2") { "_2" })" + $serviceFrontEnd = "LST-frontend$(if ($token -eq "usiow2") { "_2" })" + $serviceOcme = "LST-Ocme$(if ($token -eq "usiow2") { "_2" })" + $serviceLstV2 = "LSTV2$(if ($token -eq "usiow2") { "_2" })" + + if($token -eq "usday1"){ + Write-Host "Stopping $($serviceOcme)" + Stop-Service -DisplayName $serviceOcme -Force + } + + Write-Host "Stopping $($serviceGateway)" + Stop-Service -DisplayName $serviceGateway -Force + Start-Sleep -Seconds 1 + + Write-Host "Stopping $($serviceAuth)" + Stop-Service -DisplayName $serviceAuth -Force + Start-Sleep -Seconds 1 + + Write-Host "Stopping $($serviceSystem)" + Stop-Service -DisplayName $serviceSystem -Force + Start-Sleep -Seconds 1 + + Write-Host "Stopping $($serviceApp)" + Stop-Service -DisplayName $serviceApp -Force + Start-Sleep -Seconds 1 + + Write-Host "Stopping $($serviceFrontEnd)" + Stop-Service -DisplayName $serviceFrontEnd -Force + Start-Sleep -Seconds 1 + + Write-Host "Stopping $($serviceLstV2)" + Stop-Service -DisplayName $serviceLstV2 -Force + Start-Sleep -Seconds 1 + + ################################################################# + # Service removoal and making sure we have the new version added + ################################################################# + + $appPath = $extractedFolderPath + $nssmPath = $serverPath + "\nssm.exe" + $npmPath = "C:\Program Files\nodejs\npm.cmd" # Path to npm.cmd + + ################################################################# + # Removing all the old services + ################################################################# + Write-Host "Removing services that are no longer used." + & $nssmPath remove "LogisticsSupportTool" confirm + & $nssmPath remove $serviceAuth confirm + Start-Sleep -Seconds 5 + + ## adding in lstAdm + Write-Host "Adding $($serviceLstV2)... incase its missing." + $commandToRun = "run start" + $description = "logistics Support Tool" + & $nssmPath install $serviceLstV2 $npmPath $commandToRun + Write-Host "Setting the app directory" + & $nssmPath set $serviceLstV2 AppDirectory $appPath + Write-Host "Setting the description" + & $nssmPath set $serviceLstV2 Description $description + Write-Host "Setting recovery options" + # Set recovery options + sc.exe failure $serviceLstV2 reset= 0 actions= restart/5000/restart/5000/restart/5000 + + # Doing an install + Write-Host "Running the install to make sure everything is updated." + Set-Location $serverPath + npm run prodinstall # --omit=dev + Write-Host "Finished doing updates" + Start-Sleep -Seconds 1 + + ########################################################### + # Old system still active until we have everything off it + ########################################################### + Write-Host "Running install on obs server." + Set-Location $obslst + npm run newinstall # --omit=dev + Write-Host "Update the frontend" + npm run install:front + npm run install:ui + + Write-Host "Running db updates" + npm run db:migrate + Start-Sleep -Seconds 1 + npm run db:gen + Start-Sleep -Seconds 1 + Write-Host "incase a new default setting was added we want to add it in." + npm run db:init + + ########################################################### + # Starting the services back up. + ########################################################### + Write-Host "Starting the services" + Write-Host "Starting $($serviceSystem)" + Start-Service -DisplayName $serviceSystem + Start-Sleep -Seconds 1 + Write-Host "Starting $($serviceGateway)" + Start-Service -DisplayName $serviceGateway + Start-Sleep -Seconds 1 + #Write-Host "Starting $($serviceAuth)" + #Start-Service -DisplayName $serviceAuth + #Start-Sleep -Seconds 1 + Write-Host "Starting $($serviceApp)" + Start-Service -DisplayName $serviceApp + Start-Sleep -Seconds 1 + Write-Host "Starting $($serviceFrontEnd)" + Start-Service -DisplayName $serviceFrontEnd + Start-Sleep -Seconds 1 + Write-Host "Starting $( $serviceLstV2)" + Start-Service -DisplayName $serviceLstV2 + Start-Sleep -Seconds 1 + Write-Host "$($server) finished updating" + + if($token -eq "usday1"){ + Write-Host "Starting $($serviceOcme)" + Start-Service -DisplayName $serviceOcme + } + +} +Invoke-Command -ComputerName $server -ScriptBlock $plantFunness -ArgumentList $server, $token, $location, $buildZip, $buildLoc, $obslst, $obsBuild -Credential $credentials \ No newline at end of file diff --git a/server/scripts/updateServers.ts b/server/scripts/updateServers.ts new file mode 100644 index 0000000..6eae1c1 --- /dev/null +++ b/server/scripts/updateServers.ts @@ -0,0 +1,122 @@ +import {spawn} from "child_process"; +import {getAppInfo} from "../globalUtils/appInfo.js"; +import {db} from "../../database/dbclient.js"; +import {serverData} from "../../database/schema/serverData.js"; +import {eq, sql} from "drizzle-orm"; +import {createLog} from "../services/logger/logger.js"; + +const updateServer = async (devApp: string, server: string) => { + const app = await getAppInfo(devApp); + const serverInfo = await db.select().from(serverData).where(eq(serverData.sName, server.toLowerCase())); + + const scriptPath = `${process.env.DEVFOLDER}\\server\\scripts\\update.ps1 `; + const args = [ + "-NoProfile", + "-ExecutionPolicy", + "Bypass", + "-File", + scriptPath, + "-username", + process.env.ADMUSER, // needs moved to somewhere else. + "-admpass", + process.env.ADMPASSWORD, // needs moved to somewhere else. + "-devFolder", + process.env.DEVFOLDER, + "-server", + serverInfo[0].serverDNS, + "-serverIP", + serverInfo[0].idAddress, + "-token", + serverInfo[0].plantToken, + "-build", + `${process.env.DEVFOLDER}\\builds`, + "-location", + serverInfo[0].serverLoc, + "-obslst", + serverInfo[0].oldVersion, + "-obsBuild", + app.admConfig.oldBuild, + , + ]; + + return new Promise((resolve, reject) => { + const process = spawn("powershell", args); + + //let stdout = ""; + //let stderr = ""; + + // Collect stdout data + process.stdout.on("data", (data) => { + const output = data.toString().trim(); + createLog("info", "lst", "serverUpdater", `${output}`); + //onData(output); + }); + + // Collect stderr data + process.stderr.on("data", (data) => { + const output = data.toString().trim(); + createLog("info", "lst", "serverUpdater", `${output}`); + //onData(output); + }); + + // Handle process close + process.on("close", async (code) => { + if (code === 0) { + // if (count >= servers) { + // //onClose(`Server completed with code: ${code}`); + // } + createLog("info", "lst", "serverUpdater", `${server}`); + + //update the last build. + try { + await db.update(serverData).set({lastUpdated: sql`NOW()`}); + } catch (error) { + createLog( + "error", + "lst", + "serverUpdater", + `There was an error updating the last time the server was updated: ${error}` + ); + } + + resolve({success: true, code}); + } else { + const errorMessage = `Process exited with code ${code}`; + + // if (count >= servers) { + // //onClose(code); + // } + + reject(new Error(errorMessage)); + } + }); + + // Handle errors with the process itself + process.on("error", (error) => { + //onError(err.message); + createLog("error", "lst", "serverUpdater", `${error}`); + reject(error); + }); + }); +}; + +export async function processAllServers(devApp: string) { + const servers = await db.select().from(serverData); + + createLog("info", "lst", "serverUpdater", `Running the update on all servers`); + let count = 1; + for (const server of servers) { + try { + const updateToServer = await updateServer(devApp, server.sName); + createLog("info", "lst", "serverUpdater", `${server.sName} was updated.`); + count = count + 1; + + //return {success: true, message: `${server.sName} was updated.`, data: updateToServer}; + } catch (error: any) { + createLog("info", "lst", "serverUpdater", `Error updating ${server.sName}: ${error.message}`); + //return {success: false, message: `Error updating ${server.sName}: ${error.message}`}; + } + } +} + +updateServer("C:\\Users\\matthes01\\Documents\\lstv2", "test"); diff --git a/server/scripts/zipUpBuild.ts b/server/scripts/zipUpBuild.ts index 194f5e2..8ef737f 100644 --- a/server/scripts/zipUpBuild.ts +++ b/server/scripts/zipUpBuild.ts @@ -3,6 +3,7 @@ import path from "path"; import fs from "fs"; import {execSync} from "child_process"; import {createLog} from "../services/logger/logger.js"; +import {getAppInfo} from "../globalUtils/appInfo.js"; // create the ignore list const ignoreList = [ @@ -34,18 +35,6 @@ const ignoreList = [ "frontend/vite.config.ts", ]; -const getAdmInfo = async (appLock: string) => { - try { - const packagePath = path.join(appLock, "package.json"); - const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8")); - //const version = packageJson.version; - return packageJson; - } catch (error) { - createLog("error", "lst", "zipUpBuild", `Error in getting the version: ${error}`); - return error; - } -}; - const shouldIgnore = (itemPath: any) => { const normalizedItemPath = itemPath.replace(/\\/g, "/"); @@ -109,7 +98,7 @@ const updateBuildNumber = (appLock: string) => { }; export const createZip = async (appLock: string) => { - const app = await getAdmInfo(appLock); + const app = await getAppInfo(appLock); const zip = new AdmZip(); //dest path for this app... hard coded for meow will be in db later