aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
blob: 39ba5cb6222fde43e040a14307b3adafb9e1cd0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# sbo-batch-test

Batch-test SlackBuilds against a clean Slackware 15.0 overlay chroot.

Resolves the full SBo dependency tree (locally, never network), topologically
sorts it, builds and installs every package in a fresh disposable overlay over
a read-only 15.0 base, captures persistent per-package logs, and prints a
color-coded summary.

Built for an SBo maintainer whose daily driver is Slackware64-current but whose
packages target 15.0 stable. It verifies that SlackBuilds BUILD and install
cleanly against the 15.0 userland/toolchain/libraries, which is where
current-vs-15.0 drift bites.

## Scope and limits

- Shares the host kernel (the current VM's kernel, not a 15.0 kernel). It does
  NOT test kernel-module packages or anything tied to the running kernel
  version. Those still want a real 15.0 VM.
- Resolution is LOCAL-tree-only. No network, no sbopkg. The local SBo tree is
  the single source of truth (it contains unpublished personal/pentesting
  packages that do not exist upstream).
- Does not integrate with, wrap, or drive slackrepo. Separate, independent tool.
- Built packages are throwaway. The point is "does it build on clean 15.0",
  not producing redistributable output.

## Prerequisites

Configuration lives in an external file, not in the script. Copy `config.example`
to `~/.config/sbo-batch-tester/config` and edit it (the tool runs as root, so
that is `/root/.config/sbo-batch-tester/config`). Override the path with the
`SBO_BATCH_CONFIG` environment variable. You need three things set in it:

1. **`SLACKWARE_BASE`** - a LOCAL (non-NFS) full Slackware 15.0 install tree.
   This is the overlay lowerdir. It MUST be local (ext4/xfs). overlayfs over an
   NFS lowerdir is fragile and a known source of intermittent failures.

2. **`LOCAL_MIRROR_15`** - the NFS mountpoint for the Slackware 15.0 mirror.
   Point it at the mount root itself; the actual tree (ChangeLog.txt,
   slackware64/, patches/) is found one level down at
   `$LOCAL_MIRROR_15/slackware64-$VERSION`. Used only as a package SOURCE to
   populate and patch `SLACKWARE_BASE`. Read-only is fine. If the fstab entry is
   `noauto`, the script auto-mounts it (`mount $LOCAL_MIRROR_15`) when absent and
   leaves it mounted after the run.

3. **`SBO_TREE_ROOTS`** - one or more LOCAL SBo tree roots, resolved in order
   (first match wins). Standard SBo layout
   `<root>/<category>/<prog>/{prog.SlackBuild,prog.info,...}`. Read in place,
   never copied or synced.

Also: run as root (overlay + chroot require it).

## Populating SLACKWARE_BASE

Populate from the NFS mirror with the FULL package set, not a minimal install.
A minimal base causes false "missing dependency" results that would not happen
on a normal user's full Slackware install.

Set `SLACKWARE_BASE` and `LOCAL_MIRROR_15` in your config file, then run once
as root:

```sh
sbo-batch-test --init-base
```

This installs the full `slackware64/*/*.t?z` set into `SLACKWARE_BASE` and
exits. It refuses to clobber an already-populated base (remove the directory
first to re-init). The tool will not auto-bootstrap the base during a build; if
the base is missing or incomplete a build fails fast and points you at
`--init-base`.

The base is kept patched automatically on each run: when the mirror's
ChangeLog head differs from the recorded marker, new packages from
`patches/packages/` are applied to the local base via `upgradepkg`.

## Package cache

Set `PKG_CACHE` in your config to a local directory to cache built packages
across runs (leave empty to disable). Layout mirrors the SBo tree
(`<category>/<prog>/<prog>-<version>-...txz`), one package per prog.

The named target always builds fresh, it is the package under test. Its
dependencies are installed from the cache when their version is unchanged
(reported as `CACHED`), otherwise they are built and cached. A build order line
shows the outcome per package: `cached (1.1)`, `rebuild: 1.0 -> 1.1`, or
`build (new)`; `--dry-run` shows the same without building. The whole cache is
wiped automatically when the base is patched, since cached packages were built
against the previous base.

## Usage

```
sbo-batch-test [OPTIONS] <program-name>
sbo-batch-test [OPTIONS] <category-folder>
```

### Single-package mode

Resolve a program's full dep tree, build+install every dep in order, then the
target. The whole chain shares ONE overlay, torn down at the end.

```sh
sbo-batch-test playwright-cli
```

### Category-folder mode

Every SlackBuild dir inside the folder is an independent target. Each target
gets its OWN fresh overlay against pristine 15.0, so one target's installed
deps never leak into the next. Deps may live in other categories.

```sh
sbo-batch-test ./network
sbo-batch-test /path/to/SBo-danix/pentesting
```

### Dry run

Resolve and print the build order, build nothing.

```sh
sbo-batch-test --dry-run playwright-cli
```

### Options

| Option            | Effect                                                       |
|-------------------|--------------------------------------------------------------|
| `-h`, `--help`    | Usage text.                                                  |
| `--no-color`      | Disable ANSI color (auto-disabled when stdout is not a TTY). |
| `--dry-run`       | Resolve and print build order, do not build.                 |
| `--with-x`        | Enable X passthrough (`xhost +local:hosts`). Headless by default. Security caveat: allows local non-network connections to your X server. |
| `-j`, `--jobs N`  | Reserved. No-op stub today (builds are serial).              |
| `--init-base`     | First-time populate `SLACKWARE_BASE` from the mirror, then exit. Run once before the first build. Refuses to clobber an existing base. |

## Per-package status values

| Status           | Meaning                                                   |
|------------------|-----------------------------------------------------------|
| `SUCCESS`        | Built and installed.                                      |
| `CACHED`         | Dependency installed from the package cache, not rebuilt. The target is never CACHED. |
| `DOWNLOAD-FAILED`| Source download failed.                                   |
| `MD5-MISMATCH`   | Source MD5 did not match the .info. Hard failure.         |
| `BUILD-FAILED`   | The .SlackBuild failed or produced no package.            |
| `INSTALL-FAILED` | `installpkg` of the resulting package failed.             |
| `BLOCKED-BY-DEP` | A dependency failed, so this was not attempted.           |
| `UNMET-DEP`      | A required package is neither in the SBo tree nor in base. Also covers dependency cycles. |

Packages whose REQUIRES carry `%README%` are flagged in the summary as a
reminder to check manual/optional configuration steps. `%README%` is not a
package and is skipped for build ordering.

## Logs

Written outside the overlay so they survive teardown, under `LOG_ROOT`:

```
$LOG_ROOT/2026-06-22_14-30-05/
  <category>_<prog>.log   per-package full build/install output
  summary.log             plain-text recap (same facts as the screen summary, no color)
  build-order.txt         the resolved topological order actually used
```

Each per-package log captures the full build/install output, the resolved
`.info` build context (PRGNAM/VERSION/BUILD/TAG/REQUIRES), and the installed
file list from the package db. That is everything worth inspecting, so the
overlay is always disposed and there is no keep-overlay option.

## Design tradeoffs (on the record)

- **Shared deps are rebuilt per target.** Each category target starts from a
  clean base, so a dep shared by N targets is rebuilt N times. Correct for
  isolation, slow for heavy shared deps (qt5, boost). A future optional
  package-output cache (keep built `.tgz` outside the overlay, `installpkg` a
  cached dep when its SlackBuild + version are unchanged) is marked TODO in the
  source, not yet implemented.
- **overlayfs sharp edges.** A build that fails ONLY in the overlay but works on
  bare 15.0 is more likely an overlayfs quirk (rename/whiteout) than a real
  build bug. Noted near the build step in the source.

## Credits

Some parts of this tool are inspired by `overlay-chroot.sh` by Slackware user
bassmadrigal (Jeremy Hansen): the overlayfs setup, the system bind mounts
(dev, proc, sys, dev/pts, resolv.conf, dbus machine-id), the base patching from
the local mirror, and the teardown ordering (pts, dev/proc/sys, resolv.conf,
dbus machine-id, overlay last), which is preserved deliberately.