mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-21 10:35:26 -04:00
distros(void linux): initial packaging support
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/privesc"
|
||||
)
|
||||
|
||||
// runit (Void Linux) service helpers. Services live in /etc/sv and are "enabled"
|
||||
// by symlinking them into the /var/service supervision dir, so the greeter
|
||||
// commands branch on isRunit() instead of shelling systemctl.
|
||||
|
||||
const (
|
||||
runitSvDir = "/etc/sv"
|
||||
runitServiceDir = "/var/service"
|
||||
)
|
||||
|
||||
// isRunit reports whether this system is supervised by runit (Void Linux).
|
||||
func isRunit() bool {
|
||||
if fi, err := os.Stat("/run/runit"); err == nil && fi.IsDir() {
|
||||
return true
|
||||
}
|
||||
if _, err := os.Stat("/run/systemd/system"); err == nil {
|
||||
return false
|
||||
}
|
||||
if fi, err := os.Stat(runitServiceDir); err == nil && fi.IsDir() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func runitServiceInstalled(name string) bool {
|
||||
fi, err := os.Stat(runitSvDir + "/" + name)
|
||||
return err == nil && fi.IsDir()
|
||||
}
|
||||
|
||||
func runitServiceEnabled(name string) bool {
|
||||
_, err := os.Lstat(runitServiceDir + "/" + name)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// enableRunitService links a service into /var/service (idempotent).
|
||||
func enableRunitService(name string) error {
|
||||
if !runitServiceInstalled(name) {
|
||||
return fmt.Errorf("runit service %q not found in %s", name, runitSvDir)
|
||||
}
|
||||
if runitServiceEnabled(name) {
|
||||
return nil
|
||||
}
|
||||
return privesc.Run(context.Background(), "", "ln", "-sf",
|
||||
runitSvDir+"/"+name, runitServiceDir+"/"+name)
|
||||
}
|
||||
|
||||
// disableRunitService removes a service's supervision symlink.
|
||||
func disableRunitService(name string) error {
|
||||
if !runitServiceEnabled(name) {
|
||||
return nil
|
||||
}
|
||||
return privesc.Run(context.Background(), "", "rm", "-f",
|
||||
runitServiceDir+"/"+name)
|
||||
}
|
||||
|
||||
// ensureRunitSeat sets up the seat access a Wayland greeter needs on runit (the
|
||||
// equivalent of logind on systemd): enables seatd and adds the greeter user to
|
||||
// the seat/video/input groups. Failures are reported but non-fatal.
|
||||
func ensureRunitSeat(greeterUser string) {
|
||||
if runitServiceInstalled("seatd") {
|
||||
if err := enableRunitService("seatd"); err != nil {
|
||||
fmt.Printf(" ⚠ could not enable seatd: %v\n", err)
|
||||
} else {
|
||||
fmt.Println(" ✓ seatd enabled")
|
||||
}
|
||||
} else {
|
||||
fmt.Println(" ⚠ seatd not installed — the greeter compositor needs it for GPU/seat access")
|
||||
}
|
||||
if err := privesc.Run(context.Background(), "", "usermod", "-aG", "_seatd,video,input", greeterUser); err != nil {
|
||||
fmt.Printf(" ⚠ could not add %s to seat groups: %v\n", greeterUser, err)
|
||||
} else {
|
||||
fmt.Printf(" ✓ %s added to seat groups (_seatd, video, input)\n", greeterUser)
|
||||
}
|
||||
}
|
||||
|
||||
// ensureGreetdPamRundir adds pam_rundir to the greetd PAM stack so the post-login
|
||||
// session gets an XDG_RUNTIME_DIR on systems without logind (Void with seatd).
|
||||
// Appended outside DMS's managed auth block so it survives `dms greeter sync`.
|
||||
func ensureGreetdPamRundir() {
|
||||
const pamPath = "/etc/pam.d/greetd"
|
||||
data, err := os.ReadFile(pamPath)
|
||||
if err != nil {
|
||||
fmt.Printf(" ⚠ could not read %s: %v\n", pamPath, err)
|
||||
return
|
||||
}
|
||||
if strings.Contains(string(data), "pam_rundir") {
|
||||
return
|
||||
}
|
||||
line := "session optional pam_rundir.so"
|
||||
if err := privesc.Run(context.Background(), "", "sh", "-c",
|
||||
fmt.Sprintf("printf '%%s\\n' %q >> %s", line, pamPath)); err != nil {
|
||||
fmt.Printf(" ⚠ could not add pam_rundir to %s: %v\n", pamPath, err)
|
||||
return
|
||||
}
|
||||
fmt.Println(" ✓ pam_rundir added to greetd PAM (provides XDG_RUNTIME_DIR for the session)")
|
||||
}
|
||||
|
||||
// startGreeterHint returns the init-appropriate "start greetd now" command.
|
||||
func startGreeterHint() string {
|
||||
if isRunit() {
|
||||
return " sudo sv up greetd"
|
||||
}
|
||||
return " sudo systemctl start greetd"
|
||||
}
|
||||
Reference in New Issue
Block a user