From d176f7dd4f8757bf9c11b622f6406bf01b9715ad Mon Sep 17 00:00:00 2001 From: Joel Scheuner Date: Tue, 24 Oct 2023 18:51:19 +0200 Subject: [PATCH] Set file permissions of code directory when layer present (#27) --- cmd/localstack/file_utils.go | 17 +++++++++++++++++ cmd/localstack/main.go | 17 +++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/cmd/localstack/file_utils.go b/cmd/localstack/file_utils.go index 69e93de..ed65c70 100644 --- a/cmd/localstack/file_utils.go +++ b/cmd/localstack/file_utils.go @@ -1,6 +1,7 @@ package main import ( + "io" "os" "path/filepath" ) @@ -20,3 +21,19 @@ func ChmodRecursively(root string, mode os.FileMode) error { return nil }) } + +// Check if a directory is empty +// Source: https://stackoverflow.com/questions/30697324/how-to-check-if-directory-on-path-is-empty/30708914#30708914 +func IsDirEmpty(name string) (bool, error) { + f, err := os.Open(name) + if err != nil { + return false, err + } + defer f.Close() + + _, err = f.Readdirnames(1) // faster than f.Readdir(1) + if err == io.EOF { + return true, nil + } + return false, err // Either not empty or error, suits both cases +} diff --git a/cmd/localstack/main.go b/cmd/localstack/main.go index 67a2bd4..08b70d9 100644 --- a/cmd/localstack/main.go +++ b/cmd/localstack/main.go @@ -132,13 +132,22 @@ func main() { log.Fatal("Failed to download code archives: " + err.Error()) } - // fix permissions of the layers directory for better AWS parity + // set file permissions of the tmp directory for better AWS parity + if err := ChmodRecursively("/tmp", 0700); err != nil { + log.Warnln("Could not change file mode recursively of directory /tmp:", err) + } + // set file permissions of the layers directory for better AWS parity if err := ChmodRecursively("/opt", 0755); err != nil { log.Warnln("Could not change file mode recursively of directory /opt:", err) } - // fix permissions of the tmp directory for better AWS parity - if err := ChmodRecursively("/tmp", 0700); err != nil { - log.Warnln("Could not change file mode recursively of directory /tmp:", err) + // set file permissions of the code directory if at least one layer is present for better AWS parity + // Limitation: hot reloading likely breaks file permission parity for /var/task in combination with layers + // Heuristic for detecting the presence of layers. It might fail for an empty layer or image-based Lambda. + if isDirEmpty, _ := IsDirEmpty("/opt"); !isDirEmpty { + log.Debugln("Detected layer present") + if err := ChmodRecursively("/var/task", 0755); err != nil { + log.Warnln("Could not change file mode recursively of directory /var/task:", err) + } } // parse CLI args