mirror of
https://github.com/Mic92/sops-nix.git
synced 2026-07-17 14:35:25 +08:00
handle /run/secrets more gracefully if its a directory
This commit is contained in:
parent
74b9fe5d7f
commit
f214c1b76c
2 changed files with 30 additions and 25 deletions
|
|
@ -170,6 +170,9 @@ in
|
||||||
boot.initrd.postDeviceCommands = ''
|
boot.initrd.postDeviceCommands = ''
|
||||||
cp -r ${testAssets + "/age-keys.txt"} /run/age-keys.txt
|
cp -r ${testAssets + "/age-keys.txt"} /run/age-keys.txt
|
||||||
chmod -R 700 /run/age-keys.txt
|
chmod -R 700 /run/age-keys.txt
|
||||||
|
|
||||||
|
# if the directory exists, sops-nix should replace it with a symlink
|
||||||
|
mkdir /run/secrets
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,19 +70,19 @@ type template struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type manifest struct {
|
type manifest struct {
|
||||||
Secrets []secret `json:"secrets"`
|
Secrets []secret `json:"secrets"`
|
||||||
Templates []template `json:"templates"`
|
Templates []template `json:"templates"`
|
||||||
PlaceholderBySecretName map[string]string `json:"placeholderBySecretName"`
|
PlaceholderBySecretName map[string]string `json:"placeholderBySecretName"`
|
||||||
SecretsMountPoint string `json:"secretsMountPoint"`
|
SecretsMountPoint string `json:"secretsMountPoint"`
|
||||||
SymlinkPath string `json:"symlinkPath"`
|
SymlinkPath string `json:"symlinkPath"`
|
||||||
KeepGenerations int `json:"keepGenerations"`
|
KeepGenerations int `json:"keepGenerations"`
|
||||||
SSHKeyPaths []string `json:"sshKeyPaths"`
|
SSHKeyPaths []string `json:"sshKeyPaths"`
|
||||||
GnupgHome string `json:"gnupgHome"`
|
GnupgHome string `json:"gnupgHome"`
|
||||||
AgeKeyFile string `json:"ageKeyFile"`
|
AgeKeyFile string `json:"ageKeyFile"`
|
||||||
AgeSSHKeyPaths []string `json:"ageSshKeyPaths"`
|
AgeSSHKeyPaths []string `json:"ageSshKeyPaths"`
|
||||||
UseTmpfs bool `json:"useTmpfs"`
|
UseTmpfs bool `json:"useTmpfs"`
|
||||||
UserMode bool `json:"userMode"`
|
UserMode bool `json:"userMode"`
|
||||||
Logging loggingConfig `json:"logging"`
|
Logging loggingConfig `json:"logging"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type secretFile struct {
|
type secretFile struct {
|
||||||
|
|
@ -379,7 +379,13 @@ func prepareSecretsDir(secretMountpoint string, linkName string, keysGID int, us
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if !os.IsNotExist(err) {
|
} else if !os.IsNotExist(err) {
|
||||||
return nil, fmt.Errorf("cannot access %s: %w", linkName, err)
|
if _, err2 := os.Lstat(linkName); err2 != nil {
|
||||||
|
return nil, fmt.Errorf("cannot access %s: %w", linkName, err)
|
||||||
|
}
|
||||||
|
// if `/run/secrets` exists, but is not a symlink, we need to remove it
|
||||||
|
if err = os.RemoveAll(linkName); err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot remove %s: %w", linkName, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
generation++
|
generation++
|
||||||
dir := filepath.Join(secretMountpoint, strconv.Itoa(int(generation)))
|
dir := filepath.Join(secretMountpoint, strconv.Itoa(int(generation)))
|
||||||
|
|
@ -718,39 +724,35 @@ func (app *appContext) validateManifest() error {
|
||||||
|
|
||||||
func atomicSymlink(oldname, newname string) error {
|
func atomicSymlink(oldname, newname string) error {
|
||||||
if err := os.MkdirAll(filepath.Dir(newname), 0o755); err != nil {
|
if err := os.MkdirAll(filepath.Dir(newname), 0o755); err != nil {
|
||||||
return err
|
return fmt.Errorf("cannot create directory %s: %w", filepath.Dir(newname), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fast path: if newname does not exist yet, we can skip the whole dance
|
// Fast path: if newname does not exist yet, we can skip the whole dance
|
||||||
// below.
|
// below.
|
||||||
if err := os.Symlink(oldname, newname); err == nil || !os.IsExist(err) {
|
if err := os.Symlink(oldname, newname); err == nil || !os.IsExist(err) {
|
||||||
return err
|
return fmt.Errorf("cannot create symlink %s: %w", newname, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to use ioutil.TempDir, as we cannot overwrite a ioutil.TempFile,
|
// We need to use ioutil.TempDir, as we cannot overwrite a ioutil.TempFile,
|
||||||
// and removing+symlinking creates a TOCTOU race.
|
// and removing+symlinking creates a TOCTOU race.
|
||||||
d, err := os.MkdirTemp(filepath.Dir(newname), "."+filepath.Base(newname))
|
d, err := os.MkdirTemp(filepath.Dir(newname), "."+filepath.Base(newname))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("cannot create temporary directory: %w", err)
|
||||||
}
|
}
|
||||||
cleanup := true
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if cleanup {
|
os.RemoveAll(d)
|
||||||
os.RemoveAll(d)
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
symlink := filepath.Join(d, "tmp.symlink")
|
symlink := filepath.Join(d, "tmp.symlink")
|
||||||
if err := os.Symlink(oldname, symlink); err != nil {
|
if err := os.Symlink(oldname, symlink); err != nil {
|
||||||
return err
|
return fmt.Errorf("cannot create symlink %s: %w", symlink, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Rename(symlink, newname); err != nil {
|
if err := os.Rename(symlink, newname); err != nil {
|
||||||
return err
|
return fmt.Errorf("cannot rename %s to %s: %w", symlink, newname, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup = false
|
return nil
|
||||||
return os.RemoveAll(d)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func pruneGenerations(secretsMountPoint, secretsDir string, keepGenerations int) error {
|
func pruneGenerations(secretsMountPoint, secretsDir string, keepGenerations int) error {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue