Skip to content

Commit ffd984b

Browse files
committed
fix: 9 critical bugs blocking distro acceptance
Bug 1: VERSION STRING — use git describe instead of github.ref_name On non-tag pushes, ref_name is 'master' not a version. Now outputs 'v0.1.0', 'v0.1.0-3-gabcdef', or 'dev'. Bug 2: SILENCED BINARY TEST — removed || true from bin/gspy --version Added --help test and invalid-input smoke test. If binary crashes, CI now fails red, not green. Bug 3: MAN PAGE MISSING FROM RELEASE — restored gzip + upload step Parrot OS and Debian require man/gspy.1.gz in the release. Bug 4: DEBIAN RULES FETCHES FROM INTERNET — removed go install Debian buildd has no internet. bpf2go must come from Build-Depends. Added golang-github-cilium-ebpf-dev to debian/control. Added bpf2go existence check to Makefile generate target. Bug 5: DEBIAN DESCRIPTION FORMATTING — rewritten to be lintian-clean Lowercase synopsis, ASCII only, one-space indent, no line >80 chars. Bug 6: GOLANGCI-LINT NODE.JS 24 — upgraded to v6 / v1.59.1 Added FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true to env. Bug 7: FLASH MESSAGE NEVER CLEARS — replaced with tea.Tick(3s) Added clearFlashMsg type. Flash now auto-clears after 3 seconds. Bug 8: NO INTEGRATION TEST — added CI job with real BPF Builds test process, runs gspy --json, validates JSON output has events with gid > 0. Bug 9: PKGBUILD MISSING — created packaging/PKGBUILD Proper BlackArch groups, makedepends, prepare/build/check/package.
1 parent bff5600 commit ffd984b

7 files changed

Lines changed: 265 additions & 128 deletions

File tree

.github/workflows/build.yml

Lines changed: 178 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ permissions:
1414
contents: write
1515

1616
env:
17-
GO_VERSION: 1.21
18-
CLANG_VERSION: 16
17+
GO_VERSION: "1.21"
18+
CLANG_VERSION: "16"
19+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
1920

2021
jobs:
2122
# ─────────────────────────────────────────────────────────
@@ -34,22 +35,51 @@ jobs:
3435
go-version: ${{ env.GO_VERSION }}
3536
cache: true
3637

37-
- name: Install BPF toolchain and Generate
38+
- name: Install BPF toolchain
3839
run: |
39-
sudo apt-get update && sudo apt-get install -y clang-${{ env.CLANG_VERSION }} llvm-${{ env.CLANG_VERSION }} libbpf-dev libelf-dev
40+
sudo apt-get update && sudo apt-get install -y \
41+
clang-${{ env.CLANG_VERSION }} \
42+
llvm-${{ env.CLANG_VERSION }} \
43+
libbpf-dev libelf-dev
4044
sudo ln -sf /usr/bin/clang-${{ env.CLANG_VERSION }} /usr/bin/clang
4145
sudo ln -sf /usr/bin/llvm-strip-${{ env.CLANG_VERSION }} /usr/bin/llvm-strip
46+
# Install bpftool — try kernel-specific, then build from source
47+
sudo apt-get install -y linux-tools-$(uname -r) 2>/dev/null || \
48+
sudo apt-get install -y linux-tools-azure 2>/dev/null || true
49+
if ! sudo bpftool version 2>/dev/null; then
50+
sudo apt-get install -y git pkg-config
51+
git clone --depth 1 --recurse-submodules \
52+
https://github.com/libbpf/bpftool.git /tmp/bpftool
53+
cd /tmp/bpftool/src && make -j$(nproc) && sudo make install prefix=/usr && cd -
54+
fi
55+
56+
- name: Generate vmlinux.h and BPF bindings
57+
run: |
58+
# Generate real vmlinux.h from kernel BTF
59+
if [ -f /sys/kernel/btf/vmlinux ]; then
60+
sudo bpftool btf dump file /sys/kernel/btf/vmlinux format c > bpf/vmlinux.h
61+
echo "✓ vmlinux.h generated ($(wc -l < bpf/vmlinux.h) lines)"
62+
else
63+
echo "ERROR: /sys/kernel/btf/vmlinux not found"; exit 1
64+
fi
4265
go install github.com/cilium/ebpf/cmd/bpf2go@v0.14.0
4366
export PATH=$PATH:$(go env GOPATH)/bin
4467
make generate
4568
46-
- name: Install dependencies
47-
run: sudo apt-get update && sudo apt-get install -y libbpf-dev libelf-dev
69+
- name: Check SPDX headers
70+
run: |
71+
MISSING=$(grep -rL "SPDX-License-Identifier" \
72+
--include="*.go" --include="*.c" . | grep -v vendor/ || true)
73+
if [ -n "$MISSING" ]; then
74+
echo "ERROR: Missing SPDX headers:"; echo "$MISSING"; exit 1
75+
fi
76+
echo "✓ All source files have SPDX headers"
4877
4978
- name: golangci-lint
50-
uses: golangci/golangci-lint-action@v4
79+
uses: golangci/golangci-lint-action@v6
5180
with:
52-
version: v1.54
81+
version: v1.59.1
82+
args: --timeout=5m --build-tags=testing
5383

5484
# ─────────────────────────────────────────────────────────
5585
# Job 2: Test — run unit tests with mock BPF
@@ -68,7 +98,6 @@ jobs:
6898
cache: true
6999

70100
- name: Run tests with race detector
71-
# -tags=testing ensures we use mock.go instead of loader.go
72101
run: go test -v -race -cover -tags=testing ./...
73102

74103
# ─────────────────────────────────────────────────────────
@@ -97,35 +126,53 @@ jobs:
97126
clang-${{ env.CLANG_VERSION }} \
98127
llvm-${{ env.CLANG_VERSION }} \
99128
libelf-dev \
100-
libbpf-dev \
101-
linux-tools-common \
102-
linux-tools-generic \
103-
linux-tools-$(uname -r) || true
104-
105-
# Symlink clang tools to versioned binaries for bpf2go
129+
libbpf-dev
106130
sudo ln -sf /usr/bin/clang-${{ env.CLANG_VERSION }} /usr/bin/clang
107131
sudo ln -sf /usr/bin/llc-${{ env.CLANG_VERSION }} /usr/bin/llc
108132
sudo ln -sf /usr/bin/llvm-strip-${{ env.CLANG_VERSION }} /usr/bin/llvm-strip
133+
# Install bpftool
134+
sudo apt-get install -y linux-tools-$(uname -r) 2>/dev/null || \
135+
sudo apt-get install -y linux-tools-azure 2>/dev/null || true
136+
if ! sudo bpftool version 2>/dev/null; then
137+
sudo apt-get install -y git pkg-config
138+
git clone --depth 1 --recurse-submodules \
139+
https://github.com/libbpf/bpftool.git /tmp/bpftool
140+
cd /tmp/bpftool/src && make -j$(nproc) && sudo make install prefix=/usr && cd -
141+
fi
142+
143+
- name: Generate vmlinux.h
144+
run: |
145+
if [ ! -f /sys/kernel/btf/vmlinux ]; then
146+
echo "ERROR: /sys/kernel/btf/vmlinux not found"; exit 1
147+
fi
148+
sudo bpftool btf dump file /sys/kernel/btf/vmlinux format c > bpf/vmlinux.h
149+
grep -q "struct task_struct" bpf/vmlinux.h || { echo "ERROR: invalid vmlinux.h"; exit 1; }
150+
echo "✓ vmlinux.h generated ($(wc -l < bpf/vmlinux.h) lines)"
109151
110152
- name: Generate BPF and Build
111153
env:
112-
CGO_ENABLED: 0
154+
CGO_ENABLED: "0"
113155
run: |
114-
# Install bpf2go
115156
go install github.com/cilium/ebpf/cmd/bpf2go@v0.14.0
116-
117-
# Use local GOPATH/bin for tools
118157
export PATH=$PATH:$(go env GOPATH)/bin
119-
120-
# Generate & Build via Makefile
121-
# This handles BPF compilation and Go build in one pass
122-
make build VERSION=${{ github.ref_name }}
158+
159+
# FIX BUG 1: Use git describe for proper version string
160+
VERSION=$(git describe --tags --always --dirty 2>/dev/null || echo "dev")
161+
echo "Building with VERSION=${VERSION}"
162+
make build VERSION=${VERSION}
123163
124164
- name: Verify binary
125165
run: |
126166
ls -la bin/gspy
127167
file bin/gspy
128-
bin/gspy --version || true
168+
# FIX BUG 2: NO || true — if any of these fail, the build fails
169+
bin/gspy --version
170+
bin/gspy --help
171+
# Smoke test: binary must reject invalid input
172+
! bin/gspy notapid 2>/dev/null
173+
174+
- name: Verify man page exists
175+
run: test -s man/gspy.1 || { echo "ERROR: man/gspy.1 is missing or empty"; exit 1; }
129176

130177
- name: Upload binary artifact
131178
uses: actions/upload-artifact@v4
@@ -135,12 +182,111 @@ jobs:
135182
retention-days: 30
136183

137184
# ─────────────────────────────────────────────────────────
138-
# Job 4: Release — create GitHub release on tag push
185+
# Job 4: Integration test — real BPF against real process
186+
# ─────────────────────────────────────────────────────────
187+
integration:
188+
name: Integration test (real BPF)
189+
runs-on: ubuntu-latest
190+
needs: [build-linux]
191+
steps:
192+
- name: Checkout
193+
uses: actions/checkout@v4
194+
195+
- name: Set up Go
196+
uses: actions/setup-go@v5
197+
with:
198+
go-version: ${{ env.GO_VERSION }}
199+
cache: true
200+
201+
- name: Download binary artifact
202+
uses: actions/download-artifact@v4
203+
with:
204+
name: gspy-linux-amd64
205+
path: bin/
206+
207+
- name: Build test target process
208+
run: |
209+
chmod +x bin/gspy
210+
cat > /tmp/testproc.go << 'TESTEOF'
211+
package main
212+
213+
import (
214+
"net/http"
215+
"time"
216+
)
217+
218+
func main() {
219+
go func() {
220+
for {
221+
http.Get("http://127.0.0.1:19999")
222+
time.Sleep(100 * time.Millisecond)
223+
}
224+
}()
225+
select {}
226+
}
227+
TESTEOF
228+
go build -o /tmp/gspy-testproc /tmp/testproc.go
229+
230+
- name: Run integration test
231+
run: |
232+
set -euo pipefail
233+
234+
# Start the test target process
235+
/tmp/gspy-testproc &
236+
TESTPID=$!
237+
echo "Test target PID: $TESTPID"
238+
sleep 2
239+
240+
# Verify test process is running
241+
kill -0 $TESTPID || { echo "ERROR: test process not running"; exit 1; }
242+
243+
# Run gspy in JSON mode for 5 seconds
244+
sudo timeout 5 ./bin/gspy $TESTPID --json > /tmp/gspy-out.json 2>/tmp/gspy-err.txt || true
245+
246+
# Kill the test process
247+
kill $TESTPID 2>/dev/null || true
248+
249+
# Print output for debugging
250+
echo "=== gspy stdout ==="
251+
head -20 /tmp/gspy-out.json || true
252+
echo "=== gspy stderr ==="
253+
cat /tmp/gspy-err.txt || true
254+
255+
# Validate: output must exist and be non-empty
256+
if [ ! -s /tmp/gspy-out.json ]; then
257+
echo "FAIL: gspy produced no JSON output"
258+
exit 1
259+
fi
260+
261+
# At least one valid JSON line must exist with gid > 0
262+
python3 -c "
263+
import json, sys
264+
events = []
265+
with open('/tmp/gspy-out.json') as f:
266+
for line in f:
267+
line = line.strip()
268+
if line:
269+
try:
270+
events.append(json.loads(line))
271+
except:
272+
pass
273+
if not events:
274+
print('FAIL: no parseable JSON events')
275+
sys.exit(1)
276+
valid = [e for e in events if e.get('gid', 0) > 0]
277+
if not valid:
278+
print(f'FAIL: no events with gid > 0. Got {len(events)} events total.')
279+
sys.exit(1)
280+
print(f'PASS: {len(valid)} events with valid GID out of {len(events)} total')
281+
"
282+
283+
# ─────────────────────────────────────────────────────────
284+
# Job 5: Release — create GitHub release on tag push
139285
# ─────────────────────────────────────────────────────────
140286
release:
141287
name: Release
142288
runs-on: ubuntu-latest
143-
needs: [build-linux, lint]
289+
needs: [build-linux, lint, integration]
144290
if: startsWith(github.ref, 'refs/tags/v')
145291
steps:
146292
- uses: actions/checkout@v4
@@ -151,14 +297,18 @@ jobs:
151297
name: gspy-linux-amd64
152298
path: release/
153299

154-
- name: Compress binary
300+
- name: Prepare release artifacts
155301
run: |
156302
cd release
157303
chmod +x gspy
158304
tar czf gspy-linux-amd64.tar.gz gspy
159305
sha256sum gspy-linux-amd64.tar.gz > SHA256SUMS.txt
160306
sha256sum gspy >> SHA256SUMS.txt
161307
308+
# FIX BUG 3: Compress and include man page in release
309+
- name: Compress man page
310+
run: gzip -k man/gspy.1
311+
162312
- name: Create GitHub Release
163313
uses: softprops/action-gh-release@v2
164314
with:
@@ -168,3 +318,4 @@ jobs:
168318
files: |
169319
release/gspy-linux-amd64.tar.gz
170320
release/SHA256SUMS.txt
321+
man/gspy.1.gz

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@ LDFLAGS = -s -w \
2727
-X main.BuildGoVersion=$(GO_VERSION)
2828

2929
# Generate BPF bytecode from C source using bpf2go.
30-
# Requires: clang >= 14, go >= 1.21
30+
# Requires: clang >= 14, go >= 1.21, bpf2go
3131
# Produces: internal/bpf/gspy_bpfel.go, internal/bpf/gspy_bpfel.o
3232
# NOTE: GOFLAGS=-mod=mod is required because bpf2go is a build tool,
3333
# not vendored as a runtime dependency. When vendor/ exists, Go defaults
3434
# to -mod=vendor which blocks module resolution for tools.
3535
generate:
36+
@which bpf2go > /dev/null 2>&1 || \
37+
(echo "ERROR: bpf2go not found in PATH." && \
38+
echo "Install it with: go install github.com/cilium/ebpf/cmd/bpf2go@v0.14.0" && \
39+
exit 1)
3640
GOFLAGS=-mod=mod go generate ./internal/bpf/...
3741

3842
# Build the gspy binary.

PKGBUILD

Lines changed: 0 additions & 80 deletions
This file was deleted.

0 commit comments

Comments
 (0)