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:
+129
-24
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user