99 lines
4.7 KiB
PowerShell
99 lines
4.7 KiB
PowerShell
<#
|
|||
|
|
.SYNOPSIS
|
||
|
|
Instala (o reinstala) el demonio descarga_factura_transporte como servicio de Windows con NSSM.
|
||
|
|
|
||
|
|
.DESCRIPTION
|
||
|
|
Ejecutar en PowerShell COMO ADMINISTRADOR, desde cualquier carpeta. Ver docs/despliegue_windows.md.
|
||
|
|
No arranca el servicio: primero revisa el .env y luego ejecuta nssm start <nombre>.
|
||
|
|
|
||
|
|
.PARAMETER Cuenta
|
||
|
|
Cuenta con la que corre el servicio, en formato DOMINIO\usuario. Debe tener acceso de lectura/escritura a la
|
||
|
|
ruta de red de RUTA_RED_FACTURACION: la cuenta LocalSystem (por defecto de los servicios) NO ve recursos de red.
|
||
|
|
|
||
|
|
.PARAMETER Clave
|
||
|
|
Contraseña de la cuenta (SecureString). Si se omite, se pide por consola.
|
||
|
|
|
||
|
|
.EXAMPLE
|
||
|
|
.\deploy\instalar_servicio.ps1 -Cuenta "ABERIO\svc_facturas"
|
||
|
|
#>
|
||
|
|
param(
|
||
|
|
[string]$Nombre = "descarga_factura_transporte",
|
||
|
|
[string]$Cuenta = "",
|
||
|
|
[securestring]$Clave,
|
||
|
|
[string]$Nssm = "nssm",
|
||
|
|
[string]$Python = ""
|
||
|
|
)
|
||
|
|
|
||
|
|
$ErrorActionPreference = "Stop"
|
||
|
|
|
||
|
|
# --- Rutas (la carpeta del proyecto es la que contiene deploy\) ---------------------------------------------
|
||
|
|
$Proyecto = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
||
|
|
if (-not $Python) { $Python = Join-Path $Proyecto "venv\Scripts\python.exe" }
|
||
|
|
|
||
|
|
# --- Comprobaciones previas ----------------------------------------------------------------------------------
|
||
|
|
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
|
||
|
|
[Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
||
|
|
throw "Ejecute este script como administrador."
|
||
|
|
}
|
||
|
|
if (-not (Get-Command $Nssm -ErrorAction SilentlyContinue)) {
|
||
|
|
throw "No se encontró nssm. Descárguelo de https://nssm.cc y agréguelo al PATH, o use -Nssm 'C:\ruta\nssm.exe'."
|
||
|
|
}
|
||
|
|
if (-not (Test-Path $Python)) {
|
||
|
|
throw "No existe $Python. Cree el entorno virtual: py -3 -m venv venv ; venv\Scripts\pip install -r requirements.txt"
|
||
|
|
}
|
||
|
|
if (-not (Test-Path (Join-Path $Proyecto ".env"))) {
|
||
|
|
throw "Falta $Proyecto\.env. Copie .env.example a .env y complételo (ver docs/configurar_msal.md)."
|
||
|
|
}
|
||
|
|
if (-not $Cuenta) {
|
||
|
|
Write-Warning "Sin -Cuenta el servicio corre como LocalSystem y NO podrá escribir en la ruta de red de facturación electrónica."
|
||
|
|
}
|
||
|
|
|
||
|
|
# --- Instalación ----------------------------------------------------------------------------------------------
|
||
|
|
if (Get-Service -Name $Nombre -ErrorAction SilentlyContinue) {
|
||
|
|
Write-Host "El servicio '$Nombre' ya existe: se detiene y se reconfigura."
|
||
|
|
& $Nssm stop $Nombre confirm | Out-Null
|
||
|
|
} else {
|
||
|
|
& $Nssm install $Nombre $Python "main.py" | Out-Null
|
||
|
|
}
|
||
|
|
|
||
|
|
$LogsNssm = Join-Path $Proyecto "logs"
|
||
|
|
New-Item -ItemType Directory -Force -Path $LogsNssm | Out-Null
|
||
|
|
|
||
|
|
& $Nssm set $Nombre Application $Python
|
||
|
|
& $Nssm set $Nombre AppParameters "main.py"
|
||
|
|
& $Nssm set $Nombre AppDirectory $Proyecto # el código no depende del cwd, pero el .env y los logs sí cuentan con él
|
||
|
|
& $Nssm set $Nombre DisplayName "Descarga de facturas de transporte"
|
||
|
|
& $Nssm set $Nombre Description "Lee el buzón, valida las facturas contra SAP B1, crea el draft y responde al proveedor."
|
||
|
|
& $Nssm set $Nombre Start SERVICE_AUTO_START
|
||
|
|
& $Nssm set $Nombre AppEnvironmentExtra "PYTHONUTF8=1" "PYTHONIOENCODING=utf-8" "PYTHONUNBUFFERED=1" # emojis del log en la consola de Windows
|
||
|
|
|
||
|
|
# Salida estándar y de error del proceso (el log de la aplicación sigue en logs\descarga_factura_transporte.log)
|
||
|
|
& $Nssm set $Nombre AppStdout (Join-Path $LogsNssm "servicio.out.log")
|
||
|
|
& $Nssm set $Nombre AppStderr (Join-Path $LogsNssm "servicio.err.log")
|
||
|
|
& $Nssm set $Nombre AppRotateFiles 1
|
||
|
|
& $Nssm set $Nombre AppRotateOnline 1
|
||
|
|
& $Nssm set $Nombre AppRotateBytes 10485760 # 10 MB
|
||
|
|
|
||
|
|
# Reinicio automático si el proceso muere; espera 30 s para no entrar en un bucle rápido
|
||
|
|
& $Nssm set $Nombre AppExit Default Restart
|
||
|
|
& $Nssm set $Nombre AppRestartDelay 30000
|
||
|
|
& $Nssm set $Nombre AppThrottle 10000
|
||
|
|
|
||
|
|
# Parada limpia: Ctrl+C (el demonio lo atiende con KeyboardInterrupt) y 20 s de gracia antes de forzar
|
||
|
|
& $Nssm set $Nombre AppStopMethodSkip 0
|
||
|
|
& $Nssm set $Nombre AppStopMethodConsole 20000
|
||
|
|
& $Nssm set $Nombre AppStopMethodWindow 0
|
||
|
|
& $Nssm set $Nombre AppStopMethodThreads 0
|
||
|
|
|
||
|
|
if ($Cuenta) {
|
||
|
|
if (-not $Clave) { $Clave = Read-Host "Contraseña de $Cuenta" -AsSecureString }
|
||
|
|
$Texto = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Clave))
|
||
|
|
& $Nssm set $Nombre ObjectName $Cuenta $Texto
|
||
|
|
Remove-Variable Texto
|
||
|
|
}
|
||
|
|
|
||
|
|
Write-Host ""
|
||
|
|
Write-Host "Servicio '$Nombre' instalado. Pasos siguientes:"
|
||
|
|
Write-Host " 1. Revise $Proyecto\.env (NOTIFICACION_MODO, NOTIFICACION_EQUIPO, LOGO_URL)."
|
||
|
|
Write-Host " 2. nssm start $Nombre"
|
||
|
|
Write-Host " 3. Get-Content '$LogsNssm\descarga_factura_transporte.log' -Wait -Tail 30"
|