Archived
Public Access
Distribute kernel via Gitea Debian apt repo; track stable not mainline
- Publish .deb packages to Gitea's built-in Debian registry (apt source) instead of Releases; CI uploads to pool/stable/main and stops creating Releases. One apt source line serves amd64 and arm64. - Add linux-image-bbrv3 meta-package so `apt upgrade` tracks the latest stable kernel while older kernels stay installed for fallback. Its dependency is the actual built image package name (immune to localversion drift). - Add bbrv3-config package shipping the BBR+CAKE+ECN sysctl drop-in as a conffile (applied via postinst), replacing the installer's sysctl write. - Rewrite install.sh to add the apt source + signing key and install the meta package; keep the OS-version gate, status check and uninstall menu, plus an apt-mark hold escape hatch. - select-stable-kernel.sh: pick the highest stable point release whose series is below mainline and has a matching BBRv3 patch, so a freshly-cut series (latest stable == mainline, e.g. 7.1) is not built. Currently 7.0.12. - Exclude linux-libc-dev (clashes with the distro's headers) and drop the "by Joey" MODULE_DESCRIPTION step and release branding. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+119
-116
@@ -1,9 +1,9 @@
|
|||||||
name: 构建带有BBRv3的内核
|
name: 构建带有BBRv3的内核
|
||||||
|
|
||||||
# Gitea Actions reads workflows from .github/workflows/ (and .gitea/workflows/).
|
# Gitea Actions reads workflows from .github/workflows/ (and .gitea/workflows/).
|
||||||
# This workflow targets a self-hosted Gitea instance: release existence checks,
|
# This workflow targets a self-hosted Gitea instance. Kernel .deb packages are
|
||||||
# creation and asset uploads go through the Gitea REST API (curl), not the GitHub
|
# published to Gitea's built-in Debian package registry (an apt source), not to
|
||||||
# `gh` CLI. arm64 is cross-compiled on the x86_64 runner
|
# Releases. arm64 is cross-compiled on the x86_64 runner
|
||||||
# (CROSS_COMPILE=aarch64-linux-gnu-), so only a single ubuntu-latest runner is needed.
|
# (CROSS_COMPILE=aarch64-linux-gnu-), so only a single ubuntu-latest runner is needed.
|
||||||
|
|
||||||
on:
|
on:
|
||||||
@@ -13,14 +13,18 @@ on:
|
|||||||
- cron: "17 3 * * *"
|
- cron: "17 3 * * *"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# Gitea auto-injects GITHUB_TOKEN / GITEA_TOKEN into Actions jobs.
|
# Gitea Debian package registry for this owner, e.g.
|
||||||
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
# https://git.chilldove.com/api/packages/icePigeon/debian
|
||||||
# Gitea REST API base for this repo, e.g.
|
PKG_REGISTRY: ${{ github.server_url }}/api/packages/${{ github.repository_owner }}/debian
|
||||||
# https://git.chilldove.com/api/v1/repos/icePigeon/linux-kernel-bbrv3
|
PKG_USER: ${{ github.repository_owner }}
|
||||||
GITEA_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
# Dedicated token with write:package scope. The auto-injected GITHUB_TOKEN is
|
||||||
|
# not guaranteed to carry package-write permission, so this is a repo secret.
|
||||||
|
PKG_TOKEN: ${{ secrets.PKG_TOKEN }}
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
# Uploads authenticate via the PKG_TOKEN secret, not the auto-injected token,
|
||||||
|
# so no write permission is requested here.
|
||||||
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: bbrv3-kernel-build
|
group: bbrv3-kernel-build
|
||||||
@@ -31,59 +35,46 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
kernel_version: ${{ steps.plan.outputs.kernel_version }}
|
kernel_version: ${{ steps.plan.outputs.kernel_version }}
|
||||||
raw_kernel_version: ${{ steps.plan.outputs.raw_kernel_version }}
|
|
||||||
build_needed: ${{ steps.plan.outputs.build_needed }}
|
build_needed: ${{ steps.plan.outputs.build_needed }}
|
||||||
steps:
|
steps:
|
||||||
- name: 检查最新内核和已发布版本
|
- name: 检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 选择 stable 内核并检查 registry
|
||||||
id: plan
|
id: plan
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
raw_version=$(curl -fsSL https://www.kernel.org/finger_banner \
|
# Track an established stable series, never the freshly-cut top series
|
||||||
| awk -F: '/latest stable version/ {gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2; exit}')
|
# that still equals mainline. See scripts/select-stable-kernel.sh.
|
||||||
if [ -z "$raw_version" ]; then
|
version=$(bash scripts/select-stable-kernel.sh)
|
||||||
echo "Failed to read latest stable kernel version from kernel.org." >&2
|
echo "Selected stable kernel: $version"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
version="$raw_version"
|
|
||||||
if [[ "$version" =~ ^[0-9]+\.[0-9]+$ ]]; then
|
|
||||||
version="${version}.0"
|
|
||||||
fi
|
|
||||||
if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
||||||
echo "Unexpected stable kernel version: $raw_version" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "raw_kernel_version=$raw_version" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "kernel_version=$version" >> "$GITHUB_OUTPUT"
|
echo "kernel_version=$version" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
# Returns 0 when a release with the given tag already exists on Gitea.
|
# Already-published check against the registry's apt index (per arch).
|
||||||
release_exists() {
|
pkg_present() {
|
||||||
local tag="$1" code
|
local debarch="$1"
|
||||||
code=$(curl -sS -o /dev/null -w '%{http_code}' \
|
curl -fsSL ${PKG_TOKEN:+--user "$PKG_USER:$PKG_TOKEN"} \
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
"$PKG_REGISTRY/dists/stable/main/binary-$debarch/Packages" 2>/dev/null \
|
||||||
"$GITEA_API/releases/tags/$tag" || echo 000)
|
| grep -q "^Package: linux-image-$version-bbrv3$"
|
||||||
[ "$code" = "200" ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
missing=0
|
missing=0
|
||||||
for arch in x86_64 arm64; do
|
for da in amd64 arm64; do
|
||||||
tag="$arch-$version"
|
if pkg_present "$da"; then
|
||||||
if release_exists "$tag"; then
|
echo "linux-image-$version-bbrv3 ($da) already in registry."
|
||||||
echo "$tag already exists."
|
|
||||||
else
|
else
|
||||||
echo "$tag is missing."
|
echo "linux-image-$version-bbrv3 ($da) missing."
|
||||||
missing=1
|
missing=1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "$missing" -eq 0 ]; then
|
if [ "$missing" -eq 1 ]; then
|
||||||
echo "build_needed=false" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "All releases for $version already exist; ending workflow before build."
|
|
||||||
else
|
|
||||||
echo "build_needed=true" >> "$GITHUB_OUTPUT"
|
echo "build_needed=true" >> "$GITHUB_OUTPUT"
|
||||||
echo "At least one release for $version is missing; build will continue."
|
echo "At least one arch for $version is missing; build will continue."
|
||||||
|
else
|
||||||
|
echo "build_needed=false" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "All arches for $version already published; ending before build."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
build:
|
build:
|
||||||
@@ -94,39 +85,42 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
# Both targets build on a single x86_64 runner; arm64 is cross-compiled.
|
# Both targets build on a single x86_64 runner; arm64 is cross-compiled.
|
||||||
|
# is_primary builds the Architecture:all bbrv3-config package exactly once.
|
||||||
- arch: x86_64
|
- arch: x86_64
|
||||||
|
deb_arch: amd64
|
||||||
runs_on: ubuntu-latest
|
runs_on: ubuntu-latest
|
||||||
cross_compile: ""
|
cross_compile: ""
|
||||||
localversion: -bbrv3
|
localversion: -bbrv3
|
||||||
|
is_primary: "true"
|
||||||
- arch: arm64
|
- arch: arm64
|
||||||
|
deb_arch: arm64
|
||||||
runs_on: ubuntu-latest
|
runs_on: ubuntu-latest
|
||||||
cross_compile: aarch64-linux-gnu-
|
cross_compile: aarch64-linux-gnu-
|
||||||
localversion: -bbrv3
|
localversion: -bbrv3
|
||||||
|
is_primary: "false"
|
||||||
runs-on: ${{ matrix.runs_on }}
|
runs-on: ${{ matrix.runs_on }}
|
||||||
env:
|
env:
|
||||||
ARCH: ${{ matrix.arch }}
|
ARCH: ${{ matrix.arch }}
|
||||||
|
DEB_ARCH: ${{ matrix.deb_arch }}
|
||||||
KERNEL_VERSION: ${{ needs.preflight.outputs.kernel_version }}
|
KERNEL_VERSION: ${{ needs.preflight.outputs.kernel_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: 检查是否已发布
|
- name: 检出代码
|
||||||
id: check_release
|
uses: actions/checkout@v4
|
||||||
env:
|
|
||||||
TAG: ${{ matrix.arch }}-${{ needs.preflight.outputs.kernel_version }}
|
- name: 检查 registry 是否已发布
|
||||||
|
id: check_present
|
||||||
run: |
|
run: |
|
||||||
code=$(curl -sS -o /dev/null -w '%{http_code}' \
|
set -euo pipefail
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
if curl -fsSL ${PKG_TOKEN:+--user "$PKG_USER:$PKG_TOKEN"} \
|
||||||
"$GITEA_API/releases/tags/$TAG" || echo 000)
|
"$PKG_REGISTRY/dists/stable/main/binary-$DEB_ARCH/Packages" 2>/dev/null \
|
||||||
if [ "$code" = "200" ]; then
|
| grep -q "^Package: linux-image-$KERNEL_VERSION-bbrv3$"; then
|
||||||
echo "BUILD_NEEDED=false" >> "$GITHUB_ENV"
|
echo "BUILD_NEEDED=false" >> "$GITHUB_ENV"
|
||||||
echo "$TAG already exists; skipping build."
|
echo "linux-image-$KERNEL_VERSION-bbrv3 ($DEB_ARCH) already published; skipping."
|
||||||
else
|
else
|
||||||
echo "BUILD_NEEDED=true" >> "$GITHUB_ENV"
|
echo "BUILD_NEEDED=true" >> "$GITHUB_ENV"
|
||||||
echo "$TAG does not exist; building latest BBRv3 kernel."
|
echo "linux-image-$KERNEL_VERSION-bbrv3 ($DEB_ARCH) missing; building."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 检出代码
|
|
||||||
if: env.BUILD_NEEDED == 'true'
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 安装依赖项
|
- name: 安装依赖项
|
||||||
if: env.BUILD_NEEDED == 'true'
|
if: env.BUILD_NEEDED == 'true'
|
||||||
run: |
|
run: |
|
||||||
@@ -162,15 +156,6 @@ jobs:
|
|||||||
bash "$GITHUB_WORKSPACE/scripts/apply-bbrv3-port.sh"
|
bash "$GITHUB_WORKSPACE/scripts/apply-bbrv3-port.sh"
|
||||||
grep -n "BBR_VERSION" net/ipv4/tcp_bbr.c
|
grep -n "BBR_VERSION" net/ipv4/tcp_bbr.c
|
||||||
|
|
||||||
- name: 编译声明
|
|
||||||
if: env.BUILD_NEEDED == 'true'
|
|
||||||
working-directory: ./kernel/linux
|
|
||||||
run: |
|
|
||||||
grep -v "MODULE_DESCRIPTION" net/ipv4/tcp_bbr.c > net/ipv4/tcp_bbr.c.tmp
|
|
||||||
mv net/ipv4/tcp_bbr.c.tmp net/ipv4/tcp_bbr.c
|
|
||||||
echo 'MODULE_DESCRIPTION("TCP BBR v3 (Bottleneck Bandwidth and RTT) - Compiled & Optimized by Joey");' >> net/ipv4/tcp_bbr.c
|
|
||||||
tail -n 5 net/ipv4/tcp_bbr.c
|
|
||||||
|
|
||||||
- name: 更新 Makefile 中的版本号
|
- name: 更新 Makefile 中的版本号
|
||||||
if: env.BUILD_NEEDED == 'true'
|
if: env.BUILD_NEEDED == 'true'
|
||||||
working-directory: ./kernel/linux
|
working-directory: ./kernel/linux
|
||||||
@@ -219,66 +204,84 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
find ./kernel -maxdepth 1 -name 'linux-*.deb' -print | sort
|
find ./kernel -maxdepth 1 -name 'linux-*.deb' -print | sort
|
||||||
|
|
||||||
- name: 发布前复查是否已发布
|
- name: 构建 meta 与 config 包
|
||||||
if: env.BUILD_NEEDED == 'true'
|
if: env.BUILD_NEEDED == 'true'
|
||||||
env:
|
env:
|
||||||
TAG: ${{ matrix.arch }}-${{ needs.preflight.outputs.kernel_version }}
|
IS_PRIMARY: ${{ matrix.is_primary }}
|
||||||
run: |
|
|
||||||
code=$(curl -sS -o /dev/null -w '%{http_code}' \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
"$GITEA_API/releases/tags/$TAG" || echo 000)
|
|
||||||
if [ "$code" = "200" ]; then
|
|
||||||
echo "PUBLISH_NEEDED=false" >> "$GITHUB_ENV"
|
|
||||||
echo "$TAG was published while this job was running; skipping upload and release."
|
|
||||||
else
|
|
||||||
echo "PUBLISH_NEEDED=true" >> "$GITHUB_ENV"
|
|
||||||
echo "$TAG still missing; publishing this build."
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: 发布到 Gitea Release
|
|
||||||
if: env.BUILD_NEEDED == 'true' && env.PUBLISH_NEEDED == 'true'
|
|
||||||
env:
|
|
||||||
TAG: ${{ matrix.arch }}-${{ needs.preflight.outputs.kernel_version }}
|
|
||||||
TARGET_ARCH: ${{ matrix.arch }}
|
|
||||||
TARGET_SHA: ${{ github.sha }}
|
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
body="带有 BBRv3 的最新内核,适用于 $TARGET_ARCH 架构。Compiled & Optimized by Joey."
|
mkdir -p ./out
|
||||||
|
|
||||||
auth=(-H "Authorization: token $GITEA_TOKEN")
|
# Depend on the *actual* image package name, immune to localversion drift.
|
||||||
|
img_deb=$(find ./kernel -maxdepth 1 -name 'linux-image-*.deb' ! -name '*-dbg*' | sort | head -n1)
|
||||||
# Reuse an existing release for this tag, otherwise create it.
|
if [ -z "$img_deb" ]; then
|
||||||
release_id=$(curl -sS "${auth[@]}" "$GITEA_API/releases/tags/$TAG" | jq -r '.id // empty')
|
echo "No linux-image .deb found to base the meta-package on." >&2
|
||||||
if [ -z "$release_id" ]; then
|
exit 1
|
||||||
release_id=$(curl -sS "${auth[@]}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-X POST "$GITEA_API/releases" \
|
|
||||||
-d "$(jq -n \
|
|
||||||
--arg tag "$TAG" \
|
|
||||||
--arg target "$TARGET_SHA" \
|
|
||||||
--arg name "$TAG" \
|
|
||||||
--arg body "$body" \
|
|
||||||
'{tag_name:$tag, target_commitish:$target, name:$name, body:$body, draft:false, prerelease:false}')" \
|
|
||||||
| jq -r '.id // empty')
|
|
||||||
fi
|
fi
|
||||||
if [ -z "$release_id" ] || [ "$release_id" = "null" ]; then
|
img_pkg=$(dpkg-deb -f "$img_deb" Package)
|
||||||
echo "Failed to resolve or create Gitea release for $TAG" >&2
|
echo "Kernel image package: $img_pkg"
|
||||||
|
|
||||||
|
bash scripts/build-meta-package.sh "$KERNEL_VERSION" "$DEB_ARCH" "$img_pkg" ./out
|
||||||
|
|
||||||
|
# bbrv3-config is Architecture:all; build it once (on the primary arch).
|
||||||
|
if [ "$IS_PRIMARY" = "true" ]; then
|
||||||
|
bash scripts/build-config-package.sh ./out
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: 发布前复查是否已发布
|
||||||
|
if: env.BUILD_NEEDED == 'true'
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if curl -fsSL ${PKG_TOKEN:+--user "$PKG_USER:$PKG_TOKEN"} \
|
||||||
|
"$PKG_REGISTRY/dists/stable/main/binary-$DEB_ARCH/Packages" 2>/dev/null \
|
||||||
|
| grep -q "^Package: linux-image-$KERNEL_VERSION-bbrv3$"; then
|
||||||
|
echo "PUBLISH_NEEDED=false" >> "$GITHUB_ENV"
|
||||||
|
echo "Published while this job was running; skipping upload."
|
||||||
|
else
|
||||||
|
echo "PUBLISH_NEEDED=true" >> "$GITHUB_ENV"
|
||||||
|
echo "Still missing; publishing this build."
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: 发布到 Gitea Debian registry
|
||||||
|
if: env.BUILD_NEEDED == 'true' && env.PUBLISH_NEEDED == 'true'
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ -z "${PKG_TOKEN:-}" ]; then
|
||||||
|
echo "PKG_TOKEN secret is required to publish (needs write:package scope)." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Upload the kernel .deb packages as release assets.
|
# Gitea returns 201/202 on upload, 409 when the file already exists.
|
||||||
|
upload() {
|
||||||
|
local f="$1" code
|
||||||
|
code=$(curl -sS -o /dev/null -w '%{http_code}' \
|
||||||
|
--user "$PKG_USER:$PKG_TOKEN" --upload-file "$f" \
|
||||||
|
"$PKG_REGISTRY/pool/stable/main/upload" || echo 000)
|
||||||
|
case "$code" in
|
||||||
|
201|202) echo "Uploaded $(basename "$f") ($code)";;
|
||||||
|
409) echo "Already present $(basename "$f") (409)";;
|
||||||
|
*) echo "Upload failed: $(basename "$f") (HTTP $code)" >&2; return 1;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
assets=( ./kernel/linux-*.deb )
|
# Publish the kernel image and (x86_64) headers, plus the meta/config
|
||||||
if [ "${#assets[@]}" -eq 0 ]; then
|
# packages. Never linux-libc-dev (clashes with the distro's userspace
|
||||||
echo "No .deb assets found to upload for $TAG" >&2
|
# headers) and never *-dbg* packages.
|
||||||
|
assets=()
|
||||||
|
for f in ./kernel/linux-image-*.deb ./kernel/linux-headers-*.deb; do
|
||||||
|
case "$f" in *-dbg*) continue;; esac
|
||||||
|
assets+=("$f")
|
||||||
|
done
|
||||||
|
assets+=( ./out/*.deb )
|
||||||
|
|
||||||
|
if [ ${#assets[@]} -eq 0 ]; then
|
||||||
|
echo "No .deb assets found to upload." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for f in "${assets[@]}"; do
|
for f in "${assets[@]}"; do
|
||||||
name=$(basename "$f")
|
echo "Publishing $(basename "$f")"
|
||||||
echo "Uploading $name to release $TAG (id=$release_id)"
|
upload "$f"
|
||||||
curl -fsS "${auth[@]}" \
|
|
||||||
-X POST "$GITEA_API/releases/$release_id/assets?name=$name" \
|
|
||||||
-F "attachment=@$f" >/dev/null
|
|
||||||
done
|
done
|
||||||
echo "Published $TAG with ${#assets[@]} asset(s)."
|
echo "Published ${#assets[@]} package(s) for $KERNEL_VERSION ($DEB_ARCH)."
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# BBRv3 内核安装脚本
|
# BBRv3 内核安装脚本
|
||||||
|
|
||||||
一个用于 Debian/Ubuntu VPS 的 BBRv3 内核安装脚本。脚本会自动识别系统架构,从本仓库的 Gitea Releases 下载匹配的 BBRv3 内核 `.deb` 包并安装。内核默认启用 BBR 拥塞控制并内置 `sch_cake`;安装脚本会写入 `/etc/sysctl.d/99-bbrv3.conf`,把默认队列算法设为 `cake` 并开启 ECN(`net.ipv4.tcp_ecn=1`),安装并重启后 BBR + CAKE + ECN 自动生效。
|
一个用于 Debian/Ubuntu VPS 的 BBRv3 内核分发方案。内核 `.deb` 包发布到本仓库自建 Gitea 的 **Debian package registry(apt 源)**。安装脚本会自动识别架构、配置 apt 源并安装 `linux-image-bbrv3` meta-package,之后 `sudo apt upgrade` 即可自动跟随最新 stable 内核(旧内核保留以便回退)。内核默认启用 BBR 拥塞控制并内置 `sch_cake`;随包安装的 `bbrv3-config` 会写入 `/etc/sysctl.d/99-bbrv3.conf`,把默认队列算法设为 `cake` 并开启 ECN(`net.ipv4.tcp_ecn=1`),安装并重启后 BBR + CAKE + ECN 自动生效。
|
||||||
|
|
||||||
脚本入口:
|
脚本入口:
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ Debian testing/unstable 如缺少 `VERSION_ID`,脚本会按 `VERSION_CODENAME`
|
|||||||
运行脚本后进入交互菜单:
|
运行脚本后进入交互菜单:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
1. 安装或更新 BBR v3 内核(最新版)
|
1. 安装或更新 BBR v3 内核(最新版,apt 源自动跟随)
|
||||||
2. 安装指定版本
|
2. 安装指定版本
|
||||||
3. 检查 BBR v3 状态
|
3. 检查 BBR v3 状态
|
||||||
4. 卸载 BBR v3 内核
|
4. 卸载 BBR v3 内核
|
||||||
@@ -40,19 +40,25 @@ Debian testing/unstable 如缺少 `VERSION_ID`,脚本会按 `VERSION_CODENAME`
|
|||||||
本项目的构建目标是:
|
本项目的构建目标是:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
BBRv3 补丁固定,内核自动跟随 kernel.org 最新 stable 更新。
|
BBRv3 补丁固定,内核自动跟随 kernel.org stable 的小版本更新。
|
||||||
```
|
```
|
||||||
|
|
||||||
也就是说,BBR 实现不会在自动构建时偷偷更新;自动更新的是 Linux stable 内核版本。构建流程会把仓库内固定的 BBRv3 patch 应用到最新 stable 内核上。
|
BBR 实现不会在自动构建时偷偷更新;自动更新的是 Linux stable 内核的小版本。
|
||||||
|
|
||||||
当前 patch 选择规则:
|
**追踪的是成熟 stable,而非 mainline。** 一个新系列(如 `7.1`)刚发布时,kernel.org 的 “latest stable” 会瞬间等于 “latest mainline”——那其实还是尖端,不是经过 `.z` 打磨的 stable。因此构建脚本(`scripts/select-stable-kernel.sh`)只在满足以下**全部**条件的版本里取最高:
|
||||||
|
|
||||||
|
- 是带三段点号的点版本 `X.Y.Z`(排除刚发布、仅显示为 `X.Y` 的新系列);
|
||||||
|
- 系列 `X.Y` 严格低于当前 mainline(排除仍等于 mainline 的系列);
|
||||||
|
- 仓库存在对应的 `patches/bbrv3-linux-X.Y.patch`。
|
||||||
|
|
||||||
|
当前 patch:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
linux-7.0.y -> patches/bbrv3-linux-7.0.patch
|
patches/bbrv3-linux-7.0.patch # linux-7.0.y
|
||||||
linux-7.1.y -> patches/bbrv3-linux-7.1.patch
|
patches/bbrv3-linux-7.1.patch # linux-7.1.y
|
||||||
```
|
```
|
||||||
|
|
||||||
同一主线系列内的小版本更新会自动复用同一个 patch,例如 `7.0.11 -> 7.0.12`。如果内核跳到新的主线系列但仓库内还没有对应 patch,构建会直接失败,避免产出不可验证的内核包。
|
同系列小版本更新自动复用同一 patch(如 `7.0.11 -> 7.0.12`)。等新系列出了点版本、且 mainline 前移到再下一个系列,构建会自动接棒到新系列(前提是其 patch 已就位)。
|
||||||
|
|
||||||
## 安装最新版
|
## 安装最新版
|
||||||
|
|
||||||
@@ -64,12 +70,19 @@ linux-7.1.y -> patches/bbrv3-linux-7.1.patch
|
|||||||
|
|
||||||
脚本会:
|
脚本会:
|
||||||
|
|
||||||
- 检查系统是否为 Debian/Ubuntu,架构是否为 `x86_64` 或 `aarch64`。
|
- 检查系统是否为 Debian/Ubuntu,架构是否为 `x86_64` 或 `aarch64`,并拦截过旧系统。
|
||||||
- 从 Gitea Releases 获取当前架构匹配的最新版本。
|
- 配置 apt 源:导入 registry 签名公钥到 `/etc/apt/keyrings/`,写入 `/etc/apt/sources.list.d/bbrv3.list`。
|
||||||
- 下载内核 `.deb` 包,安装并更新引导配置。
|
- `apt-get install linux-image-bbrv3` 安装/升级到最新 stable(旧内核保留以便回退)。
|
||||||
- 提示是否重启。
|
- 提示是否重启。
|
||||||
|
|
||||||
如果访问私有仓库或遇到 Gitea API 限流,可先设置 token:
|
之后无需再跑脚本,直接 `sudo apt update && sudo apt upgrade` 即可跟随最新内核。**不希望内核被 `apt upgrade` 自动更换**时:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-mark hold linux-image-bbrv3 # 钉死,停止自动跟随
|
||||||
|
sudo apt-mark unhold linux-image-bbrv3 # 解钉,恢复自动跟随
|
||||||
|
```
|
||||||
|
|
||||||
|
如果 registry 为私有或拉取签名公钥受限,可先设置 token 再运行:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export GITEA_TOKEN=你的 Gitea Token
|
export GITEA_TOKEN=你的 Gitea Token
|
||||||
@@ -84,15 +97,30 @@ bash <(curl -fsSL https://git.chilldove.com/icePigeon/linux-kernel-bbrv3/raw/bra
|
|||||||
2. 安装指定版本
|
2. 安装指定版本
|
||||||
```
|
```
|
||||||
|
|
||||||
脚本会列出当前架构可用的 release tag,并按编号安装指定版本。
|
脚本会列出 apt 源中可用的内核包并按编号安装;装完可选择 `apt-mark hold` 钉死,避免被 `apt upgrade` 自动更换。
|
||||||
|
|
||||||
release tag 格式:
|
内核包名格式:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
x86_64-7.0.11
|
linux-image-7.0.12-bbrv3
|
||||||
arm64-7.0.11
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
也可手动安装:`sudo apt install linux-image-7.0.12-bbrv3`。
|
||||||
|
|
||||||
|
## 手动配置 apt 源(不想用脚本)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo install -d -m 0755 /etc/apt/keyrings
|
||||||
|
curl -fsSL https://git.chilldove.com/api/packages/icePigeon/debian/repository.key \
|
||||||
|
| sudo tee /etc/apt/keyrings/gitea-icePigeon.asc > /dev/null
|
||||||
|
echo "deb [signed-by=/etc/apt/keyrings/gitea-icePigeon.asc] https://git.chilldove.com/api/packages/icePigeon/debian stable main" \
|
||||||
|
| sudo tee /etc/apt/sources.list.d/bbrv3.list > /dev/null
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install linux-image-bbrv3
|
||||||
|
```
|
||||||
|
|
||||||
|
装完按需 `sudo reboot`。`bbrv3-config` 写入的 cake 默认队列需重启进新内核后才生效。
|
||||||
|
|
||||||
## 检查 BBRv3 状态
|
## 检查 BBRv3 状态
|
||||||
|
|
||||||
运行脚本后选择:
|
运行脚本后选择:
|
||||||
@@ -125,22 +153,25 @@ modinfo tcp_bbr 2>/dev/null | grep '^version:'
|
|||||||
4. 卸载 BBR v3 内核
|
4. 卸载 BBR v3 内核
|
||||||
```
|
```
|
||||||
|
|
||||||
脚本会卸载由本项目安装的 BBR v3 内核包(包名带 `-bbrv3` 后缀),删除 `/etc/sysctl.d/99-bbrv3.conf`,并更新引导配置。卸载后建议重启。
|
脚本会卸载由本项目安装的内核包(`linux-image-*-bbrv3` 与 meta 包 `linux-image-bbrv3`)及 `bbrv3-config`(purge 时带走 `/etc/sysctl.d/99-bbrv3.conf`),并移除 apt 源 `/etc/apt/sources.list.d/bbrv3.list` 与签名公钥;引导由内核包卸载钩子自动更新。卸载后建议重启。
|
||||||
|
|
||||||
## 内核包来源
|
## 内核包来源
|
||||||
|
|
||||||
`.deb` 内核包由 Gitea Actions 构建并发布到本仓库 Releases,提供 `x86_64` 与 `arm64` 两种标准 BBRv3 内核(arm64 在同一台 x86_64 runner 上交叉编译)。
|
`.deb` 内核包由 Gitea Actions 构建并发布到本仓库自建 Gitea 的 **Debian package registry**,提供 `amd64` 与 `arm64` 两种标准 BBRv3 内核(arm64 在同一台 x86_64 runner 上交叉编译)。一行 apt 源同时服务两种架构,apt 按本机架构自动取包。
|
||||||
|
|
||||||
构建流程会:
|
构建流程会:
|
||||||
|
|
||||||
- 读取 kernel.org 最新 stable 版本。
|
- 用 `scripts/select-stable-kernel.sh` 选定要追踪的 stable 版本(见上文「内核与 BBR 策略」)。
|
||||||
- 下载 `gregkh/linux` 对应 stable 分支。
|
- 下载 `gregkh/linux` 对应 stable 分支,应用仓库内固定 BBRv3 patch。
|
||||||
- 应用仓库内固定 BBRv3 patch。
|
- 默认启用 BBR,并把 `sch_cake` 编入内核(=y);`bbrv3-config` 包据此把默认队列设为 cake。
|
||||||
- 默认启用 BBR,并把 `sch_cake` 编入内核(=y),安装脚本据此把默认队列设为 cake。
|
- 构建 `linux-image-bbrv3`(meta,跟随最新)与 `bbrv3-config`(sysctl 配置)两个辅助包。
|
||||||
- 关闭 debug info,拒绝发布 `*-dbg*.deb` / `*-dbgsym*.deb`。
|
- 关闭 debug info,拒绝发布 `*-dbg*.deb` / `*-dbgsym*.deb`;不发布 `linux-libc-dev`(避免覆盖发行版头文件)。
|
||||||
|
- 发布到 registry 的 `stable/main`,已存在的版本会跳过。
|
||||||
|
|
||||||
构建不会自动更新 BBR patch 本身。
|
构建不会自动更新 BBR patch 本身。
|
||||||
|
|
||||||
|
发布所需:CI 配置一个有 `write:package` 权限的 `PKG_TOKEN` secret;Gitea 实例需启用 Packages → Debian registry。
|
||||||
|
|
||||||
## 免责声明
|
## 免责声明
|
||||||
|
|
||||||
内核升级有风险。安装前建议确认 VPS 控制台、救援模式或旧内核启动项可用。使用本项目构建或安装的内核造成的系统启动失败、网络异常或数据损失,由使用者自行承担。
|
内核升级有风险。安装前建议确认 VPS 控制台、救援模式或旧内核启动项可用。使用本项目构建或安装的内核造成的系统启动失败、网络异常或数据损失,由使用者自行承担。
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# BBRv3 内核分发改造:迁移到 Gitea Debian apt 源
|
||||||
|
|
||||||
|
日期:2026-06-17
|
||||||
|
状态:已确认,进入实现
|
||||||
|
|
||||||
|
## 背景与目标
|
||||||
|
|
||||||
|
当前分发链路是「Gitea Releases 存 `.deb` + `curl|bash` 安装脚本手动 `dpkg -i`」。
|
||||||
|
目标是改成 **apt 源**,让用户 `apt upgrade` 即可时刻跟随最新 stable 内核,并顺带提升
|
||||||
|
安全性(GPG 签名、保留旧内核可回退、apt 解依赖)。
|
||||||
|
|
||||||
|
构建层(CI 每天编译 `.deb`)保留不变;本次只替换**分发/更新层**。
|
||||||
|
|
||||||
|
## 关键决策
|
||||||
|
|
||||||
|
1. **分发层 = Gitea 自带 Debian package registry**(实例已自建 Gitea,自动 PGP 签名)。
|
||||||
|
- 上传:`PUT {server}/api/packages/{owner}/debian/pool/{dist}/{comp}/upload`
|
||||||
|
- 用户源:`deb [signed-by=…] {server}/api/packages/{owner}/debian stable main`
|
||||||
|
- 公钥:`{server}/api/packages/{owner}/debian/repository.key`
|
||||||
|
- 统一用 `stable/main` 一个桶;架构由 `.deb` 自带,apt 按 `amd64/arm64` 自动取。
|
||||||
|
2. **更新策略 = 自动跟最新**:构建 meta-package `linux-image-bbrv3`,`Depends` 当前最新
|
||||||
|
`linux-image-<ver>-bbrv3`,版本随内核版本走。`apt upgrade` 跟最新,**旧内核保留可回退**。
|
||||||
|
谨慎用户 `apt-mark hold linux-image-bbrv3` 钉死。
|
||||||
|
3. **sysctl 配置入包**:新增 `bbrv3-config`(`Architecture: all`),把
|
||||||
|
`/etc/sysctl.d/99-bbrv3.conf`(BBR + CAKE + ECN)作为 conffile 随包安装,`postinst`
|
||||||
|
跑 `sysctl --system`。装包即配置,不再依赖脚本。`meta` 依赖它。
|
||||||
|
4. **迁移 = 干净切换 + 保留入口**:CI 只发 registry,停发 Releases;`install.sh` 仍是同一
|
||||||
|
`curl|bash` 入口,菜单不变,动作改成 apt(加源 + 导 key + 装 meta)。
|
||||||
|
5. **只发 `linux-image` / `linux-headers`,排除 `linux-libc-dev`**(避免覆盖发行版 userspace
|
||||||
|
头文件)与 `*-dbg*`。
|
||||||
|
|
||||||
|
## 本次新增需求(用户补充)
|
||||||
|
|
||||||
|
6. **追踪 stable 而非 mainline**。根因:7.1.0 刚发布时 kernel.org「latest stable」== mainline
|
||||||
|
== 7.1,旧 preflight 直接取它就抓到 7.1;成熟 stable 实为 7.0.12。
|
||||||
|
**修法**:`scripts/select-stable-kernel.sh` 从 `finger_banner` 选「带三段点号 `X.Y.Z`、
|
||||||
|
`X.Y` 严格 `<` mainline、且仓库存在 `patches/bbrv3-linux-X.Y.patch`」中的最高版本。
|
||||||
|
三段号排除刚发布的 `7.1`,patch 闸门排除无补丁的 6.x → 当前命中 `7.0.12`。系列自动接棒。
|
||||||
|
7. **删除 joey 标签**:移除 `build.yml` 的「编译声明」步骤(注入 `Compiled & Optimized by
|
||||||
|
Joey` 的 `MODULE_DESCRIPTION`),让上游 patch 自带描述生效;Release 发布块里的 joey 文案
|
||||||
|
随该块一并删除。
|
||||||
|
|
||||||
|
## 改动清单
|
||||||
|
|
||||||
|
- `scripts/select-stable-kernel.sh`(新)— 选 stable 目标版本。
|
||||||
|
- `scripts/build-config-package.sh`(新)— 构建 `bbrv3-config_*_all.deb`。
|
||||||
|
- `scripts/build-meta-package.sh`(新)— 构建 `linux-image-bbrv3_<ver>_<arch>.deb`,依赖项
|
||||||
|
取自实际产出的内核包名(`dpkg-deb -f`),避免 localversion 后缀漂移。
|
||||||
|
- `.github/workflows/build.yml`(改)— preflight 用选择脚本 + 查 registry index 判存在;删
|
||||||
|
joey 步骤;构建 meta/config;发布改 registry `--upload-file`;停发 Release。
|
||||||
|
- `install.sh`(改)— 菜单动作改 apt:加源/导 key/装 meta(1)、装指定版本(2)、状态检查
|
||||||
|
(3,不变)、卸载并删源(4)。保留 OS 版本闸门、依赖安装、sudo 兜底。
|
||||||
|
- `README.md`(改)— 改写「内核来源/BBR 策略/菜单」,新增 apt 用法与 `apt-mark hold`。
|
||||||
|
|
||||||
|
## 前提(落地前核对)
|
||||||
|
|
||||||
|
- `git.chilldove.com` 启用 Packages → Debian registry(新版 Gitea 默认开)。
|
||||||
|
- CI 需 `PKG_TOKEN` secret(有 `write:package` scope);自动注入的 `GITHUB_TOKEN` 不保证有
|
||||||
|
包写权限。
|
||||||
|
- registry 保留历史版本以支撑「装指定版本」;将来再议 retention。
|
||||||
|
|
||||||
|
## 不做(YAGNI)
|
||||||
|
|
||||||
|
- 不搭 aptly/reprepro、不自管 GPG key(Gitea 全包)。
|
||||||
|
- 不做过渡期双发布。
|
||||||
|
- 不按发行版分多 distribution。
|
||||||
+120
-258
@@ -17,23 +17,29 @@ if ! command -v sudo &> /dev/null; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 检查并安装必要的依赖(命令名与 apt 包名不一致时做映射)
|
# 检查并安装必要依赖(apt 源方式只需 curl + ca-certificates)
|
||||||
declare -A CMD_PKG=( [curl]=curl [wget]=wget [dpkg]=dpkg [awk]=gawk [jq]=jq [sysctl]=procps )
|
declare -A CMD_PKG=( [curl]=curl )
|
||||||
APT_UPDATED=0
|
APT_UPDATED=0
|
||||||
|
ensure_pkg() {
|
||||||
|
local pkg="$1"
|
||||||
|
[[ "$APT_UPDATED" == "0" ]] && { sudo apt-get update > /dev/null 2>&1; APT_UPDATED=1; }
|
||||||
|
sudo apt-get install -y "$pkg" > /dev/null 2>&1
|
||||||
|
}
|
||||||
for cmd in "${!CMD_PKG[@]}"; do
|
for cmd in "${!CMD_PKG[@]}"; do
|
||||||
if ! command -v "$cmd" &> /dev/null; then
|
if ! command -v "$cmd" &> /dev/null; then
|
||||||
echo -e "\033[33m缺少依赖:$cmd,正在安装 ${CMD_PKG[$cmd]}...\033[0m"
|
echo -e "\033[33m缺少依赖:$cmd,正在安装 ${CMD_PKG[$cmd]}...\033[0m"
|
||||||
[[ "$APT_UPDATED" == "0" ]] && { sudo apt-get update > /dev/null 2>&1; APT_UPDATED=1; }
|
ensure_pkg "${CMD_PKG[$cmd]}"
|
||||||
sudo apt-get install -y "${CMD_PKG[$cmd]}" > /dev/null 2>&1
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
# 关键依赖必须就绪,否则给出明确报错(而不是后续 jq/curl 的迷惑错误)
|
# HTTPS 根证书:apt update / 拉取签名公钥都需要
|
||||||
for cmd in curl wget jq; do
|
if ! dpkg -s ca-certificates &> /dev/null; then
|
||||||
if ! command -v "$cmd" &> /dev/null; then
|
echo -e "\033[33m缺少 ca-certificates,正在安装...\033[0m"
|
||||||
echo -e "\033[31m关键依赖 $cmd 安装失败,无法继续。请手动安装后重试。\033[0m"
|
ensure_pkg ca-certificates
|
||||||
|
fi
|
||||||
|
if ! command -v curl &> /dev/null; then
|
||||||
|
echo -e "\033[31m关键依赖 curl 安装失败,无法继续。请手动安装后重试。\033[0m"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
|
|
||||||
# 检测系统架构
|
# 检测系统架构
|
||||||
ARCH=$(uname -m)
|
ARCH=$(uname -m)
|
||||||
@@ -42,76 +48,27 @@ if [[ "$ARCH" != "aarch64" && "$ARCH" != "x86_64" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Gitea 仓库坐标(自建实例 git.chilldove.com)
|
# Gitea 仓库 / Debian package registry 坐标(自建实例 git.chilldove.com)
|
||||||
GITEA_HOST="https://git.chilldove.com"
|
GITEA_HOST="https://git.chilldove.com"
|
||||||
GITEA_OWNER="icePigeon"
|
GITEA_OWNER="icePigeon"
|
||||||
GITEA_REPO="linux-kernel-bbrv3"
|
# Gitea 自带 Debian registry:apt 源 + 自动 PGP 签名
|
||||||
# Gitea Releases API
|
REG_BASE="$GITEA_HOST/api/packages/$GITEA_OWNER/debian"
|
||||||
RELEASES_API="$GITEA_HOST/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/releases"
|
REG_DIST="stable"
|
||||||
# 可选:访问私有仓库或提升 Gitea API 限额(支持 GITEA_TOKEN / GITHUB_TOKEN / GH_TOKEN)
|
REG_COMP="main"
|
||||||
GITEA_API_TOKEN="${GITEA_TOKEN:-${GITHUB_TOKEN:-${GH_TOKEN:-}}}"
|
KEYRING="/etc/apt/keyrings/gitea-$GITEA_OWNER.asc"
|
||||||
# 安装后写入的默认网络栈配置(BBR 拥塞控制 + CAKE 队列)
|
SOURCE_LIST="/etc/apt/sources.list.d/bbrv3.list"
|
||||||
|
# 跟随最新 stable 的 meta-package;sysctl 配置由 bbrv3-config 包负责
|
||||||
|
META_PKG="linux-image-bbrv3"
|
||||||
SYSCTL_DROPIN="/etc/sysctl.d/99-bbrv3.conf"
|
SYSCTL_DROPIN="/etc/sysctl.d/99-bbrv3.conf"
|
||||||
|
# 可选:访问私有仓库时给拉取签名公钥用(支持 GITEA_TOKEN / GITHUB_TOKEN / GH_TOKEN)
|
||||||
|
GITEA_API_TOKEN="${GITEA_TOKEN:-${GITHUB_TOKEN:-${GH_TOKEN:-}}}"
|
||||||
|
|
||||||
api_get() {
|
# 把 uname -m 映射成 Debian 架构名(apt 用 amd64/arm64)
|
||||||
local url="$1"
|
get_deb_arch() {
|
||||||
# 不加 -f:HTTP >= 400 时保留 JSON 错误体({"message":...}),交给
|
if [[ "$ARCH" == "aarch64" ]]; then
|
||||||
# check_release_api_response 解析并给出 token 提示;网络层失败仍会非零退出。
|
echo "arm64"
|
||||||
if [[ -n "$GITEA_API_TOKEN" ]]; then
|
|
||||||
curl -sSL \
|
|
||||||
-H "Authorization: token $GITEA_API_TOKEN" \
|
|
||||||
-H "Accept: application/json" \
|
|
||||||
"$url"
|
|
||||||
else
|
else
|
||||||
curl -sSL "$url"
|
echo "amd64"
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 分页拉取全部 release(Gitea 单页上限为 50),合并成一个 JSON 数组返回
|
|
||||||
fetch_all_releases() {
|
|
||||||
local page=1 combined="[]" data count
|
|
||||||
while :; do
|
|
||||||
data=$(api_get "$RELEASES_API?limit=50&page=$page") || return 1
|
|
||||||
# 出错或非数组(例如 {"message":...})时原样返回,交给 check_release_api_response 处理
|
|
||||||
if ! echo "$data" | jq -e 'type=="array"' > /dev/null 2>&1; then
|
|
||||||
printf '%s' "$data"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
count=$(echo "$data" | jq 'length')
|
|
||||||
combined=$(jq -n --argjson a "$combined" --argjson b "$data" '$a + $b')
|
|
||||||
[ "$count" -lt 50 ] && break
|
|
||||||
page=$((page + 1))
|
|
||||||
[ "$page" -gt 20 ] && break
|
|
||||||
done
|
|
||||||
printf '%s' "$combined"
|
|
||||||
}
|
|
||||||
|
|
||||||
# 下载 release 资源;存在 token 时带上鉴权头以支持私有仓库
|
|
||||||
wget_asset() {
|
|
||||||
local url="$1"
|
|
||||||
if [[ -n "$GITEA_API_TOKEN" ]]; then
|
|
||||||
wget -q --show-progress --header="Authorization: token $GITEA_API_TOKEN" "$url" -P /tmp/
|
|
||||||
else
|
|
||||||
wget -q --show-progress "$url" -P /tmp/
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
check_release_api_response() {
|
|
||||||
local response="$1"
|
|
||||||
local api_message=""
|
|
||||||
api_message=$(echo "$response" | jq -r 'if type=="object" then .message // "" else "" end')
|
|
||||||
|
|
||||||
if [[ -n "$api_message" ]]; then
|
|
||||||
echo -e "\033[31mGitea API 返回错误:$api_message\033[0m"
|
|
||||||
if echo "$api_message" | grep -qiE "rate limit|not found|permission|unauthor"; then
|
|
||||||
echo -e "\033[33m提示:私有仓库或受限访问可先执行 export GITEA_TOKEN=你的令牌,再重新运行脚本。\033[0m"
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! echo "$response" | jq -e 'type=="array"' > /dev/null 2>&1; then
|
|
||||||
echo -e "\033[31mGitea API 返回数据格式异常,无法继续。\033[0m"
|
|
||||||
return 1
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,95 +137,36 @@ assert_supported_kernel_install_system() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# 返回当前已安装的标准 BBRv3 内核版本(忽略遗留的 -max 包)
|
# 函数:配置 apt 源(导入签名公钥 + 写 sources.list + apt update)
|
||||||
get_installed_version() {
|
setup_apt_source() {
|
||||||
dpkg -l 2>/dev/null \
|
echo -e "\033[36m正在配置 BBRv3 apt 源...\033[0m"
|
||||||
| awk '/^ii/ && $2 ~ /^linux-image-/ && $2 ~ /-bbrv3$/ {sub(/^linux-image-/, "", $2); print $2}' \
|
sudo install -d -m 0755 /etc/apt/keyrings
|
||||||
| sort -V | tail -n 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# 把 uname -m 映射成 release tag 的架构前缀
|
# 拉取 Gitea registry 的签名公钥(armored,可直接用作 signed-by)
|
||||||
get_arch_filter() {
|
local key_args=()
|
||||||
if [[ "$ARCH" == "aarch64" ]]; then
|
[[ -n "$GITEA_API_TOKEN" ]] && key_args=(-H "Authorization: token $GITEA_API_TOKEN")
|
||||||
echo "arm64"
|
if ! curl -fsSL "${key_args[@]}" "$REG_BASE/repository.key" | sudo tee "$KEYRING" > /dev/null; then
|
||||||
elif [[ "$ARCH" == "x86_64" ]]; then
|
echo -e "\033[31m下载仓库签名公钥失败:$REG_BASE/repository.key\033[0m"
|
||||||
echo "x86_64"
|
echo -e "\033[33m提示:私有仓库可先 export GITEA_TOKEN=你的令牌 再重试。\033[0m"
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 由 release tag(如 x86_64-7.0.12)推导已安装包应有的版本串
|
|
||||||
get_expected_installed_version() {
|
|
||||||
local tag="$1"
|
|
||||||
local version
|
|
||||||
version="${tag#x86_64-}"
|
|
||||||
version="${version#arm64-}"
|
|
||||||
echo "${version}-bbrv3"
|
|
||||||
}
|
|
||||||
|
|
||||||
# 函数:智能更新引导加载程序
|
|
||||||
update_bootloader() {
|
|
||||||
echo -e "\033[36m正在更新引导加载程序...\033[0m"
|
|
||||||
if command -v update-grub &> /dev/null; then
|
|
||||||
echo -e "\033[33m检测到 GRUB,正在执行 update-grub...\033[0m"
|
|
||||||
if sudo update-grub; then
|
|
||||||
echo -e "\033[1;32mGRUB 更新成功!\033[0m"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo -e "\033[1;31mGRUB 更新失败!\033[0m"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
if [[ ! -s "$KEYRING" ]]; then
|
||||||
echo -e "\033[33m未找到 'update-grub'。您的系统可能使用 U-Boot 或其他引导程序。\033[0m"
|
echo -e "\033[31m签名公钥为空,无法继续。\033[0m"
|
||||||
echo -e "\033[33m在许多 ARM 系统上,内核安装包会自动处理引导更新,通常无需手动操作。\033[0m"
|
|
||||||
echo -e "\033[33m如果重启后新内核未生效,您可能需要手动更新引导配置,请参考您系统的文档。\033[0m"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 函数:安装后写入默认网络栈(BBR + CAKE + ECN)。内核编译期默认队列没有 cake 选项,
|
|
||||||
# 因此用 sysctl drop-in 把默认队列设为 cake;sch_cake 已内置,重启进新内核后生效。
|
|
||||||
apply_default_network_stack() {
|
|
||||||
if sudo tee "$SYSCTL_DROPIN" > /dev/null <<'EOF'
|
|
||||||
# Managed by linux-kernel-bbrv3 installer
|
|
||||||
net.core.default_qdisc = cake
|
|
||||||
net.ipv4.tcp_congestion_control = bbr
|
|
||||||
net.ipv4.tcp_ecn = 1
|
|
||||||
EOF
|
|
||||||
then
|
|
||||||
echo -e "\033[1;32m✔ 已写入默认网络栈配置(BBR + CAKE + ECN):$SYSCTL_DROPIN\033[0m"
|
|
||||||
# 当前内核若已支持则立即生效;否则仅写入,重启进新内核后生效。
|
|
||||||
sudo sysctl -p "$SYSCTL_DROPIN" > /dev/null 2>&1 || true
|
|
||||||
else
|
|
||||||
echo -e "\033[33m提示:写入 $SYSCTL_DROPIN 失败,可手动设置 net.core.default_qdisc=cake。\033[0m"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 函数:安全地安装下载的包
|
|
||||||
install_packages() {
|
|
||||||
if ! ls /tmp/linux-*.deb &> /dev/null; then
|
|
||||||
echo -e "\033[31m错误:未在 /tmp 目录下找到内核文件,安装中止。\033[0m"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for deb_file in /tmp/linux-*.deb; do
|
echo "deb [signed-by=$KEYRING] $REG_BASE $REG_DIST $REG_COMP" | sudo tee "$SOURCE_LIST" > /dev/null
|
||||||
if ! dpkg-deb -I "$deb_file" > /dev/null 2>&1; then
|
echo -e "\033[1;32m✔ 已写入 apt 源:$SOURCE_LIST\033[0m"
|
||||||
echo -e "\033[31m当前系统无法读取安装包:$deb_file\033[0m"
|
|
||||||
echo -e "\033[33m可能原因:dpkg 版本过旧,不支持该压缩格式。建议升级 dpkg 后重试。\033[0m"
|
if ! sudo apt-get update; then
|
||||||
|
echo -e "\033[31mapt-get update 失败,请检查网络或 registry 是否可访问。\033[0m"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
done
|
}
|
||||||
|
|
||||||
echo -e "\033[36m开始卸载旧版内核... \033[0m"
|
# 函数:提示重启
|
||||||
INSTALLED_PACKAGES=$(dpkg -l | grep -- '-bbrv3' | awk '{print $2}' | tr '\n' ' ')
|
prompt_reboot() {
|
||||||
if [[ -n "$INSTALLED_PACKAGES" ]]; then
|
echo -n -e "\033[33m需要重启系统来加载新内核。是否立即重启? (y/N): \033[0m"
|
||||||
sudo apt-get remove --purge $INSTALLED_PACKAGES -y > /dev/null 2>&1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\033[36m开始安装新内核... \033[0m"
|
|
||||||
if sudo dpkg -i /tmp/linux-*.deb && update_bootloader; then
|
|
||||||
echo -e "\033[1;32m内核安装并配置完成!\033[0m"
|
|
||||||
apply_default_network_stack
|
|
||||||
echo -n -e "\033[33m需要重启系统来加载新内核。是否立即重启? (y/n): \033[0m"
|
|
||||||
read -r REBOOT_NOW
|
read -r REBOOT_NOW
|
||||||
if [[ "$REBOOT_NOW" == "y" || "$REBOOT_NOW" == "Y" ]]; then
|
if [[ "$REBOOT_NOW" == "y" || "$REBOOT_NOW" == "Y" ]]; then
|
||||||
echo -e "\033[36m系统即将重启...\033[0m"
|
echo -e "\033[36m系统即将重启...\033[0m"
|
||||||
@@ -276,126 +174,99 @@ install_packages() {
|
|||||||
else
|
else
|
||||||
echo -e "\033[33m操作完成。请记得稍后手动重启 ('sudo reboot') 来应用新内核。\033[0m"
|
echo -e "\033[33m操作完成。请记得稍后手动重启 ('sudo reboot') 来应用新内核。\033[0m"
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
echo -e "\033[1;31m内核安装或引导更新失败!系统可能处于不稳定状态。请不要重启并寻求手动修复!\033[0m"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 函数:检查并安装最新版本
|
# 函数:安装或更新到最新版(meta-package 自动跟随最新 stable)
|
||||||
install_latest_version() {
|
install_latest_version() {
|
||||||
local arch_filter
|
|
||||||
local expected_version
|
|
||||||
|
|
||||||
assert_supported_kernel_install_system || return 1
|
assert_supported_kernel_install_system || return 1
|
||||||
|
setup_apt_source || return 1
|
||||||
|
|
||||||
echo -e "\033[36m正在从 Gitea 获取最新版本信息...\033[0m"
|
echo -e "\033[36m正在安装/升级 $META_PKG(自动跟随最新 stable,旧内核会保留以便回退)...\033[0m"
|
||||||
RELEASE_DATA=$(fetch_all_releases)
|
# 内核包的 postinst 会自动更新引导(update-grub / kernel-install),无需手动处理;
|
||||||
if [[ -z "$RELEASE_DATA" ]]; then
|
# bbrv3-config 的 postinst 会写入并应用 BBR + CAKE + ECN 的 sysctl 配置。
|
||||||
echo -e "\033[31m从 Gitea 获取版本信息失败。请检查网络连接或 API 状态。\033[0m"
|
if sudo apt-get install -y "$META_PKG"; then
|
||||||
|
echo -e "\033[1;32m内核安装并配置完成!默认网络栈:BBR + CAKE + ECN。\033[0m"
|
||||||
|
echo -e "\033[33m如不希望以后 apt upgrade 自动更换内核,可执行:sudo apt-mark hold $META_PKG\033[0m"
|
||||||
|
prompt_reboot
|
||||||
|
else
|
||||||
|
echo -e "\033[1;31m内核安装失败!系统未变更内核,可重试或检查上面的 apt 报错。\033[0m"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
check_release_api_response "$RELEASE_DATA" || return 1
|
|
||||||
|
|
||||||
arch_filter=$(get_arch_filter)
|
|
||||||
LATEST_TAG_NAME=$(echo "$RELEASE_DATA" | jq -r --arg filter "$arch_filter" '
|
|
||||||
map(
|
|
||||||
select(.tag_name | test("^" + $filter + "-[0-9]"; "i"))
|
|
||||||
| select(.tag_name | endswith("-max") | not)
|
|
||||||
)
|
|
||||||
| sort_by(.published_at)
|
|
||||||
| .[-1].tag_name
|
|
||||||
')
|
|
||||||
|
|
||||||
if [[ -z "$LATEST_TAG_NAME" || "$LATEST_TAG_NAME" == "null" ]]; then
|
|
||||||
echo -e "\033[31m未找到适合当前架构 ($ARCH) 的最新版本。\033[0m"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
echo -e "\033[36m检测到最新版本:\033[0m\033[1;32m$LATEST_TAG_NAME\033[0m"
|
|
||||||
|
|
||||||
INSTALLED_VERSION=$(get_installed_version)
|
|
||||||
echo -e "\033[36m当前已安装版本:\033[0m\033[1;32m${INSTALLED_VERSION:-"未安装"}\033[0m"
|
|
||||||
|
|
||||||
expected_version=$(get_expected_installed_version "$LATEST_TAG_NAME")
|
|
||||||
|
|
||||||
if [[ -n "$INSTALLED_VERSION" && "$INSTALLED_VERSION" == "$expected_version" ]]; then
|
|
||||||
echo -e "\033[1;32m(o'▽'o) 您已安装最新 BBR v3 内核,无需更新!\033[0m"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\033[33m发现新版本或未安装内核,准备下载...\033[0m"
|
|
||||||
ASSET_URLS=$(echo "$RELEASE_DATA" | jq -r --arg tag "$LATEST_TAG_NAME" '
|
|
||||||
.[] | select(.tag_name == $tag) | .assets[].browser_download_url
|
|
||||||
| select(test("(-dbg_|-dbgsym_)"; "i") | not)
|
|
||||||
')
|
|
||||||
|
|
||||||
rm -f /tmp/linux-*.deb
|
|
||||||
|
|
||||||
for URL in $ASSET_URLS; do
|
|
||||||
echo -e "\033[36m正在下载文件:$URL\033[0m"
|
|
||||||
wget_asset "$URL" || { echo -e "\033[31m下载失败:$URL\033[0m"; return 1; }
|
|
||||||
done
|
|
||||||
|
|
||||||
install_packages
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 函数:安装指定版本
|
# 函数:安装指定版本(从 apt 源里选一个具体的内核版本)
|
||||||
install_specific_version() {
|
install_specific_version() {
|
||||||
local arch_filter
|
|
||||||
|
|
||||||
assert_supported_kernel_install_system || return 1
|
assert_supported_kernel_install_system || return 1
|
||||||
|
setup_apt_source || return 1
|
||||||
|
|
||||||
RELEASE_DATA=$(fetch_all_releases)
|
echo -e "\033[36m正在从 apt 源获取可用版本...\033[0m"
|
||||||
if [[ -z "$RELEASE_DATA" ]]; then
|
# 列出仓库中所有带版本号的 BBRv3 内核包(排除无版本号的 meta 包本身)
|
||||||
echo -e "\033[31m从 Gitea 获取版本信息失败。请检查网络连接或 API 状态。\033[0m"
|
mapfile -t PKGS < <(apt-cache pkgnames 2>/dev/null \
|
||||||
return 1
|
| grep -E '^linux-image-[0-9].+-bbrv3$' | sort -V)
|
||||||
fi
|
|
||||||
check_release_api_response "$RELEASE_DATA" || return 1
|
|
||||||
|
|
||||||
arch_filter=$(get_arch_filter)
|
if [[ ${#PKGS[@]} -eq 0 ]]; then
|
||||||
MATCH_TAGS=$(echo "$RELEASE_DATA" | jq -r --arg filter "$arch_filter" '
|
echo -e "\033[31m仓库中未找到可用的 BBRv3 内核版本。\033[0m"
|
||||||
.[]
|
|
||||||
| select(.tag_name | test("^" + $filter + "-[0-9]"; "i"))
|
|
||||||
| select(.tag_name | endswith("-max") | not)
|
|
||||||
| .tag_name
|
|
||||||
')
|
|
||||||
|
|
||||||
if [[ -z "$MATCH_TAGS" ]]; then
|
|
||||||
echo -e "\033[31m未找到适合当前架构的可用版本。\033[0m"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\033[36m以下为适用于当前架构的可用版本:\033[0m"
|
echo -e "\033[36m以下为可用的内核版本:\033[0m"
|
||||||
IFS=$'\n' read -rd '' -a TAG_ARRAY <<<"$MATCH_TAGS"
|
for i in "${!PKGS[@]}"; do
|
||||||
|
echo -e "\033[33m $((i+1)). ${PKGS[$i]}\033[0m"
|
||||||
for i in "${!TAG_ARRAY[@]}"; do
|
|
||||||
echo -e "\033[33m $((i+1)). ${TAG_ARRAY[$i]}\033[0m"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo -n -e "\033[36m请输入要安装的版本编号(例如 1):\033[0m"
|
echo -n -e "\033[36m请输入要安装的版本编号(例如 1):\033[0m"
|
||||||
read -r CHOICE
|
read -r CHOICE
|
||||||
|
if ! [[ "$CHOICE" =~ ^[0-9]+$ ]] || (( CHOICE < 1 || CHOICE > ${#PKGS[@]} )); then
|
||||||
if ! [[ "$CHOICE" =~ ^[0-9]+$ ]] || (( CHOICE < 1 || CHOICE > ${#TAG_ARRAY[@]} )); then
|
|
||||||
echo -e "\033[31m输入无效编号,取消操作。\033[0m"
|
echo -e "\033[31m输入无效编号,取消操作。\033[0m"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
INDEX=$((CHOICE-1))
|
local pkg="${PKGS[$((CHOICE-1))]}"
|
||||||
SELECTED_TAG="${TAG_ARRAY[$INDEX]}"
|
echo -e "\033[36m已选择:\033[0m\033[1;32m$pkg\033[0m"
|
||||||
echo -e "\033[36m已选择版本:\033[0m\033[1;32m$SELECTED_TAG\033[0m"
|
|
||||||
|
|
||||||
ASSET_URLS=$(echo "$RELEASE_DATA" | jq -r --arg tag "$SELECTED_TAG" '
|
if sudo apt-get install -y "$pkg"; then
|
||||||
.[] | select(.tag_name == $tag) | .assets[].browser_download_url
|
echo -e "\033[1;32m已安装 $pkg。\033[0m"
|
||||||
| select(test("(-dbg_|-dbgsym_)"; "i") | not)
|
# 装指定版本通常是想钉死,提示如何阻止 apt 自动更换内核
|
||||||
')
|
if dpkg -s "$META_PKG" &> /dev/null; then
|
||||||
|
echo -n -e "\033[33m检测到已安装 $META_PKG,是否钉死当前内核、阻止 apt upgrade 自动更换? (y/N): \033[0m"
|
||||||
|
read -r HOLD_NOW
|
||||||
|
if [[ "$HOLD_NOW" == "y" || "$HOLD_NOW" == "Y" ]]; then
|
||||||
|
sudo apt-mark hold "$META_PKG" "$pkg"
|
||||||
|
echo -e "\033[1;32m已钉死:$META_PKG $pkg(解钉:sudo apt-mark unhold ...)\033[0m"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
prompt_reboot
|
||||||
|
else
|
||||||
|
echo -e "\033[1;31m安装 $pkg 失败!请检查上面的 apt 报错。\033[0m"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
rm -f /tmp/linux-*.deb
|
# 函数:卸载本项目安装的所有内容(内核包 + meta + config),并移除 apt 源
|
||||||
|
uninstall_bbrv3() {
|
||||||
|
# 带 -bbrv3 后缀的包既包含具体内核(linux-image-7.0.x-bbrv3)也包含 meta(linux-image-bbrv3)
|
||||||
|
local pkgs
|
||||||
|
pkgs=$(dpkg -l 2>/dev/null | awk '/^ii/ && $2 ~ /-bbrv3$/ {print $2}' | tr '\n' ' ')
|
||||||
|
pkgs+=" $(dpkg -s bbrv3-config &> /dev/null && echo bbrv3-config)"
|
||||||
|
pkgs=$(echo "$pkgs" | xargs) # 规整空白
|
||||||
|
|
||||||
for URL in $ASSET_URLS; do
|
if [[ -n "$pkgs" ]]; then
|
||||||
echo -e "\033[36m下载中:$URL\033[0m"
|
echo -e "\033[36m将要卸载以下包:\033[33m$pkgs\033[0m"
|
||||||
wget_asset "$URL" || { echo -e "\033[31m下载失败:$URL\033[0m"; return 1; }
|
# 内核包 postrm 钩子会自动更新引导;purge 会带走 99-bbrv3.conf(conffile)
|
||||||
done
|
sudo apt-get remove --purge -y $pkgs
|
||||||
|
else
|
||||||
|
echo -e "\033[33m未找到由本项目安装的 BBRv3 内核包。\033[0m"
|
||||||
|
fi
|
||||||
|
|
||||||
install_packages
|
# 移除 apt 源与签名公钥
|
||||||
|
if [[ -f "$SOURCE_LIST" || -f "$KEYRING" ]]; then
|
||||||
|
sudo rm -f "$SOURCE_LIST" "$KEYRING"
|
||||||
|
echo -e "\033[36m已移除 apt 源与签名公钥。\033[0m"
|
||||||
|
sudo apt-get update > /dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
# 兜底清理可能残留的 sysctl drop-in(旧版脚本写入、或非 conffile 情形)
|
||||||
|
sudo rm -f "$SYSCTL_DROPIN"
|
||||||
|
echo -e "\033[1;32m卸载完成。请记得重启系统。\033[0m"
|
||||||
}
|
}
|
||||||
|
|
||||||
# 美化输出的分隔线
|
# 美化输出的分隔线
|
||||||
@@ -411,7 +282,7 @@ echo -e "\033[1;35m(☆ω☆)✧*。 欢迎使用 BBR v3 内核安装脚本 ✧*
|
|||||||
print_separator
|
print_separator
|
||||||
|
|
||||||
echo -e "\033[1;33m╭( ・ㅂ・)و ✧ 你可以选择以下操作哦:\033[0m"
|
echo -e "\033[1;33m╭( ・ㅂ・)و ✧ 你可以选择以下操作哦:\033[0m"
|
||||||
echo -e "\033[33m 1. 🚀 安装或更新 BBR v3 内核(最新版)\033[0m"
|
echo -e "\033[33m 1. 🚀 安装或更新 BBR v3 内核(最新版,apt 源自动跟随)\033[0m"
|
||||||
echo -e "\033[33m 2. 📚 安装指定版本\033[0m"
|
echo -e "\033[33m 2. 📚 安装指定版本\033[0m"
|
||||||
echo -e "\033[33m 3. 🔍 检查 BBR v3 状态\033[0m"
|
echo -e "\033[33m 3. 🔍 检查 BBR v3 状态\033[0m"
|
||||||
echo -e "\033[33m 4. 🗑️ 卸载 BBR v3 内核\033[0m"
|
echo -e "\033[33m 4. 🗑️ 卸载 BBR v3 内核\033[0m"
|
||||||
@@ -469,16 +340,7 @@ case "$ACTION" in
|
|||||||
;;
|
;;
|
||||||
4)
|
4)
|
||||||
echo -e "\033[1;32mヽ(・∀・)ノ 您选择了卸载 BBR v3 内核!\033[0m"
|
echo -e "\033[1;32mヽ(・∀・)ノ 您选择了卸载 BBR v3 内核!\033[0m"
|
||||||
PACKAGES_TO_REMOVE=$(dpkg -l | grep -- '-bbrv3' | awk '{print $2}' | tr '\n' ' ')
|
uninstall_bbrv3
|
||||||
if [[ -n "$PACKAGES_TO_REMOVE" ]]; then
|
|
||||||
echo -e "\033[36m将要卸载以下内核包: \033[33m$PACKAGES_TO_REMOVE\033[0m"
|
|
||||||
sudo apt-get remove --purge $PACKAGES_TO_REMOVE -y
|
|
||||||
sudo rm -f "$SYSCTL_DROPIN"
|
|
||||||
update_bootloader
|
|
||||||
echo -e "\033[1;32m内核包已卸载。请记得重启系统。\033[0m"
|
|
||||||
else
|
|
||||||
echo -e "\033[33m未找到由本脚本安装的 BBR v3 内核包。\033[0m"
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo -e "\033[31m( ̄▽ ̄)ゞ 无效的选项,请输入 1-4 之间的数字哦~\033[0m"
|
echo -e "\033[31m( ̄▽ ̄)ゞ 无效的选项,请输入 1-4 之间的数字哦~\033[0m"
|
||||||
|
|||||||
Executable
+54
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build the bbrv3-config package (Architecture: all): ships the BBR + CAKE + ECN
|
||||||
|
# sysctl drop-in so installing the kernel configures the network stack with no
|
||||||
|
# installer script. The meta-package depends on it.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
out_dir=${1:?usage: build-config-package.sh <output_dir> [version]}
|
||||||
|
version=${2:-1.0}
|
||||||
|
|
||||||
|
work=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$work"' EXIT
|
||||||
|
|
||||||
|
pkgdir="$work/bbrv3-config"
|
||||||
|
mkdir -p "$pkgdir/DEBIAN" "$pkgdir/etc/sysctl.d"
|
||||||
|
|
||||||
|
cat > "$pkgdir/etc/sysctl.d/99-bbrv3.conf" <<'EOF'
|
||||||
|
# Managed by the bbrv3-config package (linux-kernel-bbrv3).
|
||||||
|
# BBR congestion control + CAKE default qdisc + ECN.
|
||||||
|
net.core.default_qdisc = cake
|
||||||
|
net.ipv4.tcp_congestion_control = bbr
|
||||||
|
net.ipv4.tcp_ecn = 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# conffile: dpkg preserves local edits to the drop-in across upgrades.
|
||||||
|
echo "/etc/sysctl.d/99-bbrv3.conf" > "$pkgdir/DEBIAN/conffiles"
|
||||||
|
|
||||||
|
cat > "$pkgdir/DEBIAN/control" <<EOF
|
||||||
|
Package: bbrv3-config
|
||||||
|
Version: $version
|
||||||
|
Architecture: all
|
||||||
|
Maintainer: linux-kernel-bbrv3
|
||||||
|
Depends: procps
|
||||||
|
Section: net
|
||||||
|
Priority: optional
|
||||||
|
Description: Default network stack (BBR + CAKE + ECN) for BBRv3 kernels
|
||||||
|
Ships /etc/sysctl.d/99-bbrv3.conf so the BBRv3 kernel boots with BBR
|
||||||
|
congestion control, the CAKE default qdisc and ECN enabled.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat > "$pkgdir/DEBIAN/postinst" <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
if [ "$1" = "configure" ]; then
|
||||||
|
# Applies now if the running kernel supports it; otherwise the settings take
|
||||||
|
# effect on the next boot into the BBRv3 kernel (sch_cake is built in there).
|
||||||
|
sysctl --system >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
chmod 0755 "$pkgdir/DEBIAN/postinst"
|
||||||
|
|
||||||
|
mkdir -p "$out_dir"
|
||||||
|
dpkg-deb --build --root-owner-group "$pkgdir" \
|
||||||
|
"$out_dir/bbrv3-config_${version}_all.deb"
|
||||||
|
echo "Built $out_dir/bbrv3-config_${version}_all.deb"
|
||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build the linux-image-bbrv3 meta-package. It depends on a specific built kernel
|
||||||
|
# package plus bbrv3-config, so `apt upgrade` tracks the newest BBRv3 kernel while
|
||||||
|
# previously installed kernels stay around for fallback.
|
||||||
|
#
|
||||||
|
# The dependency is the *actual* produced package name (passed in), not a guessed
|
||||||
|
# one, so any localversion/suffix drift from the kernel build can't break it.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
meta_version=${1:?usage: build-meta-package.sh <meta_version> <deb_arch> <depends_pkg> <out_dir>}
|
||||||
|
arch=${2:?missing deb arch (amd64|arm64)}
|
||||||
|
depends_pkg=${3:?missing kernel image package name to depend on}
|
||||||
|
out_dir=${4:?missing output dir}
|
||||||
|
|
||||||
|
work=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$work"' EXIT
|
||||||
|
|
||||||
|
pkgdir="$work/meta"
|
||||||
|
mkdir -p "$pkgdir/DEBIAN"
|
||||||
|
|
||||||
|
cat > "$pkgdir/DEBIAN/control" <<EOF
|
||||||
|
Package: linux-image-bbrv3
|
||||||
|
Version: $meta_version
|
||||||
|
Architecture: $arch
|
||||||
|
Maintainer: linux-kernel-bbrv3
|
||||||
|
Depends: $depends_pkg, bbrv3-config
|
||||||
|
Section: kernel
|
||||||
|
Priority: optional
|
||||||
|
Description: BBRv3 kernel (tracks the latest stable build)
|
||||||
|
Meta-package pulling in the newest BBRv3 kernel built by this project
|
||||||
|
($depends_pkg) plus the bbrv3-config network defaults. Run
|
||||||
|
'apt-mark hold linux-image-bbrv3' to pin your kernel and stop auto-tracking.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
mkdir -p "$out_dir"
|
||||||
|
dpkg-deb --build --root-owner-group "$pkgdir" \
|
||||||
|
"$out_dir/linux-image-bbrv3_${meta_version}_${arch}.deb"
|
||||||
|
echo "Built $out_dir/linux-image-bbrv3_${meta_version}_${arch}.deb"
|
||||||
Executable
+60
@@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Print the kernel version this project should build.
|
||||||
|
#
|
||||||
|
# We track an established *stable* series, never the bleeding edge. Right after a
|
||||||
|
# new series N.M is released, kernel.org's "latest stable version" flips to "N.M"
|
||||||
|
# and equals "latest mainline version" — that is mainline, not a baked stable.
|
||||||
|
# So we select the highest three-component point release (X.Y.Z) whose series X.Y
|
||||||
|
# is strictly below mainline AND has a matching BBRv3 patch in this repo:
|
||||||
|
# - three components exclude the freshly-cut top series (shown as "N.M");
|
||||||
|
# - the "< mainline" test excludes a series that still equals mainline;
|
||||||
|
# - the patch gate excludes series we cannot port BBRv3 onto (e.g. LTS 6.x).
|
||||||
|
# The series advances automatically once the next one matures and mainline moves on.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
repo_root=$(cd -- "$script_dir/.." && pwd)
|
||||||
|
|
||||||
|
FINGER_URL="${FINGER_URL:-https://www.kernel.org/finger_banner}"
|
||||||
|
|
||||||
|
banner=$(curl -fsSL "$FINGER_URL")
|
||||||
|
if [ -z "$banner" ]; then
|
||||||
|
echo "Failed to fetch $FINGER_URL" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Mainline major.minor, stripping any -rcN suffix: "7.1" or "7.2-rc1" -> "7.1"/"7.2".
|
||||||
|
mainline_mm=$(printf '%s\n' "$banner" \
|
||||||
|
| grep -i 'latest mainline version' \
|
||||||
|
| grep -oE '[0-9]+\.[0-9]+' | head -n1)
|
||||||
|
if [ -z "$mainline_mm" ]; then
|
||||||
|
echo "Could not parse mainline version from finger_banner." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Every three-component point release mentioned in the banner (stable + longterm),
|
||||||
|
# ascending and de-duplicated. Two-component entries like a just-released "7.1"
|
||||||
|
# are intentionally not matched here.
|
||||||
|
mapfile -t candidates < <(printf '%s\n' "$banner" \
|
||||||
|
| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | sort -V -u)
|
||||||
|
|
||||||
|
# strictly_less A B -> true when A < B under version sort.
|
||||||
|
strictly_less() {
|
||||||
|
[ "$1" != "$2" ] && [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
target=""
|
||||||
|
for v in "${candidates[@]}"; do
|
||||||
|
mm=${v%.*} # 7.0.12 -> 7.0
|
||||||
|
strictly_less "$mm" "$mainline_mm" || continue
|
||||||
|
[ -f "$repo_root/patches/bbrv3-linux-$mm.patch" ] || continue
|
||||||
|
target="$v" # candidates ascending: keep highest match
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$target" ]; then
|
||||||
|
echo "No stable series below mainline $mainline_mm has a BBRv3 patch in patches/." >&2
|
||||||
|
echo "Point releases seen: ${candidates[*]:-none}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s\n' "$target"
|
||||||
Reference in New Issue
Block a user