feat(install): install from the NeoTachyon Gitea repo with source fallback

Point the installer at https://git.rukavishnikoff.ru/hacker07/NeoTachyon and
support Gitea's GitHub-compatible API for releases. When the repository has
no published release yet, fall back to installing the backend and LuCI UI
directly from the branch source archive (tachyon/files, luci-app htdocs/root)
so the same one-liner installs the fork as-is. Repo can be overridden via
TACHYON_REPO_HOST / TACHYON_REPO_OWNER / TACHYON_REPO_NAME /
TACHYON_SOURCE_BRANCH / TACHYON_REPO_INSTALL_URL. README install/uninstall
commands now point to the Gitea raw URLs.
This commit is contained in:
2026-09-17 14:37:42 +03:00
parent 617107ef15
commit 4f2a7661fe
3 changed files with 136 additions and 28 deletions
+129 -24
View File
@@ -3,8 +3,14 @@
INSTALLER_VERSION="2.0.1"
REPO_OWNER="Dushnilin"
REPO_NAME="tachyon"
# Install source. Defaults to the NeoTachyon fork (Gitea). Override with
# TACHYON_REPO_HOST / TACHYON_REPO_OWNER / TACHYON_REPO_NAME / TACHYON_SOURCE_BRANCH
# or TACHYON_REPO_INSTALL_URL (full base URL).
REPO_HOST="${TACHYON_REPO_HOST:-git.rukavishnikoff.ru}"
REPO_OWNER="${TACHYON_REPO_OWNER:-hacker07}"
REPO_NAME="${TACHYON_REPO_NAME:-NeoTachyon}"
SOURCE_BRANCH="${TACHYON_SOURCE_BRANCH:-main}"
REPO_INSTALL_URL="${TACHYON_REPO_INSTALL_URL:-https://${REPO_HOST}/${REPO_OWNER}/${REPO_NAME}}"
# ─── TUI helpers (self-contained, no external deps) ─────────────────────────
# POSIX-compatible, works with dash/bash/mksh on OpenWrt.
@@ -2440,32 +2446,36 @@ fetch_github_latest_release_json() {
repo="$2"
response=""
message=""
url="https://api.github.com/repos/${owner}/${repo}/releases/latest"
if [ "$REPO_HOST" = "github.com" ]; then
api_base="https://api.github.com/repos/${owner}/${repo}"
else
api_base="https://${REPO_HOST}/api/v1/repos/${owner}/${repo}"
fi
url="$api_base/releases/latest"
response="$(http_get "$url" 2>/dev/null || true)"
if [ -z "$response" ] || printf '%s' "$response" | grep -q '"message": "Not Found"'; then
if [ "$REPO_HOST" = "github.com" ] && { [ -z "$response" ] || printf '%s' "$response" | grep -q '"message": "Not Found"'; }; then
warn "Latest release query failed; trying via gh-proxy.com mirror..."
response="$(http_get "https://gh-proxy.com/$url" 2>/dev/null || true)"
fi
if [ -z "$response" ] || printf '%s' "$response" | grep -q '"message": "Not Found"'; then
warn "Latest release query failed; trying release list..."
url="https://api.github.com/repos/${owner}/${repo}/releases"
warn "Latest release query failed; trying the release list..."
url="$api_base/releases"
response="$(http_get "$url" 2>/dev/null || true)"
if [ -z "$response" ] || printf '%s' "$response" | grep -q '"message": "Not Found"'; then
if [ "$REPO_HOST" = "github.com" ] && { [ -z "$response" ] || printf '%s' "$response" | grep -q '"message": "Not Found"'; }; then
warn "Release list query failed; trying via gh-proxy.com mirror..."
response="$(http_get "https://gh-proxy.com/$url" 2>/dev/null || true)"
fi
fi
[ -n "$response" ] || fail "Failed to query GitHub latest release metadata for ${owner}/${repo}"
[ -n "$response" ] || return 1
message="$(printf '%s' "$response" | install_json_ucode github-message 2>/dev/null)" ||
fail "GitHub returned an invalid latest release response for ${owner}/${repo}"
message="$(printf '%s' "$response" | install_json_ucode github-message 2>/dev/null)" || return 1
case "$message" in
*"API rate limit"*|*"rate limit exceeded"*)
fail "GitHub API rate limit reached. Try again later."
return 1
;;
"Not Found")
fail "No published latest release found for ${owner}/${repo}"
return 1
;;
esac
@@ -2477,7 +2487,14 @@ resolve_tachyon_release() {
[ "$PKG_IS_APK" -eq 1 ] && asset_ext="apk"
TACHYON_RELEASE_JSON="$(fetch_github_latest_release_json "$REPO_OWNER" "$REPO_NAME")"
TACHYON_RELEASE_AVAILABLE=0
TACHYON_RELEASE_JSON="$(fetch_github_latest_release_json "$REPO_OWNER" "$REPO_NAME" 2>/dev/null || true)"
if [ -z "$TACHYON_RELEASE_JSON" ]; then
warn "No published release found in ${REPO_INSTALL_URL}; falling back to source installation."
TACHYON_RELEASE_TAG="source-${SOURCE_BRANCH}"
return 0
fi
TACHYON_RELEASE_AVAILABLE=1
TACHYON_RELEASE_TAG="$(printf '%s' "$TACHYON_RELEASE_JSON" | install_json_ucode release-tag 2>/dev/null)"
[ -n "$TACHYON_RELEASE_TAG" ] || fail "Failed to detect the Tachyon release tag"
@@ -3034,6 +3051,86 @@ post_install() {
TOTAL_STEPS=10
# Install the backend + LuCI UI directly from the repository source tree
# (tachyon/files, luci-app-tachyon/htdocs and luci-app-tachyon/root). Used
# when the configured repository has no prebuilt release artifacts yet.
source_install_dependencies() {
for _dep in ca-bundle curl ucode ucode-mod-fs ucode-mod-uci coreutils-base64 bind-dig nftables ip-full; do
if ! pkg_is_installed "$_dep" 2>/dev/null; then
msg "Installing dependency: $_dep"
pkg_install_name "$_dep" 2>/dev/null || warn "Could not install dependency $_dep (may be provided by firmware)"
fi
done
}
source_install_from_repo() {
[ "$DRY_RUN" -eq 1 ] && { msg "[dry-run] would install NeoTachyon from source archive"; return 0; }
msg "Installing NeoTachyon from source (branch $SOURCE_BRANCH)..."
_archive_url="${REPO_INSTALL_URL}/archive/${SOURCE_BRANCH}.tar.gz"
_archive_file="${TMP_DIR:-/tmp}/neotachyon-src.tar.gz"
_src_dir="${TMP_DIR:-/tmp}/neotachyon-src"
download_file_once "$_archive_url" "$_archive_file" || fail "Failed to download the source archive from ${_archive_url}"
rm -rf "$_src_dir"
mkdir -p "$_src_dir"
tar -xzf "$_archive_file" -C "$_src_dir" 2>/dev/null || fail "Failed to extract the source archive"
_top="$(find "$_src_dir" -maxdepth 1 -type d \( -name 'NeoTachyon-*' -o -name 'tachyon-*' \) | head -n 1)"
[ -n "$_top" ] || _top="$_src_dir"
if [ -d "$_top/tachyon/files" ]; then
msg "Installing backend files..."
mkdir -p /etc /usr /www
cp -a "$_top/tachyon/files/etc/." /etc/ 2>/dev/null || true
cp -a "$_top/tachyon/files/usr/." /usr/ 2>/dev/null || true
chmod 755 /usr/bin/tachyon 2>/dev/null || true
chmod 755 /etc/init.d/tachyon /etc/init.d/tachyon-torrserver-direct 2>/dev/null || true
chmod 755 /usr/lib/cgi-bin/tachyon-agent 2>/dev/null || true
else
fail "The source archive does not contain the tachyon package"
fi
if [ -d "$_top/luci-app-tachyon/htdocs" ]; then
msg "Installing LuCI UI..."
mkdir -p /www
cp -a "$_top/luci-app-tachyon/htdocs/." /www/ 2>/dev/null || true
fi
if [ -d "$_top/luci-app-tachyon/root" ]; then
cp -a "$_top/luci-app-tachyon/root/." / 2>/dev/null || true
chmod 755 /etc/uci-defaults/50_luci-tachyon 2>/dev/null || true
fi
if [ ! -f /etc/config/tachyon ]; then
mkdir -p /etc/config
cp -f "$_top/tachyon/files/etc/config/tachyon" /etc/config/tachyon 2>/dev/null || true
fi
chmod 600 /etc/config/tachyon 2>/dev/null || true
mkdir -p /www/cgi-bin
cp -f /usr/lib/cgi-bin/tachyon-agent /www/cgi-bin/tachyon-agent 2>/dev/null || true
chmod 755 /www/cgi-bin/tachyon-agent 2>/dev/null || true
source_install_dependencies
# Apply uci-defaults (LuCI menu / rpcd acl), then start the service.
for _f in /etc/uci-defaults/50_luci-tachyon; do
if [ -f "$_f" ]; then
sh "$_f" 2>/dev/null || true
rm -f "$_f"
fi
done
/etc/init.d/tachyon enable 2>/dev/null || true
/etc/init.d/tachyon restart 2>/dev/null || true
/etc/init.d/rpcd reload 2>/dev/null || true
rm -f /var/luci-indexcache* /tmp/luci-indexcache* /tmp/luci-modulecache/* 2>/dev/null || true
msg "NeoTachyon has been installed from source."
}
main() {
trap cleanup EXIT HUP INT TERM
@@ -3075,22 +3172,30 @@ main() {
resolve_tachyon_release
debug "Resolved release tag: $TACHYON_RELEASE_TAG"
step 3 "$TOTAL_STEPS" "$(installer_text downloading_packages)"
download_tachyon_packages
if [ "$TACHYON_RELEASE_AVAILABLE" -eq 1 ]; then
step 3 "$TOTAL_STEPS" "$(installer_text downloading_packages)"
download_tachyon_packages
install_zram_if_requested
install_zram_if_requested
step 4 "$TOTAL_STEPS" "$(installer_text cleaning_legacy)"
cleanup_legacy_installation
step 4 "$TOTAL_STEPS" "$(installer_text cleaning_legacy)"
cleanup_legacy_installation
step 5 "$TOTAL_STEPS" "$(installer_text installing_backend)"
install_backend_package
step 5 "$TOTAL_STEPS" "$(installer_text installing_backend)"
install_backend_package
step 6 "$TOTAL_STEPS" "$(installer_text migrating_config)"
migrate_legacy_configuration
step 6 "$TOTAL_STEPS" "$(installer_text migrating_config)"
migrate_legacy_configuration
step 7 "$TOTAL_STEPS" "$(installer_text installing_ui)"
install_ui_packages
step 7 "$TOTAL_STEPS" "$(installer_text installing_ui)"
install_ui_packages
else
step 3 "$TOTAL_STEPS" "Installing NeoTachyon from source"
source_install_from_repo
install_zram_if_requested
cleanup_legacy_installation
fi
step 8 "$TOTAL_STEPS" "$(installer_text installing_singbox)"
install_selected_sing_box