code.pablomurad.com

bbs-hammer

SSH BBS with forums, chat, door games, retro terminals and a weather service, written in Go

build(docker): full target with DOSBox
author
Pablo Murad
date
commit
efd8a0c42b9454c113894fbcc32802a71265e75c
parent
d321a5969a72eea1a5d035f00aa51d0c8be8cdc3
changes
3 files +26 −16
@@ -196,6 +196,24 @@ USER wttr
 
 # ---------------------------------------------------------------------------
+# full: games plus DOSBox for DOS doors (bbs.dosbox, type: dos). DOSBox
+# runs headless on SDL's dummy video driver, so no X server is needed, and
+# only while someone plays. The doors and the FOSSIL driver are the
+# operator's: put them under /app/doors (a volume).
+# ---------------------------------------------------------------------------
+FROM games AS full
+
+USER root
+RUN set -eux; \
+    apt-get update; \
+    apt-get install -y --no-install-recommends dosbox; \
+    rm -rf /var/lib/apt/lists/*; \
+    mkdir -p /app/doors; \
+    chown wttr:wttr /app/doors
+
+USER wttr
+
+# ---------------------------------------------------------------------------
 # A plain `docker build` still produces the runtime image, without games.
 # ---------------------------------------------------------------------------
 FROM runtime AS default
@@ -34,13 +34,14 @@ // dosSettings is a resolved DOSBox setup.
 type dosSettings struct {
 	program   string
-	xvfb      string // xvfb-run, when there is no display to draw on
+	headless  bool // no display: SDL's dummy video driver, no window at all
 	fossilDir string
 	fossilCmd string
 }
 
-// resolveDOSBox finds DOSBox, and xvfb-run when there is no display. It
-// returns "" (DOS doors off) when either is missing.
+// resolveDOSBox finds DOSBox. It returns "" (DOS doors off) when it is
+// missing. Without a display DOSBox draws to SDL's dummy video driver, so
+// no X server (and no Xvfb) is needed.
 func resolveDOSBox(c *DOSBoxConfig) string {
 	s := resolveDOSSettings(c)
 	if s == nil {
@@ -67,13 +68,7 @@ 		return nil
 	}
 	s := &dosSettings{program: path, fossilDir: c.FossilDir, fossilCmd: c.FossilCommand}
-	if os.Getenv("DISPLAY") == "" {
-		if s.xvfb = findProgram("xvfb-run", ""); s.xvfb == "" {
-			log.Printf("bbs: DOS doors off: no display and no xvfb-run")
-
-			return nil
-		}
-	}
+	s.headless = os.Getenv("DISPLAY") == ""
 	dosConfigs.Store(path, s)
 
 	return s
@@ -149,11 +144,11 @@ } 
 	args := []string{"-conf", confPath, "-noconsole", "-exit"}
 	cmd := exec.Command(ds.program, args...)
-	if ds.xvfb != "" {
-		cmd = exec.Command(ds.xvfb, append([]string{"-a", ds.program}, args...)...)
-	}
 	cmd.Dir = tmp
 	cmd.Env = append(door.Env(filepath.Join(tmp, "DOOR.SYS"), tmp), "SDL_AUDIODRIVER=dummy")
+	if ds.headless {
+		cmd.Env = append(cmd.Env, "SDL_VIDEODRIVER=dummy")
+	}
 	cmd.Stdout = io.Discard
 	cmd.Stderr = io.Discard
 	if err := cmd.Start(); err != nil {
@@ -28,9 +28,6 @@ func TestDOSDoorThroughDOSBox(t *testing.T) { 	if _, err := exec.LookPath("dosbox"); err != nil {
 		t.Skip("dosbox not installed")
 	}
-	if _, err := exec.LookPath("xvfb-run"); err != nil {
-		t.Skip("xvfb-run not installed")
-	}
 	srv := testServer(t, &Config{
 		DOSBox: &DOSBoxConfig{},
 		Doors:  []DoorConfig{{Name: "Echo", Type: DoorDOS, Dir: t.TempDir(), Exe: "ECHO DOS SAYS HELLO>COM1", Nodes: 1}},