diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b25c15b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/default.nix b/default.nix index 811e4f2..a099027 100644 --- a/default.nix +++ b/default.nix @@ -3,6 +3,8 @@ with pkgs; let cedro = callPackage ./pkgs/c/cedro/package.nix {}; capnpc = callPackage ./pkgs/c/capnpc/package.nix {}; + gost-ctl = callPackage ./pkgs/g/gost-ctl/package.nix {}; + norouter = callPackage ./pkgs/n/norouter/package.nix {}; xbuild = callPackage ./pkgs/x/xbuild/package.nix { pkgs = pkgs; cedro = cedro; @@ -15,17 +17,78 @@ let unity_test_with_color = pkgs.unity-test.overrideAttrs { env.NIX_CFLAGS_COMPILE = "-DUNITY_OUTPUT_COLOR=1"; }; + libcello_debug = pkgs.libcello.overrideAttrs (prevAttrs: { + separateDebugInfo = true; + postInstall = '' + mkdir -p $out/lib/pkgconfig + cat >$out/lib/pkgconfig/libcello.pc < {}, + pkg-config, +}: + +let + meta = with lib; { + description = "Some true type fonts"; + homepage = "https://github.com/shen390s/my-ttf-fonts"; + license = lib.licenses.asl20; + platforms = lib.platforms.unix; + }; + pname = "my-ttf-fonts"; + version = "1.0"; + mysource = pkgs.runCommand "download-fonts" { + nativeBuiltInputs = [ pkgs.curl ]; + outputHash = "sha256-JMWxG0lCkzXhuBoBtEk8N0g6qrLRJo0WGki9A+yTbhU="; + outputHashAlgo = "sha256"; + outputHashMode = "flat"; + } '' + ${pkgs.curl}/bin/curl --output $out \ + --location \ + --max-redirs 20 \ + --retry 3 \ + --disable-epsv \ + --cookie-jar cookies \ + --insecure \ + --user-agent curl/8.17.0 -C - --fail \ + https://gitee.com/shen390s/my-ttf-fonts/archive/refs/tags/v1.0.tar.gz + ''; +in +stdenv.mkDerivation (finalAttrs: { + pname = pname; + version = version; + + src = mysource; + + unpackPhase = '' + tar -zxvf $src + ''; + + installPhase = '' + mkdir -p $out/share/fonts/truetype + _fontdir="${pname}-v${version}" + if [ -d $_fontdir/fonts/truetype ]; then + ls $_fontdir/fonts/truetype/* + cp -r $_fontdir/fonts/truetype/*.ttf $out/share/fonts/truetype/ + cp -r $_fontdir/fonts/truetype/*.ttc $out/share/fonts/truetype/ + else + echo "No fonts found in $_fontdir/fonts/truetype" + exit 0 + fi + ''; + + inherit meta; +}) diff --git a/pkgs/g/gost-ctl/gost-ctl b/pkgs/g/gost-ctl/gost-ctl new file mode 100755 index 0000000..dc69718 --- /dev/null +++ b/pkgs/g/gost-ctl/gost-ctl @@ -0,0 +1,174 @@ +#!/bin/bash +# gost-ctl — manage the GOST proxy tunnel and container network attachments +# +# Usage: gost-ctl [args] +# +# Commands: +# start Start gost-tunnel service and watcher +# stop Stop gost-tunnel service and watcher +# restart Restart gost-tunnel service +# attach Attach a container to the bridge (idempotent) +# detach Detach a container from the bridge +# status Show tunnel, bridge, and container status +# +# Config resolution (first match wins): +# $GOST_TUNNEL_CONFIG env var → /etc/gost-tunnel/env → .env in script dir + +set -e + +# ─── Config ───────────────────────────────────────────────────────────────── + +CONFIG_FILE="${GOST_TUNNEL_CONFIG:-/etc/gost-tunnel/env}" +if [ ! -f "$CONFIG_FILE" ]; then + CONFIG_FILE="$(dirname "$(realpath "$0")")/.env" +fi +if [ ! -f "$CONFIG_FILE" ]; then + echo "ERROR: config not found. Set GOST_TUNNEL_CONFIG or place .env next to gost-ctl" + exit 1 +fi +# shellcheck source=/dev/null +source "$CONFIG_FILE" + +# ─── Helpers ──────────────────────────────────────────────────────────────── + +log() { echo "[$(date '+%H:%M:%S')] $*"; } + +require_root() { + [ "$(id -u)" -eq 0 ] || { echo "ERROR: gost-ctl must be run as root"; exit 1; } +} + +# ─── Commands ─────────────────────────────────────────────────────────────── + +cmd_start() { + systemctl start gost-tunnel gost-tunnel-watcher + log "gost-tunnel started" +} + +cmd_stop() { + systemctl stop gost-tunnel-watcher gost-tunnel + log "gost-tunnel stopped" +} + +cmd_restart() { + systemctl restart gost-tunnel + log "gost-tunnel restarted" +} + +cmd_attach() { + require_root + local cname="$1" cip="$2" + [ -n "$cname" ] && [ -n "$cip" ] \ + || { echo "Usage: gost-ctl attach "; exit 1; } + + local veth_h="veth-${cname}-h" veth_c="veth-${cname}-c" + + # Idempotency: skip if already attached + if ip link show "$veth_h" >/dev/null 2>&1; then + log "$cname already attached (veth exists), skipping." + return 0 + fi + + # Wait for container PID + local pid + for i in $(seq 1 30); do + pid=$(docker inspect -f '{{.State.Pid}}' "$cname" 2>/dev/null) + [[ "$pid" =~ ^[0-9]+$ ]] && [ "$pid" -gt 0 ] && break + log "Waiting for $cname PID... ($i/30)"; sleep 1 + done + [[ "$pid" =~ ^[0-9]+$ ]] && [ "$pid" -gt 0 ] \ + || { log "ERROR: $cname PID not found"; docker logs "$cname"; exit 1; } + + log "$cname PID: $pid" + mkdir -p /var/run/netns + ln -sfT "/proc/$pid/ns/net" "/var/run/netns/$cname" + + ip link add "$veth_h" type veth peer name "$veth_c" + ip link set "$veth_h" master "$BRIDGE_NAME" + ip link set "$veth_h" up + ip link set "$veth_c" netns "$cname" + ip netns exec "$cname" ip link set "$veth_c" name eth0 + ip netns exec "$cname" ip link set lo up + ip netns exec "$cname" ip link set eth0 up + ip netns exec "$cname" ip addr add "${cip}/24" dev eth0 + ip netns exec "$cname" ip route add default via "$BRIDGE_IP" + log "$cname attached at $cip via $BRIDGE_IP" +} + +cmd_detach() { + require_root + local cname="$1" + [ -n "$cname" ] || { echo "Usage: gost-ctl detach "; exit 1; } + + local veth_h="veth-${cname}-h" + if ip link del "$veth_h" 2>/dev/null; then + log "$cname veth removed" + else + log "$cname veth not found (already detached?)" + fi + rm -f "/var/run/netns/$cname" + log "$cname detached" +} + +cmd_status() { + echo "" + local svc_state watcher_state + svc_state=$(systemctl is-active gost-tunnel 2>/dev/null || echo "inactive") + watcher_state=$(systemctl is-active gost-tunnel-watcher 2>/dev/null || echo "inactive") + echo "Service: $svc_state" + echo "Watcher: $watcher_state" + + if ip link show "$TUN_NAME" >/dev/null 2>&1; then + local tun_addr + tun_addr=$(ip -4 addr show "$TUN_NAME" | awk '/inet /{print $2}' | head -1) + echo "TUN: $TUN_NAME UP ${tun_addr:-}" + else + echo "TUN: $TUN_NAME DOWN" + fi + + if ip link show "$BRIDGE_NAME" >/dev/null 2>&1; then + local br_addr + br_addr=$(ip -4 addr show "$BRIDGE_NAME" | awk '/inet /{print $2}' | head -1) + echo "Bridge: $BRIDGE_NAME UP ${br_addr:-}" + else + echo "Bridge: $BRIDGE_NAME DOWN" + fi + + echo "" + echo "Attached containers:" + local found=0 + for veth in $(ip link show 2>/dev/null | grep -oP 'veth-\S+-h' | sort -u); do + local cname="${veth#veth-}"; cname="${cname%-h}" + local cip + cip=$(ip netns exec "$cname" ip -4 addr show eth0 2>/dev/null \ + | awk '/inet /{print $2}' | head -1 || echo "") + local link_state + link_state=$(ip link show "$veth" 2>/dev/null | grep -oP '(?<=state )\S+' | head -1) + printf " %-16s %-18s %s\n" "$cname" "$cip" "$veth ${link_state:-?}" + found=1 + done + [ "$found" -eq 0 ] && echo " (none)" + echo "" +} + +# ─── Dispatch ─────────────────────────────────────────────────────────────── + +case "${1:-}" in + start) cmd_start ;; + stop) cmd_stop ;; + restart) cmd_restart ;; + attach) shift; cmd_attach "$@" ;; + detach) shift; cmd_detach "$@" ;; + status) cmd_status ;; + *) + echo "Usage: gost-ctl [args]" + echo "" + echo "Commands:" + echo " start Start gost-tunnel service and watcher" + echo " stop Stop gost-tunnel service and watcher" + echo " restart Restart gost-tunnel service" + echo " attach Attach container to bridge" + echo " detach Detach container from bridge" + echo " status Show tunnel and container status" + exit 1 + ;; +esac diff --git a/pkgs/g/gost-ctl/package.nix b/pkgs/g/gost-ctl/package.nix new file mode 100644 index 0000000..4c6df37 --- /dev/null +++ b/pkgs/g/gost-ctl/package.nix @@ -0,0 +1,28 @@ +# xbuild.nix +{ + lib, + stdenv, + pkgs, + ... +}: + +let + gost-ctl=stdenv.mkDerivation { + pname = "gost-ctl"; + version = "0.0.1"; + + src = ./.; + + nativeBuildInputs = [ + pkgs.gost + ]; + + installPhase = '' + mkdir -p $out/bin + cp gost-ctl $out/bin + chmod +x $out/bin/gost-ctl + ''; + }; + +in + gost-ctl diff --git a/pkgs/n/norouter/package.nix b/pkgs/n/norouter/package.nix new file mode 100644 index 0000000..e2cf540 --- /dev/null +++ b/pkgs/n/norouter/package.nix @@ -0,0 +1,25 @@ +{ stdenvNoCC, lib, fetchurl, autoPatchelfHook, zlib, openssl }: + +stdenvNoCC.mkDerivation rec { + pname = "norouter"; + version = "0.6.5"; + + src = fetchurl { + url = "https://github.com/${pname}/${pname}/releases/download/v${version}/${pname}-Linux-x86_64.tgz"; + hash = "sha256-kNAzGBuYLLHITGJAerH27kj8MjmxjII63ORym//rJEk="; + }; + + nativeBuildInputs = [ autoPatchelfHook ]; + buildInputs = [ zlib openssl ]; # Add required libraries + + dontUnpack = true; + + configurePhase = '' + cat $src |gzip -dc |tar xf - + ''; + + installPhase = '' + mkdir -p $out/bin + cp norouter $out/bin + ''; +} diff --git a/pkgs/s/struct2json/package.nix b/pkgs/s/struct2json/package.nix new file mode 100644 index 0000000..b26f60b --- /dev/null +++ b/pkgs/s/struct2json/package.nix @@ -0,0 +1,37 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, + pkgs, +}: + +let + meta = with lib; { + description = "convert c struct to json"; + homepage = "https://github.com/armink/struct2json"; + license = lib.licenses.mit; + platforms = lib.platforms.unix; + }; + pname = "struct2json"; + version = "1.0.0"; +in +stdenv.mkDerivation (finalAttrs: { + pname = pname; + version = version; + + src = fetchFromGitHub { + owner = "shen390s"; + repo = "struct2json"; + rev = "master"; + hash = "sha256-ZCJC6NmdL4EASlJYlWym3rjPK6qaKGtZMQhY0GIqTTU="; + }; + + nativeBuildInputs = [ + pkgs.meson + pkgs.ninja + pkgs.pkgconf + ]; + + inherit meta; +})