Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
b399ac3
build: openwrt 25.12.1
Tbaile Mar 25, 2026
bceaca9
chore: updated build container
Tbaile Mar 25, 2026
51b2e2e
build(ppp): upstream patched the package
Tbaile Mar 25, 2026
b685ac9
build: openwrt 25.12.2
Tbaile Apr 15, 2026
5649ac8
build(netifyd): updated binaries
Tbaile Apr 15, 2026
b8fd0f9
fix: updated syntax due to python update
Tbaile Apr 16, 2026
d1b225f
chore: updated checkmk version
Tbaile May 5, 2026
700ff7c
build: added suffix support
Tbaile Apr 29, 2026
87b7b8d
updated variable generation
Tbaile Apr 29, 2026
434c54d
chore: updated python semver package
Tbaile May 5, 2026
56f13fc
fixed release path
Tbaile May 5, 2026
647de75
feat: added victoria-metrics package
Tbaile Apr 30, 2026
518f18a
feat: added victoria-logs
Tbaile Apr 30, 2026
c04d12a
feat: added telegraf package
Tbaile Apr 30, 2026
0b09db9
fix: updated spdx
Tbaile Apr 30, 2026
84e119d
feat: compiling packages
Tbaile Apr 30, 2026
64d0531
fix: accidentally overwrote telegraf config
Tbaile Apr 30, 2026
280eee8
fix: addressed deprecation warnings and removed not useful comments
Tbaile Apr 30, 2026
67d6f4e
fix: adjusted config for sensors and ethtool
Tbaile Apr 30, 2026
abecde7
chore: updated monitoring tools
Tbaile May 5, 2026
275d473
chore: downgraded version to keep compatibility with go
Tbaile May 5, 2026
f5a3a4b
chore: added skill to update packages
Tbaile May 5, 2026
3b756da
ci: fixed versioning for image build
Tbaile May 5, 2026
2cdd65b
chore: removed ipcalc fork
Tbaile May 12, 2026
794ac79
chore: removed jinja2 fork
Tbaile May 12, 2026
dd7db83
build: updated signing method for APKs (#1659)
Tbaile May 12, 2026
37c29b0
build: compiling avahi mdns (#1657)
Tbaile May 12, 2026
e1416f6
build: updated debian version and openwrt version
Tbaile May 12, 2026
0af757a
chore: move back history to persistend dir
gsanchietti May 14, 2026
3fe68d6
build: fixed issue where env variables were not honoured
Tbaile May 15, 2026
1b33f84
build: bumped to 24.12.4
Tbaile May 15, 2026
25a49b6
feat(victoria): add vmalert alerting
gsanchietti Apr 22, 2026
61f463a
feat(api): replace ns.netdata with ns.telegraf
gsanchietti Apr 23, 2026
2213e9d
feat(telegraf): add missing plugins
gsanchietti Apr 30, 2026
2b48091
refactor(ns-plug): remove netdata
gsanchietti May 5, 2026
3930f77
feat(telegraf): using uci conf for ping config, added migration path …
Tbaile May 7, 2026
0a1feb6
chore(ns-ui): version bump
Tbaile May 7, 2026
4eaa607
fix(telegraf): moving pruning of netdata config to telegraf migration
Tbaile May 7, 2026
928c5f4
fix(ns-api): using uci config for pings
Tbaile May 13, 2026
80b2891
fix(ns-plug): added service triggers for alert-proxy
Tbaile May 13, 2026
214e272
feat(victoria-metrics): added storage configuration
Tbaile May 15, 2026
f23b035
chore(ns-ui): version bump
Tbaile May 15, 2026
fd5a7e9
chore(skill): improve OpenWrt package update
Tbaile May 11, 2026
e4d859d
chore: updated adblock to 4.5.5-3
Tbaile May 11, 2026
ead56c6
fix(adblock): reload nft rules
gsanchietti May 15, 2026
87a57c8
fix(adblock): stage dns list changes
gsanchietti May 15, 2026
57fa82c
fix(ipsec): add restart dpd_action
gsanchietti May 15, 2026
5b90c12
chore(ui): bump to dev commit
gsanchietti May 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .agents/skills/openwrt-package-update/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
name: openwrt-package-update
description: >
Use when updating any forked OpenWrt package in a NethSecurity workspace from
the upstream openwrt/packages feed. Covers the full update cycle: version bump,
merging upstream file changes, updating dependent ns-api handlers and migration
scripts, UCI overlay defaults, and correlated documentation. Triggers on updating
a package by name (adblock, mwan3, banip, rsyslog, snort3, keepalived,
python-jinja2, python-semver, and similar forks), syncing with upstream, or any
request to align a local package fork with openwrt/packages — even if upstream
is not mentioned explicitly.
compatibility: Requires git and curl. Works in a NethSecurity workspace with build.conf.defaults present.
metadata:
domain: nethsecurity-packages
type: package-update
allowed-tools: Bash(git:*) Bash(curl:*) Bash(diff:*) Bash(tar:*) Bash(grep:*) Bash(sed:*) Bash(awk:*) Read Write
---

## What I do

Update a forked upstream OpenWrt package from the openwrt/packages feed. Auto-discovers the package path, compares the current version against the upstream target, extracts snapshots for comparison, applies upstream changes, propagates impact to ns-api handlers and migration scripts, and updates correlated documentation.

## Quick start

1. **Setup**: `bash scripts/setup-package.sh <package-name>` — auto-discovers upstream path, finds version commits, extracts old/new snapshots into `assets/<name>_old/` and `assets/<name>_new/`
2. **Compare**: `bash scripts/diff-package.sh <package-name>` — shows what changed upstream
3. **Merge**: Read both snapshots, apply upstream changes to local files in `packages/<package-name>/`; update PKG_VERSION and PKG_RELEASE in the Makefile
4. **Cross-package**: Grep for any changed config keys or function names in ns-api, migration scripts, and files/ overlay; update as needed
5. **Documentation**: Update `docs/` and `packages/ns-api/README.md` if user-facing behavior changed
6. **Verify**: Run `ruff check` on any changed Python files; build the package inside the container

For per-step detail on any of the above, read [references/WORKFLOW.md](references/WORKFLOW.md).

## How it works

The skill uses three helper scripts:

- **get-target-commit.sh** — reads `build.conf.defaults` for OWRT_VERSION, fetches `feeds.conf.default` from that tag, extracts the openwrt/packages commit hash
- **setup-package.sh** — auto-discovers package upstream path, uses git pickaxe to find the commit matching current PKG_VERSION then PKG_RELEASE, clones/fetches openwrt/packages bare repo into `assets/.openwrt-packages-repo/` (persistent cache), extracts both versions into named snapshots
- **diff-package.sh** — convenience wrapper: `diff -rN assets/<name>_old/ assets/<name>_new/`

## Snapshot structure

Each snapshot has the exact upstream package files at root level:
```
assets/adblock_old/
├── Makefile
├── files/
│ ├── adblock.sh
│ ├── adblock.init
│ ├── adblock.conf
│ └── ...
```

## Edge cases

- **mwan3**: Deep fork — apply upstream changes conservatively, one by one
- **snort3**: Has local patches — verify patches still apply after update
- **Version not found**: If script fails, local version is very old; check `assets/.openwrt-packages-repo/` git history
- **Empty diff**: Versions match; only update PKG_VERSION/PKG_RELEASE if tracking newer release
1 change: 1 addition & 0 deletions .agents/skills/openwrt-package-update/assets/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
88 changes: 88 additions & 0 deletions .agents/skills/openwrt-package-update/references/WORKFLOW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Detailed Workflow: Updating Upstream Packages

## 1. Identify the package

Confirm the package exists and is in scope. Read `packages/<package-name>/Makefile` to understand the current version:
- Note PKG_VERSION and PKG_RELEASE
- Check if `packages/<package-name>/patches/` exists (indicates local patches)
- Scan `files/` directory to understand what configuration files and scripts are included

## 2. Setup snapshots

Run the setup script:
```bash
bash scripts/setup-package.sh <package-name>
```

This script will:
- Auto-discover the upstream path in openwrt/packages (e.g., `net/adblock`)
- Use git pickaxe to find the commit that introduced the current PKG_VERSION
- Then find the commit that set the current PKG_RELEASE
- Extract both versions into `assets/<package-name>_old/` and `assets/<package-name>_new/`
- Output summary with commit hashes and paths

## 3. Compare and classify

Examine both snapshots using your file reading tools. Run:
```bash
bash scripts/diff-package.sh <package-name>
```

Classify each change:
- **Makefile**: version bumps, new dependencies, build flags
- **files/*.sh** / **files/*.init**: behavioral changes to shell scripts
- **files/*.conf**: UCI configuration schema changes (new/removed/renamed options)
- **files/*.sources**, **files/*.categories**, data files: content-only updates
- **New files** added / **files removed**

## 4. Apply upstream changes

For each changed file:
- If the local copy is identical to old version or has no NethSecurity-specific changes → take upstream as-is
- If the local copy has customizations → merge carefully:
- Use the diff tool to understand what changed upstream
- Manually integrate the upstream changes into the local file
- Preserve any NethSecurity-specific logic or configuration

Always:
- Update PKG_VERSION and PKG_RELEASE in `packages/<package-name>/Makefile`
- If `packages/<package-name>/patches/` exists, re-verify each patch still applies cleanly with the new version
- Test build: `make package/feeds/nethsecurity/<name>/compile V=sc` inside the build container

## 5. Cross-package impact detection

For each changed UCI option name, function name, or config key in the diff:
- Grep the workspace for references:
```bash
grep -r "<changed-key>" packages/ files/ docs/ --include="*.py" --include="*.sh" --include="*.json" --include="*.conf" --include="*.md"
```
- Grep `packages/ns-migration/` for migration scripts that reference old option names
- Grep `packages/ns-api/` for API scripts that read/write this package's configuration
- Present findings to user before making changes

## 6. Apply cross-package fixes (after user confirmation)

Update affected files:
- **ns-api scripts**: if UCI schema changed, update handlers in `packages/ns-api/files/ns.<name>`
- **Migration scripts**: if old config options are removed, add migration logic to `packages/ns-migration/files/`
- **files/ overlay defaults**: if default values changed, update `files/etc/uci-defaults/` or `files/etc/config/`
- **Documentation**: update `docs/` if user-facing behavior changed

## Edge cases

**mwan3**: This is a deep fork with significant local modifications. Apply upstream changes one by one, preferring manual review for any behavioral change. Verify the result against firewall rules and failover behavior.

**snort3, openvpn-easy-rsa**: These packages have local patches (see `packages/<name>/patches/`). After updating upstream files, re-run `quilt refresh` or regenerate patches. If patches no longer apply cleanly, update them to match the new upstream.

**Empty diff**: If upstream and local versions are the same, only update PKG_VERSION/PKG_RELEASE in the Makefile if tracking a newer release. Otherwise, the package is up-to-date.

**Version not found**: If the script cannot find the current PKG_VERSION in upstream history, it means the local version is very old or from a different source. Check git history in the bare repo (`assets/.openwrt-packages-repo/`) to understand the version trajectory.

## Helpful commands

Inside the skill directory:
- `bash scripts/get-target-commit.sh` — print the target packages feed commit hash from feeds.conf.default
- `bash scripts/setup-package.sh <name>` — extract old/new snapshots
- `bash scripts/diff-package.sh <name>` — show recursive diff
- `find assets/<name>_old/ -type f` — list all files in old snapshot
- `cat assets/<name>_old/Makefile | grep PKG_` — check old version details
38 changes: 38 additions & 0 deletions .agents/skills/openwrt-package-update/scripts/diff-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash
#
# Diff old and new package snapshots
#
# Usage: diff-package.sh <package-name>
#
# Outputs a recursive diff between assets/<name>_old/ and assets/<name>_new/
#

set -euo pipefail

PACKAGE_NAME="${1:-}"

if [[ -z "$PACKAGE_NAME" ]]; then
echo "Usage: diff-package.sh <package-name>" >&2
exit 1
fi

# Find skill root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ASSETS_DIR="$SKILL_ROOT/assets"

OLD_DIR="$ASSETS_DIR/${PACKAGE_NAME}_old"
NEW_DIR="$ASSETS_DIR/${PACKAGE_NAME}_new"

if [[ ! -d "$OLD_DIR" ]]; then
echo "Error: $OLD_DIR not found. Run setup-package.sh first." >&2
exit 1
fi

if [[ ! -d "$NEW_DIR" ]]; then
echo "Error: $NEW_DIR not found. Run setup-package.sh first." >&2
exit 1
fi

# Run recursive diff, showing added/removed/modified files
diff -rN "$OLD_DIR" "$NEW_DIR" || true
44 changes: 44 additions & 0 deletions .agents/skills/openwrt-package-update/scripts/get-target-commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/bash
#
# Get the target OpenWrt packages feed commit hash from feeds.conf.default
# at the version specified in build.conf.defaults
#
# Outputs the commit hash to stdout, or exits with error if fetch/parse fails.
#

set -euo pipefail

# Find workspace root
WORKSPACE_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && git rev-parse --show-toplevel 2>/dev/null || echo ".")

# Read OWRT_VERSION from build.conf.defaults
if [[ ! -f "$WORKSPACE_ROOT/build.conf.defaults" ]]; then
echo "Error: build.conf.defaults not found at $WORKSPACE_ROOT" >&2
exit 1
fi

OWRT_VERSION=$(grep '^OWRT_VERSION=' "$WORKSPACE_ROOT/build.conf.defaults" | cut -d'=' -f2 | tr -d ' ')

if [[ -z "$OWRT_VERSION" ]]; then
echo "Error: OWRT_VERSION not found or empty in build.conf.defaults" >&2
exit 1
fi

# Fetch feeds.conf.default from OpenWrt at the specified tag
FEEDS_URL="https://raw.githubusercontent.com/openwrt/openwrt/$OWRT_VERSION/feeds.conf.default"

FEEDS_CONTENT=$(curl -fsSL "$FEEDS_URL" 2>/dev/null || {
echo "Error: Failed to fetch $FEEDS_URL" >&2
exit 1
})

# Parse the packages line to extract the commit hash (after the ^)
# Expected format: src-git packages https://git.openwrt.org/feed/packages.git^<hash>
PACKAGES_COMMIT=$(echo "$FEEDS_CONTENT" | grep '^src-git packages' | sed 's/.*\^//g' | head -1)

if [[ -z "$PACKAGES_COMMIT" ]]; then
echo "Error: Could not parse packages commit hash from feeds.conf.default" >&2
exit 1
fi

echo "$PACKAGES_COMMIT"
162 changes: 162 additions & 0 deletions .agents/skills/openwrt-package-update/scripts/setup-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/bin/bash
#
# Setup old and new package snapshots for comparison
#
# Usage: setup-package.sh <package-name>
#
# Outputs:
# - Creates assets/<name>_old/ with the current pinned upstream version
# - Creates assets/<name>_new/ with the target upstream version (from feeds.conf.default)
# - Prints to stdout: package name, CURRENT_COMMIT, TARGET_COMMIT, upstream path
#

set -euo pipefail

PACKAGE_NAME="${1:-}"

if [[ -z "$PACKAGE_NAME" ]]; then
echo "Usage: setup-package.sh <package-name>" >&2
exit 1
fi

# Find workspace root (convert to absolute path)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_ROOT=$(cd "$SCRIPT_DIR/../../../.." && git rev-parse --show-toplevel 2>/dev/null || pwd)
SKILL_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ASSETS_DIR="$SKILL_ROOT/assets"

# Ensure assets dir exists
mkdir -p "$ASSETS_DIR"

# Read current package version from local Makefile
LOCAL_MAKEFILE="$WORKSPACE_ROOT/packages/$PACKAGE_NAME/Makefile"
if [[ ! -f "$LOCAL_MAKEFILE" ]]; then
echo "Error: $LOCAL_MAKEFILE not found" >&2
exit 1
fi

PKG_VERSION=$(grep '^PKG_VERSION:=' "$LOCAL_MAKEFILE" | cut -d'=' -f2 | tr -d ' ')
PKG_RELEASE=$(grep '^PKG_RELEASE:=' "$LOCAL_MAKEFILE" | cut -d'=' -f2 | tr -d ' ')

if [[ -z "$PKG_VERSION" ]]; then
echo "Error: PKG_VERSION not found in $LOCAL_MAKEFILE" >&2
exit 1
fi

echo "Package: $PACKAGE_NAME (version $PKG_VERSION-$PKG_RELEASE)" >&2

# Get target commit from feeds.conf.default
TARGET_COMMIT=$("$SKILL_ROOT/scripts/get-target-commit.sh")
echo "Target commit: $TARGET_COMMIT" >&2

# Clone/fetch openwrt/packages bare repo
BARE_REPO="$ASSETS_DIR/.openwrt-packages-repo"

if [[ ! -d "$BARE_REPO" ]]; then
echo "Cloning openwrt/packages (bare repo)..." >&2
git clone --bare --filter=blob:none https://github.com/openwrt/packages.git "$BARE_REPO" 2>/dev/null || {
echo "Error: Failed to clone openwrt/packages" >&2
exit 1
}
else
echo "Fetching openwrt/packages..." >&2
cd "$BARE_REPO"
git fetch origin 2>/dev/null || {
echo "Error: Failed to fetch openwrt/packages" >&2
exit 1
}
cd - > /dev/null
fi

# Auto-discover the upstream path by searching for <package-name>/Makefile
# Look in the target commit first to find the exact path
echo "Discovering upstream package path..." >&2
UPSTREAM_PATH=$(cd "$BARE_REPO" && git ls-tree -r --name-only "$TARGET_COMMIT" | grep -E "^[^/]+/$PACKAGE_NAME/Makefile$" | sed 's|/Makefile$||' | head -1)

if [[ -z "$UPSTREAM_PATH" ]]; then
echo "Error: Could not find $PACKAGE_NAME in upstream openwrt/packages at $TARGET_COMMIT" >&2
exit 1
fi

echo "Upstream path: $UPSTREAM_PATH" >&2

# Find the commit that introduced the current version
# Step 1: Find when PKG_VERSION was introduced using pickaxe
# Step 2: Find when PKG_RELEASE was set using pickaxe
echo "Finding commit that matches local version ($PKG_VERSION-$PKG_RELEASE)..." >&2

CURRENT_COMMIT=""

# Step 1: Find commits that introduced PKG_VERSION
echo " Step 1: Finding commits with PKG_VERSION:=$PKG_VERSION..." >&2
version_commits=$(cd "$BARE_REPO" && git log -S "PKG_VERSION:=$PKG_VERSION" --all --format="%H" -- "$UPSTREAM_PATH/Makefile" 2>/dev/null)

if [[ -z "$version_commits" ]]; then
echo "Error: Could not find PKG_VERSION:=$PKG_VERSION in git history" >&2
exit 1
fi

# Get the oldest commit where PKG_VERSION was introduced (last in the list when searching backwards)
version_commit=$(echo "$version_commits" | tail -1)
echo " PKG_VERSION introduced at: $version_commit" >&2

# Step 2: From that commit forward, find when PKG_RELEASE was set
# We search commits from version_commit onwards for PKG_RELEASE change
echo " Step 2: Finding commits with PKG_RELEASE:=$PKG_RELEASE after version introduction..." >&2
release_commits=$(cd "$BARE_REPO" && git log -S "PKG_RELEASE:=$PKG_RELEASE" --all --format="%H" -- "$UPSTREAM_PATH/Makefile" 2>/dev/null)

if [[ -n "$release_commits" ]]; then
# Find the first commit in release_commits that is an ancestor of or after version_commit
# Also verify both PKG_VERSION and PKG_RELEASE are present
while IFS= read -r commit; do
makefile_content=$(cd "$BARE_REPO" && git show "$commit:$UPSTREAM_PATH/Makefile" 2>/dev/null || echo "")

if echo "$makefile_content" | grep -q "^PKG_VERSION:=$PKG_VERSION" && \
echo "$makefile_content" | grep -q "^PKG_RELEASE:=$PKG_RELEASE"; then
CURRENT_COMMIT="$commit"
break
fi
done <<< "$release_commits"
fi

if [[ -z "$CURRENT_COMMIT" ]]; then
echo "Error: Could not find a commit matching $PKG_VERSION-$PKG_RELEASE in upstream history" >&2
echo "Available version range (last 20 commits):" >&2
cd "$BARE_REPO" && git log --all --oneline -20 -- "$UPSTREAM_PATH/Makefile" >&2
exit 1
fi

echo "Current commit: $CURRENT_COMMIT" >&2

# Extract the old version (current commit)
OLD_DIR="$ASSETS_DIR/${PACKAGE_NAME}_old"
rm -rf "$OLD_DIR"
mkdir -p "$OLD_DIR"

echo "Extracting old version to $OLD_DIR..." >&2
strip_level=$(echo "$UPSTREAM_PATH" | awk -F/ '{print NF}')
cd "$BARE_REPO" && git archive "$CURRENT_COMMIT" "$UPSTREAM_PATH/" | tar -x --strip-components=$strip_level -C "$OLD_DIR" 2>/dev/null || {
echo "Error: Failed to extract old version" >&2
exit 1
}

# Extract the new version (target commit)
NEW_DIR="$ASSETS_DIR/${PACKAGE_NAME}_new"
rm -rf "$NEW_DIR"
mkdir -p "$NEW_DIR"

echo "Extracting new version to $NEW_DIR..." >&2
cd "$BARE_REPO" && git archive "$TARGET_COMMIT" "$UPSTREAM_PATH/" | tar -x --strip-components=$strip_level -C "$NEW_DIR" 2>/dev/null || {
echo "Error: Failed to extract new version" >&2
exit 1
}

# Output summary to stdout
echo ""
echo "===== SETUP COMPLETE ====="
echo "Package: $PACKAGE_NAME"
echo "Current upstream commit: $CURRENT_COMMIT"
echo "Target upstream commit: $TARGET_COMMIT"
echo "Upstream path: $UPSTREAM_PATH"
echo "Old version snapshot: $OLD_DIR"
echo "New version snapshot: $NEW_DIR"
Loading
Loading