exit 0 without key on Windows to avoid Winget Validation-Executable-Error (#2376, #2247)

This commit is contained in:
henrygd
2026-09-21 11:27:37 -04:00
parent cbe4824ac3
commit a5f216f425
2 changed files with 44 additions and 1 deletions

View File

@@ -1,9 +1,11 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"os" "os"
"runtime"
"strings" "strings"
"github.com/henrygd/beszel" "github.com/henrygd/beszel"
@@ -14,6 +16,12 @@ import (
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
type noKeyProvidedError struct{}
func (noKeyProvidedError) Error() string {
return "no key provided: must set -key flag, KEY env var, or KEY_FILE env var. Use 'beszel-agent help' for usage"
}
// cli options // cli options
type cmdOptions struct { type cmdOptions struct {
key string // key is the public key(s) for SSH authentication. key string // key is the public key(s) for SSH authentication.
@@ -124,7 +132,7 @@ func (opts *cmdOptions) loadPublicKeys() ([]ssh.PublicKey, error) {
// Try key file // Try key file
keyFile, ok := utils.GetEnv("KEY_FILE") keyFile, ok := utils.GetEnv("KEY_FILE")
if !ok { if !ok {
return nil, fmt.Errorf("no key provided: must set -key flag, KEY env var, or KEY_FILE env var. Use 'beszel-agent help' for usage") return nil, noKeyProvidedError{}
} }
pubKey, err := os.ReadFile(keyFile) pubKey, err := os.ReadFile(keyFile)
@@ -138,6 +146,14 @@ func (opts *cmdOptions) getAddress() string {
return agent.GetAddress(opts.listen) return agent.GetAddress(opts.listen)
} }
func isBenignStartupError(err error, goos string) bool {
if goos != "windows" {
return false
}
var noKeyErr noKeyProvidedError
return errors.As(err, &noKeyErr)
}
// handleFingerprint handles the "fingerprint" command with subcommands "view" and "reset". // handleFingerprint handles the "fingerprint" command with subcommands "view" and "reset".
func handleFingerprint() { func handleFingerprint() {
subCmd := "" subCmd := ""
@@ -182,6 +198,12 @@ func main() {
var err error var err error
serverConfig.Keys, err = opts.loadPublicKeys() serverConfig.Keys, err = opts.loadPublicKeys()
if err != nil { if err != nil {
if isBenignStartupError(err, runtime.GOOS) {
// WinGet launches the executable without configuration during validation.
// Exit successfully in that case while retaining the error on other platforms.
log.Print("Failed to load public keys:", err)
return
}
log.Fatal("Failed to load public keys:", err) log.Fatal("Failed to load public keys:", err)
} }

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"crypto/ed25519" "crypto/ed25519"
"errors"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@@ -187,6 +188,26 @@ func TestLoadPublicKeys(t *testing.T) {
} }
} }
func TestIsBenignStartupError(t *testing.T) {
tests := []struct {
name string
err error
goos string
want bool
}{
{name: "missing key on windows", err: noKeyProvidedError{}, goos: "windows", want: true},
{name: "wrapped missing key on windows", err: errors.Join(errors.New("startup failed"), noKeyProvidedError{}), goos: "windows", want: true},
{name: "missing key on linux", err: noKeyProvidedError{}, goos: "linux", want: false},
{name: "different error on windows", err: errors.New("invalid key"), goos: "windows", want: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, isBenignStartupError(tt.err, tt.goos))
})
}
}
func TestGetNetwork(t *testing.T) { func TestGetNetwork(t *testing.T) {
tests := []struct { tests := []struct {
name string name string