From 30280965b9985a062fcd572c72279006abaa5921 Mon Sep 17 00:00:00 2001 From: RebeccaMahany Date: Fri, 6 Sep 2024 10:15:33 -0400 Subject: [PATCH] Refactor launcherLocation slightly and add tests to validate location --- pkg/packaging/detectLauncherVersion.go | 15 +++--- pkg/packaging/detectLauncherVersion_test.go | 55 ++++++++++++++++----- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/pkg/packaging/detectLauncherVersion.go b/pkg/packaging/detectLauncherVersion.go index 6d8dfb54a..58befc80e 100644 --- a/pkg/packaging/detectLauncherVersion.go +++ b/pkg/packaging/detectLauncherVersion.go @@ -19,10 +19,7 @@ func (p *PackageOptions) detectLauncherVersion(ctx context.Context) error { logger := log.With(ctxlog.FromContext(ctx), "library", "detectLauncherVersion") level.Debug(logger).Log("msg", "Attempting launcher autodetection") - launcherPath := p.launcherLocation(filepath.Join(p.packageRoot, p.binDir)) - if p.target.Platform == Windows { - launcherPath = p.launcherLocation(filepath.Join(p.packageRoot, p.binDir, string(p.target.Arch))) - } + launcherPath := p.launcherLocation() stdout, err := p.execOut(ctx, launcherPath, "-version") if err != nil { @@ -52,16 +49,20 @@ func (p *PackageOptions) detectLauncherVersion(ctx context.Context) error { // launcherLocation returns the location of the launcher binary within `binDir`. For darwin, // it may be in an app bundle -- we check to see if the binary exists there first, and then // fall back to the common location if it doesn't. -func (p *PackageOptions) launcherLocation(binDir string) string { +func (p *PackageOptions) launcherLocation() string { if p.target.Platform == Darwin { // We want /usr/local/Kolide.app, not /usr/local/bin/Kolide.app, so we use Dir to strip out `bin` - appBundleBinaryPath := filepath.Join(filepath.Dir(binDir), "Kolide.app", "Contents", "MacOS", "launcher") + appBundleBinaryPath := filepath.Join(p.packageRoot, filepath.Dir(p.binDir), "Kolide.app", "Contents", "MacOS", "launcher") if info, err := os.Stat(appBundleBinaryPath); err == nil && !info.IsDir() { return appBundleBinaryPath } } - return filepath.Join(binDir, p.target.PlatformBinaryName("launcher")) + if p.target.Platform == Windows { + return filepath.Join(p.packageRoot, p.binDir, string(p.target.Arch), p.target.PlatformBinaryName("launcher")) + } + + return filepath.Join(p.packageRoot, p.binDir, p.target.PlatformBinaryName("launcher")) } // formatVersion formats the version according to the packaging requirements of the target platform diff --git a/pkg/packaging/detectLauncherVersion_test.go b/pkg/packaging/detectLauncherVersion_test.go index 5eebfd0a5..5ff51306d 100644 --- a/pkg/packaging/detectLauncherVersion_test.go +++ b/pkg/packaging/detectLauncherVersion_test.go @@ -85,19 +85,25 @@ func TestFormatVersion(t *testing.T) { } } -func TestLauncherLocation(t *testing.T) { +func TestLauncherLocation_Darwin(t *testing.T) { t.Parallel() - pDarwin := &PackageOptions{target: Target{Platform: Darwin}} + pDarwin := &PackageOptions{ + target: Target{ + Platform: Darwin, + }, + packageRoot: t.TempDir(), + binDir: "bin", + } // First, test that if the app bundle doesn't exist, we fall back to the top-level binary - require.Equal(t, filepath.Join("some", "dir", "launcher"), pDarwin.launcherLocation(filepath.Join("some", "dir"))) + expectedFallbackLauncherLocation := filepath.Join(pDarwin.packageRoot, pDarwin.binDir, "launcher") + require.Equal(t, expectedFallbackLauncherLocation, pDarwin.launcherLocation()) // Create a temp directory with an app bundle in it - tmpDir := t.TempDir() - binDir := filepath.Join(tmpDir, "bin") + binDir := filepath.Join(pDarwin.packageRoot, pDarwin.binDir) require.NoError(t, os.MkdirAll(binDir, 0755)) - baseDir := filepath.Join(tmpDir, "Kolide.app", "Contents", "MacOS") + baseDir := filepath.Join(pDarwin.packageRoot, "Kolide.app", "Contents", "MacOS") require.NoError(t, os.MkdirAll(baseDir, 0755)) expectedLauncherBinaryPath := filepath.Join(baseDir, "launcher") f, err := os.Create(expectedLauncherBinaryPath) @@ -106,13 +112,38 @@ func TestLauncherLocation(t *testing.T) { defer os.Remove(expectedLauncherBinaryPath) // Now, confirm that we find the binary inside the app bundle - require.Equal(t, expectedLauncherBinaryPath, pDarwin.launcherLocation(binDir)) + require.Equal(t, expectedLauncherBinaryPath, pDarwin.launcherLocation()) +} + +func TestLauncherLocation_Windows(t *testing.T) { + t.Parallel() + + pWindows := &PackageOptions{ + target: Target{ + Platform: Windows, + Arch: Amd64, + }, + packageRoot: t.TempDir(), + binDir: "bin", + } // No file check for windows, just expect the binary in the given location - pWindows := &PackageOptions{target: Target{Platform: Windows}} - require.Equal(t, filepath.Join("some", "dir", "launcher.exe"), pWindows.launcherLocation(filepath.Join("some", "dir"))) + expectedLauncherLocation := filepath.Join(pWindows.packageRoot, pWindows.binDir, string(pWindows.target.Arch), "launcher.exe") + require.Equal(t, expectedLauncherLocation, pWindows.launcherLocation()) +} + +func TestLauncherLocation_Linux(t *testing.T) { + t.Parallel() + + pLinux := &PackageOptions{ + target: Target{ + Platform: Linux, + }, + packageRoot: t.TempDir(), + binDir: "bin", + } - // Same as for windows: no file check, just expect the binary in the given location - pLinux := &PackageOptions{target: Target{Platform: Linux}} - require.Equal(t, filepath.Join("some", "dir", "launcher"), pLinux.launcherLocation(filepath.Join("some", "dir"))) + // No file check for Linux, just expect the binary in the given location + expectedLauncherLocation := filepath.Join(pLinux.packageRoot, pLinux.binDir, "launcher") + require.Equal(t, expectedLauncherLocation, pLinux.launcherLocation()) }