mirror of
https://github.com/Mic92/sops-nix.git
synced 2026-07-17 14:35:25 +08:00
Merge pull request #936 from r-vdp/systemctl-restart-units
sops-install-secrets: call systemctl directly when run as a systemd unit
This commit is contained in:
commit
9ed65852b6
3 changed files with 88 additions and 28 deletions
|
|
@ -475,7 +475,9 @@ in
|
||||||
];
|
];
|
||||||
requiredBy = [ "sysinit-reactivation.target" ];
|
requiredBy = [ "sysinit-reactivation.target" ];
|
||||||
before = [ "sysinit-reactivation.target" ];
|
before = [ "sysinit-reactivation.target" ];
|
||||||
environment = cfg.environment;
|
environment = cfg.environment // {
|
||||||
|
SOPS_RESTART_UNITS_VIA_SYSTEMCTL = "1";
|
||||||
|
};
|
||||||
unitConfig.DefaultDependencies = "no";
|
unitConfig.DefaultDependencies = "no";
|
||||||
path = cfg.age.plugins;
|
path = cfg.age.plugins;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,9 @@ in
|
||||||
{
|
{
|
||||||
wantedBy = [ "systemd-sysusers.service" ];
|
wantedBy = [ "systemd-sysusers.service" ];
|
||||||
before = [ "systemd-sysusers.service" ];
|
before = [ "systemd-sysusers.service" ];
|
||||||
environment = cfg.environment;
|
environment = cfg.environment // {
|
||||||
|
SOPS_RESTART_UNITS_VIA_SYSTEMCTL = "1";
|
||||||
|
};
|
||||||
unitConfig.DefaultDependencies = "no";
|
unitConfig.DefaultDependencies = "no";
|
||||||
path = cfg.age.plugins;
|
path = cfg.age.plugins;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -1020,38 +1021,93 @@ func handleModifications(isDry bool, logcfg loggingConfig, symlinkPath string, s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeLines := func(list []string, file string) error {
|
// Decide how to propagate restart/reload requests.
|
||||||
if len(list) != 0 {
|
//
|
||||||
if _, err := os.Stat(filepath.Dir(file)); err != nil {
|
// When we run as a systemd service (useSystemdActivation = true), the
|
||||||
if os.IsNotExist(err) {
|
// unit is ordered Before=sysinit-reactivation.target, which
|
||||||
return nil
|
// switch-to-configuration restarts *after* it has already consumed
|
||||||
}
|
// /run/nixos/activation-{restart,reload}-list. Writing to those files
|
||||||
|
// from here therefore does nothing on the current switch and leaks
|
||||||
|
// into the next one. On top of that, NixOS 26.05 deprecates the
|
||||||
|
// activation-list mechanism entirely.
|
||||||
|
//
|
||||||
|
// The NixOS module sets SOPS_RESTART_UNITS_VIA_SYSTEMCTL=1 on the
|
||||||
|
// systemd unit so we know to call systemctl directly. We cannot rely
|
||||||
|
// on INVOCATION_ID for this: switch-to-configuration is almost always
|
||||||
|
// invoked from a process tree rooted in some unit (sshd, getty,
|
||||||
|
// systemd-run, ...), so the activation script inherits it too. For
|
||||||
|
// the legacy activation-script path, keep writing the list files so
|
||||||
|
// that switch-to-configuration picks them up as before.
|
||||||
|
if os.Getenv("SOPS_RESTART_UNITS_VIA_SYSTEMCTL") == "1" {
|
||||||
|
systemctl := func(verb string, units []string) error {
|
||||||
|
if len(units) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// --no-block: we are ordered before sysinit-reactivation.target
|
||||||
|
// with DefaultDependencies=no. Blocking on a normal service
|
||||||
|
// (which has After=sysinit.target) would deadlock the
|
||||||
|
// transaction.
|
||||||
|
args := append([]string{"--no-block", verb}, units...)
|
||||||
|
cmd := exec.Command("systemctl", args...)
|
||||||
|
cmd.Stdout = os.Stderr
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("error running 'systemctl %s': %w", strings.Join(args, " "), err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if isDry {
|
||||||
|
for _, u := range restart {
|
||||||
|
fmt.Fprintf(os.Stderr, "would restart %s\n", u)
|
||||||
|
}
|
||||||
|
for _, u := range reload {
|
||||||
|
fmt.Fprintf(os.Stderr, "would reload %s\n", u)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// try-restart: only act on units that are already running.
|
||||||
|
// On first activation the unit starts fresh with the new
|
||||||
|
// secret anyway, so a no-op is correct.
|
||||||
|
if err := systemctl("try-restart", restart); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o600)
|
if err := systemctl("try-reload-or-restart", reload); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() { _ = f.Close() }()
|
|
||||||
for _, unit := range list {
|
|
||||||
if _, err = f.WriteString(unit + "\n"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var dryPrefix string
|
|
||||||
if isDry {
|
|
||||||
dryPrefix = "/run/nixos/dry-activation"
|
|
||||||
} else {
|
} else {
|
||||||
dryPrefix = "/run/nixos/activation"
|
writeLines := func(list []string, file string) error {
|
||||||
}
|
if len(list) != 0 {
|
||||||
if err := writeLines(restart, dryPrefix+"-restart-list"); err != nil {
|
if _, err := os.Stat(filepath.Dir(file)); err != nil {
|
||||||
return err
|
if os.IsNotExist(err) {
|
||||||
}
|
return nil
|
||||||
if err := writeLines(reload, dryPrefix+"-reload-list"); err != nil {
|
}
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
f, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() { _ = f.Close() }()
|
||||||
|
for _, unit := range list {
|
||||||
|
if _, err = f.WriteString(unit + "\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var dryPrefix string
|
||||||
|
if isDry {
|
||||||
|
dryPrefix = "/run/nixos/dry-activation"
|
||||||
|
} else {
|
||||||
|
dryPrefix = "/run/nixos/activation"
|
||||||
|
}
|
||||||
|
if err := writeLines(restart, dryPrefix+"-restart-list"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := writeLines(reload, dryPrefix+"-reload-list"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not output changes if not requested
|
// Do not output changes if not requested
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue