mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 00:49:03 +00:00
#27275 and #27274 - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Committing-Changes.md#changes-files) for more information. - [x] Added/updated automated tests - [x] Manual QA for all new/changed functionality - For Orbit and Fleet Desktop changes: - [x] Make sure fleetd is compatible with the latest released version of Fleet (see [Must rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/fleetd-development-and-release-strategy.md)). - [x] Orbit runs on macOS, Linux and Windows. Check if the orbit feature/bugfix should only apply to one platform (`runtime.GOOS`). - [x] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)). --------- Co-authored-by: Lucas Rodriguez <lucas@fleetdm.com>
208 lines
5.3 KiB
Go
208 lines
5.3 KiB
Go
// Package wix runs the WiX packaging tools via Docker.
|
|
//
|
|
// WiX's documentation is available at https://wixtoolset.org/.
|
|
package wix
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
directoryReference = "ORBITROOT"
|
|
imageName = "fleetdm/wix:latest"
|
|
dockerPlatform = "linux/amd64"
|
|
Wine64Cmd = "wine64"
|
|
WineCmd = "wine"
|
|
)
|
|
|
|
// Heat runs the WiX Heat command on the provided directory.
|
|
//
|
|
// The Heat command creates XML fragments allowing WiX to include the entire
|
|
// directory. See
|
|
// https://wixtoolset.org/documentation/manual/v3/overview/heat.html.
|
|
func Heat(path string, native bool, localWixDir string) error {
|
|
var args []string
|
|
|
|
if !native && localWixDir == "" {
|
|
args = append(
|
|
args,
|
|
"docker", "run", "--rm", "--platform", dockerPlatform,
|
|
"--volume", path+":/wix", // mount volume
|
|
imageName, // image name
|
|
)
|
|
}
|
|
|
|
heatPath := `heat`
|
|
if localWixDir != "" {
|
|
heatPath = filepath.Join(localWixDir, `heat.exe`)
|
|
if runtime.GOOS == "darwin" {
|
|
wineExec, err := darwinWineExecutable()
|
|
if err != nil {
|
|
return fmt.Errorf("determining wine executable: %w", err)
|
|
}
|
|
args = append(args, wineExec)
|
|
}
|
|
}
|
|
|
|
args = append(args,
|
|
heatPath, "dir", "root", // command
|
|
"-out", "heat.wxs",
|
|
"-gg", "-g1", // generate UUIDs (required by wix)
|
|
"-cg", "OrbitFiles", // set ComponentGroup name
|
|
"-scom", "-sfrag", "-srd", "-sreg", // suppress unneccesary generated items
|
|
"-dr", directoryReference, // set reference name
|
|
"-ke", // keep empty directories
|
|
)
|
|
|
|
cmd := exec.Command(args[0], args[1:]...)
|
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
|
|
|
if args[0] == WineCmd || args[0] == Wine64Cmd {
|
|
cmd.Env = append(os.Environ(), "WINEDEBUG=-all")
|
|
}
|
|
|
|
if native || localWixDir != "" {
|
|
cmd.Dir = path
|
|
}
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("heat failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func darwinWineExecutable() (string, error) {
|
|
cmdOut, err := exec.Command("wine", "--version").Output()
|
|
if err != nil {
|
|
return "", fmt.Errorf("running wine to get version information: %w", err)
|
|
}
|
|
wineVerStr, found := strings.CutPrefix(string(cmdOut), "wine-")
|
|
if !found {
|
|
return "", fmt.Errorf("Unknown wine version: %q. Is Wine installed? Creating a fleetd agent for Windows (.msi) requires Wine. To install Wine see the script here: https://fleetdm.com/install-wine ", string(cmdOut))
|
|
}
|
|
wineVersion, err := strconv.ParseInt(strings.Split(wineVerStr, ".")[0], 10, 64)
|
|
if err != nil {
|
|
return "", fmt.Errorf("Unable to parse wine version: %q. Is Wine installed? Creating a fleetd agent for Windows (.msi) requires Wine. To install Wine see the script here: https://fleetdm.com/install-wine ", wineVerStr)
|
|
}
|
|
if wineVersion < 10 {
|
|
return Wine64Cmd, nil
|
|
}
|
|
return WineCmd, nil
|
|
}
|
|
|
|
// Candle runs the WiX Candle command on the provided directory.
|
|
//
|
|
// See
|
|
// https://wixtoolset.org/documentation/manual/v3/overview/candle.html.
|
|
func Candle(path string, native bool, localWixDir string, arch string) error {
|
|
var args []string
|
|
|
|
if !native && localWixDir == "" {
|
|
args = append(
|
|
args,
|
|
"docker", "run", "--rm", "--platform", dockerPlatform,
|
|
"--volume", path+":/wix", // mount volume
|
|
imageName, // image name
|
|
)
|
|
}
|
|
|
|
candlePath := `candle`
|
|
if localWixDir != "" {
|
|
candlePath = filepath.Join(localWixDir, `candle.exe`)
|
|
if runtime.GOOS == "darwin" {
|
|
wineExec, err := darwinWineExecutable()
|
|
if err != nil {
|
|
return fmt.Errorf("determining wine executable: %w", err)
|
|
}
|
|
args = append(args, wineExec)
|
|
}
|
|
}
|
|
|
|
wixArch := "x64"
|
|
if arch == "arm64" {
|
|
wixArch = "arm64"
|
|
}
|
|
|
|
args = append(args,
|
|
candlePath, "heat.wxs", "main.wxs", // command
|
|
"-ext", "WixUtilExtension",
|
|
"-arch", wixArch,
|
|
)
|
|
|
|
cmd := exec.Command(args[0], args[1:]...)
|
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
|
|
|
if args[0] == WineCmd || args[0] == Wine64Cmd {
|
|
cmd.Env = append(os.Environ(), "WINEDEBUG=-all")
|
|
}
|
|
|
|
if native || localWixDir != "" {
|
|
cmd.Dir = path
|
|
}
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("candle failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Light runs the WiX Light command on the provided directory.
|
|
//
|
|
// See
|
|
// https://wixtoolset.org/documentation/manual/v3/overview/light.html.
|
|
func Light(path string, native bool, localWixDir string) error {
|
|
var args []string
|
|
|
|
if !native && localWixDir == "" {
|
|
args = append(
|
|
args,
|
|
"docker", "run", "--rm", "--platform", dockerPlatform,
|
|
"--volume", path+":/wix", // mount volume
|
|
imageName, // image name
|
|
)
|
|
}
|
|
|
|
lightPath := `light`
|
|
if localWixDir != "" {
|
|
lightPath = filepath.Join(localWixDir, `light.exe`)
|
|
if runtime.GOOS == "darwin" {
|
|
wineExec, err := darwinWineExecutable()
|
|
if err != nil {
|
|
return fmt.Errorf("determining wine executable: %w", err)
|
|
}
|
|
args = append(args, wineExec)
|
|
}
|
|
}
|
|
args = append(args,
|
|
lightPath, "heat.wixobj", "main.wixobj", // command
|
|
"-ext", "WixUtilExtension",
|
|
"-b", "root", // Set directory for finding heat files
|
|
"-out", "orbit.msi",
|
|
"-sval", // skip validation (otherwise Wine crashes)
|
|
)
|
|
|
|
cmd := exec.Command(args[0], args[1:]...)
|
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
|
|
|
if args[0] == WineCmd || args[0] == Wine64Cmd {
|
|
cmd.Env = append(os.Environ(), "WINEDEBUG=-all")
|
|
}
|
|
|
|
if native || localWixDir != "" {
|
|
cmd.Dir = path
|
|
}
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("light failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|