1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.octoprint;
8
9 baseConfig = {
10 plugins.cura.cura_engine = "${pkgs.curaengine_stable}/bin/CuraEngine";
11 server.host = cfg.host;
12 server.port = cfg.port;
13 webcam.ffmpeg = "${pkgs.ffmpeg.bin}/bin/ffmpeg";
14 };
15
16 fullConfig = recursiveUpdate cfg.extraConfig baseConfig;
17
18 cfgUpdate = pkgs.writeText "octoprint-config.yaml" (builtins.toJSON fullConfig);
19
20 pluginsEnv = pkgs.python.buildEnv.override {
21 extraLibs = cfg.plugins pkgs.octoprint-plugins;
22 };
23
24in
25{
26 ##### interface
27
28 options = {
29
30 services.octoprint = {
31
32 enable = mkEnableOption "OctoPrint, web interface for 3D printers";
33
34 host = mkOption {
35 type = types.str;
36 default = "0.0.0.0";
37 description = ''
38 Host to bind OctoPrint to.
39 '';
40 };
41
42 port = mkOption {
43 type = types.int;
44 default = 5000;
45 description = ''
46 Port to bind OctoPrint to.
47 '';
48 };
49
50 user = mkOption {
51 type = types.str;
52 default = "octoprint";
53 description = "User for the daemon.";
54 };
55
56 group = mkOption {
57 type = types.str;
58 default = "octoprint";
59 description = "Group for the daemon.";
60 };
61
62 stateDir = mkOption {
63 type = types.path;
64 default = "/var/lib/octoprint";
65 description = "State directory of the daemon.";
66 };
67
68 plugins = mkOption {
69 default = plugins: [];
70 defaultText = "plugins: []";
71 example = literalExample "plugins: [ m3d-fio ]";
72 description = "Additional plugins.";
73 };
74
75 extraConfig = mkOption {
76 type = types.attrs;
77 default = {};
78 description = "Extra options which are added to OctoPrint's YAML configuration file.";
79 };
80
81 };
82
83 };
84
85 ##### implementation
86
87 config = mkIf cfg.enable {
88
89 users.extraUsers = optionalAttrs (cfg.user == "octoprint") (singleton
90 { name = "octoprint";
91 group = cfg.group;
92 uid = config.ids.uids.octoprint;
93 });
94
95 users.extraGroups = optionalAttrs (cfg.group == "octoprint") (singleton
96 { name = "octoprint";
97 gid = config.ids.gids.octoprint;
98 });
99
100 systemd.services.octoprint = {
101 description = "OctoPrint, web interface for 3D printers";
102 wantedBy = [ "multi-user.target" ];
103 after = [ "network.target" ];
104 path = [ pluginsEnv ];
105 environment.PYTHONPATH = makeSearchPathOutput "lib" pkgs.python.sitePackages [ pluginsEnv ];
106
107 preStart = ''
108 mkdir -p "${cfg.stateDir}"
109 if [ -e "${cfg.stateDir}/config.yaml" ]; then
110 ${pkgs.yaml-merge}/bin/yaml-merge "${cfg.stateDir}/config.yaml" "${cfgUpdate}" > "${cfg.stateDir}/config.yaml.tmp"
111 mv "${cfg.stateDir}/config.yaml.tmp" "${cfg.stateDir}/config.yaml"
112 else
113 cp "${cfgUpdate}" "${cfg.stateDir}/config.yaml"
114 chmod 600 "${cfg.stateDir}/config.yaml"
115 fi
116 chown -R ${cfg.user}:${cfg.group} "${cfg.stateDir}"
117 '';
118
119 serviceConfig = {
120 ExecStart = "${pkgs.octoprint}/bin/octoprint serve -b ${cfg.stateDir}";
121 User = cfg.user;
122 Group = cfg.group;
123 PermissionsStartOnly = true;
124 };
125 };
126
127 };
128
129}