mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-19 00:36:38 +00:00
102 lines
2.7 KiB
Go
102 lines
2.7 KiB
Go
//go:build windows
|
|
|
|
package updatemanager
|
|
|
|
import (
|
|
"context"
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
"syscall"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"golang.org/x/sys/windows/registry"
|
|
)
|
|
|
|
const (
|
|
msiDownloadURL = "https://github.com/netbirdio/netbird/releases/download/v%version/netbird_installer_%version_windows_%arch.msi"
|
|
exeDownloadURL = "https://github.com/netbirdio/netbird/releases/download/v%version/netbird_installer_%version_windows_%arch.exe"
|
|
uninstallKeyPath64 = `SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Netbird`
|
|
uninstallKeyPath32 = `SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Netbird`
|
|
|
|
installerEXE installerType = "EXE"
|
|
installerMSI installerType = "MSI"
|
|
)
|
|
|
|
type installerType string
|
|
|
|
func (u *UpdateManager) triggerUpdate(ctx context.Context, targetVersion string) error {
|
|
// Use test function if set (for testing purposes)
|
|
if u.updateFunc != nil {
|
|
return u.updateFunc(ctx, targetVersion)
|
|
}
|
|
|
|
method := installation()
|
|
return install(ctx, method, targetVersion)
|
|
}
|
|
|
|
func installation() installerType {
|
|
k, err := registry.OpenKey(registry.LOCAL_MACHINE, uninstallKeyPath64, registry.QUERY_VALUE)
|
|
if err != nil {
|
|
k, err = registry.OpenKey(registry.LOCAL_MACHINE, uninstallKeyPath32, registry.QUERY_VALUE)
|
|
if err != nil {
|
|
return installerMSI
|
|
} else {
|
|
err = k.Close()
|
|
if err != nil {
|
|
log.Warnf("Error closing registry key: %v", err)
|
|
}
|
|
}
|
|
} else {
|
|
err = k.Close()
|
|
if err != nil {
|
|
log.Warnf("Error closing registry key: %v", err)
|
|
}
|
|
}
|
|
return installerEXE
|
|
}
|
|
|
|
func install(ctx context.Context, installerType installerType, targetVersion string) error {
|
|
path, err := downloadFileToTemporaryDir(ctx, urlWithVersionArch(installerType, targetVersion))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Infof("start installation %s", path)
|
|
|
|
var cmd *exec.Cmd
|
|
if installerType == installerEXE {
|
|
cmd = exec.CommandContext(ctx, path, "/S")
|
|
} else {
|
|
cmd = exec.CommandContext(ctx, "msiexec", "/quiet", "/i", path)
|
|
}
|
|
|
|
// Detach the process from the parent
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP | 0x00000008, // 0x00000008 is DETACHED_PROCESS
|
|
}
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
log.Errorf("error starting installer: %v", err)
|
|
return err
|
|
}
|
|
|
|
if err := cmd.Process.Release(); err != nil {
|
|
log.Errorf("error releasing installer process: %v", err)
|
|
return err
|
|
}
|
|
|
|
log.Infof("installer started successfully: %s", path)
|
|
return nil
|
|
}
|
|
|
|
func urlWithVersionArch(it installerType, version string) string {
|
|
var url string
|
|
if it == installerEXE {
|
|
url = exeDownloadURL
|
|
} else {
|
|
url = msiDownloadURL
|
|
}
|
|
url = strings.ReplaceAll(url, "%version", version)
|
|
return strings.ReplaceAll(url, "%arch", runtime.GOARCH)
|
|
}
|