domain/architecture/system/deployment/nix_darwin/service/ops.bend
near-v-framework@0.5.0.0 · 111 lines · 0 definitions
1import Base
2import near-v-framework@0.5.0.0/domain/architecture/system/deployment/nix_darwin/service/type.bend as Sv
3
4def container(s: Sv.Service) -> String:
5 match s:
6 case Sv.Service{c, _, _, _, _, _, _, _, _}:
7 c
8
9def label(s: Sv.Service) -> String:
10 match s:
11 case Sv.Service{_, l, _, _, _, _, _, _, _}:
12 l
13
14def port(s: Sv.Service) -> U32:
15 match s:
16 case Sv.Service{_, _, _, _, _, _, _, _, p}:
17 p
18
19def start(s: Sv.Service) -> Sv.Start:
20 match s:
21 case Sv.Service{_, _, _, _, _, _, _, st, _}:
22 st
23
24def labels(xs: List<&2, Sv.Service>) -> List<&2, String>:
25 match xs:
26 case []:
27 []
28 case s <> rest:
29 label(s) <> labels(rest)
30
31def at_login(s: Sv.Start) -> Bool:
32 match s:
33 case Sv.AtLogin{}:
34 True{}
35 case Sv.AtBoot{}:
36 False{}
37
38# Whether any service needs a user session to start.
39def needs_login(xs: List<&2, Sv.Service>) -> Bool:
40 match xs:
41 case []:
42 False{}
43 case s <> rest:
44 at_login(start(s)) || needs_login(rest)
45
46# ---- a service as a nix-darwin launchd job ----
47# The program's path in the Nix store.
48def program(p: Sv.Program) -> String:
49 match p:
50 case Sv.RunNode{}:
51 "\"${pkgs.nodejs_24}/bin/node\""
52 case Sv.RunPython{}:
53 "\"${pkgs.python3.withPackages (ps: [ ps.watchdog ])}/bin/python3\""
54 case Sv.RunBash{}:
55 "\"${pkgs.bash}/bin/bash\""
56
57def quoted(xs: List<&2, String>) -> String:
58 match xs:
59 case []:
60 ""
61 case x <> rest:
62 " \"" ++ x ++ "\"" ++ quoted(rest)
63
64def env(e: Sv.Env) -> String:
65 match e:
66 case Sv.Plain{k, v}:
67 " " ++ k ++ " = \"" ++ v ++ "\";"
68 case Sv.Expr{k, x}:
69 " " ++ k ++ " = " ++ x ++ ";"
70
71def envs(xs: List<&2, Sv.Env>) -> String:
72 match xs:
73 case []:
74 ""
75 case e <> rest:
76 env(e) ++ envs(rest)
77
78# At login: a launch agent in the user's session. At boot: a launch daemon that runs as the user.
79def job_kind(s: Sv.Start) -> String:
80 match s:
81 case Sv.AtLogin{}:
82 "launchd.user.agents"
83 case Sv.AtBoot{}:
84 "launchd.daemons"
85
86def user_name(s: Sv.Start, +user: String) -> String:
87 match s:
88 case Sv.AtLogin{}:
89 ""
90 case Sv.AtBoot{}:
91 " UserName = \"" ++ user ++ "\";"
92
93def job(s: Sv.Service, +user: String, +logs: String) -> String:
94 match s:
95 case Sv.Service{_, +l, p, args, dir, e, +log, +st, _}:
96 " " ++ job_kind(st) ++ ".\"" ++ l ++ "\".serviceConfig = {\n" ++
97 " Label = \"" ++ l ++ "\";" ++ user_name(st, user) ++ "\n" ++
98 " ProgramArguments = [ " ++ program(p) ++ quoted(args) ++ " ];\n" ++
99 " WorkingDirectory = \"" ++ dir ++ "\";\n" ++
100 " EnvironmentVariables = {" ++ envs(e) ++ " };\n" ++
101 " RunAtLoad = true; KeepAlive = true; ThrottleInterval = 10;\n" ++
102 " StandardOutPath = \"" ++ logs ++ "/" ++ log ++ ".log\";\n" ++
103 " StandardErrorPath = \"" ++ logs ++ "/" ++ log ++ ".log\";\n" ++
104 " };\n"
105
106def jobs(xs: List<&2, Sv.Service>, +user: String, +logs: String) -> String:
107 match xs:
108 case []:
109 ""
110 case s <> rest:
111 job(s, user, logs) ++ jobs(rest, user, logs)