-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge a2c467c into backport/bosouza/VAULT-31409-unseal-trace/precisel…
…y-helped-skunk
- Loading branch information
Showing
10 changed files
with
272 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:improvement | ||
core: Added new `enable_post_unseal_trace` and `post_unseal_trace_directory` config options to generate Go traces during the post-unseal step for debug purposes. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package trace | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"runtime/trace" | ||
"time" | ||
) | ||
|
||
func StartDebugTrace(dir string, filePrefix string) (file string, stop func() error, err error) { | ||
dirMustExist := true | ||
if dir == "" { | ||
dirMustExist = false // if a dir is provided it must exist, otherwise we'll create a default one | ||
dir = filepath.Join(os.TempDir(), "vault-traces") | ||
} | ||
|
||
d, err := os.Stat(dir) | ||
if err != nil && !os.IsNotExist(err) { | ||
return "", nil, fmt.Errorf("failed to stat trace directory %q: %s", dir, err) | ||
} | ||
|
||
if os.IsNotExist(err) && dirMustExist { | ||
return "", nil, fmt.Errorf("trace directory %q does not exist", dir) | ||
} | ||
|
||
if !os.IsNotExist(err) && !d.IsDir() { | ||
return "", nil, fmt.Errorf("trace directory %q is not a directory", dir) | ||
} | ||
|
||
if os.IsNotExist(err) { | ||
if err := os.Mkdir(dir, 0o700); err != nil { | ||
return "", nil, fmt.Errorf("failed to create trace directory %q: %s", dir, err) | ||
} | ||
} | ||
|
||
// would prefer a more human readable time reference in the file name but the column | ||
// character can cause problems in filenames | ||
fileName := fmt.Sprintf("%s-%d.trace", filePrefix, time.Now().Unix()) | ||
traceFile, err := filepath.Abs(filepath.Join(dir, fileName)) | ||
if err != nil { | ||
return "", nil, fmt.Errorf("failed to get absolute path for trace file: %s", err) | ||
} | ||
f, err := os.Create(traceFile) | ||
if err != nil { | ||
return "", nil, fmt.Errorf("failed to create trace file %q: %s", traceFile, err) | ||
} | ||
|
||
if err := trace.Start(f); err != nil { | ||
f.Close() | ||
return "", nil, fmt.Errorf("failed to start trace: %s", err) | ||
} | ||
|
||
stop = func() error { | ||
trace.Stop() | ||
return f.Close() | ||
} | ||
|
||
return f.Name(), stop, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package trace | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
"runtime" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// TestStartDebugTrace tests the debug trace functionality creating real | ||
// files and traces. | ||
func TestStartDebugTrace(t *testing.T) { | ||
t.Run("error_on_non_existent_dir", func(t *testing.T) { | ||
_, _, err := StartDebugTrace("non-existent-dir", "filePrefix") | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "does not exist") | ||
}) | ||
|
||
t.Run("error_on_non_dir", func(t *testing.T) { | ||
f, err := os.CreateTemp("", "") | ||
require.NoError(t, err) | ||
require.NoError(t, f.Close()) | ||
_, _, err = StartDebugTrace(f.Name(), "") | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "is not a directory") | ||
}) | ||
|
||
t.Run("error_on_failed_to_create_trace_file", func(t *testing.T) { | ||
noWriteFolder := filepath.Join(os.TempDir(), "no-write-permissions") | ||
// create folder without write permission | ||
err := os.Mkdir(noWriteFolder, 0o000) | ||
t.Cleanup(func() { | ||
os.RemoveAll(noWriteFolder) | ||
}) | ||
require.NoError(t, err) | ||
_, _, err = StartDebugTrace(noWriteFolder, "") | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "failed to create trace file") | ||
}) | ||
|
||
t.Run("error_trying_to_start_second_concurrent_trace", func(t *testing.T) { | ||
dir, err := os.MkdirTemp("", "") | ||
require.NoError(t, err) | ||
t.Cleanup(func() { | ||
os.RemoveAll(dir) | ||
}) | ||
_, stop, err := StartDebugTrace(dir, "filePrefix") | ||
require.NoError(t, err) | ||
_, stopNil, err := StartDebugTrace(dir, "filePrefix") | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "failed to start trace") | ||
require.NoError(t, stop()) | ||
require.Nil(t, stopNil) | ||
}) | ||
|
||
t.Run("error_when_stating_tmp_dir_with_restricted_permissions", func(t *testing.T) { | ||
// this test relies on setting TMPDIR so skip it if we're not on a Unix system | ||
if runtime.GOOS == "windows" { | ||
t.Skip("skipping test on Windows") | ||
} | ||
|
||
tmpMissingPermissions := filepath.Join(t.TempDir(), "missing_permissions") | ||
err := os.Mkdir(tmpMissingPermissions, 0o000) | ||
require.NoError(t, err) | ||
t.Setenv("TMPDIR", tmpMissingPermissions) | ||
_, _, err = StartDebugTrace("", "filePrefix") | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), "failed to stat trace directory") | ||
}) | ||
|
||
t.Run("successful_trace_generates_non_empty_file", func(t *testing.T) { | ||
dir, err := os.MkdirTemp("", "") | ||
require.NoError(t, err) | ||
t.Cleanup(func() { | ||
os.RemoveAll(dir) | ||
}) | ||
file, stop, err := StartDebugTrace(dir, "filePrefix") | ||
require.NoError(t, err) | ||
require.NoError(t, stop()) | ||
f, err := os.Stat(file) | ||
require.NoError(t, err) | ||
require.Greater(t, f.Size(), int64(0)) | ||
}) | ||
|
||
t.Run("successful_creation_of_tmp_dir", func(t *testing.T) { | ||
os.RemoveAll(filepath.Join(os.TempDir(), "vault-traces")) | ||
file, stop, err := StartDebugTrace("", "filePrefix") | ||
require.NoError(t, err) | ||
require.NoError(t, stop()) | ||
require.Contains(t, file, filepath.Join(os.TempDir(), "vault-traces", "filePrefix")) | ||
f, err := os.Stat(file) | ||
require.NoError(t, err) | ||
require.Greater(t, f.Size(), int64(0)) | ||
}) | ||
|
||
t.Run("successful_trace_with_existing_tmp_dir", func(t *testing.T) { | ||
os.Mkdir(filepath.Join(os.TempDir(), "vault-traces"), 0o700) | ||
file, stop, err := StartDebugTrace("", "filePrefix") | ||
require.NoError(t, err) | ||
require.NoError(t, stop()) | ||
require.Contains(t, file, filepath.Join(os.TempDir(), "vault-traces", "filePrefix")) | ||
f, err := os.Stat(file) | ||
require.NoError(t, err) | ||
require.Greater(t, f.Size(), int64(0)) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters