Compare commits

..

7 Commits

15 changed files with 274 additions and 92 deletions

View File

@@ -14,3 +14,4 @@ scripts/services.ps1
drizzle.config.ts drizzle.config.ts
tsconfig.json tsconfig.json
.includeCleanup .includeCleanup
.env-example

View File

@@ -1,5 +1,6 @@
lstWrapper/publish lstWrapper/publish
controller/lst_ctl.exe controller/lst_ctl.exe
controller/.env-example
scripts/update-controller-bumpBuild.ps1 scripts/update-controller-bumpBuild.ps1
scripts/update-controller-server.ps1 scripts/update-controller-server.ps1
scripts/update-controller-zip.ps1 scripts/update-controller-zip.ps1

View File

@@ -5,7 +5,7 @@ meta {
} }
post { post {
url: http://usmcd1vms036:8080/api/controller/update url: http://usmar1vms006:8080/lst/api/controller/update
body: json body: json
auth: inherit auth: inherit
} }

View File

@@ -13,7 +13,7 @@ import (
socketio "github.com/googollee/go-socket.io" socketio "github.com/googollee/go-socket.io"
) )
func copyBuild(server *socketio.Server, plant string) { func copyBuild(server *socketio.Server, plant string, drive string) {
// Load from environment in real-life code! // Load from environment in real-life code!
user := os.Getenv("ADM_USER") user := os.Getenv("ADM_USER")
pass := os.Getenv("ADM_PASS") pass := os.Getenv("ADM_PASS")
@@ -21,7 +21,7 @@ func copyBuild(server *socketio.Server, plant string) {
// latest build // latest build
latestbuild := lastestBuild() latestbuild := lastestBuild()
src := latestbuild src := latestbuild
plantServer := fmt.Sprintf("\\\\%v\\e$\\lst", plant) plantServer := fmt.Sprintf("\\\\%v\\%v$\\lst", plant, drive)
// Build PowerShell // Build PowerShell
psScript := fmt.Sprintf(` psScript := fmt.Sprintf(`

View File

@@ -31,6 +31,8 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/robfig/cron v1.2.0 // indirect
github.com/robfig/cron/v3 v3.0.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.8.0 // indirect golang.org/x/arch v0.8.0 // indirect

View File

@@ -55,6 +55,10 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E=
github.com/robfig/cron/v3 v3.0.0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=

View File

@@ -74,6 +74,13 @@
</div> </div>
<div id="logWindow"></div> <div id="logWindow"></div>
<div>
<button id="USMCD1VMS036">USMCD1VMS036</button>
<button id="USBET1VMS006">USBET1VMS006</button>
<button id="USBOW1VMS006">USBOW1VMS006</button>
<button id="USSLC1VMS006">USSLC1VMS006</button>
<button id="USSTP1VMS006">USSTP1VMS006</button>
</div>
<script> <script>
// ✅ Define socket in global scope // ✅ Define socket in global scope
@@ -198,6 +205,50 @@
}; };
}; };
// all the server copy buttons
document.getElementById("USMCD1VMS036").onclick = () => {
socket.emit("update", {
action: "copy",
target: "USMCD1VMS036",
drive: "e",
}); // "frontend" = payload target
logMessage("info", "Copying to USMCD1VMS036");
};
document.getElementById("USBET1VMS006").onclick = () => {
socket.emit("update", {
action: "copy",
target: "USBET1VMS006",
drive: "e",
}); // "frontend" = payload target
logMessage("info", "Copying to USBET1VMS006");
};
document.getElementById("USBOW1VMS006").onclick = () => {
socket.emit("update", {
action: "copy",
target: "USBOW1VMS006",
drive: "e",
}); // "frontend" = payload target
logMessage("info", "Copying to USBOW1VMS006");
};
document.getElementById("USSLC1VMS006").onclick = () => {
socket.emit("update", {
action: "copy",
target: "USSLC1VMS006",
drive: "e",
}); // "frontend" = payload target
logMessage("info", "Copying to USSLC1VMS006");
};
document.getElementById("USSTP1VMS006").onclick = () => {
socket.emit("update", {
action: "copy",
target: "USSTP1VMS006",
drive: "d",
}); // "frontend" = payload target
logMessage("info", "Copying to USSLC1VMS006");
};
socket.on("logs", (msg) => logMessage("logs", msg)); socket.on("logs", (msg) => logMessage("logs", msg));
socket.on("errors", (msg) => logMessage("errors", msg)); socket.on("errors", (msg) => logMessage("errors", msg));
socket.on("buildlogs", (msg) => logMessage("build", msg)); socket.on("buildlogs", (msg) => logMessage("build", msg));

View File

@@ -0,0 +1,5 @@
package bot
func main() {
}

View File

@@ -6,11 +6,13 @@ import (
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
socketio "github.com/googollee/go-socket.io" socketio "github.com/googollee/go-socket.io"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"lst.net/pkg"
) )
func main() { func main() {
@@ -90,13 +92,42 @@ func main() {
registerUpdateChannel(server) registerUpdateChannel(server)
// Broadcast logs to room // Broadcast logs to room
go func() { // go func() {
for i := 0; ; i++ { // for i := 0; ; i++ {
time.Sleep(2 * time.Second) // time.Sleep(2 * time.Second)
msg := fmt.Sprintf("Log line %d @ %s", i, time.Now().Format(time.RFC3339)) // msg := fmt.Sprintf("Log line %d @ %s", i, time.Now().Format(time.RFC3339))
// server.BroadcastToRoom("/", "logs", "logs", msg)
// }
// }()
// go pkg.JobScheduler(server, "0 9 * * *", func() {
// fmt.Println("This is the time checker")
// server.BroadcastToRoom("/", "logs", "logs", "Just ran at 9:00 for example")
// })
// schedule the update checker
go pkg.JobScheduler(server, "0 8 * * 1-4", func() {
host, err := os.Hostname()
if err != nil {
server.BroadcastToRoom("/", "update", "updateLogs", "Could not retrieve hostname")
return
}
if strings.Contains(host, "VMS") || strings.Contains(host, "vms") {
fmt.Println("On a server ok to start the update job")
server.BroadcastToRoom("/", "update", "updateLogs", "On a server ok to start the update job")
updates := UpdateApp(server)
fmt.Println("📦 Starting update loop")
for msg := range updates { // this will block until the channel closes
fmt.Println(msg)
server.BroadcastToRoom("/", "logs", "logs", msg) server.BroadcastToRoom("/", "logs", "logs", msg)
} }
}()
fmt.Println("✅ Update process finished")
}
})
// Broadcast errors to room // Broadcast errors to room
go func() { go func() {

View File

@@ -0,0 +1,31 @@
package pkg
import (
"fmt"
"time"
_ "time/tzdata"
socketio "github.com/googollee/go-socket.io"
"github.com/robfig/cron/v3"
)
func JobScheduler(server *socketio.Server, cronTime string, jobFunc func()) {
// time zone helper https://nodatime.org/TimeZones
loc, err := time.LoadLocation(("America/Chicago"))
if err != nil {
fmt.Printf("There was an error getting location: %v", err)
server.BroadcastToRoom("/", "logs", "logs", fmt.Sprintf("There was an error getting location: %v", err))
}
crontJob := cron.New(cron.WithLocation(loc)) // cron.WithSeconds()
// reference for the cron time format https://pkg.go.dev/github.com/robfig/cron@v1.2.0#hdr-CRON_Expression_Format
// we can use 6 feilds but we need to add this in with cron.WithSeconds into our cron job other wise we can use use the standard 5 fields https://crontab.guru/
crontJob.AddFunc(cronTime, jobFunc)
crontJob.Start()
}

View File

@@ -17,6 +17,7 @@ import (
type UpdatePayload struct { type UpdatePayload struct {
Action string `json:"action"` Action string `json:"action"`
Target string `json:"target"` Target string `json:"target"`
Drive string `json:"drive"`
} }
func registerUpdateChannel(server *socketio.Server) { func registerUpdateChannel(server *socketio.Server) {
@@ -31,7 +32,7 @@ func registerUpdateChannel(server *socketio.Server) {
server.OnEvent("/", "update", func(s socketio.Conn, payload UpdatePayload) { server.OnEvent("/", "update", func(s socketio.Conn, payload UpdatePayload) {
switch strings.ToLower(payload.Action) { switch strings.ToLower(payload.Action) {
case "copy": case "copy":
copyLatestBuild(server, payload.Target) copyLatestBuild(server, payload.Target, payload.Drive)
case "update": case "update":
updateServer(server, payload.Target) updateServer(server, payload.Target)
@@ -80,10 +81,10 @@ func updateServer(server *socketio.Server, target string) {
} }
} }
func copyLatestBuild(server *socketio.Server, target string) { func copyLatestBuild(server *socketio.Server, target string, drive string) {
server.BroadcastToRoom("/", "update", "updateLogs", server.BroadcastToRoom("/", "update", "updateLogs",
fmt.Sprintf("🚀 Copying latest build to %v", target)) fmt.Sprintf("🚀 Copying latest build to %v", target))
copyBuild(server, target) copyBuild(server, target, drive)
} }
func triggerRemoteUpdate(server *socketio.Server, remoteURL string, payload UpdatePayload) { func triggerRemoteUpdate(server *socketio.Server, remoteURL string, payload UpdatePayload) {

View File

@@ -46,7 +46,7 @@ Please note that if you plan to utlize the scanner app you must use IIS to run a
- Change the phycical path to the path that you have the lst wrapper in, below is the example we used to install the app from the install instructions. - Change the phycical path to the path that you have the lst wrapper in, below is the example we used to install the app from the install instructions.
```bash ```bash
E:\LST\lstWrapper E:\LST\lstWrapper\publish
``` ```
![](/img/install/application.png) ![](/img/install/application.png)

View File

@@ -53,8 +53,6 @@ Lastly scan the cage of preforms, resin, or color you will be consuming to the l
## Consuming new manual material via LST. ## Consuming new manual material via LST.
NOTE: you will need to be logged in and permissions in lst to be able to consume material.
Click on material helper on the left side bar. Click on material helper on the left side bar.
Enter the lot and running number and click consume, the card also comes with basic insturctions. Enter the lot and running number and click consume, the card also comes with basic insturctions.

View File

@@ -5,7 +5,8 @@ function Update-Server {
[string]$AppRoot, [string]$AppRoot,
[string]$Destination, [string]$Destination,
[string]$Server, [string]$Server,
[string]$Token [string]$Token,
[string]$ControllerBuild
) )
@@ -26,7 +27,8 @@ function Update-Server {
if ($num) { if ($num) {
$BuildNumber = $num + 1 $BuildNumber = $num + 1
} else { }
else {
$BuildNumber = 1 $BuildNumber = 1
} }
} }
@@ -35,7 +37,13 @@ function Update-Server {
$BuildNumber = $BuildNumber - 1 $BuildNumber = $BuildNumber - 1
# Convert to string # Convert to string
if ($ControllerBuild -eq "yes") {
$BuildNumber = $BuildNumber.ToString() $BuildNumber = $BuildNumber.ToString()
}
else {
$BuildNumber = ([int]$BuildNumber - 1).ToString()
}
# copy the latest build over # copy the latest build over
@@ -56,9 +64,11 @@ function Update-Server {
$zipFile = Join-Path $BuildFolder "controllers-$BuildNumber.zip" $zipFile = Join-Path $BuildFolder "controllers-$BuildNumber.zip"
Copy-Item -Path $zipFile -Destination "z:\" -Force Copy-Item -Path $zipFile -Destination "z:\" -Force
Write-Host "Files copied to $($Server)" Write-Host "Files copied to $($Server)"
} catch { }
catch {
Write-Host "Error: $_" Write-Host "Error: $_"
} finally { }
finally {
# Remove the mapped drive after copying # Remove the mapped drive after copying
if (Get-PSDrive -Name "z" -ErrorAction SilentlyContinue) { if (Get-PSDrive -Name "z" -ErrorAction SilentlyContinue) {
Write-Host "Removing mapped drive..." Write-Host "Removing mapped drive..."
@@ -68,7 +78,7 @@ function Update-Server {
# do the stop services, unzip, and restart service and pool # do the stop services, unzip, and restart service and pool
$ControllerUpdate = { $ControllerUpdate = {
param ($Server, $Token, $Destination, $BuildFile) param ($Server, $Token, $Destination, $BuildFile)
@@ -78,8 +88,8 @@ $ControllerUpdate = {
$BuildFileLoc = "$LocalPath\$BuildFile" $BuildFileLoc = "$LocalPath\$BuildFile"
# where is nssm.exe # where is nssm.exe
$nssmPath= Join-Path $LocalPath "nssm.exe" #$nssmPath = Join-Path $LocalPath "nssm.exe"
$npmPath = "C:\Program Files\nodejs\npm.cmd" #$npmPath = "C:\Program Files\nodejs\npm.cmd"
Write-Host "Stopping the services to do the updates, pkgs and db changes." Write-Host "Stopping the services to do the updates, pkgs and db changes."
@@ -90,26 +100,29 @@ $ControllerUpdate = {
Stop-Service -DisplayName $Controller -Force Stop-Service -DisplayName $Controller -Force
Start-Sleep -Seconds 1 Start-Sleep -Seconds 1
Write-Host "Stopping $($Wrapper)"
try { try {
Stop-WebAppPool -Name $Wrapper -ErrorAction Stop Stop-WebAppPool -Name $Wrapper -ErrorAction Stop
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
$state = (Get-WebAppPoolState -Name $Wrapper).Value $state = (Get-WebAppPoolState -Name $Wrapper).Value
Write-Host "Result: $state" Write-Host "Result: $state"
} catch { }
catch {
Write-Error $_.Exception.Message Write-Error $_.Exception.Message
} }
Write-Host "Unzipping the folder..." Write-Host "Unzipping the folder..."
write-host $BuildFileLoc #write-host $BuildFileLoc
write-host $LocalPath #write-host $LocalPath
# Extract the files to the build path # Extract the files to the build path
try { try {
# Expand the archive # Expand the archive
Expand-Archive -Path $BuildFileLoc -DestinationPath $LocalPath -Force Expand-Archive -Path $BuildFileLoc -DestinationPath $LocalPath -Force
} catch { }
catch {
Write-Host "Error: $_" Write-Host "Error: $_"
exit 1 # Exit with a non-zero code if there's an error exit 1 # Exit with a non-zero code if there's an error
} }
@@ -124,12 +137,14 @@ $ControllerUpdate = {
Start-Service -DisplayName $Controller Start-Service -DisplayName $Controller
Start-Sleep -Seconds 1 Start-Sleep -Seconds 1
Write-Host "Starting $($Wrapper)"
try { try {
Start-WebAppPool -Name $Wrapper Start-WebAppPool -Name $Wrapper
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
$state = (Get-WebAppPoolState -Name $Wrapper).Value $state = (Get-WebAppPoolState -Name $Wrapper).Value
Write-Host "Result: $state" Write-Host "Result: $state"
} catch { }
catch {
Write-Error $_.Exception.Message Write-Error $_.Exception.Message
exit 1 exit 1
} }

View File

@@ -1,8 +1,9 @@
param ( param (
[string]$App_Path = "C:\Users\matthes01\Documents\lst", # with this it makes it optional to pass a new parameter over. [string]$App_Path = "C:\Users\matthes01\Documents\lst", # with this it makes it optional to pass a new parameter over.
[string]$Server = "usmcd1vms036",
[string]$Token = "test3", [string]$Token = "test3",
[string]$Remote_Path = "E$\LST" [string]$Remote_Path = "E$\LST",
[string]$BuildController = "yes",
[string]$PlantToUpdate = "all"
) )
# imports of the other functions # imports of the other functions
@@ -11,7 +12,19 @@ param (
. ".\update-controller-server" . ".\update-controller-server"
# example string to pass over, you must be in the script dir when you run this script. or it will fail to find the linked scripts # example string to pass over, you must be in the script dir when you run this script. or it will fail to find the linked scripts
# .\update-controllers.ps1 -App_Path "C:\Users\matthes01\Documents\lst" -Server "usmcd1vms036" -Token "test3" -Remote_Path "E$\LST"
# If we do not pass plant to update over it will auto do all plants if we want a specific plant we need to do like below
# .\update-controllers.ps1 -App_Path "C:\Users\matthes01\Documents\lst" -Token "test3" -BuildController no -PlantToUpdate "usmcd1vms006" -Remote_Path "E$\LST"
$Plants = @(
@{ Server = "usmcd1vms036"; Token = "test3"; Remote_Path = "E$\LST"}
@{ Server = "usmar1vms006"; Token = "usmar1" ; Remote_Path = "E$\LST"}
@{ Server = "usbet1vms006"; Token = "usbet1"; Remote_Path = "E$\LST" }
@{ Server = "usbow1vms006"; Token = "usbow1" ; Remote_Path = "E$\LST"}
@{ Server = "usslc1vms006"; Token = "usslc1" ; Remote_Path = "E$\LST"}
@{ Server = "usstp1vms006"; Token = "usstp1" ; Remote_Path = "D$\LST"}
)
$EnvFile = Join-Path $App_Path ".env" $EnvFile = Join-Path $App_Path ".env"
if (-Not (Test-Path $EnvFile)) { if (-Not (Test-Path $EnvFile)) {
@@ -77,35 +90,64 @@ if (-Not (Test-Path $ControlIncludes)) {
# last one to make sure we have is the build folder # last one to make sure we have is the build folder
$BuildFolder = Join-Path $App_Path "controllerBuilds" $BuildFolder = Join-Path $App_Path "controllerBuilds"
if (-Not (Test-Path $BuildFolder)) { if (-Not (Test-Path $BuildFolder)) {
write-host "Build folder missing creating it" write-host "Build folder missing creating it"
New-Item -Path $BuildFolder -ItemType Directory | Out-Null New-Item -Path $BuildFolder -ItemType Directory | Out-Null
} }
# now we can create the zip # only rebuild if we push yes over
Zip-Includes -IncludesFile $ControlIncludes -BuildNumber $BuildNumber -BuildFolder $BuildFolder -AppRoot $App_Path if ($BuildController -eq "yes") {
Start-Sleep -Seconds 3 # now we can create the zip
#------------------------------------------------------------------------------------ Zip-Includes -IncludesFile $ControlIncludes -BuildNumber $BuildNumber -BuildFolder $BuildFolder -AppRoot $App_Path
Start-Sleep -Seconds 3
# Checking to make sure the server is up and online
Write-Output "Checking if $($Token) is online to update."
$pingResult = Test-Connection -ComputerName $Server -Count 2 -Quiet
if (-not $pingResult) {
Write-Output "Server $($Server), token $($Token) is NOT reachable. Exiting script."
exit 1 # Terminate the script with a non-zero exit code
} }
else {
Write-Output "Server $($Server), token $($Token) is online." $BuildNumber = ([int]$BuildNumber - 1).ToString()
}
#------------------------------------------------------------------------------------
# now that the server is up lets update the server with the current build # now that the server is up lets update the server with the current build
# do the update to the plant. # do the update to the plant.
Update-Server -ADM_USER $ADM_USER -ADM_PASS $ADM_PASS -AppRoot $App_Path -Destination $Remote_Path -Server $Server -Token $Token if ($PlantToUpdate -ne "all") {
# Checking to make sure the server is up and online
Write-Output "Checking if $($Token) is online to update."
$pingResult = Test-Connection -ComputerName $Server -Count 2 -Quiet
if (-not $pingResult) {
Write-Output "Server $($PlantToUpdate), token $($Token) is NOT reachable. Exiting script."
exit 1 # Terminate the script with a non-zero exit code
}
Write-Output "Server $($PlantToUpdate), token $($Token) is online."
Update-Server -ADM_USER $ADM_USER -ADM_PASS $ADM_PASS -AppRoot $App_Path -Destination $Remote_Path -Server $PlantToUpdate -Token $Token -ControllerBuild $BuildController
}
else {
foreach ($plant in $Plants) {
# Checking to make sure the server is up and online
Write-Output "Checking if $($plant.Token) is online to update."
$pingResult = Test-Connection -ComputerName $plant.Server -Count 2 -Quiet
if (-not $pingResult) {
Write-Output "Server $($plant.Server), token $($plant.Token) is NOT reachable. Exiting script."
exit 1 # Terminate the script with a non-zero exit code
}
Write-Output "Server $($plant.Server), token $($plant.Token) is online."
Write-Output "Plant to update: $($plant.Token)"
Update-Server -ADM_USER $ADM_USER -ADM_PASS $ADM_PASS -AppRoot $App_Path -Destination $plant.Remote_Path -Server $plant.Server -Token $plant.Token
}
}
# bump the build number # bump the build number
$BuildNumber = Bump-Build -AppRoot $App_Path if ($BuildController -eq "yes") {
$BuildNumber = Bump-Build -AppRoot $App_Path
}
# function to create the zip controller-1.zip # function to create the zip controller-1.zip