
In addition to logging `GOOS` and `GOARCH`, also log more info about the system: - Windows: the Windows version and edition. - Linux: distribution, distribution version, and kernel version. - macOS: just "macOS", until we know more about getting info there too.
81 lines
1.9 KiB
Go
81 lines
1.9 KiB
Go
package sysinfo
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
"golang.org/x/sys/windows/registry"
|
|
)
|
|
|
|
// editionCanSymlink maps the EditionID key in the registry to a boolean indicating whether
|
|
// symlinks are available.
|
|
var editionCanSymlink = map[string]bool{
|
|
"Core": false, // Windows Home misses the tool to allow symlinking to a user.
|
|
"Professional": true, // Still requires explicit right to be assigned to the user.
|
|
}
|
|
|
|
// canSymlink tries to determine whether the running system can use symbolic
|
|
// links, based on information from the Windows registry.
|
|
func canSymlink() (bool, error) {
|
|
editionID, err := windowsEditionID()
|
|
if err != nil {
|
|
return false, fmt.Errorf("determining edition of Windows: %w", err)
|
|
}
|
|
|
|
canSymlink, found := editionCanSymlink[editionID]
|
|
if !found {
|
|
log.Warn().Str("editionID", editionID).Msg("unknown Windows edition, assuming it can use symlinks")
|
|
return true, nil
|
|
}
|
|
|
|
return canSymlink, nil
|
|
}
|
|
|
|
func description() (string, error) {
|
|
productName, err := registryReadString(
|
|
`SOFTWARE\Microsoft\Windows NT\CurrentVersion`,
|
|
"ProductName",
|
|
)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
editionID, err := windowsEditionID()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
description := fmt.Sprintf("%s (%s)", productName, editionID)
|
|
return description, nil
|
|
}
|
|
|
|
func windowsEditionID() (string, error) {
|
|
// Values seen so far:
|
|
// - "Professional"
|
|
// - "Core"
|
|
return registryReadString(
|
|
`SOFTWARE\Microsoft\Windows NT\CurrentVersion`,
|
|
"EditionID",
|
|
)
|
|
}
|
|
|
|
func registryReadString(keyPath, valueName string) (string, error) {
|
|
regkey, err := registry.OpenKey(
|
|
registry.LOCAL_MACHINE,
|
|
keyPath,
|
|
registry.QUERY_VALUE)
|
|
if err != nil {
|
|
return "", fmt.Errorf("opening registry key %q: %w", keyPath, err)
|
|
}
|
|
defer regkey.Close()
|
|
|
|
value, _, err := regkey.GetStringValue(valueName)
|
|
if err != nil {
|
|
return "", fmt.Errorf("reading registry key %q: %w", valueName, err)
|
|
}
|
|
|
|
return value, nil
|
|
}
|