From 2cc01d3a0019f1cc350f76189273d352bb3db94f Mon Sep 17 00:00:00 2001 From: hugoShaka Date: Thu, 17 Jul 2025 16:49:54 -0400 Subject: [PATCH] Fix oneoff.sh bug on MacOS --- lib/web/scripts/oneoff/oneoff.sh | 2 +- lib/web/scripts/oneoff/oneoff_test.go | 106 ++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/lib/web/scripts/oneoff/oneoff.sh b/lib/web/scripts/oneoff/oneoff.sh index eaa15841be18b..1b86eec3fe903 100644 --- a/lib/web/scripts/oneoff/oneoff.sh +++ b/lib/web/scripts/oneoff/oneoff.sh @@ -21,7 +21,7 @@ trap 'rm -rf -- "$tempDir"' EXIT teleportTarballName() { if [ "${OS}" = "Darwin" ]; then - if [ "$fips" = "true"]; then + if [ "$fips" = "true" ]; then echo "FIPS version of Teleport is not compatible with MacOS. Please run this script in a Linux machine." return 1 fi diff --git a/lib/web/scripts/oneoff/oneoff_test.go b/lib/web/scripts/oneoff/oneoff_test.go index 47e7352072d44..d829c3015459f 100644 --- a/lib/web/scripts/oneoff/oneoff_test.go +++ b/lib/web/scripts/oneoff/oneoff_test.go @@ -131,6 +131,112 @@ func TestOneOffScript(t *testing.T) { require.NoDirExists(t, testWorkingDir) }) + t.Run("command can be executed on MacOS", func(t *testing.T) { + // set up + testWorkingDir := t.TempDir() + require.NoError(t, os.Mkdir(testWorkingDir+"/bin/", 0o755)) + scriptLocation := testWorkingDir + "/" + scriptName + + teleportMock, err := bintest.NewMock(testWorkingDir + "/bin/teleport") + require.NoError(t, err) + t.Cleanup(func() { + assert.NoError(t, teleportMock.Close()) + }) + + teleportBinTarball, err := utils.CompressTarGzArchive([]string{"teleport/teleport"}, singleFileFS{file: teleportMock.Path}) + require.NoError(t, err) + + testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + assert.Equal(t, "/teleport-v13.1.0-darwin-universal-bin.tar.gz", req.URL.Path) + http.ServeContent(w, req, "teleport-v13.1.0-darwin-universal-bin.tar.gz", time.Now(), bytes.NewReader(teleportBinTarball.Bytes())) + })) + t.Cleanup(func() { testServer.Close() }) + + script, err := BuildScript(OneOffScriptParams{ + BinUname: unameMock.Path, + BinMktemp: mktempMock.Path, + CDNBaseURL: testServer.URL, + TeleportVersion: "v13.1.0", + EntrypointArgs: "version", + SuccessMessage: "Test was a success.", + }) + require.NoError(t, err) + + unameMock.Expect("-s").AndWriteToStdout("Darwin") + unameMock.Expect("-m").AndWriteToStdout("x86_64") + mktempMock.Expect("-d", "-p", homeDir).AndWriteToStdout(testWorkingDir) + teleportMock.Expect("version").AndWriteToStdout(teleportVersionOutput) + + err = os.WriteFile(scriptLocation, []byte(script), 0700) + require.NoError(t, err) + + // execute script + out, err := exec.Command("sh", scriptLocation).CombinedOutput() + + // validate + require.NoError(t, err, string(out)) + + require.True(t, unameMock.Check(t)) + require.True(t, mktempMock.Check(t)) + require.True(t, teleportMock.Check(t)) + + require.Contains(t, string(out), "teleport version") + require.Contains(t, string(out), teleportVersionOutput) + require.Contains(t, string(out), "Test was a success.") + + // Script should remove the temporary directory. + require.NoDirExists(t, testWorkingDir) + }) + + t.Run("MacOS + fips fails", func(t *testing.T) { + // set up + testWorkingDir := t.TempDir() + require.NoError(t, os.Mkdir(testWorkingDir+"/bin/", 0o755)) + scriptLocation := testWorkingDir + "/" + scriptName + + teleportMock, err := bintest.NewMock(testWorkingDir + "/bin/teleport") + require.NoError(t, err) + t.Cleanup(func() { + assert.NoError(t, teleportMock.Close()) + }) + + testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + assert.Fail(t, "should not be called", req.URL.String()) + })) + t.Cleanup(func() { testServer.Close() }) + + script, err := BuildScript(OneOffScriptParams{ + BinUname: unameMock.Path, + BinMktemp: mktempMock.Path, + CDNBaseURL: testServer.URL, + TeleportVersion: "v13.1.0", + EntrypointArgs: "version", + SuccessMessage: "Test was a success.", + TeleportFIPS: true, + }) + require.NoError(t, err) + + unameMock.Expect("-s").AndWriteToStdout("Darwin") + unameMock.Expect("-m").AndWriteToStdout("x86_64") + mktempMock.Expect("-d", "-p", homeDir).AndWriteToStdout(testWorkingDir) + // no call expected to teleportMock + + err = os.WriteFile(scriptLocation, []byte(script), 0700) + require.NoError(t, err) + + // execute script + out, err := exec.Command("sh", scriptLocation).CombinedOutput() + + // validate + require.Error(t, err, string(out)) + + require.True(t, unameMock.Check(t)) + require.True(t, mktempMock.Check(t)) + + // Script should remove the temporary directory. + require.NoDirExists(t, testWorkingDir) + }) + t.Run("command with prefix can be executed", func(t *testing.T) { // set up testWorkingDir := t.TempDir()