Make ordinary workspaces group shareable
This commit is contained in:
58
internal/fileops/modes.go
Normal file
58
internal/fileops/modes.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package fileops
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// WorkspaceDirectoryMode is the POSIX mode for ordinary, shareable workspace
|
||||
// directories. The set-group-ID bit preserves the configured workspace group
|
||||
// for nested files and directories.
|
||||
const WorkspaceDirectoryMode os.FileMode = os.ModeSetgid | 0o775
|
||||
|
||||
// WorkspaceFileMode is the POSIX mode for ordinary, shareable workspace files.
|
||||
const WorkspaceFileMode os.FileMode = 0o664
|
||||
|
||||
// EnsureWorkspaceDirectory creates directory and makes every directory created
|
||||
// for it conform to the ordinary workspace sharing contract. Existing
|
||||
// directories retain their owner and group; only their mode is updated.
|
||||
func EnsureWorkspaceDirectory(directory string) error {
|
||||
if strings.TrimSpace(directory) == "" {
|
||||
return fmt.Errorf("workspace directory is required")
|
||||
}
|
||||
|
||||
directory = filepath.Clean(directory)
|
||||
missing := make([]string, 0)
|
||||
for current := directory; ; current = filepath.Dir(current) {
|
||||
info, err := os.Lstat(current)
|
||||
if err == nil {
|
||||
if !info.IsDir() {
|
||||
return fmt.Errorf("workspace directory %q is not a directory", current)
|
||||
}
|
||||
break
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
return fmt.Errorf("inspect workspace directory %q: %w", current, err)
|
||||
}
|
||||
missing = append(missing, current)
|
||||
parent := filepath.Dir(current)
|
||||
if parent == current {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(directory, WorkspaceDirectoryMode); err != nil {
|
||||
return fmt.Errorf("create workspace directory %q: %w", directory, err)
|
||||
}
|
||||
for index := len(missing) - 1; index >= 0; index-- {
|
||||
if err := os.Chmod(missing[index], WorkspaceDirectoryMode); err != nil {
|
||||
return fmt.Errorf("set workspace directory permissions %q: %w", missing[index], err)
|
||||
}
|
||||
}
|
||||
if err := os.Chmod(directory, WorkspaceDirectoryMode); err != nil {
|
||||
return fmt.Errorf("set workspace directory permissions %q: %w", directory, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user