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/klipper: preserve SAVE_CONFIG for nixos-managed config #370704

Merged
merged 2 commits into from
Jan 12, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 36 additions & 23 deletions nixos/modules/services/misc/klipper.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ let
};
in
{
imports = [
(lib.mkRenamedOptionModule
[ "services" "klipper" "mutableConfigFolder" ]
[ "services" "klipper" "configDir" ]
)
];

##### interface
options = {
services.klipper = {
Expand Down Expand Up @@ -52,23 +59,22 @@ in
default = false;
example = true;
description = ''
Whether to copy the config to a mutable directory instead of using the one directly from the nix store.
This will only copy the config if the file at `services.klipper.mutableConfigPath` doesn't exist.
Whether to manage the config outside of NixOS.

It will still be initialized with the defined NixOS config if the file doesn't already exist.
'';
};

mutableConfigFolder = lib.mkOption {
configDir = lib.mkOption {
type = lib.types.path;
default = "/var/lib/klipper";
description = "Path to mutable Klipper config file.";
description = "Path to Klipper config file.";
};

configFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Path to default Klipper config.
'';
description = "Path to default Klipper config.";
};

octoprintIntegration = lib.mkOption {
Expand Down Expand Up @@ -162,11 +168,6 @@ in
}
];

environment.etc = lib.mkIf (!cfg.mutableConfig) {
"klipper.cfg".source =
if cfg.settings != null then format.generate "klipper.cfg" cfg.settings else cfg.configFile;
};

services.klipper = lib.mkIf cfg.octoprintIntegration {
user = config.services.octoprint.user;
group = config.services.octoprint.group;
Expand All @@ -178,29 +179,41 @@ in
"--input-tty=${cfg.inputTTY}"
+ lib.optionalString (cfg.apiSocket != null) " --api-server=${cfg.apiSocket}"
+ lib.optionalString (cfg.logFile != null) " --logfile=${cfg.logFile}";
printerConfigPath =
if cfg.mutableConfig then cfg.mutableConfigFolder + "/printer.cfg" else "/etc/klipper.cfg";
printerConfigFile =
printerConfig =
if cfg.settings != null then format.generate "klipper.cfg" cfg.settings else cfg.configFile;
in
{
description = "Klipper 3D Printer Firmware";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
preStart = ''
mkdir -p ${cfg.mutableConfigFolder}
${lib.optionalString (cfg.mutableConfig) ''
[ -e ${printerConfigPath} ] || {
cp ${printerConfigFile} ${printerConfigPath}
chmod +w ${printerConfigPath}
mkdir -p ${cfg.configDir}
pushd ${cfg.configDir}
if [ -e printer.cfg ]; then
${
if cfg.mutableConfig then
":"
else
''
# Backup existing config using the same date format klipper uses for SAVE_CONFIG
old_config="printer-$(date +"%Y%m%d_%H%M%S").cfg"
mv printer.cfg "$old_config"
# Preserve SAVE_CONFIG section from the existing config
cat ${printerConfig} <(printf "\n") <(sed -n '/#*# <---------------------- SAVE_CONFIG ---------------------->/,$p' "$old_config") > printer.cfg
${pkgs.diffutils}/bin/cmp printer.cfg "$old_config" && rm "$old_config"
''
}
''}
mkdir -p ${cfg.mutableConfigFolder}/gcodes
else
cat ${printerConfig} > printer.cfg
fi
popd
'';

restartTriggers = lib.optional (!cfg.mutableConfig) [ printerConfig ];

serviceConfig =
{
ExecStart = "${cfg.package}/bin/klippy ${klippyArgs} ${printerConfigPath}";
ExecStart = "${cfg.package}/bin/klippy ${klippyArgs} ${cfg.configDir}/printer.cfg";
RuntimeDirectory = "klipper";
StateDirectory = "klipper";
SupplementaryGroups = [ "dialout" ];
Expand Down