支持多平台linux-amd64 linux-arm64 win
This commit is contained in:
@@ -258,7 +258,6 @@ def updateGetMaxCodeByDeptId(
|
|||||||
def getUploadUrl(
|
def getUploadUrl(
|
||||||
deviceID: str | None = None,
|
deviceID: str | None = None,
|
||||||
):
|
):
|
||||||
# 生成唯一文件名,避免覆盖
|
|
||||||
return BaseResponse(data=get_update_package(deviceID))
|
return BaseResponse(data=get_update_package(deviceID))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Generated
+1
@@ -1,6 +1,7 @@
|
|||||||
<component name="ProjectDictionaryState">
|
<component name="ProjectDictionaryState">
|
||||||
<dictionary name="project">
|
<dictionary name="project">
|
||||||
<words>
|
<words>
|
||||||
|
<w>linux</w>
|
||||||
<w>从海康sdk获取图片以及信息</w>
|
<w>从海康sdk获取图片以及信息</w>
|
||||||
</words>
|
</words>
|
||||||
</dictionary>
|
</dictionary>
|
||||||
|
|||||||
Generated
+7
-1
@@ -1,6 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module type="WEB_MODULE" version="4">
|
<module type="WEB_MODULE" version="4">
|
||||||
<component name="Go" enabled="true" />
|
<component name="Go" enabled="true">
|
||||||
|
<buildTags>
|
||||||
|
<option name="os" value="linux" />
|
||||||
|
<option name="arch" value="arm64" />
|
||||||
|
<option name="cgo" value="NO" />
|
||||||
|
</buildTags>
|
||||||
|
</component>
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$" />
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 94 KiB |
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 134 KiB |
Binary file not shown.
@@ -0,0 +1,44 @@
|
|||||||
|
# build_all.ps1
|
||||||
|
# 一键打包 main 和 updater,三平台: Windows 64, Linux amd64, Linux arm64
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# 项目根目录
|
||||||
|
$RootDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
Set-Location $RootDir
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# 定义要打包的平台
|
||||||
|
$targets = @(
|
||||||
|
@{ OS="windows"; ARCH="amd64"; Dir="build/win"; MainOut="main.exe"; UpdaterOut="updater.exe" },
|
||||||
|
@{ OS="linux"; ARCH="amd64"; Dir="build/linux_amd64"; MainOut="main"; UpdaterOut="updater" },
|
||||||
|
@{ OS="linux"; ARCH="arm64"; Dir="build/linux_arm64"; MainOut="main"; UpdaterOut="updater" }
|
||||||
|
)
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# 循环打包
|
||||||
|
foreach ($t in $targets) {
|
||||||
|
Write-Host "=== Build $($t.OS)-$($t.ARCH) Version ==="
|
||||||
|
|
||||||
|
# 设置环境变量
|
||||||
|
$env:GOOS = $t.OS
|
||||||
|
$env:GOARCH = $t.ARCH
|
||||||
|
$env:CGO_ENABLED = "0"
|
||||||
|
|
||||||
|
# 创建输出目录
|
||||||
|
if (!(Test-Path $t.Dir)) {
|
||||||
|
New-Item -ItemType Directory -Path $t.Dir | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 编译 main
|
||||||
|
Write-Host "Building main..."
|
||||||
|
go build -ldflags="-s -w" -o "$($t.Dir)/$($t.MainOut)" ./main
|
||||||
|
|
||||||
|
# 编译 updater
|
||||||
|
Write-Host "Building updater..."
|
||||||
|
go build -ldflags="-s -w" -o "$($t.Dir)/$($t.UpdaterOut)" ./updater
|
||||||
|
|
||||||
|
Write-Host "$($t.OS)-$($t.ARCH) Build complete, Output dir: $($t.Dir)"
|
||||||
|
Write-Host ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "All builds finished."
|
||||||
Binary file not shown.
Binary file not shown.
@@ -4,13 +4,11 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
|
||||||
"sentinel/pkg/config"
|
"sentinel/pkg/config"
|
||||||
"sentinel/pkg/log"
|
"sentinel/pkg/log"
|
||||||
model2 "sentinel/pkg/model"
|
model2 "sentinel/pkg/model"
|
||||||
"sentinel/pkg/utils"
|
"sentinel/pkg/utils"
|
||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -154,38 +152,58 @@ func (b *BusinessService) handleRestart() {
|
|||||||
_ = cmd.Start()
|
_ = cmd.Start()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleCheckUpdate 触发更新流程(主程序侧)
|
|
||||||
func (b *BusinessService) handleCheckUpdate() {
|
func (b *BusinessService) handleCheckUpdate() {
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
"--version", strconv.Itoa(config.APP_VERSION),
|
"--version", strconv.Itoa(config.APP_VERSION),
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command("./updater.exe", args...)
|
launcher := newUpdaterLauncher()
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
|
|
||||||
// OS 级脱离父进程
|
if err := launcher.Start(args); err != nil {
|
||||||
switch runtime.GOOS {
|
|
||||||
case "windows":
|
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
||||||
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
log.Println("[BUS] failed to start updater:", err)
|
log.Println("[BUS] failed to start updater:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println(
|
log.Println(
|
||||||
"[BUS] updater started (pid=%d), exiting main program\n",
|
"[BUS] updater started, exiting main program",
|
||||||
cmd.Process.Pid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 给 updater 留出启动窗口(尤其是 systemd / docker 环境)
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleCheckUpdate 触发更新流程(主程序侧)
|
||||||
|
//func (b *BusinessService) handleCheckUpdate() {
|
||||||
|
//
|
||||||
|
// args := []string{
|
||||||
|
// "--version", strconv.Itoa(config.APP_VERSION),
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// cmd := exec.Command("./updater.exe", args...)
|
||||||
|
// cmd.Stdout = os.Stdout
|
||||||
|
// cmd.Stderr = os.Stderr
|
||||||
|
//
|
||||||
|
// // OS 级脱离父进程
|
||||||
|
// switch runtime.GOOS {
|
||||||
|
// case "windows":
|
||||||
|
// cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
// CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if err := cmd.Start(); err != nil {
|
||||||
|
// log.Println("[BUS] failed to start updater:", err)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// log.Println(
|
||||||
|
// "[BUS] updater started (pid=%d), exiting main program\n",
|
||||||
|
// cmd.Process.Pid,
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// // 给 updater 留出启动窗口(尤其是 systemd / docker 环境)
|
||||||
|
// time.Sleep(500 * time.Millisecond)
|
||||||
|
//
|
||||||
|
// os.Exit(0)
|
||||||
|
//}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ func main() {
|
|||||||
|
|
||||||
fmt.Println(banner)
|
fmt.Println(banner)
|
||||||
deviceID := device.GetDeviceID()
|
deviceID := device.GetDeviceID()
|
||||||
log.Init(config.Log_file_dic) // 初始化日志目录
|
log.Init(config.Log_file_dic) // 初始化日志目录
|
||||||
log.Info("Device id: " + deviceID) // 第一次启动记录
|
log.Info("Device id: " + deviceID) // 第一次启动记录
|
||||||
log.Println("版本号: ", config.APP_VERSION) // 第一次启动记录
|
log.Println("版本号: ", config.APP_VERSION) // 第一次启动记录
|
||||||
|
|
||||||
var mqttSvc *MQTTService
|
var mqttSvc *MQTTService
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "sentinel/pkg/platform"
|
||||||
|
|
||||||
|
func newUpdaterLauncher() platform.UpdaterLauncher {
|
||||||
|
return &updaterLauncher{}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
type updaterLauncher struct{}
|
||||||
|
|
||||||
|
func (u *updaterLauncher) Start(args []string) error {
|
||||||
|
cmd := exec.Command("./updater", args...)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
// Linux 下先不做进程组处理,保证能跑
|
||||||
|
return cmd.Start()
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
type updaterLauncher struct{}
|
||||||
|
|
||||||
|
func (u *updaterLauncher) Start(args []string) error {
|
||||||
|
cmd := exec.Command("./updater.exe", args...)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd.Start()
|
||||||
|
}
|
||||||
@@ -12,7 +12,8 @@ import (
|
|||||||
"sentinel/pkg/log"
|
"sentinel/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const baseURL = "http://127.0.0.1:13011"
|
// const baseURL = "http://127.0.0.1:13011"
|
||||||
|
const baseURL = "https://ai.ronsunny.cn:8090"
|
||||||
|
|
||||||
var client = &http.Client{
|
var client = &http.Client{
|
||||||
Timeout: 5 * time.Second,
|
Timeout: 5 * time.Second,
|
||||||
@@ -59,6 +60,7 @@ func do(method, path string, query map[string]string, body any, out any) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("apikey", "NzusyzcLIUoZ22tflHN2sOjHrry3W7zJ")
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package platform
|
||||||
|
|
||||||
|
type UpdaterLauncher interface {
|
||||||
|
Start(args []string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type MainProgramStarter interface {
|
||||||
|
Start(targetExe string) error
|
||||||
|
|
||||||
|
GetMainName() string
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 94 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 134 KiB |
@@ -7,14 +7,11 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"sentinel/pkg/device"
|
"sentinel/pkg/device"
|
||||||
"sentinel/pkg/log"
|
"sentinel/pkg/log"
|
||||||
"sentinel/pkg/net"
|
"sentinel/pkg/net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -60,20 +57,14 @@ func RunUpdate(deviceID string, version int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
selfDir := filepath.Dir(selfPath)
|
selfDir := filepath.Dir(selfPath)
|
||||||
targetExe := filepath.Join(selfDir, "main.exe") // Windows 固定名,可根据实际改
|
|
||||||
|
starter := newMainProgramStarter()
|
||||||
|
targetExe := filepath.Join(selfDir, starter.GetMainName())
|
||||||
|
|
||||||
// 2. 对比版本号,没有新版本则直接启动原程序
|
// 2. 对比版本号,没有新版本则直接启动原程序
|
||||||
if info.Version <= version {
|
if info.Version <= version {
|
||||||
fmt.Println("[updater] 暂未发现新版本,启动原程序")
|
fmt.Println("[updater] 暂未发现新版本,启动原程序")
|
||||||
cmd := exec.Command(targetExe)
|
if err := starter.Start(targetExe); err != nil {
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
||||||
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
@@ -131,19 +122,11 @@ func RunUpdate(deviceID string, version int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 6. 启动主程序,同时完全退出自己
|
// 6. 启动主程序,同时完全退出自己
|
||||||
cmd := exec.Command(targetExe)
|
if err := starter.Start(targetExe); err != nil {
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
||||||
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fmt.Printf("[updater] 更新完成,新程序已启动,退出更新程序")
|
||||||
fmt.Printf("[updater] 更新完成,新程序已启动 (pid=%d),退出更新程序\n", cmd.Process.Pid)
|
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "sentinel/pkg/platform"
|
||||||
|
|
||||||
|
func newMainProgramStarter() platform.MainProgramStarter {
|
||||||
|
return &mainProgramStarter{}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mainProgramStarter struct{}
|
||||||
|
|
||||||
|
func (s *mainProgramStarter) GetMainName() string {
|
||||||
|
return "main"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *mainProgramStarter) Start(targetExe string) error {
|
||||||
|
if err := os.Chmod(targetExe, 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd := exec.Command(targetExe)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
// Linux 下:先保持最简单,保证能跑
|
||||||
|
return cmd.Start()
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mainProgramStarter struct{}
|
||||||
|
|
||||||
|
func (s *mainProgramStarter) GetMainName() string {
|
||||||
|
return "main.exe"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *mainProgramStarter) Start(targetExe string) error {
|
||||||
|
cmd := exec.Command(targetExe)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
// Windows:新进程组,脱离 Ctrl+C / 父进程
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd.Start()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user