Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e53d0ab98d | |||
| 2ca51adc61 | |||
| 67ecf36883 | |||
| 9a35306340 | |||
| a4bb6f170a | |||
| f9114426cc | |||
| 8ee2a03a2c | |||
| 0275b1871d | |||
| 9491dc50a8 | |||
| e7eb3e6557 | |||
| a596acfb72 | |||
| b727e54589 | |||
| 2af08c455a | |||
| d049846564 | |||
| 97308f9d15 | |||
| 4cef273e57 | |||
| 660474a6ce | |||
| 93dd14967d | |||
| 923a3872fe | |||
| 5f10e34341 | |||
| b80d322650 | |||
| fff386f9d5 | |||
| 93f4e1feea | |||
| 97255b42fb | |||
| 554a2c349f | |||
| 10501168c5 | |||
| d346c61c28 | |||
| 7652095109 | |||
| 6b58ac67f6 | |||
| 3ad1d52fe2 | |||
| 2e8cc24e81 | |||
| 36e73fd9ed | |||
| 3d14e4a370 | |||
| c6b8c9c905 | |||
| f980b6ace9 | |||
| 6a27280f8d | |||
| 38b0cdcf0e | |||
| 268627ed63 | |||
| 55a663cf7a | |||
| 8b76ccb742 | |||
| d0f6cb0e70 | |||
| 56ebe6bbab | |||
| dc90de7ff1 | |||
| 319f47eb73 | |||
| fd2889ccca | |||
| 0859f50897 | |||
| 5c002f0b2b | |||
| 5a824c2098 | |||
| ffb381e40e | |||
| 0a70d7fd39 | |||
| 8d81ee1f7e | |||
| 1e248306a6 | |||
| 7cd6a6e0a1 | |||
| 8f58feffbe | |||
| 5790ef753b | |||
| 9a49fd6b24 | |||
| b35e431200 | |||
| 4b52382326 | |||
| 11506699e3 | |||
| 4c6c707dd0 | |||
| d69a4104fc | |||
| c3f81eef25 | |||
| 05276f9eea | |||
| 0105b29bfc | |||
| 0cbba6b290 | |||
| 250f7bf93a | |||
| 4efeb3b60f | |||
| d20061614c | |||
| 289c9f7ebe | |||
| bdfa74be54 | |||
| 6efdc35b19 | |||
| 20278d67f1 | |||
| a4f69a5f7d | |||
| 9b1643afac | |||
| a9086eac84 | |||
| 4bd6744df4 | |||
| 274a485f8d | |||
| 747aef0005 | |||
| a0e17c6e22 | |||
| 19973c24d8 | |||
| 9a4c8b703e | |||
| 968a25eaf1 | |||
| 13fb22c7ee | |||
| 6c867774f7 | |||
| 7c3e4a6e39 | |||
| 466a32a90a | |||
| cb4882e983 | |||
| 87378e49ac | |||
| 100434fc3c | |||
| deef4702f4 | |||
| 1c2415bc1b | |||
| fac09b381f |
@@ -0,0 +1,129 @@
|
|||||||
|
name: CI
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
components: clippy, rustfmt
|
||||||
|
- name: Install system dependencies (Linux)
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
run: sudo apt-get update && sudo apt-get install -y libdrm-dev libdrm-amdgpu1
|
||||||
|
- name: Cargo fmt
|
||||||
|
run: cargo fmt --all -- --check
|
||||||
|
- name: Clippy
|
||||||
|
run: cargo clippy --all-targets --all-features -- -D warnings
|
||||||
|
- name: Build (release)
|
||||||
|
run: cargo build --release --workspace
|
||||||
|
|
||||||
|
- name: "Linux: start agent and run WS probe"
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
RUST_LOG=info SOCKTOP_ENABLE_SSL=0 SOCKTOP_AGENT_GPU=0 SOCKTOP_AGENT_TEMP=0 ./target/release/socktop_agent -p 3000 > agent.log 2>&1 &
|
||||||
|
AGENT_PID=$!
|
||||||
|
for i in {1..60}; do
|
||||||
|
if curl -fsS http://127.0.0.1:3000/healthz >/dev/null; then break; fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
if ! curl -fsS http://127.0.0.1:3000/healthz >/dev/null; then
|
||||||
|
echo "--- agent.log (tail) ---"
|
||||||
|
tail -n 200 agent.log || true
|
||||||
|
(command -v ss >/dev/null && ss -ltnp || netstat -ltnp) || true
|
||||||
|
kill $AGENT_PID || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
SOCKTOP_WS=ws://127.0.0.1:3000/ws cargo test -p socktop --test ws_probe -- --nocapture
|
||||||
|
kill $AGENT_PID || true
|
||||||
|
|
||||||
|
- name: "Windows: start agent and run WS probe"
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$env:SOCKTOP_ENABLE_SSL = "0"
|
||||||
|
$env:SOCKTOP_AGENT_GPU = "0"
|
||||||
|
$env:SOCKTOP_AGENT_TEMP = "0"
|
||||||
|
$out = Join-Path $PWD "agent.out.txt"
|
||||||
|
$err = Join-Path $PWD "agent.err.txt"
|
||||||
|
$p = Start-Process -FilePath "${PWD}\target\release\socktop_agent.exe" -ArgumentList "-p 3000" -RedirectStandardOutput $out -RedirectStandardError $err -PassThru -NoNewWindow
|
||||||
|
$ready = $false
|
||||||
|
for ($i = 0; $i -lt 60; $i++) {
|
||||||
|
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
|
||||||
|
$pinfo.FileName = "curl.exe"
|
||||||
|
$pinfo.Arguments = "-fsS http://127.0.0.1:3000/healthz"
|
||||||
|
$pinfo.RedirectStandardOutput = $true
|
||||||
|
$pinfo.RedirectStandardError = $true
|
||||||
|
$pinfo.UseShellExecute = $false
|
||||||
|
$proc = [System.Diagnostics.Process]::Start($pinfo)
|
||||||
|
$proc.WaitForExit()
|
||||||
|
if ($proc.ExitCode -eq 0) { $ready = $true; break }
|
||||||
|
Start-Sleep -Seconds 1
|
||||||
|
}
|
||||||
|
if (-not $ready) {
|
||||||
|
Write-Warning "TCP connect to (127.0.0.1 : 3000) failed"
|
||||||
|
if (Test-Path $out) { Write-Host "--- agent.out (full) ---"; Get-Content $out }
|
||||||
|
if (Test-Path $err) { Write-Host "--- agent.err (full) ---"; Get-Content $err }
|
||||||
|
Write-Host "--- netstat ---"
|
||||||
|
netstat -ano | Select-String ":3000" | ForEach-Object { $_.Line }
|
||||||
|
if ($p -and !$p.HasExited) { Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue }
|
||||||
|
throw "agent did not become ready"
|
||||||
|
}
|
||||||
|
$env:SOCKTOP_WS = "ws://127.0.0.1:3000/ws"
|
||||||
|
try {
|
||||||
|
cargo test -p socktop --test ws_probe -- --nocapture
|
||||||
|
} finally {
|
||||||
|
if ($p -and !$p.HasExited) { Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue }
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Smoke test (client --help)
|
||||||
|
run: cargo run -p socktop -- --help
|
||||||
|
|
||||||
|
- name: Package artifacts (Linux)
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
mkdir -p dist
|
||||||
|
cp target/release/socktop dist/
|
||||||
|
cp target/release/socktop_agent dist/
|
||||||
|
tar czf socktop-${{ matrix.os }}.tar.gz -C dist .
|
||||||
|
|
||||||
|
- name: Package artifacts (Windows)
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
New-Item -ItemType Directory -Force -Path dist | Out-Null
|
||||||
|
Copy-Item target\release\socktop.exe dist\
|
||||||
|
Copy-Item target\release\socktop_agent.exe dist\
|
||||||
|
Compress-Archive -Path dist\* -DestinationPath socktop-${{ matrix.os }}.zip -Force
|
||||||
|
|
||||||
|
- name: Upload build artifacts (ephemeral)
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: socktop-${{ matrix.os }}
|
||||||
|
path: |
|
||||||
|
*.tar.gz
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
- name: Upload to rolling GitHub Release (main only)
|
||||||
|
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
tag_name: latest
|
||||||
|
name: Latest build
|
||||||
|
prerelease: true
|
||||||
|
draft: false
|
||||||
|
files: |
|
||||||
|
*.tar.gz
|
||||||
|
*.zip
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug executable 'socktop'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--bin=socktop",
|
||||||
|
"--package=socktop"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "socktop",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": ["ws://127.0.0.1:3000/ws"],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in executable 'socktop'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--bin=socktop",
|
||||||
|
"--package=socktop"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "socktop",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug executable 'socktop_agent'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--bin=socktop_agent",
|
||||||
|
"--package=socktop_agent"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "socktop_agent",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in executable 'socktop_agent'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--bin=socktop_agent",
|
||||||
|
"--package=socktop_agent"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "socktop_agent",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,423 +0,0 @@
|
|||||||
# APT Repository Setup Summary
|
|
||||||
|
|
||||||
## 🎉 What You Now Have
|
|
||||||
|
|
||||||
You now have a complete system for creating and hosting your own APT repository for socktop packages, **without needing a sponsor or official Debian/Ubuntu approval**.
|
|
||||||
|
|
||||||
## 📁 Files Created
|
|
||||||
|
|
||||||
### Scripts (in `scripts/`)
|
|
||||||
- **`init-apt-repo.sh`** - Initializes the APT repository directory structure
|
|
||||||
- **`add-package-to-repo.sh`** - Adds .deb packages to the repository and generates metadata
|
|
||||||
- **`sign-apt-repo.sh`** - Signs the repository with your GPG key
|
|
||||||
- **`setup-apt-repo.sh`** - All-in-one interactive wizard to set everything up
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
- **`QUICK_START_APT_REPO.md`** - Quick start guide (< 10 minutes)
|
|
||||||
- **`docs/APT_REPOSITORY.md`** - Comprehensive 600+ line guide covering everything
|
|
||||||
- **`APT_REPO_SUMMARY.md`** - This file
|
|
||||||
|
|
||||||
### GitHub Actions
|
|
||||||
- **`.github/workflows/publish-apt-repo.yml`** - Automated building, signing, and publishing
|
|
||||||
|
|
||||||
## 🚀 Quick Start (Choose One)
|
|
||||||
|
|
||||||
### Option 1: Interactive Setup (Recommended for First Time)
|
|
||||||
|
|
||||||
Run the setup wizard:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./scripts/setup-apt-repo.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
This walks you through:
|
|
||||||
1. ✅ Checking prerequisites
|
|
||||||
2. 🔑 Setting up GPG key
|
|
||||||
3. 📦 Finding/building packages
|
|
||||||
4. 📝 Creating repository structure
|
|
||||||
5. ✍️ Signing the repository
|
|
||||||
6. 📋 Next steps to publish to gh-pages
|
|
||||||
|
|
||||||
### Option 2: Manual Step-by-Step
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Initialize
|
|
||||||
./scripts/init-apt-repo.sh
|
|
||||||
|
|
||||||
# 2. Build packages
|
|
||||||
cargo deb --package socktop
|
|
||||||
cargo deb --package socktop_agent
|
|
||||||
|
|
||||||
# 3. Add packages
|
|
||||||
./scripts/add-package-to-repo.sh target/debian/socktop_*.deb
|
|
||||||
./scripts/add-package-to-repo.sh target/debian/socktop-agent_*.deb
|
|
||||||
|
|
||||||
# 4. Sign (replace YOUR-KEY-ID)
|
|
||||||
./scripts/sign-apt-repo.sh apt-repo stable YOUR-KEY-ID
|
|
||||||
|
|
||||||
# 5. Update URLs
|
|
||||||
sed -i 's/YOUR-USERNAME/your-github-username/g' apt-repo/*.{md,html}
|
|
||||||
|
|
||||||
# 6. Publish to gh-pages (see below)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Option 3: Fully Automated (After Initial Setup)
|
|
||||||
|
|
||||||
Once gh-pages branch exists, just tag releases:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git tag v1.50.0
|
|
||||||
git push --tags
|
|
||||||
|
|
||||||
# GitHub Actions will:
|
|
||||||
# - Build packages for AMD64 and ARM64
|
|
||||||
# - Update APT repository
|
|
||||||
# - Sign with your GPG key
|
|
||||||
# - Push to gh-pages branch automatically
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📤 Publishing to GitHub Pages (gh-pages branch)
|
|
||||||
|
|
||||||
**Why gh-pages branch?**
|
|
||||||
- ✅ Keeps main branch clean (source code only)
|
|
||||||
- ✅ Separate branch for published content
|
|
||||||
- ✅ GitHub Actions can auto-update it
|
|
||||||
- ✅ You can customize the landing page
|
|
||||||
|
|
||||||
**Initial Setup:**
|
|
||||||
```bash
|
|
||||||
# Create gh-pages branch
|
|
||||||
git checkout --orphan gh-pages
|
|
||||||
git rm -rf .
|
|
||||||
|
|
||||||
# Copy apt-repo CONTENTS to root (not the folder!)
|
|
||||||
cp -r apt-repo/* .
|
|
||||||
rm -rf apt-repo
|
|
||||||
|
|
||||||
# Commit and push
|
|
||||||
git add .
|
|
||||||
git commit -m "Initialize APT repository"
|
|
||||||
git push -u origin gh-pages
|
|
||||||
|
|
||||||
# Return to main
|
|
||||||
git checkout main
|
|
||||||
```
|
|
||||||
|
|
||||||
**Enable in GitHub:**
|
|
||||||
1. Settings → Pages
|
|
||||||
2. Source: **gh-pages** → **/ (root)**
|
|
||||||
3. Save
|
|
||||||
|
|
||||||
Your repo will be at: `https://your-username.github.io/socktop/`
|
|
||||||
|
|
||||||
**Note:** GitHub Pages only allows `/` (root) or `/docs`. Since we use gh-pages branch, contents go in the root of that branch.
|
|
||||||
|
|
||||||
See `SETUP_GITHUB_PAGES.md` for detailed step-by-step instructions.
|
|
||||||
|
|
||||||
### Alternative: Self-Hosted Server
|
|
||||||
|
|
||||||
Copy `apt-repo/` contents to your web server:
|
|
||||||
```bash
|
|
||||||
rsync -avz apt-repo/ user@example.com:/var/www/apt/
|
|
||||||
```
|
|
||||||
|
|
||||||
Configure Apache/Nginx to serve the directory. See `docs/APT_REPOSITORY.md` for details.
|
|
||||||
|
|
||||||
## 🤖 GitHub Actions Automation
|
|
||||||
|
|
||||||
### Required Secrets
|
|
||||||
|
|
||||||
Add these in GitHub Settings → Secrets → Actions:
|
|
||||||
|
|
||||||
1. **GPG_PRIVATE_KEY**
|
|
||||||
```bash
|
|
||||||
gpg --armor --export-secret-key YOUR-KEY-ID
|
|
||||||
# Copy entire output including BEGIN/END lines
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **GPG_KEY_ID**
|
|
||||||
```bash
|
|
||||||
gpg --list-secret-keys --keyid-format LONG
|
|
||||||
# Use the ID after "rsa4096/"
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **GPG_PASSPHRASE**
|
|
||||||
```bash
|
|
||||||
# Your GPG passphrase (leave empty if no passphrase)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Triggers
|
|
||||||
|
|
||||||
The workflow runs on:
|
|
||||||
- **Version tags**: `git tag v1.50.0 && git push --tags`
|
|
||||||
- **Manual dispatch**: Actions tab → "Publish APT Repository" → Run workflow
|
|
||||||
|
|
||||||
### What It Does
|
|
||||||
|
|
||||||
1. ✅ Builds packages for AMD64 and ARM64
|
|
||||||
2. ✅ Initializes or updates APT repository
|
|
||||||
3. ✅ Generates Packages files and metadata
|
|
||||||
4. ✅ Signs with your GPG key
|
|
||||||
5. ✅ Commits and pushes to gh-pages branch
|
|
||||||
6. ✅ Creates GitHub Release with artifacts
|
|
||||||
7. ✅ Generates summary with installation instructions
|
|
||||||
|
|
||||||
## 👥 User Installation
|
|
||||||
|
|
||||||
Once published, users install with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Add repository
|
|
||||||
curl -fsSL https://your-username.github.io/socktop/KEY.gpg | \
|
|
||||||
sudo gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg
|
|
||||||
|
|
||||||
echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://your-username.github.io/socktop stable main" | \
|
|
||||||
sudo tee /etc/apt/sources.list.d/socktop.list
|
|
||||||
|
|
||||||
# Install
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install socktop socktop-agent
|
|
||||||
|
|
||||||
# The agent service is automatically installed and configured
|
|
||||||
sudo systemctl enable --now socktop-agent
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 Maintenance
|
|
||||||
|
|
||||||
### Release New Version (Automated)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Update version in Cargo.toml, commit changes
|
|
||||||
git add . && git commit -m "Bump version to 1.51.0"
|
|
||||||
git tag v1.51.0
|
|
||||||
git push origin main --tags
|
|
||||||
|
|
||||||
# GitHub Actions automatically:
|
|
||||||
# - Builds packages for AMD64 and ARM64
|
|
||||||
# - Updates apt-repo
|
|
||||||
# - Signs with GPG
|
|
||||||
# - Pushes to gh-pages branch
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manual Update (if needed)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# On main branch
|
|
||||||
cargo deb --package socktop
|
|
||||||
./scripts/add-package-to-repo.sh target/debian/socktop_*.deb
|
|
||||||
./scripts/sign-apt-repo.sh
|
|
||||||
|
|
||||||
# Switch to gh-pages and update
|
|
||||||
git checkout gh-pages
|
|
||||||
cp -r apt-repo/* .
|
|
||||||
git add . && git commit -m "Release v1.51.0" && git push
|
|
||||||
git checkout main
|
|
||||||
```
|
|
||||||
|
|
||||||
### Remove Old Versions
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# On gh-pages branch
|
|
||||||
git checkout gh-pages
|
|
||||||
rm pool/main/socktop_1.50.0_*.deb
|
|
||||||
# Regenerate metadata (re-add remaining packages)
|
|
||||||
git add . && git commit -m "Remove old versions" && git push
|
|
||||||
git checkout main
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎯 Key Benefits
|
|
||||||
|
|
||||||
✅ **No sponsor needed** - Host your own repository
|
|
||||||
✅ **Full control** - You decide when to release
|
|
||||||
✅ **Free hosting** - GitHub Pages at no cost
|
|
||||||
✅ **Automated** - GitHub Actions does the work
|
|
||||||
✅ **Professional** - Just like official repos
|
|
||||||
✅ **Multi-arch** - AMD64, ARM64 support built-in
|
|
||||||
✅ **Secure** - GPG signed packages
|
|
||||||
✅ **Easy updates** - Users get updates via `apt upgrade`
|
|
||||||
|
|
||||||
## 📊 Repository Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
apt-repo/
|
|
||||||
├── dists/
|
|
||||||
│ └── stable/
|
|
||||||
│ ├── Release # Main metadata (checksums)
|
|
||||||
│ ├── Release.gpg # Detached signature
|
|
||||||
│ ├── InRelease # Clearsigned release
|
|
||||||
│ └── main/
|
|
||||||
│ ├── binary-amd64/
|
|
||||||
│ │ ├── Packages # Package list
|
|
||||||
│ │ ├── Packages.gz # Compressed
|
|
||||||
│ │ └── Release # Component metadata
|
|
||||||
│ ├── binary-arm64/
|
|
||||||
│ └── binary-armhf/
|
|
||||||
├── pool/
|
|
||||||
│ └── main/
|
|
||||||
│ ├── socktop_1.50.0_amd64.deb
|
|
||||||
│ ├── socktop-agent_1.50.1_amd64.deb
|
|
||||||
│ ├── socktop_1.50.0_arm64.deb
|
|
||||||
│ └── socktop-agent_1.50.1_arm64.deb
|
|
||||||
├── KEY.gpg # Public GPG key
|
|
||||||
├── README.md # Repository info
|
|
||||||
├── index.html # Web interface
|
|
||||||
└── packages.html # Package listing
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔑 GPG Key Management
|
|
||||||
|
|
||||||
### Create New Key
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gpg --full-generate-key
|
|
||||||
# Choose RSA 4096, no expiration (or 2 years)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Export Keys
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Public key (for users)
|
|
||||||
gpg --armor --export YOUR-KEY-ID > KEY.gpg
|
|
||||||
|
|
||||||
# Private key (for GitHub Secrets)
|
|
||||||
gpg --armor --export-secret-key YOUR-KEY-ID
|
|
||||||
```
|
|
||||||
|
|
||||||
### Backup Keys
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Backup to safe location
|
|
||||||
gpg --export-secret-keys YOUR-KEY-ID > gpg-private-backup.key
|
|
||||||
gpg --export YOUR-KEY-ID > gpg-public-backup.key
|
|
||||||
```
|
|
||||||
|
|
||||||
### Key Rotation
|
|
||||||
|
|
||||||
If your key expires or is compromised:
|
|
||||||
```bash
|
|
||||||
./scripts/sign-apt-repo.sh apt-repo stable NEW-KEY-ID
|
|
||||||
gpg --armor --export NEW-KEY-ID > apt-repo/KEY.gpg
|
|
||||||
# Users need to re-import the key
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🐛 Troubleshooting
|
|
||||||
|
|
||||||
### "Repository not signed"
|
|
||||||
```bash
|
|
||||||
./scripts/sign-apt-repo.sh apt-repo stable YOUR-KEY-ID
|
|
||||||
ls apt-repo/dists/stable/Release* # Should show 3 files
|
|
||||||
```
|
|
||||||
|
|
||||||
### "Package not found"
|
|
||||||
```bash
|
|
||||||
cd apt-repo
|
|
||||||
dpkg-scanpackages --arch amd64 pool/main /dev/null > dists/stable/main/binary-amd64/Packages
|
|
||||||
gzip -9 -k -f dists/stable/main/binary-amd64/Packages
|
|
||||||
cd ..
|
|
||||||
./scripts/sign-apt-repo.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### "404 Not Found" on GitHub Pages
|
|
||||||
- Wait 2-3 minutes after pushing
|
|
||||||
- Check Settings → Pages is enabled
|
|
||||||
- Verify source branch/directory
|
|
||||||
|
|
||||||
### GitHub Actions not signing
|
|
||||||
- Check all 3 secrets are set correctly
|
|
||||||
- GPG_PRIVATE_KEY must include BEGIN/END lines
|
|
||||||
- Test signing locally first
|
|
||||||
|
|
||||||
## 📚 Documentation
|
|
||||||
|
|
||||||
| File | Purpose | Length |
|
|
||||||
|------|---------|--------|
|
|
||||||
| `QUICK_START_APT_REPO.md` | Get started in < 10 minutes | Quick |
|
|
||||||
| `SETUP_GITHUB_PAGES.md` | Detailed gh-pages setup guide | Step-by-step |
|
|
||||||
| `docs/APT_REPOSITORY.md` | Complete guide with all options | Comprehensive |
|
|
||||||
| `docs/DEBIAN_PACKAGING.md` | How .deb packages are built | Technical |
|
|
||||||
| `DEBIAN_PACKAGING_SUMMARY.md` | Overview of packaging work | Summary |
|
|
||||||
| `APT_REPO_SUMMARY.md` | This file | Overview |
|
|
||||||
|
|
||||||
## 🎓 Learning Path
|
|
||||||
|
|
||||||
1. **Start here**: `QUICK_START_APT_REPO.md` (10 min)
|
|
||||||
2. **Set up**: Run `./scripts/setup-apt-repo.sh` (15 min)
|
|
||||||
3. **Publish**: Follow `SETUP_GITHUB_PAGES.md` (5 min)
|
|
||||||
4. **Automate**: Set up GitHub Actions secrets (10 min)
|
|
||||||
5. **Advanced**: Read `docs/APT_REPOSITORY.md` as needed
|
|
||||||
|
|
||||||
## 🚦 Next Steps
|
|
||||||
|
|
||||||
Choose your path:
|
|
||||||
|
|
||||||
### Just Getting Started?
|
|
||||||
1. ✅ Read `QUICK_START_APT_REPO.md`
|
|
||||||
2. ✅ Run `./scripts/setup-apt-repo.sh`
|
|
||||||
3. ✅ Follow `SETUP_GITHUB_PAGES.md` to publish
|
|
||||||
4. ✅ Test installation on a VM
|
|
||||||
|
|
||||||
### Want Automation?
|
|
||||||
1. ✅ Generate/export GPG key
|
|
||||||
2. ✅ Add GitHub Secrets
|
|
||||||
3. ✅ Tag a release: `git tag v1.50.0 && git push --tags`
|
|
||||||
4. ✅ Watch GitHub Actions magic happen
|
|
||||||
|
|
||||||
### Want to Understand Everything?
|
|
||||||
1. ✅ Read `docs/APT_REPOSITORY.md` (comprehensive)
|
|
||||||
2. ✅ Study the scripts in `scripts/`
|
|
||||||
3. ✅ Examine `.github/workflows/publish-apt-repo.yml`
|
|
||||||
4. ✅ Learn about Debian repository format
|
|
||||||
|
|
||||||
### Ready for Production?
|
|
||||||
1. ✅ Set up monitoring/analytics
|
|
||||||
2. ✅ Create PPA for Ubuntu (Launchpad)
|
|
||||||
3. ✅ Apply to Debian mentors for official inclusion
|
|
||||||
4. ✅ Set up repository mirrors
|
|
||||||
5. ✅ Document best practices for users
|
|
||||||
|
|
||||||
## 🌟 Success Criteria
|
|
||||||
|
|
||||||
You'll know you're successful when:
|
|
||||||
|
|
||||||
- [ ] Users can `apt install socktop`
|
|
||||||
- [ ] Updates work with `apt upgrade`
|
|
||||||
- [ ] Multiple architectures supported
|
|
||||||
- [ ] Repository is GPG signed
|
|
||||||
- [ ] GitHub Actions publishes automatically
|
|
||||||
- [ ] Installation instructions in README
|
|
||||||
- [ ] Zero sponsor or approval needed
|
|
||||||
|
|
||||||
## 💡 Pro Tips
|
|
||||||
|
|
||||||
1. **Test first**: Always test on a fresh VM before publishing
|
|
||||||
2. **Keep versions**: Don't delete old .deb files immediately
|
|
||||||
3. **Backup GPG key**: Store it safely offline
|
|
||||||
4. **Monitor downloads**: Use GitHub Insights or server logs
|
|
||||||
5. **Document everything**: Help users troubleshoot
|
|
||||||
6. **Version consistently**: Use semantic versioning
|
|
||||||
7. **Sign always**: Never publish unsigned repositories
|
|
||||||
|
|
||||||
## 🔗 Resources
|
|
||||||
|
|
||||||
- [Debian Repository Format](https://wiki.debian.org/DebianRepository/Format)
|
|
||||||
- [GitHub Pages Docs](https://docs.github.com/en/pages)
|
|
||||||
- [cargo-deb](https://github.com/kornelski/cargo-deb)
|
|
||||||
- [Ubuntu PPA Guide](https://help.launchpad.net/Packaging/PPA)
|
|
||||||
- [Debian Mentors](https://mentors.debian.net/)
|
|
||||||
|
|
||||||
## 🎊 Congratulations!
|
|
||||||
|
|
||||||
You now have everything you need to:
|
|
||||||
- ✅ Create your own APT repository
|
|
||||||
- ✅ Host it for free on GitHub Pages
|
|
||||||
- ✅ Automate the entire process
|
|
||||||
- ✅ Distribute packages professionally
|
|
||||||
- ✅ Provide easy installation for users
|
|
||||||
|
|
||||||
**No sponsor required. No approval needed. You're in control!** 🚀
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Questions?** Check the docs or open an issue.
|
|
||||||
|
|
||||||
**Ready to publish?** Run `./scripts/setup-apt-repo.sh` and follow the wizard!
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
[workspace]
|
||||||
|
resolver = "2"
|
||||||
|
members = [
|
||||||
|
"socktop",
|
||||||
|
"socktop_agent"
|
||||||
|
]
|
||||||
|
|
||||||
|
[workspace.dependencies]
|
||||||
|
# async + streams
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
futures = "0.3"
|
||||||
|
futures-util = "0.3"
|
||||||
|
anyhow = "1.0"
|
||||||
|
|
||||||
|
# websocket
|
||||||
|
tokio-tungstenite = { version = "0.24", features = ["__rustls-tls", "connect"] }
|
||||||
|
tungstenite = "0.24"
|
||||||
|
url = "2.5"
|
||||||
|
|
||||||
|
# JSON + error handling
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
thiserror = "1.0"
|
||||||
|
|
||||||
|
# system stats
|
||||||
|
sysinfo = "0.32"
|
||||||
|
|
||||||
|
# CLI UI
|
||||||
|
ratatui = "0.28"
|
||||||
|
crossterm = "0.27"
|
||||||
|
|
||||||
|
# date/time
|
||||||
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|
||||||
|
# web server (remote-agent)
|
||||||
|
axum = { version = "0.7", features = ["ws"] }
|
||||||
|
|
||||||
|
# protobuf
|
||||||
|
prost = "0.13"
|
||||||
|
prost-types = "0.13"
|
||||||
|
bytes = "1"
|
||||||
|
dirs-next = "2"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
# Favor smaller, simpler binaries with good runtime perf
|
||||||
|
lto = "thin"
|
||||||
|
codegen-units = 1
|
||||||
|
panic = "abort"
|
||||||
|
opt-level = 3
|
||||||
|
strip = "symbols"
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
# 🚀 Get Your APT Repository Live in 5 Minutes
|
|
||||||
|
|
||||||
## You're Here Because...
|
|
||||||
|
|
||||||
You want to publish socktop packages via APT, but GitHub Pages won't let you select `apt-repo/` folder. Here's why and how to fix it:
|
|
||||||
|
|
||||||
**The Issue:** GitHub Pages only serves from `/` (root) or `/docs`, not custom folders like `/apt-repo`.
|
|
||||||
|
|
||||||
**The Solution:** Use a `gh-pages` branch where `apt-repo` contents go in the root.
|
|
||||||
|
|
||||||
## Quick Setup (5 Steps)
|
|
||||||
|
|
||||||
### 1. Create apt-repo locally (if you haven't)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./scripts/setup-apt-repo.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
This creates `apt-repo/` with your packages and signs them.
|
|
||||||
|
|
||||||
### 2. Create gh-pages branch
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git checkout --orphan gh-pages
|
|
||||||
git rm -rf .
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Copy apt-repo to root
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cp -r apt-repo/* .
|
|
||||||
rm -rf apt-repo
|
|
||||||
ls
|
|
||||||
# You should see: dists/ pool/ KEY.gpg index.html README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Push to GitHub
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git add .
|
|
||||||
git commit -m "Initialize APT repository"
|
|
||||||
git push -u origin gh-pages
|
|
||||||
git checkout main
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Enable GitHub Pages
|
|
||||||
|
|
||||||
1. Go to: **Settings → Pages**
|
|
||||||
2. Source: **gh-pages** → **/ (root)**
|
|
||||||
3. Click **Save**
|
|
||||||
|
|
||||||
**Done!** ✅ Your repo will be live at `https://your-username.github.io/socktop/` in 1-2 minutes.
|
|
||||||
|
|
||||||
## Test It
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -I https://your-username.github.io/socktop/KEY.gpg
|
|
||||||
# Should return: HTTP/2 200
|
|
||||||
```
|
|
||||||
|
|
||||||
## Install It (On Any Debian/Ubuntu System)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsSL https://your-username.github.io/socktop/KEY.gpg | \
|
|
||||||
sudo gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg
|
|
||||||
|
|
||||||
echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://your-username.github.io/socktop stable main" | \
|
|
||||||
sudo tee /etc/apt/sources.list.d/socktop.list
|
|
||||||
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install socktop socktop-agent
|
|
||||||
```
|
|
||||||
|
|
||||||
## What's Next?
|
|
||||||
|
|
||||||
### Now (Optional):
|
|
||||||
- Customize `index.html` on gh-pages for a nice landing page
|
|
||||||
- Add installation instructions to your main README
|
|
||||||
|
|
||||||
### Later:
|
|
||||||
- Set up GitHub Actions automation (see `QUICK_START_APT_REPO.md`)
|
|
||||||
- Add more architectures (ARM64, ARMv7)
|
|
||||||
|
|
||||||
## Understanding the Setup
|
|
||||||
|
|
||||||
```
|
|
||||||
main branch: gh-pages branch:
|
|
||||||
├── src/ ├── dists/
|
|
||||||
├── Cargo.toml ├── pool/
|
|
||||||
├── scripts/ ├── KEY.gpg
|
|
||||||
└── apt-repo/ (local) └── index.html ← GitHub Pages serves this
|
|
||||||
|
|
||||||
Work here ↑ Published here ↑
|
|
||||||
```
|
|
||||||
|
|
||||||
- **main**: Your development work
|
|
||||||
- **gh-pages**: What users see/download
|
|
||||||
- **apt-repo/**: Local folder (ignored in git, see `.gitignore`)
|
|
||||||
|
|
||||||
## Need More Help?
|
|
||||||
|
|
||||||
- **Quick start**: `QUICK_START_APT_REPO.md`
|
|
||||||
- **Detailed setup**: `SETUP_GITHUB_PAGES.md`
|
|
||||||
- **Why gh-pages?**: `WHY_GHPAGES_BRANCH.md`
|
|
||||||
- **Full guide**: `docs/APT_REPOSITORY.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**You got this!** 🎉
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
||||||
|
|
||||||
mQGNBGkih7QBDADgX6sYMx2Lp6qcZxeCCizcy4TFsxcRJfp5mfbMplVES0hQToIP
|
|
||||||
EMC11JqPwQdLliXKjUr8Z2kgM2oqvH+dkdgzUGrw6kTK8YHc+qs37iJAOVS9D72X
|
|
||||||
tTld282NrtFwzb74nS2GKPkpWI7aSKBpHtWFPX/1ONsc56qGqFd3wwikEvCz8MeJ
|
|
||||||
HwCD1JZ9F+2DyyXWsTJNgDwPloJSUbtyVuk2gd6PeTg7AQdx92Pk/mggmYbHtP8N
|
|
||||||
wy072ku1g8K/hplmwIOGpSx1JWvAQkDU/Bb/jSqrYg2wSHO7IQnYE8I3x/zglYBl
|
|
||||||
FYNh47TVQr0zPVSYR1MQkHU5YLBTDc5UgDvtcsYUiTtq4D/m8HWmKja0/UKGxvDJ
|
|
||||||
P5sUPcp4dk77RdoCtUe5HImYGS8lo5N3+t0lz8sd9rYmRiIO4f7FJaJqJeHbUJyn
|
|
||||||
iw/GCQh5D5/D571dICrEq/QhL+k5KhJljPGoVMGPFXJIc7q+CxvGp2oOo5fOlbOn
|
|
||||||
3kSrM93AJPwT8FMAEQEAAbRFSmFzb24gV2l0dHkgKHNvY2t0b3AgYXB0IHNpZ25p
|
|
||||||
bmcga2V5KSA8amFzb25wd2l0dHkrc29ja3RvcEBwcm90b24ubWU+iQHOBBMBCgA4
|
|
||||||
FiEEHnVWqAU5uDlLwoINESwaeYRl+/IFAmkih7QCGwMFCwkIBwIGFQoJCAsCBBYC
|
|
||||||
AwECHgECF4AACgkQESwaeYRl+/KV+gwAzfZVZEhO7MQV2EmNeKVK1GycFSm2oUAl
|
|
||||||
ZbwNIEHu6+tOzqXJb8o65BtGlbLSGavsMpgRCK2SL83DdLOkutG1ahQiJr+5GaXC
|
|
||||||
zbQgX+VWqGPZtQ+I6/rVoYZPMTCrqpAmFgvVpqv0xod7w8/wny8/XmhQ37KY2/0l
|
|
||||||
B38oNTvdA7C8jzSrI6kr3XqurvQRW7z+MnC+nCp9Ob9bYtY0kpd4U3NrVdb8m32U
|
|
||||||
d5LVFwD1OGvzLOSqyJ33IKjSJc4KLvW+aEsHXe+fHO9UEzH8Nbo5MmVvX3QIHiyq
|
|
||||||
jD4zN16AGsGYqCK4irtQCiD3wBOdsG/RVkgIcdlmAH3EGEp7Ux8+7v1PXYI+UrSs
|
|
||||||
XE7f1xFTJ2r5TMex6W3he073Em4qhQsrnMF5syTZsM6N+5UqXVOM1RuDVVXr7929
|
|
||||||
hC3G8pK/A2W5Lwpxl2yzock2CxhvUn7M/xm4VbcPlWTCUd/QzU8VtsgaGHcuhi5e
|
|
||||||
xHY1AU07STLB9RinjBVf2bmk4oDQcmB6uQGNBGkih7QBDACrjE+xSWP92n931/5t
|
|
||||||
+tXcujwFlIpSZdbSQFr0B0YyjPRUP4FSzEGu8vuM5ChUfWKhmN1dDr5C4qFo9NgQ
|
|
||||||
6oCN2HubajSGyXNwnOMlMb5ck79Ubmy9yDV9/ZLqpJJiozGap2/EnNoDhaANlmUg
|
|
||||||
rfqUHpIB8XC2IZ0Itt05tp/u78dJiB+R6ReZn/bVUafNV4jIqYZfLRzI3FTJ4xvK
|
|
||||||
FGs/ER+JajAdJQ8LPfazmDQSGw0huguxhopZwKQ/qWZMn1OHq/ZaPvCqbQt3irLw
|
|
||||||
dLPDC4pEaYGRyADYeyuarG0DVyUQ9XRc/NufKDvOAn33LpBPBpcvNQAsVhWTCYl7
|
|
||||||
ogQ+suVYVN8Tu7v4bUSHKwzXKvLN/ojJX/Fh7eTW4TPsgLHNHAEDUkSQozIe9vO6
|
|
||||||
o+vydDqRxuXJgdkR7lqP6PQDYrhRYZGJf57eKf6VtTKYFaMbiMWPU+vcHeB0/iDe
|
|
||||||
Pv81qro2LD2PG5WCzDpNETBceCTjykb9r0VHx4/JsiojKmsAEQEAAYkBtgQYAQoA
|
|
||||||
IBYhBB51VqgFObg5S8KCDREsGnmEZfvyBQJpIoe0AhsMAAoJEBEsGnmEZfvyNp8M
|
|
||||||
AIH+6+hGB3qADdnhNgb+3fN0511eK9Uk82lxgGARLcD8GN1UP0HlvEqkxCHy3PUe
|
|
||||||
tHcsuYVz7i8pmpEGdFx9zv7MelenUsJniUQ++OZKx6iUG/MYqz//NxY+5lyRmcu2
|
|
||||||
aYvUxhkgf9zgxXTkTyV2VV32mX//cHcwc+c/089QAPzCMaSrHdNK+ED9+k8uquJ1
|
|
||||||
lSL9Bm15z/EV42v9Q/4KTM5OBLHpNw0Rvn9C0iuZVwHXBrrA/HSGXpA54AqNUMpZ
|
|
||||||
kRPgLQcy5yVE2y1aXLXt2XdTn6YPzrAjNoazYYuCWHYIZU7dGkIswpsDirDLKHdD
|
|
||||||
onb3VShmSpemYjsuFiqhfi6qwCkeHsz/CpQAp70SZ+z9oB8H80PJVKPbPIP3zEf3
|
|
||||||
i7bcsqHA7stF+8sJclXgxBUBeDJ3O2jN/scBOcvNA6xoRp7+oJbnjDRuxBmh+fVg
|
|
||||||
TIuw2++vTF2Ml0EMv7ePTpr7b1DofuJRNYGkuAIMVXHjLTqMiTJUce3OUy003zMg
|
|
||||||
Dg==
|
|
||||||
=AaPQ
|
|
||||||
-----END PGP PUBLIC KEY BLOCK-----
|
|
||||||
@@ -1,221 +0,0 @@
|
|||||||
# Quick Start: Setting Up Your socktop APT Repository
|
|
||||||
|
|
||||||
This guide will get your APT repository up and running in **under 10 minutes**.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- [ ] Debian packages built (or use GitHub Actions to build them)
|
|
||||||
- [ ] GPG key for signing
|
|
||||||
- [ ] GitHub repository with Pages enabled
|
|
||||||
|
|
||||||
## Step 1: Create GPG Key (if needed)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generate a new key
|
|
||||||
gpg --full-generate-key
|
|
||||||
|
|
||||||
# Select:
|
|
||||||
# - RSA and RSA (default)
|
|
||||||
# - 4096 bits
|
|
||||||
# - Key does not expire (or 2 years)
|
|
||||||
# - Your name and email
|
|
||||||
|
|
||||||
# Get your key ID
|
|
||||||
gpg --list-secret-keys --keyid-format LONG
|
|
||||||
# Look for the part after "rsa4096/" - that's your KEY-ID
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 2: Initialize Repository Locally
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd socktop
|
|
||||||
|
|
||||||
# Create the repository structure
|
|
||||||
./scripts/init-apt-repo.sh
|
|
||||||
|
|
||||||
# Build packages (or download from GitHub Actions)
|
|
||||||
cargo install cargo-deb
|
|
||||||
cargo deb --package socktop
|
|
||||||
cargo deb --package socktop_agent
|
|
||||||
|
|
||||||
# Add packages to repository
|
|
||||||
./scripts/add-package-to-repo.sh target/debian/socktop_*.deb
|
|
||||||
./scripts/add-package-to-repo.sh target/debian/socktop-agent_*.deb
|
|
||||||
|
|
||||||
# Sign the repository (replace YOUR-KEY-ID with actual key ID)
|
|
||||||
./scripts/sign-apt-repo.sh apt-repo stable YOUR-KEY-ID
|
|
||||||
|
|
||||||
# Update URLs with your GitHub username
|
|
||||||
sed -i 's/YOUR-USERNAME/your-github-username/g' apt-repo/README.md apt-repo/index.html
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 3: Publish to GitHub Pages (gh-pages branch)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create gh-pages branch
|
|
||||||
git checkout --orphan gh-pages
|
|
||||||
git rm -rf .
|
|
||||||
|
|
||||||
# Copy apt-repo CONTENTS to root (not the folder itself)
|
|
||||||
cp -r apt-repo/* .
|
|
||||||
rm -rf apt-repo
|
|
||||||
|
|
||||||
# Commit and push
|
|
||||||
git add .
|
|
||||||
git commit -m "Initialize APT repository"
|
|
||||||
git push -u origin gh-pages
|
|
||||||
|
|
||||||
# Go back to main branch
|
|
||||||
git checkout main
|
|
||||||
```
|
|
||||||
|
|
||||||
Then in GitHub:
|
|
||||||
1. Go to **Settings → Pages**
|
|
||||||
2. Source: **Deploy from a branch**
|
|
||||||
3. Branch: **gh-pages** → **/ (root)** → **Save**
|
|
||||||
|
|
||||||
Wait 1-2 minutes, then visit: `https://your-username.github.io/socktop/`
|
|
||||||
|
|
||||||
## Step 4: Automate with GitHub Actions
|
|
||||||
|
|
||||||
Add these secrets to your repository (Settings → Secrets → Actions):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Export your private key
|
|
||||||
gpg --armor --export-secret-key YOUR-KEY-ID
|
|
||||||
|
|
||||||
# Copy the ENTIRE output and save as secret: GPG_PRIVATE_KEY
|
|
||||||
```
|
|
||||||
|
|
||||||
Add these three secrets:
|
|
||||||
- **GPG_PRIVATE_KEY**: Your exported private key
|
|
||||||
- **GPG_KEY_ID**: Your key ID (e.g., `ABC123DEF456`)
|
|
||||||
- **GPG_PASSPHRASE**: Your key passphrase (leave empty if no passphrase)
|
|
||||||
|
|
||||||
The workflow in `.github/workflows/publish-apt-repo.yml` will now:
|
|
||||||
- Build packages for AMD64 and ARM64
|
|
||||||
- Update the APT repository
|
|
||||||
- Sign with your GPG key
|
|
||||||
- Push to gh-pages automatically
|
|
||||||
|
|
||||||
Trigger it by:
|
|
||||||
- Creating a version tag: `git tag v1.50.0 && git push --tags`
|
|
||||||
- Manual dispatch from GitHub Actions tab
|
|
||||||
|
|
||||||
## Step 5: Test It
|
|
||||||
|
|
||||||
On any Debian/Ubuntu system:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Add your repository
|
|
||||||
curl -fsSL https://your-username.github.io/socktop/KEY.gpg | \
|
|
||||||
sudo gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg
|
|
||||||
|
|
||||||
echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://your-username.github.io/socktop stable main" | \
|
|
||||||
sudo tee /etc/apt/sources.list.d/socktop.list
|
|
||||||
|
|
||||||
# Install
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install socktop socktop-agent
|
|
||||||
|
|
||||||
# Verify
|
|
||||||
socktop --version
|
|
||||||
socktop_agent --version
|
|
||||||
```
|
|
||||||
|
|
||||||
## Maintenance
|
|
||||||
|
|
||||||
### Add a New Version
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build new packages
|
|
||||||
cargo deb --package socktop
|
|
||||||
cargo deb --package socktop_agent
|
|
||||||
|
|
||||||
# Add to repository
|
|
||||||
./scripts/add-package-to-repo.sh target/debian/socktop_*.deb
|
|
||||||
./scripts/add-package-to-repo.sh target/debian/socktop-agent_*.deb
|
|
||||||
|
|
||||||
# Re-sign
|
|
||||||
./scripts/sign-apt-repo.sh apt-repo stable YOUR-KEY-ID
|
|
||||||
|
|
||||||
# Publish
|
|
||||||
cd docs/apt # or wherever your apt-repo is
|
|
||||||
git add .
|
|
||||||
git commit -m "Release v1.51.0"
|
|
||||||
git push origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
### Or Just Tag and Let GitHub Actions Do It
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Update version in Cargo.toml
|
|
||||||
# Commit changes
|
|
||||||
git add .
|
|
||||||
git commit -m "Bump version to 1.51.0"
|
|
||||||
|
|
||||||
# Tag and push
|
|
||||||
git tag v1.51.0
|
|
||||||
git push origin main --tags
|
|
||||||
|
|
||||||
# GitHub Actions will:
|
|
||||||
# - Build packages for AMD64 and ARM64
|
|
||||||
# - Update gh-pages branch automatically
|
|
||||||
# - Sign and publish!
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### "Repository not signed" error
|
|
||||||
|
|
||||||
Make sure you signed it:
|
|
||||||
```bash
|
|
||||||
./scripts/sign-apt-repo.sh apt-repo stable YOUR-KEY-ID
|
|
||||||
ls apt-repo/dists/stable/Release*
|
|
||||||
# Should show: Release, Release.gpg, InRelease, KEY.gpg
|
|
||||||
```
|
|
||||||
|
|
||||||
### "404 Not Found" on GitHub Pages
|
|
||||||
|
|
||||||
1. Check Settings → Pages is enabled
|
|
||||||
2. Wait 2-3 minutes for GitHub to deploy
|
|
||||||
3. Verify the URL structure matches your settings
|
|
||||||
|
|
||||||
### GitHub Actions not signing
|
|
||||||
|
|
||||||
Check that all three secrets are set correctly:
|
|
||||||
- Settings → Secrets and variables → Actions
|
|
||||||
- Make sure GPG_PRIVATE_KEY includes the BEGIN/END lines
|
|
||||||
- Test locally first
|
|
||||||
|
|
||||||
## What's Next?
|
|
||||||
|
|
||||||
✅ You now have a working APT repository!
|
|
||||||
|
|
||||||
**Share it:**
|
|
||||||
- Add installation instructions to your main README
|
|
||||||
- Tweet/blog about it
|
|
||||||
- Submit to awesome-rust lists
|
|
||||||
|
|
||||||
**Improve it:**
|
|
||||||
- Customize your GitHub Pages site (it's just HTML!)
|
|
||||||
- Add more architectures (ARMv7)
|
|
||||||
- Create multiple distributions (stable, testing)
|
|
||||||
- Set up download statistics
|
|
||||||
- Apply to Ubuntu PPA (Launchpad)
|
|
||||||
- Eventually submit to official Debian repos
|
|
||||||
|
|
||||||
## Full Documentation
|
|
||||||
|
|
||||||
For detailed information, see:
|
|
||||||
- `docs/APT_REPOSITORY.md` - Complete APT repository guide
|
|
||||||
- `docs/DEBIAN_PACKAGING.md` - Debian packaging details
|
|
||||||
- `DEBIAN_PACKAGING_SUMMARY.md` - Quick summary
|
|
||||||
|
|
||||||
## Questions?
|
|
||||||
|
|
||||||
Open an issue on GitHub or check the full documentation.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Happy packaging! 📦**
|
|
||||||
@@ -1,38 +1,487 @@
|
|||||||
# socktop APT Repository
|
# socktop
|
||||||
|
|
||||||
This repository contains Debian packages for socktop and socktop-agent.
|
socktop is a remote system monitor with a rich TUI, inspired by top/btop, talking to a lightweight agent over WebSockets.
|
||||||
|
|
||||||
## Adding this repository
|
- Linux agent: near-zero CPU when idle (request-driven, no always-on sampler)
|
||||||
|
- TUI: smooth graphs, sortable process table, scrollbars, readable colors
|
||||||
|
|
||||||
Add the repository to your system:
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Remote monitoring via WebSocket (JSON over WS)
|
||||||
|
- Optional WSS (TLS): agent auto‑generates a self‑signed cert on first run; client pins the cert via --tls-ca/-t
|
||||||
|
- TUI built with ratatui
|
||||||
|
- CPU
|
||||||
|
- Overall sparkline + per-core mini bars
|
||||||
|
- Accurate per-process CPU% (Linux /proc deltas), normalized to 0–100%
|
||||||
|
- Memory/Swap gauges with human units
|
||||||
|
- Disks: per-device usage
|
||||||
|
- Network: per-interface throughput with sparklines and peak markers
|
||||||
|
- Temperatures: CPU (optional)
|
||||||
|
- Top processes (top 50)
|
||||||
|
- PID, name, CPU%, memory, and memory%
|
||||||
|
- Click-to-sort by CPU% or Mem (descending)
|
||||||
|
- Scrollbar and mouse/keyboard scrolling
|
||||||
|
- Total process count shown in the header
|
||||||
|
- Only top-level processes listed (threads hidden) — matches btop/top
|
||||||
|
- Optional GPU metrics (can be disabled)
|
||||||
|
- Optional auth token for the agent
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prerequisites: Install Rust (rustup)
|
||||||
|
|
||||||
|
Rust is fast, safe, and cross‑platform. Installing it will make your machine better. Consider yourself privileged.
|
||||||
|
|
||||||
|
Linux/macOS:
|
||||||
```bash
|
```bash
|
||||||
# Add the GPG key
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
curl -fsSL https://jasonwitty.github.io/socktop/KEY.gpg | sudo gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg
|
# load cargo for this shell
|
||||||
|
source "$HOME/.cargo/env"
|
||||||
# Add the repository
|
# ensure stable is up to date
|
||||||
echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://jasonwitty.github.io/socktop stable main" | sudo tee /etc/apt/sources.list.d/socktop.list
|
rustup update stable
|
||||||
|
rustc --version
|
||||||
# Update and install
|
cargo --version
|
||||||
sudo apt update
|
# after install you may need to reload your shell, e.g.:
|
||||||
sudo apt install socktop socktop-agent
|
exec bash # or: exec zsh / exec fish
|
||||||
```
|
```
|
||||||
|
|
||||||
## Manual Installation
|
Windows (for the brave): install from https://rustup.rs with the MSVC toolchain. Yes, you’ll need Visual Studio Build Tools. You chose Windows — enjoy the ride.
|
||||||
|
|
||||||
You can also download and install packages manually from the `pool/main/` directory.
|
### Raspberry Pi / Ubuntu / PopOS (required)
|
||||||
|
|
||||||
|
Install GPU support with apt command below
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://jasonwitty.github.io/socktop/pool/main/socktop_VERSION_ARCH.deb
|
sudo apt-get update
|
||||||
sudo dpkg -i socktop_VERSION_ARCH.deb
|
sudo apt-get install libdrm-dev libdrm-amdgpu1
|
||||||
```
|
```
|
||||||
|
|
||||||
## Supported Architectures
|
---
|
||||||
|
|
||||||
- amd64 (x86_64)
|
## Architecture
|
||||||
- arm64 (aarch64)
|
|
||||||
- armhf (32-bit ARM)
|
|
||||||
|
|
||||||
## Building from Source
|
Two components:
|
||||||
|
|
||||||
See the main repository at https://github.com/jasonwitty/socktop
|
1) Agent (remote): small Rust WS server using sysinfo + /proc. It collects on demand when the client asks (fast metrics ~500 ms, processes ~2 s, disks ~5 s). No background loop when nobody is connected.
|
||||||
|
|
||||||
|
2) Client (local): TUI that connects to ws://HOST:PORT/ws (or wss://HOST:PORT/ws when TLS is enabled) and renders updates.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
- Build both binaries:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/jasonwitty/socktop.git
|
||||||
|
cd socktop
|
||||||
|
cargo build --release
|
||||||
|
```
|
||||||
|
|
||||||
|
- Start the agent on the target machine (default port 3000):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./target/release/socktop_agent --port 3000
|
||||||
|
```
|
||||||
|
|
||||||
|
- Connect with the TUI from your local machine:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./target/release/socktop ws://REMOTE_HOST:3000/ws
|
||||||
|
```
|
||||||
|
|
||||||
|
### Quick demo (no agent setup)
|
||||||
|
|
||||||
|
Spin up a temporary local agent on port 3231 and connect automatically:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop --demo
|
||||||
|
```
|
||||||
|
|
||||||
|
Or just run `socktop` with no arguments and pick the built‑in `demo` entry from the interactive profile list (if you have saved profiles, `demo` is appended). The demo agent:
|
||||||
|
|
||||||
|
- Runs locally (`ws://127.0.0.1:3231/ws`)
|
||||||
|
- Stops automatically (you'll see "Stopped demo agent on port 3231") when you quit the TUI or press Ctrl-C
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Install (from crates.io)
|
||||||
|
|
||||||
|
You don’t need to clone this repo to use socktop. Install the published binaries with cargo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# TUI (client)
|
||||||
|
cargo install socktop
|
||||||
|
# Agent (server)
|
||||||
|
cargo install socktop_agent
|
||||||
|
```
|
||||||
|
|
||||||
|
This drops socktop and socktop_agent into ~/.cargo/bin (add it to PATH).
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- After installing Rust via rustup, reload your shell (e.g., exec bash) so cargo is on PATH.
|
||||||
|
- Windows: you can also grab prebuilt EXEs from GitHub Actions artifacts if rustup scares you. It shouldn’t. Be brave.
|
||||||
|
|
||||||
|
Option B: System-wide agent (Linux)
|
||||||
|
```bash
|
||||||
|
# If you installed with cargo, binaries are in ~/.cargo/bin
|
||||||
|
sudo install -o root -g root -m 0755 "$HOME/.cargo/bin/socktop_agent" /usr/local/bin/socktop_agent
|
||||||
|
|
||||||
|
# Install and enable the systemd service (example unit in docs/)
|
||||||
|
sudo install -o root -g root -m 0644 docs/socktop-agent.service /etc/systemd/system/socktop-agent.service
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now socktop-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Agent (server):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop_agent --port 3000
|
||||||
|
# or env: SOCKTOP_PORT=3000 socktop_agent
|
||||||
|
# optional auth: SOCKTOP_TOKEN=changeme socktop_agent
|
||||||
|
# enable TLS (self‑signed cert, default port 8443; you can also use -p):
|
||||||
|
socktop_agent --enableSSL --port 8443
|
||||||
|
```
|
||||||
|
|
||||||
|
Client (TUI):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop ws://HOST:3000/ws
|
||||||
|
# with token:
|
||||||
|
socktop "ws://HOST:3000/ws?token=changeme"
|
||||||
|
# TLS with pinned server certificate (recommended over the internet):
|
||||||
|
socktop --tls-ca /path/to/cert.pem wss://HOST:8443/ws
|
||||||
|
# shorthand:
|
||||||
|
socktop -t /path/to/cert.pem wss://HOST:8443/ws
|
||||||
|
# Note: providing --tls-ca/-t automatically upgrades ws:// to wss:// if you forget
|
||||||
|
```
|
||||||
|
|
||||||
|
Intervals (client-driven):
|
||||||
|
- Fast metrics: ~500 ms
|
||||||
|
- Processes: ~2 s (top 50)
|
||||||
|
- Disks: ~5 s
|
||||||
|
|
||||||
|
The agent stays idle unless queried. When queried, it collects just what’s needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Connection Profiles (Named)
|
||||||
|
|
||||||
|
You can save frequently used connection settings (URL + optional TLS CA path) under a short name and reuse them later.
|
||||||
|
|
||||||
|
Config file location:
|
||||||
|
|
||||||
|
- Linux (XDG): `$XDG_CONFIG_HOME/socktop/profiles.json`
|
||||||
|
- Fallback (when XDG not set): `~/.config/socktop/profiles.json`
|
||||||
|
|
||||||
|
### Creating a profile
|
||||||
|
|
||||||
|
First time you specify a new `--profile/-P` name together with a URL (and optional `--tls-ca`), it is saved automatically:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop --profile prod ws://prod-host:3000/ws
|
||||||
|
# With TLS pinning:
|
||||||
|
socktop --profile prod-tls --tls-ca /path/to/cert.pem wss://prod-host:8443/ws
|
||||||
|
|
||||||
|
You can also set custom intervals (milliseconds):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop --profile prod --metrics-interval-ms 750 --processes-interval-ms 3000 ws://prod-host:3000/ws
|
||||||
|
```
|
||||||
|
```
|
||||||
|
|
||||||
|
If a profile already exists you will be prompted before overwriting:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ socktop --profile prod ws://new-host:3000/ws
|
||||||
|
Overwrite existing profile 'prod'? [y/N]: y
|
||||||
|
```
|
||||||
|
|
||||||
|
To overwrite without an interactive prompt pass `--save`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop --profile prod --save ws://new-host:3000/ws
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using a saved profile
|
||||||
|
|
||||||
|
Just pass the profile name (no URL needed):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop --profile prod
|
||||||
|
socktop -P prod-tls # short flag
|
||||||
|
```
|
||||||
|
|
||||||
|
The stored URL (and TLS CA path, if any) plus any saved intervals will be used. TLS auto-upgrade still applies if a CA path is stored alongside a ws:// URL.
|
||||||
|
|
||||||
|
### Interactive selection (no args)
|
||||||
|
|
||||||
|
If you run `socktop` with no arguments and at least one profile exists, you will be shown a numbered list to pick from:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ socktop
|
||||||
|
Select profile:
|
||||||
|
1. prod
|
||||||
|
2. prod-tls
|
||||||
|
Enter number (or blank to abort): 2
|
||||||
|
```
|
||||||
|
|
||||||
|
Choosing a number starts the TUI with that profile. A built‑in `demo` option is always appended; selecting it launches a local agent on port 3231 (no TLS) and connects to `ws://127.0.0.1:3231/ws`. Pressing Enter on blank aborts without connecting.
|
||||||
|
|
||||||
|
### JSON format
|
||||||
|
|
||||||
|
An example `profiles.json` (pretty‑printed):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"prod": { "url": "ws://prod-host:3000/ws" },
|
||||||
|
"prod-tls": {
|
||||||
|
"url": "wss://prod-host:8443/ws",
|
||||||
|
"tls_ca": "/home/user/certs/prod-cert.pem",
|
||||||
|
"metrics_interval_ms": 500,
|
||||||
|
"processes_interval_ms": 2000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"version": 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- The `tls_ca` path is stored as given; if you move or rotate the certificate update the profile by re-running with `--profile NAME --save`.
|
||||||
|
- Deleting a profile: edit the JSON file and remove the entry (TUI does not yet have an in-app delete command).
|
||||||
|
- Profiles are client-side convenience only; they do not affect the agent.
|
||||||
|
- Intervals: `metrics_interval_ms` controls the fast metrics poll (default 500 ms). `processes_interval_ms` controls process list polling (default 2000 ms). Values below 100 ms (metrics) or 200 ms (processes) are clamped.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Updating
|
||||||
|
|
||||||
|
Update the agent (systemd):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# on the server running the agent
|
||||||
|
cargo install socktop_agent --force
|
||||||
|
sudo systemctl stop socktop-agent
|
||||||
|
sudo install -o root -g root -m 0755 "$HOME/.cargo/bin/socktop_agent" /usr/local/bin/socktop_agent
|
||||||
|
# if you changed the unit file:
|
||||||
|
# sudo install -o root -g root -m 0644 docs/socktop-agent.service /etc/systemd/system/socktop-agent.service
|
||||||
|
# sudo systemctl daemon-reload
|
||||||
|
sudo systemctl start socktop-agent
|
||||||
|
sudo systemctl status socktop-agent --no-pager
|
||||||
|
# logs:
|
||||||
|
# journalctl -u socktop-agent -f
|
||||||
|
```
|
||||||
|
|
||||||
|
Update the TUI (client):
|
||||||
|
```bash
|
||||||
|
cargo install socktop --force
|
||||||
|
socktop ws://HOST:3000/ws
|
||||||
|
```
|
||||||
|
|
||||||
|
Tip: If only the binary changed, restart is enough. If the unit file changed, run sudo systemctl daemon-reload.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration (agent)
|
||||||
|
|
||||||
|
- Port:
|
||||||
|
- Flag: --port 8080 or -p 8080
|
||||||
|
- Positional: socktop_agent 8080
|
||||||
|
- Env: SOCKTOP_PORT=8080
|
||||||
|
- TLS (self‑signed):
|
||||||
|
- Enable: --enableSSL
|
||||||
|
- Default TLS port: 8443 (override with --port/-p)
|
||||||
|
- Certificate/Key location (created on first TLS run):
|
||||||
|
- Linux (XDG): $XDG_CONFIG_HOME/socktop_agent/tls/{cert.pem,key.pem} (defaults to ~/.config)
|
||||||
|
- The agent prints these paths on creation.
|
||||||
|
- You can set XDG_CONFIG_HOME before first run to control where certs are written.
|
||||||
|
- Auth token (optional): SOCKTOP_TOKEN=changeme
|
||||||
|
- Disable GPU metrics: SOCKTOP_AGENT_GPU=0
|
||||||
|
- Disable CPU temperature: SOCKTOP_AGENT_TEMP=0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Keyboard & Mouse
|
||||||
|
|
||||||
|
- Quit: q or Esc
|
||||||
|
- Processes pane:
|
||||||
|
- Click “CPU %” to sort by CPU descending
|
||||||
|
- Click “Mem” to sort by memory descending
|
||||||
|
- Mouse wheel: scroll
|
||||||
|
- Drag scrollbar: scroll
|
||||||
|
- Arrow/PageUp/PageDown/Home/End: scroll
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example agent JSON
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"cpu_total": 12.4,
|
||||||
|
"cpu_per_core": [11.2, 15.7],
|
||||||
|
"mem_total": 33554432,
|
||||||
|
"mem_used": 18321408,
|
||||||
|
"swap_total": 0,
|
||||||
|
"swap_used": 0,
|
||||||
|
"process_count": 127,
|
||||||
|
"hostname": "myserver",
|
||||||
|
"cpu_temp_c": 42.5,
|
||||||
|
"disks": [{"name":"nvme0n1p2","total":512000000000,"available":320000000000}],
|
||||||
|
"networks": [{"name":"eth0","received":12345678,"transmitted":87654321}],
|
||||||
|
"top_processes": [
|
||||||
|
{"pid":1234,"name":"nginx","cpu_usage":1.2,"mem_bytes":12345678}
|
||||||
|
],
|
||||||
|
"gpus": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- process_count is merged into the main metrics on the client when processes are polled.
|
||||||
|
- top_processes are the current top 50 (sorting in the TUI is client-side).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
Set a token on the agent and pass it as a query param from the client:
|
||||||
|
|
||||||
|
Server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SOCKTOP_TOKEN=changeme socktop_agent --port 3000
|
||||||
|
```
|
||||||
|
|
||||||
|
Client:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop "ws://HOST:3000/ws?token=changeme"
|
||||||
|
```
|
||||||
|
|
||||||
|
### TLS / WSS
|
||||||
|
|
||||||
|
For encrypted connections, enable TLS on the agent and pin the server certificate on the client.
|
||||||
|
|
||||||
|
Server (generates self‑signed cert and key on first run):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop_agent --enableSSL --port 8443
|
||||||
|
```
|
||||||
|
|
||||||
|
Client (trust/pin the server cert; copy cert.pem from the agent):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
socktop --tls-ca /path/to/agent/cert.pem wss://HOST:8443/ws
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- Do not copy the private key off the server; only the cert.pem is needed by clients.
|
||||||
|
- When --tls-ca/-t is supplied, the client auto‑upgrades ws:// to wss:// to avoid protocol mismatch.
|
||||||
|
- You can run multiple clients with different cert paths by passing --tls-ca per invocation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Using tmux to monitor multiple hosts
|
||||||
|
|
||||||
|
You can use tmux to show multiple socktop instances in a single terminal.
|
||||||
|
|
||||||
|

|
||||||
|
monitoring 4 Raspberry Pis using Tmux
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
- Install tmux (Ubuntu/Debian: `sudo apt-get install tmux`)
|
||||||
|
|
||||||
|
Key bindings (defaults):
|
||||||
|
- Split left/right: Ctrl-b %
|
||||||
|
- Split top/bottom: Ctrl-b "
|
||||||
|
- Move between panes: Ctrl-b + Arrow keys
|
||||||
|
- Show pane numbers: Ctrl-b q
|
||||||
|
- Close a pane: Ctrl-b x
|
||||||
|
- Detach from session: Ctrl-b d
|
||||||
|
|
||||||
|
Two panes (left/right)
|
||||||
|
- This creates a session named "socktop", splits it horizontally, and starts two socktops.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tmux new-session -d -s socktop 'socktop ws://HOST1:3000/ws' \; \
|
||||||
|
split-window -h 'socktop ws://HOST2:3000/ws' \; \
|
||||||
|
select-layout even-horizontal \; \
|
||||||
|
attach
|
||||||
|
```
|
||||||
|
|
||||||
|
Four panes (top-left, top-right, bottom-left, bottom-right)
|
||||||
|
- This creates a 2x2 grid with one socktop per pane.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tmux new-session -d -s socktop 'socktop ws://HOST1:3000/ws' \; \
|
||||||
|
split-window -h 'socktop ws://HOST2:3000/ws' \; \
|
||||||
|
select-pane -t 0 \; split-window -v 'socktop ws://HOST3:3000/ws' \; \
|
||||||
|
select-pane -t 1 \; split-window -v 'socktop ws://HOST4:3000/ws' \; \
|
||||||
|
select-layout tiled \; \
|
||||||
|
attach
|
||||||
|
```
|
||||||
|
|
||||||
|
Tips:
|
||||||
|
- Replace HOST1..HOST4 (and ports) with your targets.
|
||||||
|
- Reattach later: `tmux attach -t socktop`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Platform notes
|
||||||
|
|
||||||
|
- Linux: fully supported (agent and client).
|
||||||
|
- Raspberry Pi:
|
||||||
|
- 64-bit: aarch64-unknown-linux-gnu
|
||||||
|
- 32-bit: armv7-unknown-linux-gnueabihf
|
||||||
|
- Windows:
|
||||||
|
- TUI + agent can build with stable Rust; bring your own MSVC. You’re on Windows; you know the drill.
|
||||||
|
- CPU temperature may be unavailable.
|
||||||
|
- binary exe for both available in build artifacts under actions.
|
||||||
|
- macOS:
|
||||||
|
- TUI works; agent is primarily targeted at Linux. Agent will run just fine on macos for debugging but I have not documented how to run as a service, I may not given the "security" feautures with applications on macos. We will see.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo fmt
|
||||||
|
cargo clippy --all-targets --all-features
|
||||||
|
cargo run -p socktop -- ws://127.0.0.1:3000/ws
|
||||||
|
# TLS (dev): first run will create certs under ~/.config/socktop_agent/tls/
|
||||||
|
cargo run -p socktop_agent -- --enableSSL --port 8443
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
- [x] Agent authentication (token)
|
||||||
|
- [x] Hide per-thread entries; only show processes
|
||||||
|
- [x] Sort top processes in the TUI
|
||||||
|
- [ ] Configurable refresh intervals (client)
|
||||||
|
- [ ] Export metrics to file
|
||||||
|
- [x] TLS / WSS support (self‑signed server cert + client pinning)
|
||||||
|
- [x] Split processes/disks to separate WS calls with independent cadences (already logical on client; formalize API)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT — see LICENSE.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
- ratatui for the TUI
|
||||||
|
- sysinfo for system metrics
|
||||||
|
- tokio-tungstenite for WebSockets
|
||||||
|
|||||||
@@ -1,351 +0,0 @@
|
|||||||
# Setting Up GitHub Pages for socktop APT Repository
|
|
||||||
|
|
||||||
This guide walks you through the initial setup of your APT repository on GitHub Pages using the `gh-pages` branch.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- [ ] You've run `./scripts/setup-apt-repo.sh` or manually created `apt-repo/`
|
|
||||||
- [ ] `apt-repo/` contains signed packages and metadata
|
|
||||||
- [ ] You have a GitHub repository for socktop
|
|
||||||
|
|
||||||
## Step-by-Step Setup
|
|
||||||
|
|
||||||
### 1. Verify Your Local Repository
|
|
||||||
|
|
||||||
First, make sure everything is ready:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check that apt-repo exists and has content
|
|
||||||
ls -la apt-repo/
|
|
||||||
|
|
||||||
# You should see:
|
|
||||||
# - dists/stable/Release, Release.gpg, InRelease
|
|
||||||
# - pool/main/*.deb
|
|
||||||
# - KEY.gpg
|
|
||||||
# - index.html, README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Create and Switch to gh-pages Branch
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create a new orphan branch (no history from main)
|
|
||||||
git checkout --orphan gh-pages
|
|
||||||
|
|
||||||
# Remove all files from staging
|
|
||||||
git rm -rf .
|
|
||||||
```
|
|
||||||
|
|
||||||
**Important:** This creates a completely separate branch. Don't worry - your main branch is safe!
|
|
||||||
|
|
||||||
### 3. Copy APT Repository to Root
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Copy CONTENTS of apt-repo to root of gh-pages
|
|
||||||
cp -r apt-repo/* .
|
|
||||||
|
|
||||||
# Remove the apt-repo directory itself
|
|
||||||
rm -rf apt-repo
|
|
||||||
|
|
||||||
# Verify the structure
|
|
||||||
ls -la
|
|
||||||
|
|
||||||
# You should see in the current directory:
|
|
||||||
# - dists/
|
|
||||||
# - pool/
|
|
||||||
# - KEY.gpg
|
|
||||||
# - index.html
|
|
||||||
# - README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
**Why root?** GitHub Pages can only serve from:
|
|
||||||
- `/` (root) - what we're doing
|
|
||||||
- `/docs` directory
|
|
||||||
- NOT from custom directories like `/apt-repo`
|
|
||||||
|
|
||||||
### 4. Commit and Push
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Add all files
|
|
||||||
git add .
|
|
||||||
|
|
||||||
# Commit
|
|
||||||
git commit -m "Initialize APT repository for GitHub Pages"
|
|
||||||
|
|
||||||
# Push to gh-pages branch
|
|
||||||
git push -u origin gh-pages
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Return to Main Branch
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Switch back to your main development branch
|
|
||||||
git checkout main
|
|
||||||
|
|
||||||
# Verify you're back on main
|
|
||||||
git branch
|
|
||||||
# Should show: * main
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Enable GitHub Pages
|
|
||||||
|
|
||||||
1. Go to your repository on GitHub
|
|
||||||
2. Click **Settings** (top right)
|
|
||||||
3. Click **Pages** (left sidebar)
|
|
||||||
4. Under "Build and deployment":
|
|
||||||
- Source: **Deploy from a branch**
|
|
||||||
- Branch: **gh-pages**
|
|
||||||
- Folder: **/ (root)**
|
|
||||||
- Click **Save**
|
|
||||||
|
|
||||||
### 7. Wait for Deployment
|
|
||||||
|
|
||||||
GitHub will deploy your site. This usually takes 1-2 minutes.
|
|
||||||
|
|
||||||
You can watch the progress:
|
|
||||||
- Go to **Actions** tab
|
|
||||||
- Look for "pages build and deployment" workflow
|
|
||||||
|
|
||||||
### 8. Verify Your Repository is Live
|
|
||||||
|
|
||||||
Once deployed, your repository will be at:
|
|
||||||
|
|
||||||
```
|
|
||||||
https://YOUR-USERNAME.github.io/socktop/
|
|
||||||
```
|
|
||||||
|
|
||||||
Test it:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check the public key is accessible
|
|
||||||
curl -I https://YOUR-USERNAME.github.io/socktop/KEY.gpg
|
|
||||||
|
|
||||||
# Should return: HTTP/2 200
|
|
||||||
|
|
||||||
# Check the Release file
|
|
||||||
curl -I https://YOUR-USERNAME.github.io/socktop/dists/stable/Release
|
|
||||||
|
|
||||||
# Should return: HTTP/2 200
|
|
||||||
```
|
|
||||||
|
|
||||||
### 9. Test Installation (Optional but Recommended)
|
|
||||||
|
|
||||||
On a Debian/Ubuntu VM or system:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Add GPG key
|
|
||||||
curl -fsSL https://YOUR-USERNAME.github.io/socktop/KEY.gpg | \
|
|
||||||
sudo gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg
|
|
||||||
|
|
||||||
# Add repository
|
|
||||||
echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://YOUR-USERNAME.github.io/socktop stable main" | \
|
|
||||||
sudo tee /etc/apt/sources.list.d/socktop.list
|
|
||||||
|
|
||||||
# Update package lists
|
|
||||||
sudo apt update
|
|
||||||
|
|
||||||
# You should see:
|
|
||||||
# Get:1 https://YOUR-USERNAME.github.io/socktop stable InRelease [xxx B]
|
|
||||||
|
|
||||||
# Install packages
|
|
||||||
sudo apt install socktop socktop-agent
|
|
||||||
|
|
||||||
# Verify
|
|
||||||
socktop --version
|
|
||||||
```
|
|
||||||
|
|
||||||
## Understanding the Two Branches
|
|
||||||
|
|
||||||
After setup, you'll have two branches:
|
|
||||||
|
|
||||||
### `main` branch (development)
|
|
||||||
```
|
|
||||||
main/
|
|
||||||
├── src/
|
|
||||||
├── Cargo.toml
|
|
||||||
├── scripts/
|
|
||||||
├── docs/
|
|
||||||
├── apt-repo/ ← Local build artifact (not published)
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
**Purpose:** Source code, development, building packages
|
|
||||||
|
|
||||||
### `gh-pages` branch (published)
|
|
||||||
```
|
|
||||||
gh-pages/
|
|
||||||
├── dists/
|
|
||||||
├── pool/
|
|
||||||
├── KEY.gpg
|
|
||||||
├── index.html ← Customize this for a nice landing page!
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
**Purpose:** Published APT repository served by GitHub Pages
|
|
||||||
|
|
||||||
## Workflow Going Forward
|
|
||||||
|
|
||||||
### Manual Updates
|
|
||||||
|
|
||||||
When you release a new version:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. On main branch, build new packages
|
|
||||||
git checkout main
|
|
||||||
cargo deb --package socktop
|
|
||||||
cargo deb --package socktop_agent
|
|
||||||
|
|
||||||
# 2. Update local apt-repo
|
|
||||||
./scripts/add-package-to-repo.sh target/debian/socktop_*.deb
|
|
||||||
./scripts/add-package-to-repo.sh target/debian/socktop-agent_*.deb
|
|
||||||
./scripts/sign-apt-repo.sh apt-repo stable YOUR-GPG-KEY-ID
|
|
||||||
|
|
||||||
# 3. Switch to gh-pages and update
|
|
||||||
git checkout gh-pages
|
|
||||||
cp -r apt-repo/* .
|
|
||||||
git add .
|
|
||||||
git commit -m "Release v1.51.0"
|
|
||||||
git push origin gh-pages
|
|
||||||
|
|
||||||
# 4. Return to main
|
|
||||||
git checkout main
|
|
||||||
```
|
|
||||||
|
|
||||||
### Automated Updates (Recommended)
|
|
||||||
|
|
||||||
Set up GitHub Actions to do this automatically:
|
|
||||||
|
|
||||||
1. Add GitHub Secrets (Settings → Secrets → Actions):
|
|
||||||
- `GPG_PRIVATE_KEY` - Your exported private key
|
|
||||||
- `GPG_KEY_ID` - Your GPG key ID
|
|
||||||
- `GPG_PASSPHRASE` - Your GPG passphrase (if any)
|
|
||||||
|
|
||||||
2. Tag and push:
|
|
||||||
```bash
|
|
||||||
git tag v1.51.0
|
|
||||||
git push origin main --tags
|
|
||||||
```
|
|
||||||
|
|
||||||
3. GitHub Actions will automatically:
|
|
||||||
- Build packages for AMD64 and ARM64
|
|
||||||
- Update apt-repo
|
|
||||||
- Sign with your GPG key
|
|
||||||
- Push to gh-pages
|
|
||||||
- Create GitHub Release
|
|
||||||
|
|
||||||
See `.github/workflows/publish-apt-repo.yml` for details.
|
|
||||||
|
|
||||||
## Customizing Your GitHub Pages Site
|
|
||||||
|
|
||||||
The `gh-pages` branch contains `index.html` which users see when they visit:
|
|
||||||
`https://YOUR-USERNAME.github.io/socktop/`
|
|
||||||
|
|
||||||
You can customize this! On the `gh-pages` branch:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git checkout gh-pages
|
|
||||||
|
|
||||||
# Edit index.html
|
|
||||||
nano index.html
|
|
||||||
|
|
||||||
# Add features, badges, screenshots, etc.
|
|
||||||
|
|
||||||
git add index.html
|
|
||||||
git commit -m "Improve landing page"
|
|
||||||
git push origin gh-pages
|
|
||||||
|
|
||||||
git checkout main
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### "404 Not Found" on GitHub Pages
|
|
||||||
|
|
||||||
**Check:**
|
|
||||||
- Settings → Pages shows "Your site is live at..."
|
|
||||||
- Wait 2-3 minutes after pushing
|
|
||||||
- Verify branch is `gh-pages` and folder is `/`
|
|
||||||
- Check Actions tab for deployment errors
|
|
||||||
|
|
||||||
### "Repository not found" when installing
|
|
||||||
|
|
||||||
**Check:**
|
|
||||||
- URL is correct: `https://USERNAME.github.io/REPO/` (no trailing /apt-repo)
|
|
||||||
- Files exist at the URLs:
|
|
||||||
```bash
|
|
||||||
curl -I https://USERNAME.github.io/REPO/dists/stable/InRelease
|
|
||||||
curl -I https://USERNAME.github.io/REPO/KEY.gpg
|
|
||||||
```
|
|
||||||
|
|
||||||
### "GPG error" when installing
|
|
||||||
|
|
||||||
**Check:**
|
|
||||||
- Repository is signed: `ls gh-pages/dists/stable/Release.gpg`
|
|
||||||
- Users imported the key: `curl https://USERNAME.github.io/REPO/KEY.gpg | gpg --import`
|
|
||||||
|
|
||||||
### Changes not appearing
|
|
||||||
|
|
||||||
**Check:**
|
|
||||||
- You committed and pushed to `gh-pages` (not `main`)
|
|
||||||
- Wait 1-2 minutes for GitHub to redeploy
|
|
||||||
- Clear browser cache if viewing index.html
|
|
||||||
- For apt: `sudo apt clean && sudo apt update`
|
|
||||||
|
|
||||||
## Success Checklist
|
|
||||||
|
|
||||||
After completing this guide, you should have:
|
|
||||||
|
|
||||||
- [ ] `gh-pages` branch created and pushed
|
|
||||||
- [ ] GitHub Pages enabled and deployed
|
|
||||||
- [ ] Site accessible at `https://USERNAME.github.io/socktop/`
|
|
||||||
- [ ] `KEY.gpg` downloadable
|
|
||||||
- [ ] `dists/stable/InRelease` accessible
|
|
||||||
- [ ] Packages in `pool/main/*.deb` downloadable
|
|
||||||
- [ ] Successfully tested installation on a test system
|
|
||||||
- [ ] Understand the workflow for future updates
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
1. **Update your main README.md** with installation instructions
|
|
||||||
2. **Set up GitHub Actions** for automated releases
|
|
||||||
3. **Customize index.html** on gh-pages for a nice landing page
|
|
||||||
4. **Test on multiple architectures** (AMD64, ARM64)
|
|
||||||
5. **Share your repository** with users
|
|
||||||
|
|
||||||
## Quick Reference
|
|
||||||
|
|
||||||
**Switch branches:**
|
|
||||||
```bash
|
|
||||||
git checkout main # Development
|
|
||||||
git checkout gh-pages # Published site
|
|
||||||
```
|
|
||||||
|
|
||||||
**Update published site manually:**
|
|
||||||
```bash
|
|
||||||
git checkout main
|
|
||||||
# ... build packages, update apt-repo ...
|
|
||||||
git checkout gh-pages
|
|
||||||
cp -r apt-repo/* .
|
|
||||||
git add . && git commit -m "Update" && git push
|
|
||||||
git checkout main
|
|
||||||
```
|
|
||||||
|
|
||||||
**Your repository URL:**
|
|
||||||
```
|
|
||||||
https://YOUR-USERNAME.github.io/socktop/
|
|
||||||
```
|
|
||||||
|
|
||||||
**User installation command:**
|
|
||||||
```bash
|
|
||||||
curl -fsSL https://YOUR-USERNAME.github.io/socktop/KEY.gpg | \
|
|
||||||
sudo gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg
|
|
||||||
echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://YOUR-USERNAME.github.io/socktop stable main" | \
|
|
||||||
sudo tee /etc/apt/sources.list.d/socktop.list
|
|
||||||
sudo apt update && sudo apt install socktop socktop-agent
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Need help?** See:
|
|
||||||
- `QUICK_START_APT_REPO.md` - Overall quick start
|
|
||||||
- `docs/APT_REPOSITORY.md` - Comprehensive guide
|
|
||||||
- `docs/APT_WORKFLOW.md` - Visual workflow diagrams
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
# Why We Use the gh-pages Branch
|
|
||||||
|
|
||||||
## The Problem
|
|
||||||
|
|
||||||
GitHub Pages has a limitation - it can only serve static sites from:
|
|
||||||
|
|
||||||
1. **`/` (root)** of a branch
|
|
||||||
2. **`/docs`** directory of a branch
|
|
||||||
3. **NOT** from custom directories like `/apt-repo`
|
|
||||||
|
|
||||||
## Why Not `/docs`?
|
|
||||||
|
|
||||||
When you tried to enable GitHub Pages with `apt-repo/` checked into main, you couldn't select it because:
|
|
||||||
|
|
||||||
```
|
|
||||||
main/
|
|
||||||
├── src/
|
|
||||||
├── Cargo.toml
|
|
||||||
├── apt-repo/ ← GitHub Pages can't serve from here!
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
You could move it to `/docs`:
|
|
||||||
```
|
|
||||||
main/
|
|
||||||
├── src/
|
|
||||||
├── Cargo.toml
|
|
||||||
├── docs/ ← GitHub Pages CAN serve from here
|
|
||||||
│ ├── dists/
|
|
||||||
│ ├── pool/
|
|
||||||
│ └── ...
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
But this has downsides:
|
|
||||||
- ❌ Mixed source code and published content
|
|
||||||
- ❌ Large .deb files bloat the main branch
|
|
||||||
- ❌ Can't easily customize the site without affecting source
|
|
||||||
- ❌ Messy git history with binary files
|
|
||||||
|
|
||||||
## Why gh-pages Branch (Our Solution)
|
|
||||||
|
|
||||||
Using a separate `gh-pages` branch is cleaner:
|
|
||||||
|
|
||||||
```
|
|
||||||
main branch (source code):
|
|
||||||
├── src/
|
|
||||||
├── Cargo.toml
|
|
||||||
├── scripts/
|
|
||||||
└── docs/ ← Documentation source
|
|
||||||
|
|
||||||
gh-pages branch (published):
|
|
||||||
├── dists/
|
|
||||||
├── pool/
|
|
||||||
├── KEY.gpg
|
|
||||||
├── index.html ← Customizable landing page
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### Benefits
|
|
||||||
|
|
||||||
✅ **Clean separation**: Source code stays in `main`, published content in `gh-pages`
|
|
||||||
✅ **No binary bloat**: .deb files don't clutter your main branch history
|
|
||||||
✅ **Easy automation**: GitHub Actions can push to gh-pages without affecting main
|
|
||||||
✅ **Customizable**: You can make a beautiful landing page on gh-pages
|
|
||||||
✅ **Standard practice**: Most GitHub Pages projects use gh-pages branch
|
|
||||||
✅ **Root URL**: Your repo is at `https://username.github.io/socktop/` (not `/apt-repo`)
|
|
||||||
|
|
||||||
### Workflow
|
|
||||||
|
|
||||||
```
|
|
||||||
Developer (main branch)
|
|
||||||
↓
|
|
||||||
Build packages
|
|
||||||
↓
|
|
||||||
Update apt-repo/ (local)
|
|
||||||
↓
|
|
||||||
Push to gh-pages branch
|
|
||||||
↓
|
|
||||||
GitHub Pages serves
|
|
||||||
↓
|
|
||||||
Users: apt install socktop
|
|
||||||
```
|
|
||||||
|
|
||||||
## The Setup
|
|
||||||
|
|
||||||
**One-time setup:**
|
|
||||||
```bash
|
|
||||||
git checkout --orphan gh-pages
|
|
||||||
git rm -rf .
|
|
||||||
cp -r apt-repo/* .
|
|
||||||
rm -rf apt-repo
|
|
||||||
git add . && git commit -m "Initialize APT repository"
|
|
||||||
git push -u origin gh-pages
|
|
||||||
git checkout main
|
|
||||||
```
|
|
||||||
|
|
||||||
**Going forward:**
|
|
||||||
- Work on `main` branch for development
|
|
||||||
- `gh-pages` branch gets updated by GitHub Actions (or manually)
|
|
||||||
- Never need to switch branches manually after automation is set up!
|
|
||||||
|
|
||||||
## Comparison
|
|
||||||
|
|
||||||
| Approach | Location | URL | Pros | Cons |
|
|
||||||
|----------|----------|-----|------|------|
|
|
||||||
| **gh-pages branch** ✅ | gh-pages:/ | `username.github.io/socktop/` | Clean, automated, customizable | Two branches |
|
|
||||||
| `/docs` on main | main:/docs | `username.github.io/socktop/` | One branch | Mixed content, binary bloat |
|
|
||||||
| `/apt-repo` on main | main:/apt-repo | ❌ Not possible | - | GitHub Pages won't allow it |
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
The `gh-pages` branch approach is:
|
|
||||||
- The **cleanest** solution
|
|
||||||
- The **most flexible** for customization
|
|
||||||
- The **easiest to automate**
|
|
||||||
- **Industry standard** for GitHub Pages
|
|
||||||
|
|
||||||
That's why we chose it! 🚀
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNED MESSAGE-----
|
|
||||||
Hash: SHA512
|
|
||||||
|
|
||||||
Origin: socktop
|
|
||||||
Label: socktop
|
|
||||||
Suite: stable
|
|
||||||
Codename: stable
|
|
||||||
Architectures: amd64 arm64 armhf riscv64
|
|
||||||
Components: main
|
|
||||||
Description: socktop APT repository
|
|
||||||
Date: Mon, 24 Aug 2026 14:30:55 +0000
|
|
||||||
MD5Sum:
|
|
||||||
ada07cbd3ac088cecb5dc9d08518823d 1627 main/binary-amd64/Packages
|
|
||||||
fbb8924917960d65b5bcad003ccb90c2 830 main/binary-amd64/Packages.gz
|
|
||||||
71b8d2e69d19d4db385bc3f2be603b72 1627 main/binary-arm64/Packages
|
|
||||||
70831c731ff47542094fe3417e385aa6 830 main/binary-arm64/Packages.gz
|
|
||||||
129d1b34bf48c75861a188d6ae8fba77 1611 main/binary-armhf/Packages
|
|
||||||
54e691233b47bb1f0d89f82b00d9403f 814 main/binary-armhf/Packages.gz
|
|
||||||
4c3fc0b399405dd682dac1318adda05f 1623 main/binary-riscv64/Packages
|
|
||||||
15bcbe1806bf2577849090556c3a2a81 817 main/binary-riscv64/Packages.gz
|
|
||||||
SHA256:
|
|
||||||
88a907a84f4d292e34426d71e328561aba9658440e588f62f0f3b5d7f5c5f121 1627 main/binary-amd64/Packages
|
|
||||||
3a87b0b38cb79d231b8ed66e1fdc9a54369d0d3f2f0686f6513cece15f0dc967 830 main/binary-amd64/Packages.gz
|
|
||||||
84a43993bf58648174ef5bf1d4542e96f5d7903acedc0405f8f3aeab4fdbb4e7 1627 main/binary-arm64/Packages
|
|
||||||
fd8e6a7ec2b7c438659b0fe8fa825670ccfbeb2298c01b55020cbdad2acb3313 830 main/binary-arm64/Packages.gz
|
|
||||||
63a89cdee8e5c93867b2dd5193df162304ea97855ad68135c5c5d0753700102c 1611 main/binary-armhf/Packages
|
|
||||||
c81f19a798757bd1806bb860aba238757edf1b902338554e30bcddba86b3c02b 814 main/binary-armhf/Packages.gz
|
|
||||||
fa590edf01fbdd63817bd1cee4ab49d93bd47d60d74ecdae961cfa927e5b0526 1623 main/binary-riscv64/Packages
|
|
||||||
3815e37b15c4ac150e23ce76786bfda0165e325d00b3650466442356ac39221b 817 main/binary-riscv64/Packages.gz
|
|
||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQGzBAEBCgAdFiEEHnVWqAU5uDlLwoINESwaeYRl+/IFAmqMVaEACgkQESwaeYRl
|
|
||||||
+/JqUQv+PFvgvw2yMwX1jfCeyKAfc/BmWIitVo5eOYS4P4iMqnOLGP9M44okbhgH
|
|
||||||
Ss7l9kg13Bmtn3TdF6eWOoyfhb/Zchpf5O4xeaXLCBsaTjFtX2BAgg7Z441AkEVP
|
|
||||||
AzaGcmbev6+R7EM3EEqk0fvVLyYHWw9qY9ADC+ArZ7GxYgVgAkIcM2V1bzjJQtOw
|
|
||||||
dYR2XwGWiFZet62DXVsCs6g26tUyvmR062GcKmk1xQY/g9SbOqPXYP7Uou5hw+UZ
|
|
||||||
QAY9LFnCWDz0OATclIKZzqhp7oMjWe3T96d/25lV+fQ2Cmk7ayPGaTrpeTnvCfzO
|
|
||||||
u46DIQkkTpyalhZPcC0hgCg9tbh2rzAF6ETy+oKmYYE8wEA8wqIvJdGt1RZT/IUg
|
|
||||||
SQEma61GavK0nBVjPjEjchT5hfTgS03YBea15lA5sZiEAD0SOV4QHxbbVmszGEaQ
|
|
||||||
Ha4AnRLBji9Ea5E3848QTJLPq1BZ7zLvU6Tn8Nlutuh2doizSQlX3xSozvUV9BYp
|
|
||||||
bWU/J6Ye
|
|
||||||
=8uE3
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
Origin: socktop
|
|
||||||
Label: socktop
|
|
||||||
Suite: stable
|
|
||||||
Codename: stable
|
|
||||||
Architectures: amd64 arm64 armhf riscv64
|
|
||||||
Components: main
|
|
||||||
Description: socktop APT repository
|
|
||||||
Date: Mon, 24 Aug 2026 14:30:55 +0000
|
|
||||||
MD5Sum:
|
|
||||||
ada07cbd3ac088cecb5dc9d08518823d 1627 main/binary-amd64/Packages
|
|
||||||
fbb8924917960d65b5bcad003ccb90c2 830 main/binary-amd64/Packages.gz
|
|
||||||
71b8d2e69d19d4db385bc3f2be603b72 1627 main/binary-arm64/Packages
|
|
||||||
70831c731ff47542094fe3417e385aa6 830 main/binary-arm64/Packages.gz
|
|
||||||
129d1b34bf48c75861a188d6ae8fba77 1611 main/binary-armhf/Packages
|
|
||||||
54e691233b47bb1f0d89f82b00d9403f 814 main/binary-armhf/Packages.gz
|
|
||||||
4c3fc0b399405dd682dac1318adda05f 1623 main/binary-riscv64/Packages
|
|
||||||
15bcbe1806bf2577849090556c3a2a81 817 main/binary-riscv64/Packages.gz
|
|
||||||
SHA256:
|
|
||||||
88a907a84f4d292e34426d71e328561aba9658440e588f62f0f3b5d7f5c5f121 1627 main/binary-amd64/Packages
|
|
||||||
3a87b0b38cb79d231b8ed66e1fdc9a54369d0d3f2f0686f6513cece15f0dc967 830 main/binary-amd64/Packages.gz
|
|
||||||
84a43993bf58648174ef5bf1d4542e96f5d7903acedc0405f8f3aeab4fdbb4e7 1627 main/binary-arm64/Packages
|
|
||||||
fd8e6a7ec2b7c438659b0fe8fa825670ccfbeb2298c01b55020cbdad2acb3313 830 main/binary-arm64/Packages.gz
|
|
||||||
63a89cdee8e5c93867b2dd5193df162304ea97855ad68135c5c5d0753700102c 1611 main/binary-armhf/Packages
|
|
||||||
c81f19a798757bd1806bb860aba238757edf1b902338554e30bcddba86b3c02b 814 main/binary-armhf/Packages.gz
|
|
||||||
fa590edf01fbdd63817bd1cee4ab49d93bd47d60d74ecdae961cfa927e5b0526 1623 main/binary-riscv64/Packages
|
|
||||||
3815e37b15c4ac150e23ce76786bfda0165e325d00b3650466442356ac39221b 817 main/binary-riscv64/Packages.gz
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQGzBAABCgAdFiEEHnVWqAU5uDlLwoINESwaeYRl+/IFAmqMVZ8ACgkQESwaeYRl
|
|
||||||
+/JgAgwA1xKy+N7n4S4bjP1LxoLDa0fOHnxORd2dajYHkA6NqORSd2KPgWqBwtlA
|
|
||||||
TGA8wJ8Gurdluu6kaZ8rJ55PUVZFX2qU/UsXy0Pn1Kp2NMuMhdkzXUuYI/oKILof
|
|
||||||
TtYKqubJ4+LZvfrCdOWusDGhybA4DXaPGm+/EjJ6xKJDm0N6Ht4YhUlb9uTFH8jr
|
|
||||||
y/hzl9Qcp2GoaDIXoLQCYPfUePHSH7JRn77uuKu3DKC3rwP2QXyBDNfWRJY0X89L
|
|
||||||
fGBzAxgj2jE7/Gn/T3X3QGTsSAlZeuEIu88/+qwyi3kq7SeBWFf70kGHFS3RPAmh
|
|
||||||
ULMpQe44N0H3faBIC1wER/P12NIDCi633XkL5WVwA+HvSWk8DZGu+cV4s7BcmWbD
|
|
||||||
8KOcJe9dEoYpcGbxpZMqe0iCc6pr7vQ5FBlt0Zj0LzvONSL55kH8L7tG/uX4VXcM
|
|
||||||
g6LLLJjm6oLWT8U8QNskOgAVxTgyZgHUVa2cAG0jZp0BErSegg38mHLs3QXtdySc
|
|
||||||
xd4t41hM
|
|
||||||
=OG4V
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
Package: socktop
|
|
||||||
Version: 1.60.2-1
|
|
||||||
Architecture: amd64
|
|
||||||
Maintainer: Jason Witty <jasonpwitty+socktop@proton.me>
|
|
||||||
Installed-Size: 3441
|
|
||||||
Depends: libc6 (>= 2.34)
|
|
||||||
Filename: pool/main/socktop_1.60.2-1_amd64.deb
|
|
||||||
Size: 1313748
|
|
||||||
MD5sum: 24517013f7e9683f2bbbbf07debdffca
|
|
||||||
SHA1: c5c9498bfcc8a8d21342f1f4b5797e4c000462d7
|
|
||||||
SHA256: b5d21f5f322af61e7ea6846ba337e5e48697969cf40b098d01ad4927c912d6e6
|
|
||||||
Section: admin
|
|
||||||
Priority: optional
|
|
||||||
Homepage: https://github.com/jasonwitty/socktop
|
|
||||||
Description: Remote system monitor over WebSocket, TUI like top
|
|
||||||
socktop is a remote system monitor with a rich terminal user interface (TUI)
|
|
||||||
that connects to remote hosts running the socktop_agent over WebSocket. It
|
|
||||||
provides real-time monitoring of CPU, memory, processes, and more with an
|
|
||||||
interface similar to the traditional 'top' command.
|
|
||||||
|
|
||||||
Package: socktop-agent
|
|
||||||
Version: 1.60.2-1
|
|
||||||
Architecture: amd64
|
|
||||||
Maintainer: Jason Witty <jasonpwitty+socktop@proton.me>
|
|
||||||
Installed-Size: 6537
|
|
||||||
Depends: libc6 (>= 2.34), libdrm-amdgpu1 (>= 2.4.80)
|
|
||||||
Filename: pool/main/socktop-agent_1.60.2-1_amd64.deb
|
|
||||||
Size: 1858208
|
|
||||||
MD5sum: fa4f1a29b22fe191140787da50c70cd1
|
|
||||||
SHA1: b310e7f5a29be4d18add88a6b30437eb34d2e6a1
|
|
||||||
SHA256: 328975156e28ffc2d38a23c317406b9220f0062992f97bfea327403ba6d26d71
|
|
||||||
Section: admin
|
|
||||||
Priority: optional
|
|
||||||
Homepage: https://github.com/jasonwitty/socktop
|
|
||||||
Description: Socktop agent daemon. Serves host metrics over WebSocket.
|
|
||||||
socktop_agent is the daemon component that runs on remote hosts to collect and
|
|
||||||
serve system metrics over WebSocket. It gathers CPU, memory, disk, network,
|
|
||||||
GPU, and process information that can be monitored remotely by the socktop TUI
|
|
||||||
client.
|
|
||||||
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
Archive: stable
|
|
||||||
Component: main
|
|
||||||
Origin: socktop
|
|
||||||
Label: socktop
|
|
||||||
Architecture: amd64
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
Package: socktop
|
|
||||||
Version: 1.60.2-1
|
|
||||||
Architecture: arm64
|
|
||||||
Maintainer: Jason Witty <jasonpwitty+socktop@proton.me>
|
|
||||||
Installed-Size: 2994
|
|
||||||
Depends: libc6 (>= 2.34)
|
|
||||||
Filename: pool/main/socktop_1.60.2-1_arm64.deb
|
|
||||||
Size: 1176428
|
|
||||||
MD5sum: 6c628e55b118550964fdd3429ade9013
|
|
||||||
SHA1: 814407491af72cc8c03dfc4aca1fcd29676d84e7
|
|
||||||
SHA256: fb3f29fe439d7e8a6813c52811a4acb9dc5a390acbbe5c8b5a7d77301bf7df39
|
|
||||||
Section: admin
|
|
||||||
Priority: optional
|
|
||||||
Homepage: https://github.com/jasonwitty/socktop
|
|
||||||
Description: Remote system monitor over WebSocket, TUI like top
|
|
||||||
socktop is a remote system monitor with a rich terminal user interface (TUI)
|
|
||||||
that connects to remote hosts running the socktop_agent over WebSocket. It
|
|
||||||
provides real-time monitoring of CPU, memory, processes, and more with an
|
|
||||||
interface similar to the traditional 'top' command.
|
|
||||||
|
|
||||||
Package: socktop-agent
|
|
||||||
Version: 1.60.2-1
|
|
||||||
Architecture: arm64
|
|
||||||
Maintainer: Jason Witty <jasonpwitty+socktop@proton.me>
|
|
||||||
Installed-Size: 5158
|
|
||||||
Depends: libc6 (>= 2.34), libdrm-amdgpu1 (>= 2.4.80)
|
|
||||||
Filename: pool/main/socktop-agent_1.60.2-1_arm64.deb
|
|
||||||
Size: 1648768
|
|
||||||
MD5sum: d40c11e1a82a4deee69a8f09b99b8a3c
|
|
||||||
SHA1: bb17940a085d9cdda0d0ae26aa73843f3b293705
|
|
||||||
SHA256: 9f0779dafe9e2c5029c65201e2d45abb2cc9b9dfae38deb6d650f6c9a5fd07ce
|
|
||||||
Section: admin
|
|
||||||
Priority: optional
|
|
||||||
Homepage: https://github.com/jasonwitty/socktop
|
|
||||||
Description: Socktop agent daemon. Serves host metrics over WebSocket.
|
|
||||||
socktop_agent is the daemon component that runs on remote hosts to collect and
|
|
||||||
serve system metrics over WebSocket. It gathers CPU, memory, disk, network,
|
|
||||||
GPU, and process information that can be monitored remotely by the socktop TUI
|
|
||||||
client.
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
Package: socktop
|
|
||||||
Version: 1.60.2-1
|
|
||||||
Architecture: armhf
|
|
||||||
Maintainer: Jason Witty <jasonpwitty+socktop@proton.me>
|
|
||||||
Installed-Size: 2764
|
|
||||||
Depends: libc6:armhf (>= 2.35)
|
|
||||||
Filename: pool/main/socktop_1.60.2-1_armhf.deb
|
|
||||||
Size: 1029920
|
|
||||||
MD5sum: 731d71c8450006624db51f802a1b75fa
|
|
||||||
SHA1: 7a797ecb089208171bc762a2602af8048b9d74fa
|
|
||||||
SHA256: bfd6d29c18826ed20a9f0e3af2e0f5cc2d24dd23f621110f9d58aed60f7ca1a5
|
|
||||||
Section: admin
|
|
||||||
Priority: optional
|
|
||||||
Homepage: https://github.com/jasonwitty/socktop
|
|
||||||
Description: Remote system monitor over WebSocket, TUI like top
|
|
||||||
socktop is a remote system monitor with a rich terminal user interface (TUI)
|
|
||||||
that connects to remote hosts running the socktop_agent over WebSocket. It
|
|
||||||
provides real-time monitoring of CPU, memory, processes, and more with an
|
|
||||||
interface similar to the traditional 'top' command.
|
|
||||||
|
|
||||||
Package: socktop-agent
|
|
||||||
Version: 1.60.2-1
|
|
||||||
Architecture: armhf
|
|
||||||
Maintainer: Jason Witty <jasonpwitty+socktop@proton.me>
|
|
||||||
Installed-Size: 3821
|
|
||||||
Depends: libc6:armhf (>= 2.35)
|
|
||||||
Filename: pool/main/socktop-agent_1.60.2-1_armhf.deb
|
|
||||||
Size: 1462340
|
|
||||||
MD5sum: b987e05b88a9a32fb3379c54413a1eb0
|
|
||||||
SHA1: c751d0bf6ced067c667895f36379df4bc7b1170c
|
|
||||||
SHA256: c2bcce2e679d96cc9076d118abd9a766ed413f306d88dcc59912814c1962ba04
|
|
||||||
Section: admin
|
|
||||||
Priority: optional
|
|
||||||
Homepage: https://github.com/jasonwitty/socktop
|
|
||||||
Description: Socktop agent daemon. Serves host metrics over WebSocket.
|
|
||||||
socktop_agent is the daemon component that runs on remote hosts to collect and
|
|
||||||
serve system metrics over WebSocket. It gathers CPU, memory, disk, network,
|
|
||||||
GPU, and process information that can be monitored remotely by the socktop TUI
|
|
||||||
client.
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
Package: socktop
|
|
||||||
Version: 1.60.2-1
|
|
||||||
Architecture: riscv64
|
|
||||||
Maintainer: Jason Witty <jasonpwitty+socktop@proton.me>
|
|
||||||
Installed-Size: 2668
|
|
||||||
Depends: libc6:riscv64 (>= 2.35)
|
|
||||||
Filename: pool/main/socktop_1.60.2-1_riscv64.deb
|
|
||||||
Size: 1166192
|
|
||||||
MD5sum: 11e89c1f7909fc90047a74d2880d1362
|
|
||||||
SHA1: 4089962ff3864209a026b585fe2b6490cfe014a2
|
|
||||||
SHA256: e1fad743c74934a11e49808d0bba80c26f05e6d75c231f239870866ba50e1e38
|
|
||||||
Section: admin
|
|
||||||
Priority: optional
|
|
||||||
Homepage: https://github.com/jasonwitty/socktop
|
|
||||||
Description: Remote system monitor over WebSocket, TUI like top
|
|
||||||
socktop is a remote system monitor with a rich terminal user interface (TUI)
|
|
||||||
that connects to remote hosts running the socktop_agent over WebSocket. It
|
|
||||||
provides real-time monitoring of CPU, memory, processes, and more with an
|
|
||||||
interface similar to the traditional 'top' command.
|
|
||||||
|
|
||||||
Package: socktop-agent
|
|
||||||
Version: 1.60.2-1
|
|
||||||
Architecture: riscv64
|
|
||||||
Maintainer: Jason Witty <jasonpwitty+socktop@proton.me>
|
|
||||||
Installed-Size: 3846
|
|
||||||
Depends: libc6:riscv64 (>= 2.35)
|
|
||||||
Filename: pool/main/socktop-agent_1.60.2-1_riscv64.deb
|
|
||||||
Size: 1637096
|
|
||||||
MD5sum: 98347f203e942073464ff8b8d16796bb
|
|
||||||
SHA1: dec2ae6fdd5bea71f43f9e24842a0851150e24fd
|
|
||||||
SHA256: fd4070c6e0b29adf5bb9de32f098431e9dcf7456e1fc7f4460a5e9a5708496cc
|
|
||||||
Section: admin
|
|
||||||
Priority: optional
|
|
||||||
Homepage: https://github.com/jasonwitty/socktop
|
|
||||||
Description: Socktop agent daemon. Serves host metrics over WebSocket.
|
|
||||||
socktop_agent is the daemon component that runs on remote hosts to collect and
|
|
||||||
serve system metrics over WebSocket. It gathers CPU, memory, disk, network,
|
|
||||||
GPU, and process information that can be monitored remotely by the socktop TUI
|
|
||||||
client.
|
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 775 KiB |
|
After Width: | Height: | Size: 879 KiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 2.4 MiB |
@@ -0,0 +1,18 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Socktop agent
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/local/bin/socktop_agent --port 3000
|
||||||
|
Environment=RUST_LOG=info
|
||||||
|
# Optional auth:
|
||||||
|
# Environment=SOCKTOP_TOKEN=changeme
|
||||||
|
Restart=on-failure
|
||||||
|
User=socktop
|
||||||
|
Group=socktop
|
||||||
|
NoNewPrivileges=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
After Width: | Height: | Size: 151 KiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
@@ -1,364 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>socktop APT Repository</title>
|
|
||||||
<style>
|
|
||||||
/* Catppuccin Frappe Color Palette */
|
|
||||||
:root {
|
|
||||||
--ctp-base: #303446;
|
|
||||||
--ctp-mantle: #292c3c;
|
|
||||||
--ctp-crust: #232634;
|
|
||||||
--ctp-text: #c6d0f5;
|
|
||||||
--ctp-subtext1: #b5bfe2;
|
|
||||||
--ctp-subtext0: #a5adce;
|
|
||||||
--ctp-overlay2: #949cbb;
|
|
||||||
--ctp-overlay1: #838ba7;
|
|
||||||
--ctp-overlay0: #737994;
|
|
||||||
--ctp-surface2: #626880;
|
|
||||||
--ctp-surface1: #51576d;
|
|
||||||
--ctp-surface0: #414559;
|
|
||||||
--ctp-lavender: #babbf1;
|
|
||||||
--ctp-blue: #8caaee;
|
|
||||||
--ctp-sapphire: #85c1dc;
|
|
||||||
--ctp-sky: #99d1db;
|
|
||||||
--ctp-teal: #81c8be;
|
|
||||||
--ctp-green: #a6d189;
|
|
||||||
--ctp-yellow: #e5c890;
|
|
||||||
--ctp-peach: #ef9f76;
|
|
||||||
--ctp-maroon: #ea999c;
|
|
||||||
--ctp-red: #e78284;
|
|
||||||
--ctp-mauve: #ca9ee6;
|
|
||||||
--ctp-pink: #f4b8e4;
|
|
||||||
--ctp-flamingo: #eebebe;
|
|
||||||
--ctp-rosewater: #f2d5cf;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family:
|
|
||||||
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
||||||
"Helvetica Neue", Arial, sans-serif;
|
|
||||||
background-color: var(--ctp-base);
|
|
||||||
color: var(--ctp-text);
|
|
||||||
line-height: 1.6;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 900px;
|
|
||||||
margin: 0 auto;
|
|
||||||
background-color: var(--ctp-mantle);
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 40px;
|
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: var(--ctp-blue);
|
|
||||||
font-size: 2.5em;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border-bottom: 3px solid var(--ctp-surface0);
|
|
||||||
padding-bottom: 15px;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
color: var(--ctp-mauve);
|
|
||||||
font-size: 1.8em;
|
|
||||||
margin-top: 35px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
color: var(--ctp-sapphire);
|
|
||||||
font-size: 1.3em;
|
|
||||||
margin-top: 25px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
color: var(--ctp-subtext0);
|
|
||||||
}
|
|
||||||
.subtitle {
|
|
||||||
color: var(--ctp-subtext1);
|
|
||||||
font-size: 1.2em;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
background-color: var(--ctp-surface0);
|
|
||||||
color: var(--ctp-green);
|
|
||||||
padding: 3px 8px;
|
|
||||||
border-radius: 5px;
|
|
||||||
font-family: "Courier New", Courier, monospace;
|
|
||||||
font-size: 0.95em;
|
|
||||||
}
|
|
||||||
pre {
|
|
||||||
background-color: var(--ctp-crust);
|
|
||||||
border: 1px solid var(--ctp-surface0);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 20px;
|
|
||||||
overflow-x: auto;
|
|
||||||
margin: 15px 0;
|
|
||||||
position: relative;
|
|
||||||
padding-top: 18px; /* leave space for top-right button */
|
|
||||||
}
|
|
||||||
pre code {
|
|
||||||
background: transparent;
|
|
||||||
color: var(--ctp-text);
|
|
||||||
display: block;
|
|
||||||
white-space: pre;
|
|
||||||
font-family: "Courier New", Courier, monospace;
|
|
||||||
font-size: 0.95em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy button styles */
|
|
||||||
.copy-btn {
|
|
||||||
position: absolute;
|
|
||||||
top: 8px;
|
|
||||||
right: 8px;
|
|
||||||
background: var(--ctp-surface1);
|
|
||||||
color: var(--ctp-text);
|
|
||||||
border: 1px solid var(--ctp-surface2);
|
|
||||||
padding: 6px 8px;
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
transition:
|
|
||||||
background 0.12s ease,
|
|
||||||
transform 0.08s ease;
|
|
||||||
}
|
|
||||||
.copy-btn:hover {
|
|
||||||
background: var(--ctp-surface2);
|
|
||||||
transform: translateY(-1px);
|
|
||||||
}
|
|
||||||
.copy-btn:active {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
.copy-btn.copied {
|
|
||||||
background: var(--ctp-green);
|
|
||||||
color: var(--ctp-crust);
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
|
||||||
display: inline-block;
|
|
||||||
background-color: var(--ctp-surface1);
|
|
||||||
color: var(--ctp-text);
|
|
||||||
padding: 5px 12px;
|
|
||||||
border-radius: 6px;
|
|
||||||
font-size: 0.9em;
|
|
||||||
margin: 5px 5px 5px 0;
|
|
||||||
border: 1px solid var(--ctp-surface2);
|
|
||||||
}
|
|
||||||
.badge.arch {
|
|
||||||
background-color: var(--ctp-surface0);
|
|
||||||
color: var(--ctp-lavender);
|
|
||||||
}
|
|
||||||
|
|
||||||
.note {
|
|
||||||
background-color: var(--ctp-surface0);
|
|
||||||
border-left: 4px solid var(--ctp-yellow);
|
|
||||||
padding: 15px;
|
|
||||||
margin: 20px 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
.note strong {
|
|
||||||
color: var(--ctp-yellow);
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
margin-top: 50px;
|
|
||||||
padding-top: 20px;
|
|
||||||
border-top: 2px solid var(--ctp-surface0);
|
|
||||||
text-align: center;
|
|
||||||
color: var(--ctp-overlay1);
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.command-comment {
|
|
||||||
color: var(--ctp-overlay1);
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.highlight-blue {
|
|
||||||
color: var(--ctp-blue);
|
|
||||||
}
|
|
||||||
.highlight-green {
|
|
||||||
color: var(--ctp-green);
|
|
||||||
}
|
|
||||||
.highlight-yellow {
|
|
||||||
color: var(--ctp-yellow);
|
|
||||||
}
|
|
||||||
.highlight-mauve {
|
|
||||||
color: var(--ctp-mauve);
|
|
||||||
}
|
|
||||||
.highlight-peach {
|
|
||||||
color: var(--ctp-peach);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.container {
|
|
||||||
padding: 25px;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font-size: 2em;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>socktop APT Repository</h1>
|
|
||||||
<p class="subtitle">
|
|
||||||
System monitor with remote agent support for Linux systems
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>📦 Quick Installation</h2>
|
|
||||||
<p>Add this repository to your Debian/Ubuntu system:</p>
|
|
||||||
|
|
||||||
<h3>Step 1: Add GPG Key</h3>
|
|
||||||
<pre><code># Add the repository's GPG signing key
|
|
||||||
curl -fsSL https://jasonwitty.github.io/socktop/KEY.gpg | \
|
|
||||||
sudo gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg</code></pre>
|
|
||||||
|
|
||||||
<h3>Step 2: Add Repository</h3>
|
|
||||||
<pre><code># Add the APT repository to your sources
|
|
||||||
echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://jasonwitty.github.io/socktop stable main" | \
|
|
||||||
sudo tee /etc/apt/sources.list.d/socktop.list</code></pre>
|
|
||||||
|
|
||||||
<h3>Step 3: Install</h3>
|
|
||||||
<pre><code># Update package lists and install
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install socktop socktop-agent</code></pre>
|
|
||||||
|
|
||||||
<h2>📋 What's Included</h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<strong class="highlight-blue">socktop</strong> - Terminal
|
|
||||||
UI client for monitoring systems
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<strong class="highlight-mauve">socktop-agent</strong> -
|
|
||||||
Background agent that reports system metrics
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="note">
|
|
||||||
<strong>Note:</strong> The agent package automatically installs
|
|
||||||
and configures a systemd service. Enable it with:
|
|
||||||
<code>sudo systemctl enable --now socktop-agent</code>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>🏗️ Supported Architectures</h2>
|
|
||||||
<div>
|
|
||||||
<span class="badge arch">amd64</span>
|
|
||||||
<span class="badge arch">arm64</span>
|
|
||||||
<span class="badge arch">armhf</span>
|
|
||||||
<span class="badge arch">riscv64</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>🔧 Usage</h2>
|
|
||||||
<p>After installation:</p>
|
|
||||||
<pre><code># Start the TUI client
|
|
||||||
socktop
|
|
||||||
|
|
||||||
# Connect to a remote agent
|
|
||||||
socktop ws://hostname:3000
|
|
||||||
|
|
||||||
# Start the agent (if not using systemd)
|
|
||||||
socktop_agent</code></pre>
|
|
||||||
|
|
||||||
<h2>🔗 Links</h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="https://github.com/jasonwitty/socktop"
|
|
||||||
>Source Code on GitHub</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://github.com/jasonwitty/socktop/issues"
|
|
||||||
>Report Issues</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li><a href="README.md">Repository Documentation</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="footer">
|
|
||||||
<p>Hosted on GitHub Pages | Packages signed with GPG</p>
|
|
||||||
<p>
|
|
||||||
Theme:
|
|
||||||
<a href="https://github.com/catppuccin/catppuccin"
|
|
||||||
>Catppuccin Frappe</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Attach copy buttons to all <pre> blocks and enable copy-to-clipboard.
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
|
||||||
const pres = document.querySelectorAll("pre");
|
|
||||||
pres.forEach((pre) => {
|
|
||||||
// Create button
|
|
||||||
const btn = document.createElement("button");
|
|
||||||
btn.type = "button";
|
|
||||||
btn.className = "copy-btn";
|
|
||||||
btn.setAttribute("aria-label", "Copy code to clipboard");
|
|
||||||
// Use emoji for simplicity; you can replace with SVG if desired
|
|
||||||
btn.innerText = "📋";
|
|
||||||
|
|
||||||
// Append to pre
|
|
||||||
pre.appendChild(btn);
|
|
||||||
|
|
||||||
// Click handler
|
|
||||||
btn.addEventListener("click", async (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
const code = pre.querySelector("code");
|
|
||||||
const text = code ? code.innerText : pre.innerText;
|
|
||||||
try {
|
|
||||||
if (!navigator.clipboard) {
|
|
||||||
// Fallback method
|
|
||||||
const textarea =
|
|
||||||
document.createElement("textarea");
|
|
||||||
textarea.value = text;
|
|
||||||
textarea.style.position = "fixed";
|
|
||||||
textarea.style.left = "-9999px";
|
|
||||||
document.body.appendChild(textarea);
|
|
||||||
textarea.select();
|
|
||||||
document.execCommand("copy");
|
|
||||||
document.body.removeChild(textarea);
|
|
||||||
} else {
|
|
||||||
await navigator.clipboard.writeText(text);
|
|
||||||
}
|
|
||||||
// feedback
|
|
||||||
btn.classList.add("copied");
|
|
||||||
const prior = btn.innerText;
|
|
||||||
btn.innerText = "✓ Copied";
|
|
||||||
setTimeout(() => {
|
|
||||||
btn.classList.remove("copied");
|
|
||||||
btn.innerText = "📋";
|
|
||||||
}, 1800);
|
|
||||||
} catch (err) {
|
|
||||||
btn.innerText = "✖";
|
|
||||||
setTimeout(() => (btn.innerText = "📋"), 1500);
|
|
||||||
console.error("Copy failed", err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
socktop_agent: TLS enabled. Listening on wss://0.0.0.0:8433/ws
|
||||||
|
socktop_agent: TLS enabled. Listening on wss://0.0.0.0:8433/ws
|
||||||
|
socktop_agent: TLS enabled. Listening on wss://0.0.0.0:8433/ws
|
||||||
|
Error: Address already in use (os error 98)
|
||||||
|
socktop_agent: TLS enabled. Listening on wss://0.0.0.0:8433/ws
|
||||||
|
Error: Address already in use (os error 98)
|
||||||
|
socktop_agent: TLS enabled. Listening on wss://0.0.0.0:8443/ws
|
||||||
|
socktop_agent: TLS enabled. Listening on wss://0.0.0.0:8443/ws
|
||||||