diff --git a/install_alloy.ps1 b/install_alloy.ps1 new file mode 100644 index 0000000..669ecbf --- /dev/null +++ b/install_alloy.ps1 @@ -0,0 +1,145 @@ +#requires -RunAsAdministrator +Set-StrictMode -Version Latest +$ErrorActionPreference = "Stop" + +# ========================= +# Parámetros Globales +# ========================= +$RepoUrl = "https://git.insidemicro.com/panotuco/dex.git" +$RepoLocalPath = "C:\ProgramData\Alloy\repo_config" +$DataPath = "C:\ProgramData\Alloy" +$ScriptsRoot = Join-Path $DataPath "scripts" +$BookmarksPath = Join-Path $DataPath "bookmarks" +$TmpDir = Join-Path $env:TEMP "grafana-alloy-install" + +$TaskNameSync = "Sync Alloy Config from Git" +$TaskNameBoot = "Send Windows Boot Event to Loki" + +$SyncScriptPath = Join-Path $ScriptsRoot "sync-alloy-git.ps1" +$BootScriptPath = Join-Path $ScriptsRoot "send-boot-event.ps1" + +$GitHubLatestApi = "https://api.github.com/repos/grafana/alloy/releases/latest" + +# ========================= +# Utilidades +# ========================= +function Write-Log { + param([string]$Message, [string]$Level = "INFO") + $line = "[{0}] [{1}] {2}" -f (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $Level, $Message + Write-Host $line +} + +function Ensure-Directory { + param([string]$Path) + if (-not (Test-Path -LiteralPath $Path)) { + New-Item -ItemType Directory -Path $Path -Force | Out-Null + } +} + +# ========================= +# Validaciones e Directorios +# ========================= +Ensure-Directory -Path $TmpDir +Ensure-Directory -Path $ScriptsRoot +Ensure-Directory -Path $DataPath +Ensure-Directory -Path $BookmarksPath + +# ========================= +# 1. Instalación de Grafana Alloy +# ========================= +$installerName = "alloy-installer-windows-amd64.exe" +$installerPath = Join-Path $TmpDir $installerName + +Write-Log "Consultando última release de Grafana Alloy..." +$release = Invoke-RestMethod -Uri $GitHubLatestApi -Headers @{ "Accept" = "application/vnd.github+json" } +$asset = $release.assets | Where-Object { $_.name -eq $installerName } | Select-Object -First 1 +$downloadUrl = $asset.browser_download_url + +Write-Log "Descargando e instalando Alloy..." +Invoke-WebRequest -Uri $downloadUrl -OutFile $installerPath +$installProcess = Start-Process -FilePath $installerPath -ArgumentList "/S" -Wait -PassThru + +# Detectar ruta de instalación (normalmente Program Files\GrafanaLabs\Alloy) +$InstallRoot = Join-Path $env:ProgramFiles "GrafanaLabs\Alloy" +if (-not (Test-Path $InstallRoot)) { $InstallRoot = Join-Path $env:ProgramFiles "Alloy" } +$AlloyConfigPath = Join-Path $InstallRoot "config.alloy" + +# ========================= +# 2. Instalación de Git y Clonación +# ========================= +if (!(Get-Command git -ErrorAction SilentlyContinue)) { + Write-Log "Instalando Git vía winget..." + winget install --id Git.Git -e --source winget --accept-package-agreements --accept-source-agreements + $env:Path += ";C:\Program Files\Git\cmd" +} + +if (!(Test-Path $RepoLocalPath)) { + Write-Log "Clonando repositorio de configuración..." + git clone $RepoUrl $RepoLocalPath +} + +# ========================= +# 3. Script de Sincronización (GitOps) +# ========================= +$SyncScriptContent = @" +Set-Location "$RepoLocalPath" +git fetch origin +`$local = git rev-parse HEAD +`$remote = git rev-parse origin/main + +if (`$local -ne `$remote) { + git reset --hard origin/main + Copy-Item -Path (Join-Path "$RepoLocalPath" "config.alloy") -Destination "$AlloyConfigPath" -Force + Restart-Service -Name "Alloy" -Force + Write-Output "Configuracion actualizada y servicio reiniciado" +} +"@ +Set-Content -Path $SyncScriptPath -Value $SyncScriptContent -Encoding UTF8 + +# ========================= +# 4. Script de Boot (Tu lógica de Loki) +# ========================= +$BootScriptContent = @' +Start-Sleep -Seconds 180 +$event = Get-WinEvent -LogName "Microsoft-Windows-Diagnostics-Performance/Operational" -MaxEvents 20 | Where-Object { $_.Id -eq 100 } | Select-Object -First 1 +if ($null -eq $event) { exit 0 } + +$timestamp = [string](([DateTimeOffset]$event.TimeCreated).ToUnixTimeMilliseconds() * 1000000) +[xml]$xml = $event.ToXml() +$data = @{} +foreach ($d in $xml.Event.EventData.Data) { $data[[string]$d.Name] = [string]$d.'#text' } + +$logObject = [ordered]@{ + machine_name = $env:COMPUTERNAME + boot_time_ms = $data["BootTime"] + message = $event.Message +} +$logLine = $logObject | ConvertTo-Json -Compress +$payload = "{ `"streams`": [ { `"stream`": { `"job`": `"windows_boot_custom`", `"computer`": `"$($env:COMPUTERNAME)`" }, `"values`": [ [ `"$timestamp`", `"$($logLine.Replace('"', '\"'))`" ] ] } ] }" + +Invoke-WebRequest -Uri "https://loki.insidemicro.com/loki/api/v1/push" -Method Post -ContentType "application/json" -Body ([System.Text.Encoding]::UTF8.GetBytes($payload)) +'@ +Set-Content -Path $BootScriptPath -Value $BootScriptContent -Encoding UTF8 + +# ========================= +# 5. Registro de Tareas Programadas +# ========================= +$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest +$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable + +# Tarea Sync (Cada 10 min) +$actionSync = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$SyncScriptPath`"" +$triggerSync = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 10) +Register-ScheduledTask -TaskName $TaskNameSync -Action $actionSync -Trigger $triggerSync -Principal $principal -Settings $settings -Force + +# Tarea Boot (Al iniciar) +$actionBoot = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$BootScriptPath`"" +$triggerBoot = New-ScheduledTaskTrigger -AtStartup +Register-ScheduledTask -TaskName $TaskNameBoot -Action $actionBoot -Trigger $triggerBoot -Principal $principal -Settings $settings -Force + +# ========================= +# 6. Arranque Inicial +# ========================= +Write-Log "Sincronizando configuración inicial..." +& $SyncScriptPath +Write-Log "Proceso completado." \ No newline at end of file