better handling of path differences for MSI installers (#7035)

Related to #7036, Tested in:

- [x] macOS via `fleetctl package --type=msi` (non-native)
- [x] Linux native via `docker run -v "$(pwd)" fleetdm/fleetctl package --type=msi` (native)
- [x] Windows via `fleetctl pacakge --type=msi` (thanks to @edwardsb) (non-native)
This commit is contained in:
Roberto Dip
2022-08-05 17:12:05 -03:00
committed by GitHub
parent e40c5b02c1
commit 6fead4c08d
3 changed files with 23 additions and 48 deletions
+1
View File
@@ -0,0 +1 @@
* Fixed a bug preventing `.msi` installers to be generated on Windows machines.
+22 -25
View File
@@ -7,26 +7,12 @@ import (
"fmt"
"os"
"os/exec"
"strings"
)
const (
directoryReference = "ORBITROOT"
linuxPathSeparator = "/"
windowsPathSeparator = "\\"
directoryReference = "ORBITROOT"
)
// windowsJoin returns the result of replacing each slash ('/') character in
// each path with a Windows separator character ('\') and joining them using
// the Windows separator character.
//
// We can't use filepath.FromSlash because this func is run in a *nix
// machine.
func windowsJoin(paths ...string) string {
s := strings.Join(paths, windowsPathSeparator)
return strings.ReplaceAll(s, linuxPathSeparator, windowsPathSeparator)
}
// Heat runs the WiX Heat command on the provided directory.
//
// The Heat command creates XML fragments allowing WiX to include the entire
@@ -39,14 +25,14 @@ func Heat(path string, native bool) error {
args = append(
args,
"docker", "run", "--rm", "--platform", "linux/amd64",
"--volume", path+":"+path, // mount volume
"--volume", path+":/wix", // mount volume
"fleetdm/wix:latest", // image name
)
}
args = append(args,
"heat", "dir", windowsJoin(path, "root"), // command
"-out", windowsJoin(path, "heat.wxs"),
"heat", "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
@@ -57,6 +43,10 @@ func Heat(path string, native bool) error {
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
if native {
cmd.Dir = path
}
if err := cmd.Run(); err != nil {
return fmt.Errorf("heat failed: %w", err)
}
@@ -75,14 +65,13 @@ func Candle(path string, native bool) error {
args = append(
args,
"docker", "run", "--rm", "--platform", "linux/amd64",
"--volume", path+":"+path, // mount volume
"--volume", path+":/wix", // mount volume
"fleetdm/wix:latest", // image name
)
}
args = append(args,
"candle", windowsJoin(path, "heat.wxs"), windowsJoin(path, "main.wxs"), // command
"-out", windowsJoin(path, ""),
"candle", "heat.wxs", "main.wxs", // command
"-ext", "WixUtilExtension",
"-arch", "x64",
)
@@ -90,6 +79,10 @@ func Candle(path string, native bool) error {
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
if native {
cmd.Dir = path
}
if err := cmd.Run(); err != nil {
return fmt.Errorf("candle failed: %w", err)
}
@@ -108,22 +101,26 @@ func Light(path string, native bool) error {
args = append(
args,
"docker", "run", "--rm", "--platform", "linux/amd64",
"--volume", path+":"+path, // mount volume
"--volume", path+":/wix", // mount volume
"fleetdm/wix:latest", // image name
)
}
args = append(args,
"light", windowsJoin(path, "heat.wixobj"), windowsJoin(path, "main.wixobj"), // command
"light", "heat.wixobj", "main.wixobj", // command
"-ext", "WixUtilExtension",
"-b", windowsJoin(path, "root"), // Set directory for finding heat files
"-out", windowsJoin(path, "orbit.msi"),
"-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 native {
cmd.Dir = path
}
if err := cmd.Run(); err != nil {
return fmt.Errorf("light failed: %w", err)
}
-23
View File
@@ -1,23 +0,0 @@
package wix
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestWindowsJoin(t *testing.T) {
cases := []struct {
in []string
out string
}{
{[]string{"one\\two", "three"}, "one\\two\\three"},
{[]string{"one/two/three", "four.txt"}, "one\\two\\three\\four.txt"},
{[]string{"one", "two", "three"}, "one\\two\\three"},
{[]string{"one/two/three", "four/five.txt"}, "one\\two\\three\\four\\five.txt"},
}
for _, c := range cases {
require.Equal(t, c.out, windowsJoin(c.in...))
}
}