$UPDATE_SOURCE = "C:\SEMS-development" #如果为http开头则是网络更新,否则则是本地路径更新 # $UPDATE_SOURCE = "https://1.u1227383.nyat.app:23587/api/v1/repos/zhanpeng" $TOCKEN = "e9aaae4b5f7756d0a2977764dbcbdfeb68bb2e13" $PRODUCTION_FOLDER = "C:\SEMS-production" $RAWDATA_FOLDER = "C:\tmp" if (Test-Path -Path $PRODUCTION_FOLDER -PathType Container) { Write-Output "[初始化]生产环境文件夹存在:$PRODUCTION_FOLDER" } else { New-Item -Path $PRODUCTION_FOLDER -ItemType Directory -ErrorAction SilentlyContinue | Out-Null Write-Output "[初始化]生产环境文件夹不存在,已新建:$PRODUCTION_FOLDER" } Write-Output "[初始化]程序更新源路径为:$UPDATE_SOURCE" function UpdateProgram { param ( $name #程序名称 ) #在生产部署文件夹中找以$name命名的文件夹,其中包含了版本信息 $nowVersion = Get-ChildItem -Path $PRODUCTION_FOLDER -Directory | Where-Object { $_.Name -like "*$name*" } #当前部署的版本,是一个文件夹对象,可能为空 #判断是否为网络更新,网络更新在生产环境中用,本地更新便于开发时测试 if ($UPDATE_SOURCE.Contains("http")) { #尝试获取最新版本信息,若获取不到则停止更新 try { $response = Invoke-RestMethod -Uri "$UPDATE_SOURCE/$name/releases/latest?token=$TOCKEN" #判断最新版本号是否大于当前部署版本号 if ($response.name -gt $nowVersion.name) { #新建缓存文件夹 New-Item -Path "$PRODUCTION_FOLDER/caches" -ItemType Directory -ErrorAction SilentlyContinue | Out-Null foreach ($asset in $response.assets) { if ($asset.name.Contains("zip")) { Write-Output "[更新]正在下载安装包$($asset.name.Replace(".zip",'')): $($asset.browser_download_url)" #要把安装包保存的路径 $latestFile = "$PRODUCTION_FOLDER\caches\$($asset.name)" Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $latestFile #把路径字符串转换为文件对象,便于后续处理 $latestFile = Get-Item -Path $latestFile Write-Output "[更新]下载完成,保存在$latestFile" } else { Write-Output "[更新]正在下载配置文件$($asset.name): $($asset.browser_download_url)" #要把配置文件保存的路径 $latestConfigFile = "$PRODUCTION_FOLDER\$($asset.name)" Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $latestConfigFile Write-Output "[更新]下载完成,保存在$latestConfigFile" #把路径字符串转换为文件对象,便于后续处理 $latestConfigFile = Get-Item -Path $latestConfigFile } } # Write-Output "[更新]正在下载$($response.assets.name.Replace(".zip",'')): $($response.assets.browser_download_url)" # #要把安装包保存的路径 # $latestFile = "$PRODUCTION_FOLDER\$($response.assets.name)" # Invoke-WebRequest -Uri $response.assets.browser_download_url -OutFile $latestFile # Write-Output "[更新]下载完成,保存在$latestFile" } else { Write-Output "[更新] $name 不需要更新,部署版本为$($nowVersion.name), 最新版本为$($response.name)" Return } } catch { Write-Output "[更新]最新版本请求失败,跳过处理。错误信息:$_" Return } } else { $latestFile = Get-ChildItem -Path $UPDATE_SOURCE -File -Depth 3 | Where-Object { $_.Name -like "*$name*.zip" } | Sort-Object -Property Name | Select-Object -Last 1 #判断最新版本号是否大于当前部署版本号 if ($latestFile.BaseName -gt $nowVersion.Name) { Write-Output "[更新]正在复制$($latestFile.FullName)到 $PRODUCTION_FOLDER\$($latestFile.Name)" Copy-Item -Path $latestFile.FullName -Destination $PRODUCTION_FOLDER\$($latestFile.Name) -Force $latestFile = Get-Item -Path $PRODUCTION_FOLDER\$($latestFile.Name) } else { Write-Output "[更新] $name 不需要更新,部署版本为$($nowVersion.name), 最新版本为$($latestFile.BaseName)" Return } } #停止运行程序 if ($name -eq "SEMS-data-collection") { $process = Get-Process -Name "SEMS-data-collection" -ErrorAction SilentlyContinue if ($process) { # 检查进程是否存在,若存在则杀掉 Stop-Process -Id $process.Id -Force Write-Output "[更新] $name 进程存在,已执行终止命令" } else { Write-Output "[更新] $name 进程不存在" } } if ($name.ToLower() -eq "sems-on-device-server" -or $name.ToLower() -eq "sems-model-inference" ) { $container = docker inspect -f "{{.State.Running}}" $name.ToLower() if ($container -eq "true") { Write-Output "[更新] 容器 $($name.ToLower()) 正在运行, 正在执行终止命令" docker stop $name.ToLower() } else { Write-Output "[更新] 容器 $($name.ToLower()) 不在运行" } } Write-Output "[更新]${name}程序有更新:$($latestFile.BaseName.Replace("$name-", ''))" #删除当前部署的旧版本 if (-not [string]::IsNullOrEmpty($nowVersion.FullName)) { Remove-Item -Path $nowVersion.FullName -Recurse -Force Write-Output "[更新]已删除旧版本${name}程序:$($nowVersion.Name.Replace("$name-", '')) " } #解压安装包到生产部署文件夹 if ($name -eq "SEMS-data-collection") { $destinationPath = $PRODUCTION_FOLDER } else { $destinationPath = "$PRODUCTION_FOLDER\$($latestFile.BaseName)" } Expand-Archive -Path $latestFile.FullName -DestinationPath $destinationPath -Force #删除安装包 Remove-Item -Path $latestFile.FullName -Force Write-Output "[更新]已更新${name}程序到:$PRODUCTION_FOLDER\$($latestFile.BaseName), 并删除安装包 $($latestFile.FullName)" #判断配置是否有更新,若有更新 if (![string]::IsNullOrEmpty($latestConfigFile)) { Write-Output "[更新]正在更新${name}的配置文件:$($latestConfigFile.BaseName)" #???????此功能需要进一步撰写,如何实现对比两个yaml文件,分别为新文件与旧文件,若新文件中有旧文件中没有,则添加;若新旧文件中都有,则不做任何改动,若新文件中没有,旧文件中有则删除。若旧文件为空或不存在则直接用新文件覆盖。请将上述功能封装为一个函数,输入为新旧两个文件的路径 } } ####################### # 更新生产环境程序 # ###################### UpdateProgram -name "SEMS-data-collection" UpdateProgram -name "SEMS-model-inference" UpdateProgram -name "SEMS-on-device-server" ################################################# # 检查程序是否在运行,若不在运行则重启 # ################################################## Write-Output "[状态]准备开始检查程序运行状态" # 检查 Docker Desktop 服务状态 $process = Get-Process -Name "Docker Desktop" -ErrorAction SilentlyContinue if ($process) { Write-Output "[状态]Docker Desktop 正在运行" } else { Write-Output "[状态]Docker Desktop运行正常不在运行,正在启动,请等待10s" Start-Process -FilePath "C:\Program Files\Docker\Docker\Docker Desktop.exe" Start-Sleep -Seconds 10 # 等待 Docker Desktop 启动 $process = Get-Process -Name "Docker Desktop" -ErrorAction SilentlyContinue if ($process) { Write-Output "[状态]Docker Desktop已成功运行" } else { Write-Output "[状态]Docker Desktop启动失败" } } $folders = Get-ChildItem -Path $PRODUCTION_FOLDER -Directory $folderDataCollection = $folders | Where-Object { $_.Name -like "*SEMS-data-collection*" } Write-Output $folderDataCollection.Name $folderModelInference = $folders | Where-Object { $_.Name -like "*SEMS-model-inference*" } Write-Output $folderModelInference.Name $folderOnDeviceServer = $folders | Where-Object { $_.Name -like "*SEMS-on-device-server*" } Write-Output $folderOnDeviceServer.Name $process = Get-Process -Name "SEMS-data-collection" -ErrorAction SilentlyContinue $restart_flag = "false" if ($process) { # 检查进程是否正在运行 if ($process.Responding) { Write-Output "[状态]进程 'SEMS-data-collection' 正在运行" } else { $restart_flag = "true" Write-Output "[状态]进程 'SEMS-data-collection' 存在但未响应" } } else { $restart_flag = "true" Write-Output "[状态]进程 'SEMS-data-collection' 不存在" } if ($restart_flag -eq "true") { $exeFile = Get-ChildItem -Path "$folderDataCollection" -Recurse -File -Depth 2 -Filter "SEMS-data-collection.exe" Write-Output "[状态]启动进程 $($exeFile.FullName)" Start-Process -FilePath $exeFile.FullName } $container = docker inspect -f "{{.State.Running}}" sems-on-device-server if ($container -eq "true") { Write-Output "[状态]容器 'sems-model-inference' 正在运行" } else { Write-Output "[状态]容器 'sems-model-inference' 不在运行,正在启动" docker run --rm -d -p "22111:22111" -v "$($folderModelInference.FullName):/app" --name sems-model-inference sems-model-inference:latest } if ($container -eq "true") { Write-Output "[状态]容器 'sems-on-device-server' 正在运行" } else { Write-Output "[状态]容器 'sems-on-device-server' 不在运行,正在运行" docker run --rm -d -p "22110:22110" -v "$($folderOnDeviceServer.FullName):/app" -v "${RAWDATA_FOLDER}:/data" --env-file "C:\SEMS-production\configs\.env" --name sems-on-device-server --link sems-model-inference sems-on-device-server:latest }