Commit 3fdf5b97 by PLN (Algolia)

fix(tools): restore the exec bit on 63 scripts, in the INDEX where it counts

core.fileMode=false means chmod fixes your tree and nothing else — the 203/EXEC
class (log 032) recurs on every fresh checkout because the index said 644.
git update-index --chmod=+x is the repo-level fix; every shebang'd script under
tools/ + gig-up.sh + perf.sh now ships executable.
parent 774087a0
......@@ -179,7 +179,22 @@ done
# steals MIDI from SuperDirt and never sends a CC at anything.
leds(){
[ "${GIG_LEDS:-paint}" = off ] && { info "leds: disabled (GIG_LEDS=off)."; return; }
if ! "$DIR/tools/lcxl-leds.py" --map -q 2>/tmp/gig-leds.err; then
# LCXL3 plugged? Its driver owns BOTH translation (v3 DAW protocol -> the
# corpus's v2 CCs, faders -> Ardour gains included) and paint+OLED. It
# Conflicts= the v2 watcher, so exactly one painter owns the board. Restart,
# not start: idempotent, and re-reads the current track.
if aconnect -l 2>/dev/null | grep -q "LCXL3"; then
if systemctl --user restart lcxl3-driver.service 2>/tmp/gig-leds-unit.err; then
ok "leds: LCXL3 — lcxl3-driver owns translation + paint (journalctl --user -u lcxl3-driver). LOOK AT IT."
else
warn "leds: lcxl3-driver FAILED — faders will not reach Ardour without it."
warn "leds: $(head -2 /tmp/gig-leds-unit.err | tr '\n' ' ')"
fi
return
fi
# Original LCXL (v2): convention paint + the touch-reactive watcher.
# python3-invoked on purpose: core.fileMode=false keeps eating exec bits.
if ! python3 "$DIR/tools/lcxl-leds.py" --map -q 2>/tmp/gig-leds.err; then
warn "leds: paint failed — $(head -2 /tmp/gig-leds.err | tr '\n' ' ')"
warn "leds: if input works but the board is dark, that's a USB OUT stall — REPLUG the LCXL."
return
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -50,12 +50,30 @@ import sys
# unit, label, process that proves it really works (None = the unit is the whole
# story), boot policy, blurb
#
# Boot policies:
# login enabled at boot, started by --ensure
# on-demand NOT enabled at boot, but started by --ensure (parvagues-sc: a
# login must not start SuperDirt, a rig bring-up must)
# manual NOT enabled, NOT started by --ensure or the target — a human
# starts it for the hardware it serves (lcxl-leds-watch vs the
# plugged surface generation; Conflicts= makes auto-start hostile)
SERVICES = [
("parvagues-sc", "SuperDirt", "scsynth", "on-demand", "the sound"),
("parvagues-sc-watchdog", "sc-watchdog", None, "login", "restarts SuperDirt if scsynth dies"),
("tidal-ardour-autoroute", "autoroute", None, "login", "orbits → Ardour Tidal NN tracks"),
("midi-autoconnect", "MIDI wiring", None, "login", "LCXL → Midi Through, return leg cut"),
("lcxl-leds-watch", "LCXL LEDs", None, "login", "the surface paint"),
# Added 2026-09-05, the night the LCXL3 sat untranslated while every check
# was green: the driver only ran when a session remembered to start it. It
# translates the v3 DAW protocol to the corpus's v2 CCs (fader → Ardour
# gains included) and owns paint + OLED. Conflicts= with lcxl-leds-watch:
# one painter per board, whichever surface generation is plugged.
("lcxl3-driver", "LCXL3 driver", None, "login", "v3 surface → v2 CCs + paint + OLED"),
# "manual" since 2026-09-05: this is the ORIGINAL LCXL's painter. On the
# LCXL3 rig it fails forever misdiagnosing a USB OUT stall, and starting it
# Conflicts=-kills lcxl3-driver — so neither boot nor --ensure may start
# it. Start it BY HAND only when the v2 board is plugged.
("lcxl-leds-watch", "LCXL LEDs", None, "manual", "the v2 surface paint (original LCXL only)"),
("parvagues-bridge", "Bridge", None, "login", "dashboard + perf toolbar"),
# Added 2026-08-29. Absent from this list until then, and that absence IS why
# CosmicFest has no session log: the unit was installed 2026-07-29 and never
......@@ -63,6 +81,11 @@ SERVICES = [
# sessions that exist (through 2026-08-20) are exactly those manual runs.
# Costs 0.4% of a core at 1 Hz, so there is no reason for it to ever be off.
("gig-log", "gig-log", None, "login", "1 Hz session recorder: thermals, xruns, gear, MIDI"),
# Added 2026-09-05: parvagues-gear managed it but THE list didn't know it —
# the exact "list lived in three places" failure this module exists to end.
# Debt: its unit file still lives only in ~/.config/systemd/user (not
# repo-owned like the others).
("perf-tray", "perf tray", None, "login", "tray: what's up, perf mode, gear pause"),
]
TARGET = "parvagues-rig.target"
......@@ -105,7 +128,10 @@ def states() -> dict[str, dict[str, str]]:
def gen_target() -> str:
wants = "\n".join(f"Wants={u}.service" for u in UNITS)
# "manual" units stay out of the target: it must be safe to start the whole
# rig with one command, and a manual unit (lcxl-leds-watch) would Conflict=
# away the driver of whichever surface is actually plugged.
wants = "\n".join(f"Wants={u}.service" for u in UNITS if BOOT[u] != "manual")
return f"""[Unit]
# GENERATED by tools/rig_units.py --target. Do not hand-edit: add a row to
# SERVICES in that module and regenerate, or the list drifts out of the one
......@@ -133,7 +159,10 @@ def ensure(apply: bool) -> int:
# "linked" is NOT enabled, and neither is "disabled".
if BOOT[u] == "login" and s["enabled"] not in ("enabled", "enabled-runtime"):
todo.append(("enable", u, s["enabled"]))
if s["active"] != "active":
# "manual" units are never auto-started: lcxl-leds-watch Conflicts=
# lcxl3-driver, so starting it here would KILL the LCXL3 translation
# mid-bring-up while printing nothing but green.
if s["active"] != "active" and BOOT[u] != "manual":
todo.append(("start", u, s["active"]))
if not todo:
print(f"rig: all {len(UNITS)} units enabled-per-policy and active — nothing to do")
......@@ -162,9 +191,12 @@ def status() -> int:
note.append("NOT enabled at boot")
bad += 1
if s["active"] != "active":
if BOOT[u] == "manual":
note.append("manual — start by hand for its hardware")
else:
note.append("NOT running")
bad += 1
if s["enabled"] == "linked" and not want_enabled:
if s["enabled"] == "linked" and BOOT[u] == "on-demand":
note.append("on-demand, as designed")
print(f"{u:<24} {BOOT[u]:<10} {s['enabled']:<10} {s['active']:<10} {'; '.join(note) or BLURB[u]}")
print(f"\nrig: {len(UNITS)} unit(s), {bad} problem(s)")
......@@ -179,9 +211,19 @@ def main() -> int:
g.add_argument("--ensure", action="store_true", help="enable per boot policy AND start")
g.add_argument("--target", action="store_true", help=f"print the generated {TARGET}")
p.add_argument("--apply", action="store_true", help="with --ensure: actually act")
p.add_argument(
"--boot",
choices=["login", "on-demand", "manual", "auto"],
help="with --list: only units with this boot policy ('auto' = login + on-demand, i.e. everything --ensure may start)",
)
a = p.parse_args()
if a.list:
print("\n".join(UNITS))
units = UNITS
if a.boot == "auto":
units = [u for u in UNITS if BOOT[u] != "manual"]
elif a.boot:
units = [u for u in UNITS if BOOT[u] == a.boot]
print("\n".join(units))
return 0
if a.target:
print(gen_target(), end="")
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment