Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/home-assistant: reload the daemon when configuration changed #151241

Merged
merged 2 commits into from
Jun 22, 2022

Conversation

andir
Copy link
Member

@andir andir commented Dec 18, 2021

Motivation for this change

Reload the service when configuration changes. This means that we don't
have a potentially slow startup for every small configuration change.

Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 22.05 Release Notes (or backporting 21.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
    • (Release notes changes) Ran nixos/doc/manual/md-to-db.sh to update generated release notes
  • Fits CONTRIBUTING.md.

@andir andir requested a review from mweinelt December 18, 2021 22:23
@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Dec 18, 2021
configFile
lovelaceConfigFile
];
reloadIfChanged = true;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhm, this should probably depend on !configWritable && !lovelaceConfigWritable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, you should add a note somewhere reminding users of the security implications here - "Please restart this service whenever a security update is released" or some such.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually that is already happening and I'm testing that in the VM test. As soon as the binary changes the service restarts anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What? With reloadIfChanged? I'm pretty sure it never used to... That is great.

ping @dasJ who is really deep into the switching script right now.
ping @mweinelt who maybe thought this wasn't the case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until #49528 is properly fixed there is actually a workaround we are using downstream. It's ugly but works and it doesn't add security implications.
Just add a second service that reloads the main service and give the reload service the restart triggers. Then don't give the main service restartIfChanged=true

I have included parts of our exim module as an example:

exim module
{
  systemd.services.exim-reload = {
    description = "Exim config reload";
    wantedBy = [ "multi-user.target" ];
    stopIfChanged = false;

    restartTriggers = [ config.environment.etc."exim.conf".source ];

    script = ''
      # Ensure the unit is already active
      ${config.systemd.package}/bin/systemctl is-active exim.service >/dev/null || exit 0
      ${config.systemd.package}/bin/systemctl reload-or-restart exim.service
    '';

    sandbox = 2;
    serviceConfig = {
      Type = "oneshot";
      RemainAfterExit = true;
      User = "exim";
      Group = "exim";
      SystemCallFilter = "@system-service";
    };

    apparmor = {
      enable = true;
      extraConfig = ''
        /run/dbus/system_bus_socket rw,
      '';
    };
  };

  security.polkit.extraConfig = ''
    polkit.addRule(function(action, subject) {
      if (action.id == "org.freedesktop.systemd1.manage-units" &&
        action.lookup("unit") == "exim.service" &&
        action.lookup("verb") == "reload-or-restart" &&
        subject.user == "exim") {
          return polkit.Result.YES;
      }
    });
  '';
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dasJ can you explain why this works as expected then? Did you have a look at the test code that I added to this PR?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at the code now. I have really no idea why that works. Are you 100% sure it gets reloaded once and restarted the second time and it's not hass restarting itself? Printing the switch-to-configuration.pl call should explain what it's asking systemd to do

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately the reloadIfChanged feature isn't really documented well (or correct). My current working theory is that the restartIfChanged list is an additional list of restart triggers and the reloadIfChanged boolean switches to reloading instead of restarting when the list changes. Meaning that it actually does exactly what we want in this case. The naming of these options is very unfortunate but I think it is working as expected.

I'll see if I can get this deployed tonight and give it some real-world testing as well was writing a VM test for the restartIfChanged semantics.

Copy link
Member

@aanderse aanderse Dec 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @flokli because of past conversations about how we thought if ExecStart ever changes the service should be restarted... we were both under the impression reloadIfChanged forces the service to never restart. Brief conversations with @mweinelt leave me with the impression that they also think this... 🤔

Thanks for offering to look into this @andir! And thanks for your feedback @dasJ!

@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux labels Dec 18, 2021
@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 19, 2022
@mweinelt
Copy link
Member

Just found this PR and I really have to wonder how I missed it or forgot looking into it.

Having a proper reload mechanism would be awesome to have. I think I'll annoy Janne, who has been working on this topic quite recently.

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 22, 2022
@dasJ
Copy link
Member

dasJ commented Jun 22, 2022

Oh no

Reload the service when configuration changes. This means that we don't
have a potentially slow startup for every small configuration change.
@mweinelt mweinelt force-pushed the hass-reload-on-config-changes branch from 7a6322c to cfbcf38 Compare June 22, 2022 14:20
@mweinelt
Copy link
Member

mweinelt commented Jun 22, 2022

Rebased and did a few cosmetical changes. The use of specializations for the test scenario is neat. Thanks for providing these.

@ofborg test home-assistant

@ofborg ofborg bot added 10.rebuild-linux: 1-10 and removed 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux labels Jun 22, 2022
With multiple specialization changes this isn't very helpful anymore,
but no biggie since we check the log for errors anyway and the log is
not too verbose anyway.
@mweinelt mweinelt force-pushed the hass-reload-on-config-changes branch from 1ca0704 to d26a6e3 Compare June 22, 2022 15:02
@mweinelt mweinelt merged commit b15badc into NixOS:master Jun 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants