diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 19da804c13f..f3883ff56d3 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -251,6 +251,7 @@ cfdyndns = 227; gammu-smsd = 228; pdnsd = 229; + octoprint = 230; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -478,6 +479,7 @@ rmilter = 226; cfdyndns = 227; pdnsd = 229; + octoprint = 230; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 8254cdd6f5e..2509af7c0f2 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -229,6 +229,7 @@ ./services/misc/nix-gc.nix ./services/misc/nixos-manual.nix ./services/misc/nix-ssh-serve.nix + ./services/misc/octoprint.nix ./services/misc/parsoid.nix ./services/misc/phd.nix ./services/misc/plex.nix diff --git a/nixos/modules/services/misc/octoprint.nix b/nixos/modules/services/misc/octoprint.nix new file mode 100644 index 00000000000..bb9dc5da2eb --- /dev/null +++ b/nixos/modules/services/misc/octoprint.nix @@ -0,0 +1,118 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.octoprint; + + cfgUpdate = pkgs.writeText "octoprint-config.yaml" (builtins.toJSON { + plugins.cura.cura_engine = "${pkgs.curaengine}/bin/CuraEngine"; + server.host = cfg.host; + server.port = cfg.port; + webcam.ffmpeg = "${pkgs.ffmpeg}/bin/ffmpeg"; + }); + + pluginsEnv = pkgs.python.buildEnv.override { + extraLibs = cfg.plugins pkgs.octoprint-plugins; + }; + +in +{ + ##### interface + + options = { + + services.octoprint = { + + enable = mkEnableOption "OctoPrint, web interface for 3D printers"; + + host = mkOption { + type = types.str; + default = "0.0.0.0"; + description = '' + Host to bind OctoPrint to. + ''; + }; + + port = mkOption { + type = types.int; + default = 5000; + description = '' + Port to bind OctoPrint to. + ''; + }; + + user = mkOption { + type = types.str; + default = "octoprint"; + description = "User for the daemon."; + }; + + group = mkOption { + type = types.str; + default = "octoprint"; + description = "Group for the daemon."; + }; + + stateDir = mkOption { + type = types.path; + default = "/var/lib/octoprint"; + description = "State directory of the daemon."; + }; + + plugins = mkOption { + default = plugins: []; + example = literalExample "plugins: [ m3d-fio ]"; + description = "Additional plugins."; + }; + + }; + + }; + + ##### implementation + + config = mkIf cfg.enable { + + users.extraUsers = optionalAttrs (cfg.user == "octoprint") (singleton + { name = "octoprint"; + group = cfg.group; + uid = config.ids.uids.octoprint; + }); + + users.extraGroups = optionalAttrs (cfg.group == "octoprint") (singleton + { name = "octoprint"; + gid = config.ids.gids.octoprint; + }); + + systemd.services.octoprint = { + description = "OctoPrint, web interface for 3D printers"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + path = [ pluginsEnv ]; + environment.PYTHONPATH = makeSearchPath pkgs.python.sitePackages [ pluginsEnv ]; + + preStart = '' + mkdir -p "${cfg.stateDir}" + if [ -e "${cfg.stateDir}/config.yaml" ]; then + ${pkgs.yaml-merge}/bin/yaml-merge "${cfg.stateDir}/config.yaml" "${cfgUpdate}" > "${cfg.stateDir}/config.yaml.tmp" + mv "${cfg.stateDir}/config.yaml.tmp" "${cfg.stateDir}/config.yaml" + else + cp "${cfgUpdate}" "${cfg.stateDir}/config.yaml" + chmod 600 "${cfg.stateDir}/config.yaml" + fi + chown -R ${cfg.user}:${cfg.group} "${cfg.stateDir}" + ''; + + serviceConfig = { + ExecStart = "${pkgs.octoprint}/bin/octoprint -b ${cfg.stateDir}"; + User = cfg.user; + Group = cfg.group; + PermissionsStartOnly = true; + }; + }; + + }; + +}