| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "net" |
| 5 | "os" |
| 6 | "strings" |
| 7 | ) |
| 8 | |
| 9 | // NotifyReady tells systemd this process is ready to serve, for a unit |
| 10 | // declared Type=notify. |
| 11 | // |
| 12 | // It exists so that "the process was exec'd" and "the process is serving" |
| 13 | // stop being the same fact to systemd. With Type=simple, `systemctl restart` |
| 14 | // succeeds the instant the binary is exec'd — so a console that starts and |
| 15 | // then dies on its first request, or half-applies a migration, restarts |
| 16 | // SUCCESSFULLY as far as the adopt pass can tell, and the pass then stamps a |
| 17 | // version nothing is really running. Signalled after the listener is open, |
| 18 | // a broken build fails its restart instead, and adoption's existing rollback |
| 19 | // takes over. |
| 20 | // |
| 21 | // No dependency: the protocol is one datagram on the socket systemd names in |
| 22 | // NOTIFY_SOCKET. An unset variable means "not under systemd" — a laptop, a |
| 23 | // test, `go run` — and is not an error. |
| 24 | // |
| 25 | // An "@" prefix denotes a Linux abstract socket, which net.Dial expects as a |
| 26 | // leading NUL. |
| 27 | // |
| 28 | // This is the code half only: it is INERT until console.service is declared |
| 29 | // Type=notify, a pinfra change outside this repo — see the runbook in |
| 30 | // .superpowers/sdd/2026-08-23-console-as-an-app/. |
| 31 | func NotifyReady() error { |
| 32 | sock := os.Getenv("NOTIFY_SOCKET") |
| 33 | if sock == "" { |
| 34 | return nil |
| 35 | } |
| 36 | if strings.HasPrefix(sock, "@") { |
| 37 | sock = "\x00" + sock[1:] |
| 38 | } |
| 39 | conn, err := net.Dial("unixgram", sock) |
| 40 | if err != nil { |
| 41 | return err |
| 42 | } |
| 43 | defer conn.Close() |
| 44 | _, err = conn.Write([]byte("READY=1")) |
| 45 | return err |
| 46 | } |
| 47 | |