<# Скрипт устанавливает ЛЭРС УЧЁТ сервер и службу опроса на операционные системы Linux, которые используют systemd для управления сервисами. Позволяет установить сервер и/или службу опроса. Для управления используются флаги -server и -pollservice Кроме того, скрипт может обновить существующую установку, используя флаг -update. Флаги -server и -pollservice при этом игнорируются. Службы настраиваются для запуска из-под учётной записи lers. Если такой учётной записи нет, она будет создана. #> param ([string]$version, [switch]$server, [switch]$pollservice, [switch]$force, [switch] $update, [switch] $uninstall) Set-StrictMode -Version 1 $ErrorActionPreference = "Stop" ################################### # Вспомогательные функции ################################### # Запрашивает адрес сервера ЛЭРС function Get-ServerAddress { do { $serverAddress = Read-Host -Prompt "Введите адрес сервера ЛЭРС, к которому подключится служба опроса." # Проверяем, что это действительно сервер ЛЭРС try { $response = Invoke-RestMethod -Method GET -Uri "$serverAddress/api/v1/serverInfo" if ($response.type -ne "LersServer") { throw "Неверный тип сервера" } return $serverAddress } catch { Write-Error "$serverAddress не является сервером ЛЭРС. $_" } } while ($true) } # Возвращает версию и описание ОС function Get-OsRelease { return Get-Content /etc/os-release | ConvertFrom-StringData } # Рекурсивно удаляет папку если она существует. function Remove-DirectoryIfNotExists([string] $path) { if (Test-Path $path) { Remove-Item -Path $path -Recurse -Force } } ################################### # Функции установки зависимостей. ################################### # Устанавливает рантайм aspnet function Install-DotnetRuntime { $os = Get-OsRelease if ($os.ID -eq "`"redos`"") { dnf install aspnetcore-runtime-$dotnetRuntimeVersion -y } elseif (($os.ID -eq "ubuntu") -and ($os.VERSION_ID.StartsWith("`"24."))) { apt-get update apt install aspnetcore-runtime-$dotnetRuntimeVersion -y } elseif (($os.ID -eq "astra") -and ($os.VERSION_ID.StartsWith("1.7"))) { # Перед установкой регистрируем репозиторий microsoft. wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb # Устанавливаем рантайм apt-get update apt install aspnetcore-runtime-$dotnetRuntimeVersion -y # Убираем регистрацию репозитория и удаляем скачанный пакет. apt remove packages-microsoft-prod -y Remove-Item -Path packages-microsoft-prod.deb -Force } else { $os | Format-Table Write-Error "Неподдерживаемая операционная система $($os.ID)" exit 2; } if(!$?) { Write-Error "Не удалось установить среду выполнения dotnet" exit 1; } } # Устанавливает зависимости сервера function Install-ServerDependencies { $os = Get-OsRelease Write-Host "Устанавливаются зависимости модуля отчётов сервера ЛЭРС" if ($os.ID -eq "`"redos`"") { dnf install libgdiplus -y } elseif ($os.ID -eq "ubuntu") { apt-get update apt-get install -y libc6 libgdiplus libicu-dev libharfbuzz0b libfontconfig1 libfreetype6 libpango-1.0-0 libpangocairo-1.0 } elseif (($os.ID -eq "astra") -and ($os.VERSION_ID.StartsWith("1.7"))) { # Регистрируем расширенный репозиторий astra $astraLinux_1_7_ExtendedRepos | Set-Content -Path "/etc/apt/sources.list.d/astra-ext.list" # Ставим зависимости apt-get update apt-get install -y libc6 libgdiplus libicu-dev libharfbuzz0b libfontconfig1 libfreetype6 libpango-1.0-0 libpangocairo-1.0 # Удаляем расширенный репозиторий Remove-Item -Path "/etc/apt/sources.list.d/astra-ext.list" -Force } else { $os | Format-Table Write-Error "Неподдерживаемая операционная система" exit 2; } if(!$?) { Write-Error "Не удалось установить требуемые для сервера компоненты" exit 1; } } ################################### # Константы ################################### $dotnetRuntimeVersion="8.0" $lersUser = "lers" $lersDir = "/usr/LERS" $dataDir = "/var/LERS" $configDir = "/etc/LERS" $serverExecutable = "$lersDir/Server/Lers.Server.dll" $pollServiceExecutable = "$lersDir/PollService/Lers.PollService.dll" $serverServiceName = "lers.server.service" $serverServiceFile = "/etc/systemd/system/$serverServiceName" $pollserviceServiceName = "lers.pollservice.service" $pollserviceServiceFile = "/etc/systemd/system/$pollserviceServiceName" ################################### # Ресурсы ################################### $serverSystemd = @" [Unit] Description=ЛЭРС УЧЁТ - Сервер After=network.target StartLimitIntervalSec=0 [Service] Type=simple Restart=always RestartSec=1 User=$lersUser ExecStart=/usr/bin/dotnet $serverExecutable [Install] WantedBy=multi-user.target "@ $pollserviceSystemd = @" [Unit] Description=ЛЭРС УЧЁТ - Служба опроса After=network.target StartLimitIntervalSec=0 [Service] Type=simple Restart=always RestartSec=1 User=$lersUser ExecStart=/usr/bin/dotnet $pollServiceExecutable [Install] WantedBy=multi-user.target "@ $astraLinux_1_7_ExtendedRepos = @" # Основной репозиторий deb https://dl.astralinux.ru/astra/stable/1.7_x86-64/repository-main/ 1.7_x86-64 main contrib non-free # Оперативные обновления основного репозитория deb https://dl.astralinux.ru/astra/stable/1.7_x86-64/repository-update/ 1.7_x86-64 main contrib non-free # Базовый репозиторий deb https://dl.astralinux.ru/astra/stable/1.7_x86-64/repository-base/ 1.7_x86-64 main contrib non-free # Расширенный репозиторий deb https://dl.astralinux.ru/astra/stable/1.7_x86-64/repository-extended/ 1.7_x86-64 main contrib non-free # Расширенный репозиторий (компонент astra-ce) deb https://dl.astralinux.ru/astra/stable/1.7_x86-64/repository-extended/ 1.7_x86-64 astra-ce "@ ################################### # Установочный скрипт ################################### # Убедимся, что запущены от ROOT. if ($PSVersionTable.Platform -eq "Unix") { if ( $(whoami) -ne "root") { Write-Host "Запустите скрипт от имени root через sudo" exit 1 } } # Убедимся, что используется systemd $serviceManager = (ps --no-headers -o comm 1) if ($serviceManager -ne "systemd") { Write-Error "Неподдерживаемая система управления службами $serviceManager" exit 3; } # Убедимся, что передана верная комбинация флагов if ($uninstall -and $update) { Write-Error "Флаги -update и -uninstall нельзя использовать вместе."; exit 1; } # Определяем откуда будем загружать пакеты. if ($version) { $serverUrl = "https://update.lers.ru/v/$version/files/Server.zip" $pollServiceUrl = "https://update.lers.ru/v/$version/files/PollService.zip" } else { $serverUrl = "https://update.lers.ru/download/files/Server.zip" $pollServiceUrl = "https://update.lers.ru/download/files/PollService.zip" } # Останавливаем запущенные службы, если они есть if (Test-Path -Path $serverServiceFile) { systemctl stop $serverServiceName } if (Test-Path -Path $pollserviceServiceFile) { systemctl stop $pollserviceServiceName } ################################## # Удаление системы. ################################## if ($uninstall) { Write-Host "Удаление ЛЭРС УЧЁТ" if (Test-Path -Path $serverServiceFile) { Write-Host "Удаление службы $serverServiceName" systemctl disable $serverServiceName Remove-Item -Path $serverServiceFile -Force } if (Test-Path -Path $pollserviceServiceFile) { Write-Host "Удаление службы $pollserviceServiceName" systemctl disable $pollserviceServiceName Remove-Item -Path $pollserviceServiceFile -Force } Write-Host "Удаление исполняемых файлов и данных" Remove-DirectoryIfNotExists -path $lersDir Remove-DirectoryIfNotExists -path $dataDir Write-Host "Удаление ЛЭРС УЧЁТ завершено." Write-Host "Папка с конфигурацией $configDir не удалена. Вы можете удалить её вручную, если не планируете переустанавливать ЛЭРС УЧЁТ." exit 0; } ################################## # Установка и обновление системы. ################################## if ($update) { # В режиме обновления игнорируем ключи -server и -pollservice # Вместо этого по наличию файлов определяем установлены ли сервер и служба опроса $server = Test-Path -Path $serverExecutable $pollservice = Test-Path -Path $pollServiceExecutable } elseif (-not $server -and -not $pollservice) { $server = $true $pollservice = $true } Install-DotnetRuntime if ($server) { Install-ServerDependencies } # Создаём пользователя getent passwd $lersUser if($?) { Write-Host "Пользователь $lersUser уже существует." } else { Write-Host "Создаётся пользователь $lersUser" useradd $lersUser } # Создаём папки для настроек и данных if ($force -and -not $update) { Remove-Item -Path $configDir -Recurse -Force } New-Item -ItemType Directory -Path $dataDir -Force New-Item -ItemType Directory -Path $configDir -Force # Загружаем и распаковываем архивы с программой if ($server) { wget $serverUrl -O Server.zip if ($update) { Write-Host "Обновляется база данных..." # В режиме обновления распакуем сервер во временную папку # и попытаемся обновить БД. Если не вышло обновиться, завершаем работу. $lersTempPath = [System.IO.Path]::GetTempPath() $lersTempPath = Join-Path -Path $lersTempPath -ChildPath "lers" if (Test-Path -LiteralPath $lersTempPath) { Remove-Item -Path $lersTempPath -Recurse -Force } Expand-Archive -LiteralPath 'Server.zip' -DestinationPath $lersTempPath -Force Remove-Item -Path 'Server.zip' -Force # Обновляем существующую БД dotnet "$lersTempPath/Server/Lers.Server.dll" cli db-update if ($?) { # Перемещаем распакованные файлы в финальную папку. # Предварительно очищаем сервер, чтобы убрать все ставшие ненужными сборки. Remove-Item -Path "$lersDir/Server" -Recurse -Force Remove-Item -Path "$lersDir/Database" -Recurse -Force Remove-Item -Path "$lersDir/Server.Bootstrapper" -Recurse -Force Remove-Item -Path "$lersDir/Updater" -Recurse -Force Get-ChildItem -Path $lersTempPath | Move-Item -Destination $lersDir -Force } else { Write-Error "Не удалось обновить базу данных. Обновление прекращено." exit 3; } } else { Expand-Archive -LiteralPath 'Server.zip' -DestinationPath $lersDir -Force Remove-Item -Path 'Server.zip' -Force } } if ($pollservice) { wget $pollServiceUrl -O PollService.zip Expand-Archive -LiteralPath 'PollService.zip' -DestinationPath $lersDir -Force Remove-Item -Path 'PollService.zip' -Force } # Настраиваем подключение службы опроса if (-not $update) { if ($pollservice) { if ($server) { # Сервер установлен, обращаемся к адресу по умолчанию. $serverAddress = "http://localhost:10000"; } else { # Сервер не установлен, запрашиваем. $serverAddress = Get-ServerAddress; } $templateConfig = "$lersDir/PollService/Lers.PollService.ini.template" $config = "$configDir/Lers.PollService.ini" (Get-Content $templateConfig).Replace("`$SERVER_ADDRESS`$:`$SERVER_PORT`$", $serverAddress) | Set-Content $config -Force Write-Host "Служба опроса настроена на подключение к серверу $serverAddress" } if ($server) { # Запускаем конфигурацию сервера dotnet $lersDir/Server.Bootstrapper/Lers.Setup.Bootstrapper.Cli.dll } } # Загружаем обновления для раздачи if ($server) { dotnet $lersDir/Updater/Lers.UpdateService.dll update-dist dotnet $lersDir/Updater/Lers.UpdateService.dll update-plugins } # Устанавливаем пользователю разрешения на папки с данными. chown -R $lersUser $dataDir chown -R $lersUser $configDir if (-not $update) { # Создаём службы systemd if ($server) { $serverSystemd | Set-Content $serverServiceFile -Force } if ($pollservice) { $pollserviceSystemd | Set-Content $pollserviceServiceFile -Force } } # Запускаем службы systemctl daemon-reload if (Test-Path -Path $serverServiceFile) { systemctl start $serverServiceName } if (Test-Path -Path $pollserviceServiceFile) { systemctl start $pollserviceServiceName }