mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-27 09:04:13 +00:00
Compare commits
95 Commits
v0.102.2-n
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82c477266d | ||
|
|
169be97026 | ||
|
|
4b7c342c77 | ||
|
|
7d5ccc0678 | ||
|
|
1ca779880b | ||
|
|
3b779cd5a0 | ||
|
|
b94fd1efcd | ||
|
|
abcc23c4f3 | ||
|
|
ebaf37e9d0 | ||
|
|
7c165b9579 | ||
|
|
c536e45d0f | ||
|
|
655bd92178 | ||
|
|
211c0275d3 | ||
|
|
5456d57aeb | ||
|
|
8ea4499052 | ||
|
|
6657c90e36 | ||
|
|
0764ac287e | ||
|
|
c4fd1878a7 | ||
|
|
3d70f92ed5 | ||
|
|
fa826f0d00 | ||
|
|
733b059681 | ||
|
|
78d876e71b | ||
|
|
6468019136 | ||
|
|
e2b6f7d721 | ||
|
|
fd87eec476 | ||
|
|
a0468461ab | ||
|
|
2f5718146a | ||
|
|
f26676db2c | ||
|
|
fade8f89ed | ||
|
|
ed4e490463 | ||
|
|
6898f47e2e | ||
|
|
f0d2621199 | ||
|
|
c6998b6ac2 | ||
|
|
45a8285ae8 | ||
|
|
80e26f33fb | ||
|
|
25495448ed | ||
|
|
1882876922 | ||
|
|
7227e5ceb9 | ||
|
|
7f1c592235 | ||
|
|
72fb5f1a5a | ||
|
|
2fecebc0c2 | ||
|
|
85eb98ed34 | ||
|
|
714a986a78 | ||
|
|
bcfdabb32d | ||
|
|
3597c61cfc | ||
|
|
552fde428e | ||
|
|
ca86becf85 | ||
|
|
bfff2a241b | ||
|
|
3e9ef5ac6c | ||
|
|
f1dc3014fc | ||
|
|
19463b8621 | ||
|
|
a79ae41dd5 | ||
|
|
e4d51676cc | ||
|
|
e6f828d6f1 | ||
|
|
8ee606bfb1 | ||
|
|
58ea896cb0 | ||
|
|
d256a83fb7 | ||
|
|
c731486454 | ||
|
|
8cabe48f7d | ||
|
|
c499b2d76e | ||
|
|
4ebf558719 | ||
|
|
2b0bfaaa12 | ||
|
|
a71b979036 | ||
|
|
106c2df4d2 | ||
|
|
40600c3557 | ||
|
|
aa2da83969 | ||
|
|
bb98418ac9 | ||
|
|
b58e1d80ee | ||
|
|
4f1709e136 | ||
|
|
83804422c4 | ||
|
|
8aef779fcd | ||
|
|
0b5b6e68e3 | ||
|
|
f889c2e358 | ||
|
|
1e38fc2861 | ||
|
|
88ba08fcba | ||
|
|
865a4f3434 | ||
|
|
7163aad850 | ||
|
|
25a167f9b4 | ||
|
|
bc9cbb3627 | ||
|
|
ef8002bf13 | ||
|
|
29d255676f | ||
|
|
ba4e2688e4 | ||
|
|
749d5ed5e7 | ||
|
|
afbb7d4ede | ||
|
|
2986e64162 | ||
|
|
1ab63857d3 | ||
|
|
61ccad952a | ||
|
|
85a556d0a0 | ||
|
|
ed82c8ca6b | ||
|
|
266507ef09 | ||
|
|
5fed8a6c88 | ||
|
|
1d186706f6 | ||
|
|
83bd495f0f | ||
|
|
5c73330be6 | ||
|
|
ade6241357 |
91
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
91
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
name: Bug Report
|
||||||
|
description: Report a bug in Orama Network
|
||||||
|
labels: ["bug"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for reporting a bug! Please fill out the sections below.
|
||||||
|
|
||||||
|
**Security issues:** If this is a security vulnerability, do NOT open an issue. Email security@orama.io instead.
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Orama version
|
||||||
|
description: "Run `orama version` to find this"
|
||||||
|
placeholder: "v0.18.0-beta"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: dropdown
|
||||||
|
id: component
|
||||||
|
attributes:
|
||||||
|
label: Component
|
||||||
|
options:
|
||||||
|
- Gateway / API
|
||||||
|
- CLI (orama command)
|
||||||
|
- WireGuard / Networking
|
||||||
|
- RQLite / Storage
|
||||||
|
- Olric / Caching
|
||||||
|
- IPFS / Pinning
|
||||||
|
- CoreDNS
|
||||||
|
- OramaOS
|
||||||
|
- Other
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: A clear description of the bug
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: steps
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: Minimal steps to reproduce the behavior
|
||||||
|
placeholder: |
|
||||||
|
1. Run `orama ...`
|
||||||
|
2. See error
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: expected
|
||||||
|
attributes:
|
||||||
|
label: Expected behavior
|
||||||
|
description: What you expected to happen
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: actual
|
||||||
|
attributes:
|
||||||
|
label: Actual behavior
|
||||||
|
description: What actually happened (include error messages and logs if any)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: environment
|
||||||
|
attributes:
|
||||||
|
label: Environment
|
||||||
|
description: OS, Go version, deployment environment, etc.
|
||||||
|
placeholder: |
|
||||||
|
- OS: Ubuntu 22.04
|
||||||
|
- Go: 1.23
|
||||||
|
- Environment: sandbox
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: context
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
description: Logs, screenshots, monitor reports, or anything else that might help
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
49
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
49
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
name: Feature Request
|
||||||
|
description: Suggest a new feature or improvement
|
||||||
|
labels: ["enhancement"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for the suggestion! Please describe what you'd like to see.
|
||||||
|
|
||||||
|
- type: dropdown
|
||||||
|
id: component
|
||||||
|
attributes:
|
||||||
|
label: Component
|
||||||
|
options:
|
||||||
|
- Gateway / API
|
||||||
|
- CLI (orama command)
|
||||||
|
- WireGuard / Networking
|
||||||
|
- RQLite / Storage
|
||||||
|
- Olric / Caching
|
||||||
|
- IPFS / Pinning
|
||||||
|
- CoreDNS
|
||||||
|
- OramaOS
|
||||||
|
- Other
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Problem
|
||||||
|
description: What problem does this solve? Why do you need it?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: Proposed solution
|
||||||
|
description: How do you think this should work?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: Alternatives considered
|
||||||
|
description: Any workarounds or alternative approaches you've thought of
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
31
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
31
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
## Summary
|
||||||
|
|
||||||
|
<!-- What does this PR do? Keep it to 1-3 bullet points. -->
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
<!-- Why is this change needed? Link to an issue if applicable. -->
|
||||||
|
|
||||||
|
## Test plan
|
||||||
|
|
||||||
|
<!-- How did you verify this works? -->
|
||||||
|
|
||||||
|
- [ ] `make test` passes
|
||||||
|
- [ ] Tested on sandbox/staging environment
|
||||||
|
|
||||||
|
## Distributed system impact
|
||||||
|
|
||||||
|
<!-- Does this change affect any of the following? If yes, explain. -->
|
||||||
|
|
||||||
|
- [ ] Raft quorum / RQLite
|
||||||
|
- [ ] WireGuard mesh / networking
|
||||||
|
- [ ] Olric gossip / caching
|
||||||
|
- [ ] Service startup ordering
|
||||||
|
- [ ] Rolling upgrade compatibility
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
- [ ] Tests added for new functionality or bug fix
|
||||||
|
- [ ] No debug code (`fmt.Println`, `log.Println`) left behind
|
||||||
|
- [ ] Docs updated (if user-facing behavior changed)
|
||||||
|
- [ ] Errors wrapped with context (`fmt.Errorf("...: %w", err)`)
|
||||||
80
.github/workflows/publish-sdk.yml
vendored
Normal file
80
.github/workflows/publish-sdk.yml
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
name: Publish SDK to npm
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Version to publish (e.g., 1.0.0). Leave empty to use package.json version."
|
||||||
|
required: false
|
||||||
|
dry-run:
|
||||||
|
description: "Dry run (don't actually publish)"
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
name: Build & Publish @debros/orama
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: sdk
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "20"
|
||||||
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
with:
|
||||||
|
version: 9
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Bump version
|
||||||
|
if: inputs.version != ''
|
||||||
|
run: npm version ${{ inputs.version }} --no-git-tag-version
|
||||||
|
|
||||||
|
- name: Typecheck
|
||||||
|
run: pnpm typecheck
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: pnpm build
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
run: pnpm vitest run tests/unit
|
||||||
|
|
||||||
|
- name: Publish (dry run)
|
||||||
|
if: inputs.dry-run == true
|
||||||
|
run: npm publish --access public --dry-run
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
|
- name: Publish
|
||||||
|
if: inputs.dry-run == false
|
||||||
|
run: npm publish --access public
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get published version
|
||||||
|
if: inputs.dry-run == false
|
||||||
|
id: version
|
||||||
|
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Create git tag
|
||||||
|
if: inputs.dry-run == false
|
||||||
|
working-directory: .
|
||||||
|
run: |
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git tag "sdk/v${{ steps.version.outputs.version }}"
|
||||||
|
git push origin "sdk/v${{ steps.version.outputs.version }}"
|
||||||
10
.github/workflows/release-apt.yml
vendored
10
.github/workflows/release-apt.yml
vendored
@ -28,7 +28,8 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: "1.23"
|
go-version: "1.24"
|
||||||
|
cache-dependency-path: core/go.sum
|
||||||
|
|
||||||
- name: Get version
|
- name: Get version
|
||||||
id: version
|
id: version
|
||||||
@ -46,6 +47,7 @@ jobs:
|
|||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
- name: Build binary
|
- name: Build binary
|
||||||
|
working-directory: core
|
||||||
env:
|
env:
|
||||||
GOARCH: ${{ matrix.arch }}
|
GOARCH: ${{ matrix.arch }}
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
@ -57,9 +59,9 @@ jobs:
|
|||||||
|
|
||||||
mkdir -p build/usr/local/bin
|
mkdir -p build/usr/local/bin
|
||||||
go build -ldflags "$LDFLAGS" -o build/usr/local/bin/orama cmd/cli/main.go
|
go build -ldflags "$LDFLAGS" -o build/usr/local/bin/orama cmd/cli/main.go
|
||||||
go build -ldflags "$LDFLAGS" -o build/usr/local/bin/debros-node cmd/node/main.go
|
go build -ldflags "$LDFLAGS" -o build/usr/local/bin/orama-node cmd/node/main.go
|
||||||
# Build the entire gateway package so helper files (e.g., config parsing) are included
|
# Build the entire gateway package so helper files (e.g., config parsing) are included
|
||||||
go build -ldflags "$LDFLAGS" -o build/usr/local/bin/debros-gateway ./cmd/gateway
|
go build -ldflags "$LDFLAGS" -o build/usr/local/bin/orama-gateway ./cmd/gateway
|
||||||
|
|
||||||
- name: Create Debian package structure
|
- name: Create Debian package structure
|
||||||
run: |
|
run: |
|
||||||
@ -71,7 +73,7 @@ jobs:
|
|||||||
mkdir -p ${PKG_NAME}/usr/local/bin
|
mkdir -p ${PKG_NAME}/usr/local/bin
|
||||||
|
|
||||||
# Copy binaries
|
# Copy binaries
|
||||||
cp build/usr/local/bin/* ${PKG_NAME}/usr/local/bin/
|
cp core/build/usr/local/bin/* ${PKG_NAME}/usr/local/bin/
|
||||||
chmod 755 ${PKG_NAME}/usr/local/bin/*
|
chmod 755 ${PKG_NAME}/usr/local/bin/*
|
||||||
|
|
||||||
# Create control file
|
# Create control file
|
||||||
|
|||||||
4
.github/workflows/release.yaml
vendored
4
.github/workflows/release.yaml
vendored
@ -23,8 +23,8 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: '1.21'
|
go-version: '1.24'
|
||||||
cache: true
|
cache-dependency-path: core/go.sum
|
||||||
|
|
||||||
- name: Run GoReleaser
|
- name: Run GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v5
|
uses: goreleaser/goreleaser-action@v5
|
||||||
|
|||||||
162
.gitignore
vendored
162
.gitignore
vendored
@ -1,110 +1,90 @@
|
|||||||
# Binaries for programs and plugins
|
# === Global ===
|
||||||
*.exe
|
|
||||||
*.exe~
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
|
||||||
*.test
|
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
|
||||||
*.out
|
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
|
||||||
# vendor/
|
|
||||||
|
|
||||||
# Go workspace file
|
|
||||||
go.work
|
|
||||||
|
|
||||||
# Built binaries
|
|
||||||
bin/
|
|
||||||
dist/
|
|
||||||
|
|
||||||
# IDE and editor files
|
|
||||||
.vscode/
|
|
||||||
.idea/
|
|
||||||
*.swp
|
|
||||||
*.swo
|
|
||||||
*~
|
|
||||||
|
|
||||||
# OS generated files
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.codex/
|
|
||||||
redeploy-6.sh
|
|
||||||
.DS_Store?
|
.DS_Store?
|
||||||
._*
|
._*
|
||||||
.Spotlight-V100
|
.Spotlight-V100
|
||||||
.Trashes
|
.Trashes
|
||||||
ehthumbs.db
|
ehthumbs.db
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
# Log files
|
# IDE
|
||||||
*.log
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
.cursor/
|
||||||
|
|
||||||
# Environment variables
|
# Environment & credentials
|
||||||
.env
|
.env
|
||||||
.env.local
|
.env.*
|
||||||
.env.*.local
|
!.env.example
|
||||||
|
.mcp.json
|
||||||
|
.claude/
|
||||||
|
.codex/
|
||||||
|
|
||||||
# E2E test config (contains production credentials)
|
# === Core (Go) ===
|
||||||
e2e/config.yaml
|
core/phantom-auth/
|
||||||
|
core/bin/
|
||||||
|
core/bin-linux/
|
||||||
|
core/dist/
|
||||||
|
core/orama-cli-linux
|
||||||
|
core/keys_backup/
|
||||||
|
core/.gocache/
|
||||||
|
core/configs/
|
||||||
|
core/data/*
|
||||||
|
core/tmp/
|
||||||
|
core/temp/
|
||||||
|
core/results/
|
||||||
|
core/rnd/
|
||||||
|
core/vps.txt
|
||||||
|
core/coverage.txt
|
||||||
|
core/coverage.html
|
||||||
|
core/profile.out
|
||||||
|
core/e2e/config.yaml
|
||||||
|
core/scripts/remote-nodes.conf
|
||||||
|
|
||||||
# Temporary files
|
# Go build artifacts
|
||||||
tmp/
|
*.exe
|
||||||
temp/
|
*.exe~
|
||||||
*.tmp
|
*.dll
|
||||||
|
*.so
|
||||||
# Coverage reports
|
*.dylib
|
||||||
coverage.txt
|
*.test
|
||||||
coverage.html
|
*.out
|
||||||
profile.out
|
|
||||||
|
|
||||||
# Build artifacts
|
|
||||||
*.deb
|
*.deb
|
||||||
*.rpm
|
*.rpm
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
*.zip
|
*.zip
|
||||||
|
go.work
|
||||||
|
|
||||||
# Local development files
|
# Logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Databases
|
||||||
|
*.db
|
||||||
|
|
||||||
|
# === Website ===
|
||||||
|
website/node_modules/
|
||||||
|
website/dist/
|
||||||
|
website/invest-api/invest-api
|
||||||
|
website/invest-api/*.db
|
||||||
|
website/invest-api/*.db-shm
|
||||||
|
website/invest-api/*.db-wal
|
||||||
|
|
||||||
|
# === SDK (TypeScript) ===
|
||||||
|
sdk/node_modules/
|
||||||
|
sdk/dist/
|
||||||
|
sdk/coverage/
|
||||||
|
|
||||||
|
# === Vault (Zig) ===
|
||||||
|
vault/.zig-cache/
|
||||||
|
vault/zig-out/
|
||||||
|
|
||||||
|
# === OS ===
|
||||||
|
os/output/
|
||||||
|
|
||||||
|
# === Local development ===
|
||||||
|
.dev/
|
||||||
.local/
|
.local/
|
||||||
local/
|
local/
|
||||||
|
|
||||||
data/*
|
|
||||||
./bootstrap
|
|
||||||
./node
|
|
||||||
data/bootstrap/rqlite/
|
|
||||||
|
|
||||||
.env.*
|
|
||||||
|
|
||||||
configs/
|
|
||||||
|
|
||||||
.dev/
|
|
||||||
|
|
||||||
.gocache/
|
|
||||||
|
|
||||||
.claude/
|
|
||||||
.mcp.json
|
|
||||||
.cursor/
|
|
||||||
|
|
||||||
# Remote node credentials
|
|
||||||
scripts/remote-nodes.conf
|
|
||||||
|
|
||||||
orama-cli-linux
|
|
||||||
|
|
||||||
rnd/
|
|
||||||
|
|
||||||
keys_backup/
|
|
||||||
|
|
||||||
vps.txt
|
|
||||||
|
|
||||||
bin-linux/
|
|
||||||
|
|
||||||
website/
|
|
||||||
|
|
||||||
terms-agreement
|
|
||||||
|
|
||||||
cli
|
|
||||||
./inspector
|
|
||||||
|
|
||||||
results/
|
|
||||||
@ -2,18 +2,20 @@
|
|||||||
# Builds and releases orama (CLI) and orama-node binaries
|
# Builds and releases orama (CLI) and orama-node binaries
|
||||||
# Publishes to: GitHub Releases, Homebrew, and apt (.deb packages)
|
# Publishes to: GitHub Releases, Homebrew, and apt (.deb packages)
|
||||||
|
|
||||||
project_name: debros-network
|
project_name: orama-network
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- GO111MODULE=on
|
- GO111MODULE=on
|
||||||
|
|
||||||
before:
|
before:
|
||||||
hooks:
|
hooks:
|
||||||
- go mod tidy
|
- cmd: go mod tidy
|
||||||
|
dir: core
|
||||||
|
|
||||||
builds:
|
builds:
|
||||||
# orama CLI binary
|
# orama CLI binary
|
||||||
- id: orama
|
- id: orama
|
||||||
|
dir: core
|
||||||
main: ./cmd/cli
|
main: ./cmd/cli
|
||||||
binary: orama
|
binary: orama
|
||||||
goos:
|
goos:
|
||||||
@ -31,6 +33,7 @@ builds:
|
|||||||
|
|
||||||
# orama-node binary (Linux only for apt)
|
# orama-node binary (Linux only for apt)
|
||||||
- id: orama-node
|
- id: orama-node
|
||||||
|
dir: core
|
||||||
main: ./cmd/node
|
main: ./cmd/node
|
||||||
binary: orama-node
|
binary: orama-node
|
||||||
goos:
|
goos:
|
||||||
@ -75,7 +78,7 @@ nfpms:
|
|||||||
- orama
|
- orama
|
||||||
vendor: DeBros
|
vendor: DeBros
|
||||||
homepage: https://github.com/DeBrosOfficial/network
|
homepage: https://github.com/DeBrosOfficial/network
|
||||||
maintainer: DeBros <support@debros.io>
|
maintainer: DeBros <dev@debros.io>
|
||||||
description: CLI tool for the Orama decentralized network
|
description: CLI tool for the Orama decentralized network
|
||||||
license: MIT
|
license: MIT
|
||||||
formats:
|
formats:
|
||||||
@ -84,7 +87,7 @@ nfpms:
|
|||||||
section: utils
|
section: utils
|
||||||
priority: optional
|
priority: optional
|
||||||
contents:
|
contents:
|
||||||
- src: ./README.md
|
- src: ./core/README.md
|
||||||
dst: /usr/share/doc/orama/README.md
|
dst: /usr/share/doc/orama/README.md
|
||||||
deb:
|
deb:
|
||||||
lintian_overrides:
|
lintian_overrides:
|
||||||
@ -97,7 +100,7 @@ nfpms:
|
|||||||
- orama-node
|
- orama-node
|
||||||
vendor: DeBros
|
vendor: DeBros
|
||||||
homepage: https://github.com/DeBrosOfficial/network
|
homepage: https://github.com/DeBrosOfficial/network
|
||||||
maintainer: DeBros <support@debros.io>
|
maintainer: DeBros <dev@debros.io>
|
||||||
description: Node daemon for the Orama decentralized network
|
description: Node daemon for the Orama decentralized network
|
||||||
license: MIT
|
license: MIT
|
||||||
formats:
|
formats:
|
||||||
@ -106,7 +109,7 @@ nfpms:
|
|||||||
section: net
|
section: net
|
||||||
priority: optional
|
priority: optional
|
||||||
contents:
|
contents:
|
||||||
- src: ./README.md
|
- src: ./core/README.md
|
||||||
dst: /usr/share/doc/orama-node/README.md
|
dst: /usr/share/doc/orama-node/README.md
|
||||||
deb:
|
deb:
|
||||||
lintian_overrides:
|
lintian_overrides:
|
||||||
|
|||||||
@ -32,7 +32,7 @@ This Code applies within all project spaces and when an individual is officially
|
|||||||
|
|
||||||
## Enforcement
|
## Enforcement
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the maintainers at: security@debros.io
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the maintainers at: security@orama.io
|
||||||
|
|
||||||
All complaints will be reviewed and investigated promptly and fairly.
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
|||||||
@ -1,47 +1,78 @@
|
|||||||
# Contributing to DeBros Network
|
# Contributing to Orama Network
|
||||||
|
|
||||||
Thanks for helping improve the network! This guide covers setup, local dev, tests, and PR guidelines.
|
Thanks for helping improve the network! This monorepo contains multiple projects — pick the one relevant to your contribution.
|
||||||
|
|
||||||
## Requirements
|
## Repository Structure
|
||||||
|
|
||||||
- Go 1.22+ (1.23 recommended)
|
| Package | Language | Build |
|
||||||
- RQLite (optional for local runs; the Makefile starts nodes with embedded setup)
|
|---------|----------|-------|
|
||||||
- Make (optional)
|
| `core/` | Go 1.24+ | `make core-build` |
|
||||||
|
| `website/` | TypeScript (pnpm) | `make website-build` |
|
||||||
|
| `vault/` | Zig 0.14+ | `make vault-build` |
|
||||||
|
| `os/` | Go + Buildroot | `make os-build` |
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/DeBrosOfficial/network.git
|
git clone https://github.com/DeBrosOfficial/network.git
|
||||||
cd network
|
cd network
|
||||||
make deps
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build, Test, Lint
|
### Core (Go)
|
||||||
|
|
||||||
- Build: `make build`
|
|
||||||
- Test: `make test`
|
|
||||||
- Format/Vet: `make fmt vet` (or `make lint`)
|
|
||||||
|
|
||||||
````
|
|
||||||
|
|
||||||
Useful CLI commands:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/orama health
|
cd core
|
||||||
./bin/orama peers
|
make deps
|
||||||
./bin/orama status
|
make build
|
||||||
````
|
make test
|
||||||
|
```
|
||||||
|
|
||||||
## Versioning
|
### Website
|
||||||
|
|
||||||
- The CLI reports its version via `orama version`.
|
```bash
|
||||||
- Releases are tagged (e.g., `v0.18.0-beta`) and published via GoReleaser.
|
cd website
|
||||||
|
pnpm install
|
||||||
|
pnpm dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vault (Zig)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd vault
|
||||||
|
zig build
|
||||||
|
zig build test
|
||||||
|
```
|
||||||
|
|
||||||
## Pull Requests
|
## Pull Requests
|
||||||
|
|
||||||
1. Fork and create a topic branch.
|
1. Fork and create a topic branch from `main`.
|
||||||
2. Ensure `make build test` passes; include tests for new functionality.
|
2. Ensure `make test` passes for affected packages.
|
||||||
3. Keep PRs focused and well-described (motivation, approach, testing).
|
3. Include tests for new functionality or bug fixes.
|
||||||
4. Update README/docs for behavior changes.
|
4. Keep PRs focused — one concern per PR.
|
||||||
|
5. Write a clear description: motivation, approach, and how you tested it.
|
||||||
|
6. Update docs if you're changing user-facing behavior.
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
### Go (core/, os/)
|
||||||
|
|
||||||
|
- Follow standard Go conventions
|
||||||
|
- Run `make lint` before submitting
|
||||||
|
- Wrap errors with context: `fmt.Errorf("failed to X: %w", err)`
|
||||||
|
- No magic values — use named constants
|
||||||
|
|
||||||
|
### TypeScript (website/)
|
||||||
|
|
||||||
|
- TypeScript strict mode
|
||||||
|
- Follow existing patterns in the codebase
|
||||||
|
|
||||||
|
### Zig (vault/)
|
||||||
|
|
||||||
|
- Follow standard Zig conventions
|
||||||
|
- Run `zig build test` before submitting
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
If you find a security vulnerability, **do not open a public issue**. Email security@debros.io instead.
|
||||||
|
|
||||||
Thank you for contributing!
|
Thank you for contributing!
|
||||||
|
|||||||
316
Makefile
316
Makefile
@ -1,288 +1,66 @@
|
|||||||
TEST?=./...
|
# Orama Monorepo
|
||||||
|
# Delegates to sub-project Makefiles
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: help build test clean
|
||||||
test:
|
|
||||||
@echo Running tests...
|
|
||||||
go test -v $(TEST)
|
|
||||||
|
|
||||||
# Gateway-focused E2E tests assume gateway and nodes are already running
|
# === Core (Go network) ===
|
||||||
# Auto-discovers configuration from ~/.orama and queries database for API key
|
.PHONY: core core-build core-test core-clean core-lint
|
||||||
# No environment variables required
|
core: core-build
|
||||||
.PHONY: test-e2e test-e2e-deployments test-e2e-fullstack test-e2e-https test-e2e-quick test-e2e-local test-e2e-prod test-e2e-shared test-e2e-cluster test-e2e-integration test-e2e-production
|
|
||||||
|
|
||||||
# Check if gateway is running (helper)
|
core-build:
|
||||||
.PHONY: check-gateway
|
$(MAKE) -C core build
|
||||||
check-gateway:
|
|
||||||
@if ! curl -sf http://localhost:6001/v1/health > /dev/null 2>&1; then \
|
|
||||||
echo "❌ Gateway not running on localhost:6001"; \
|
|
||||||
echo ""; \
|
|
||||||
echo "To run tests locally:"; \
|
|
||||||
echo " 1. Start the dev environment: make dev"; \
|
|
||||||
echo " 2. Wait for all services to start (~30 seconds)"; \
|
|
||||||
echo " 3. Run tests: make test-e2e-local"; \
|
|
||||||
echo ""; \
|
|
||||||
echo "To run tests against production:"; \
|
|
||||||
echo " ORAMA_GATEWAY_URL=https://dbrs.space make test-e2e"; \
|
|
||||||
exit 1; \
|
|
||||||
fi
|
|
||||||
@echo "✅ Gateway is running"
|
|
||||||
|
|
||||||
# Local E2E tests - checks gateway first
|
core-test:
|
||||||
test-e2e-local: check-gateway
|
$(MAKE) -C core test
|
||||||
@echo "Running E2E tests against local dev environment..."
|
|
||||||
go test -v -tags e2e -timeout 30m ./e2e/...
|
|
||||||
|
|
||||||
# Production E2E tests - includes production-only tests
|
core-lint:
|
||||||
test-e2e-prod:
|
$(MAKE) -C core lint
|
||||||
@if [ -z "$$ORAMA_GATEWAY_URL" ]; then \
|
|
||||||
echo "❌ ORAMA_GATEWAY_URL not set"; \
|
|
||||||
echo "Usage: ORAMA_GATEWAY_URL=https://dbrs.space make test-e2e-prod"; \
|
|
||||||
exit 1; \
|
|
||||||
fi
|
|
||||||
@echo "Running E2E tests (including production-only) against $$ORAMA_GATEWAY_URL..."
|
|
||||||
go test -v -tags "e2e production" -timeout 30m ./e2e/...
|
|
||||||
|
|
||||||
# Generic e2e target (works with both local and production)
|
core-clean:
|
||||||
test-e2e:
|
$(MAKE) -C core clean
|
||||||
@echo "Running comprehensive E2E tests..."
|
|
||||||
@echo "Auto-discovering configuration from ~/.orama..."
|
|
||||||
@echo "Tip: Use 'make test-e2e-local' for local or 'make test-e2e-prod' for production"
|
|
||||||
go test -v -tags e2e -timeout 30m ./e2e/...
|
|
||||||
|
|
||||||
test-e2e-deployments:
|
# === Website ===
|
||||||
@echo "Running deployment E2E tests..."
|
.PHONY: website website-dev website-build
|
||||||
go test -v -tags e2e -timeout 15m ./e2e/deployments/...
|
website-dev:
|
||||||
|
cd website && pnpm dev
|
||||||
|
|
||||||
test-e2e-fullstack:
|
website-build:
|
||||||
@echo "Running fullstack E2E tests..."
|
cd website && pnpm build
|
||||||
go test -v -tags e2e -timeout 20m -run "TestFullStack" ./e2e/...
|
|
||||||
|
|
||||||
test-e2e-https:
|
# === SDK (TypeScript) ===
|
||||||
@echo "Running HTTPS/external access E2E tests..."
|
.PHONY: sdk sdk-build sdk-test
|
||||||
go test -v -tags e2e -timeout 10m -run "TestHTTPS" ./e2e/...
|
sdk: sdk-build
|
||||||
|
|
||||||
test-e2e-shared:
|
sdk-build:
|
||||||
@echo "Running shared E2E tests..."
|
cd sdk && pnpm install && pnpm build
|
||||||
go test -v -tags e2e -timeout 10m ./e2e/shared/...
|
|
||||||
|
|
||||||
test-e2e-cluster:
|
sdk-test:
|
||||||
@echo "Running cluster E2E tests..."
|
cd sdk && pnpm test
|
||||||
go test -v -tags e2e -timeout 15m ./e2e/cluster/...
|
|
||||||
|
|
||||||
test-e2e-integration:
|
# === Vault (Zig) ===
|
||||||
@echo "Running integration E2E tests..."
|
.PHONY: vault vault-build vault-test
|
||||||
go test -v -tags e2e -timeout 20m ./e2e/integration/...
|
vault-build:
|
||||||
|
cd vault && zig build
|
||||||
|
|
||||||
test-e2e-production:
|
vault-test:
|
||||||
@echo "Running production-only E2E tests..."
|
cd vault && zig build test
|
||||||
go test -v -tags "e2e production" -timeout 15m ./e2e/production/...
|
|
||||||
|
|
||||||
test-e2e-quick:
|
# === OS ===
|
||||||
@echo "Running quick E2E smoke tests..."
|
.PHONY: os os-build
|
||||||
go test -v -tags e2e -timeout 5m -run "TestStatic|TestHealth" ./e2e/...
|
os-build:
|
||||||
|
$(MAKE) -C os
|
||||||
|
|
||||||
# Network - Distributed P2P Database System
|
# === Aggregate ===
|
||||||
# Makefile for development and build tasks
|
build: core-build
|
||||||
|
test: core-test
|
||||||
|
clean: core-clean
|
||||||
|
|
||||||
.PHONY: build clean test run-node run-node2 run-node3 run-example deps tidy fmt vet lint clear-ports install-hooks kill redeploy-devnet redeploy-testnet release health
|
|
||||||
|
|
||||||
VERSION := 0.102.2
|
|
||||||
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
|
||||||
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
||||||
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
|
|
||||||
LDFLAGS_LINUX := -s -w $(LDFLAGS)
|
|
||||||
|
|
||||||
# Build targets
|
|
||||||
build: deps
|
|
||||||
@echo "Building network executables (version=$(VERSION))..."
|
|
||||||
@mkdir -p bin
|
|
||||||
go build -ldflags "$(LDFLAGS)" -o bin/identity ./cmd/identity
|
|
||||||
go build -ldflags "$(LDFLAGS)" -o bin/orama-node ./cmd/node
|
|
||||||
go build -ldflags "$(LDFLAGS)" -o bin/orama cmd/cli/main.go
|
|
||||||
go build -ldflags "$(LDFLAGS)" -o bin/rqlite-mcp ./cmd/rqlite-mcp
|
|
||||||
# Inject gateway build metadata via pkg path variables
|
|
||||||
go build -ldflags "$(LDFLAGS) -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildVersion=$(VERSION)' -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildCommit=$(COMMIT)' -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildTime=$(DATE)'" -o bin/gateway ./cmd/gateway
|
|
||||||
@echo "Build complete! Run ./bin/orama version"
|
|
||||||
|
|
||||||
# Cross-compile all binaries for Linux (used with --pre-built flag on VPS)
|
|
||||||
# Builds: DeBros binaries + Olric + CoreDNS (with rqlite plugin) + Caddy (with orama DNS module)
|
|
||||||
build-linux: deps
|
|
||||||
@echo "Cross-compiling all binaries for linux/amd64 (version=$(VERSION))..."
|
|
||||||
@mkdir -p bin-linux
|
|
||||||
GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS_LINUX)" -trimpath -o bin-linux/identity ./cmd/identity
|
|
||||||
GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS_LINUX)" -trimpath -o bin-linux/orama-node ./cmd/node
|
|
||||||
GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS_LINUX)" -trimpath -o bin-linux/orama cmd/cli/main.go
|
|
||||||
GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS_LINUX)" -trimpath -o bin-linux/rqlite-mcp ./cmd/rqlite-mcp
|
|
||||||
GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS_LINUX) -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildVersion=$(VERSION)' -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildCommit=$(COMMIT)' -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildTime=$(DATE)'" -trimpath -o bin-linux/gateway ./cmd/gateway
|
|
||||||
GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS_LINUX)" -trimpath -o bin-linux/orama-cli ./cmd/cli
|
|
||||||
@echo "Building Olric for linux/amd64..."
|
|
||||||
GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -trimpath -o bin-linux/olric-server github.com/olric-data/olric/cmd/olric-server
|
|
||||||
@echo "✓ All Linux binaries built in bin-linux/"
|
|
||||||
@echo ""
|
|
||||||
@echo "Next steps:"
|
|
||||||
@echo " 1. Build CoreDNS: make build-linux-coredns"
|
|
||||||
@echo " 2. Build Caddy: make build-linux-caddy"
|
|
||||||
@echo " 3. Or build all: make build-linux-all"
|
|
||||||
|
|
||||||
# Build CoreDNS with rqlite plugin for Linux
|
|
||||||
build-linux-coredns:
|
|
||||||
@bash scripts/build-linux-coredns.sh
|
|
||||||
|
|
||||||
# Build Caddy with orama DNS module for Linux
|
|
||||||
build-linux-caddy:
|
|
||||||
@bash scripts/build-linux-caddy.sh
|
|
||||||
|
|
||||||
# Build everything for Linux (all binaries + CoreDNS + Caddy)
|
|
||||||
build-linux-all: build-linux build-linux-coredns build-linux-caddy
|
|
||||||
@echo ""
|
|
||||||
@echo "✅ All Linux binaries ready in bin-linux/:"
|
|
||||||
@ls -la bin-linux/
|
|
||||||
@echo ""
|
|
||||||
@echo "Deploy to VPS:"
|
|
||||||
@echo " scp bin-linux/* ubuntu@<ip>:/home/debros/bin/"
|
|
||||||
@echo " scp bin-linux/coredns ubuntu@<ip>:/usr/local/bin/coredns"
|
|
||||||
@echo " scp bin-linux/caddy ubuntu@<ip>:/usr/bin/caddy"
|
|
||||||
@echo " sudo orama install --pre-built --no-pull ..."
|
|
||||||
|
|
||||||
# Install git hooks
|
|
||||||
install-hooks:
|
|
||||||
@echo "Installing git hooks..."
|
|
||||||
@bash scripts/install-hooks.sh
|
|
||||||
|
|
||||||
# Clean build artifacts
|
|
||||||
clean:
|
|
||||||
@echo "Cleaning build artifacts..."
|
|
||||||
rm -rf bin/
|
|
||||||
rm -rf data/
|
|
||||||
@echo "Clean complete!"
|
|
||||||
|
|
||||||
# Run bootstrap node (auto-selects identity and data dir)
|
|
||||||
run-node:
|
|
||||||
@echo "Starting node..."
|
|
||||||
@echo "Config: ~/.orama/node.yaml"
|
|
||||||
go run ./cmd/orama-node --config node.yaml
|
|
||||||
|
|
||||||
# Run second node - requires join address
|
|
||||||
run-node2:
|
|
||||||
@echo "Starting second node..."
|
|
||||||
@echo "Config: ~/.orama/node2.yaml"
|
|
||||||
go run ./cmd/orama-node --config node2.yaml
|
|
||||||
|
|
||||||
# Run third node - requires join address
|
|
||||||
run-node3:
|
|
||||||
@echo "Starting third node..."
|
|
||||||
@echo "Config: ~/.orama/node3.yaml"
|
|
||||||
go run ./cmd/orama-node --config node3.yaml
|
|
||||||
|
|
||||||
# Run gateway HTTP server
|
|
||||||
run-gateway:
|
|
||||||
@echo "Starting gateway HTTP server..."
|
|
||||||
@echo "Note: Config must be in ~/.orama/data/gateway.yaml"
|
|
||||||
go run ./cmd/orama-gateway
|
|
||||||
|
|
||||||
# Development environment target
|
|
||||||
# Uses orama dev up to start full stack with dependency and port checking
|
|
||||||
dev: build
|
|
||||||
@./bin/orama dev up
|
|
||||||
|
|
||||||
# Graceful shutdown of all dev services
|
|
||||||
stop:
|
|
||||||
@if [ -f ./bin/orama ]; then \
|
|
||||||
./bin/orama dev down || true; \
|
|
||||||
fi
|
|
||||||
@bash scripts/dev-kill-all.sh
|
|
||||||
|
|
||||||
# Force kill all processes (immediate termination)
|
|
||||||
kill:
|
|
||||||
@bash scripts/dev-kill-all.sh
|
|
||||||
|
|
||||||
# Deploy to devnet (build + rolling upgrade all nodes)
|
|
||||||
redeploy-devnet:
|
|
||||||
@bash scripts/redeploy.sh --devnet
|
|
||||||
|
|
||||||
# Deploy to devnet without rebuilding
|
|
||||||
redeploy-devnet-quick:
|
|
||||||
@bash scripts/redeploy.sh --devnet --no-build
|
|
||||||
|
|
||||||
# Deploy to testnet (build + rolling upgrade all nodes)
|
|
||||||
redeploy-testnet:
|
|
||||||
@bash scripts/redeploy.sh --testnet
|
|
||||||
|
|
||||||
# Deploy to testnet without rebuilding
|
|
||||||
redeploy-testnet-quick:
|
|
||||||
@bash scripts/redeploy.sh --testnet --no-build
|
|
||||||
|
|
||||||
# Interactive release workflow (tag + push)
|
|
||||||
release:
|
|
||||||
@bash scripts/release.sh
|
|
||||||
|
|
||||||
# Check health of all nodes in an environment
|
|
||||||
# Usage: make health ENV=devnet
|
|
||||||
health:
|
|
||||||
@if [ -z "$(ENV)" ]; then \
|
|
||||||
echo "Usage: make health ENV=devnet|testnet"; \
|
|
||||||
exit 1; \
|
|
||||||
fi
|
|
||||||
@while IFS='|' read -r env host pass role key; do \
|
|
||||||
[ -z "$$env" ] && continue; \
|
|
||||||
case "$$env" in \#*) continue;; esac; \
|
|
||||||
env="$$(echo "$$env" | xargs)"; \
|
|
||||||
[ "$$env" != "$(ENV)" ] && continue; \
|
|
||||||
role="$$(echo "$$role" | xargs)"; \
|
|
||||||
bash scripts/check-node-health.sh "$$host" "$$pass" "$$host ($$role)"; \
|
|
||||||
done < scripts/remote-nodes.conf
|
|
||||||
|
|
||||||
# Help
|
|
||||||
help:
|
help:
|
||||||
@echo "Available targets:"
|
@echo "Orama Monorepo"
|
||||||
@echo " build - Build all executables"
|
|
||||||
@echo " clean - Clean build artifacts"
|
|
||||||
@echo " test - Run unit tests"
|
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Local Development (Recommended):"
|
@echo " Core (Go): make core-build | core-test | core-lint | core-clean"
|
||||||
@echo " make dev - Start full development stack with one command"
|
@echo " Website: make website-dev | website-build"
|
||||||
@echo " - Checks dependencies and available ports"
|
@echo " Vault (Zig): make vault-build | vault-test"
|
||||||
@echo " - Generates configs and starts all services"
|
@echo " OS: make os-build"
|
||||||
@echo " - Validates cluster health"
|
|
||||||
@echo " make stop - Gracefully stop all development services"
|
|
||||||
@echo " make kill - Force kill all development services (use if stop fails)"
|
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "E2E Testing:"
|
@echo " Aggregate: make build | test | clean (delegates to core)"
|
||||||
@echo " make test-e2e-local - Run E2E tests against local dev (checks gateway first)"
|
|
||||||
@echo " make test-e2e-prod - Run all E2E tests incl. production-only (needs ORAMA_GATEWAY_URL)"
|
|
||||||
@echo " make test-e2e-shared - Run shared E2E tests (cache, storage, pubsub, auth)"
|
|
||||||
@echo " make test-e2e-cluster - Run cluster E2E tests (libp2p, olric, rqlite, namespace)"
|
|
||||||
@echo " make test-e2e-integration - Run integration E2E tests (fullstack, persistence, concurrency)"
|
|
||||||
@echo " make test-e2e-deployments - Run deployment E2E tests"
|
|
||||||
@echo " make test-e2e-production - Run production-only E2E tests (DNS, HTTPS, cross-node)"
|
|
||||||
@echo " make test-e2e-quick - Quick smoke tests (static deploys, health checks)"
|
|
||||||
@echo " make test-e2e - Generic E2E tests (auto-discovers config)"
|
|
||||||
@echo ""
|
|
||||||
@echo " Example production test:"
|
|
||||||
@echo " ORAMA_GATEWAY_URL=https://dbrs.space make test-e2e-prod"
|
|
||||||
@echo ""
|
|
||||||
@echo "Deployment:"
|
|
||||||
@echo " make redeploy-devnet - Build + rolling deploy to all devnet nodes"
|
|
||||||
@echo " make redeploy-devnet-quick - Deploy to devnet without rebuilding"
|
|
||||||
@echo " make redeploy-testnet - Build + rolling deploy to all testnet nodes"
|
|
||||||
@echo " make redeploy-testnet-quick- Deploy to testnet without rebuilding"
|
|
||||||
@echo " make health ENV=devnet - Check health of all nodes in an environment"
|
|
||||||
@echo " make release - Interactive release workflow (tag + push)"
|
|
||||||
@echo ""
|
|
||||||
@echo "Development Management (via orama):"
|
|
||||||
@echo " ./bin/orama dev status - Show status of all dev services"
|
|
||||||
@echo " ./bin/orama dev logs <component> [--follow]"
|
|
||||||
@echo ""
|
|
||||||
@echo "Individual Node Targets (advanced):"
|
|
||||||
@echo " run-node - Start first node directly"
|
|
||||||
@echo " run-node2 - Start second node directly"
|
|
||||||
@echo " run-node3 - Start third node directly"
|
|
||||||
@echo " run-gateway - Start HTTP gateway directly"
|
|
||||||
@echo ""
|
|
||||||
@echo "Maintenance:"
|
|
||||||
@echo " deps - Download dependencies"
|
|
||||||
@echo " tidy - Tidy dependencies"
|
|
||||||
@echo " fmt - Format code"
|
|
||||||
@echo " vet - Vet code"
|
|
||||||
@echo " lint - Lint code (fmt + vet)"
|
|
||||||
@echo " help - Show this help"
|
|
||||||
|
|||||||
575
README.md
575
README.md
@ -1,557 +1,50 @@
|
|||||||
# Orama Network - Distributed P2P Platform
|
# Orama Network
|
||||||
|
|
||||||
A high-performance API Gateway and distributed platform built in Go. Provides a unified HTTP/HTTPS API for distributed SQL (RQLite), distributed caching (Olric), decentralized storage (IPFS), pub/sub messaging, and serverless WebAssembly execution.
|
A decentralized infrastructure platform combining distributed SQL, IPFS storage, caching, serverless WASM execution, and privacy relay — all managed through a unified API gateway.
|
||||||
|
|
||||||
**Architecture:** Modular Gateway / Edge Proxy following SOLID principles
|
## Packages
|
||||||
|
|
||||||
## Features
|
| Package | Language | Description |
|
||||||
|
|---------|----------|-------------|
|
||||||
- **🔐 Authentication** - Wallet signatures, API keys, JWT tokens
|
| [core/](core/) | Go | API gateway, distributed node, CLI, and client SDK |
|
||||||
- **💾 Storage** - IPFS-based decentralized file storage with encryption
|
| [sdk/](sdk/) | TypeScript | `@debros/orama` — JavaScript/TypeScript SDK ([npm](https://www.npmjs.com/package/@debros/orama)) |
|
||||||
- **⚡ Cache** - Distributed cache with Olric (in-memory key-value)
|
| [website/](website/) | TypeScript | Marketing website and invest portal |
|
||||||
- **🗄️ Database** - RQLite distributed SQL with Raft consensus + Per-namespace SQLite databases
|
| [vault/](vault/) | Zig | Distributed secrets vault (Shamir's Secret Sharing) |
|
||||||
- **📡 Pub/Sub** - Real-time messaging via LibP2P and WebSocket
|
| [os/](os/) | Go + Buildroot | OramaOS — hardened minimal Linux for network nodes |
|
||||||
- **⚙️ Serverless** - WebAssembly function execution with host functions
|
|
||||||
- **🌐 HTTP Gateway** - Unified REST API with automatic HTTPS (Let's Encrypt)
|
|
||||||
- **📦 Client SDK** - Type-safe Go SDK for all services
|
|
||||||
- **🚀 App Deployments** - Deploy React, Next.js, Go, Node.js apps with automatic domains
|
|
||||||
- **🗄️ SQLite Databases** - Per-namespace isolated databases with IPFS backups
|
|
||||||
|
|
||||||
## Application Deployments
|
|
||||||
|
|
||||||
Deploy full-stack applications with automatic domain assignment and namespace isolation.
|
|
||||||
|
|
||||||
### Deploy a React App
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build your app
|
|
||||||
cd my-react-app
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
# Deploy to Orama Network
|
|
||||||
orama deploy static ./dist --name my-app
|
|
||||||
|
|
||||||
# Your app is now live at: https://my-app.orama.network
|
|
||||||
```
|
|
||||||
|
|
||||||
### Deploy Next.js with SSR
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd my-nextjs-app
|
|
||||||
|
|
||||||
# Ensure next.config.js has: output: 'standalone'
|
|
||||||
npm run build
|
|
||||||
orama deploy nextjs . --name my-nextjs --ssr
|
|
||||||
|
|
||||||
# Live at: https://my-nextjs.orama.network
|
|
||||||
```
|
|
||||||
|
|
||||||
### Deploy Go Backend
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build for Linux (name binary 'app' for auto-detection)
|
|
||||||
GOOS=linux GOARCH=amd64 go build -o app main.go
|
|
||||||
|
|
||||||
# Deploy (must implement /health endpoint)
|
|
||||||
orama deploy go ./app --name my-api
|
|
||||||
|
|
||||||
# API live at: https://my-api.orama.network
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create SQLite Database
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create database
|
|
||||||
orama db create my-database
|
|
||||||
|
|
||||||
# Create schema
|
|
||||||
orama db query my-database "CREATE TABLE users (id INT, name TEXT)"
|
|
||||||
|
|
||||||
# Insert data
|
|
||||||
orama db query my-database "INSERT INTO users VALUES (1, 'Alice')"
|
|
||||||
|
|
||||||
# Query data
|
|
||||||
orama db query my-database "SELECT * FROM users"
|
|
||||||
|
|
||||||
# Backup to IPFS
|
|
||||||
orama db backup my-database
|
|
||||||
```
|
|
||||||
|
|
||||||
### Full-Stack Example
|
|
||||||
|
|
||||||
Deploy a complete app with React frontend, Go backend, and SQLite database:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Create database
|
|
||||||
orama db create myapp-db
|
|
||||||
orama db query myapp-db "CREATE TABLE users (id INT PRIMARY KEY, name TEXT)"
|
|
||||||
|
|
||||||
# 2. Deploy Go backend (connects to database)
|
|
||||||
GOOS=linux GOARCH=amd64 go build -o api main.go
|
|
||||||
orama deploy go ./api --name myapp-api
|
|
||||||
|
|
||||||
# 3. Deploy React frontend (calls backend API)
|
|
||||||
cd frontend && npm run build
|
|
||||||
orama deploy static ./dist --name myapp
|
|
||||||
|
|
||||||
# Access:
|
|
||||||
# Frontend: https://myapp.orama.network
|
|
||||||
# Backend: https://myapp-api.orama.network
|
|
||||||
```
|
|
||||||
|
|
||||||
**📖 Full Guide**: See [Deployment Guide](docs/DEPLOYMENT_GUIDE.md) for complete documentation, examples, and best practices.
|
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### Local Development
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build the project
|
# Build the core network binaries
|
||||||
make build
|
make core-build
|
||||||
|
|
||||||
# Start 5-node development cluster
|
# Run tests
|
||||||
make dev
|
make core-test
|
||||||
|
|
||||||
|
# Start website dev server
|
||||||
|
make website-dev
|
||||||
|
|
||||||
|
# Build vault
|
||||||
|
make vault-build
|
||||||
```
|
```
|
||||||
|
|
||||||
The cluster automatically performs health checks before declaring success.
|
|
||||||
|
|
||||||
### Stop Development Environment
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make stop
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing Services
|
|
||||||
|
|
||||||
After running `make dev`, test service health using these curl requests:
|
|
||||||
|
|
||||||
### Node Unified Gateways
|
|
||||||
|
|
||||||
Each node is accessible via a single unified gateway port:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Node-1 (port 6001)
|
|
||||||
curl http://localhost:6001/health
|
|
||||||
|
|
||||||
# Node-2 (port 6002)
|
|
||||||
curl http://localhost:6002/health
|
|
||||||
|
|
||||||
# Node-3 (port 6003)
|
|
||||||
curl http://localhost:6003/health
|
|
||||||
|
|
||||||
# Node-4 (port 6004)
|
|
||||||
curl http://localhost:6004/health
|
|
||||||
|
|
||||||
# Node-5 (port 6005)
|
|
||||||
curl http://localhost:6005/health
|
|
||||||
```
|
|
||||||
|
|
||||||
## Network Architecture
|
|
||||||
|
|
||||||
### Unified Gateway Ports
|
|
||||||
|
|
||||||
```
|
|
||||||
Node-1: localhost:6001 → /rqlite/http, /rqlite/raft, /cluster, /ipfs/api
|
|
||||||
Node-2: localhost:6002 → Same routes
|
|
||||||
Node-3: localhost:6003 → Same routes
|
|
||||||
Node-4: localhost:6004 → Same routes
|
|
||||||
Node-5: localhost:6005 → Same routes
|
|
||||||
```
|
|
||||||
|
|
||||||
### Direct Service Ports (for debugging)
|
|
||||||
|
|
||||||
```
|
|
||||||
RQLite HTTP: 5001, 5002, 5003, 5004, 5005 (one per node)
|
|
||||||
RQLite Raft: 7001, 7002, 7003, 7004, 7005
|
|
||||||
IPFS API: 4501, 4502, 4503, 4504, 4505
|
|
||||||
IPFS Swarm: 4101, 4102, 4103, 4104, 4105
|
|
||||||
Cluster API: 9094, 9104, 9114, 9124, 9134
|
|
||||||
Internal Gateway: 6000
|
|
||||||
Olric Cache: 3320
|
|
||||||
Anon SOCKS: 9050
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Start full cluster (5 nodes + gateway)
|
|
||||||
make dev
|
|
||||||
|
|
||||||
# Check service status
|
|
||||||
orama dev status
|
|
||||||
|
|
||||||
# View logs
|
|
||||||
orama dev logs node-1 # Node-1 logs
|
|
||||||
orama dev logs node-1 --follow # Follow logs in real-time
|
|
||||||
orama dev logs gateway --follow # Gateway logs
|
|
||||||
|
|
||||||
# Stop all services
|
|
||||||
orama stop
|
|
||||||
|
|
||||||
# Build binaries
|
|
||||||
make build
|
|
||||||
```
|
|
||||||
|
|
||||||
## CLI Commands
|
|
||||||
|
|
||||||
### Authentication
|
|
||||||
|
|
||||||
```bash
|
|
||||||
orama auth login # Authenticate with wallet
|
|
||||||
orama auth status # Check authentication
|
|
||||||
orama auth logout # Clear credentials
|
|
||||||
```
|
|
||||||
|
|
||||||
### Application Deployments
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Deploy applications
|
|
||||||
orama deploy static <path> --name myapp # React, Vue, static sites
|
|
||||||
orama deploy nextjs <path> --name myapp --ssr # Next.js with SSR (requires output: 'standalone')
|
|
||||||
orama deploy go <path> --name myapp # Go binaries (must have /health endpoint)
|
|
||||||
orama deploy nodejs <path> --name myapp # Node.js apps (must have /health endpoint)
|
|
||||||
|
|
||||||
# Manage deployments
|
|
||||||
orama deployments list # List all deployments
|
|
||||||
orama deployments get <name> # Get deployment details
|
|
||||||
orama deployments logs <name> --follow # View logs
|
|
||||||
orama deployments delete <name> # Delete deployment
|
|
||||||
orama deployments rollback <name> --version 1 # Rollback to version
|
|
||||||
```
|
|
||||||
|
|
||||||
### SQLite Databases
|
|
||||||
|
|
||||||
```bash
|
|
||||||
orama db create <name> # Create database
|
|
||||||
orama db query <name> "SELECT * FROM t" # Execute SQL query
|
|
||||||
orama db list # List all databases
|
|
||||||
orama db backup <name> # Backup to IPFS
|
|
||||||
orama db backups <name> # List backups
|
|
||||||
```
|
|
||||||
|
|
||||||
### Network Status
|
|
||||||
|
|
||||||
```bash
|
|
||||||
orama health # Cluster health check
|
|
||||||
orama peers # List connected peers
|
|
||||||
orama status # Network status
|
|
||||||
```
|
|
||||||
|
|
||||||
### RQLite Operations
|
|
||||||
|
|
||||||
```bash
|
|
||||||
orama query "SELECT * FROM users"
|
|
||||||
orama query "CREATE TABLE users (id INTEGER PRIMARY KEY)"
|
|
||||||
orama transaction --file ops.json
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pub/Sub
|
|
||||||
|
|
||||||
```bash
|
|
||||||
orama pubsub publish <topic> <message>
|
|
||||||
orama pubsub subscribe <topic> 30s
|
|
||||||
orama pubsub topics
|
|
||||||
```
|
|
||||||
|
|
||||||
## Serverless Functions (WASM)
|
|
||||||
|
|
||||||
Orama supports high-performance serverless function execution using WebAssembly (WASM). Functions are isolated, secure, and can interact with network services like the distributed cache.
|
|
||||||
|
|
||||||
### 1. Build Functions
|
|
||||||
|
|
||||||
Functions must be compiled to WASM. We recommend using [TinyGo](https://tinygo.org/).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build example functions to examples/functions/bin/
|
|
||||||
./examples/functions/build.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Deployment
|
|
||||||
|
|
||||||
Deploy your compiled `.wasm` file to the network via the Gateway.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Deploy a function
|
|
||||||
curl -X POST http://localhost:6001/v1/functions \
|
|
||||||
-H "Authorization: Bearer <your_api_key>" \
|
|
||||||
-F "name=hello-world" \
|
|
||||||
-F "namespace=default" \
|
|
||||||
-F "wasm=@./examples/functions/bin/hello.wasm"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Invocation
|
|
||||||
|
|
||||||
Trigger your function with a JSON payload. The function receives the payload via `stdin` and returns its response via `stdout`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Invoke via HTTP
|
|
||||||
curl -X POST http://localhost:6001/v1/functions/hello-world/invoke \
|
|
||||||
-H "Authorization: Bearer <your_api_key>" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"name": "Developer"}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Management
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# List all functions in a namespace
|
|
||||||
curl http://localhost:6001/v1/functions?namespace=default
|
|
||||||
|
|
||||||
# Delete a function
|
|
||||||
curl -X DELETE http://localhost:6001/v1/functions/hello-world?namespace=default
|
|
||||||
```
|
|
||||||
|
|
||||||
## Production Deployment
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
- Ubuntu 22.04+ or Debian 12+
|
|
||||||
- `amd64` or `arm64` architecture
|
|
||||||
- 4GB RAM, 50GB SSD, 2 CPU cores
|
|
||||||
|
|
||||||
### Required Ports
|
|
||||||
|
|
||||||
**External (must be open in firewall):**
|
|
||||||
|
|
||||||
- **80** - HTTP (ACME/Let's Encrypt certificate challenges)
|
|
||||||
- **443** - HTTPS (Main gateway API endpoint)
|
|
||||||
- **4101** - IPFS Swarm (peer connections)
|
|
||||||
- **7001** - RQLite Raft (cluster consensus)
|
|
||||||
|
|
||||||
**Internal (bound to localhost, no firewall needed):**
|
|
||||||
|
|
||||||
- 4501 - IPFS API
|
|
||||||
- 5001 - RQLite HTTP API
|
|
||||||
- 6001 - Unified Gateway
|
|
||||||
- 8080 - IPFS Gateway
|
|
||||||
- 9050 - Anyone SOCKS5 proxy
|
|
||||||
- 9094 - IPFS Cluster API
|
|
||||||
- 3320/3322 - Olric Cache
|
|
||||||
|
|
||||||
**Anyone Relay Mode (optional, for earning rewards):**
|
|
||||||
|
|
||||||
- 9001 - Anyone ORPort (relay traffic, must be open externally)
|
|
||||||
|
|
||||||
### Anyone Network Integration
|
|
||||||
|
|
||||||
Orama Network integrates with the [Anyone Protocol](https://anyone.io) for anonymous routing. By default, nodes run as **clients** (consuming the network). Optionally, you can run as a **relay operator** to earn rewards.
|
|
||||||
|
|
||||||
**Client Mode (Default):**
|
|
||||||
- Routes traffic through Anyone network for anonymity
|
|
||||||
- SOCKS5 proxy on localhost:9050
|
|
||||||
- No rewards, just consumes network
|
|
||||||
|
|
||||||
**Relay Mode (Earn Rewards):**
|
|
||||||
- Provide bandwidth to the Anyone network
|
|
||||||
- Earn $ANYONE tokens as a relay operator
|
|
||||||
- Requires 100 $ANYONE tokens in your wallet
|
|
||||||
- Requires ORPort (9001) open to the internet
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install as relay operator (earn rewards)
|
|
||||||
sudo orama install --vps-ip <IP> --domain <domain> \
|
|
||||||
--anyone-relay \
|
|
||||||
--anyone-nickname "MyRelay" \
|
|
||||||
--anyone-contact "operator@email.com" \
|
|
||||||
--anyone-wallet "0x1234...abcd"
|
|
||||||
|
|
||||||
# With exit relay (legal implications apply)
|
|
||||||
sudo orama install --vps-ip <IP> --domain <domain> \
|
|
||||||
--anyone-relay \
|
|
||||||
--anyone-exit \
|
|
||||||
--anyone-nickname "MyExitRelay" \
|
|
||||||
--anyone-contact "operator@email.com" \
|
|
||||||
--anyone-wallet "0x1234...abcd"
|
|
||||||
|
|
||||||
# Migrate existing Anyone installation
|
|
||||||
sudo orama install --vps-ip <IP> --domain <domain> \
|
|
||||||
--anyone-relay \
|
|
||||||
--anyone-migrate \
|
|
||||||
--anyone-nickname "MyRelay" \
|
|
||||||
--anyone-contact "operator@email.com" \
|
|
||||||
--anyone-wallet "0x1234...abcd"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Important:** After installation, register your relay at [dashboard.anyone.io](https://dashboard.anyone.io) to start earning rewards.
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
**macOS (Homebrew):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew install DeBrosOfficial/tap/orama
|
|
||||||
```
|
|
||||||
|
|
||||||
**Linux (Debian/Ubuntu):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Download and install the latest .deb package
|
|
||||||
curl -sL https://github.com/DeBrosOfficial/network/releases/latest/download/orama_$(curl -s https://api.github.com/repos/DeBrosOfficial/network/releases/latest | grep tag_name | cut -d '"' -f 4 | tr -d 'v')_linux_amd64.deb -o orama.deb
|
|
||||||
sudo dpkg -i orama.deb
|
|
||||||
```
|
|
||||||
|
|
||||||
**From Source:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go install github.com/DeBrosOfficial/network/cmd/cli@latest
|
|
||||||
```
|
|
||||||
|
|
||||||
**Setup (after installation):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo orama install --interactive
|
|
||||||
```
|
|
||||||
|
|
||||||
### Service Management
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Status
|
|
||||||
orama status
|
|
||||||
|
|
||||||
# Control services
|
|
||||||
sudo orama start
|
|
||||||
sudo orama stop
|
|
||||||
sudo orama restart
|
|
||||||
|
|
||||||
# View logs
|
|
||||||
orama logs node --follow
|
|
||||||
orama logs gateway --follow
|
|
||||||
orama logs ipfs --follow
|
|
||||||
```
|
|
||||||
|
|
||||||
### Upgrade
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Upgrade to latest version
|
|
||||||
sudo orama upgrade --interactive
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
All configuration lives in `~/.orama/`:
|
|
||||||
|
|
||||||
- `configs/node.yaml` - Node configuration
|
|
||||||
- `configs/gateway.yaml` - Gateway configuration
|
|
||||||
- `configs/olric.yaml` - Cache configuration
|
|
||||||
- `secrets/` - Keys and certificates
|
|
||||||
- `data/` - Service data directories
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Services Not Starting
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check status
|
|
||||||
systemctl status debros-node
|
|
||||||
|
|
||||||
# View logs
|
|
||||||
journalctl -u debros-node -f
|
|
||||||
|
|
||||||
# Check log files
|
|
||||||
tail -f /home/debros/.orama/logs/node.log
|
|
||||||
```
|
|
||||||
|
|
||||||
### Port Conflicts
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check what's using specific ports
|
|
||||||
sudo lsof -i :443 # HTTPS Gateway
|
|
||||||
sudo lsof -i :7001 # TCP/SNI Gateway
|
|
||||||
sudo lsof -i :6001 # Internal Gateway
|
|
||||||
```
|
|
||||||
|
|
||||||
### RQLite Cluster Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Connect to RQLite CLI
|
|
||||||
rqlite -H localhost -p 5001
|
|
||||||
|
|
||||||
# Check cluster status
|
|
||||||
.nodes
|
|
||||||
.status
|
|
||||||
.ready
|
|
||||||
|
|
||||||
# Check consistency level
|
|
||||||
.consistency
|
|
||||||
```
|
|
||||||
|
|
||||||
### Reset Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Production reset (⚠️ DESTROYS DATA)
|
|
||||||
sudo orama uninstall
|
|
||||||
sudo rm -rf /home/debros/.orama
|
|
||||||
sudo orama install
|
|
||||||
```
|
|
||||||
|
|
||||||
## HTTP Gateway API
|
|
||||||
|
|
||||||
### Main Gateway Endpoints
|
|
||||||
|
|
||||||
- `GET /health` - Health status
|
|
||||||
- `GET /v1/status` - Full status
|
|
||||||
- `GET /v1/version` - Version info
|
|
||||||
- `POST /v1/rqlite/exec` - Execute SQL
|
|
||||||
- `POST /v1/rqlite/query` - Query database
|
|
||||||
- `GET /v1/rqlite/schema` - Get schema
|
|
||||||
- `POST /v1/pubsub/publish` - Publish message
|
|
||||||
- `GET /v1/pubsub/topics` - List topics
|
|
||||||
- `GET /v1/pubsub/ws?topic=<name>` - WebSocket subscribe
|
|
||||||
- `POST /v1/functions` - Deploy function (multipart/form-data)
|
|
||||||
- `POST /v1/functions/{name}/invoke` - Invoke function
|
|
||||||
- `GET /v1/functions` - List functions
|
|
||||||
- `DELETE /v1/functions/{name}` - Delete function
|
|
||||||
- `GET /v1/functions/{name}/logs` - Get function logs
|
|
||||||
|
|
||||||
See `openapi/gateway.yaml` for complete API specification.
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- **[Deployment Guide](docs/DEPLOYMENT_GUIDE.md)** - Deploy React, Next.js, Go apps and manage databases
|
| Document | Description |
|
||||||
- **[Architecture Guide](docs/ARCHITECTURE.md)** - System architecture and design patterns
|
|----------|-------------|
|
||||||
- **[Client SDK](docs/CLIENT_SDK.md)** - Go SDK documentation and examples
|
| [Architecture](core/docs/ARCHITECTURE.md) | System architecture and design patterns |
|
||||||
- **[Gateway API](docs/GATEWAY_API.md)** - Complete HTTP API reference
|
| [Deployment Guide](core/docs/DEPLOYMENT_GUIDE.md) | Deploy apps, databases, and domains |
|
||||||
- **[Security Deployment](docs/SECURITY_DEPLOYMENT_GUIDE.md)** - Production security hardening
|
| [Dev & Deploy](core/docs/DEV_DEPLOY.md) | Building, deploying to VPS, rolling upgrades |
|
||||||
- **[Testing Plan](docs/TESTING_PLAN.md)** - Comprehensive testing strategy and implementation
|
| [Security](core/docs/SECURITY.md) | Security hardening and threat model |
|
||||||
|
| [Monitoring](core/docs/MONITORING.md) | Cluster health monitoring |
|
||||||
## Resources
|
| [Client SDK](core/docs/CLIENT_SDK.md) | Go SDK documentation |
|
||||||
|
| [Serverless](core/docs/SERVERLESS.md) | WASM serverless functions |
|
||||||
- [RQLite Documentation](https://rqlite.io/docs/)
|
| [Common Problems](core/docs/COMMON_PROBLEMS.md) | Troubleshooting known issues |
|
||||||
- [IPFS Documentation](https://docs.ipfs.tech/)
|
|
||||||
- [LibP2P Documentation](https://docs.libp2p.io/)
|
|
||||||
- [WebAssembly](https://webassembly.org/)
|
|
||||||
- [GitHub Repository](https://github.com/DeBrosOfficial/network)
|
|
||||||
- [Issue Tracker](https://github.com/DeBrosOfficial/network/issues)
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
network/
|
|
||||||
├── cmd/ # Binary entry points
|
|
||||||
│ ├── cli/ # CLI tool
|
|
||||||
│ ├── gateway/ # HTTP Gateway
|
|
||||||
│ ├── node/ # P2P Node
|
|
||||||
│ └── rqlite-mcp/ # RQLite MCP server
|
|
||||||
├── pkg/ # Core packages
|
|
||||||
│ ├── gateway/ # Gateway implementation
|
|
||||||
│ │ └── handlers/ # HTTP handlers by domain
|
|
||||||
│ ├── client/ # Go SDK
|
|
||||||
│ ├── serverless/ # WASM engine
|
|
||||||
│ ├── rqlite/ # Database ORM
|
|
||||||
│ ├── contracts/ # Interface definitions
|
|
||||||
│ ├── httputil/ # HTTP utilities
|
|
||||||
│ └── errors/ # Error handling
|
|
||||||
├── docs/ # Documentation
|
|
||||||
├── e2e/ # End-to-end tests
|
|
||||||
└── examples/ # Example code
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions are welcome! This project follows:
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, development, and PR guidelines.
|
||||||
- **SOLID Principles** - Single responsibility, open/closed, etc.
|
|
||||||
- **DRY Principle** - Don't repeat yourself
|
|
||||||
- **Clean Architecture** - Clear separation of concerns
|
|
||||||
- **Test Coverage** - Unit and E2E tests required
|
|
||||||
|
|
||||||
See our architecture docs for design patterns and guidelines.
|
## License
|
||||||
|
|
||||||
|
[AGPL-3.0](LICENSE)
|
||||||
|
|||||||
221
cmd/cli/main.go
221
cmd/cli/main.go
@ -1,221 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/DeBrosOfficial/network/pkg/cli"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
timeout = 30 * time.Second
|
|
||||||
format = "table"
|
|
||||||
)
|
|
||||||
|
|
||||||
// version metadata populated via -ldflags at build time
|
|
||||||
var (
|
|
||||||
version = "dev"
|
|
||||||
commit = ""
|
|
||||||
date = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if len(os.Args) < 2 {
|
|
||||||
showHelp()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
command := os.Args[1]
|
|
||||||
args := os.Args[2:]
|
|
||||||
|
|
||||||
// Parse global flags
|
|
||||||
parseGlobalFlags(args)
|
|
||||||
|
|
||||||
switch command {
|
|
||||||
case "version":
|
|
||||||
fmt.Printf("orama %s", version)
|
|
||||||
if commit != "" {
|
|
||||||
fmt.Printf(" (commit %s)", commit)
|
|
||||||
}
|
|
||||||
if date != "" {
|
|
||||||
fmt.Printf(" built %s", date)
|
|
||||||
}
|
|
||||||
fmt.Println()
|
|
||||||
return
|
|
||||||
|
|
||||||
// Development environment commands
|
|
||||||
case "dev":
|
|
||||||
cli.HandleDevCommand(args)
|
|
||||||
|
|
||||||
// Production environment commands (legacy with 'prod' prefix)
|
|
||||||
case "prod":
|
|
||||||
cli.HandleProdCommand(args)
|
|
||||||
|
|
||||||
// Direct production commands (new simplified interface)
|
|
||||||
case "invite":
|
|
||||||
cli.HandleProdCommand(append([]string{"invite"}, args...))
|
|
||||||
case "install":
|
|
||||||
cli.HandleProdCommand(append([]string{"install"}, args...))
|
|
||||||
case "upgrade":
|
|
||||||
cli.HandleProdCommand(append([]string{"upgrade"}, args...))
|
|
||||||
case "migrate":
|
|
||||||
cli.HandleProdCommand(append([]string{"migrate"}, args...))
|
|
||||||
case "status":
|
|
||||||
cli.HandleProdCommand(append([]string{"status"}, args...))
|
|
||||||
case "start":
|
|
||||||
cli.HandleProdCommand(append([]string{"start"}, args...))
|
|
||||||
case "stop":
|
|
||||||
cli.HandleProdCommand(append([]string{"stop"}, args...))
|
|
||||||
case "restart":
|
|
||||||
cli.HandleProdCommand(append([]string{"restart"}, args...))
|
|
||||||
case "logs":
|
|
||||||
cli.HandleProdCommand(append([]string{"logs"}, args...))
|
|
||||||
case "uninstall":
|
|
||||||
cli.HandleProdCommand(append([]string{"uninstall"}, args...))
|
|
||||||
|
|
||||||
// Authentication commands
|
|
||||||
case "auth":
|
|
||||||
cli.HandleAuthCommand(args)
|
|
||||||
|
|
||||||
// Deployment commands
|
|
||||||
case "deploy":
|
|
||||||
cli.HandleDeployCommand(args)
|
|
||||||
case "deployments":
|
|
||||||
cli.HandleDeploymentsCommand(args)
|
|
||||||
|
|
||||||
// Database commands
|
|
||||||
case "db":
|
|
||||||
cli.HandleDBCommand(args)
|
|
||||||
|
|
||||||
// Cluster inspection
|
|
||||||
case "inspect":
|
|
||||||
cli.HandleInspectCommand(args)
|
|
||||||
|
|
||||||
// Namespace management
|
|
||||||
case "namespace":
|
|
||||||
cli.HandleNamespaceCommand(args)
|
|
||||||
|
|
||||||
// Environment management
|
|
||||||
case "env":
|
|
||||||
cli.HandleEnvCommand(args)
|
|
||||||
|
|
||||||
// Help
|
|
||||||
case "help", "--help", "-h":
|
|
||||||
showHelp()
|
|
||||||
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command)
|
|
||||||
showHelp()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseGlobalFlags(args []string) {
|
|
||||||
for i, arg := range args {
|
|
||||||
switch arg {
|
|
||||||
case "-f", "--format":
|
|
||||||
if i+1 < len(args) {
|
|
||||||
format = args[i+1]
|
|
||||||
}
|
|
||||||
case "-t", "--timeout":
|
|
||||||
if i+1 < len(args) {
|
|
||||||
if d, err := time.ParseDuration(args[i+1]); err == nil {
|
|
||||||
timeout = d
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func showHelp() {
|
|
||||||
fmt.Printf("Orama CLI - Distributed P2P Network Management Tool\n\n")
|
|
||||||
fmt.Printf("Usage: orama <command> [args...]\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("💻 Local Development:\n")
|
|
||||||
fmt.Printf(" dev up - Start full local dev environment\n")
|
|
||||||
fmt.Printf(" dev down - Stop all dev services\n")
|
|
||||||
fmt.Printf(" dev status - Show status of dev services\n")
|
|
||||||
fmt.Printf(" dev logs <component> - View dev component logs\n")
|
|
||||||
fmt.Printf(" dev help - Show dev command help\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("🚀 Production Deployment:\n")
|
|
||||||
fmt.Printf(" install - Install production node (requires root/sudo)\n")
|
|
||||||
fmt.Printf(" upgrade - Upgrade existing installation\n")
|
|
||||||
fmt.Printf(" status - Show production service status\n")
|
|
||||||
fmt.Printf(" start - Start all production services (requires root/sudo)\n")
|
|
||||||
fmt.Printf(" stop - Stop all production services (requires root/sudo)\n")
|
|
||||||
fmt.Printf(" restart - Restart all production services (requires root/sudo)\n")
|
|
||||||
fmt.Printf(" logs <service> - View production service logs\n")
|
|
||||||
fmt.Printf(" uninstall - Remove production services (requires root/sudo)\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("🔐 Authentication:\n")
|
|
||||||
fmt.Printf(" auth login - Authenticate with wallet\n")
|
|
||||||
fmt.Printf(" auth logout - Clear stored credentials\n")
|
|
||||||
fmt.Printf(" auth whoami - Show current authentication\n")
|
|
||||||
fmt.Printf(" auth status - Show detailed auth info\n")
|
|
||||||
fmt.Printf(" auth help - Show auth command help\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("📦 Deployments:\n")
|
|
||||||
fmt.Printf(" deploy static <path> - Deploy a static site (React, Vue, etc.)\n")
|
|
||||||
fmt.Printf(" deploy nextjs <path> - Deploy a Next.js application\n")
|
|
||||||
fmt.Printf(" deploy go <path> - Deploy a Go backend\n")
|
|
||||||
fmt.Printf(" deploy nodejs <path> - Deploy a Node.js backend\n")
|
|
||||||
fmt.Printf(" deployments list - List all deployments\n")
|
|
||||||
fmt.Printf(" deployments get <name> - Get deployment details\n")
|
|
||||||
fmt.Printf(" deployments logs <name> - View deployment logs\n")
|
|
||||||
fmt.Printf(" deployments delete <name> - Delete a deployment\n")
|
|
||||||
fmt.Printf(" deployments rollback <name> - Rollback to previous version\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("🗄️ Databases:\n")
|
|
||||||
fmt.Printf(" db create <name> - Create a SQLite database\n")
|
|
||||||
fmt.Printf(" db query <name> \"<sql>\" - Execute SQL query\n")
|
|
||||||
fmt.Printf(" db list - List all databases\n")
|
|
||||||
fmt.Printf(" db backup <name> - Backup database to IPFS\n")
|
|
||||||
fmt.Printf(" db backups <name> - List database backups\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("🏢 Namespaces:\n")
|
|
||||||
fmt.Printf(" namespace delete - Delete current namespace and all resources\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("🔍 Cluster Inspection:\n")
|
|
||||||
fmt.Printf(" inspect - Inspect cluster health via SSH\n")
|
|
||||||
fmt.Printf(" inspect --env devnet - Inspect devnet nodes\n")
|
|
||||||
fmt.Printf(" inspect --subsystem rqlite - Inspect only RQLite subsystem\n")
|
|
||||||
fmt.Printf(" inspect --format json - Output as JSON\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("🌍 Environments:\n")
|
|
||||||
fmt.Printf(" env list - List all environments\n")
|
|
||||||
fmt.Printf(" env current - Show current environment\n")
|
|
||||||
fmt.Printf(" env switch <name> - Switch to environment\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("Global Flags:\n")
|
|
||||||
fmt.Printf(" -f, --format <format> - Output format: table, json (default: table)\n")
|
|
||||||
fmt.Printf(" -t, --timeout <duration> - Operation timeout (default: 30s)\n")
|
|
||||||
fmt.Printf(" --help, -h - Show this help message\n\n")
|
|
||||||
|
|
||||||
fmt.Printf("Examples:\n")
|
|
||||||
fmt.Printf(" # Deploy a React app\n")
|
|
||||||
fmt.Printf(" cd my-react-app && npm run build\n")
|
|
||||||
fmt.Printf(" orama deploy static ./dist --name my-app\n\n")
|
|
||||||
|
|
||||||
fmt.Printf(" # Deploy a Next.js app with SSR\n")
|
|
||||||
fmt.Printf(" cd my-nextjs-app && npm run build\n")
|
|
||||||
fmt.Printf(" orama deploy nextjs . --name my-nextjs --ssr\n\n")
|
|
||||||
|
|
||||||
fmt.Printf(" # Create and use a database\n")
|
|
||||||
fmt.Printf(" orama db create my-db\n")
|
|
||||||
fmt.Printf(" orama db query my-db \"CREATE TABLE users (id INT, name TEXT)\"\n")
|
|
||||||
fmt.Printf(" orama db query my-db \"INSERT INTO users VALUES (1, 'Alice')\"\n\n")
|
|
||||||
|
|
||||||
fmt.Printf(" # Manage deployments\n")
|
|
||||||
fmt.Printf(" orama deployments list\n")
|
|
||||||
fmt.Printf(" orama deployments get my-app\n")
|
|
||||||
fmt.Printf(" orama deployments logs my-app --follow\n\n")
|
|
||||||
|
|
||||||
fmt.Printf(" # First node (creates new cluster)\n")
|
|
||||||
fmt.Printf(" sudo orama install --vps-ip 203.0.113.1 --domain node-1.orama.network\n\n")
|
|
||||||
|
|
||||||
fmt.Printf(" # Service management\n")
|
|
||||||
fmt.Printf(" orama status\n")
|
|
||||||
fmt.Printf(" orama logs node --follow\n")
|
|
||||||
}
|
|
||||||
@ -1,326 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/rqlite/gorqlite"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MCP JSON-RPC types
|
|
||||||
type JSONRPCRequest struct {
|
|
||||||
JSONRPC string `json:"jsonrpc"`
|
|
||||||
ID any `json:"id,omitempty"`
|
|
||||||
Method string `json:"method"`
|
|
||||||
Params json.RawMessage `json:"params,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type JSONRPCResponse struct {
|
|
||||||
JSONRPC string `json:"jsonrpc"`
|
|
||||||
ID any `json:"id"`
|
|
||||||
Result any `json:"result,omitempty"`
|
|
||||||
Error *ResponseError `json:"error,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResponseError struct {
|
|
||||||
Code int `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tool definition
|
|
||||||
type Tool struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
InputSchema any `json:"inputSchema"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tool call types
|
|
||||||
type CallToolRequest struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Arguments json.RawMessage `json:"arguments"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TextContent struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Text string `json:"text"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CallToolResult struct {
|
|
||||||
Content []TextContent `json:"content"`
|
|
||||||
IsError bool `json:"isError,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MCPServer struct {
|
|
||||||
conn *gorqlite.Connection
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMCPServer(rqliteURL string) (*MCPServer, error) {
|
|
||||||
// Disable gorqlite cluster discovery to avoid /nodes timeouts from unreachable peers
|
|
||||||
if strings.Contains(rqliteURL, "?") {
|
|
||||||
rqliteURL += "&disableClusterDiscovery=true"
|
|
||||||
} else {
|
|
||||||
rqliteURL += "?disableClusterDiscovery=true"
|
|
||||||
}
|
|
||||||
conn, err := gorqlite.Open(rqliteURL)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &MCPServer{
|
|
||||||
conn: conn,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *MCPServer) handleRequest(req JSONRPCRequest) JSONRPCResponse {
|
|
||||||
var resp JSONRPCResponse
|
|
||||||
resp.JSONRPC = "2.0"
|
|
||||||
resp.ID = req.ID
|
|
||||||
|
|
||||||
// Debug logging disabled to prevent excessive disk writes
|
|
||||||
// log.Printf("Received method: %s", req.Method)
|
|
||||||
|
|
||||||
switch req.Method {
|
|
||||||
case "initialize":
|
|
||||||
resp.Result = map[string]any{
|
|
||||||
"protocolVersion": "2024-11-05",
|
|
||||||
"capabilities": map[string]any{
|
|
||||||
"tools": map[string]any{},
|
|
||||||
},
|
|
||||||
"serverInfo": map[string]any{
|
|
||||||
"name": "rqlite-mcp",
|
|
||||||
"version": "0.1.0",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
case "notifications/initialized":
|
|
||||||
// This is a notification, no response needed
|
|
||||||
return JSONRPCResponse{}
|
|
||||||
|
|
||||||
case "tools/list":
|
|
||||||
// Debug logging disabled to prevent excessive disk writes
|
|
||||||
tools := []Tool{
|
|
||||||
{
|
|
||||||
Name: "list_tables",
|
|
||||||
Description: "List all tables in the Rqlite database",
|
|
||||||
InputSchema: map[string]any{
|
|
||||||
"type": "object",
|
|
||||||
"properties": map[string]any{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "query",
|
|
||||||
Description: "Run a SELECT query on the Rqlite database",
|
|
||||||
InputSchema: map[string]any{
|
|
||||||
"type": "object",
|
|
||||||
"properties": map[string]any{
|
|
||||||
"sql": map[string]any{
|
|
||||||
"type": "string",
|
|
||||||
"description": "The SQL SELECT query to run",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"required": []string{"sql"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "execute",
|
|
||||||
Description: "Run an INSERT, UPDATE, or DELETE statement on the Rqlite database",
|
|
||||||
InputSchema: map[string]any{
|
|
||||||
"type": "object",
|
|
||||||
"properties": map[string]any{
|
|
||||||
"sql": map[string]any{
|
|
||||||
"type": "string",
|
|
||||||
"description": "The SQL statement (INSERT, UPDATE, DELETE) to run",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"required": []string{"sql"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
resp.Result = map[string]any{"tools": tools}
|
|
||||||
|
|
||||||
case "tools/call":
|
|
||||||
var callReq CallToolRequest
|
|
||||||
if err := json.Unmarshal(req.Params, &callReq); err != nil {
|
|
||||||
resp.Error = &ResponseError{Code: -32700, Message: "Parse error"}
|
|
||||||
return resp
|
|
||||||
}
|
|
||||||
resp.Result = s.handleToolCall(callReq)
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Debug logging disabled to prevent excessive disk writes
|
|
||||||
resp.Error = &ResponseError{Code: -32601, Message: "Method not found"}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *MCPServer) handleToolCall(req CallToolRequest) CallToolResult {
|
|
||||||
// Debug logging disabled to prevent excessive disk writes
|
|
||||||
// log.Printf("Tool call: %s", req.Name)
|
|
||||||
|
|
||||||
switch req.Name {
|
|
||||||
case "list_tables":
|
|
||||||
rows, err := s.conn.QueryOne("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")
|
|
||||||
if err != nil {
|
|
||||||
return errorResult(fmt.Sprintf("Error listing tables: %v", err))
|
|
||||||
}
|
|
||||||
var tables []string
|
|
||||||
for rows.Next() {
|
|
||||||
slice, err := rows.Slice()
|
|
||||||
if err == nil && len(slice) > 0 {
|
|
||||||
tables = append(tables, fmt.Sprint(slice[0]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(tables) == 0 {
|
|
||||||
return textResult("No tables found")
|
|
||||||
}
|
|
||||||
return textResult(strings.Join(tables, "\n"))
|
|
||||||
|
|
||||||
case "query":
|
|
||||||
var args struct {
|
|
||||||
SQL string `json:"sql"`
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(req.Arguments, &args); err != nil {
|
|
||||||
return errorResult(fmt.Sprintf("Invalid arguments: %v", err))
|
|
||||||
}
|
|
||||||
// Debug logging disabled to prevent excessive disk writes
|
|
||||||
rows, err := s.conn.QueryOne(args.SQL)
|
|
||||||
if err != nil {
|
|
||||||
return errorResult(fmt.Sprintf("Query error: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
var result strings.Builder
|
|
||||||
cols := rows.Columns()
|
|
||||||
result.WriteString(strings.Join(cols, " | ") + "\n")
|
|
||||||
result.WriteString(strings.Repeat("-", len(cols)*10) + "\n")
|
|
||||||
|
|
||||||
rowCount := 0
|
|
||||||
for rows.Next() {
|
|
||||||
vals, err := rows.Slice()
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
rowCount++
|
|
||||||
for i, v := range vals {
|
|
||||||
if i > 0 {
|
|
||||||
result.WriteString(" | ")
|
|
||||||
}
|
|
||||||
result.WriteString(fmt.Sprint(v))
|
|
||||||
}
|
|
||||||
result.WriteString("\n")
|
|
||||||
}
|
|
||||||
result.WriteString(fmt.Sprintf("\n(%d rows)", rowCount))
|
|
||||||
return textResult(result.String())
|
|
||||||
|
|
||||||
case "execute":
|
|
||||||
var args struct {
|
|
||||||
SQL string `json:"sql"`
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(req.Arguments, &args); err != nil {
|
|
||||||
return errorResult(fmt.Sprintf("Invalid arguments: %v", err))
|
|
||||||
}
|
|
||||||
// Debug logging disabled to prevent excessive disk writes
|
|
||||||
res, err := s.conn.WriteOne(args.SQL)
|
|
||||||
if err != nil {
|
|
||||||
return errorResult(fmt.Sprintf("Execution error: %v", err))
|
|
||||||
}
|
|
||||||
return textResult(fmt.Sprintf("Rows affected: %d", res.RowsAffected))
|
|
||||||
|
|
||||||
default:
|
|
||||||
return errorResult(fmt.Sprintf("Unknown tool: %s", req.Name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func textResult(text string) CallToolResult {
|
|
||||||
return CallToolResult{
|
|
||||||
Content: []TextContent{
|
|
||||||
{
|
|
||||||
Type: "text",
|
|
||||||
Text: text,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func errorResult(text string) CallToolResult {
|
|
||||||
return CallToolResult{
|
|
||||||
Content: []TextContent{
|
|
||||||
{
|
|
||||||
Type: "text",
|
|
||||||
Text: text,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
IsError: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Log to stderr so stdout is clean for JSON-RPC
|
|
||||||
log.SetOutput(os.Stderr)
|
|
||||||
|
|
||||||
rqliteURL := "http://localhost:5001"
|
|
||||||
if u := os.Getenv("RQLITE_URL"); u != "" {
|
|
||||||
rqliteURL = u
|
|
||||||
}
|
|
||||||
|
|
||||||
var server *MCPServer
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// Retry connecting to rqlite
|
|
||||||
maxRetries := 30
|
|
||||||
for i := 0; i < maxRetries; i++ {
|
|
||||||
server, err = NewMCPServer(rqliteURL)
|
|
||||||
if err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if i%5 == 0 {
|
|
||||||
log.Printf("Waiting for Rqlite at %s... (%d/%d)", rqliteURL, i+1, maxRetries)
|
|
||||||
}
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to connect to Rqlite after %d retries: %v", maxRetries, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("MCP Rqlite server started (stdio transport)")
|
|
||||||
log.Printf("Connected to Rqlite at %s", rqliteURL)
|
|
||||||
|
|
||||||
// Read JSON-RPC requests from stdin, write responses to stdout
|
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Text()
|
|
||||||
if line == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var req JSONRPCRequest
|
|
||||||
if err := json.Unmarshal([]byte(line), &req); err != nil {
|
|
||||||
// Debug logging disabled to prevent excessive disk writes
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := server.handleRequest(req)
|
|
||||||
|
|
||||||
// Don't send response for notifications (no ID)
|
|
||||||
if req.ID == nil && strings.HasPrefix(req.Method, "notifications/") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
respData, err := json.Marshal(resp)
|
|
||||||
if err != nil {
|
|
||||||
// Debug logging disabled to prevent excessive disk writes
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(string(respData))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
|
||||||
// Debug logging disabled to prevent excessive disk writes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8
core/.env.example
Normal file
8
core/.env.example
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# OpenRouter API Key for changelog generation
|
||||||
|
# Get your API key from https://openrouter.ai/keys
|
||||||
|
OPENROUTER_API_KEY=your-api-key-here
|
||||||
|
|
||||||
|
# ZeroSSL API Key for TLS certificates (alternative to Let's Encrypt)
|
||||||
|
# Get your free API key from https://app.zerossl.com/developer
|
||||||
|
# If not set, Caddy will use Let's Encrypt as the default CA
|
||||||
|
ZEROSSL_API_KEY=
|
||||||
@ -8,7 +8,7 @@ NOCOLOR='\033[0m'
|
|||||||
|
|
||||||
# Run tests before push
|
# Run tests before push
|
||||||
echo -e "\n${CYAN}Running tests...${NOCOLOR}"
|
echo -e "\n${CYAN}Running tests...${NOCOLOR}"
|
||||||
go test ./... # Runs all tests in your repo
|
cd "$(git rev-parse --show-toplevel)/core" && go test ./...
|
||||||
status=$?
|
status=$?
|
||||||
if [ $status -ne 0 ]; then
|
if [ $status -ne 0 ]; then
|
||||||
echo -e "${RED}Push aborted: some tests failed.${NOCOLOR}"
|
echo -e "${RED}Push aborted: some tests failed.${NOCOLOR}"
|
||||||
181
core/Makefile
Normal file
181
core/Makefile
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
TEST?=./...
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test:
|
||||||
|
@echo Running tests...
|
||||||
|
go test -v $(TEST)
|
||||||
|
|
||||||
|
# Gateway-focused E2E tests assume gateway and nodes are already running
|
||||||
|
# Auto-discovers configuration from ~/.orama and queries database for API key
|
||||||
|
# No environment variables required
|
||||||
|
.PHONY: test-e2e test-e2e-deployments test-e2e-fullstack test-e2e-https test-e2e-quick test-e2e-prod test-e2e-shared test-e2e-cluster test-e2e-integration test-e2e-production
|
||||||
|
|
||||||
|
# Production E2E tests - includes production-only tests
|
||||||
|
test-e2e-prod:
|
||||||
|
@if [ -z "$$ORAMA_GATEWAY_URL" ]; then \
|
||||||
|
echo "❌ ORAMA_GATEWAY_URL not set"; \
|
||||||
|
echo "Usage: ORAMA_GATEWAY_URL=https://dbrs.space make test-e2e-prod"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
@echo "Running E2E tests (including production-only) against $$ORAMA_GATEWAY_URL..."
|
||||||
|
go test -v -tags "e2e production" -timeout 30m ./e2e/...
|
||||||
|
|
||||||
|
# Generic e2e target
|
||||||
|
test-e2e:
|
||||||
|
@echo "Running comprehensive E2E tests..."
|
||||||
|
@echo "Auto-discovering configuration from ~/.orama..."
|
||||||
|
go test -v -tags e2e -timeout 30m ./e2e/...
|
||||||
|
|
||||||
|
test-e2e-deployments:
|
||||||
|
@echo "Running deployment E2E tests..."
|
||||||
|
go test -v -tags e2e -timeout 15m ./e2e/deployments/...
|
||||||
|
|
||||||
|
test-e2e-fullstack:
|
||||||
|
@echo "Running fullstack E2E tests..."
|
||||||
|
go test -v -tags e2e -timeout 20m -run "TestFullStack" ./e2e/...
|
||||||
|
|
||||||
|
test-e2e-https:
|
||||||
|
@echo "Running HTTPS/external access E2E tests..."
|
||||||
|
go test -v -tags e2e -timeout 10m -run "TestHTTPS" ./e2e/...
|
||||||
|
|
||||||
|
test-e2e-shared:
|
||||||
|
@echo "Running shared E2E tests..."
|
||||||
|
go test -v -tags e2e -timeout 10m ./e2e/shared/...
|
||||||
|
|
||||||
|
test-e2e-cluster:
|
||||||
|
@echo "Running cluster E2E tests..."
|
||||||
|
go test -v -tags e2e -timeout 15m ./e2e/cluster/...
|
||||||
|
|
||||||
|
test-e2e-integration:
|
||||||
|
@echo "Running integration E2E tests..."
|
||||||
|
go test -v -tags e2e -timeout 20m ./e2e/integration/...
|
||||||
|
|
||||||
|
test-e2e-production:
|
||||||
|
@echo "Running production-only E2E tests..."
|
||||||
|
go test -v -tags "e2e production" -timeout 15m ./e2e/production/...
|
||||||
|
|
||||||
|
test-e2e-quick:
|
||||||
|
@echo "Running quick E2E smoke tests..."
|
||||||
|
go test -v -tags e2e -timeout 5m -run "TestStatic|TestHealth" ./e2e/...
|
||||||
|
|
||||||
|
# Network - Distributed P2P Database System
|
||||||
|
# Makefile for development and build tasks
|
||||||
|
|
||||||
|
.PHONY: build clean test deps tidy fmt vet lint install-hooks push-devnet push-testnet rollout-devnet rollout-testnet release
|
||||||
|
|
||||||
|
VERSION := 0.120.0
|
||||||
|
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||||
|
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||||
|
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
|
||||||
|
LDFLAGS_LINUX := -s -w $(LDFLAGS)
|
||||||
|
|
||||||
|
# Build targets
|
||||||
|
build: deps
|
||||||
|
@echo "Building network executables (version=$(VERSION))..."
|
||||||
|
@mkdir -p bin
|
||||||
|
go build -ldflags "$(LDFLAGS)" -o bin/identity ./cmd/identity
|
||||||
|
go build -ldflags "$(LDFLAGS)" -o bin/orama-node ./cmd/node
|
||||||
|
go build -ldflags "$(LDFLAGS)" -o bin/orama ./cmd/cli/
|
||||||
|
# Inject gateway build metadata via pkg path variables
|
||||||
|
go build -ldflags "$(LDFLAGS) -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildVersion=$(VERSION)' -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildCommit=$(COMMIT)' -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildTime=$(DATE)'" -o bin/gateway ./cmd/gateway
|
||||||
|
go build -ldflags "$(LDFLAGS)" -o bin/sfu ./cmd/sfu
|
||||||
|
go build -ldflags "$(LDFLAGS)" -o bin/turn ./cmd/turn
|
||||||
|
@echo "Build complete! Run ./bin/orama version"
|
||||||
|
|
||||||
|
# Cross-compile CLI for Linux (only binary needed locally; VPS builds everything else from source)
|
||||||
|
build-linux: deps
|
||||||
|
@echo "Cross-compiling CLI for linux/amd64 (version=$(VERSION))..."
|
||||||
|
@mkdir -p bin-linux
|
||||||
|
GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS_LINUX)" -trimpath -o bin-linux/orama ./cmd/cli/
|
||||||
|
@echo "✓ CLI built at bin-linux/orama"
|
||||||
|
@echo ""
|
||||||
|
@echo "Prefer 'make build-archive' for full pre-built binary archive."
|
||||||
|
|
||||||
|
# Build pre-compiled binary archive for deployment (all binaries + deps)
|
||||||
|
build-archive: deps
|
||||||
|
@echo "Building binary archive (version=$(VERSION))..."
|
||||||
|
go build -ldflags "$(LDFLAGS)" -o bin/orama ./cmd/cli/
|
||||||
|
./bin/orama build --output /tmp/orama-$(VERSION)-linux-amd64.tar.gz
|
||||||
|
|
||||||
|
# Install git hooks
|
||||||
|
install-hooks:
|
||||||
|
@echo "Installing git hooks..."
|
||||||
|
@bash scripts/install-hooks.sh
|
||||||
|
|
||||||
|
# Install orama CLI to ~/.local/bin and configure PATH
|
||||||
|
install: build
|
||||||
|
@bash scripts/install.sh
|
||||||
|
|
||||||
|
# Clean build artifacts
|
||||||
|
clean:
|
||||||
|
@echo "Cleaning build artifacts..."
|
||||||
|
rm -rf bin/
|
||||||
|
rm -rf data/
|
||||||
|
@echo "Clean complete!"
|
||||||
|
|
||||||
|
# Push binary archive to devnet nodes (fanout distribution)
|
||||||
|
push-devnet:
|
||||||
|
./bin/orama node push --env devnet
|
||||||
|
|
||||||
|
# Push binary archive to testnet nodes (fanout distribution)
|
||||||
|
push-testnet:
|
||||||
|
./bin/orama node push --env testnet
|
||||||
|
|
||||||
|
# Full rollout to devnet (build + push + rolling upgrade)
|
||||||
|
rollout-devnet:
|
||||||
|
./bin/orama node rollout --env devnet --yes
|
||||||
|
|
||||||
|
# Full rollout to testnet (build + push + rolling upgrade)
|
||||||
|
rollout-testnet:
|
||||||
|
./bin/orama node rollout --env testnet --yes
|
||||||
|
|
||||||
|
# Interactive release workflow (tag + push)
|
||||||
|
release:
|
||||||
|
@bash scripts/release.sh
|
||||||
|
|
||||||
|
# Check health of all nodes in an environment
|
||||||
|
# Usage: make health ENV=devnet
|
||||||
|
health:
|
||||||
|
@if [ -z "$(ENV)" ]; then \
|
||||||
|
echo "Usage: make health ENV=devnet|testnet"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
./bin/orama monitor report --env $(ENV)
|
||||||
|
|
||||||
|
# Help
|
||||||
|
help:
|
||||||
|
@echo "Available targets:"
|
||||||
|
@echo " build - Build all executables"
|
||||||
|
@echo " install - Build and install 'orama' CLI to ~/.local/bin"
|
||||||
|
@echo " clean - Clean build artifacts"
|
||||||
|
@echo " test - Run unit tests"
|
||||||
|
@echo ""
|
||||||
|
@echo "E2E Testing:"
|
||||||
|
@echo " make test-e2e-prod - Run all E2E tests incl. production-only (needs ORAMA_GATEWAY_URL)"
|
||||||
|
@echo " make test-e2e-shared - Run shared E2E tests (cache, storage, pubsub, auth)"
|
||||||
|
@echo " make test-e2e-cluster - Run cluster E2E tests (libp2p, olric, rqlite, namespace)"
|
||||||
|
@echo " make test-e2e-integration - Run integration E2E tests (fullstack, persistence, concurrency)"
|
||||||
|
@echo " make test-e2e-deployments - Run deployment E2E tests"
|
||||||
|
@echo " make test-e2e-production - Run production-only E2E tests (DNS, HTTPS, cross-node)"
|
||||||
|
@echo " make test-e2e-quick - Quick smoke tests (static deploys, health checks)"
|
||||||
|
@echo " make test-e2e - Generic E2E tests (auto-discovers config)"
|
||||||
|
@echo ""
|
||||||
|
@echo " Example:"
|
||||||
|
@echo " ORAMA_GATEWAY_URL=https://orama-devnet.network make test-e2e-prod"
|
||||||
|
@echo ""
|
||||||
|
@echo "Deployment:"
|
||||||
|
@echo " make build-archive - Build pre-compiled binary archive for deployment"
|
||||||
|
@echo " make push-devnet - Push binary archive to devnet nodes"
|
||||||
|
@echo " make push-testnet - Push binary archive to testnet nodes"
|
||||||
|
@echo " make rollout-devnet - Full rollout: build + push + rolling upgrade (devnet)"
|
||||||
|
@echo " make rollout-testnet - Full rollout: build + push + rolling upgrade (testnet)"
|
||||||
|
@echo " make health ENV=devnet - Check health of all nodes in an environment"
|
||||||
|
@echo " make release - Interactive release workflow (tag + push)"
|
||||||
|
@echo ""
|
||||||
|
@echo "Maintenance:"
|
||||||
|
@echo " deps - Download dependencies"
|
||||||
|
@echo " tidy - Tidy dependencies"
|
||||||
|
@echo " fmt - Format code"
|
||||||
|
@echo " vet - Vet code"
|
||||||
|
@echo " lint - Lint code (fmt + vet)"
|
||||||
|
@echo " help - Show this help"
|
||||||
5
core/cmd/cli/main.go
Normal file
5
core/cmd/cli/main.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
runCLI()
|
||||||
|
}
|
||||||
103
core/cmd/cli/root.go
Normal file
103
core/cmd/cli/root.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
// Command groups
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/app"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/authcmd"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/buildcmd"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/dbcmd"
|
||||||
|
deploycmd "github.com/DeBrosOfficial/network/pkg/cli/cmd/deploy"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/envcmd"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/functioncmd"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/inspectcmd"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/monitorcmd"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/namespacecmd"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/node"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/cli/cmd/sandboxcmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
// version metadata populated via -ldflags at build time
|
||||||
|
// Must match Makefile: -X 'main.version=...' -X 'main.commit=...' -X 'main.date=...'
|
||||||
|
var (
|
||||||
|
version = "dev"
|
||||||
|
commit = ""
|
||||||
|
date = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
func newRootCmd() *cobra.Command {
|
||||||
|
rootCmd := &cobra.Command{
|
||||||
|
Use: "orama",
|
||||||
|
Short: "Orama CLI - Distributed P2P Network Management Tool",
|
||||||
|
Long: `Orama CLI is a tool for managing nodes, deploying applications,
|
||||||
|
and interacting with the Orama distributed network.`,
|
||||||
|
SilenceUsage: true,
|
||||||
|
SilenceErrors: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version command
|
||||||
|
rootCmd.AddCommand(&cobra.Command{
|
||||||
|
Use: "version",
|
||||||
|
Short: "Show version information",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
fmt.Printf("orama %s", version)
|
||||||
|
if commit != "" {
|
||||||
|
fmt.Printf(" (commit %s)", commit)
|
||||||
|
}
|
||||||
|
if date != "" {
|
||||||
|
fmt.Printf(" built %s", date)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Node operator commands (was "prod")
|
||||||
|
rootCmd.AddCommand(node.Cmd)
|
||||||
|
|
||||||
|
// Deploy command (top-level, upsert)
|
||||||
|
rootCmd.AddCommand(deploycmd.Cmd)
|
||||||
|
|
||||||
|
// App management (was "deployments")
|
||||||
|
rootCmd.AddCommand(app.Cmd)
|
||||||
|
|
||||||
|
// Database commands
|
||||||
|
rootCmd.AddCommand(dbcmd.Cmd)
|
||||||
|
|
||||||
|
// Namespace commands
|
||||||
|
rootCmd.AddCommand(namespacecmd.Cmd)
|
||||||
|
|
||||||
|
// Environment commands
|
||||||
|
rootCmd.AddCommand(envcmd.Cmd)
|
||||||
|
|
||||||
|
// Auth commands
|
||||||
|
rootCmd.AddCommand(authcmd.Cmd)
|
||||||
|
|
||||||
|
// Inspect command
|
||||||
|
rootCmd.AddCommand(inspectcmd.Cmd)
|
||||||
|
|
||||||
|
// Monitor command
|
||||||
|
rootCmd.AddCommand(monitorcmd.Cmd)
|
||||||
|
|
||||||
|
// Serverless function commands
|
||||||
|
rootCmd.AddCommand(functioncmd.Cmd)
|
||||||
|
|
||||||
|
// Build command (cross-compile binary archive)
|
||||||
|
rootCmd.AddCommand(buildcmd.Cmd)
|
||||||
|
|
||||||
|
// Sandbox command (ephemeral Hetzner Cloud clusters)
|
||||||
|
rootCmd.AddCommand(sandboxcmd.Cmd)
|
||||||
|
|
||||||
|
return rootCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCLI() {
|
||||||
|
rootCmd := newRootCmd()
|
||||||
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -69,6 +69,13 @@ func parseGatewayConfig(logger *logging.ColoredLogger) *gateway.Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load YAML
|
// Load YAML
|
||||||
|
type yamlWebRTCCfg struct {
|
||||||
|
Enabled bool `yaml:"enabled"`
|
||||||
|
SFUPort int `yaml:"sfu_port"`
|
||||||
|
TURNDomain string `yaml:"turn_domain"`
|
||||||
|
TURNSecret string `yaml:"turn_secret"`
|
||||||
|
}
|
||||||
|
|
||||||
type yamlCfg struct {
|
type yamlCfg struct {
|
||||||
ListenAddr string `yaml:"listen_addr"`
|
ListenAddr string `yaml:"listen_addr"`
|
||||||
ClientNamespace string `yaml:"client_namespace"`
|
ClientNamespace string `yaml:"client_namespace"`
|
||||||
@ -84,6 +91,7 @@ func parseGatewayConfig(logger *logging.ColoredLogger) *gateway.Config {
|
|||||||
IPFSAPIURL string `yaml:"ipfs_api_url"`
|
IPFSAPIURL string `yaml:"ipfs_api_url"`
|
||||||
IPFSTimeout string `yaml:"ipfs_timeout"`
|
IPFSTimeout string `yaml:"ipfs_timeout"`
|
||||||
IPFSReplicationFactor int `yaml:"ipfs_replication_factor"`
|
IPFSReplicationFactor int `yaml:"ipfs_replication_factor"`
|
||||||
|
WebRTC yamlWebRTCCfg `yaml:"webrtc"`
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := os.ReadFile(configPath)
|
data, err := os.ReadFile(configPath)
|
||||||
@ -192,6 +200,18 @@ func parseGatewayConfig(logger *logging.ColoredLogger) *gateway.Config {
|
|||||||
cfg.IPFSReplicationFactor = y.IPFSReplicationFactor
|
cfg.IPFSReplicationFactor = y.IPFSReplicationFactor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WebRTC configuration
|
||||||
|
cfg.WebRTCEnabled = y.WebRTC.Enabled
|
||||||
|
if y.WebRTC.SFUPort > 0 {
|
||||||
|
cfg.SFUPort = y.WebRTC.SFUPort
|
||||||
|
}
|
||||||
|
if v := strings.TrimSpace(y.WebRTC.TURNDomain); v != "" {
|
||||||
|
cfg.TURNDomain = v
|
||||||
|
}
|
||||||
|
if v := strings.TrimSpace(y.WebRTC.TURNSecret); v != "" {
|
||||||
|
cfg.TURNSecret = v
|
||||||
|
}
|
||||||
|
|
||||||
// Validate configuration
|
// Validate configuration
|
||||||
if errs := cfg.ValidateConfig(); len(errs) > 0 {
|
if errs := cfg.ValidateConfig(); len(errs) > 0 {
|
||||||
fmt.Fprintf(os.Stderr, "\nGateway configuration errors (%d):\n", len(errs))
|
fmt.Fprintf(os.Stderr, "\nGateway configuration errors (%d):\n", len(errs))
|
||||||
@ -66,15 +66,25 @@ func main() {
|
|||||||
|
|
||||||
// Create HTTP server for ACME challenge (port 80)
|
// Create HTTP server for ACME challenge (port 80)
|
||||||
httpServer := &http.Server{
|
httpServer := &http.Server{
|
||||||
Addr: ":80",
|
Addr: ":80",
|
||||||
Handler: manager.HTTPHandler(nil), // Redirects all HTTP traffic to HTTPS except ACME challenge
|
Handler: manager.HTTPHandler(nil), // Redirects all HTTP traffic to HTTPS except ACME challenge
|
||||||
|
ReadHeaderTimeout: 10 * time.Second,
|
||||||
|
ReadTimeout: 60 * time.Second,
|
||||||
|
WriteTimeout: 120 * time.Second,
|
||||||
|
IdleTimeout: 120 * time.Second,
|
||||||
|
MaxHeaderBytes: 1 << 20, // 1MB
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create HTTPS server (port 443)
|
// Create HTTPS server (port 443)
|
||||||
httpsServer := &http.Server{
|
httpsServer := &http.Server{
|
||||||
Addr: ":443",
|
Addr: ":443",
|
||||||
Handler: gw.Routes(),
|
Handler: gw.Routes(),
|
||||||
TLSConfig: manager.TLSConfig(),
|
TLSConfig: manager.TLSConfig(),
|
||||||
|
ReadHeaderTimeout: 10 * time.Second,
|
||||||
|
ReadTimeout: 60 * time.Second,
|
||||||
|
WriteTimeout: 120 * time.Second,
|
||||||
|
IdleTimeout: 120 * time.Second,
|
||||||
|
MaxHeaderBytes: 1 << 20, // 1MB
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start HTTP server for ACME challenge
|
// Start HTTP server for ACME challenge
|
||||||
@ -161,8 +171,13 @@ func main() {
|
|||||||
|
|
||||||
// Standard HTTP server (no HTTPS)
|
// Standard HTTP server (no HTTPS)
|
||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
Addr: cfg.ListenAddr,
|
Addr: cfg.ListenAddr,
|
||||||
Handler: gw.Routes(),
|
Handler: gw.Routes(),
|
||||||
|
ReadHeaderTimeout: 10 * time.Second,
|
||||||
|
ReadTimeout: 60 * time.Second,
|
||||||
|
WriteTimeout: 120 * time.Second,
|
||||||
|
IdleTimeout: 120 * time.Second,
|
||||||
|
MaxHeaderBytes: 1 << 20, // 1MB
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to bind listener explicitly so binding failures are visible immediately.
|
// Try to bind listener explicitly so binding failures are visible immediately.
|
||||||
118
core/cmd/sfu/config.go
Normal file
118
core/cmd/sfu/config.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/config"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/logging"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/sfu"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newSFUServer creates a new SFU server from config and logger.
|
||||||
|
// Wrapper to keep main.go clean and avoid importing sfu in main.
|
||||||
|
func newSFUServer(cfg *sfu.Config, logger *zap.Logger) (*sfu.Server, error) {
|
||||||
|
return sfu.NewServer(cfg, logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseSFUConfig(logger *logging.ColoredLogger) *sfu.Config {
|
||||||
|
configFlag := flag.String("config", "", "Config file path (absolute path or filename in ~/.orama)")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var configPath string
|
||||||
|
var err error
|
||||||
|
if *configFlag != "" {
|
||||||
|
if filepath.IsAbs(*configFlag) {
|
||||||
|
configPath = *configFlag
|
||||||
|
} else {
|
||||||
|
configPath, err = config.DefaultPath(*configFlag)
|
||||||
|
if err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentSFU, "Failed to determine config path", zap.Error(err))
|
||||||
|
fmt.Fprintf(os.Stderr, "Configuration error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
configPath, err = config.DefaultPath("sfu.yaml")
|
||||||
|
if err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentSFU, "Failed to determine config path", zap.Error(err))
|
||||||
|
fmt.Fprintf(os.Stderr, "Configuration error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type yamlTURNServer struct {
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
Port int `yaml:"port"`
|
||||||
|
Secure bool `yaml:"secure"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type yamlCfg struct {
|
||||||
|
ListenAddr string `yaml:"listen_addr"`
|
||||||
|
Namespace string `yaml:"namespace"`
|
||||||
|
MediaPortStart int `yaml:"media_port_start"`
|
||||||
|
MediaPortEnd int `yaml:"media_port_end"`
|
||||||
|
TURNServers []yamlTURNServer `yaml:"turn_servers"`
|
||||||
|
TURNSecret string `yaml:"turn_secret"`
|
||||||
|
TURNCredentialTTL int `yaml:"turn_credential_ttl"`
|
||||||
|
RQLiteDSN string `yaml:"rqlite_dsn"`
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(configPath)
|
||||||
|
if err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentSFU, "Config file not found",
|
||||||
|
zap.String("path", configPath), zap.Error(err))
|
||||||
|
fmt.Fprintf(os.Stderr, "\nConfig file not found at %s\n", configPath)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var y yamlCfg
|
||||||
|
if err := config.DecodeStrict(strings.NewReader(string(data)), &y); err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentSFU, "Failed to parse SFU config", zap.Error(err))
|
||||||
|
fmt.Fprintf(os.Stderr, "Configuration parse error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var turnServers []sfu.TURNServerConfig
|
||||||
|
for _, ts := range y.TURNServers {
|
||||||
|
turnServers = append(turnServers, sfu.TURNServerConfig{
|
||||||
|
Host: ts.Host,
|
||||||
|
Port: ts.Port,
|
||||||
|
Secure: ts.Secure,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &sfu.Config{
|
||||||
|
ListenAddr: y.ListenAddr,
|
||||||
|
Namespace: y.Namespace,
|
||||||
|
MediaPortStart: y.MediaPortStart,
|
||||||
|
MediaPortEnd: y.MediaPortEnd,
|
||||||
|
TURNServers: turnServers,
|
||||||
|
TURNSecret: y.TURNSecret,
|
||||||
|
TURNCredentialTTL: y.TURNCredentialTTL,
|
||||||
|
RQLiteDSN: y.RQLiteDSN,
|
||||||
|
}
|
||||||
|
|
||||||
|
if errs := cfg.Validate(); len(errs) > 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, "\nSFU configuration errors (%d):\n", len(errs))
|
||||||
|
for _, e := range errs {
|
||||||
|
fmt.Fprintf(os.Stderr, " - %s\n", e)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(os.Stderr, "\nPlease fix the configuration and try again.\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.ComponentInfo(logging.ComponentSFU, "Loaded SFU configuration",
|
||||||
|
zap.String("path", configPath),
|
||||||
|
zap.String("listen_addr", cfg.ListenAddr),
|
||||||
|
zap.String("namespace", cfg.Namespace),
|
||||||
|
zap.Int("media_ports", cfg.MediaPortEnd-cfg.MediaPortStart),
|
||||||
|
zap.Int("turn_servers", len(cfg.TURNServers)),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
61
core/cmd/sfu/main.go
Normal file
61
core/cmd/sfu/main.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/logging"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
version = "dev"
|
||||||
|
commit = "unknown"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
logger, err := logging.NewColoredLogger(logging.ComponentSFU, true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.ComponentInfo(logging.ComponentSFU, "Starting SFU server",
|
||||||
|
zap.String("version", version),
|
||||||
|
zap.String("commit", commit))
|
||||||
|
|
||||||
|
cfg := parseSFUConfig(logger)
|
||||||
|
|
||||||
|
server, err := newSFUServer(cfg, logger.Logger)
|
||||||
|
if err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentSFU, "Failed to create SFU server", zap.Error(err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start HTTP server in background
|
||||||
|
go func() {
|
||||||
|
if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||||
|
logger.ComponentError(logging.ComponentSFU, "SFU server error", zap.Error(err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Wait for termination signal
|
||||||
|
quit := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
|
||||||
|
sig := <-quit
|
||||||
|
|
||||||
|
logger.ComponentInfo(logging.ComponentSFU, "Shutdown signal received", zap.String("signal", sig.String()))
|
||||||
|
|
||||||
|
// Graceful drain: notify peers and wait
|
||||||
|
server.Drain(30 * time.Second)
|
||||||
|
|
||||||
|
if err := server.Close(); err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentSFU, "Error during shutdown", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.ComponentInfo(logging.ComponentSFU, "SFU server shutdown complete")
|
||||||
|
}
|
||||||
100
core/cmd/turn/config.go
Normal file
100
core/cmd/turn/config.go
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/config"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/logging"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/turn"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseTURNConfig(logger *logging.ColoredLogger) *turn.Config {
|
||||||
|
configFlag := flag.String("config", "", "Config file path (absolute path or filename in ~/.orama)")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var configPath string
|
||||||
|
var err error
|
||||||
|
if *configFlag != "" {
|
||||||
|
if filepath.IsAbs(*configFlag) {
|
||||||
|
configPath = *configFlag
|
||||||
|
} else {
|
||||||
|
configPath, err = config.DefaultPath(*configFlag)
|
||||||
|
if err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentTURN, "Failed to determine config path", zap.Error(err))
|
||||||
|
fmt.Fprintf(os.Stderr, "Configuration error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
configPath, err = config.DefaultPath("turn.yaml")
|
||||||
|
if err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentTURN, "Failed to determine config path", zap.Error(err))
|
||||||
|
fmt.Fprintf(os.Stderr, "Configuration error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type yamlCfg struct {
|
||||||
|
ListenAddr string `yaml:"listen_addr"`
|
||||||
|
TURNSListenAddr string `yaml:"turns_listen_addr"`
|
||||||
|
PublicIP string `yaml:"public_ip"`
|
||||||
|
Realm string `yaml:"realm"`
|
||||||
|
AuthSecret string `yaml:"auth_secret"`
|
||||||
|
RelayPortStart int `yaml:"relay_port_start"`
|
||||||
|
RelayPortEnd int `yaml:"relay_port_end"`
|
||||||
|
Namespace string `yaml:"namespace"`
|
||||||
|
TLSCertPath string `yaml:"tls_cert_path"`
|
||||||
|
TLSKeyPath string `yaml:"tls_key_path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(configPath)
|
||||||
|
if err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentTURN, "Config file not found",
|
||||||
|
zap.String("path", configPath), zap.Error(err))
|
||||||
|
fmt.Fprintf(os.Stderr, "\nConfig file not found at %s\n", configPath)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var y yamlCfg
|
||||||
|
if err := config.DecodeStrict(strings.NewReader(string(data)), &y); err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentTURN, "Failed to parse TURN config", zap.Error(err))
|
||||||
|
fmt.Fprintf(os.Stderr, "Configuration parse error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &turn.Config{
|
||||||
|
ListenAddr: y.ListenAddr,
|
||||||
|
TURNSListenAddr: y.TURNSListenAddr,
|
||||||
|
PublicIP: y.PublicIP,
|
||||||
|
Realm: y.Realm,
|
||||||
|
AuthSecret: y.AuthSecret,
|
||||||
|
RelayPortStart: y.RelayPortStart,
|
||||||
|
RelayPortEnd: y.RelayPortEnd,
|
||||||
|
Namespace: y.Namespace,
|
||||||
|
TLSCertPath: y.TLSCertPath,
|
||||||
|
TLSKeyPath: y.TLSKeyPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
if errs := cfg.Validate(); len(errs) > 0 {
|
||||||
|
fmt.Fprintf(os.Stderr, "\nTURN configuration errors (%d):\n", len(errs))
|
||||||
|
for _, e := range errs {
|
||||||
|
fmt.Fprintf(os.Stderr, " - %s\n", e)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(os.Stderr, "\nPlease fix the configuration and try again.\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.ComponentInfo(logging.ComponentTURN, "Loaded TURN configuration",
|
||||||
|
zap.String("path", configPath),
|
||||||
|
zap.String("listen_addr", cfg.ListenAddr),
|
||||||
|
zap.String("namespace", cfg.Namespace),
|
||||||
|
zap.String("realm", cfg.Realm),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
48
core/cmd/turn/main.go
Normal file
48
core/cmd/turn/main.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/logging"
|
||||||
|
"github.com/DeBrosOfficial/network/pkg/turn"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
version = "dev"
|
||||||
|
commit = "unknown"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
logger, err := logging.NewColoredLogger(logging.ComponentTURN, true)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.ComponentInfo(logging.ComponentTURN, "Starting TURN server",
|
||||||
|
zap.String("version", version),
|
||||||
|
zap.String("commit", commit))
|
||||||
|
|
||||||
|
cfg := parseTURNConfig(logger)
|
||||||
|
|
||||||
|
server, err := turn.NewServer(cfg, logger.Logger)
|
||||||
|
if err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentTURN, "Failed to start TURN server", zap.Error(err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for termination signal
|
||||||
|
quit := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
|
||||||
|
sig := <-quit
|
||||||
|
|
||||||
|
logger.ComponentInfo(logging.ComponentTURN, "Shutdown signal received", zap.String("signal", sig.String()))
|
||||||
|
|
||||||
|
if err := server.Close(); err != nil {
|
||||||
|
logger.ComponentError(logging.ComponentTURN, "Error during shutdown", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.ComponentInfo(logging.ComponentTURN, "TURN server shutdown complete")
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@ Section: net
|
|||||||
Priority: optional
|
Priority: optional
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: libc6
|
Depends: libc6
|
||||||
Maintainer: DeBros Team <dev@debros.io>
|
Maintainer: DeBros Team <dev@orama.io>
|
||||||
Description: Orama Network - Distributed P2P Database System
|
Description: Orama Network - Distributed P2P Database System
|
||||||
Orama is a distributed peer-to-peer network that combines
|
Orama is a distributed peer-to-peer network that combines
|
||||||
RQLite for distributed SQL, IPFS for content-addressed storage,
|
RQLite for distributed SQL, IPFS for content-addressed storage,
|
||||||
@ -357,11 +357,36 @@ Function Invocation:
|
|||||||
|
|
||||||
All inter-node communication is encrypted via a WireGuard VPN mesh:
|
All inter-node communication is encrypted via a WireGuard VPN mesh:
|
||||||
|
|
||||||
- **WireGuard IPs:** Each node gets a private IP (10.0.0.x) used for all cluster traffic
|
- **WireGuard IPs:** Each node gets a private IP (10.0.0.x/24) used for all cluster traffic
|
||||||
- **UFW Firewall:** Only public ports are exposed: 22 (SSH), 53 (DNS, nameservers only), 80/443 (HTTP/HTTPS), 51820 (WireGuard UDP)
|
- **UFW Firewall:** Only public ports are exposed: 22 (SSH), 53 (DNS, nameservers only), 80/443 (HTTP/HTTPS), 51820 (WireGuard UDP)
|
||||||
|
- **IPv6 disabled:** System-wide via sysctl to prevent bypass of IPv4 firewall rules
|
||||||
- **Internal services** (RQLite 5001/7001, IPFS 4001/4501, Olric 3320/3322, Gateway 6001) are only accessible via WireGuard or localhost
|
- **Internal services** (RQLite 5001/7001, IPFS 4001/4501, Olric 3320/3322, Gateway 6001) are only accessible via WireGuard or localhost
|
||||||
- **Invite tokens:** Single-use, time-limited tokens for secure node joining. No shared secrets on the CLI
|
- **Invite tokens:** Single-use, time-limited tokens for secure node joining. No shared secrets on the CLI
|
||||||
- **Join flow:** New nodes authenticate via HTTPS (443), establish WireGuard tunnel, then join all services over the encrypted mesh
|
- **Join flow:** New nodes authenticate via HTTPS (443) with TOFU certificate pinning, establish WireGuard tunnel, then join all services over the encrypted mesh
|
||||||
|
|
||||||
|
### Service Authentication
|
||||||
|
|
||||||
|
- **RQLite:** HTTP basic auth on all queries/executions — credentials generated at genesis, distributed via join response
|
||||||
|
- **Olric:** Memberlist gossip encrypted with a shared 32-byte key
|
||||||
|
- **IPFS Cluster:** TrustedPeers restricted to known cluster peer IDs (not `*`)
|
||||||
|
- **Internal endpoints:** `/v1/internal/wg/peers` and `/v1/internal/wg/peer/remove` require cluster secret
|
||||||
|
- **Vault:** V1 push/pull endpoints require session token authentication when guardian is configured
|
||||||
|
- **WebSockets:** Origin header validated against the node's configured domain
|
||||||
|
|
||||||
|
### Token & Key Security
|
||||||
|
|
||||||
|
- **Refresh tokens:** Stored as SHA-256 hashes (never plaintext)
|
||||||
|
- **API keys:** Stored as HMAC-SHA256 hashes with a server-side secret
|
||||||
|
- **TURN secrets:** Encrypted at rest with AES-256-GCM (key derived from cluster secret)
|
||||||
|
- **Binary signing:** Build archives signed with rootwallet EVM signature, verified on install
|
||||||
|
|
||||||
|
### Process Isolation
|
||||||
|
|
||||||
|
- **Dedicated user:** All services run as `orama` user (not root)
|
||||||
|
- **systemd hardening:** `ProtectSystem=strict`, `NoNewPrivileges=yes`, `PrivateDevices=yes`, etc.
|
||||||
|
- **Capabilities:** Caddy and CoreDNS get `CAP_NET_BIND_SERVICE` for privileged ports
|
||||||
|
|
||||||
|
See [SECURITY.md](SECURITY.md) for the full security hardening reference.
|
||||||
|
|
||||||
### TLS/HTTPS
|
### TLS/HTTPS
|
||||||
|
|
||||||
@ -439,11 +464,10 @@ All inter-node communication is encrypted via a WireGuard VPN mesh:
|
|||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
### Development
|
### Building & Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make dev # Start 5-node cluster
|
make build # Build all binaries
|
||||||
make stop # Stop all services
|
|
||||||
make test # Run unit tests
|
make test # Run unit tests
|
||||||
make test-e2e # Run E2E tests
|
make test-e2e # Run E2E tests
|
||||||
```
|
```
|
||||||
@ -475,6 +499,61 @@ configured, use the IP over HTTP port 80 (`http://<ip>`) which goes through Cadd
|
|||||||
|
|
||||||
Planned containerization with Docker Compose and Kubernetes support.
|
Planned containerization with Docker Compose and Kubernetes support.
|
||||||
|
|
||||||
|
## WebRTC (Voice/Video/Data)
|
||||||
|
|
||||||
|
Namespaces can opt in to WebRTC support for real-time voice, video, and data channels.
|
||||||
|
|
||||||
|
### Components
|
||||||
|
|
||||||
|
- **SFU (Selective Forwarding Unit)** — Pion WebRTC server that handles signaling (WebSocket), SDP negotiation, and RTP forwarding. Runs on all 3 cluster nodes, binds only to WireGuard IPs.
|
||||||
|
- **TURN Server** — Pion TURN relay that provides NAT traversal. Runs on 2 of 3 nodes for redundancy. Public-facing (UDP 3478, 443, relay range 49152-65535).
|
||||||
|
|
||||||
|
### Security Model
|
||||||
|
|
||||||
|
- **TURN-shielded**: SFU binds only to WireGuard (10.0.0.x), never 0.0.0.0. All client media flows through TURN relay.
|
||||||
|
- **Forced relay**: `iceTransportPolicy: relay` enforced server-side — no direct peer connections.
|
||||||
|
- **HMAC credentials**: Per-namespace TURN shared secret with 10-minute TTL.
|
||||||
|
- **Namespace isolation**: Each namespace has its own TURN secret, port ranges, and rooms.
|
||||||
|
|
||||||
|
### Port Allocation
|
||||||
|
|
||||||
|
WebRTC uses a separate port allocation system from core namespace services:
|
||||||
|
|
||||||
|
| Service | Port Range |
|
||||||
|
|---------|-----------|
|
||||||
|
| SFU signaling | 30000-30099 |
|
||||||
|
| SFU media (RTP) | 20000-29999 |
|
||||||
|
| TURN listen | 3478/udp (standard) |
|
||||||
|
| TURN TLS | 443/udp |
|
||||||
|
| TURN relay | 49152-65535/udp |
|
||||||
|
|
||||||
|
See [docs/WEBRTC.md](WEBRTC.md) for full details including client integration, API reference, and debugging.
|
||||||
|
|
||||||
|
## OramaOS
|
||||||
|
|
||||||
|
For mainnet, devnet, and testnet environments, nodes run **OramaOS** — a custom minimal Linux image built with Buildroot.
|
||||||
|
|
||||||
|
**Key properties:**
|
||||||
|
- No SSH, no shell — operators cannot access the filesystem
|
||||||
|
- LUKS full-disk encryption with Shamir key distribution across peers
|
||||||
|
- Read-only rootfs (SquashFS + dm-verity)
|
||||||
|
- A/B partition updates with cryptographic signature verification
|
||||||
|
- Service sandboxing via Linux namespaces + seccomp
|
||||||
|
- Single root process: the **orama-agent**
|
||||||
|
|
||||||
|
**The orama-agent manages:**
|
||||||
|
- Boot sequence and LUKS key reconstruction
|
||||||
|
- WireGuard tunnel setup
|
||||||
|
- Service lifecycle in sandboxed namespaces
|
||||||
|
- Command reception from Gateway over WireGuard (port 9998)
|
||||||
|
- OS updates (download, verify, A/B swap, reboot with rollback)
|
||||||
|
|
||||||
|
**Node enrollment:** OramaOS nodes join via `orama node enroll` instead of `orama node install`. The enrollment flow uses a registration code + invite token + wallet verification.
|
||||||
|
|
||||||
|
See [ORAMAOS_DEPLOYMENT.md](ORAMAOS_DEPLOYMENT.md) for the full deployment guide.
|
||||||
|
|
||||||
|
Sandbox clusters remain on Ubuntu for development convenience.
|
||||||
|
|
||||||
## Future Enhancements
|
## Future Enhancements
|
||||||
|
|
||||||
1. **GraphQL Support** - GraphQL gateway alongside REST
|
1. **GraphQL Support** - GraphQL gateway alongside REST
|
||||||
@ -2,17 +2,25 @@
|
|||||||
|
|
||||||
How to completely remove all Orama Network state from a VPS so it can be reinstalled fresh.
|
How to completely remove all Orama Network state from a VPS so it can be reinstalled fresh.
|
||||||
|
|
||||||
|
> **OramaOS nodes:** This guide applies to Ubuntu-based nodes only. OramaOS has no SSH or shell access. To remove an OramaOS node: use `POST /v1/node/leave` via the Gateway API for graceful departure, or reflash the OramaOS image via your VPS provider's dashboard for a factory reset. See [ORAMAOS_DEPLOYMENT.md](ORAMAOS_DEPLOYMENT.md) for details.
|
||||||
|
|
||||||
## Quick Clean (Copy-Paste)
|
## Quick Clean (Copy-Paste)
|
||||||
|
|
||||||
Run this as root or with sudo on the target VPS:
|
Run this as root or with sudo on the target VPS:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Stop and disable all services
|
# 1. Stop and disable all services
|
||||||
sudo systemctl stop debros-node debros-ipfs debros-ipfs-cluster debros-olric debros-anyone-relay debros-anyone-client coredns caddy 2>/dev/null
|
sudo systemctl stop orama-node orama-ipfs orama-ipfs-cluster orama-olric orama-anyone-relay orama-anyone-client coredns caddy 2>/dev/null
|
||||||
sudo systemctl disable debros-node debros-ipfs debros-ipfs-cluster debros-olric debros-anyone-relay debros-anyone-client coredns caddy 2>/dev/null
|
sudo systemctl disable orama-node orama-ipfs orama-ipfs-cluster orama-olric orama-anyone-relay orama-anyone-client coredns caddy 2>/dev/null
|
||||||
|
|
||||||
|
# 1b. Kill leftover processes (binaries may run outside systemd)
|
||||||
|
sudo pkill -f orama-node 2>/dev/null; sudo pkill -f ipfs-cluster-service 2>/dev/null
|
||||||
|
sudo pkill -f "ipfs daemon" 2>/dev/null; sudo pkill -f olric-server 2>/dev/null
|
||||||
|
sudo pkill -f rqlited 2>/dev/null; sudo pkill -f coredns 2>/dev/null
|
||||||
|
sleep 1
|
||||||
|
|
||||||
# 2. Remove systemd service files
|
# 2. Remove systemd service files
|
||||||
sudo rm -f /etc/systemd/system/debros-*.service
|
sudo rm -f /etc/systemd/system/orama-*.service
|
||||||
sudo rm -f /etc/systemd/system/coredns.service
|
sudo rm -f /etc/systemd/system/coredns.service
|
||||||
sudo rm -f /etc/systemd/system/caddy.service
|
sudo rm -f /etc/systemd/system/caddy.service
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
@ -31,14 +39,15 @@ sudo ufw --force reset
|
|||||||
sudo ufw allow 22/tcp
|
sudo ufw allow 22/tcp
|
||||||
sudo ufw --force enable
|
sudo ufw --force enable
|
||||||
|
|
||||||
# 5. Remove debros user and home directory
|
# 5. Remove orama data directory
|
||||||
sudo userdel -r debros 2>/dev/null
|
sudo rm -rf /opt/orama
|
||||||
sudo rm -rf /home/debros
|
|
||||||
|
|
||||||
# 6. Remove sudoers files
|
# 6. Remove legacy orama user (if exists from old installs)
|
||||||
sudo rm -f /etc/sudoers.d/debros-access
|
sudo userdel -r orama 2>/dev/null
|
||||||
sudo rm -f /etc/sudoers.d/debros-deployments
|
sudo rm -rf /home/orama
|
||||||
sudo rm -f /etc/sudoers.d/debros-wireguard
|
sudo rm -f /etc/sudoers.d/orama-access
|
||||||
|
sudo rm -f /etc/sudoers.d/orama-deployments
|
||||||
|
sudo rm -f /etc/sudoers.d/orama-wireguard
|
||||||
|
|
||||||
# 7. Remove CoreDNS config
|
# 7. Remove CoreDNS config
|
||||||
sudo rm -rf /etc/coredns
|
sudo rm -rf /etc/coredns
|
||||||
@ -62,17 +71,16 @@ echo "Node cleaned. Ready for fresh install."
|
|||||||
|
|
||||||
| Category | Paths |
|
| Category | Paths |
|
||||||
|----------|-------|
|
|----------|-------|
|
||||||
| **User** | `debros` system user and `/home/debros/` |
|
| **App data** | `/opt/orama/.orama/` (configs, secrets, logs, IPFS, RQLite, Olric) |
|
||||||
| **App data** | `/home/debros/.orama/` (configs, secrets, logs, IPFS, RQLite, Olric) |
|
| **Source code** | `/opt/orama/src/` |
|
||||||
| **Source code** | `/home/debros/src/` |
|
| **Binaries** | `/opt/orama/bin/orama-node`, `/opt/orama/bin/gateway` |
|
||||||
| **Binaries** | `/home/debros/bin/orama-node`, `/home/debros/bin/gateway` |
|
| **Systemd** | `orama-*.service`, `coredns.service`, `caddy.service`, `orama-deploy-*.service` |
|
||||||
| **Systemd** | `debros-*.service`, `coredns.service`, `caddy.service`, `orama-deploy-*.service` |
|
|
||||||
| **WireGuard** | `/etc/wireguard/wg0.conf`, `wg-quick@wg0` systemd unit |
|
| **WireGuard** | `/etc/wireguard/wg0.conf`, `wg-quick@wg0` systemd unit |
|
||||||
| **Firewall** | All UFW rules (reset to default + SSH only) |
|
| **Firewall** | All UFW rules (reset to default + SSH only) |
|
||||||
| **Sudoers** | `/etc/sudoers.d/debros-*` |
|
| **Legacy** | `orama` user, `/etc/sudoers.d/orama-*` (old installs only) |
|
||||||
| **CoreDNS** | `/etc/coredns/Corefile` |
|
| **CoreDNS** | `/etc/coredns/Corefile` |
|
||||||
| **Caddy** | `/etc/caddy/Caddyfile`, `/var/lib/caddy/` (TLS certs) |
|
| **Caddy** | `/etc/caddy/Caddyfile`, `/var/lib/caddy/` (TLS certs) |
|
||||||
| **Anyone Relay** | `debros-anyone-relay.service`, `debros-anyone-client.service` |
|
| **Anyone Relay** | `orama-anyone-relay.service`, `orama-anyone-client.service` |
|
||||||
| **Temp files** | `/tmp/orama`, `/tmp/network-source.*`, build dirs |
|
| **Temp files** | `/tmp/orama`, `/tmp/network-source.*`, build dirs |
|
||||||
|
|
||||||
## What This Does NOT Remove
|
## What This Does NOT Remove
|
||||||
@ -121,18 +129,19 @@ for entry in "${NODES[@]}"; do
|
|||||||
IFS=: read -r userhost pass <<< "$entry"
|
IFS=: read -r userhost pass <<< "$entry"
|
||||||
echo "Cleaning $userhost..."
|
echo "Cleaning $userhost..."
|
||||||
sshpass -p "$pass" ssh -o StrictHostKeyChecking=no "$userhost" 'bash -s' << 'CLEAN'
|
sshpass -p "$pass" ssh -o StrictHostKeyChecking=no "$userhost" 'bash -s' << 'CLEAN'
|
||||||
sudo systemctl stop debros-node debros-ipfs debros-ipfs-cluster debros-olric debros-anyone-relay debros-anyone-client coredns caddy 2>/dev/null
|
sudo systemctl stop orama-node orama-ipfs orama-ipfs-cluster orama-olric orama-anyone-relay orama-anyone-client coredns caddy 2>/dev/null
|
||||||
sudo systemctl disable debros-node debros-ipfs debros-ipfs-cluster debros-olric debros-anyone-relay debros-anyone-client coredns caddy 2>/dev/null
|
sudo systemctl disable orama-node orama-ipfs orama-ipfs-cluster orama-olric orama-anyone-relay orama-anyone-client coredns caddy 2>/dev/null
|
||||||
sudo rm -f /etc/systemd/system/debros-*.service /etc/systemd/system/coredns.service /etc/systemd/system/caddy.service /etc/systemd/system/orama-deploy-*.service
|
sudo rm -f /etc/systemd/system/orama-*.service /etc/systemd/system/coredns.service /etc/systemd/system/caddy.service /etc/systemd/system/orama-deploy-*.service
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
sudo systemctl stop wg-quick@wg0 2>/dev/null
|
sudo systemctl stop wg-quick@wg0 2>/dev/null
|
||||||
sudo wg-quick down wg0 2>/dev/null
|
sudo wg-quick down wg0 2>/dev/null
|
||||||
sudo systemctl disable wg-quick@wg0 2>/dev/null
|
sudo systemctl disable wg-quick@wg0 2>/dev/null
|
||||||
sudo rm -f /etc/wireguard/wg0.conf
|
sudo rm -f /etc/wireguard/wg0.conf
|
||||||
sudo ufw --force reset && sudo ufw allow 22/tcp && sudo ufw --force enable
|
sudo ufw --force reset && sudo ufw allow 22/tcp && sudo ufw --force enable
|
||||||
sudo userdel -r debros 2>/dev/null
|
sudo rm -rf /opt/orama
|
||||||
sudo rm -rf /home/debros
|
sudo userdel -r orama 2>/dev/null
|
||||||
sudo rm -f /etc/sudoers.d/debros-access /etc/sudoers.d/debros-deployments /etc/sudoers.d/debros-wireguard
|
sudo rm -rf /home/orama
|
||||||
|
sudo rm -f /etc/sudoers.d/orama-access /etc/sudoers.d/orama-deployments /etc/sudoers.d/orama-wireguard
|
||||||
sudo rm -rf /etc/coredns /etc/caddy /var/lib/caddy
|
sudo rm -rf /etc/coredns /etc/caddy /var/lib/caddy
|
||||||
sudo rm -f /tmp/orama /tmp/network-source.tar.gz
|
sudo rm -f /tmp/orama /tmp/network-source.tar.gz
|
||||||
sudo rm -rf /tmp/network-extract /tmp/coredns-build /tmp/caddy-build
|
sudo rm -rf /tmp/network-extract /tmp/coredns-build /tmp/caddy-build
|
||||||
@ -32,7 +32,7 @@ wg set wg0 peer <NodeA-pubkey> remove
|
|||||||
wg set wg0 peer <NodeA-pubkey> endpoint <NodeA-public-ip>:51820 allowed-ips <NodeA-wg-ip>/32 persistent-keepalive 25
|
wg set wg0 peer <NodeA-pubkey> endpoint <NodeA-public-ip>:51820 allowed-ips <NodeA-wg-ip>/32 persistent-keepalive 25
|
||||||
```
|
```
|
||||||
|
|
||||||
Then restart services: `sudo orama prod restart`
|
Then restart services: `sudo orama node restart`
|
||||||
|
|
||||||
You can find peer public keys with `wg show wg0`.
|
You can find peer public keys with `wg show wg0`.
|
||||||
|
|
||||||
@ -41,19 +41,19 @@ You can find peer public keys with `wg show wg0`.
|
|||||||
Check the Olric config on each node:
|
Check the Olric config on each node:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cat /home/debros/.orama/data/namespaces/<name>/configs/olric-*.yaml
|
cat /opt/orama/.orama/data/namespaces/<name>/configs/olric-*.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
If `bindAddr` is `0.0.0.0`, the node will try to bind to IPv6 on dual-stack hosts, breaking memberlist gossip.
|
If `bindAddr` is `0.0.0.0`, the node will try to bind to IPv6 on dual-stack hosts, breaking memberlist gossip.
|
||||||
|
|
||||||
**Fix:** Edit the YAML to use the node's WireGuard IP (run `ip addr show wg0` to find it), then restart: `sudo orama prod restart`
|
**Fix:** Edit the YAML to use the node's WireGuard IP (run `ip addr show wg0` to find it), then restart: `sudo orama node restart`
|
||||||
|
|
||||||
This was fixed in code (BindAddr validation in `SpawnOlric`), so new namespaces won't have this issue.
|
This was fixed in code (BindAddr validation in `SpawnOlric`), so new namespaces won't have this issue.
|
||||||
|
|
||||||
### Check 3: Olric logs show "Failed UDP ping" constantly
|
### Check 3: Olric logs show "Failed UDP ping" constantly
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
journalctl -u debros-namespace-olric@<name>.service --no-pager -n 30
|
journalctl -u orama-namespace-olric@<name>.service --no-pager -n 30
|
||||||
```
|
```
|
||||||
|
|
||||||
If every UDP ping fails but TCP stream connections succeed, it's the WireGuard packet loss issue (see Check 1).
|
If every UDP ping fails but TCP stream connections succeed, it's the WireGuard packet loss issue (see Check 1).
|
||||||
@ -69,7 +69,7 @@ If every UDP ping fails but TCP stream connections succeed, it's the WireGuard p
|
|||||||
**Fix:** Edit the gateway config manually:
|
**Fix:** Edit the gateway config manually:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
vim /home/debros/.orama/data/namespaces/<name>/configs/gateway-*.yaml
|
vim /opt/orama/.orama/data/namespaces/<name>/configs/gateway-*.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
Add/fix:
|
Add/fix:
|
||||||
@ -82,7 +82,7 @@ olric_servers:
|
|||||||
- "10.0.0.Z:10002"
|
- "10.0.0.Z:10002"
|
||||||
```
|
```
|
||||||
|
|
||||||
Then: `sudo orama prod restart`
|
Then: `sudo orama node restart`
|
||||||
|
|
||||||
This was fixed in code, so new namespaces get the correct config.
|
This was fixed in code, so new namespaces get the correct config.
|
||||||
|
|
||||||
@ -90,12 +90,12 @@ This was fixed in code, so new namespaces get the correct config.
|
|||||||
|
|
||||||
## 3. Namespace not restoring after restart (missing cluster-state.json)
|
## 3. Namespace not restoring after restart (missing cluster-state.json)
|
||||||
|
|
||||||
**Symptom:** After `orama prod restart`, the namespace services don't come back because `RestoreLocalClustersFromDisk` has no state file.
|
**Symptom:** After `orama node restart`, the namespace services don't come back because `RestoreLocalClustersFromDisk` has no state file.
|
||||||
|
|
||||||
**Check:**
|
**Check:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ls /home/debros/.orama/data/namespaces/<name>/cluster-state.json
|
ls /opt/orama/.orama/data/namespaces/<name>/cluster-state.json
|
||||||
```
|
```
|
||||||
|
|
||||||
If the file doesn't exist, the node can't restore the namespace.
|
If the file doesn't exist, the node can't restore the namespace.
|
||||||
@ -117,17 +117,17 @@ This was fixed in code — `ProvisionCluster` now saves state to all nodes (incl
|
|||||||
|
|
||||||
## 4. Namespace gateway processes not restarting after upgrade
|
## 4. Namespace gateway processes not restarting after upgrade
|
||||||
|
|
||||||
**Symptom:** After `orama upgrade --restart` or `orama prod restart`, namespace gateway/olric/rqlite services don't start.
|
**Symptom:** After `orama upgrade --restart` or `orama node restart`, namespace gateway/olric/rqlite services don't start.
|
||||||
|
|
||||||
**Cause:** `orama prod stop` disables systemd template services (`debros-namespace-gateway@<name>.service`). They have `PartOf=debros-node.service`, but that only propagates restart to **enabled** services.
|
**Cause:** `orama node stop` disables systemd template services (`orama-namespace-gateway@<name>.service`). They have `PartOf=orama-node.service`, but that only propagates restart to **enabled** services.
|
||||||
|
|
||||||
**Fix:** Re-enable the services before restarting:
|
**Fix:** Re-enable the services before restarting:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
systemctl enable debros-namespace-rqlite@<name>.service
|
systemctl enable orama-namespace-rqlite@<name>.service
|
||||||
systemctl enable debros-namespace-olric@<name>.service
|
systemctl enable orama-namespace-olric@<name>.service
|
||||||
systemctl enable debros-namespace-gateway@<name>.service
|
systemctl enable orama-namespace-gateway@<name>.service
|
||||||
sudo orama prod restart
|
sudo orama node restart
|
||||||
```
|
```
|
||||||
|
|
||||||
This was fixed in code — the upgrade orchestrator now re-enables `@` services before restarting.
|
This was fixed in code — the upgrade orchestrator now re-enables `@` services before restarting.
|
||||||
@ -150,11 +150,68 @@ ssh -n user@host 'command'
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. RQLite returns 401 Unauthorized
|
||||||
|
|
||||||
|
**Symptom:** RQLite queries fail with HTTP 401 after security hardening.
|
||||||
|
|
||||||
|
**Cause:** RQLite now requires basic auth. The client isn't sending credentials.
|
||||||
|
|
||||||
|
**Fix:** Ensure the RQLite client is configured with the credentials from `/opt/orama/.orama/secrets/rqlite-auth.json`. The central RQLite client wrapper (`pkg/rqlite/client.go`) handles this automatically. If using a standalone client (e.g., CoreDNS plugin), ensure it's also configured.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Olric cluster split after upgrade
|
||||||
|
|
||||||
|
**Symptom:** Olric nodes can't gossip after enabling memberlist encryption.
|
||||||
|
|
||||||
|
**Cause:** Olric memberlist encryption is all-or-nothing. Nodes with encryption can't communicate with nodes without it.
|
||||||
|
|
||||||
|
**Fix:** All nodes must be restarted simultaneously when enabling Olric encryption. The cache will be lost (it rebuilds from DB). This is expected — Olric is a cache, not persistent storage.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. OramaOS: LUKS unlock fails
|
||||||
|
|
||||||
|
**Symptom:** OramaOS node can't reconstruct its LUKS key after reboot.
|
||||||
|
|
||||||
|
**Cause:** Not enough peer vault-guardians are online to meet the Shamir threshold (K = max(3, N/3)).
|
||||||
|
|
||||||
|
**Fix:** Ensure enough cluster nodes are online and reachable over WireGuard. The agent retries with exponential backoff. For genesis nodes before 5+ peers exist, use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
orama node unlock --genesis --node-ip <wg-ip>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. OramaOS: Enrollment timeout
|
||||||
|
|
||||||
|
**Symptom:** `orama node enroll` hangs or times out.
|
||||||
|
|
||||||
|
**Cause:** The OramaOS node's port 9999 isn't reachable, or the Gateway can't reach the node's WebSocket.
|
||||||
|
|
||||||
|
**Fix:** Check that port 9999 is open in your VPS provider's external firewall (Hetzner firewall, AWS security groups, etc.). OramaOS opens it internally, but provider-level firewalls must be configured separately.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Binary signature verification fails
|
||||||
|
|
||||||
|
**Symptom:** `orama node install` rejects the binary archive with a signature error.
|
||||||
|
|
||||||
|
**Cause:** The archive was tampered with, or the manifest.sig file is missing/corrupted.
|
||||||
|
|
||||||
|
**Fix:** Rebuild the archive with `orama build` and re-sign with `make sign` (in the orama-os repo). Ensure you're using the rootwallet that matches the embedded signer address.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## General Debugging Tips
|
## General Debugging Tips
|
||||||
|
|
||||||
- **Always use `sudo orama prod restart`** instead of raw `systemctl` commands
|
- **Always use `sudo orama node restart`** instead of raw `systemctl` commands
|
||||||
- **Namespace data lives at:** `/home/debros/.orama/data/namespaces/<name>/`
|
- **Namespace data lives at:** `/opt/orama/.orama/data/namespaces/<name>/`
|
||||||
- **Check service logs:** `journalctl -u debros-namespace-olric@<name>.service --no-pager -n 50`
|
- **Check service logs:** `journalctl -u orama-namespace-olric@<name>.service --no-pager -n 50`
|
||||||
- **Check WireGuard:** `wg show wg0` — look for recent handshakes and transfer bytes
|
- **Check WireGuard:** `wg show wg0` — look for recent handshakes and transfer bytes
|
||||||
- **Check gateway health:** `curl http://localhost:<port>/v1/health` from the node itself
|
- **Check gateway health:** `curl http://localhost:<port>/v1/health` from the node itself
|
||||||
- **Node IPs:** Check `scripts/remote-nodes.conf` for credentials, `wg show wg0` for WG IPs
|
- **Node IPs:** Check `scripts/remote-nodes.conf` for credentials, `wg show wg0` for WG IPs
|
||||||
|
- **OramaOS nodes:** No SSH access — use Gateway API endpoints (`/v1/node/status`, `/v1/node/logs`) for diagnostics
|
||||||
@ -163,7 +163,7 @@ orama deploy nextjs ./nextjs.tar.gz --name my-nextjs --ssr
|
|||||||
# URLs:
|
# URLs:
|
||||||
# • https://my-nextjs.orama.network
|
# • https://my-nextjs.orama.network
|
||||||
#
|
#
|
||||||
# ⚠️ Note: SSR deployment may take a minute to start. Check status with: orama deployments get my-nextjs
|
# ⚠️ Note: SSR deployment may take a minute to start. Check status with: orama app get my-nextjs
|
||||||
```
|
```
|
||||||
|
|
||||||
### What Happens Behind the Scenes
|
### What Happens Behind the Scenes
|
||||||
@ -369,7 +369,7 @@ orama db create my-database
|
|||||||
# Output:
|
# Output:
|
||||||
# ✅ Database created: my-database
|
# ✅ Database created: my-database
|
||||||
# Home Node: node-abc123
|
# Home Node: node-abc123
|
||||||
# File Path: /home/debros/.orama/data/sqlite/your-namespace/my-database.db
|
# File Path: /opt/orama/.orama/data/sqlite/your-namespace/my-database.db
|
||||||
```
|
```
|
||||||
|
|
||||||
### Executing Queries
|
### Executing Queries
|
||||||
@ -588,7 +588,7 @@ func main() {
|
|||||||
// DATABASE_NAME env var is automatically set by Orama
|
// DATABASE_NAME env var is automatically set by Orama
|
||||||
dbPath := os.Getenv("DATABASE_PATH")
|
dbPath := os.Getenv("DATABASE_PATH")
|
||||||
if dbPath == "" {
|
if dbPath == "" {
|
||||||
dbPath = "/home/debros/.orama/data/sqlite/" + os.Getenv("NAMESPACE") + "/myapp-db.db"
|
dbPath = "/opt/orama/.orama/data/sqlite/" + os.Getenv("NAMESPACE") + "/myapp-db.db"
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -795,7 +795,7 @@ Open your browser to:
|
|||||||
### List All Deployments
|
### List All Deployments
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
orama deployments list
|
orama app list
|
||||||
|
|
||||||
# Output:
|
# Output:
|
||||||
# NAME TYPE STATUS VERSION CREATED
|
# NAME TYPE STATUS VERSION CREATED
|
||||||
@ -809,7 +809,7 @@ orama deployments list
|
|||||||
### Get Deployment Details
|
### Get Deployment Details
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
orama deployments get my-react-app
|
orama app get my-react-app
|
||||||
|
|
||||||
# Output:
|
# Output:
|
||||||
# Deployment: my-react-app
|
# Deployment: my-react-app
|
||||||
@ -835,17 +835,17 @@ orama deployments get my-react-app
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# View last 100 lines
|
# View last 100 lines
|
||||||
orama deployments logs my-nextjs
|
orama app logs my-nextjs
|
||||||
|
|
||||||
# Follow logs in real-time
|
# Follow logs in real-time
|
||||||
orama deployments logs my-nextjs --follow
|
orama app logs my-nextjs --follow
|
||||||
```
|
```
|
||||||
|
|
||||||
### Rollback to Previous Version
|
### Rollback to Previous Version
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Rollback to version 1
|
# Rollback to version 1
|
||||||
orama deployments rollback my-nextjs --version 1
|
orama app rollback my-nextjs --version 1
|
||||||
|
|
||||||
# Output:
|
# Output:
|
||||||
# ⚠️ Rolling back 'my-nextjs' to version 1. Continue? (y/N): y
|
# ⚠️ Rolling back 'my-nextjs' to version 1. Continue? (y/N): y
|
||||||
@ -862,7 +862,7 @@ orama deployments rollback my-nextjs --version 1
|
|||||||
### Delete Deployment
|
### Delete Deployment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
orama deployments delete my-old-app
|
orama app delete my-old-app
|
||||||
|
|
||||||
# Output:
|
# Output:
|
||||||
# ⚠️ Are you sure you want to delete deployment 'my-old-app'? (y/N): y
|
# ⚠️ Are you sure you want to delete deployment 'my-old-app'? (y/N): y
|
||||||
@ -872,6 +872,57 @@ orama deployments delete my-old-app
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## WebRTC (Voice/Video/Data)
|
||||||
|
|
||||||
|
Namespaces can enable WebRTC support for real-time communication (voice calls, video calls, data channels).
|
||||||
|
|
||||||
|
### Enable WebRTC
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable WebRTC for a namespace (must be run on a cluster node)
|
||||||
|
orama namespace enable webrtc --namespace myapp
|
||||||
|
|
||||||
|
# Check WebRTC status
|
||||||
|
orama namespace webrtc-status --namespace myapp
|
||||||
|
```
|
||||||
|
|
||||||
|
This provisions SFU servers on all 3 nodes and TURN relay servers on 2 nodes, allocates port blocks, creates DNS records, and opens firewall ports.
|
||||||
|
|
||||||
|
### Disable WebRTC
|
||||||
|
|
||||||
|
```bash
|
||||||
|
orama namespace disable webrtc --namespace myapp
|
||||||
|
```
|
||||||
|
|
||||||
|
Stops all SFU/TURN services, deallocates ports, removes DNS records, and closes firewall ports.
|
||||||
|
|
||||||
|
### Client Integration
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 1. Get TURN credentials
|
||||||
|
const creds = await fetch('https://ns-myapp.orama.network/v1/webrtc/turn/credentials', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Authorization': `Bearer ${jwt}` }
|
||||||
|
});
|
||||||
|
const { urls, username, credential, ttl } = await creds.json();
|
||||||
|
|
||||||
|
// 2. Create PeerConnection (forced relay)
|
||||||
|
const pc = new RTCPeerConnection({
|
||||||
|
iceServers: [{ urls, username, credential }],
|
||||||
|
iceTransportPolicy: 'relay'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Connect signaling WebSocket
|
||||||
|
const ws = new WebSocket(
|
||||||
|
`wss://ns-myapp.orama.network/v1/webrtc/signal?room=${roomId}`,
|
||||||
|
['Bearer', jwt]
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
See [docs/WEBRTC.md](WEBRTC.md) for the full API reference, room management, credential protocol, and debugging guide.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Deployment Issues
|
### Deployment Issues
|
||||||
@ -880,10 +931,10 @@ orama deployments delete my-old-app
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check deployment details
|
# Check deployment details
|
||||||
orama deployments get my-app
|
orama app get my-app
|
||||||
|
|
||||||
# View logs for errors
|
# View logs for errors
|
||||||
orama deployments logs my-app
|
orama app logs my-app
|
||||||
|
|
||||||
# Common issues:
|
# Common issues:
|
||||||
# - Binary not compiled for Linux (GOOS=linux GOARCH=amd64)
|
# - Binary not compiled for Linux (GOOS=linux GOARCH=amd64)
|
||||||
@ -896,7 +947,7 @@ orama deployments logs my-app
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Check deployment status
|
# 1. Check deployment status
|
||||||
orama deployments get my-app
|
orama app get my-app
|
||||||
|
|
||||||
# 2. Verify DNS (may take up to 10 seconds to propagate)
|
# 2. Verify DNS (may take up to 10 seconds to propagate)
|
||||||
dig my-app.orama.network
|
dig my-app.orama.network
|
||||||
@ -980,7 +1031,7 @@ orama auth status
|
|||||||
|
|
||||||
- **Explore the API**: See `/docs/GATEWAY_API.md` for HTTP API details
|
- **Explore the API**: See `/docs/GATEWAY_API.md` for HTTP API details
|
||||||
- **Advanced Features**: Custom domains, load balancing, autoscaling (coming soon)
|
- **Advanced Features**: Custom domains, load balancing, autoscaling (coming soon)
|
||||||
- **Production Deployment**: Install nodes with `orama install` for production clusters
|
- **Production Deployment**: Install nodes with `orama node install` for production clusters
|
||||||
- **Client SDK**: Use the Go/JS SDK for programmatic deployments
|
- **Client SDK**: Use the Go/JS SDK for programmatic deployments
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -41,7 +41,7 @@ Install nodes **one at a time**, waiting for each to complete before starting th
|
|||||||
```bash
|
```bash
|
||||||
# SSH: <user>@<ns1-ip>
|
# SSH: <user>@<ns1-ip>
|
||||||
|
|
||||||
sudo orama install --no-pull --pre-built \
|
sudo orama node install \
|
||||||
--vps-ip <ns1-ip> \
|
--vps-ip <ns1-ip> \
|
||||||
--domain <your-domain.com> \
|
--domain <your-domain.com> \
|
||||||
--base-domain <your-domain.com> \
|
--base-domain <your-domain.com> \
|
||||||
@ -50,7 +50,7 @@ sudo orama install --no-pull --pre-built \
|
|||||||
|
|
||||||
After ns1 is installed, generate invite tokens:
|
After ns1 is installed, generate invite tokens:
|
||||||
```bash
|
```bash
|
||||||
orama invite --expiry 24h
|
sudo orama node invite --expiry 24h
|
||||||
```
|
```
|
||||||
|
|
||||||
## ns2 - Nameserver + Relay
|
## ns2 - Nameserver + Relay
|
||||||
@ -58,7 +58,7 @@ orama invite --expiry 24h
|
|||||||
```bash
|
```bash
|
||||||
# SSH: <user>@<ns2-ip>
|
# SSH: <user>@<ns2-ip>
|
||||||
|
|
||||||
sudo orama install --no-pull --pre-built \
|
sudo orama node install \
|
||||||
--join http://<ns1-ip> --token <TOKEN> \
|
--join http://<ns1-ip> --token <TOKEN> \
|
||||||
--vps-ip <ns2-ip> \
|
--vps-ip <ns2-ip> \
|
||||||
--domain <your-domain.com> \
|
--domain <your-domain.com> \
|
||||||
@ -68,8 +68,7 @@ sudo orama install --no-pull --pre-built \
|
|||||||
--anyone-nickname <relay-name> \
|
--anyone-nickname <relay-name> \
|
||||||
--anyone-wallet <wallet-address> \
|
--anyone-wallet <wallet-address> \
|
||||||
--anyone-contact "<contact-info>" \
|
--anyone-contact "<contact-info>" \
|
||||||
--anyone-family "<fingerprint1>,<fingerprint2>,..." \
|
--anyone-family "<fingerprint1>,<fingerprint2>,..."
|
||||||
--anyone-bandwidth 30
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## ns3 - Nameserver + Relay
|
## ns3 - Nameserver + Relay
|
||||||
@ -77,7 +76,7 @@ sudo orama install --no-pull --pre-built \
|
|||||||
```bash
|
```bash
|
||||||
# SSH: <user>@<ns3-ip>
|
# SSH: <user>@<ns3-ip>
|
||||||
|
|
||||||
sudo orama install --no-pull --pre-built \
|
sudo orama node install \
|
||||||
--join http://<ns1-ip> --token <TOKEN> \
|
--join http://<ns1-ip> --token <TOKEN> \
|
||||||
--vps-ip <ns3-ip> \
|
--vps-ip <ns3-ip> \
|
||||||
--domain <your-domain.com> \
|
--domain <your-domain.com> \
|
||||||
@ -87,27 +86,25 @@ sudo orama install --no-pull --pre-built \
|
|||||||
--anyone-nickname <relay-name> \
|
--anyone-nickname <relay-name> \
|
||||||
--anyone-wallet <wallet-address> \
|
--anyone-wallet <wallet-address> \
|
||||||
--anyone-contact "<contact-info>" \
|
--anyone-contact "<contact-info>" \
|
||||||
--anyone-family "<fingerprint1>,<fingerprint2>,..." \
|
--anyone-family "<fingerprint1>,<fingerprint2>,..."
|
||||||
--anyone-bandwidth 30
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## node4 - Non-Nameserver + Relay
|
## node4 - Non-Nameserver + Relay
|
||||||
|
|
||||||
|
Domain is auto-generated (e.g., `node-a3f8k2.<your-domain.com>`). No `--domain` flag needed.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# SSH: <user>@<node4-ip>
|
# SSH: <user>@<node4-ip>
|
||||||
|
|
||||||
sudo orama install --no-pull --pre-built \
|
sudo orama node install \
|
||||||
--join http://<ns1-ip> --token <TOKEN> \
|
--join http://<ns1-ip> --token <TOKEN> \
|
||||||
--vps-ip <node4-ip> \
|
--vps-ip <node4-ip> \
|
||||||
--domain node4.<your-domain.com> \
|
|
||||||
--base-domain <your-domain.com> \
|
--base-domain <your-domain.com> \
|
||||||
--skip-checks \
|
|
||||||
--anyone-relay --anyone-migrate \
|
--anyone-relay --anyone-migrate \
|
||||||
--anyone-nickname <relay-name> \
|
--anyone-nickname <relay-name> \
|
||||||
--anyone-wallet <wallet-address> \
|
--anyone-wallet <wallet-address> \
|
||||||
--anyone-contact "<contact-info>" \
|
--anyone-contact "<contact-info>" \
|
||||||
--anyone-family "<fingerprint1>,<fingerprint2>,..." \
|
--anyone-family "<fingerprint1>,<fingerprint2>,..."
|
||||||
--anyone-bandwidth 30
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## node5 - Non-Nameserver + Relay
|
## node5 - Non-Nameserver + Relay
|
||||||
@ -115,18 +112,15 @@ sudo orama install --no-pull --pre-built \
|
|||||||
```bash
|
```bash
|
||||||
# SSH: <user>@<node5-ip>
|
# SSH: <user>@<node5-ip>
|
||||||
|
|
||||||
sudo orama install --no-pull --pre-built \
|
sudo orama node install \
|
||||||
--join http://<ns1-ip> --token <TOKEN> \
|
--join http://<ns1-ip> --token <TOKEN> \
|
||||||
--vps-ip <node5-ip> \
|
--vps-ip <node5-ip> \
|
||||||
--domain node5.<your-domain.com> \
|
|
||||||
--base-domain <your-domain.com> \
|
--base-domain <your-domain.com> \
|
||||||
--skip-checks \
|
|
||||||
--anyone-relay --anyone-migrate \
|
--anyone-relay --anyone-migrate \
|
||||||
--anyone-nickname <relay-name> \
|
--anyone-nickname <relay-name> \
|
||||||
--anyone-wallet <wallet-address> \
|
--anyone-wallet <wallet-address> \
|
||||||
--anyone-contact "<contact-info>" \
|
--anyone-contact "<contact-info>" \
|
||||||
--anyone-family "<fingerprint1>,<fingerprint2>,..." \
|
--anyone-family "<fingerprint1>,<fingerprint2>,..."
|
||||||
--anyone-bandwidth 30
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## node6 - Non-Nameserver (No Anyone Relay)
|
## node6 - Non-Nameserver (No Anyone Relay)
|
||||||
@ -134,12 +128,10 @@ sudo orama install --no-pull --pre-built \
|
|||||||
```bash
|
```bash
|
||||||
# SSH: <user>@<node6-ip>
|
# SSH: <user>@<node6-ip>
|
||||||
|
|
||||||
sudo orama install --no-pull --pre-built \
|
sudo orama node install \
|
||||||
--join http://<ns1-ip> --token <TOKEN> \
|
--join http://<ns1-ip> --token <TOKEN> \
|
||||||
--vps-ip <node6-ip> \
|
--vps-ip <node6-ip> \
|
||||||
--domain node6.<your-domain.com> \
|
--base-domain <your-domain.com>
|
||||||
--base-domain <your-domain.com> \
|
|
||||||
--skip-checks
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Verification
|
## Verification
|
||||||
@ -147,13 +139,14 @@ sudo orama install --no-pull --pre-built \
|
|||||||
After all nodes are installed, verify cluster health:
|
After all nodes are installed, verify cluster health:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check RQLite cluster (from any node)
|
# Full cluster report (from local machine)
|
||||||
|
./bin/orama monitor report --env devnet
|
||||||
|
|
||||||
|
# Single node health
|
||||||
|
./bin/orama monitor report --env devnet --node <ip>
|
||||||
|
|
||||||
|
# Or manually from any VPS:
|
||||||
curl -s http://localhost:5001/status | jq -r '.store.raft.state, .store.raft.num_peers'
|
curl -s http://localhost:5001/status | jq -r '.store.raft.state, .store.raft.num_peers'
|
||||||
# Should show: Leader (on one node) and N-1 peers
|
|
||||||
|
|
||||||
# Check gateway health
|
|
||||||
curl -s http://localhost:6001/health
|
curl -s http://localhost:6001/health
|
||||||
|
systemctl status orama-anyone-relay
|
||||||
# Check Anyone relay (on nodes with relays)
|
|
||||||
systemctl status debros-anyone-relay
|
|
||||||
```
|
```
|
||||||
@ -17,7 +17,6 @@ make build
|
|||||||
# bin/orama — the CLI
|
# bin/orama — the CLI
|
||||||
# bin/gateway — standalone gateway (optional)
|
# bin/gateway — standalone gateway (optional)
|
||||||
# bin/identity — identity tool
|
# bin/identity — identity tool
|
||||||
# bin/rqlite-mcp — RQLite MCP server
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running Tests
|
## Running Tests
|
||||||
@ -26,197 +25,124 @@ make build
|
|||||||
make test
|
make test
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running Locally (macOS)
|
|
||||||
|
|
||||||
The node runs in "direct mode" on macOS — processes are managed directly instead of via systemd.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Start a single node
|
|
||||||
make run-node
|
|
||||||
|
|
||||||
# Start multiple nodes for cluster testing
|
|
||||||
make run-node2
|
|
||||||
make run-node3
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deploying to VPS
|
## Deploying to VPS
|
||||||
|
|
||||||
There are two deployment workflows: **development** (fast iteration, no git required) and **production** (via git).
|
All binaries are pre-compiled locally and shipped as a binary archive. Zero compilation on the VPS.
|
||||||
|
|
||||||
### Development Deployment (Fast Iteration)
|
### Deploy Workflow
|
||||||
|
|
||||||
Use this when iterating quickly — no need to commit or push to git.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Build the CLI for Linux
|
# One-command: build + push + rolling upgrade
|
||||||
GOOS=linux GOARCH=amd64 go build -o orama-cli-linux ./cmd/cli
|
orama node rollout --env testnet
|
||||||
|
|
||||||
# 2. Generate a source archive (excludes .git, node_modules, bin/, etc.)
|
# Or step by step:
|
||||||
./scripts/generate-source-archive.sh
|
|
||||||
# Creates: /tmp/network-source.tar.gz
|
|
||||||
|
|
||||||
# 3. Copy CLI and source to the VPS
|
# 1. Build binary archive (cross-compiles all binaries for linux/amd64)
|
||||||
sshpass -p '<password>' scp -o StrictHostKeyChecking=no orama-cli-linux ubuntu@<ip>:/tmp/orama
|
orama build
|
||||||
sshpass -p '<password>' scp -o StrictHostKeyChecking=no /tmp/network-source.tar.gz ubuntu@<ip>:/tmp/
|
# Creates: /tmp/orama-<version>-linux-amd64.tar.gz
|
||||||
|
|
||||||
# 4. On the VPS: extract source and install the CLI
|
# 2. Push archive to all nodes (fanout via hub node)
|
||||||
ssh ubuntu@<ip>
|
orama node push --env testnet
|
||||||
sudo rm -rf /home/debros/src && sudo mkdir -p /home/debros/src
|
|
||||||
sudo tar xzf /tmp/network-source.tar.gz -C /home/debros/src
|
|
||||||
sudo chown -R debros:debros /home/debros/src
|
|
||||||
sudo mv /tmp/orama /usr/local/bin/orama && sudo chmod +x /usr/local/bin/orama
|
|
||||||
|
|
||||||
# 5. Upgrade using local source (skips git pull)
|
# 3. Rolling upgrade (one node at a time, followers first, leader last)
|
||||||
sudo orama upgrade --no-pull --restart
|
orama node upgrade --env testnet
|
||||||
```
|
```
|
||||||
|
|
||||||
### Development Deployment with Pre-Built Binaries (Fastest)
|
### Fresh Node Install
|
||||||
|
|
||||||
Cross-compile everything locally and skip all Go compilation on the VPS. This is significantly faster because your local machine compiles much faster than the VPS.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Cross-compile all binaries for Linux (DeBros + Olric + CoreDNS + Caddy)
|
# Build the archive first (if not already built)
|
||||||
make build-linux-all
|
orama build
|
||||||
# Outputs everything to bin-linux/
|
|
||||||
|
|
||||||
# 2. Generate a single deploy archive (source + pre-built binaries)
|
# Install on a new VPS (auto-uploads binary archive, zero compilation)
|
||||||
./scripts/generate-source-archive.sh
|
orama node install --vps-ip <ip> --nameserver --domain <domain> --base-domain <domain>
|
||||||
# Creates: /tmp/network-source.tar.gz (includes bin-linux/ if present)
|
|
||||||
|
|
||||||
# 3. Copy the single archive to the VPS
|
|
||||||
sshpass -p '<password>' scp -o StrictHostKeyChecking=no /tmp/network-source.tar.gz ubuntu@<ip>:/tmp/
|
|
||||||
|
|
||||||
# 4. Extract and install everything on the VPS
|
|
||||||
sshpass -p '<password>' ssh -o StrictHostKeyChecking=no ubuntu@<ip> \
|
|
||||||
'sudo bash -s' < scripts/extract-deploy.sh
|
|
||||||
|
|
||||||
# 5. Install/upgrade with --pre-built (skips ALL Go compilation on VPS)
|
|
||||||
sudo orama install --no-pull --pre-built --vps-ip <ip> ...
|
|
||||||
# or
|
|
||||||
sudo orama upgrade --no-pull --pre-built --restart
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**What `--pre-built` skips:** Go installation, `make build`, Olric `go install`, CoreDNS build, Caddy/xcaddy build.
|
The installer auto-detects the binary archive at `/opt/orama/manifest.json` and copies pre-built binaries instead of compiling from source.
|
||||||
|
|
||||||
**What `--pre-built` still runs:** apt dependencies, RQLite/IPFS/IPFS Cluster downloads (pre-built binary downloads, fast), Anyone relay setup, config generation, systemd service creation.
|
|
||||||
|
|
||||||
### Production Deployment (Via Git)
|
|
||||||
|
|
||||||
For production releases — pulls source from GitHub on the VPS.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Commit and push your changes
|
|
||||||
git push origin <branch>
|
|
||||||
|
|
||||||
# 2. Build the CLI for Linux
|
|
||||||
GOOS=linux GOARCH=amd64 go build -o orama-cli-linux ./cmd/cli
|
|
||||||
|
|
||||||
# 3. Deploy the CLI to the VPS
|
|
||||||
sshpass -p '<password>' scp orama-cli-linux ubuntu@<ip>:/tmp/orama
|
|
||||||
ssh ubuntu@<ip> "sudo mv /tmp/orama /usr/local/bin/orama && sudo chmod +x /usr/local/bin/orama"
|
|
||||||
|
|
||||||
# 4. Run upgrade (downloads source from GitHub)
|
|
||||||
ssh ubuntu@<ip> "sudo orama upgrade --branch <branch> --restart"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Upgrading a Multi-Node Cluster (CRITICAL)
|
### Upgrading a Multi-Node Cluster (CRITICAL)
|
||||||
|
|
||||||
**NEVER restart all nodes simultaneously.** RQLite uses Raft consensus and requires a majority (quorum) to function. Restarting all nodes at once can cause cluster splits where nodes elect different leaders or form isolated clusters.
|
**NEVER restart all nodes simultaneously.** RQLite uses Raft consensus and requires a majority (quorum) to function.
|
||||||
|
|
||||||
#### Safe Upgrade Procedure (Rolling Restart)
|
#### Safe Upgrade Procedure
|
||||||
|
|
||||||
Always upgrade nodes **one at a time**, waiting for each to rejoin before proceeding:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Build locally
|
# Full rollout (build + push + rolling upgrade, one command)
|
||||||
make build-linux-all
|
orama node rollout --env testnet
|
||||||
./scripts/generate-source-archive.sh
|
|
||||||
# Creates: /tmp/network-source.tar.gz (includes bin-linux/)
|
|
||||||
|
|
||||||
# 2. Upload to ONE node first (the "hub" node)
|
# Or with more control:
|
||||||
sshpass -p '<password>' scp /tmp/network-source.tar.gz ubuntu@<hub-ip>:/tmp/
|
orama node push --env testnet # Push archive to all nodes
|
||||||
|
orama node upgrade --env testnet # Rolling upgrade (auto-detects leader)
|
||||||
|
orama node upgrade --env testnet --node 1.2.3.4 # Single node only
|
||||||
|
orama node upgrade --env testnet --delay 60 # 60s between nodes
|
||||||
|
```
|
||||||
|
|
||||||
# 3. Fan out from hub to all other nodes (server-to-server is faster)
|
The rolling upgrade automatically:
|
||||||
ssh ubuntu@<hub-ip>
|
1. Upgrades **follower** nodes first
|
||||||
for ip in <ip2> <ip3> <ip4> <ip5> <ip6>; do
|
2. Upgrades the **leader** last
|
||||||
scp /tmp/network-source.tar.gz ubuntu@$ip:/tmp/
|
3. Waits a configurable delay between nodes (default: 30s)
|
||||||
done
|
|
||||||
exit
|
|
||||||
|
|
||||||
# 4. Extract on ALL nodes (can be done in parallel, no restart yet)
|
After each node, verify health:
|
||||||
for ip in <ip1> <ip2> <ip3> <ip4> <ip5> <ip6>; do
|
```bash
|
||||||
ssh ubuntu@$ip 'sudo bash -s' < scripts/extract-deploy.sh
|
orama monitor report --env testnet
|
||||||
done
|
|
||||||
|
|
||||||
# 5. Find the RQLite leader (upgrade this one LAST)
|
|
||||||
ssh ubuntu@<any-node> 'curl -s http://localhost:5001/status | jq -r .store.raft.state'
|
|
||||||
|
|
||||||
# 6. Upgrade FOLLOWER nodes one at a time
|
|
||||||
# First stop services, then upgrade, which restarts them
|
|
||||||
ssh ubuntu@<follower-ip> 'sudo orama prod stop && sudo orama upgrade --no-pull --pre-built --restart'
|
|
||||||
|
|
||||||
# Wait for rejoin before proceeding to next node
|
|
||||||
ssh ubuntu@<leader-ip> 'curl -s http://localhost:5001/status | jq -r .store.raft.num_peers'
|
|
||||||
# Should show expected number of peers (N-1)
|
|
||||||
|
|
||||||
# Repeat for each follower...
|
|
||||||
|
|
||||||
# 7. Upgrade the LEADER node last
|
|
||||||
ssh ubuntu@<leader-ip> 'sudo orama prod stop && sudo orama upgrade --no-pull --pre-built --restart'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### What NOT to Do
|
#### What NOT to Do
|
||||||
|
|
||||||
- **DON'T** stop all nodes, replace binaries, then start all nodes
|
- **DON'T** stop all nodes, replace binaries, then start all nodes
|
||||||
- **DON'T** run `orama upgrade --restart` on multiple nodes in parallel
|
- **DON'T** run `orama node upgrade --restart` on multiple nodes in parallel
|
||||||
- **DON'T** clear RQLite data directories unless doing a full cluster rebuild
|
- **DON'T** clear RQLite data directories unless doing a full cluster rebuild
|
||||||
- **DON'T** use `systemctl stop debros-node` on multiple nodes simultaneously
|
- **DON'T** use `systemctl stop orama-node` on multiple nodes simultaneously
|
||||||
|
|
||||||
#### Recovery from Cluster Split
|
#### Recovery from Cluster Split
|
||||||
|
|
||||||
If nodes get stuck in "Candidate" state or show "leader not found" errors:
|
If nodes get stuck in "Candidate" state or show "leader not found" errors:
|
||||||
|
|
||||||
1. Identify which node has the most recent data (usually the old leader)
|
|
||||||
2. Keep that node running as the new leader
|
|
||||||
3. On each other node, clear RQLite data and restart:
|
|
||||||
```bash
|
|
||||||
sudo orama prod stop
|
|
||||||
sudo rm -rf /home/debros/.orama/data/rqlite
|
|
||||||
sudo systemctl start debros-node
|
|
||||||
```
|
|
||||||
4. The node should automatically rejoin using its configured `rqlite_join_address`
|
|
||||||
|
|
||||||
If automatic rejoin fails, the node may have started without the `-join` flag. Check:
|
|
||||||
```bash
|
```bash
|
||||||
ps aux | grep rqlited
|
# Recover the Raft cluster (specify the node with highest commit index as leader)
|
||||||
# Should include: -join 10.0.0.1:7001 (or similar)
|
orama node recover-raft --env testnet --leader 1.2.3.4
|
||||||
```
|
```
|
||||||
|
|
||||||
If `-join` is missing, the node bootstrapped standalone. You'll need to either:
|
This will:
|
||||||
- Restart debros-node (it should detect empty data and use join)
|
1. Stop orama-node on ALL nodes
|
||||||
- Or do a full cluster rebuild from CLEAN_NODE.md
|
2. Backup + delete raft/ on non-leader nodes
|
||||||
|
3. Start the leader, wait for Leader state
|
||||||
|
4. Start remaining nodes in batches
|
||||||
|
5. Verify cluster health
|
||||||
|
|
||||||
### Deploying to Multiple Nodes
|
### Cleaning Nodes for Reinstallation
|
||||||
|
|
||||||
To deploy to all nodes, repeat steps 3-5 (dev) or 3-4 (production) for each VPS IP.
|
```bash
|
||||||
|
# Wipe all data and services (preserves Anyone relay keys)
|
||||||
|
orama node clean --env testnet --force
|
||||||
|
|
||||||
**Important:** When using `--restart`, do nodes one at a time (see "Upgrading a Multi-Node Cluster" above).
|
# Also remove shared binaries (rqlited, ipfs, caddy, etc.)
|
||||||
|
orama node clean --env testnet --nuclear --force
|
||||||
|
|
||||||
|
# Single node only
|
||||||
|
orama node clean --env testnet --node 1.2.3.4 --force
|
||||||
|
```
|
||||||
|
|
||||||
|
### Push Options
|
||||||
|
|
||||||
|
```bash
|
||||||
|
orama node push --env devnet # Fanout via hub (default, fastest)
|
||||||
|
orama node push --env testnet --node 1.2.3.4 # Single node
|
||||||
|
orama node push --env testnet --direct # Sequential, no fanout
|
||||||
|
```
|
||||||
|
|
||||||
### CLI Flags Reference
|
### CLI Flags Reference
|
||||||
|
|
||||||
#### `orama install`
|
#### `orama node install`
|
||||||
|
|
||||||
| Flag | Description |
|
| Flag | Description |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
| `--vps-ip <ip>` | VPS public IP address (required) |
|
| `--vps-ip <ip>` | VPS public IP address (required) |
|
||||||
| `--domain <domain>` | Domain for HTTPS certificates. Nameserver nodes use the base domain (e.g., `example.com`); non-nameserver nodes use a subdomain (e.g., `node-4.example.com`) |
|
| `--domain <domain>` | Domain for HTTPS certificates. Required for nameserver nodes (use the base domain, e.g., `example.com`). Auto-generated for non-nameserver nodes if omitted (e.g., `node-a3f8k2.example.com`) |
|
||||||
| `--base-domain <domain>` | Base domain for deployment routing (e.g., example.com) |
|
| `--base-domain <domain>` | Base domain for deployment routing (e.g., example.com) |
|
||||||
| `--nameserver` | Configure this node as a nameserver (CoreDNS + Caddy) |
|
| `--nameserver` | Configure this node as a nameserver (CoreDNS + Caddy) |
|
||||||
| `--join <url>` | Join existing cluster via HTTPS URL (e.g., `https://node1.example.com`) |
|
| `--join <url>` | Join existing cluster via HTTPS URL (e.g., `https://node1.example.com`) |
|
||||||
| `--token <token>` | Invite token for joining (from `orama invite` on existing node) |
|
| `--token <token>` | Invite token for joining (from `orama node invite` on existing node) |
|
||||||
| `--branch <branch>` | Git branch to use (default: main) |
|
|
||||||
| `--no-pull` | Skip git clone/pull, use existing `/home/debros/src` |
|
|
||||||
| `--pre-built` | Skip all Go compilation, use pre-built binaries already on disk (see above) |
|
|
||||||
| `--force` | Force reconfiguration even if already installed |
|
| `--force` | Force reconfiguration even if already installed |
|
||||||
| `--skip-firewall` | Skip UFW firewall setup |
|
| `--skip-firewall` | Skip UFW firewall setup |
|
||||||
| `--skip-checks` | Skip minimum resource checks (RAM/CPU) |
|
| `--skip-checks` | Skip minimum resource checks (RAM/CPU) |
|
||||||
@ -231,7 +157,7 @@ To deploy to all nodes, repeat steps 3-5 (dev) or 3-4 (production) for each VPS
|
|||||||
| `--anyone-bandwidth <pct>` | Limit relay to N% of VPS bandwidth (default: 30, 0=unlimited). Runs a speedtest during install to measure available bandwidth |
|
| `--anyone-bandwidth <pct>` | Limit relay to N% of VPS bandwidth (default: 30, 0=unlimited). Runs a speedtest during install to measure available bandwidth |
|
||||||
| `--anyone-accounting <GB>` | Monthly data cap for relay in GB (0=unlimited) |
|
| `--anyone-accounting <GB>` | Monthly data cap for relay in GB (0=unlimited) |
|
||||||
|
|
||||||
#### `orama invite`
|
#### `orama node invite`
|
||||||
|
|
||||||
| Flag | Description |
|
| Flag | Description |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
@ -243,54 +169,132 @@ To deploy to all nodes, repeat steps 3-5 (dev) or 3-4 (production) for each VPS
|
|||||||
- **Expiry is checked in UTC.** RQLite uses `datetime('now')` which is always UTC. If your local timezone differs, account for the offset when choosing expiry durations.
|
- **Expiry is checked in UTC.** RQLite uses `datetime('now')` which is always UTC. If your local timezone differs, account for the offset when choosing expiry durations.
|
||||||
- **Use longer expiry for multi-node deployments.** When deploying multiple nodes, use `--expiry 24h` to avoid tokens expiring mid-deployment.
|
- **Use longer expiry for multi-node deployments.** When deploying multiple nodes, use `--expiry 24h` to avoid tokens expiring mid-deployment.
|
||||||
|
|
||||||
#### `orama upgrade`
|
#### `orama node upgrade`
|
||||||
|
|
||||||
| Flag | Description |
|
| Flag | Description |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
| `--branch <branch>` | Git branch to pull from |
|
| `--restart` | Restart all services after upgrade (local mode) |
|
||||||
| `--no-pull` | Skip git pull, use existing source |
|
| `--env <env>` | Target environment for remote rolling upgrade |
|
||||||
| `--pre-built` | Skip all Go compilation, use pre-built binaries already on disk |
|
| `--node <ip>` | Upgrade a single node only |
|
||||||
| `--restart` | Restart all services after upgrade |
|
| `--delay <seconds>` | Delay between nodes during rolling upgrade (default: 30) |
|
||||||
| `--anyone-relay` | Enable Anyone relay (same flags as install) |
|
| `--anyone-relay` | Enable Anyone relay (same flags as install) |
|
||||||
| `--anyone-bandwidth <pct>` | Limit relay to N% of VPS bandwidth (default: 30, 0=unlimited) |
|
| `--anyone-bandwidth <pct>` | Limit relay to N% of VPS bandwidth (default: 30, 0=unlimited) |
|
||||||
| `--anyone-accounting <GB>` | Monthly data cap for relay in GB (0=unlimited) |
|
| `--anyone-accounting <GB>` | Monthly data cap for relay in GB (0=unlimited) |
|
||||||
|
|
||||||
#### `orama prod` (Service Management)
|
#### `orama build`
|
||||||
|
|
||||||
|
| Flag | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `--arch <arch>` | Target architecture (default: amd64) |
|
||||||
|
| `--output <path>` | Output archive path |
|
||||||
|
| `--verbose` | Verbose build output |
|
||||||
|
|
||||||
|
#### `orama node push`
|
||||||
|
|
||||||
|
| Flag | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `--env <env>` | Target environment (required) |
|
||||||
|
| `--node <ip>` | Push to a single node only |
|
||||||
|
| `--direct` | Sequential upload (no hub fanout) |
|
||||||
|
|
||||||
|
#### `orama node rollout`
|
||||||
|
|
||||||
|
| Flag | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `--env <env>` | Target environment (required) |
|
||||||
|
| `--no-build` | Skip the build step |
|
||||||
|
| `--yes` | Skip confirmation |
|
||||||
|
| `--delay <seconds>` | Delay between nodes (default: 30) |
|
||||||
|
|
||||||
|
#### `orama node clean`
|
||||||
|
|
||||||
|
| Flag | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `--env <env>` | Target environment (required) |
|
||||||
|
| `--node <ip>` | Clean a single node only |
|
||||||
|
| `--nuclear` | Also remove shared binaries |
|
||||||
|
| `--force` | Skip confirmation (DESTRUCTIVE) |
|
||||||
|
|
||||||
|
#### `orama node recover-raft`
|
||||||
|
|
||||||
|
| Flag | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `--env <env>` | Target environment (required) |
|
||||||
|
| `--leader <ip>` | Leader node IP — highest commit index (required) |
|
||||||
|
| `--force` | Skip confirmation (DESTRUCTIVE) |
|
||||||
|
|
||||||
|
#### `orama node` (Service Management)
|
||||||
|
|
||||||
Use these commands to manage services on production nodes:
|
Use these commands to manage services on production nodes:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Stop all services (debros-node, coredns, caddy)
|
# Stop all services (orama-node, coredns, caddy)
|
||||||
sudo orama prod stop
|
sudo orama node stop
|
||||||
|
|
||||||
# Start all services
|
# Start all services
|
||||||
sudo orama prod start
|
sudo orama node start
|
||||||
|
|
||||||
# Restart all services
|
# Restart all services
|
||||||
sudo orama prod restart
|
sudo orama node restart
|
||||||
|
|
||||||
# Check service status
|
# Check service status
|
||||||
sudo orama prod status
|
sudo orama node status
|
||||||
|
|
||||||
|
# Diagnose common issues
|
||||||
|
sudo orama node doctor
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** Always use `orama prod stop` instead of manually running `systemctl stop`. The CLI ensures all related services (including CoreDNS and Caddy on nameserver nodes) are handled correctly.
|
**Note:** Always use `orama node stop` instead of manually running `systemctl stop`. The CLI ensures all related services (including CoreDNS and Caddy on nameserver nodes) are handled correctly.
|
||||||
|
|
||||||
|
#### `orama node report`
|
||||||
|
|
||||||
|
Outputs comprehensive health data as JSON. Used by `orama monitor` over SSH:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo orama node report --json
|
||||||
|
```
|
||||||
|
|
||||||
|
See [MONITORING.md](MONITORING.md) for full details.
|
||||||
|
|
||||||
|
#### `orama monitor`
|
||||||
|
|
||||||
|
Real-time cluster monitoring from your local machine:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Interactive TUI
|
||||||
|
orama monitor --env testnet
|
||||||
|
|
||||||
|
# Cluster overview
|
||||||
|
orama monitor cluster --env testnet
|
||||||
|
|
||||||
|
# Alerts only
|
||||||
|
orama monitor alerts --env testnet
|
||||||
|
|
||||||
|
# Full JSON for LLM analysis
|
||||||
|
orama monitor report --env testnet
|
||||||
|
```
|
||||||
|
|
||||||
|
See [MONITORING.md](MONITORING.md) for all subcommands and flags.
|
||||||
|
|
||||||
### Node Join Flow
|
### Node Join Flow
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Genesis node (first node, creates cluster)
|
# 1. Genesis node (first node, creates cluster)
|
||||||
# Nameserver nodes use the base domain as --domain
|
# Nameserver nodes use the base domain as --domain
|
||||||
sudo orama install --vps-ip 1.2.3.4 --domain example.com \
|
sudo orama node install --vps-ip 1.2.3.4 --domain example.com \
|
||||||
--base-domain example.com --nameserver
|
--base-domain example.com --nameserver
|
||||||
|
|
||||||
# 2. On genesis node, generate an invite
|
# 2. On genesis node, generate an invite
|
||||||
orama invite
|
orama node invite --expiry 24h
|
||||||
# Output: sudo orama install --join https://example.com --token <TOKEN> --vps-ip <IP>
|
# Output: sudo orama node install --join https://example.com --token <TOKEN> --vps-ip <IP>
|
||||||
|
|
||||||
# 3. On the new node, run the printed command
|
# 3a. Join as nameserver (requires --domain set to base domain)
|
||||||
# Nameserver nodes use the base domain; non-nameserver nodes use subdomains (e.g., node-4.example.com)
|
sudo orama node install --join http://1.2.3.4 --token abc123... \
|
||||||
sudo orama install --join https://example.com --token abc123... \
|
|
||||||
--vps-ip 5.6.7.8 --domain example.com --base-domain example.com --nameserver
|
--vps-ip 5.6.7.8 --domain example.com --base-domain example.com --nameserver
|
||||||
|
|
||||||
|
# 3b. Join as regular node (domain auto-generated, no --domain needed)
|
||||||
|
sudo orama node install --join http://1.2.3.4 --token abc123... \
|
||||||
|
--vps-ip 5.6.7.8 --base-domain example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
The join flow establishes a WireGuard VPN tunnel before starting cluster services.
|
The join flow establishes a WireGuard VPN tunnel before starting cluster services.
|
||||||
@ -306,7 +310,7 @@ node's IP so that `node1.example.com` resolves publicly.
|
|||||||
**If DNS is not yet configured**, you can use the genesis node's public IP with HTTP as a fallback:
|
**If DNS is not yet configured**, you can use the genesis node's public IP with HTTP as a fallback:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo orama install --join http://1.2.3.4 --vps-ip 5.6.7.8 --token abc123... --nameserver
|
sudo orama node install --join http://1.2.3.4 --vps-ip 5.6.7.8 --token abc123... --nameserver
|
||||||
```
|
```
|
||||||
|
|
||||||
This works because Caddy's `:80` block proxies all HTTP traffic to the gateway. However, once DNS
|
This works because Caddy's `:80` block proxies all HTTP traffic to the gateway. However, once DNS
|
||||||
@ -316,9 +320,37 @@ is properly configured, always use the HTTPS domain URL.
|
|||||||
UFW from external access. The join request goes through Caddy on port 80 (HTTP) or 443 (HTTPS),
|
UFW from external access. The join request goes through Caddy on port 80 (HTTP) or 443 (HTTPS),
|
||||||
which proxies to the gateway internally.
|
which proxies to the gateway internally.
|
||||||
|
|
||||||
## Pre-Install Checklist
|
## OramaOS Enrollment
|
||||||
|
|
||||||
Before running `orama install` on a VPS, ensure:
|
For OramaOS nodes (mainnet, devnet, testnet), use the enrollment flow instead of `orama node install`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Flash OramaOS image to VPS (via provider dashboard)
|
||||||
|
# 2. Generate invite token on existing cluster node
|
||||||
|
orama node invite --expiry 24h
|
||||||
|
|
||||||
|
# 3. Enroll the OramaOS node
|
||||||
|
orama node enroll --node-ip <vps-public-ip> --token <invite-token> --gateway <gateway-url>
|
||||||
|
|
||||||
|
# 4. For genesis node reboots (before 5+ peers exist)
|
||||||
|
orama node unlock --genesis --node-ip <wg-ip>
|
||||||
|
```
|
||||||
|
|
||||||
|
OramaOS nodes have no SSH access. All management happens through the Gateway API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Status, logs, commands — all via Gateway proxy
|
||||||
|
curl "https://gateway.example.com/v1/node/status?node_id=<id>"
|
||||||
|
curl "https://gateway.example.com/v1/node/logs?node_id=<id>&service=gateway"
|
||||||
|
```
|
||||||
|
|
||||||
|
See [ORAMAOS_DEPLOYMENT.md](ORAMAOS_DEPLOYMENT.md) for the full guide.
|
||||||
|
|
||||||
|
**Note:** `orama node clean` does not work on OramaOS nodes (no SSH). Use `orama node leave` for graceful departure, or reflash the image for a factory reset.
|
||||||
|
|
||||||
|
## Pre-Install Checklist (Ubuntu Only)
|
||||||
|
|
||||||
|
Before running `orama node install` on a VPS, ensure:
|
||||||
|
|
||||||
1. **Stop Docker if running.** Docker commonly binds ports 4001 and 8080 which conflict with IPFS. The installer checks for port conflicts and shows which process is using each port, but it's easier to stop Docker first:
|
1. **Stop Docker if running.** Docker commonly binds ports 4001 and 8080 which conflict with IPFS. The installer checks for port conflicts and shows which process is using each port, but it's easier to stop Docker first:
|
||||||
```bash
|
```bash
|
||||||
@ -331,12 +363,7 @@ Before running `orama install` on a VPS, ensure:
|
|||||||
sudo systemctl stop ipfs
|
sudo systemctl stop ipfs
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Ensure `make` is installed.** Required for building CoreDNS and Caddy from source:
|
3. **Stop any service on port 53** (for nameserver nodes). The installer handles `systemd-resolved` automatically, but other DNS services (like `bind9` or `dnsmasq`) must be stopped manually.
|
||||||
```bash
|
|
||||||
sudo apt-get install -y make
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Stop any service on port 53** (for nameserver nodes). The installer handles `systemd-resolved` automatically, but other DNS services (like `bind9` or `dnsmasq`) must be stopped manually.
|
|
||||||
|
|
||||||
## Recovering from Failed Joins
|
## Recovering from Failed Joins
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ Multiple subsystems can be combined: `--subsystem rqlite,olric,dns`
|
|||||||
| **ipfs** | Daemon active, cluster active, swarm peer count, cluster peer count, cluster errors, repo usage %, swarm key present, bootstrap list empty, cross-node version consistency |
|
| **ipfs** | Daemon active, cluster active, swarm peer count, cluster peer count, cluster errors, repo usage %, swarm key present, bootstrap list empty, cross-node version consistency |
|
||||||
| **dns** | CoreDNS active, Caddy active, ports (53/80/443), memory, restart count, log errors, Corefile exists, SOA/NS/wildcard/base-A resolution, TLS cert expiry, cross-node nameserver availability |
|
| **dns** | CoreDNS active, Caddy active, ports (53/80/443), memory, restart count, log errors, Corefile exists, SOA/NS/wildcard/base-A resolution, TLS cert expiry, cross-node nameserver availability |
|
||||||
| **wireguard** | Interface up, service active, correct 10.0.0.x IP, listen port 51820, peer count vs expected, MTU 1420, config exists + permissions 600, peer handshakes (fresh/stale/never), peer traffic, catch-all route detection, cross-node peer count + MTU consistency |
|
| **wireguard** | Interface up, service active, correct 10.0.0.x IP, listen port 51820, peer count vs expected, MTU 1420, config exists + permissions 600, peer handshakes (fresh/stale/never), peer traffic, catch-all route detection, cross-node peer count + MTU consistency |
|
||||||
| **system** | Core services (debros-node, rqlite, olric, ipfs, ipfs-cluster, wg-quick), nameserver services (coredns, caddy), failed systemd units, memory/disk/inode usage, load average, OOM kills, swap, UFW active, process user (debros), panic count, expected ports |
|
| **system** | Core services (orama-node, rqlite, olric, ipfs, ipfs-cluster, wg-quick), nameserver services (coredns, caddy), failed systemd units, memory/disk/inode usage, load average, OOM kills, swap, UFW active, process user (orama), panic count, expected ports |
|
||||||
| **network** | Internet reachability, default route, WireGuard route, TCP connection count, TIME_WAIT count, TCP retransmission rate, WireGuard mesh ping (all peers) |
|
| **network** | Internet reachability, default route, WireGuard route, TCP connection count, TIME_WAIT count, TCP retransmission rate, WireGuard mesh ping (all peers) |
|
||||||
| **namespace** | Per-namespace: RQLite up + raft state + readyz, Olric memberlist, Gateway HTTP health. Cross-namespace: all-healthy check, RQLite quorum per namespace |
|
| **namespace** | Per-namespace: RQLite up + raft state + readyz, Olric memberlist, Gateway HTTP health. Cross-namespace: all-healthy check, RQLite quorum per namespace |
|
||||||
|
|
||||||
@ -167,18 +167,18 @@ The inspector reads node definitions from a pipe-delimited config file (default:
|
|||||||
### Format
|
### Format
|
||||||
|
|
||||||
```
|
```
|
||||||
# environment|user@host|password|role|ssh_key
|
# environment|user@host|role
|
||||||
devnet|ubuntu@1.2.3.4|mypassword|node|
|
devnet|ubuntu@1.2.3.4|node
|
||||||
devnet|ubuntu@5.6.7.8|mypassword|nameserver-ns1|/path/to/key
|
devnet|ubuntu@5.6.7.8|nameserver-ns1
|
||||||
```
|
```
|
||||||
|
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
|-------|-------------|
|
|-------|-------------|
|
||||||
| `environment` | Cluster name (`devnet`, `testnet`) |
|
| `environment` | Cluster name (`devnet`, `testnet`) |
|
||||||
| `user@host` | SSH credentials |
|
| `user@host` | SSH credentials |
|
||||||
| `password` | SSH password |
|
|
||||||
| `role` | `node` or `nameserver-ns1`, `nameserver-ns2`, etc. |
|
| `role` | `node` or `nameserver-ns1`, `nameserver-ns2`, etc. |
|
||||||
| `ssh_key` | Optional path to SSH private key |
|
|
||||||
|
SSH keys are resolved from rootwallet (`rw vault ssh get <host>/<user> --priv`).
|
||||||
|
|
||||||
Blank lines and lines starting with `#` are ignored.
|
Blank lines and lines starting with `#` are ignored.
|
||||||
|
|
||||||
278
core/docs/MONITORING.md
Normal file
278
core/docs/MONITORING.md
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
# Monitoring
|
||||||
|
|
||||||
|
Real-time cluster health monitoring via SSH. The system has two parts:
|
||||||
|
|
||||||
|
1. **`orama node report`** — Runs on each VPS node, collects all local health data, outputs JSON
|
||||||
|
2. **`orama monitor`** — Runs on your local machine, SSHes into nodes, aggregates results, displays via TUI or tables
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
Developer Machine VPS Nodes (via SSH)
|
||||||
|
┌──────────────────┐ ┌────────────────────┐
|
||||||
|
│ orama monitor │ ──SSH──────────>│ orama node report │
|
||||||
|
│ (TUI / tables) │ <──JSON─────── │ (local collector) │
|
||||||
|
│ │ └────────────────────┘
|
||||||
|
│ CollectOnce() │ ──SSH──────────>│ orama node report │
|
||||||
|
│ DeriveAlerts() │ <──JSON─────── │ (local collector) │
|
||||||
|
│ Render() │ └────────────────────┘
|
||||||
|
└──────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Each node runs `orama node report --json` locally (no SSH to other nodes), collecting data via `os/exec` and `net/http` to localhost services. The monitor SSHes into all nodes in parallel, collects reports, then runs cross-node analysis to detect cluster-wide issues.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Interactive TUI (auto-refreshes every 30s)
|
||||||
|
orama monitor --env testnet
|
||||||
|
|
||||||
|
# Cluster overview table
|
||||||
|
orama monitor cluster --env testnet
|
||||||
|
|
||||||
|
# Alerts only
|
||||||
|
orama monitor alerts --env testnet
|
||||||
|
|
||||||
|
# Full JSON report (pipe to jq or feed to LLM)
|
||||||
|
orama monitor report --env testnet
|
||||||
|
```
|
||||||
|
|
||||||
|
## `orama monitor` — Local Orchestrator
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
orama monitor [subcommand] --env <environment> [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
Without a subcommand, launches the interactive TUI.
|
||||||
|
|
||||||
|
### Global Flags
|
||||||
|
|
||||||
|
| Flag | Default | Description |
|
||||||
|
|------|---------|-------------|
|
||||||
|
| `--env` | *(required)* | Environment: `devnet`, `testnet`, `mainnet` |
|
||||||
|
| `--json` | `false` | Machine-readable JSON output (for one-shot subcommands) |
|
||||||
|
| `--node` | | Filter to a specific node host/IP |
|
||||||
|
| `--config` | `scripts/remote-nodes.conf` | Path to node configuration file |
|
||||||
|
|
||||||
|
### Subcommands
|
||||||
|
|
||||||
|
| Subcommand | Description |
|
||||||
|
|------------|-------------|
|
||||||
|
| `live` | Interactive TUI monitor (default when no subcommand) |
|
||||||
|
| `cluster` | Cluster overview: all nodes, roles, RQLite state, WG peers |
|
||||||
|
| `node` | Per-node health details (system, services, WG, DNS) |
|
||||||
|
| `service` | Service status matrix across all nodes |
|
||||||
|
| `mesh` | WireGuard mesh connectivity and peer details |
|
||||||
|
| `dns` | DNS health: CoreDNS, Caddy, TLS cert expiry, resolution |
|
||||||
|
| `namespaces` | Namespace health across nodes |
|
||||||
|
| `alerts` | Active alerts and warnings sorted by severity |
|
||||||
|
| `report` | Full JSON dump optimized for LLM consumption |
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Cluster overview
|
||||||
|
orama monitor cluster --env testnet
|
||||||
|
|
||||||
|
# Cluster overview as JSON
|
||||||
|
orama monitor cluster --env testnet --json
|
||||||
|
|
||||||
|
# Alerts for all nodes
|
||||||
|
orama monitor alerts --env testnet
|
||||||
|
|
||||||
|
# Single-node deep dive
|
||||||
|
orama monitor node --env testnet --node 51.195.109.238
|
||||||
|
|
||||||
|
# Services for one node
|
||||||
|
orama monitor service --env testnet --node 51.195.109.238
|
||||||
|
|
||||||
|
# WireGuard mesh details
|
||||||
|
orama monitor mesh --env testnet
|
||||||
|
|
||||||
|
# DNS health
|
||||||
|
orama monitor dns --env testnet
|
||||||
|
|
||||||
|
# Namespace health
|
||||||
|
orama monitor namespaces --env testnet
|
||||||
|
|
||||||
|
# Full report for LLM analysis
|
||||||
|
orama monitor report --env testnet | jq .
|
||||||
|
|
||||||
|
# Single-node report
|
||||||
|
orama monitor report --env testnet --node 51.195.109.238
|
||||||
|
|
||||||
|
# Custom config file
|
||||||
|
orama monitor cluster --config /path/to/nodes.conf --env devnet
|
||||||
|
```
|
||||||
|
|
||||||
|
### Interactive TUI
|
||||||
|
|
||||||
|
The `live` subcommand (default) launches a full-screen terminal UI:
|
||||||
|
|
||||||
|
**Tabs:** Overview | Nodes | Services | WG Mesh | DNS | Namespaces | Alerts
|
||||||
|
|
||||||
|
**Key Bindings:**
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `Tab` / `Shift+Tab` | Switch tabs |
|
||||||
|
| `j` / `k` or `↑` / `↓` | Scroll content |
|
||||||
|
| `r` | Force refresh |
|
||||||
|
| `q` / `Ctrl+C` | Quit |
|
||||||
|
|
||||||
|
The TUI auto-refreshes every 30 seconds. A spinner shows during data collection. Colors indicate health: green = healthy, red = critical, yellow = warning.
|
||||||
|
|
||||||
|
### LLM Report Format
|
||||||
|
|
||||||
|
`orama monitor report` outputs structured JSON designed for AI consumption:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"environment": "testnet",
|
||||||
|
"collected_at": "2026-02-16T12:00:00Z",
|
||||||
|
"duration_seconds": 3.2,
|
||||||
|
"node_count": 3,
|
||||||
|
"healthy_count": 3
|
||||||
|
},
|
||||||
|
"summary": {
|
||||||
|
"rqlite_leader": "10.0.0.1",
|
||||||
|
"rqlite_voters": "3/3",
|
||||||
|
"rqlite_raft_term": 42,
|
||||||
|
"wg_mesh_status": "all connected",
|
||||||
|
"service_health": "all nominal",
|
||||||
|
"critical_alerts": 0,
|
||||||
|
"warning_alerts": 1,
|
||||||
|
"info_alerts": 0
|
||||||
|
},
|
||||||
|
"alerts": [...],
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"host": "51.195.109.238",
|
||||||
|
"status": "healthy",
|
||||||
|
"collection_ms": 526,
|
||||||
|
"report": { ... }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## `orama node report` — VPS-Side Collector
|
||||||
|
|
||||||
|
Runs locally on a VPS node. Collects all system and service data in parallel and outputs a single JSON blob. Requires root privileges.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On a VPS node
|
||||||
|
sudo orama node report --json
|
||||||
|
```
|
||||||
|
|
||||||
|
### What It Collects
|
||||||
|
|
||||||
|
| Section | Data |
|
||||||
|
|---------|------|
|
||||||
|
| **system** | CPU count, load average, memory/disk/swap usage, OOM kills, kernel version, uptime, clock time |
|
||||||
|
| **services** | Systemd service states (active, restarts, memory, CPU, restart loop detection) for 10 core services |
|
||||||
|
| **rqlite** | Raft state, leader, term, applied/commit index, peers, strong read test, readyz, debug vars |
|
||||||
|
| **olric** | Service state, memberlist, member count, restarts, memory, log analysis |
|
||||||
|
| **ipfs** | Daemon/cluster state, swarm/cluster peers, repo size, versions, swarm key |
|
||||||
|
| **gateway** | HTTP health check, subsystem status |
|
||||||
|
| **wireguard** | Interface state, WG IP, peers, handshake ages, MTU, config permissions |
|
||||||
|
| **dns** | CoreDNS/Caddy state, port bindings, resolution tests, TLS cert expiry |
|
||||||
|
| **anyone** | Relay/client state, bootstrap progress, fingerprint |
|
||||||
|
| **network** | Internet reachability, TCP stats, retransmission rate, listening ports, UFW rules |
|
||||||
|
| **processes** | Zombie count, orphan orama processes, panic/fatal count in logs |
|
||||||
|
| **namespaces** | Per-namespace service probes (RQLite, Olric, Gateway) |
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
All 12 collectors run in parallel with goroutines. Typical collection time is **< 1 second** per node. HTTP timeouts are 3 seconds, command timeouts are 4 seconds.
|
||||||
|
|
||||||
|
### Output Schema
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"timestamp": "2026-02-16T12:00:00Z",
|
||||||
|
"hostname": "ns1",
|
||||||
|
"version": "0.107.0",
|
||||||
|
"collect_ms": 526,
|
||||||
|
"errors": [],
|
||||||
|
"system": { "cpu_count": 4, "load_avg_1": 0.1, "mem_total_mb": 7937, ... },
|
||||||
|
"services": { "services": [...], "failed_units": [] },
|
||||||
|
"rqlite": { "responsive": true, "raft_state": "Leader", "term": 42, ... },
|
||||||
|
"olric": { "service_active": true, "memberlist_up": true, ... },
|
||||||
|
"ipfs": { "daemon_active": true, "swarm_peers": 2, ... },
|
||||||
|
"gateway": { "responsive": true, "http_status": 200, ... },
|
||||||
|
"wireguard": { "interface_up": true, "wg_ip": "10.0.0.1", "peers": [...], ... },
|
||||||
|
"dns": { "coredns_active": true, "caddy_active": true, "base_tls_days_left": 88, ... },
|
||||||
|
"anyone": { "relay_active": true, "bootstrapped": true, ... },
|
||||||
|
"network": { "internet_reachable": true, "ufw_active": true, ... },
|
||||||
|
"processes": { "zombie_count": 0, "orphan_count": 0, "panic_count": 0, ... },
|
||||||
|
"namespaces": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Alert Detection
|
||||||
|
|
||||||
|
Alerts are derived from cross-node analysis of all collected reports. Each alert has a severity level and identifies the affected subsystem and node.
|
||||||
|
|
||||||
|
### Alert Severities
|
||||||
|
|
||||||
|
| Severity | Examples |
|
||||||
|
|----------|----------|
|
||||||
|
| **critical** | SSH collection failed (node unreachable), no RQLite leader, split brain, RQLite unresponsive, WireGuard interface down, WG peer never handshaked, OOM kills, service failed, UFW inactive |
|
||||||
|
| **warning** | Strong read failed, memory > 90%, disk > 85%, stale WG handshake (> 3min), Raft term inconsistency, applied index lag > 100, restart loop detected, TLS cert < 14 days, DNS down, namespace gateway down, Anyone not bootstrapped, clock skew > 5s, binary version mismatch, internet unreachable, high TCP retransmission |
|
||||||
|
| **info** | Zombie processes, orphan orama processes, swap usage > 30% |
|
||||||
|
|
||||||
|
### Cross-Node Checks
|
||||||
|
|
||||||
|
These checks compare data across all nodes:
|
||||||
|
|
||||||
|
- **RQLite Leader**: Exactly one leader exists (no split brain)
|
||||||
|
- **Leader Agreement**: All nodes agree on the same leader address
|
||||||
|
- **Raft Term Consistency**: Term values within 1 of each other
|
||||||
|
- **Applied Index Lag**: Followers within 100 entries of the leader
|
||||||
|
- **WireGuard Peer Symmetry**: Each node has N-1 peers
|
||||||
|
- **Clock Skew**: Node clocks within 5 seconds of each other
|
||||||
|
- **Binary Version**: All nodes running the same version
|
||||||
|
- **WebRTC SFU Coverage**: SFU running on expected nodes (3/3) per namespace
|
||||||
|
- **WebRTC TURN Redundancy**: TURN running on expected nodes (2/3) per namespace
|
||||||
|
|
||||||
|
### Per-Node Checks
|
||||||
|
|
||||||
|
- **RQLite**: Responsive, ready, strong read
|
||||||
|
- **WireGuard**: Interface up, handshake freshness
|
||||||
|
- **System**: Memory, disk, load, OOM kills, swap
|
||||||
|
- **Services**: Systemd state, restart loops
|
||||||
|
- **DNS**: CoreDNS/Caddy up, TLS cert expiry, SOA resolution
|
||||||
|
- **Anyone**: Bootstrap progress
|
||||||
|
- **Processes**: Zombies, orphans, panics in logs
|
||||||
|
- **Namespaces**: Gateway and RQLite per namespace
|
||||||
|
- **WebRTC**: SFU and TURN service health (when provisioned)
|
||||||
|
- **Network**: UFW, internet reachability, TCP retransmission
|
||||||
|
|
||||||
|
## Monitor vs Inspector
|
||||||
|
|
||||||
|
Both tools check cluster health, but they serve different purposes:
|
||||||
|
|
||||||
|
| | `orama monitor` | `orama inspect` |
|
||||||
|
|---|---|---|
|
||||||
|
| **Data source** | `orama node report --json` (single SSH call per node) | 15+ SSH commands per node per subsystem |
|
||||||
|
| **Speed** | ~3-5s for full cluster | ~4-10s for full cluster |
|
||||||
|
| **Output** | TUI, tables, JSON | Tables, JSON |
|
||||||
|
| **Focus** | Real-time monitoring, alert detection | Deep diagnostic checks with pass/fail/warn |
|
||||||
|
| **AI support** | `report` subcommand for LLM input | `--ai` flag for inline analysis |
|
||||||
|
| **Use case** | "Is anything wrong right now?" | "What exactly is wrong and why?" |
|
||||||
|
|
||||||
|
Use `monitor` for day-to-day health checks and the interactive TUI. Use `inspect` for deep diagnostics when something is already known to be broken.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Uses the same `scripts/remote-nodes.conf` as the inspector. See [INSPECTOR.md](INSPECTOR.md#configuration) for format details.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Nodes must have the `orama` CLI installed (via `orama node install` or `upload-source.sh`). The monitor runs `sudo orama node report --json` over SSH, so the binary must be at `/usr/local/bin/orama` on each node.
|
||||||
233
core/docs/ORAMAOS_DEPLOYMENT.md
Normal file
233
core/docs/ORAMAOS_DEPLOYMENT.md
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
# OramaOS Deployment Guide
|
||||||
|
|
||||||
|
OramaOS is a custom minimal Linux image built with Buildroot. It replaces the standard Ubuntu-based node deployment for mainnet, devnet, and testnet environments. Sandbox clusters remain on Ubuntu for development convenience.
|
||||||
|
|
||||||
|
## What is OramaOS?
|
||||||
|
|
||||||
|
OramaOS is a locked-down operating system designed specifically for Orama node operators. Key properties:
|
||||||
|
|
||||||
|
- **No SSH, no shell** — operators cannot access the filesystem or run commands on the machine
|
||||||
|
- **LUKS full-disk encryption** — the data partition is encrypted; the key is split via Shamir's Secret Sharing across peer nodes
|
||||||
|
- **Read-only rootfs** — the OS image uses SquashFS with dm-verity integrity verification
|
||||||
|
- **A/B partition updates** — signed OS images are applied atomically with automatic rollback on failure
|
||||||
|
- **Service sandboxing** — each service runs in its own Linux namespace with seccomp syscall filtering
|
||||||
|
- **Signed binaries** — all updates are cryptographically signed with the Orama rootwallet
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
Partition Layout:
|
||||||
|
/dev/sda1 — ESP (EFI System Partition, systemd-boot)
|
||||||
|
/dev/sda2 — rootfs-A (SquashFS, read-only, dm-verity)
|
||||||
|
/dev/sda3 — rootfs-B (standby, for A/B updates)
|
||||||
|
/dev/sda4 — data (LUKS2 encrypted, ext4)
|
||||||
|
|
||||||
|
Boot Flow:
|
||||||
|
systemd-boot → dm-verity rootfs → orama-agent → WireGuard → services
|
||||||
|
```
|
||||||
|
|
||||||
|
The **orama-agent** is the only root process. It manages:
|
||||||
|
- Boot sequence and LUKS key reconstruction
|
||||||
|
- WireGuard tunnel setup
|
||||||
|
- Service lifecycle (start, stop, restart in sandboxed namespaces)
|
||||||
|
- Command reception from the Gateway over WireGuard
|
||||||
|
- OS updates (download, verify signature, A/B swap, reboot)
|
||||||
|
|
||||||
|
## Enrollment Flow
|
||||||
|
|
||||||
|
OramaOS nodes join the cluster through an enrollment process (different from the Ubuntu `orama node install` flow):
|
||||||
|
|
||||||
|
### Step 1: Flash OramaOS to VPS
|
||||||
|
|
||||||
|
Download the OramaOS image and flash it to your VPS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Download image (URL provided upon acceptance)
|
||||||
|
wget https://releases.orama.network/oramaos-v1.0.0-amd64.qcow2
|
||||||
|
|
||||||
|
# Flash to VPS (provider-specific — Hetzner, Vultr, etc.)
|
||||||
|
# Most providers support uploading custom images via their dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: First Boot — Enrollment Mode
|
||||||
|
|
||||||
|
On first boot, the agent:
|
||||||
|
1. Generates a random 8-character registration code
|
||||||
|
2. Starts a temporary HTTP server on port 9999
|
||||||
|
3. Opens an outbound WebSocket to the Gateway
|
||||||
|
4. Waits for enrollment to complete
|
||||||
|
|
||||||
|
The registration code is displayed on the VPS console (if available) and served at `http://<vps-ip>:9999/`.
|
||||||
|
|
||||||
|
### Step 3: Run Enrollment from CLI
|
||||||
|
|
||||||
|
On your local machine (where you have the `orama` CLI and rootwallet):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate an invite token on any existing cluster node
|
||||||
|
orama node invite --expiry 24h
|
||||||
|
|
||||||
|
# Enroll the OramaOS node
|
||||||
|
orama node enroll --node-ip <vps-public-ip> --token <invite-token> --gateway <gateway-url>
|
||||||
|
```
|
||||||
|
|
||||||
|
The enrollment command:
|
||||||
|
1. Fetches the registration code from the node (port 9999)
|
||||||
|
2. Sends the code + invite token to the Gateway
|
||||||
|
3. Gateway validates everything, assigns a WireGuard IP, and pushes config to the node
|
||||||
|
4. Node configures WireGuard, formats the LUKS-encrypted data partition
|
||||||
|
5. LUKS key is split via Shamir and distributed to peer vault-guardians
|
||||||
|
6. Services start in sandboxed namespaces
|
||||||
|
7. Port 9999 closes permanently
|
||||||
|
|
||||||
|
### Step 4: Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check the node is online and healthy
|
||||||
|
orama monitor report --env <env>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Genesis Node
|
||||||
|
|
||||||
|
The first OramaOS node in a cluster is the **genesis node**. It has a special boot path because there are no peers yet for Shamir key distribution:
|
||||||
|
|
||||||
|
1. Genesis generates a LUKS key and encrypts the data partition
|
||||||
|
2. The LUKS key is encrypted with a rootwallet-derived key and stored on the unencrypted rootfs
|
||||||
|
3. On reboot (before enough peers exist), the operator must manually unlock:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
orama node unlock --genesis --node-ip <wg-ip>
|
||||||
|
```
|
||||||
|
|
||||||
|
This command:
|
||||||
|
1. Fetches the encrypted genesis key from the node
|
||||||
|
2. Decrypts it using the rootwallet (`rw decrypt`)
|
||||||
|
3. Sends the decrypted LUKS key to the agent over WireGuard
|
||||||
|
|
||||||
|
Once 5+ peers have joined, the genesis node distributes Shamir shares to peers, deletes the local encrypted key, and transitions to normal Shamir-based unlock. After this transition, `orama node unlock` is no longer needed.
|
||||||
|
|
||||||
|
## Normal Reboot (Shamir Unlock)
|
||||||
|
|
||||||
|
When an enrolled OramaOS node reboots:
|
||||||
|
|
||||||
|
1. Agent starts, brings up WireGuard
|
||||||
|
2. Contacts peer vault-guardians over WireGuard
|
||||||
|
3. Fetches K Shamir shares (K = threshold, typically `max(3, N/3)`)
|
||||||
|
4. Reconstructs LUKS key via Lagrange interpolation over GF(256)
|
||||||
|
5. Decrypts and mounts data partition
|
||||||
|
6. Starts all services
|
||||||
|
7. Zeros key from memory
|
||||||
|
|
||||||
|
If not enough peers are available, the agent enters a degraded "waiting for peers" state and retries with exponential backoff (1s, 2s, 4s, 8s, 16s, max 5 retries per cycle).
|
||||||
|
|
||||||
|
## Node Management
|
||||||
|
|
||||||
|
Since OramaOS has no SSH, all management happens through the Gateway API:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check node status
|
||||||
|
curl "https://gateway.example.com/v1/node/status?node_id=<id>"
|
||||||
|
|
||||||
|
# Send a command (e.g., restart a service)
|
||||||
|
curl -X POST "https://gateway.example.com/v1/node/command?node_id=<id>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"action":"restart","service":"rqlite"}'
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
curl "https://gateway.example.com/v1/node/logs?node_id=<id>&service=gateway&lines=100"
|
||||||
|
|
||||||
|
# Graceful node departure
|
||||||
|
curl -X POST "https://gateway.example.com/v1/node/leave" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"node_id":"<id>"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
The Gateway proxies these requests to the agent over WireGuard (port 9998). The agent is never directly accessible from the public internet.
|
||||||
|
|
||||||
|
## OS Updates
|
||||||
|
|
||||||
|
OramaOS uses an A/B partition scheme for atomic, rollback-safe updates:
|
||||||
|
|
||||||
|
1. Agent periodically checks for new versions
|
||||||
|
2. Downloads the signed image (P2P over WireGuard between nodes)
|
||||||
|
3. Verifies the rootwallet EVM signature against the embedded public key
|
||||||
|
4. Writes to the standby partition (if running from A, writes to B)
|
||||||
|
5. Sets systemd-boot to boot from B with `tries_left=3`
|
||||||
|
6. Reboots
|
||||||
|
7. If B boots successfully (agent starts, WG connects, services healthy): marks B as "good"
|
||||||
|
8. If B fails 3 times: systemd-boot automatically falls back to A
|
||||||
|
|
||||||
|
No operator intervention is needed for updates. Failed updates are automatically rolled back.
|
||||||
|
|
||||||
|
## Service Sandboxing
|
||||||
|
|
||||||
|
Each service on OramaOS runs in an isolated environment:
|
||||||
|
|
||||||
|
- **Mount namespace** — each service only sees its own data directory as writable; everything else is read-only
|
||||||
|
- **UTS namespace** — isolated hostname
|
||||||
|
- **Dedicated UID/GID** — each service runs as a different user (not root)
|
||||||
|
- **Seccomp filtering** — per-service syscall allowlist (initially in audit mode, then enforce mode)
|
||||||
|
|
||||||
|
Services and their sandbox profiles:
|
||||||
|
| Service | Writable Path | Extra Syscalls |
|
||||||
|
|---------|--------------|----------------|
|
||||||
|
| RQLite | `/opt/orama/.orama/data/rqlite` | fsync, fdatasync (Raft + SQLite WAL) |
|
||||||
|
| Olric | `/opt/orama/.orama/data/olric` | sendmmsg, recvmmsg (gossip) |
|
||||||
|
| IPFS | `/opt/orama/.orama/data/ipfs` | sendfile, splice (data transfer) |
|
||||||
|
| Gateway | `/opt/orama/.orama/data/gateway` | sendfile, splice (HTTP) |
|
||||||
|
| CoreDNS | `/opt/orama/.orama/data/coredns` | sendmmsg, recvmmsg (DNS) |
|
||||||
|
|
||||||
|
## OramaOS vs Ubuntu Deployment
|
||||||
|
|
||||||
|
| Feature | Ubuntu | OramaOS |
|
||||||
|
|---------|--------|---------|
|
||||||
|
| SSH access | Yes | No |
|
||||||
|
| Shell access | Yes | No |
|
||||||
|
| Disk encryption | No | LUKS2 (Shamir) |
|
||||||
|
| OS updates | Manual (`orama node upgrade`) | Automatic (signed, A/B) |
|
||||||
|
| Service isolation | systemd only | Namespaces + seccomp |
|
||||||
|
| Rootfs integrity | None | dm-verity |
|
||||||
|
| Binary signing | Optional | Required |
|
||||||
|
| Operator data access | Full | None |
|
||||||
|
| Environments | All (including sandbox) | Mainnet, devnet, testnet |
|
||||||
|
|
||||||
|
## Cleaning / Factory Reset
|
||||||
|
|
||||||
|
OramaOS nodes cannot be cleaned with the standard `orama node clean` command (no SSH access). Instead:
|
||||||
|
|
||||||
|
- **Graceful departure:** `orama node leave` via the Gateway API — stops services, redistributes Shamir shares, removes WG peer
|
||||||
|
- **Factory reset:** Reflash the OramaOS image on the VPS via the hosting provider's dashboard
|
||||||
|
- **Data is unrecoverable:** Since the LUKS key is distributed across peers, reflashing destroys all data permanently
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Node stuck in enrollment mode
|
||||||
|
The node boots but enrollment never completes.
|
||||||
|
|
||||||
|
**Check:** Can you reach `http://<vps-ip>:9999/` from your machine? If not, the VPS firewall may be blocking port 9999.
|
||||||
|
|
||||||
|
**Fix:** Ensure port 9999 is open in the VPS provider's firewall. OramaOS opens it automatically via its internal firewall, but external provider firewalls (Hetzner, AWS security groups) must be configured separately.
|
||||||
|
|
||||||
|
### LUKS unlock fails (not enough peers)
|
||||||
|
After reboot, the node can't reconstruct its LUKS key.
|
||||||
|
|
||||||
|
**Check:** How many peer nodes are online? The node needs at least K peers (threshold) to be reachable over WireGuard.
|
||||||
|
|
||||||
|
**Fix:** Ensure enough cluster nodes are online. If this is the genesis node and fewer than 5 peers exist, use:
|
||||||
|
```bash
|
||||||
|
orama node unlock --genesis --node-ip <wg-ip>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update failed, node rolled back
|
||||||
|
The node applied an update but reverted to the previous version.
|
||||||
|
|
||||||
|
**Check:** The agent logs will show why the new partition failed to boot (accessible via `GET /v1/node/logs?service=agent`).
|
||||||
|
|
||||||
|
**Common causes:** Corrupted download (signature verification should catch this), hardware issue, or incompatible configuration.
|
||||||
|
|
||||||
|
### Services not starting after reboot
|
||||||
|
The node rebooted and LUKS unlocked, but services are unhealthy.
|
||||||
|
|
||||||
|
**Check:** `GET /v1/node/status` — which services are down?
|
||||||
|
|
||||||
|
**Fix:** Try restarting the specific service via `POST /v1/node/command` with `{"action":"restart","service":"<name>"}`. If the issue persists, check service logs.
|
||||||
208
core/docs/SANDBOX.md
Normal file
208
core/docs/SANDBOX.md
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
# Sandbox: Ephemeral Hetzner Cloud Clusters
|
||||||
|
|
||||||
|
Spin up temporary 5-node Orama clusters on Hetzner Cloud for development and testing. Total cost: ~€0.04/hour.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# One-time setup (API key, domain, floating IPs, SSH key)
|
||||||
|
orama sandbox setup
|
||||||
|
|
||||||
|
# Create a cluster (~5 minutes)
|
||||||
|
orama sandbox create --name my-feature
|
||||||
|
|
||||||
|
# Check health
|
||||||
|
orama sandbox status
|
||||||
|
|
||||||
|
# SSH into a node
|
||||||
|
orama sandbox ssh 1
|
||||||
|
|
||||||
|
# Deploy code changes
|
||||||
|
orama sandbox rollout
|
||||||
|
|
||||||
|
# Tear it down
|
||||||
|
orama sandbox destroy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### 1. Hetzner Cloud Account
|
||||||
|
|
||||||
|
Create a project at [console.hetzner.cloud](https://console.hetzner.cloud) and generate an API token with read/write permissions under **Security > API Tokens**.
|
||||||
|
|
||||||
|
### 2. Domain with Glue Records
|
||||||
|
|
||||||
|
You need a domain (or subdomain) that points to Hetzner Floating IPs. The `orama sandbox setup` wizard will guide you through this.
|
||||||
|
|
||||||
|
**Example:** Using `sbx.dbrs.space`
|
||||||
|
|
||||||
|
At your domain registrar:
|
||||||
|
1. Create glue records (Personal DNS Servers):
|
||||||
|
- `ns1.sbx.dbrs.space` → `<floating-ip-1>`
|
||||||
|
- `ns2.sbx.dbrs.space` → `<floating-ip-2>`
|
||||||
|
2. Set custom nameservers for `sbx.dbrs.space`:
|
||||||
|
- `ns1.sbx.dbrs.space`
|
||||||
|
- `ns2.sbx.dbrs.space`
|
||||||
|
|
||||||
|
DNS propagation can take up to 48 hours.
|
||||||
|
|
||||||
|
### 3. Binary Archive
|
||||||
|
|
||||||
|
Build the binary archive before creating a cluster:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
orama build
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates `/tmp/orama-<version>-linux-amd64.tar.gz` with all pre-compiled binaries.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Run the interactive setup wizard:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
orama sandbox setup
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
1. Prompt for your Hetzner API token and validate it
|
||||||
|
2. Ask for your sandbox domain
|
||||||
|
3. Create or reuse 2 Hetzner Floating IPs (~$0.005/hr each)
|
||||||
|
4. Create a firewall with sandbox rules
|
||||||
|
5. Create a rootwallet SSH entry (`sandbox/root`) if it doesn't exist
|
||||||
|
6. Upload the wallet-derived public key to Hetzner
|
||||||
|
7. Display DNS configuration instructions
|
||||||
|
|
||||||
|
Config is saved to `~/.orama/sandbox.yaml`.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### `orama sandbox create [--name <name>]`
|
||||||
|
|
||||||
|
Creates a new 5-node cluster. If `--name` is omitted, a random name is generated (e.g., "swift-falcon").
|
||||||
|
|
||||||
|
**Cluster layout:**
|
||||||
|
- Nodes 1-2: Nameservers (CoreDNS + Caddy + all services)
|
||||||
|
- Nodes 3-5: Regular nodes (all services except CoreDNS)
|
||||||
|
|
||||||
|
**Phases:**
|
||||||
|
1. Provision 5 CX22 servers on Hetzner (parallel, ~90s)
|
||||||
|
2. Assign floating IPs to nameserver nodes (~10s)
|
||||||
|
3. Upload binary archive to all nodes (parallel, ~60s)
|
||||||
|
4. Install genesis node + generate invite tokens (~120s)
|
||||||
|
5. Join remaining 4 nodes (serial with health checks, ~180s)
|
||||||
|
6. Verify cluster health (~15s)
|
||||||
|
|
||||||
|
**One sandbox at a time.** Since the floating IPs are shared, only one sandbox can own the nameservers. Destroy the active sandbox before creating a new one.
|
||||||
|
|
||||||
|
### `orama sandbox destroy [--name <name>] [--force]`
|
||||||
|
|
||||||
|
Tears down a cluster:
|
||||||
|
1. Unassigns floating IPs
|
||||||
|
2. Deletes all 5 servers (parallel)
|
||||||
|
3. Removes state file
|
||||||
|
|
||||||
|
Use `--force` to skip confirmation.
|
||||||
|
|
||||||
|
### `orama sandbox list`
|
||||||
|
|
||||||
|
Lists all sandboxes with their status. Also checks Hetzner for orphaned servers that don't have a corresponding state file.
|
||||||
|
|
||||||
|
### `orama sandbox status [--name <name>]`
|
||||||
|
|
||||||
|
Shows per-node health including:
|
||||||
|
- Service status (active/inactive)
|
||||||
|
- RQLite role (Leader/Follower)
|
||||||
|
- Cluster summary (commit index, voter count)
|
||||||
|
|
||||||
|
### `orama sandbox rollout [--name <name>]`
|
||||||
|
|
||||||
|
Deploys code changes:
|
||||||
|
1. Uses the latest binary archive from `/tmp/` (run `orama build` first)
|
||||||
|
2. Pushes to all nodes
|
||||||
|
3. Rolling upgrade: followers first, leader last, 15s between nodes
|
||||||
|
|
||||||
|
### `orama sandbox ssh <node-number>`
|
||||||
|
|
||||||
|
Opens an interactive SSH session to a sandbox node (1-5).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
orama sandbox ssh 1 # SSH into node 1 (genesis/ns1)
|
||||||
|
orama sandbox ssh 3 # SSH into node 3 (regular node)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Floating IPs
|
||||||
|
|
||||||
|
Hetzner Floating IPs are persistent IPv4 addresses that can be reassigned between servers. They solve the DNS chicken-and-egg problem:
|
||||||
|
|
||||||
|
- Glue records at the registrar point to 2 Floating IPs (configured once)
|
||||||
|
- Each new sandbox assigns the Floating IPs to its nameserver nodes
|
||||||
|
- DNS works instantly — no propagation delay between clusters
|
||||||
|
|
||||||
|
### SSH Authentication
|
||||||
|
|
||||||
|
Sandbox uses a rootwallet-derived SSH key (`sandbox/root` vault entry), the same mechanism as production. The wallet must be unlocked (`rw unlock`) before running sandbox commands that use SSH. The public key is uploaded to Hetzner during setup and injected into every server at creation time.
|
||||||
|
|
||||||
|
### Server Naming
|
||||||
|
|
||||||
|
Servers: `sbx-<name>-<N>` (e.g., `sbx-swift-falcon-1` through `sbx-swift-falcon-5`)
|
||||||
|
|
||||||
|
### State Files
|
||||||
|
|
||||||
|
Sandbox state is stored at `~/.orama/sandboxes/<name>.yaml`. This tracks server IDs, IPs, roles, and cluster status.
|
||||||
|
|
||||||
|
## Cost
|
||||||
|
|
||||||
|
| Resource | Cost | Qty | Total |
|
||||||
|
|----------|------|-----|-------|
|
||||||
|
| CX22 (2 vCPU, 4GB) | €0.006/hr | 5 | €0.03/hr |
|
||||||
|
| Floating IPv4 | €0.005/hr | 2 | €0.01/hr |
|
||||||
|
| **Total** | | | **~€0.04/hr** |
|
||||||
|
|
||||||
|
Servers are billed per hour. Floating IPs are billed as long as they exist (even unassigned). Destroy the sandbox when not in use to save on server costs.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "sandbox not configured"
|
||||||
|
|
||||||
|
Run `orama sandbox setup` first.
|
||||||
|
|
||||||
|
### "no binary archive found"
|
||||||
|
|
||||||
|
Run `orama build` to create the binary archive.
|
||||||
|
|
||||||
|
### "sandbox X is already active"
|
||||||
|
|
||||||
|
Only one sandbox can be active at a time. Destroy it first:
|
||||||
|
```bash
|
||||||
|
orama sandbox destroy --name <name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Server creation fails
|
||||||
|
|
||||||
|
Check:
|
||||||
|
- Hetzner API token is valid and has read/write permissions
|
||||||
|
- You haven't hit Hetzner's server limit (default: 10 per project)
|
||||||
|
- The selected location has CX22 capacity
|
||||||
|
|
||||||
|
### Genesis install fails
|
||||||
|
|
||||||
|
SSH into the node to debug:
|
||||||
|
```bash
|
||||||
|
orama sandbox ssh 1
|
||||||
|
journalctl -u orama-node -f
|
||||||
|
```
|
||||||
|
|
||||||
|
The sandbox will be left in "error" state. You can destroy and recreate it.
|
||||||
|
|
||||||
|
### DNS not resolving
|
||||||
|
|
||||||
|
1. Verify glue records are configured at your registrar
|
||||||
|
2. Check propagation: `dig NS sbx.dbrs.space @8.8.8.8`
|
||||||
|
3. Propagation can take 24-48 hours for new domains
|
||||||
|
|
||||||
|
### Orphaned servers
|
||||||
|
|
||||||
|
If `orama sandbox list` shows orphaned servers, delete them manually at [console.hetzner.cloud](https://console.hetzner.cloud). Sandbox servers are labeled `orama-sandbox=<name>` for easy identification.
|
||||||
194
core/docs/SECURITY.md
Normal file
194
core/docs/SECURITY.md
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
# Security Hardening
|
||||||
|
|
||||||
|
This document describes all security measures applied to the Orama Network, covering both Phase 1 (service hardening on existing Ubuntu nodes) and Phase 2 (OramaOS locked-down image).
|
||||||
|
|
||||||
|
## Phase 1: Service Hardening
|
||||||
|
|
||||||
|
These measures apply to all nodes (Ubuntu and OramaOS).
|
||||||
|
|
||||||
|
### Network Isolation
|
||||||
|
|
||||||
|
**CIDR Validation (Step 1.1)**
|
||||||
|
- WireGuard subnet restricted to `10.0.0.0/24` across all components: firewall rules, rate limiter, auth module, and WireGuard PostUp/PostDown iptables rules
|
||||||
|
- Prevents other tenants on shared VPS providers from bypassing the firewall via overlapping `10.x.x.x` ranges
|
||||||
|
|
||||||
|
**IPv6 Disabled (Step 1.2)**
|
||||||
|
- IPv6 disabled system-wide via sysctl: `net.ipv6.conf.all.disable_ipv6=1`
|
||||||
|
- Prevents services bound to `0.0.0.0` from being reachable via IPv6 (which had no firewall rules)
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
|
**Internal Endpoint Auth (Step 1.3)**
|
||||||
|
- `/v1/internal/wg/peers` and `/v1/internal/wg/peer/remove` now require cluster secret validation
|
||||||
|
- Peer removal additionally validates the request originates from a WireGuard subnet IP
|
||||||
|
|
||||||
|
**RQLite Authentication (Step 1.7)**
|
||||||
|
- RQLite runs with `-auth` flag pointing to a credentials file
|
||||||
|
- All RQLite HTTP requests include `Authorization: Basic <base64>` headers
|
||||||
|
- Credentials generated at cluster genesis, distributed to joining nodes via join response
|
||||||
|
- Both the central RQLite client wrapper and the standalone CoreDNS RQLite client send auth
|
||||||
|
|
||||||
|
**Olric Gossip Encryption (Step 1.8)**
|
||||||
|
- Olric memberlist uses a 32-byte encryption key for all gossip traffic
|
||||||
|
- Key generated at genesis, distributed via join response
|
||||||
|
- Prevents rogue nodes from joining the gossip ring and poisoning caches
|
||||||
|
- Note: encryption is all-or-nothing (coordinated restart required when enabling)
|
||||||
|
|
||||||
|
**IPFS Cluster TrustedPeers (Step 1.9)**
|
||||||
|
- IPFS Cluster `TrustedPeers` populated with actual cluster peer IDs (was `["*"]`)
|
||||||
|
- New peers added to TrustedPeers on all existing nodes during join
|
||||||
|
- Prevents unauthorized peers from controlling IPFS pinning
|
||||||
|
|
||||||
|
**Vault V1 Auth Enforcement (Step 1.14)**
|
||||||
|
- V1 push/pull endpoints require a valid session token when vault-guardian is configured
|
||||||
|
- Previously, auth was optional for backward compatibility — any WG peer could read/overwrite Shamir shares
|
||||||
|
|
||||||
|
### Token & Key Storage
|
||||||
|
|
||||||
|
**Refresh Token Hashing (Step 1.5)**
|
||||||
|
- Refresh tokens stored as SHA-256 hashes in RQLite (never plaintext)
|
||||||
|
- On lookup: hash the incoming token, query by hash
|
||||||
|
- On revocation: hash before revoking (both single-token and by-subject)
|
||||||
|
- Existing tokens invalidated on upgrade (users re-authenticate)
|
||||||
|
|
||||||
|
**API Key Hashing (Step 1.6)**
|
||||||
|
- API keys stored as HMAC-SHA256 hashes using a server-side secret
|
||||||
|
- HMAC secret generated at cluster genesis, stored in `~/.orama/secrets/api-key-hmac-secret`
|
||||||
|
- On lookup: compute HMAC, query by hash — fast enough for every request (unlike bcrypt)
|
||||||
|
- In-memory cache uses raw key as cache key (never persisted)
|
||||||
|
- During rolling upgrade: dual lookup (HMAC first, then raw as fallback) until all nodes upgraded
|
||||||
|
|
||||||
|
**TURN Secret Encryption (Step 1.15)**
|
||||||
|
- TURN shared secrets encrypted at rest in RQLite using AES-256-GCM
|
||||||
|
- Encryption key derived via HKDF from the cluster secret with purpose string `"turn-encryption"`
|
||||||
|
|
||||||
|
### TLS & Transport
|
||||||
|
|
||||||
|
**InsecureSkipVerify Fix (Step 1.10)**
|
||||||
|
- During node join, TLS verification uses TOFU (Trust On First Use)
|
||||||
|
- Invite token output includes the CA certificate fingerprint (SHA-256)
|
||||||
|
- Joining node verifies the server cert fingerprint matches before proceeding
|
||||||
|
- After join: CA cert stored locally for future connections
|
||||||
|
|
||||||
|
**WebSocket Origin Validation (Step 1.4)**
|
||||||
|
- All WebSocket upgraders validate the `Origin` header against the node's configured domain
|
||||||
|
- Non-browser clients (no Origin header) are still allowed
|
||||||
|
- Prevents cross-site WebSocket hijacking attacks
|
||||||
|
|
||||||
|
### Process Isolation
|
||||||
|
|
||||||
|
**Dedicated User (Step 1.11)**
|
||||||
|
- All services run as the `orama` user (not root)
|
||||||
|
- Caddy and CoreDNS get `AmbientCapabilities=CAP_NET_BIND_SERVICE` for ports 80/443 and 53
|
||||||
|
- WireGuard stays as root (kernel netlink requires it)
|
||||||
|
- vault-guardian already had proper hardening
|
||||||
|
|
||||||
|
**systemd Hardening (Step 1.12)**
|
||||||
|
- All service units include:
|
||||||
|
```ini
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=yes
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
PrivateDevices=yes
|
||||||
|
ProtectKernelTunables=yes
|
||||||
|
ProtectKernelModules=yes
|
||||||
|
RestrictNamespaces=yes
|
||||||
|
ReadWritePaths=/opt/orama/.orama
|
||||||
|
```
|
||||||
|
- Applied to both template files (`pkg/environments/templates/`) and hardcoded unit generators (`pkg/environments/production/services.go`)
|
||||||
|
|
||||||
|
### Supply Chain
|
||||||
|
|
||||||
|
**Binary Signing (Step 1.13)**
|
||||||
|
- Build archives include `manifest.sig` — a rootwallet EVM signature of the manifest hash
|
||||||
|
- During install, the signature is verified against the embedded Orama public key
|
||||||
|
- Unsigned or tampered archives are rejected
|
||||||
|
|
||||||
|
## Phase 2: OramaOS
|
||||||
|
|
||||||
|
These measures apply only to OramaOS nodes (mainnet, devnet, testnet).
|
||||||
|
|
||||||
|
### Immutable OS
|
||||||
|
|
||||||
|
- **Read-only rootfs** — SquashFS with dm-verity integrity verification
|
||||||
|
- **No shell** — `/bin/sh` symlinked to `/bin/false`, no bash/ash/ssh
|
||||||
|
- **No SSH** — OpenSSH not included in the image
|
||||||
|
- **Minimal packages** — only what's needed for systemd, cryptsetup, and the agent
|
||||||
|
|
||||||
|
### Full-Disk Encryption
|
||||||
|
|
||||||
|
- **LUKS2** with AES-XTS-Plain64 on the data partition
|
||||||
|
- **Shamir's Secret Sharing** over GF(256) — LUKS key split across peer vault-guardians
|
||||||
|
- **Adaptive threshold** — K = max(3, N/3) where N is the number of peers
|
||||||
|
- **Key zeroing** — LUKS key wiped from memory immediately after use
|
||||||
|
- **Malicious share detection** — fetch K+1 shares when possible, verify consistency
|
||||||
|
|
||||||
|
### Service Sandboxing
|
||||||
|
|
||||||
|
Each service runs in isolated Linux namespaces:
|
||||||
|
- **CLONE_NEWNS** — mount namespace (filesystem isolation)
|
||||||
|
- **CLONE_NEWUTS** — hostname namespace
|
||||||
|
- **Dedicated UID/GID** — each service has its own user
|
||||||
|
- **Seccomp filtering** — per-service syscall allowlist
|
||||||
|
|
||||||
|
Note: CLONE_NEWPID is intentionally omitted — it makes services PID 1 in their namespace, which changes signal semantics (SIGTERM ignored by default for PID 1).
|
||||||
|
|
||||||
|
### Signed Updates
|
||||||
|
|
||||||
|
- A/B partition scheme with systemd-boot and boot counting (`tries_left=3`)
|
||||||
|
- All updates signed with rootwallet EVM signature (secp256k1 + keccak256)
|
||||||
|
- Signer address: `0xb5d8a496c8b2412990d7D467E17727fdF5954afC`
|
||||||
|
- P2P distribution over WireGuard between nodes
|
||||||
|
- Automatic rollback on 3 consecutive boot failures
|
||||||
|
|
||||||
|
### Zero Operator Access
|
||||||
|
|
||||||
|
- Operators cannot read data on the machine (LUKS encrypted, no shell)
|
||||||
|
- Management only through Gateway API → agent over WireGuard
|
||||||
|
- All commands are logged and auditable
|
||||||
|
- No root access, no console access, no file system access
|
||||||
|
|
||||||
|
## Rollout Strategy
|
||||||
|
|
||||||
|
### Phase 1 Batches
|
||||||
|
|
||||||
|
```
|
||||||
|
Batch 1 (zero-risk, no restart):
|
||||||
|
- CIDR fix
|
||||||
|
- IPv6 disable
|
||||||
|
- Internal endpoint auth
|
||||||
|
- WebSocket origin check
|
||||||
|
|
||||||
|
Batch 2 (medium-risk, restart needed):
|
||||||
|
- Hash refresh tokens
|
||||||
|
- Hash API keys
|
||||||
|
- Binary signing
|
||||||
|
- Vault V1 auth enforcement
|
||||||
|
- TURN secret encryption
|
||||||
|
|
||||||
|
Batch 3 (high-risk, coordinated rollout):
|
||||||
|
- RQLite auth (followers first, leader last)
|
||||||
|
- Olric encryption (simultaneous restart)
|
||||||
|
- IPFS Cluster TrustedPeers
|
||||||
|
|
||||||
|
Batch 4 (infrastructure changes):
|
||||||
|
- InsecureSkipVerify fix
|
||||||
|
- Dedicated user
|
||||||
|
- systemd hardening
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 2
|
||||||
|
|
||||||
|
1. Build and test OramaOS image in QEMU
|
||||||
|
2. Deploy to sandbox cluster alongside Ubuntu nodes
|
||||||
|
3. Verify interop and stability
|
||||||
|
4. Gradual migration: testnet → devnet → mainnet (one node at a time, maintaining Raft quorum)
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
All changes verified on sandbox cluster before production deployment:
|
||||||
|
|
||||||
|
- `make test` — all unit tests pass
|
||||||
|
- `orama monitor report --env sandbox` — full cluster health
|
||||||
|
- Manual endpoint testing (e.g., curl without auth → 401)
|
||||||
|
- Security-specific checks (IPv6 listeners, RQLite auth, binary signatures)
|
||||||
374
core/docs/SERVERLESS.md
Normal file
374
core/docs/SERVERLESS.md
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
# Serverless Functions
|
||||||
|
|
||||||
|
Orama Network runs serverless functions as sandboxed WebAssembly (WASM) modules. Functions are written in Go, compiled to WASM with TinyGo, and executed in an isolated wazero runtime with configurable memory limits and timeouts.
|
||||||
|
|
||||||
|
Functions receive input via **stdin** (JSON) and return output via **stdout** (JSON). They can also access Orama services — database, cache, storage, secrets, PubSub, and HTTP — through **host functions** injected by the runtime.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Scaffold a new function
|
||||||
|
orama function init my-function
|
||||||
|
|
||||||
|
# 2. Edit your handler
|
||||||
|
cd my-function
|
||||||
|
# edit function.go
|
||||||
|
|
||||||
|
# 3. Build to WASM
|
||||||
|
orama function build
|
||||||
|
|
||||||
|
# 4. Deploy
|
||||||
|
orama function deploy
|
||||||
|
|
||||||
|
# 5. Invoke
|
||||||
|
orama function invoke my-function --data '{"name": "World"}'
|
||||||
|
|
||||||
|
# 6. View logs
|
||||||
|
orama function logs my-function
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
my-function/
|
||||||
|
├── function.go # Handler code
|
||||||
|
└── function.yaml # Configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
### function.yaml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: my-function # Required. Letters, digits, hyphens, underscores.
|
||||||
|
public: false # Allow unauthenticated invocation (default: false)
|
||||||
|
memory: 64 # Memory limit in MB (1-256, default: 64)
|
||||||
|
timeout: 30 # Execution timeout in seconds (1-300, default: 30)
|
||||||
|
retry:
|
||||||
|
count: 0 # Retry attempts on failure (default: 0)
|
||||||
|
delay: 5 # Seconds between retries (default: 5)
|
||||||
|
env: # Environment variables (accessible via get_env)
|
||||||
|
MY_VAR: "value"
|
||||||
|
```
|
||||||
|
|
||||||
|
### function.go (minimal)
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Read JSON input from stdin
|
||||||
|
var input []byte
|
||||||
|
buf := make([]byte, 4096)
|
||||||
|
for {
|
||||||
|
n, err := os.Stdin.Read(buf)
|
||||||
|
if n > 0 {
|
||||||
|
input = append(input, buf[:n]...)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var payload map[string]interface{}
|
||||||
|
json.Unmarshal(input, &payload)
|
||||||
|
|
||||||
|
// Process and return JSON output via stdout
|
||||||
|
response := map[string]interface{}{
|
||||||
|
"result": "Hello!",
|
||||||
|
}
|
||||||
|
output, _ := json.Marshal(response)
|
||||||
|
os.Stdout.Write(output)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
Functions are compiled to WASM using [TinyGo](https://tinygo.org/):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Using the CLI (recommended)
|
||||||
|
orama function build
|
||||||
|
|
||||||
|
# Or manually
|
||||||
|
tinygo build -o function.wasm -target wasi function.go
|
||||||
|
```
|
||||||
|
|
||||||
|
## Host Functions API
|
||||||
|
|
||||||
|
Host functions let your WASM code interact with Orama services. They are imported from the `"env"` or `"host"` module (both work) and use a pointer/length ABI for string parameters.
|
||||||
|
|
||||||
|
All host functions are registered at runtime by the engine. They are available to every function without additional configuration.
|
||||||
|
|
||||||
|
### Context
|
||||||
|
|
||||||
|
| Function | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `get_caller_wallet()` → string | Wallet address of the caller (from JWT) |
|
||||||
|
| `get_request_id()` → string | Unique invocation ID |
|
||||||
|
| `get_env(key)` → string | Environment variable from function.yaml |
|
||||||
|
| `get_secret(name)` → string | Decrypted secret value (see [Managing Secrets](#managing-secrets)) |
|
||||||
|
|
||||||
|
### Database (RQLite)
|
||||||
|
|
||||||
|
| Function | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `db_query(sql, argsJSON)` → JSON | Execute SELECT query. Args as JSON array. Returns JSON array of row objects. |
|
||||||
|
| `db_execute(sql, argsJSON)` → int | Execute INSERT/UPDATE/DELETE. Returns affected row count. |
|
||||||
|
|
||||||
|
Example query from WASM:
|
||||||
|
```
|
||||||
|
db_query("SELECT push_token, device_type FROM devices WHERE user_id = ?", '["user123"]')
|
||||||
|
→ [{"push_token": "abc...", "device_type": "ios"}]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cache (Olric Distributed Cache)
|
||||||
|
|
||||||
|
| Function | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `cache_get(key)` → bytes | Get cached value by key. Returns empty on miss. |
|
||||||
|
| `cache_set(key, value, ttl)` | Store value with TTL in seconds. |
|
||||||
|
| `cache_incr(key)` → int64 | Atomically increment by 1 (init to 0 if missing). |
|
||||||
|
| `cache_incr_by(key, delta)` → int64 | Atomically increment by delta. |
|
||||||
|
|
||||||
|
### HTTP
|
||||||
|
|
||||||
|
| Function | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `http_fetch(method, url, headersJSON, body)` → JSON | Make outbound HTTP request. Headers as JSON object. Returns `{"status": 200, "headers": {...}, "body": "..."}`. Timeout: 30s. |
|
||||||
|
|
||||||
|
### PubSub
|
||||||
|
|
||||||
|
| Function | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `pubsub_publish(topic, dataJSON)` → bool | Publish message to a PubSub topic. Returns true on success. |
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
| Function | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `log_info(message)` | Log info-level message (captured in invocation logs). |
|
||||||
|
| `log_error(message)` | Log error-level message. |
|
||||||
|
|
||||||
|
## Managing Secrets
|
||||||
|
|
||||||
|
Secrets are encrypted at rest (AES-256-GCM) and scoped to your namespace. Functions read them via `get_secret("name")` at runtime.
|
||||||
|
|
||||||
|
### CLI Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Set a secret (inline value)
|
||||||
|
orama function secrets set APNS_KEY_ID "ABC123DEF"
|
||||||
|
|
||||||
|
# Set a secret from a file (useful for PEM keys, certificates)
|
||||||
|
orama function secrets set APNS_AUTH_KEY --from-file ./AuthKey_ABC123.p8
|
||||||
|
|
||||||
|
# List all secret names (values are never shown)
|
||||||
|
orama function secrets list
|
||||||
|
|
||||||
|
# Delete a secret
|
||||||
|
orama function secrets delete APNS_KEY_ID
|
||||||
|
|
||||||
|
# Delete without confirmation
|
||||||
|
orama function secrets delete APNS_KEY_ID --force
|
||||||
|
```
|
||||||
|
|
||||||
|
### How It Works
|
||||||
|
|
||||||
|
1. **You set secrets** via the CLI → encrypted and stored in the database
|
||||||
|
2. **Functions read secrets** at runtime via `get_secret("name")` → decrypted on demand
|
||||||
|
3. **Namespace isolation** → each namespace has its own secret store; functions in namespace A cannot read secrets from namespace B
|
||||||
|
|
||||||
|
## PubSub Triggers
|
||||||
|
|
||||||
|
Triggers let functions react to events automatically. When a message is published to a PubSub topic, all functions with a trigger on that topic are invoked asynchronously.
|
||||||
|
|
||||||
|
### CLI Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Add a trigger: invoke "call-push-handler" when messages hit "calls:invite"
|
||||||
|
orama function triggers add call-push-handler --topic calls:invite
|
||||||
|
|
||||||
|
# List triggers for a function
|
||||||
|
orama function triggers list call-push-handler
|
||||||
|
|
||||||
|
# Delete a trigger
|
||||||
|
orama function triggers delete call-push-handler <trigger-id>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Trigger Event Payload
|
||||||
|
|
||||||
|
When triggered via PubSub, the function receives this JSON via stdin:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"topic": "calls:invite",
|
||||||
|
"data": { ... },
|
||||||
|
"namespace": "my-namespace",
|
||||||
|
"trigger_depth": 1,
|
||||||
|
"timestamp": 1708972800
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Depth Limiting
|
||||||
|
|
||||||
|
To prevent infinite loops (function A publishes to topic → triggers function A again), trigger depth is tracked. Maximum depth is **5**. If a function's output triggers another function, `trigger_depth` increments. At depth 5, no further triggers fire.
|
||||||
|
|
||||||
|
## Function Lifecycle
|
||||||
|
|
||||||
|
### Versioning
|
||||||
|
|
||||||
|
Each deploy creates a new version. The WASM binary is stored in **IPFS** (content-addressed) and metadata is stored in **RQLite**.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List versions
|
||||||
|
orama function versions my-function
|
||||||
|
|
||||||
|
# Invoke a specific version
|
||||||
|
curl -X POST .../v1/functions/my-function@2/invoke
|
||||||
|
```
|
||||||
|
|
||||||
|
### Invocation Logging
|
||||||
|
|
||||||
|
Every invocation is logged with: request ID, duration, status (success/error/timeout), input/output size, and any `log_info`/`log_error` messages.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
orama function logs my-function
|
||||||
|
```
|
||||||
|
|
||||||
|
## CLI Reference
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `orama function init <name>` | Scaffold a new function project |
|
||||||
|
| `orama function build [dir]` | Compile Go to WASM |
|
||||||
|
| `orama function deploy [dir]` | Deploy WASM to the network |
|
||||||
|
| `orama function invoke <name> --data <json>` | Invoke a function |
|
||||||
|
| `orama function list` | List deployed functions |
|
||||||
|
| `orama function get <name>` | Get function details |
|
||||||
|
| `orama function delete <name>` | Delete a function |
|
||||||
|
| `orama function logs <name>` | View invocation logs |
|
||||||
|
| `orama function versions <name>` | List function versions |
|
||||||
|
| `orama function secrets set <name> <value>` | Set an encrypted secret |
|
||||||
|
| `orama function secrets list` | List secret names |
|
||||||
|
| `orama function secrets delete <name>` | Delete a secret |
|
||||||
|
| `orama function triggers add <fn> --topic <t>` | Add PubSub trigger |
|
||||||
|
| `orama function triggers list <fn>` | List triggers |
|
||||||
|
| `orama function triggers delete <fn> <id>` | Delete a trigger |
|
||||||
|
|
||||||
|
## HTTP API Reference
|
||||||
|
|
||||||
|
| Method | Endpoint | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| POST | `/v1/functions` | Deploy function (multipart/form-data) |
|
||||||
|
| GET | `/v1/functions` | List functions |
|
||||||
|
| GET | `/v1/functions/{name}` | Get function info |
|
||||||
|
| DELETE | `/v1/functions/{name}` | Delete function |
|
||||||
|
| POST | `/v1/functions/{name}/invoke` | Invoke function |
|
||||||
|
| GET | `/v1/functions/{name}/versions` | List versions |
|
||||||
|
| GET | `/v1/functions/{name}/logs` | Get logs |
|
||||||
|
| WS | `/v1/functions/{name}/ws` | WebSocket invoke (streaming) |
|
||||||
|
| PUT | `/v1/functions/secrets` | Set a secret |
|
||||||
|
| GET | `/v1/functions/secrets` | List secret names |
|
||||||
|
| DELETE | `/v1/functions/secrets/{name}` | Delete a secret |
|
||||||
|
| POST | `/v1/functions/{name}/triggers` | Add PubSub trigger |
|
||||||
|
| GET | `/v1/functions/{name}/triggers` | List triggers |
|
||||||
|
| DELETE | `/v1/functions/{name}/triggers/{id}` | Delete trigger |
|
||||||
|
| POST | `/v1/invoke/{namespace}/{name}` | Direct invoke (alt endpoint) |
|
||||||
|
|
||||||
|
## Example: Call Push Handler
|
||||||
|
|
||||||
|
A real-world function that sends VoIP push notifications when a call invite is published to PubSub:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# function.yaml
|
||||||
|
name: call-push-handler
|
||||||
|
memory: 128
|
||||||
|
timeout: 30
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// function.go — triggered by PubSub on "calls:invite"
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This function:
|
||||||
|
// 1. Receives a call invite event from PubSub trigger
|
||||||
|
// 2. Queries the database for the callee's device info
|
||||||
|
// 3. Reads push notification credentials from secrets
|
||||||
|
// 4. Sends a push notification via http_fetch
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Read PubSub trigger event from stdin
|
||||||
|
var input []byte
|
||||||
|
buf := make([]byte, 4096)
|
||||||
|
for {
|
||||||
|
n, err := os.Stdin.Read(buf)
|
||||||
|
if n > 0 {
|
||||||
|
input = append(input, buf[:n]...)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the trigger event wrapper
|
||||||
|
var event struct {
|
||||||
|
Topic string `json:"topic"`
|
||||||
|
Data json.RawMessage `json:"data"`
|
||||||
|
}
|
||||||
|
json.Unmarshal(input, &event)
|
||||||
|
|
||||||
|
// Parse the actual call invite data
|
||||||
|
var invite struct {
|
||||||
|
CalleeID string `json:"calleeId"`
|
||||||
|
CallerName string `json:"callerName"`
|
||||||
|
CallType string `json:"callType"`
|
||||||
|
}
|
||||||
|
json.Unmarshal(event.Data, &invite)
|
||||||
|
|
||||||
|
// At this point, the function would use host functions:
|
||||||
|
//
|
||||||
|
// 1. db_query("SELECT push_token, device_type FROM devices WHERE user_id = ?",
|
||||||
|
// json.Marshal([]string{invite.CalleeID}))
|
||||||
|
//
|
||||||
|
// 2. get_secret("FCM_SERVER_KEY") for Android push
|
||||||
|
// get_secret("APNS_KEY_PEM") for iOS push
|
||||||
|
//
|
||||||
|
// 3. http_fetch("POST", "https://fcm.googleapis.com/v1/...", headers, body)
|
||||||
|
//
|
||||||
|
// 4. log_info("Push sent to " + invite.CalleeID)
|
||||||
|
//
|
||||||
|
// Note: Host functions use the WASM ABI (pointer/length).
|
||||||
|
// A Go SDK for ergonomic access is planned.
|
||||||
|
|
||||||
|
response := map[string]interface{}{
|
||||||
|
"status": "sent",
|
||||||
|
"callee": invite.CalleeID,
|
||||||
|
}
|
||||||
|
output, _ := json.Marshal(response)
|
||||||
|
os.Stdout.Write(output)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy and wire the trigger:
|
||||||
|
```bash
|
||||||
|
orama function build
|
||||||
|
orama function deploy
|
||||||
|
|
||||||
|
# Set push notification secrets
|
||||||
|
orama function secrets set FCM_SERVER_KEY "your-fcm-key"
|
||||||
|
orama function secrets set APNS_KEY_PEM --from-file ./AuthKey.p8
|
||||||
|
orama function secrets set APNS_KEY_ID "ABC123"
|
||||||
|
orama function secrets set APNS_TEAM_ID "TEAM456"
|
||||||
|
|
||||||
|
# Wire the PubSub trigger
|
||||||
|
orama function triggers add call-push-handler --topic calls:invite
|
||||||
|
```
|
||||||
291
core/docs/WEBRTC.md
Normal file
291
core/docs/WEBRTC.md
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
# WebRTC Integration
|
||||||
|
|
||||||
|
Real-time voice, video, and data channels for Orama Network namespaces.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
Client A Client B
|
||||||
|
│ │
|
||||||
|
│ 1. Get TURN credentials (REST) │
|
||||||
|
│ 2. Connect WebSocket (signaling) │
|
||||||
|
│ 3. Exchange SDP/ICE via SFU │
|
||||||
|
│ │
|
||||||
|
▼ ▼
|
||||||
|
┌──────────┐ UDP relay ┌──────────┐
|
||||||
|
│ TURN │◄──────────────────►│ TURN │
|
||||||
|
│ Server │ (public IPs) │ Server │
|
||||||
|
│ Node 1 │ │ Node 2 │
|
||||||
|
└────┬─────┘ └────┬─────┘
|
||||||
|
│ WireGuard │ WireGuard
|
||||||
|
▼ ▼
|
||||||
|
┌──────────────────────────────────────────┐
|
||||||
|
│ SFU Servers (3 nodes) │
|
||||||
|
│ - WebSocket signaling (WireGuard only) │
|
||||||
|
│ - Pion WebRTC (RTP forwarding) │
|
||||||
|
│ - Room management │
|
||||||
|
│ - Track publish/subscribe │
|
||||||
|
└──────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key design decisions:**
|
||||||
|
- **TURN-shielded**: SFU binds only to WireGuard IPs. All client media flows through TURN relay.
|
||||||
|
- **`iceTransportPolicy: relay`** enforced server-side — no direct peer connections.
|
||||||
|
- **Opt-in per namespace** via `orama namespace enable webrtc`.
|
||||||
|
- **SFU on all 3 nodes**, **TURN on 2 of 3 nodes** (redundancy without over-provisioning).
|
||||||
|
- **Separate port allocation** from existing namespace services.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Namespace must be provisioned with a ready cluster (RQLite + Olric + Gateway running).
|
||||||
|
- Command must be run on a cluster node (uses internal gateway endpoint).
|
||||||
|
|
||||||
|
## Enable / Disable
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable WebRTC for a namespace
|
||||||
|
orama namespace enable webrtc --namespace myapp
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
orama namespace webrtc-status --namespace myapp
|
||||||
|
|
||||||
|
# Disable WebRTC (stops services, deallocates ports, removes DNS)
|
||||||
|
orama namespace disable webrtc --namespace myapp
|
||||||
|
```
|
||||||
|
|
||||||
|
### What happens on enable:
|
||||||
|
1. Generates a per-namespace TURN shared secret (32 bytes, crypto/rand)
|
||||||
|
2. Inserts `namespace_webrtc_config` DB record
|
||||||
|
3. Allocates WebRTC port blocks on each node (SFU signaling + media range, TURN relay range)
|
||||||
|
4. Spawns TURN on 2 nodes (selected by capacity)
|
||||||
|
5. Spawns SFU on all 3 nodes
|
||||||
|
6. Creates DNS A records: `turn.ns-{name}.{baseDomain}` pointing to TURN node public IPs
|
||||||
|
7. Updates cluster state on all nodes (for cold-boot restoration)
|
||||||
|
|
||||||
|
### What happens on disable:
|
||||||
|
1. Stops SFU on all 3 nodes
|
||||||
|
2. Stops TURN on 2 nodes
|
||||||
|
3. Deallocates all WebRTC ports
|
||||||
|
4. Deletes TURN DNS records
|
||||||
|
5. Cleans up DB records (`namespace_webrtc_config`, `webrtc_rooms`)
|
||||||
|
6. Updates cluster state
|
||||||
|
|
||||||
|
## Client Integration (JavaScript)
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
|
All WebRTC endpoints require authentication. Use one of:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Option A: API Key via header (recommended)
|
||||||
|
X-API-Key: <your-namespace-api-key>
|
||||||
|
|
||||||
|
# Option B: API Key via Authorization header
|
||||||
|
Authorization: ApiKey <your-namespace-api-key>
|
||||||
|
|
||||||
|
# Option C: JWT Bearer token
|
||||||
|
Authorization: Bearer <jwt>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1. Get TURN Credentials
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const response = await fetch('https://ns-myapp.orama-devnet.network/v1/webrtc/turn/credentials', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'X-API-Key': apiKey }
|
||||||
|
});
|
||||||
|
|
||||||
|
const { uris, username, password, ttl } = await response.json();
|
||||||
|
// uris: [
|
||||||
|
// "turn:turn.ns-myapp.orama-devnet.network:3478?transport=udp",
|
||||||
|
// "turn:turn.ns-myapp.orama-devnet.network:3478?transport=tcp",
|
||||||
|
// "turns:turn.ns-myapp.orama-devnet.network:5349"
|
||||||
|
// ]
|
||||||
|
// username: "{expiry_unix}:{namespace}"
|
||||||
|
// password: HMAC-SHA1 derived (base64)
|
||||||
|
// ttl: 600 (seconds)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Create PeerConnection
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const pc = new RTCPeerConnection({
|
||||||
|
iceServers: [{ urls: uris, username, credential: password }],
|
||||||
|
iceTransportPolicy: 'relay' // enforced by SFU
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Connect Signaling WebSocket
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const ws = new WebSocket(
|
||||||
|
`wss://ns-myapp.orama-devnet.network/v1/webrtc/signal?room=${roomId}&api_key=${apiKey}`
|
||||||
|
);
|
||||||
|
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
const msg = JSON.parse(event.data);
|
||||||
|
switch (msg.type) {
|
||||||
|
case 'offer': handleOffer(msg); break;
|
||||||
|
case 'answer': handleAnswer(msg); break;
|
||||||
|
case 'ice-candidate': handleICE(msg); break;
|
||||||
|
case 'peer-joined': handleJoin(msg); break;
|
||||||
|
case 'peer-left': handleLeave(msg); break;
|
||||||
|
case 'turn-credentials':
|
||||||
|
case 'refresh-credentials':
|
||||||
|
updateTURN(msg); // SFU sends refreshed creds at 80% TTL
|
||||||
|
break;
|
||||||
|
case 'server-draining':
|
||||||
|
reconnect(); // SFU shutting down, reconnect to another node
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Room Management (REST)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const headers = { 'X-API-Key': apiKey, 'Content-Type': 'application/json' };
|
||||||
|
|
||||||
|
// Create room
|
||||||
|
await fetch('/v1/webrtc/rooms', {
|
||||||
|
method: 'POST',
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify({ room_id: 'my-room' })
|
||||||
|
});
|
||||||
|
|
||||||
|
// List rooms
|
||||||
|
const rooms = await fetch('/v1/webrtc/rooms', { headers });
|
||||||
|
|
||||||
|
// Close room
|
||||||
|
await fetch('/v1/webrtc/rooms?room_id=my-room', {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### REST Endpoints
|
||||||
|
|
||||||
|
| Method | Path | Auth | Description |
|
||||||
|
|--------|------|------|-------------|
|
||||||
|
| POST | `/v1/webrtc/turn/credentials` | JWT/API key | Get TURN relay credentials |
|
||||||
|
| GET/WS | `/v1/webrtc/signal` | JWT/API key | WebSocket signaling |
|
||||||
|
| GET | `/v1/webrtc/rooms` | JWT/API key | List rooms |
|
||||||
|
| POST | `/v1/webrtc/rooms` | JWT/API key (owner) | Create room |
|
||||||
|
| DELETE | `/v1/webrtc/rooms` | JWT/API key (owner) | Close room |
|
||||||
|
|
||||||
|
### Signaling Messages
|
||||||
|
|
||||||
|
| Type | Direction | Description |
|
||||||
|
|------|-----------|-------------|
|
||||||
|
| `join` | Client → SFU | Join room |
|
||||||
|
| `offer` | Client ↔ SFU | SDP offer |
|
||||||
|
| `answer` | Client ↔ SFU | SDP answer |
|
||||||
|
| `ice-candidate` | Client ↔ SFU | ICE candidate |
|
||||||
|
| `leave` | Client → SFU | Leave room |
|
||||||
|
| `peer-joined` | SFU → Client | New peer notification |
|
||||||
|
| `peer-left` | SFU → Client | Peer departure |
|
||||||
|
| `turn-credentials` | SFU → Client | Initial TURN credentials |
|
||||||
|
| `refresh-credentials` | SFU → Client | Refreshed credentials (at 80% TTL) |
|
||||||
|
| `server-draining` | SFU → Client | SFU shutting down |
|
||||||
|
|
||||||
|
## Port Allocation
|
||||||
|
|
||||||
|
WebRTC uses a **separate port allocation system** from the core namespace ports:
|
||||||
|
|
||||||
|
| Service | Port Range | Protocol | Per Namespace |
|
||||||
|
|---------|-----------|----------|---------------|
|
||||||
|
| SFU signaling | 30000-30099 | TCP (WireGuard only) | 1 port |
|
||||||
|
| SFU media (RTP) | 20000-29999 | UDP (WireGuard only) | 500 ports |
|
||||||
|
| TURN listen | 3478 | UDP + TCP | fixed |
|
||||||
|
| TURNS (TLS) | 5349 | TCP | fixed |
|
||||||
|
| TURN relay | 49152-65535 | UDP | 800 ports |
|
||||||
|
|
||||||
|
## TURN Credential Protocol
|
||||||
|
|
||||||
|
- Credentials use HMAC-SHA1 with a per-namespace shared secret
|
||||||
|
- Username format: `{expiry_unix}:{namespace}`
|
||||||
|
- Password: `base64(HMAC-SHA1(shared_secret, username))`
|
||||||
|
- Default TTL: 600 seconds (10 minutes)
|
||||||
|
- SFU proactively sends `refresh-credentials` at 80% of TTL (8 minutes)
|
||||||
|
- Clients should update ICE servers on receiving refresh
|
||||||
|
|
||||||
|
## TURNS TLS Certificate
|
||||||
|
|
||||||
|
TURNS (port 5349) uses TLS. Certificate provisioning:
|
||||||
|
|
||||||
|
1. **Let's Encrypt (primary)**: On TURN spawn, the TURN domain is added to the local Caddy instance's Caddyfile. Caddy provisions a Let's Encrypt cert via DNS-01 ACME challenge (using the orama DNS provider). TURN reads the cert from Caddy's storage.
|
||||||
|
2. **Self-signed (fallback)**: If Caddy cert provisioning fails (timeout, Caddy not running), a self-signed cert is generated with the node's public IP as SAN.
|
||||||
|
|
||||||
|
Caddy auto-renews Let's Encrypt certs at ~60 days. TURN picks up renewed certs on restart.
|
||||||
|
|
||||||
|
## Monitoring
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check WebRTC status
|
||||||
|
orama namespace webrtc-status --namespace myapp
|
||||||
|
|
||||||
|
# Monitor report includes SFU/TURN status
|
||||||
|
orama monitor report --env devnet
|
||||||
|
|
||||||
|
# Inspector checks WebRTC health
|
||||||
|
orama inspector --env devnet
|
||||||
|
```
|
||||||
|
|
||||||
|
The monitoring report includes per-namespace `sfu_up` and `turn_up` fields. The inspector runs cross-node checks to verify SFU coverage (3 nodes) and TURN redundancy (2 nodes).
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# SFU logs
|
||||||
|
journalctl -u orama-namespace-sfu@myapp -f
|
||||||
|
|
||||||
|
# TURN logs
|
||||||
|
journalctl -u orama-namespace-turn@myapp -f
|
||||||
|
|
||||||
|
# Check service status
|
||||||
|
systemctl status orama-namespace-sfu@myapp
|
||||||
|
systemctl status orama-namespace-turn@myapp
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Model
|
||||||
|
|
||||||
|
- **Forced relay**: `iceTransportPolicy: relay` enforced server-side. Clients cannot bypass TURN.
|
||||||
|
- **HMAC credentials**: Per-namespace TURN shared secret. Credentials expire after 10 minutes.
|
||||||
|
- **Namespace isolation**: Each namespace has its own TURN secret, port ranges, and rooms.
|
||||||
|
- **Authentication required**: All WebRTC endpoints require API key or JWT (`X-API-Key` header, `Authorization: ApiKey`, or `Authorization: Bearer`).
|
||||||
|
- **Room management**: Creating/closing rooms requires namespace ownership.
|
||||||
|
- **SFU on WireGuard only**: SFU binds to 10.0.0.x, never 0.0.0.0. Only reachable via TURN relay.
|
||||||
|
- **Permissions-Policy**: `camera=(self), microphone=(self)` — only same-origin can access media devices.
|
||||||
|
|
||||||
|
## Firewall
|
||||||
|
|
||||||
|
When WebRTC is enabled, the following ports are opened via UFW on TURN nodes:
|
||||||
|
|
||||||
|
| Port | Protocol | Purpose |
|
||||||
|
|------|----------|---------|
|
||||||
|
| 3478 | UDP | TURN standard |
|
||||||
|
| 3478 | TCP | TURN TCP fallback (for clients behind UDP-blocking firewalls) |
|
||||||
|
| 5349 | TCP | TURNS — TURN over TLS (encrypted, works through strict firewalls/DPI) |
|
||||||
|
| 49152-65535 | UDP | TURN relay range (allocated per namespace) |
|
||||||
|
|
||||||
|
SFU ports are NOT opened in the firewall — they are WireGuard-internal only.
|
||||||
|
|
||||||
|
## Database Tables
|
||||||
|
|
||||||
|
| Table | Purpose |
|
||||||
|
|-------|---------|
|
||||||
|
| `namespace_webrtc_config` | Per-namespace WebRTC config (enabled, TURN secret, node counts) |
|
||||||
|
| `webrtc_rooms` | Room-to-SFU-node affinity |
|
||||||
|
| `webrtc_port_allocations` | SFU/TURN port tracking |
|
||||||
|
|
||||||
|
## Cold Boot Recovery
|
||||||
|
|
||||||
|
On node restart, the cluster state file (`cluster_state.json`) includes `has_sfu`, `has_turn`, and port allocation data. The restore process:
|
||||||
|
|
||||||
|
1. Core services restore first: RQLite → Olric → Gateway
|
||||||
|
2. If `has_turn` is set: fetches TURN shared secret from DB, spawns TURN
|
||||||
|
3. If `has_sfu` is set: fetches WebRTC config from DB, spawns SFU with TURN server list
|
||||||
|
|
||||||
|
If the DB is unavailable during restore, SFU/TURN restoration is skipped with a warning log. They will be restored on the next successful DB connection.
|
||||||
@ -5,7 +5,6 @@ package e2e
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
@ -37,10 +36,10 @@ type ServerConfig struct {
|
|||||||
IsNameserver bool `yaml:"is_nameserver"`
|
IsNameserver bool `yaml:"is_nameserver"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultConfig returns the default configuration for local development
|
// DefaultConfig returns the default configuration
|
||||||
func DefaultConfig() *E2EConfig {
|
func DefaultConfig() *E2EConfig {
|
||||||
return &E2EConfig{
|
return &E2EConfig{
|
||||||
Mode: "local",
|
Mode: "production",
|
||||||
BaseDomain: "orama.network",
|
BaseDomain: "orama.network",
|
||||||
Servers: []ServerConfig{},
|
Servers: []ServerConfig{},
|
||||||
Nameservers: []string{},
|
Nameservers: []string{},
|
||||||
@ -94,7 +93,7 @@ func LoadE2EConfig() (*E2EConfig, error) {
|
|||||||
|
|
||||||
// Apply defaults for empty values
|
// Apply defaults for empty values
|
||||||
if cfg.Mode == "" {
|
if cfg.Mode == "" {
|
||||||
cfg.Mode = "local"
|
cfg.Mode = "production"
|
||||||
}
|
}
|
||||||
if cfg.BaseDomain == "" {
|
if cfg.BaseDomain == "" {
|
||||||
cfg.BaseDomain = "orama.network"
|
cfg.BaseDomain = "orama.network"
|
||||||
@ -117,29 +116,6 @@ func IsProductionMode() bool {
|
|||||||
return cfg.Mode == "production"
|
return cfg.Mode == "production"
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLocalMode returns true if running in local mode
|
|
||||||
func IsLocalMode() bool {
|
|
||||||
return !IsProductionMode()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SkipIfLocal skips the test if running in local mode
|
|
||||||
// Use this for tests that require real production infrastructure
|
|
||||||
func SkipIfLocal(t *testing.T) {
|
|
||||||
t.Helper()
|
|
||||||
if IsLocalMode() {
|
|
||||||
t.Skip("Skipping: requires production environment (set mode: production in e2e/config.yaml)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SkipIfProduction skips the test if running in production mode
|
|
||||||
// Use this for tests that should only run locally
|
|
||||||
func SkipIfProduction(t *testing.T) {
|
|
||||||
t.Helper()
|
|
||||||
if IsProductionMode() {
|
|
||||||
t.Skip("Skipping: local-only test")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetServerIPs returns a list of all server IP addresses from config
|
// GetServerIPs returns a list of all server IP addresses from config
|
||||||
func GetServerIPs(cfg *E2EConfig) []string {
|
func GetServerIPs(cfg *E2EConfig) []string {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
@ -120,8 +120,6 @@ func TestDynamicReplica_CreatedOnDeploy(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Dynamic app served from both nodes", func(t *testing.T) {
|
t.Run("Dynamic app served from both nodes", func(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
if len(env.Config.Servers) < 2 {
|
if len(env.Config.Servers) < 2 {
|
||||||
t.Skip("Requires at least 2 servers")
|
t.Skip("Requires at least 2 servers")
|
||||||
}
|
}
|
||||||
@ -147,7 +145,6 @@ func TestDynamicReplica_CreatedOnDeploy(t *testing.T) {
|
|||||||
func TestReplica_UpdatePropagation(t *testing.T) {
|
func TestReplica_UpdatePropagation(t *testing.T) {
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err, "Failed to load test environment")
|
require.NoError(t, err, "Failed to load test environment")
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
if len(env.Config.Servers) < 2 {
|
if len(env.Config.Servers) < 2 {
|
||||||
t.Skip("Requires at least 2 servers")
|
t.Skip("Requires at least 2 servers")
|
||||||
@ -202,7 +199,6 @@ func TestReplica_UpdatePropagation(t *testing.T) {
|
|||||||
func TestReplica_RollbackPropagation(t *testing.T) {
|
func TestReplica_RollbackPropagation(t *testing.T) {
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err, "Failed to load test environment")
|
require.NoError(t, err, "Failed to load test environment")
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
if len(env.Config.Servers) < 2 {
|
if len(env.Config.Servers) < 2 {
|
||||||
t.Skip("Requires at least 2 servers")
|
t.Skip("Requires at least 2 servers")
|
||||||
@ -259,7 +255,6 @@ func TestReplica_RollbackPropagation(t *testing.T) {
|
|||||||
func TestReplica_TeardownOnDelete(t *testing.T) {
|
func TestReplica_TeardownOnDelete(t *testing.T) {
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err, "Failed to load test environment")
|
require.NoError(t, err, "Failed to load test environment")
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
if len(env.Config.Servers) < 2 {
|
if len(env.Config.Servers) < 2 {
|
||||||
t.Skip("Requires at least 2 servers")
|
t.Skip("Requires at least 2 servers")
|
||||||
@ -277,8 +277,8 @@ func GetGatewayURL() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default fallback
|
// Fallback to devnet
|
||||||
return "http://localhost:6001"
|
return "https://orama-devnet.network"
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRQLiteNodes returns rqlite endpoint addresses from config
|
// GetRQLiteNodes returns rqlite endpoint addresses from config
|
||||||
@ -290,32 +290,14 @@ func GetRQLiteNodes() []string {
|
|||||||
}
|
}
|
||||||
cacheMutex.RUnlock()
|
cacheMutex.RUnlock()
|
||||||
|
|
||||||
// Try all node config files
|
// No fallback — require explicit configuration via RQLITE_NODES env var
|
||||||
for _, cfgFile := range []string{"node-1.yaml", "node-2.yaml", "node-3.yaml", "node-4.yaml", "node-5.yaml"} {
|
return nil
|
||||||
nodeCfg, err := loadNodeConfig(cfgFile)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if db, ok := nodeCfg["database"].(map[interface{}]interface{}); ok {
|
|
||||||
if rqlitePort, ok := db["rqlite_port"].(int); ok {
|
|
||||||
nodes := []string{fmt.Sprintf("http://localhost:%d", rqlitePort)}
|
|
||||||
cacheMutex.Lock()
|
|
||||||
rqliteCache = nodes
|
|
||||||
cacheMutex.Unlock()
|
|
||||||
return nodes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default fallback
|
|
||||||
return []string{"http://localhost:5001"}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// queryAPIKeyFromRQLite queries the SQLite database directly for an API key
|
// queryAPIKeyFromRQLite queries the SQLite database directly for an API key
|
||||||
func queryAPIKeyFromRQLite() (string, error) {
|
func queryAPIKeyFromRQLite() (string, error) {
|
||||||
// 1. Check environment variable first
|
// 1. Check environment variable first
|
||||||
if envKey := os.Getenv("DEBROS_API_KEY"); envKey != "" {
|
if envKey := os.Getenv("ORAMA_API_KEY"); envKey != "" {
|
||||||
return envKey, nil
|
return envKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,21 +310,14 @@ func queryAPIKeyFromRQLite() (string, error) {
|
|||||||
// Fall through to local database check if remote fails
|
// Fall through to local database check if remote fails
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Build database path from bootstrap/node config (for local development)
|
// 3. Build database path from node config
|
||||||
homeDir, err := os.UserHomeDir()
|
homeDir, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to get home directory: %w", err)
|
return "", fmt.Errorf("failed to get home directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try all node data directories (both production and development paths)
|
// Production paths (~/.orama/data/node-x/...)
|
||||||
dbPaths := []string{
|
dbPaths := []string{
|
||||||
// Development paths (~/.orama/node-x/...)
|
|
||||||
filepath.Join(homeDir, ".orama", "node-1", "rqlite", "db.sqlite"),
|
|
||||||
filepath.Join(homeDir, ".orama", "node-2", "rqlite", "db.sqlite"),
|
|
||||||
filepath.Join(homeDir, ".orama", "node-3", "rqlite", "db.sqlite"),
|
|
||||||
filepath.Join(homeDir, ".orama", "node-4", "rqlite", "db.sqlite"),
|
|
||||||
filepath.Join(homeDir, ".orama", "node-5", "rqlite", "db.sqlite"),
|
|
||||||
// Production paths (~/.orama/data/node-x/...)
|
|
||||||
filepath.Join(homeDir, ".orama", "data", "node-1", "rqlite", "db.sqlite"),
|
filepath.Join(homeDir, ".orama", "data", "node-1", "rqlite", "db.sqlite"),
|
||||||
filepath.Join(homeDir, ".orama", "data", "node-2", "rqlite", "db.sqlite"),
|
filepath.Join(homeDir, ".orama", "data", "node-2", "rqlite", "db.sqlite"),
|
||||||
filepath.Join(homeDir, ".orama", "data", "node-3", "rqlite", "db.sqlite"),
|
filepath.Join(homeDir, ".orama", "data", "node-3", "rqlite", "db.sqlite"),
|
||||||
@ -449,7 +424,7 @@ func GetAPIKey() string {
|
|||||||
cacheMutex.RUnlock()
|
cacheMutex.RUnlock()
|
||||||
|
|
||||||
// 1. Check env var
|
// 1. Check env var
|
||||||
if envKey := os.Getenv("DEBROS_API_KEY"); envKey != "" {
|
if envKey := os.Getenv("ORAMA_API_KEY"); envKey != "" {
|
||||||
cacheMutex.Lock()
|
cacheMutex.Lock()
|
||||||
apiKeyCache = envKey
|
apiKeyCache = envKey
|
||||||
cacheMutex.Unlock()
|
cacheMutex.Unlock()
|
||||||
@ -556,8 +531,8 @@ func GetIPFSClusterURL() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default fallback
|
// No fallback — require explicit configuration
|
||||||
return "http://localhost:9094"
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIPFSAPIURL returns the IPFS API URL from config
|
// GetIPFSAPIURL returns the IPFS API URL from config
|
||||||
@ -588,8 +563,8 @@ func GetIPFSAPIURL() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default fallback
|
// No fallback — require explicit configuration
|
||||||
return "http://localhost:5001"
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetClientNamespace returns the test client namespace from config
|
// GetClientNamespace returns the test client namespace from config
|
||||||
@ -1213,8 +1188,8 @@ type E2ETestEnv struct {
|
|||||||
GatewayURL string
|
GatewayURL string
|
||||||
APIKey string
|
APIKey string
|
||||||
Namespace string
|
Namespace string
|
||||||
BaseDomain string // Domain for deployment routing (e.g., "dbrs.space")
|
BaseDomain string // Domain for deployment routing (e.g., "dbrs.space")
|
||||||
Config *E2EConfig // Full E2E configuration (for production tests)
|
Config *E2EConfig // Full E2E configuration (for production tests)
|
||||||
HTTPClient *http.Client
|
HTTPClient *http.Client
|
||||||
SkipCleanup bool
|
SkipCleanup bool
|
||||||
}
|
}
|
||||||
@ -1231,11 +1206,6 @@ func LoadTestEnv() (*E2ETestEnv, error) {
|
|||||||
// Load E2E config (for base_domain and production settings)
|
// Load E2E config (for base_domain and production settings)
|
||||||
cfg, err := LoadE2EConfig()
|
cfg, err := LoadE2EConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If config loading fails in production mode, that's an error
|
|
||||||
if IsProductionMode() {
|
|
||||||
return nil, fmt.Errorf("failed to load e2e config: %w", err)
|
|
||||||
}
|
|
||||||
// For local mode, use defaults
|
|
||||||
cfg = DefaultConfig()
|
cfg = DefaultConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,16 +57,16 @@ func TestDomainRouting_BasicRouting(t *testing.T) {
|
|||||||
t.Logf("✓ Standard domain routing works: %s", domain)
|
t.Logf("✓ Standard domain routing works: %s", domain)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Non-debros domain passes through", func(t *testing.T) {
|
t.Run("Non-orama domain passes through", func(t *testing.T) {
|
||||||
// Request with non-debros domain should not route to deployment
|
// Request with non-orama domain should not route to deployment
|
||||||
resp := e2e.TestDeploymentWithHostHeader(t, env, "example.com", "/")
|
resp := e2e.TestDeploymentWithHostHeader(t, env, "example.com", "/")
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
// Should either return 404 or pass to default handler
|
// Should either return 404 or pass to default handler
|
||||||
assert.NotEqual(t, http.StatusOK, resp.StatusCode,
|
assert.NotEqual(t, http.StatusOK, resp.StatusCode,
|
||||||
"Non-debros domain should not route to deployment")
|
"Non-orama domain should not route to deployment")
|
||||||
|
|
||||||
t.Logf("✓ Non-debros domains correctly pass through (status: %d)", resp.StatusCode)
|
t.Logf("✓ Non-orama domains correctly pass through (status: %d)", resp.StatusCode)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("API paths bypass domain routing", func(t *testing.T) {
|
t.Run("API paths bypass domain routing", func(t *testing.T) {
|
||||||
@ -18,8 +18,6 @@ import (
|
|||||||
// TestIPFS_ContentPinnedOnMultipleNodes verifies that deploying a static app
|
// TestIPFS_ContentPinnedOnMultipleNodes verifies that deploying a static app
|
||||||
// makes the IPFS content available across multiple nodes.
|
// makes the IPFS content available across multiple nodes.
|
||||||
func TestIPFS_ContentPinnedOnMultipleNodes(t *testing.T) {
|
func TestIPFS_ContentPinnedOnMultipleNodes(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -19,8 +19,6 @@ import (
|
|||||||
// TestCrossNode_ProxyRouting tests that requests routed through the gateway
|
// TestCrossNode_ProxyRouting tests that requests routed through the gateway
|
||||||
// are served correctly for a deployment.
|
// are served correctly for a deployment.
|
||||||
func TestCrossNode_ProxyRouting(t *testing.T) {
|
func TestCrossNode_ProxyRouting(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err, "Failed to load test environment")
|
require.NoError(t, err, "Failed to load test environment")
|
||||||
|
|
||||||
@ -60,8 +58,6 @@ func TestCrossNode_ProxyRouting(t *testing.T) {
|
|||||||
|
|
||||||
// TestCrossNode_APIConsistency tests that API responses are consistent
|
// TestCrossNode_APIConsistency tests that API responses are consistent
|
||||||
func TestCrossNode_APIConsistency(t *testing.T) {
|
func TestCrossNode_APIConsistency(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err, "Failed to load test environment")
|
require.NoError(t, err, "Failed to load test environment")
|
||||||
|
|
||||||
@ -110,8 +106,6 @@ func TestCrossNode_APIConsistency(t *testing.T) {
|
|||||||
|
|
||||||
// TestCrossNode_DeploymentGetConsistency tests that deployment details are correct
|
// TestCrossNode_DeploymentGetConsistency tests that deployment details are correct
|
||||||
func TestCrossNode_DeploymentGetConsistency(t *testing.T) {
|
func TestCrossNode_DeploymentGetConsistency(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err, "Failed to load test environment")
|
require.NoError(t, err, "Failed to load test environment")
|
||||||
|
|
||||||
@ -22,8 +22,6 @@ import (
|
|||||||
// TestFailover_HomeNodeDown verifies that when the home node's deployment process
|
// TestFailover_HomeNodeDown verifies that when the home node's deployment process
|
||||||
// is down, requests still succeed via the replica node.
|
// is down, requests still succeed via the replica node.
|
||||||
func TestFailover_HomeNodeDown(t *testing.T) {
|
func TestFailover_HomeNodeDown(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -68,8 +66,6 @@ func TestFailover_HomeNodeDown(t *testing.T) {
|
|||||||
// TestFailover_5xxRetry verifies that if one node returns a gateway error,
|
// TestFailover_5xxRetry verifies that if one node returns a gateway error,
|
||||||
// the middleware retries on the next replica.
|
// the middleware retries on the next replica.
|
||||||
func TestFailover_5xxRetry(t *testing.T) {
|
func TestFailover_5xxRetry(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -112,8 +108,6 @@ func TestFailover_5xxRetry(t *testing.T) {
|
|||||||
// TestFailover_CrossNodeProxyTimeout verifies that cross-node proxy fails fast
|
// TestFailover_CrossNodeProxyTimeout verifies that cross-node proxy fails fast
|
||||||
// (within a reasonable timeout) rather than hanging.
|
// (within a reasonable timeout) rather than hanging.
|
||||||
func TestFailover_CrossNodeProxyTimeout(t *testing.T) {
|
func TestFailover_CrossNodeProxyTimeout(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -18,8 +18,6 @@ import (
|
|||||||
|
|
||||||
// TestHTTPS_CertificateValid tests that HTTPS works with a valid certificate
|
// TestHTTPS_CertificateValid tests that HTTPS works with a valid certificate
|
||||||
func TestHTTPS_CertificateValid(t *testing.T) {
|
func TestHTTPS_CertificateValid(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err, "Failed to load test environment")
|
require.NoError(t, err, "Failed to load test environment")
|
||||||
|
|
||||||
@ -86,8 +84,6 @@ func TestHTTPS_CertificateValid(t *testing.T) {
|
|||||||
|
|
||||||
// TestHTTPS_CertificateDetails tests certificate properties
|
// TestHTTPS_CertificateDetails tests certificate properties
|
||||||
func TestHTTPS_CertificateDetails(t *testing.T) {
|
func TestHTTPS_CertificateDetails(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err, "Failed to load test environment")
|
require.NoError(t, err, "Failed to load test environment")
|
||||||
|
|
||||||
@ -152,8 +148,6 @@ func TestHTTPS_CertificateDetails(t *testing.T) {
|
|||||||
|
|
||||||
// TestHTTPS_HTTPRedirect tests that HTTP requests are redirected to HTTPS
|
// TestHTTPS_HTTPRedirect tests that HTTP requests are redirected to HTTPS
|
||||||
func TestHTTPS_HTTPRedirect(t *testing.T) {
|
func TestHTTPS_HTTPRedirect(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err, "Failed to load test environment")
|
require.NoError(t, err, "Failed to load test environment")
|
||||||
|
|
||||||
@ -17,8 +17,6 @@ import (
|
|||||||
// TestMiddleware_NonExistentDeployment verifies that requests to a non-existent
|
// TestMiddleware_NonExistentDeployment verifies that requests to a non-existent
|
||||||
// deployment return 404 (not 502 or hang).
|
// deployment return 404 (not 502 or hang).
|
||||||
func TestMiddleware_NonExistentDeployment(t *testing.T) {
|
func TestMiddleware_NonExistentDeployment(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -51,8 +49,6 @@ func TestMiddleware_NonExistentDeployment(t *testing.T) {
|
|||||||
// TestMiddleware_InternalAPIAuthRejection verifies that internal replica API
|
// TestMiddleware_InternalAPIAuthRejection verifies that internal replica API
|
||||||
// endpoints reject requests without the proper internal auth header.
|
// endpoints reject requests without the proper internal auth header.
|
||||||
func TestMiddleware_InternalAPIAuthRejection(t *testing.T) {
|
func TestMiddleware_InternalAPIAuthRejection(t *testing.T) {
|
||||||
e2e.SkipIfLocal(t)
|
|
||||||
|
|
||||||
env, err := e2e.LoadTestEnv()
|
env, err := e2e.LoadTestEnv()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ func TestNetwork_ProxyAnonSuccess(t *testing.T) {
|
|||||||
Body: map[string]interface{}{
|
Body: map[string]interface{}{
|
||||||
"url": "https://httpbin.org/get",
|
"url": "https://httpbin.org/get",
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"headers": map[string]string{"User-Agent": "DeBros-E2E-Test/1.0"},
|
"headers": map[string]string{"User-Agent": "Orama-E2E-Test/1.0"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ func TestNetwork_ProxyAnonPostRequest(t *testing.T) {
|
|||||||
Body: map[string]interface{}{
|
Body: map[string]interface{}{
|
||||||
"url": "https://httpbin.org/post",
|
"url": "https://httpbin.org/post",
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
"headers": map[string]string{"User-Agent": "DeBros-E2E-Test/1.0"},
|
"headers": map[string]string{"User-Agent": "Orama-E2E-Test/1.0"},
|
||||||
"body": "test_data",
|
"body": "test_data",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
241
core/e2e/shared/webrtc_test.go
Normal file
241
core/e2e/shared/webrtc_test.go
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
//go:build e2e
|
||||||
|
|
||||||
|
package shared_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
e2e "github.com/DeBrosOfficial/network/e2e"
|
||||||
|
)
|
||||||
|
|
||||||
|
// turnCredentialsResponse is the expected response from the TURN credentials endpoint.
|
||||||
|
type turnCredentialsResponse struct {
|
||||||
|
URLs []string `json:"urls"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Credential string `json:"credential"`
|
||||||
|
TTL int `json:"ttl"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWebRTC_TURNCredentials_RequiresAuth verifies that the TURN credentials endpoint
|
||||||
|
// rejects unauthenticated requests.
|
||||||
|
func TestWebRTC_TURNCredentials_RequiresAuth(t *testing.T) {
|
||||||
|
e2e.SkipIfMissingGateway(t)
|
||||||
|
|
||||||
|
gatewayURL := e2e.GetGatewayURL()
|
||||||
|
client := e2e.NewHTTPClient(10 * time.Second)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", gatewayURL+"/v1/webrtc/turn/credentials", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("request failed: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusUnauthorized {
|
||||||
|
t.Fatalf("expected 401 Unauthorized, got %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWebRTC_TURNCredentials_ValidResponse verifies that authenticated requests to the
|
||||||
|
// TURN credentials endpoint return a valid credential structure.
|
||||||
|
func TestWebRTC_TURNCredentials_ValidResponse(t *testing.T) {
|
||||||
|
e2e.SkipIfMissingGateway(t)
|
||||||
|
|
||||||
|
gatewayURL := e2e.GetGatewayURL()
|
||||||
|
apiKey := e2e.GetAPIKey()
|
||||||
|
if apiKey == "" {
|
||||||
|
t.Skip("no API key configured")
|
||||||
|
}
|
||||||
|
client := e2e.NewHTTPClient(10 * time.Second)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", gatewayURL+"/v1/webrtc/turn/credentials", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("request failed: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
t.Fatalf("expected 200 OK, got %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
var creds turnCredentialsResponse
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&creds); err != nil {
|
||||||
|
t.Fatalf("failed to decode response: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(creds.URLs) == 0 {
|
||||||
|
t.Fatal("expected at least one TURN URL")
|
||||||
|
}
|
||||||
|
if creds.Username == "" {
|
||||||
|
t.Fatal("expected non-empty username")
|
||||||
|
}
|
||||||
|
if creds.Credential == "" {
|
||||||
|
t.Fatal("expected non-empty credential")
|
||||||
|
}
|
||||||
|
if creds.TTL <= 0 {
|
||||||
|
t.Fatalf("expected positive TTL, got %d", creds.TTL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWebRTC_Rooms_RequiresAuth verifies that the rooms endpoint rejects unauthenticated requests.
|
||||||
|
func TestWebRTC_Rooms_RequiresAuth(t *testing.T) {
|
||||||
|
e2e.SkipIfMissingGateway(t)
|
||||||
|
|
||||||
|
gatewayURL := e2e.GetGatewayURL()
|
||||||
|
client := e2e.NewHTTPClient(10 * time.Second)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", gatewayURL+"/v1/webrtc/rooms", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("request failed: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusUnauthorized {
|
||||||
|
t.Fatalf("expected 401 Unauthorized, got %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWebRTC_Signal_RequiresAuth verifies that the signaling WebSocket rejects
|
||||||
|
// unauthenticated connections.
|
||||||
|
func TestWebRTC_Signal_RequiresAuth(t *testing.T) {
|
||||||
|
e2e.SkipIfMissingGateway(t)
|
||||||
|
|
||||||
|
gatewayURL := e2e.GetGatewayURL()
|
||||||
|
client := e2e.NewHTTPClient(10 * time.Second)
|
||||||
|
|
||||||
|
// Use regular HTTP GET to the signal endpoint — without auth it should return 401
|
||||||
|
// before WebSocket upgrade
|
||||||
|
req, err := http.NewRequest("GET", gatewayURL+"/v1/webrtc/signal?room=test-room", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("request failed: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusUnauthorized {
|
||||||
|
t.Fatalf("expected 401, got %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWebRTC_Rooms_CreateAndList verifies room creation and listing with proper auth.
|
||||||
|
func TestWebRTC_Rooms_CreateAndList(t *testing.T) {
|
||||||
|
e2e.SkipIfMissingGateway(t)
|
||||||
|
|
||||||
|
gatewayURL := e2e.GetGatewayURL()
|
||||||
|
apiKey := e2e.GetAPIKey()
|
||||||
|
if apiKey == "" {
|
||||||
|
t.Skip("no API key configured")
|
||||||
|
}
|
||||||
|
client := e2e.NewHTTPClient(10 * time.Second)
|
||||||
|
|
||||||
|
roomID := e2e.GenerateUniqueID("e2e-webrtc-room")
|
||||||
|
|
||||||
|
// Create room
|
||||||
|
createBody, _ := json.Marshal(map[string]string{"room_id": roomID})
|
||||||
|
req, err := http.NewRequest("POST", gatewayURL+"/v1/webrtc/rooms", bytes.NewReader(createBody))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("create room failed: %v", err)
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
|
||||||
|
t.Fatalf("expected 200/201, got %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List rooms
|
||||||
|
req, err = http.NewRequest("GET", gatewayURL+"/v1/webrtc/rooms", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||||
|
|
||||||
|
resp, err = client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("list rooms failed: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
t.Fatalf("expected 200, got %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up: delete room
|
||||||
|
req, err = http.NewRequest("DELETE", gatewayURL+"/v1/webrtc/rooms?room_id="+roomID, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||||
|
|
||||||
|
resp2, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("delete room failed: %v", err)
|
||||||
|
}
|
||||||
|
resp2.Body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWebRTC_PermissionsPolicy verifies the Permissions-Policy header allows camera and microphone.
|
||||||
|
func TestWebRTC_PermissionsPolicy(t *testing.T) {
|
||||||
|
e2e.SkipIfMissingGateway(t)
|
||||||
|
|
||||||
|
gatewayURL := e2e.GetGatewayURL()
|
||||||
|
apiKey := e2e.GetAPIKey()
|
||||||
|
if apiKey == "" {
|
||||||
|
t.Skip("no API key configured")
|
||||||
|
}
|
||||||
|
client := e2e.NewHTTPClient(10 * time.Second)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", gatewayURL+"/v1/webrtc/rooms", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create request: %v", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("request failed: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
pp := resp.Header.Get("Permissions-Policy")
|
||||||
|
if pp == "" {
|
||||||
|
t.Skip("Permissions-Policy header not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(pp, "camera=(self)") {
|
||||||
|
t.Errorf("Permissions-Policy missing camera=(self), got: %s", pp)
|
||||||
|
}
|
||||||
|
if !strings.Contains(pp, "microphone=(self)") {
|
||||||
|
t.Errorf("Permissions-Policy missing microphone=(self), got: %s", pp)
|
||||||
|
}
|
||||||
|
}
|
||||||
182
core/go.mod
Normal file
182
core/go.mod
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
module github.com/DeBrosOfficial/network
|
||||||
|
|
||||||
|
go 1.24.6
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/charmbracelet/bubbles v0.20.0
|
||||||
|
github.com/charmbracelet/bubbletea v1.2.4
|
||||||
|
github.com/charmbracelet/lipgloss v1.0.0
|
||||||
|
github.com/coredns/caddy v1.1.4
|
||||||
|
github.com/coredns/coredns v1.12.1
|
||||||
|
github.com/ethereum/go-ethereum v1.13.14
|
||||||
|
github.com/go-chi/chi/v5 v5.2.3
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
|
||||||
|
github.com/libp2p/go-libp2p v0.41.1
|
||||||
|
github.com/libp2p/go-libp2p-pubsub v0.14.2
|
||||||
|
github.com/mackerelio/go-osstat v0.2.6
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.32
|
||||||
|
github.com/mdp/qrterminal/v3 v3.2.1
|
||||||
|
github.com/miekg/dns v1.1.70
|
||||||
|
github.com/multiformats/go-multiaddr v0.16.0
|
||||||
|
github.com/olric-data/olric v0.7.0
|
||||||
|
github.com/pion/interceptor v0.1.40
|
||||||
|
github.com/pion/rtcp v1.2.15
|
||||||
|
github.com/pion/turn/v4 v4.0.2
|
||||||
|
github.com/pion/webrtc/v4 v4.1.2
|
||||||
|
github.com/rqlite/gorqlite v0.0.0-20250609141355-ac86a4a1c9a8
|
||||||
|
github.com/spf13/cobra v1.10.2
|
||||||
|
github.com/stretchr/testify v1.11.1
|
||||||
|
github.com/tetratelabs/wazero v1.11.0
|
||||||
|
go.uber.org/zap v1.27.0
|
||||||
|
golang.org/x/crypto v0.47.0
|
||||||
|
golang.org/x/net v0.49.0
|
||||||
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/RoaringBitmap/roaring v1.9.4 // indirect
|
||||||
|
github.com/apparentlymart/go-cidr v1.1.0 // indirect
|
||||||
|
github.com/armon/go-metrics v0.4.1 // indirect
|
||||||
|
github.com/atotto/clipboard v0.1.4 // indirect
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
|
github.com/benbjohnson/clock v1.3.5 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/bits-and-blooms/bitset v1.22.0 // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
|
||||||
|
github.com/buraksezer/consistent v0.10.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
github.com/charmbracelet/x/ansi v0.4.5 // indirect
|
||||||
|
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||||
|
github.com/containerd/cgroups v1.1.0 // indirect
|
||||||
|
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
|
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/docker/go-units v0.5.0 // indirect
|
||||||
|
github.com/elastic/gosigar v0.14.3 // indirect
|
||||||
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||||
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
|
||||||
|
github.com/flynn/noise v1.1.0 // indirect
|
||||||
|
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||||
|
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/google/btree v1.1.3 // indirect
|
||||||
|
github.com/google/gopacket v1.1.19 // indirect
|
||||||
|
github.com/google/pprof v0.0.0-20250208200701-d0013a598941 // indirect
|
||||||
|
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||||
|
github.com/hashicorp/go-metrics v0.5.4 // indirect
|
||||||
|
github.com/hashicorp/go-msgpack/v2 v2.1.3 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
|
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
|
||||||
|
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||||
|
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||||
|
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||||
|
github.com/hashicorp/logutils v1.0.0 // indirect
|
||||||
|
github.com/hashicorp/memberlist v0.5.3 // indirect
|
||||||
|
github.com/holiman/uint256 v1.2.4 // indirect
|
||||||
|
github.com/huin/goupnp v1.3.0 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/ipfs/go-cid v0.5.0 // indirect
|
||||||
|
github.com/ipfs/go-log/v2 v2.6.0 // indirect
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||||
|
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
|
||||||
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||||
|
github.com/koron/go-ssdp v0.0.6 // indirect
|
||||||
|
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||||
|
github.com/libp2p/go-flow-metrics v0.2.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
|
||||||
|
github.com/libp2p/go-msgio v0.3.0 // indirect
|
||||||
|
github.com/libp2p/go-netroute v0.3.0 // indirect
|
||||||
|
github.com/libp2p/go-reuseport v0.4.0 // indirect
|
||||||
|
github.com/libp2p/go-yamux/v5 v5.0.1 // indirect
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||||
|
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
|
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
|
||||||
|
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
|
||||||
|
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||||
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||||
|
github.com/mschoch/smat v0.2.0 // indirect
|
||||||
|
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||||
|
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||||
|
github.com/muesli/termenv v0.15.2 // indirect
|
||||||
|
github.com/multiformats/go-base32 v0.1.0 // indirect
|
||||||
|
github.com/multiformats/go-base36 v0.2.0 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr-dns v0.4.1 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
|
||||||
|
github.com/multiformats/go-multibase v0.2.0 // indirect
|
||||||
|
github.com/multiformats/go-multicodec v0.9.1 // indirect
|
||||||
|
github.com/multiformats/go-multihash v0.2.3 // indirect
|
||||||
|
github.com/multiformats/go-multistream v0.6.1 // indirect
|
||||||
|
github.com/multiformats/go-varint v0.0.7 // indirect
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
|
||||||
|
github.com/opencontainers/runtime-spec v1.2.0 // indirect
|
||||||
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
|
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
|
||||||
|
github.com/pion/datachannel v1.5.10 // indirect
|
||||||
|
github.com/pion/dtls/v2 v2.2.12 // indirect
|
||||||
|
github.com/pion/dtls/v3 v3.0.6 // indirect
|
||||||
|
github.com/pion/ice/v4 v4.0.10 // indirect
|
||||||
|
github.com/pion/logging v0.2.3 // indirect
|
||||||
|
github.com/pion/mdns/v2 v2.0.7 // indirect
|
||||||
|
github.com/pion/randutil v0.1.0 // indirect
|
||||||
|
github.com/pion/rtp v1.8.19 // indirect
|
||||||
|
github.com/pion/sctp v1.8.39 // indirect
|
||||||
|
github.com/pion/sdp/v3 v3.0.13 // indirect
|
||||||
|
github.com/pion/srtp/v3 v3.0.6 // indirect
|
||||||
|
github.com/pion/stun v0.6.1 // indirect
|
||||||
|
github.com/pion/stun/v3 v3.0.0 // indirect
|
||||||
|
github.com/pion/transport/v2 v2.2.10 // indirect
|
||||||
|
github.com/pion/transport/v3 v3.0.7 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.23.0 // indirect
|
||||||
|
github.com/prometheus/client_model v0.6.2 // indirect
|
||||||
|
github.com/prometheus/common v0.67.5 // indirect
|
||||||
|
github.com/prometheus/procfs v0.16.1 // indirect
|
||||||
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.50.1 // indirect
|
||||||
|
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect
|
||||||
|
github.com/raulk/go-watchdog v1.3.0 // indirect
|
||||||
|
github.com/redis/go-redis/v9 v9.8.0 // indirect
|
||||||
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||||
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.9 // indirect
|
||||||
|
github.com/tidwall/btree v1.7.0 // indirect
|
||||||
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
|
github.com/tidwall/redcon v1.6.2 // indirect
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||||
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
|
github.com/wlynxg/anet v0.0.5 // indirect
|
||||||
|
go.uber.org/dig v1.19.0 // indirect
|
||||||
|
go.uber.org/fx v1.24.0 // indirect
|
||||||
|
go.uber.org/mock v0.6.0 // indirect
|
||||||
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
|
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect
|
||||||
|
golang.org/x/mod v0.31.0 // indirect
|
||||||
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
|
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect
|
||||||
|
golang.org/x/term v0.39.0 // indirect
|
||||||
|
golang.org/x/text v0.33.0 // indirect
|
||||||
|
golang.org/x/time v0.14.0 // indirect
|
||||||
|
golang.org/x/tools v0.40.0 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
|
||||||
|
google.golang.org/grpc v1.78.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
|
lukechampine.com/blake3 v1.4.1 // indirect
|
||||||
|
rsc.io/qr v0.2.0 // indirect
|
||||||
|
)
|
||||||
@ -2,80 +2,13 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
|||||||
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
|
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
|
||||||
cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw=
|
|
||||||
cloud.google.com/go/auth v0.18.0 h1:wnqy5hrv7p3k7cShwAU/Br3nzod7fxoqG+k0VZ+/Pk0=
|
|
||||||
cloud.google.com/go/auth v0.18.0/go.mod h1:wwkPM1AgE1f2u6dG443MiWoD8C3BtOywNsUMcUTVDRo=
|
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
|
||||||
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
|
||||||
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
|
|
||||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
|
||||||
github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA=
|
|
||||||
github.com/Azure/go-autorest/autorest v0.11.30 h1:iaZ1RGz/ALZtN5eq4Nr1SOFSlf2E4pDI3Tcsl+dZPVE=
|
|
||||||
github.com/Azure/go-autorest/autorest v0.11.30/go.mod h1:t1kpPIOpIVX7annvothKvb0stsrXa37i7b+xpmBW8Fs=
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.22 h1:/GblQdIudfEM3AWWZ0mrYJQSd7JS4S/Mbzh6F0ov0Xc=
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk=
|
|
||||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 h1:Ov8avRZi2vmrE2JcXw+tu5K/yB41r7xK9GZDiBF7NdM=
|
|
||||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.13/go.mod h1:5BAVfWLWXihP47vYrPuBKKf4cS0bXI+KM9Qx6ETDJYo=
|
|
||||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc=
|
|
||||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0=
|
|
||||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
|
||||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
|
||||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
|
||||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
|
|
||||||
github.com/Azure/go-autorest/autorest/to v0.2.0 h1:nQOZzFCudTh+TvquAtCRjM01VEYx85e9qbwt5ncW4L8=
|
|
||||||
github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
|
|
||||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
|
||||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.71.0 h1:xjmjXOsiLfUF1wWXYXc8Gg6M7Jbz6a7FtqbnvGKfTvA=
|
|
||||||
github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.71.0/go.mod h1:y05SPqKEtrigKul+JBVM69ehv3lOgyKwrUIwLugoaSI=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/obfuscate v0.71.0 h1:jX8qS7CkNzL1fdcDptrOkbWpsRFTQ58ICjp/mj02u1k=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/obfuscate v0.71.0/go.mod h1:B3T0If+WdWAwPMpawjm1lieJyqSI0v04dQZHq15WGxY=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.71.0 h1:bowQteds9+7I4Dd+CsBRVXdlMOOGuBm5zdUQdB/6j1M=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.71.0/go.mod h1:XeZj0IgsiL3vgeEGTucf61JvJRh1LxWMUbZA/XJsPD0=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/proto v0.71.0 h1:YTwecwy8kF1zsL2HK6KVa7XLRZYZ0Ypb2anlG0zDLeE=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/proto v0.71.0/go.mod h1:KSn4jt3CykV6CT1C8Rknn/Nj3E+VYHK/UDWolg/+kzw=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.73.0-rc.1 h1:fVqr9ApWmUMEExmgn8iFPfwm9ZrlEfFWgTKp1IcNH18=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.73.0-rc.1/go.mod h1:lwkSvCXABHXyqy6mG9WBU6MTK9/E0i0R8JVApUtT+XA=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/trace v0.71.0 h1:9UrKHDacMlAWfP2wpSxrZOQbtkwLY2AOAjYgGkgM96Y=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/trace v0.71.0/go.mod h1:wfVwOlKORIB4IB1vdncTuCTx/OrVU69TLBIiBpewe1Q=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/util/log v0.71.0 h1:VJ+nm5E0+UdLPkg2H7FKapx0syNcKzCFXA2vfcHz0Bc=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/util/log v0.71.0/go.mod h1:oG6f6Qe23zPTLOVh0nXjlIXohrjUGXeFjh7S3Na/WyU=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/util/scrubber v0.71.0 h1:lA3CL+2yHU9gulyR/C0VssVzmvCs/jCHzt+CBs9uH4Q=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/util/scrubber v0.71.0/go.mod h1:/JHi9UFqdFYy/SFmFozY26dNOl/ODVLSQaF1LKDPiBI=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/version v0.71.0 h1:jqkKmhFrhHSLpiC3twQFDCXU7nyFcC1EnwagDQxFWVs=
|
|
||||||
github.com/DataDog/datadog-agent/pkg/version v0.71.0/go.mod h1:FYj51C1ib86rpr5tlLEep9jitqvljIJ5Uz2rrimGTeY=
|
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4=
|
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
github.com/DataDog/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw=
|
|
||||||
github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw=
|
|
||||||
github.com/DataDog/dd-trace-go/v2 v2.5.0 h1:Tp4McT135WhbdT/6BYcAoRvl5gH7YKzehSo6Q3uuxBM=
|
|
||||||
github.com/DataDog/dd-trace-go/v2 v2.5.0/go.mod h1:A9rVmQfyzYUFCctFdKkli9us7G/YhXlMICpQ958wJUA=
|
|
||||||
github.com/DataDog/go-libddwaf/v4 v4.8.0 h1:m6Bl1lS2RtVN4MtdTYhR5vJ2fWQ3WmNy4FiNBpzrp6w=
|
|
||||||
github.com/DataDog/go-libddwaf/v4 v4.8.0/go.mod h1:/AZqP6zw3qGJK5mLrA0PkfK3UQDk1zCI2fUNCt4xftE=
|
|
||||||
github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633 h1:ZRLR9Lbym748e8RznWzmSoK+OfV+8qW6SdNYA4/IqdA=
|
|
||||||
github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633/go.mod h1:YFoTl1xsMzdSRFIu33oCSPS/3+HZAPGpO3oOM96wXCM=
|
|
||||||
github.com/DataDog/go-sqllexer v0.1.8 h1:ku9DpghFHeyyviR28W/3R4cCJwzpsuC08YIoltnx5ds=
|
|
||||||
github.com/DataDog/go-sqllexer v0.1.8/go.mod h1:GGpo1h9/BVSN+6NJKaEcJ9Jn44Hqc63Rakeb+24Mjgo=
|
|
||||||
github.com/DataDog/go-tuf v1.1.1-0.5.2 h1:YWvghV4ZvrQsPcUw8IOUMSDpqc3W5ruOIC+KJxPknv0=
|
|
||||||
github.com/DataDog/go-tuf v1.1.1-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0=
|
|
||||||
github.com/DataDog/sketches-go v1.4.7 h1:eHs5/0i2Sdf20Zkj0udVFWuCrXGRFig2Dcfm5rtcTxc=
|
|
||||||
github.com/DataDog/sketches-go v1.4.7/go.mod h1:eAmQ/EBmtSO+nQp7IZMZVRPT4BQTmIc5RZQ+deGlTPM=
|
|
||||||
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
|
||||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
|
||||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
|
||||||
github.com/RoaringBitmap/roaring v1.9.4 h1:yhEIoH4YezLYT04s1nHehNO64EKFTop/wBhxv2QzDdQ=
|
github.com/RoaringBitmap/roaring v1.9.4 h1:yhEIoH4YezLYT04s1nHehNO64EKFTop/wBhxv2QzDdQ=
|
||||||
github.com/RoaringBitmap/roaring v1.9.4/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
|
github.com/RoaringBitmap/roaring v1.9.4/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
@ -90,38 +23,6 @@ github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJ
|
|||||||
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
|
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
|
||||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.41.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU=
|
|
||||||
github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
|
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.32.7 h1:vxUyWGUwmkQ2g19n7JY/9YL8MfAIl7bTesIUykECXmY=
|
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.32.7/go.mod h1:2/Qm5vKUU/r7Y+zUk/Ptt2MDAEKAfUtKc1+3U1Mo3oY=
|
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.7 h1:tHK47VqqtJxOymRrNtUXN5SP/zUTvZKeLx4tH6PGQc8=
|
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.7/go.mod h1:qOZk8sPDrxhf+4Wf4oT2urYJrYt3RejHSzgAquYeppw=
|
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY=
|
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA=
|
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U=
|
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ=
|
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik=
|
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM=
|
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 h1:RuNSMoozM8oXlgLG/n6WLaFGoea7/CddrCfIiSA+xdY=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17/go.mod h1:F2xxQ9TZz5gDWsclCtPQscGpP0VUOc8RqgFM3vDENmU=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.1 h1:1jIdwWOulae7bBLIgB36OZ0DINACb1wxM6wdGlx4eHE=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.1/go.mod h1:tE2zGlMIlxWv+7Otap7ctRp3qeKqtnja7DZguj3Vu/Y=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.1 h1:72DBkm/CCuWx2LMHAXvLDkZfzopT3psfAeyZDIt1/yE=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.1/go.mod h1:A+oSJxFvzgjZWkpM0mXs3RxB5O1SD6473w3qafOC9eU=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 h1:v6EiMvhEYBoHABfbGB4alOYmCIrcgyPPiBE1wZAEbqk=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 h1:gd84Omyu9JLriJVCbGApcLzVR3XtmC4ZDPcAI6Ftvds=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ=
|
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ=
|
|
||||||
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
|
|
||||||
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
@ -146,8 +47,6 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtyd
|
|||||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
github.com/buraksezer/consistent v0.10.0 h1:hqBgz1PvNLC5rkWcEBVAL9dFMBWz6I0VgUCW25rrZlU=
|
github.com/buraksezer/consistent v0.10.0 h1:hqBgz1PvNLC5rkWcEBVAL9dFMBWz6I0VgUCW25rrZlU=
|
||||||
github.com/buraksezer/consistent v0.10.0/go.mod h1:6BrVajWq7wbKZlTOUPs/XVfR8c0maujuPowduSpZqmw=
|
github.com/buraksezer/consistent v0.10.0/go.mod h1:6BrVajWq7wbKZlTOUPs/XVfR8c0maujuPowduSpZqmw=
|
||||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
|
||||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
@ -161,8 +60,6 @@ github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSe
|
|||||||
github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||||
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
||||||
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
|
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
|
||||||
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs=
|
|
||||||
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo=
|
|
||||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||||
@ -174,10 +71,6 @@ github.com/coredns/caddy v1.1.4 h1:+Lls5xASB0QsA2jpCroCOwpPlb5GjIGlxdjXxdX0XVo=
|
|||||||
github.com/coredns/caddy v1.1.4/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4=
|
github.com/coredns/caddy v1.1.4/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4=
|
||||||
github.com/coredns/coredns v1.12.1 h1:haptbGscSbdWU46xrjdPj1vp3wvH1Z2FgCSQKEdgN5s=
|
github.com/coredns/coredns v1.12.1 h1:haptbGscSbdWU46xrjdPj1vp3wvH1Z2FgCSQKEdgN5s=
|
||||||
github.com/coredns/coredns v1.12.1/go.mod h1:V26ngiKdNvAiEre5PTAvklrvTjnNjl6lakq1nbE/NbU=
|
github.com/coredns/coredns v1.12.1/go.mod h1:V26ngiKdNvAiEre5PTAvklrvTjnNjl6lakq1nbE/NbU=
|
||||||
github.com/coredns/coredns v1.14.1 h1:U7ZvMsMn3IfXhaiEHKkW0wsCKG4H5dPvWyMeSLhAodM=
|
|
||||||
github.com/coredns/coredns v1.14.1/go.mod h1:oYbISnKw+U930dyDU+VVJ+VCWpRD/frU7NfHlqeqH7U=
|
|
||||||
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
|
||||||
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||||
@ -185,9 +78,7 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
|||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -197,38 +88,19 @@ github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U
|
|||||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
|
||||||
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
|
|
||||||
github.com/dnstap/golang-dnstap v0.4.0 h1:KRHBoURygdGtBjDI2w4HifJfMAhhOqDuktAokaSa234=
|
|
||||||
github.com/dnstap/golang-dnstap v0.4.0/go.mod h1:FqsSdH58NAmkAvKcpyxht7i4FoBjKu8E4JUPt8ipSUs=
|
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/dunglas/httpsfv v1.1.0 h1:Jw76nAyKWKZKFrpMMcL76y35tOpYHqQPzHQiwDvpe54=
|
|
||||||
github.com/dunglas/httpsfv v1.1.0/go.mod h1:zID2mqw9mFsnt7YC3vYQ9/cjq30q41W+1AnDwH8TiMg=
|
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
|
||||||
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
|
||||||
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
|
||||||
github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
|
github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
|
||||||
github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo=
|
github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo=
|
||||||
github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
|
github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
|
||||||
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
|
|
||||||
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
|
||||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
||||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
||||||
github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ=
|
github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ=
|
||||||
github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU=
|
github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU=
|
||||||
github.com/expr-lang/expr v1.17.7 h1:Q0xY/e/2aCIp8g9s/LGvMDCC5PxYlvHgDZRQ4y16JX8=
|
|
||||||
github.com/expr-lang/expr v1.17.7/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
|
||||||
github.com/farsightsec/golang-framestream v0.3.0 h1:/spFQHucTle/ZIPkYqrfshQqPe2VQEzesH243TjIwqA=
|
|
||||||
github.com/farsightsec/golang-framestream v0.3.0/go.mod h1:eNde4IQyEiA5br02AouhEHCu3p3UzrCdFR4LuQHklMI=
|
|
||||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
|
||||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
|
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
|
||||||
@ -236,8 +108,6 @@ github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwU
|
|||||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||||
github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE=
|
github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE=
|
||||||
@ -249,24 +119,10 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
|
|||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
|
||||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
|
||||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
|
||||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
|
||||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
|
||||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
|
||||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
|
||||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
|
||||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
|
||||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
|
||||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
|
||||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
@ -278,16 +134,10 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
|
|||||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
|
||||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@ -303,8 +153,6 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
|
|||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||||
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
|
||||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
@ -323,38 +171,22 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
|
|||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20250208200701-d0013a598941 h1:43XjGa6toxLpeksjcxs1jIoIyr+vUfOqY2c6HB4bpoc=
|
github.com/google/pprof v0.0.0-20250208200701-d0013a598941 h1:43XjGa6toxLpeksjcxs1jIoIyr+vUfOqY2c6HB4bpoc=
|
||||||
github.com/google/pprof v0.0.0-20250208200701-d0013a598941/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
github.com/google/pprof v0.0.0-20250208200701-d0013a598941/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||||
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
|
||||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ=
|
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
|
||||||
github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU=
|
|
||||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||||
github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14=
|
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
|
||||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0 h1:WcmKMm43DR7RdtlkEXQJyo5ws8iTp98CyhCCbOHMvNI=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
|
|
||||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=
|
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=
|
||||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
|
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
|
||||||
github.com/hashicorp/cronexpr v1.1.3 h1:rl5IkxXN2m681EfivTlccqIryzYJSXRGRNa0xeG7NA4=
|
|
||||||
github.com/hashicorp/cronexpr v1.1.3/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4=
|
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
@ -365,14 +197,11 @@ github.com/hashicorp/go-msgpack/v2 v2.1.3/go.mod h1:SjlwKKFnwBXvxD/I1bEcfJIBbEJ+
|
|||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||||
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
|
||||||
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
|
||||||
github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=
|
github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=
|
||||||
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
|
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
|
||||||
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
|
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||||
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||||
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||||
@ -382,16 +211,12 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI
|
|||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||||
github.com/hashicorp/memberlist v0.5.3 h1:tQ1jOCypD0WvMemw/ZhhtH+PWpzcftQvgCorLu0hndk=
|
github.com/hashicorp/memberlist v0.5.3 h1:tQ1jOCypD0WvMemw/ZhhtH+PWpzcftQvgCorLu0hndk=
|
||||||
github.com/hashicorp/memberlist v0.5.3/go.mod h1:h60o12SZn/ua/j0B6iKAZezA4eDaGsIuPO70eOaJ6WE=
|
github.com/hashicorp/memberlist v0.5.3/go.mod h1:h60o12SZn/ua/j0B6iKAZezA4eDaGsIuPO70eOaJ6WE=
|
||||||
github.com/hashicorp/nomad/api v0.0.0-20250909143645-a3b86c697f38 h1:1LTbcTpGdSdbj0ee7YZHNe4R2XqxfyWwIkSGWRhgkfM=
|
|
||||||
github.com/hashicorp/nomad/api v0.0.0-20250909143645-a3b86c697f38/go.mod h1:0Tdp+9HbvwrxprXv/LfYZ8P21bOl4oA8Afyet1kUvhI=
|
|
||||||
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
|
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
|
||||||
github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
|
github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
|
||||||
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
|
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
|
||||||
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
|
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/infobloxopen/go-trees v0.0.0-20200715205103-96a057b8dfb9 h1:w66aaP3c6SIQ0pi3QH1Tb4AMO3aWoEPxd1CNvLphbkA=
|
|
||||||
github.com/infobloxopen/go-trees v0.0.0-20200715205103-96a057b8dfb9/go.mod h1:BaIJzjD2ZnHmx2acPF6XfGLPzNCMiBbMRqJr+8/8uRI=
|
|
||||||
github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg=
|
github.com/ipfs/go-cid v0.5.0 h1:goEKKhaGm0ul11IHA7I6p1GmKz8kEYniqFopaB5Otwg=
|
||||||
github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk=
|
github.com/ipfs/go-cid v0.5.0/go.mod h1:0L7vmeNXpQpUS9vt+yEARkJ8rOg43DF3iPgn4GIN0mk=
|
||||||
github.com/ipfs/go-log/v2 v2.6.0 h1:2Nu1KKQQ2ayonKp4MPo6pXCjqw1ULc9iohRqWV5EYqg=
|
github.com/ipfs/go-log/v2 v2.6.0 h1:2Nu1KKQQ2ayonKp4MPo6pXCjqw1ULc9iohRqWV5EYqg=
|
||||||
@ -401,15 +226,11 @@ github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+
|
|||||||
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
|
github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk=
|
||||||
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
|
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
|
||||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
@ -422,8 +243,6 @@ github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2
|
|||||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/koron/go-ssdp v0.0.5 h1:E1iSMxIs4WqxTbIBLtmNBeOOC+1sCIXQeqTWVnpmwhk=
|
|
||||||
github.com/koron/go-ssdp v0.0.5/go.mod h1:Qm59B7hpKpDqfyRNWRNr00jGwLdXjDyZh6y7rH6VS0w=
|
|
||||||
github.com/koron/go-ssdp v0.0.6 h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU=
|
github.com/koron/go-ssdp v0.0.6 h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU=
|
||||||
github.com/koron/go-ssdp v0.0.6/go.mod h1:0R9LfRJGek1zWTjN3JUNlm5INCDYGpRDfAptnct63fI=
|
github.com/koron/go-ssdp v0.0.6/go.mod h1:0R9LfRJGek1zWTjN3JUNlm5INCDYGpRDfAptnct63fI=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
@ -442,8 +261,6 @@ github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C
|
|||||||
github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc=
|
github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc=
|
||||||
github.com/libp2p/go-libp2p v0.41.1 h1:8ecNQVT5ev/jqALTvisSJeVNvXYJyK4NhQx1nNRXQZE=
|
github.com/libp2p/go-libp2p v0.41.1 h1:8ecNQVT5ev/jqALTvisSJeVNvXYJyK4NhQx1nNRXQZE=
|
||||||
github.com/libp2p/go-libp2p v0.41.1/go.mod h1:DcGTovJzQl/I7HMrby5ZRjeD0kQkGiy+9w6aEkSZpRI=
|
github.com/libp2p/go-libp2p v0.41.1/go.mod h1:DcGTovJzQl/I7HMrby5ZRjeD0kQkGiy+9w6aEkSZpRI=
|
||||||
github.com/libp2p/go-libp2p v0.46.0 h1:0T2yvIKpZ3DVYCuPOFxPD1layhRU486pj9rSlGWYnDM=
|
|
||||||
github.com/libp2p/go-libp2p v0.46.0/go.mod h1:TbIDnpDjBLa7isdgYpbxozIVPBTmM/7qKOJP4SFySrQ=
|
|
||||||
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
|
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
|
||||||
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
|
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
|
||||||
github.com/libp2p/go-libp2p-pubsub v0.14.2 h1:nT5lFHPQOFJcp9CW8hpKtvbpQNdl2udJuzLQWbgRum8=
|
github.com/libp2p/go-libp2p-pubsub v0.14.2 h1:nT5lFHPQOFJcp9CW8hpKtvbpQNdl2udJuzLQWbgRum8=
|
||||||
@ -452,26 +269,18 @@ github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUI
|
|||||||
github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg=
|
github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg=
|
||||||
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
|
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
|
||||||
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
|
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
|
||||||
github.com/libp2p/go-netroute v0.2.2 h1:Dejd8cQ47Qx2kRABg6lPwknU7+nBnFRpko45/fFPuZ8=
|
|
||||||
github.com/libp2p/go-netroute v0.2.2/go.mod h1:Rntq6jUAH0l9Gg17w5bFGhcC9a+vk4KNXs6s7IljKYE=
|
|
||||||
github.com/libp2p/go-netroute v0.3.0 h1:nqPCXHmeNmgTJnktosJ/sIef9hvwYCrsLxXmfNks/oc=
|
github.com/libp2p/go-netroute v0.3.0 h1:nqPCXHmeNmgTJnktosJ/sIef9hvwYCrsLxXmfNks/oc=
|
||||||
github.com/libp2p/go-netroute v0.3.0/go.mod h1:Nkd5ShYgSMS5MUKy/MU2T57xFoOKvvLR92Lic48LEyA=
|
github.com/libp2p/go-netroute v0.3.0/go.mod h1:Nkd5ShYgSMS5MUKy/MU2T57xFoOKvvLR92Lic48LEyA=
|
||||||
github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s=
|
github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s=
|
||||||
github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU=
|
github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU=
|
||||||
github.com/libp2p/go-yamux/v5 v5.0.0 h1:2djUh96d3Jiac/JpGkKs4TO49YhsfLopAoryfPmf+Po=
|
|
||||||
github.com/libp2p/go-yamux/v5 v5.0.0/go.mod h1:en+3cdX51U0ZslwRdRLrvQsdayFt3TSUKvBGErzpWbU=
|
|
||||||
github.com/libp2p/go-yamux/v5 v5.0.1 h1:f0WoX/bEF2E8SbE4c/k1Mo+/9z0O4oC/hWEA+nfYRSg=
|
github.com/libp2p/go-yamux/v5 v5.0.1 h1:f0WoX/bEF2E8SbE4c/k1Mo+/9z0O4oC/hWEA+nfYRSg=
|
||||||
github.com/libp2p/go-yamux/v5 v5.0.1/go.mod h1:en+3cdX51U0ZslwRdRLrvQsdayFt3TSUKvBGErzpWbU=
|
github.com/libp2p/go-yamux/v5 v5.0.1/go.mod h1:en+3cdX51U0ZslwRdRLrvQsdayFt3TSUKvBGErzpWbU=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc=
|
|
||||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
|
|
||||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||||
github.com/mackerelio/go-osstat v0.2.6 h1:gs4U8BZeS1tjrL08tt5VUliVvSWP26Ai2Ob8Lr7f2i0=
|
github.com/mackerelio/go-osstat v0.2.6 h1:gs4U8BZeS1tjrL08tt5VUliVvSWP26Ai2Ob8Lr7f2i0=
|
||||||
github.com/mackerelio/go-osstat v0.2.6/go.mod h1:lRy8V9ZuHpuRVZh+vyTkODeDPl3/d5MgXHtLSaqG8bA=
|
github.com/mackerelio/go-osstat v0.2.6/go.mod h1:lRy8V9ZuHpuRVZh+vyTkODeDPl3/d5MgXHtLSaqG8bA=
|
||||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
|
||||||
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk=
|
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk=
|
||||||
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU=
|
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
@ -485,10 +294,9 @@ github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU
|
|||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
|
github.com/mdp/qrterminal/v3 v3.2.1 h1:6+yQjiiOsSuXT5n9/m60E54vdgFsw0zhADHhHLrFet4=
|
||||||
|
github.com/mdp/qrterminal/v3 v3.2.1/go.mod h1:jOTmXvnBsMy5xqLniO0R++Jmjs2sTm9dFSuQ5kpz/SU=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||||
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
|
||||||
github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE=
|
|
||||||
github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE=
|
|
||||||
github.com/miekg/dns v1.1.70 h1:DZ4u2AV35VJxdD9Fo9fIWm119BsQL5cZU1cQ9s0LkqA=
|
github.com/miekg/dns v1.1.70 h1:DZ4u2AV35VJxdD9Fo9fIWm119BsQL5cZU1cQ9s0LkqA=
|
||||||
github.com/miekg/dns v1.1.70/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
|
github.com/miekg/dns v1.1.70/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
|
||||||
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
|
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
|
||||||
@ -501,20 +309,10 @@ github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8Rv
|
|||||||
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||||
github.com/minio/simdjson-go v0.4.5 h1:r4IQwjRGmWCQ2VeMc7fGiilu1z5du0gJ/I/FsKwgo5A=
|
|
||||||
github.com/minio/simdjson-go v0.4.5/go.mod h1:eoNz0DcLQRyEDeaPr4Ru6JpjlZPzbA0IodxVJk8lO8E=
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
|
||||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
|
||||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
|
||||||
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||||
@ -531,8 +329,6 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg
|
|||||||
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
||||||
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
||||||
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
|
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
|
||||||
github.com/multiformats/go-multiaddr v0.15.0 h1:zB/HeaI/apcZiTDwhY5YqMvNVl/oQYvs3XySU+qeAVo=
|
|
||||||
github.com/multiformats/go-multiaddr v0.15.0/go.mod h1:JSVUmXDjsVFiW7RjIFMP7+Ev+h1DTbiJgVeTV/tcmP0=
|
|
||||||
github.com/multiformats/go-multiaddr v0.16.0 h1:oGWEVKioVQcdIOBlYM8BH1rZDWOGJSqr9/BKl6zQ4qc=
|
github.com/multiformats/go-multiaddr v0.16.0 h1:oGWEVKioVQcdIOBlYM8BH1rZDWOGJSqr9/BKl6zQ4qc=
|
||||||
github.com/multiformats/go-multiaddr v0.16.0/go.mod h1:JSVUmXDjsVFiW7RjIFMP7+Ev+h1DTbiJgVeTV/tcmP0=
|
github.com/multiformats/go-multiaddr v0.16.0/go.mod h1:JSVUmXDjsVFiW7RjIFMP7+Ev+h1DTbiJgVeTV/tcmP0=
|
||||||
github.com/multiformats/go-multiaddr-dns v0.4.1 h1:whi/uCLbDS3mSEUMb1MsoT4uzUeZB0N32yzufqS0i5M=
|
github.com/multiformats/go-multiaddr-dns v0.4.1 h1:whi/uCLbDS3mSEUMb1MsoT4uzUeZB0N32yzufqS0i5M=
|
||||||
@ -541,15 +337,11 @@ github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/e
|
|||||||
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
|
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
|
||||||
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
||||||
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
||||||
github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg=
|
|
||||||
github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k=
|
|
||||||
github.com/multiformats/go-multicodec v0.9.1 h1:x/Fuxr7ZuR4jJV4Os5g444F7xC4XmyUaT/FWtE+9Zjo=
|
github.com/multiformats/go-multicodec v0.9.1 h1:x/Fuxr7ZuR4jJV4Os5g444F7xC4XmyUaT/FWtE+9Zjo=
|
||||||
github.com/multiformats/go-multicodec v0.9.1/go.mod h1:LLWNMtyV5ithSBUo3vFIMaeDy+h3EbkMTek1m+Fybbo=
|
github.com/multiformats/go-multicodec v0.9.1/go.mod h1:LLWNMtyV5ithSBUo3vFIMaeDy+h3EbkMTek1m+Fybbo=
|
||||||
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
|
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
|
||||||
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
|
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
|
||||||
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
|
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
|
||||||
github.com/multiformats/go-multistream v0.6.0 h1:ZaHKbsL404720283o4c/IHQXiS6gb8qAN5EIJ4PN5EA=
|
|
||||||
github.com/multiformats/go-multistream v0.6.0/go.mod h1:MOyoG5otO24cHIg8kf9QW2/NozURlkP/rvi2FQJyCPg=
|
|
||||||
github.com/multiformats/go-multistream v0.6.1 h1:4aoX5v6T+yWmc2raBHsTvzmFhOI8WVOer28DeBBEYdQ=
|
github.com/multiformats/go-multistream v0.6.1 h1:4aoX5v6T+yWmc2raBHsTvzmFhOI8WVOer28DeBBEYdQ=
|
||||||
github.com/multiformats/go-multistream v0.6.1/go.mod h1:ksQf6kqHAb6zIsyw7Zm+gAuVo57Qbq84E27YlYqavqw=
|
github.com/multiformats/go-multistream v0.6.1/go.mod h1:ksQf6kqHAb6zIsyw7Zm+gAuVo57Qbq84E27YlYqavqw=
|
||||||
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
||||||
@ -569,42 +361,22 @@ github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlR
|
|||||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
|
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
|
||||||
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU=
|
|
||||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
|
||||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0 h1:uhcF5Jd7rP9DVEL10Siffyepr6SvlKbUsjH5JpNCRi8=
|
|
||||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0/go.mod h1:+oCZ5GXXr7KPI/DNOQORPTq5AWHfALJj9c72b0+YsEY=
|
|
||||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||||
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
|
|
||||||
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
|
||||||
github.com/oschwald/geoip2-golang/v2 v2.1.0 h1:DjnLhNJu9WHwTrmoiQFvgmyJoczhdnm7LB23UBI2Amo=
|
|
||||||
github.com/oschwald/geoip2-golang/v2 v2.1.0/go.mod h1:qdVmcPgrTJ4q2eP9tHq/yldMTdp2VMr33uVdFbHBiBc=
|
|
||||||
github.com/oschwald/maxminddb-golang/v2 v2.1.1 h1:lA8FH0oOrM4u7mLvowq8IT6a3Q/qEnqRzLQn9eH5ojc=
|
|
||||||
github.com/oschwald/maxminddb-golang/v2 v2.1.1/go.mod h1:PLdx6PR+siSIoXqqy7C7r3SB3KZnhxWr1Dp6g0Hacl8=
|
|
||||||
github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0=
|
|
||||||
github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac=
|
|
||||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
|
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
|
||||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
|
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
|
||||||
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
|
||||||
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
|
||||||
github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o=
|
github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o=
|
||||||
github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M=
|
github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M=
|
||||||
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
|
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
|
||||||
github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=
|
github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=
|
||||||
github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
|
github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
|
||||||
github.com/pion/dtls/v3 v3.0.4 h1:44CZekewMzfrn9pmGrj5BNnTMDCFwr+6sLH+cCuLM7U=
|
|
||||||
github.com/pion/dtls/v3 v3.0.4/go.mod h1:R373CsjxWqNPf6MEkfdy3aSe9niZvL/JaKlGeFphtMg=
|
|
||||||
github.com/pion/dtls/v3 v3.0.6 h1:7Hkd8WhAJNbRgq9RgdNh1aaWlZlGpYTzdqjy9x9sK2E=
|
github.com/pion/dtls/v3 v3.0.6 h1:7Hkd8WhAJNbRgq9RgdNh1aaWlZlGpYTzdqjy9x9sK2E=
|
||||||
github.com/pion/dtls/v3 v3.0.6/go.mod h1:iJxNQ3Uhn1NZWOMWlLxEEHAN5yX7GyPvvKw04v9bzYU=
|
github.com/pion/dtls/v3 v3.0.6/go.mod h1:iJxNQ3Uhn1NZWOMWlLxEEHAN5yX7GyPvvKw04v9bzYU=
|
||||||
github.com/pion/ice/v4 v4.0.8 h1:ajNx0idNG+S+v9Phu4LSn2cs8JEfTsA1/tEjkkAVpFY=
|
|
||||||
github.com/pion/ice/v4 v4.0.8/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw=
|
|
||||||
github.com/pion/ice/v4 v4.0.10 h1:P59w1iauC/wPk9PdY8Vjl4fOFL5B+USq1+xbDcN6gT4=
|
github.com/pion/ice/v4 v4.0.10 h1:P59w1iauC/wPk9PdY8Vjl4fOFL5B+USq1+xbDcN6gT4=
|
||||||
github.com/pion/ice/v4 v4.0.10/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw=
|
github.com/pion/ice/v4 v4.0.10/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw=
|
||||||
github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI=
|
|
||||||
github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y=
|
|
||||||
github.com/pion/interceptor v0.1.40 h1:e0BjnPcGpr2CFQgKhrQisBU7V3GXK6wrfYrGYaU6Jq4=
|
github.com/pion/interceptor v0.1.40 h1:e0BjnPcGpr2CFQgKhrQisBU7V3GXK6wrfYrGYaU6Jq4=
|
||||||
github.com/pion/interceptor v0.1.40/go.mod h1:Z6kqH7M/FYirg3frjGJ21VLSRJGBXB/KqaTIrdqnOic=
|
github.com/pion/interceptor v0.1.40/go.mod h1:Z6kqH7M/FYirg3frjGJ21VLSRJGBXB/KqaTIrdqnOic=
|
||||||
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
|
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
|
||||||
@ -616,20 +388,12 @@ github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
|
|||||||
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
||||||
github.com/pion/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo=
|
github.com/pion/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo=
|
||||||
github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0=
|
github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0=
|
||||||
github.com/pion/rtp v1.8.11 h1:17xjnY5WO5hgO6SD3/NTIUPvSFw/PbLsIJyz1r1yNIk=
|
|
||||||
github.com/pion/rtp v1.8.11/go.mod h1:8uMBJj32Pa1wwx8Fuv/AsFhn8jsgw+3rUC2PfoBZ8p4=
|
|
||||||
github.com/pion/rtp v1.8.19 h1:jhdO/3XhL/aKm/wARFVmvTfq0lC/CvN1xwYKmduly3c=
|
github.com/pion/rtp v1.8.19 h1:jhdO/3XhL/aKm/wARFVmvTfq0lC/CvN1xwYKmduly3c=
|
||||||
github.com/pion/rtp v1.8.19/go.mod h1:bAu2UFKScgzyFqvUKmbvzSdPr+NGbZtv6UB2hesqXBk=
|
github.com/pion/rtp v1.8.19/go.mod h1:bAu2UFKScgzyFqvUKmbvzSdPr+NGbZtv6UB2hesqXBk=
|
||||||
github.com/pion/sctp v1.8.37 h1:ZDmGPtRPX9mKCiVXtMbTWybFw3z/hVKAZgU81wcOrqs=
|
|
||||||
github.com/pion/sctp v1.8.37/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE=
|
|
||||||
github.com/pion/sctp v1.8.39 h1:PJma40vRHa3UTO3C4MyeJDQ+KIobVYRZQZ0Nt7SjQnE=
|
github.com/pion/sctp v1.8.39 h1:PJma40vRHa3UTO3C4MyeJDQ+KIobVYRZQZ0Nt7SjQnE=
|
||||||
github.com/pion/sctp v1.8.39/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE=
|
github.com/pion/sctp v1.8.39/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE=
|
||||||
github.com/pion/sdp/v3 v3.0.10 h1:6MChLE/1xYB+CjumMw+gZ9ufp2DPApuVSnDT8t5MIgA=
|
|
||||||
github.com/pion/sdp/v3 v3.0.10/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E=
|
|
||||||
github.com/pion/sdp/v3 v3.0.13 h1:uN3SS2b+QDZnWXgdr69SM8KB4EbcnPnPf2Laxhty/l4=
|
github.com/pion/sdp/v3 v3.0.13 h1:uN3SS2b+QDZnWXgdr69SM8KB4EbcnPnPf2Laxhty/l4=
|
||||||
github.com/pion/sdp/v3 v3.0.13/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E=
|
github.com/pion/sdp/v3 v3.0.13/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E=
|
||||||
github.com/pion/srtp/v3 v3.0.4 h1:2Z6vDVxzrX3UHEgrUyIGM4rRouoC7v+NiF1IHtp9B5M=
|
|
||||||
github.com/pion/srtp/v3 v3.0.4/go.mod h1:1Jx3FwDoxpRaTh1oRV8A/6G1BnFL+QI82eK4ms8EEJQ=
|
|
||||||
github.com/pion/srtp/v3 v3.0.6 h1:E2gyj1f5X10sB/qILUGIkL4C2CqK269Xq167PbGCc/4=
|
github.com/pion/srtp/v3 v3.0.6 h1:E2gyj1f5X10sB/qILUGIkL4C2CqK269Xq167PbGCc/4=
|
||||||
github.com/pion/srtp/v3 v3.0.6/go.mod h1:BxvziG3v/armJHAaJ87euvkhHqWe9I7iiOy50K2QkhY=
|
github.com/pion/srtp/v3 v3.0.6/go.mod h1:BxvziG3v/armJHAaJ87euvkhHqWe9I7iiOy50K2QkhY=
|
||||||
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
|
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
|
||||||
@ -642,34 +406,23 @@ github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQp
|
|||||||
github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E=
|
github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E=
|
||||||
github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=
|
github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=
|
||||||
github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
|
github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
|
||||||
github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM=
|
|
||||||
github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA=
|
|
||||||
github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps=
|
github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps=
|
||||||
github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs=
|
github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs=
|
||||||
github.com/pion/webrtc/v4 v4.0.10 h1:Hq/JLjhqLxi+NmCtE8lnRPDr8H4LcNvwg8OxVcdv56Q=
|
|
||||||
github.com/pion/webrtc/v4 v4.0.10/go.mod h1:ViHLVaNpiuvaH8pdiuQxuA9awuE6KVzAXx3vVWilOck=
|
|
||||||
github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54=
|
github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54=
|
||||||
github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U=
|
github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
|
||||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
|
||||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
|
||||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
|
||||||
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
||||||
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
@ -682,8 +435,6 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
|||||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||||
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
|
|
||||||
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
|
|
||||||
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
|
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
|
||||||
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
|
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
|
||||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
@ -694,22 +445,12 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
|
|||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
||||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
|
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
|
||||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
|
||||||
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
|
||||||
github.com/quic-go/quic-go v0.50.1 h1:unsgjFIUqW8a2oopkY7YNONpV1gYND6Nt9hnt1PN94Q=
|
github.com/quic-go/quic-go v0.50.1 h1:unsgjFIUqW8a2oopkY7YNONpV1gYND6Nt9hnt1PN94Q=
|
||||||
github.com/quic-go/quic-go v0.50.1/go.mod h1:Vim6OmUvlYdwBhXP9ZVrtGmCMWa3wEqhq3NgYrI8b4E=
|
github.com/quic-go/quic-go v0.50.1/go.mod h1:Vim6OmUvlYdwBhXP9ZVrtGmCMWa3wEqhq3NgYrI8b4E=
|
||||||
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
|
||||||
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
|
||||||
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
|
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
|
||||||
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
|
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
|
||||||
github.com/quic-go/webtransport-go v0.9.0 h1:jgys+7/wm6JarGDrW+lD/r9BGqBAmqY/ssklE09bA70=
|
|
||||||
github.com/quic-go/webtransport-go v0.9.0/go.mod h1:4FUYIiUc75XSsF6HShcLeXXYZJ9AGwo/xh3L8M/P1ao=
|
|
||||||
github.com/quic-go/webtransport-go v0.10.0 h1:LqXXPOXuETY5Xe8ITdGisBzTYmUOy5eSj+9n4hLTjHI=
|
|
||||||
github.com/quic-go/webtransport-go v0.10.0/go.mod h1:LeGIXr5BQKE3UsynwVBeQrU1TPrbh73MGoC6jd+V7ow=
|
|
||||||
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
|
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
|
||||||
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
|
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
|
||||||
github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI=
|
github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI=
|
||||||
@ -717,8 +458,7 @@ github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q
|
|||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
|
||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/rqlite/gorqlite v0.0.0-20250609141355-ac86a4a1c9a8 h1:BoxiqWvhprOB2isgM59s8wkgKwAoyQH66Twfmof41oE=
|
github.com/rqlite/gorqlite v0.0.0-20250609141355-ac86a4a1c9a8 h1:BoxiqWvhprOB2isgM59s8wkgKwAoyQH66Twfmof41oE=
|
||||||
github.com/rqlite/gorqlite v0.0.0-20250609141355-ac86a4a1c9a8/go.mod h1:xF/KoXmrRyahPfo5L7Szb5cAAUl53dMWBh9cMruGEZg=
|
github.com/rqlite/gorqlite v0.0.0-20250609141355-ac86a4a1c9a8/go.mod h1:xF/KoXmrRyahPfo5L7Szb5cAAUl53dMWBh9cMruGEZg=
|
||||||
@ -727,12 +467,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
|
|||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/secure-systems-lab/go-securesystemslib v0.9.0 h1:rf1HIbL64nUpEIZnjLZ3mcNEL9NBPB0iuVjyxvq3LZc=
|
|
||||||
github.com/secure-systems-lab/go-securesystemslib v0.9.0/go.mod h1:DVHKMcZ+V4/woA/peqr+L0joiRXbPpQ042GgJckkFgw=
|
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU=
|
|
||||||
github.com/shirou/gopsutil/v4 v4.25.8-0.20250809033336-ffcdc2b7662f h1:S+PHRM3lk96X0/cGEGUukqltzkX/ekUx0F9DoCGK1G0=
|
|
||||||
github.com/shirou/gopsutil/v4 v4.25.8-0.20250809033336-ffcdc2b7662f/go.mod h1:4f4j4w8HLMPWEFs3BO2UBBLigKAaWYwkSkbIt/6Q4Ss=
|
|
||||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||||
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
||||||
@ -778,18 +513,13 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
|||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
|
||||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||||
github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA=
|
github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA=
|
||||||
github.com/tetratelabs/wazero v1.11.0/go.mod h1:eV28rsN8Q+xwjogd7f4/Pp4xFxO7uOGbLcD/LzB1wiU=
|
github.com/tetratelabs/wazero v1.11.0/go.mod h1:eV28rsN8Q+xwjogd7f4/Pp4xFxO7uOGbLcD/LzB1wiU=
|
||||||
github.com/theckman/httpforwarded v0.4.0 h1:N55vGJT+6ojTnLY3LQCNliJC4TW0P0Pkeys1G1WpX2w=
|
|
||||||
github.com/theckman/httpforwarded v0.4.0/go.mod h1:GVkFynv6FJreNbgH/bpOU9ITDZ7a5WuzdNCtIMI1pVI=
|
|
||||||
github.com/tidwall/btree v1.1.0/go.mod h1:TzIRzen6yHbibdSfK6t8QimqbUnoxUSrZfeW7Uob0q4=
|
github.com/tidwall/btree v1.1.0/go.mod h1:TzIRzen6yHbibdSfK6t8QimqbUnoxUSrZfeW7Uob0q4=
|
||||||
github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI=
|
github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI=
|
||||||
github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY=
|
github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY=
|
||||||
@ -797,12 +527,6 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
|||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/redcon v1.6.2 h1:5qfvrrybgtO85jnhSravmkZyC0D+7WstbfCs3MmPhow=
|
github.com/tidwall/redcon v1.6.2 h1:5qfvrrybgtO85jnhSravmkZyC0D+7WstbfCs3MmPhow=
|
||||||
github.com/tidwall/redcon v1.6.2/go.mod h1:p5Wbsgeyi2VSTBWOcA5vRXrOb9arFTcU2+ZzFjqV75Y=
|
github.com/tidwall/redcon v1.6.2/go.mod h1:p5Wbsgeyi2VSTBWOcA5vRXrOb9arFTcU2+ZzFjqV75Y=
|
||||||
github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww=
|
|
||||||
github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
|
||||||
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
|
|
||||||
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
|
|
||||||
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
|
|
||||||
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
|
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||||
@ -814,64 +538,28 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV
|
|||||||
github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
||||||
github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
|
github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
|
||||||
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
|
||||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
|
||||||
go.etcd.io/etcd/api/v3 v3.6.7 h1:7BNJ2gQmc3DNM+9cRkv7KkGQDayElg8x3X+tFDYS+E0=
|
|
||||||
go.etcd.io/etcd/api/v3 v3.6.7/go.mod h1:xJ81TLj9hxrYYEDmXTeKURMeY3qEDN24hqe+q7KhbnI=
|
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.6.7 h1:vvzgyozz46q+TyeGBuFzVuI53/yd133CHceNb/AhBVs=
|
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.6.7/go.mod h1:2IVulJ3FZ/czIGl9T4lMF1uxzrhRahLqe+hSgy+Kh7Q=
|
|
||||||
go.etcd.io/etcd/client/v3 v3.6.7 h1:9WqA5RpIBtdMxAy1ukXLAdtg2pAxNqW5NUoO2wQrE6U=
|
|
||||||
go.etcd.io/etcd/client/v3 v3.6.7/go.mod h1:2XfROY56AXnUqGsvl+6k29wrwsSbEh1lAouQB1vHpeE=
|
|
||||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||||
go.opentelemetry.io/collector/component v1.39.0 h1:GJw80zXURBG4h0sh97bPLEn2Ra+NAWUpskaooA0wru4=
|
|
||||||
go.opentelemetry.io/collector/component v1.39.0/go.mod h1:NPaMPTLQuxm5QaaWdqkxYKztC0bRdV+86Q9ir7xS/2k=
|
|
||||||
go.opentelemetry.io/collector/featuregate v1.46.0 h1:z3JlymFdWW6aDo9cYAJ6bCqT+OI2DlurJ9P8HqfuKWQ=
|
|
||||||
go.opentelemetry.io/collector/featuregate v1.46.0/go.mod h1:d0tiRzVYrytB6LkcYgz2ESFTv7OktRPQe0QEQcPt1L4=
|
|
||||||
go.opentelemetry.io/collector/internal/telemetry v0.133.0 h1:YxbckZC9HniNOZgnSofTOe0AB/bEsmISNdQeS+3CU3o=
|
|
||||||
go.opentelemetry.io/collector/internal/telemetry v0.133.0/go.mod h1:akUK7X6ZQ+CbbCjyXLv9y/EHt5jIy+J+nGoLvndZN14=
|
|
||||||
go.opentelemetry.io/collector/pdata v1.46.0 h1:XzhnIWNtc/gbOyFiewRvybR4s3phKHrWxL3yc/wVLDo=
|
|
||||||
go.opentelemetry.io/collector/pdata v1.46.0/go.mod h1:D2e3BWCUC/bUg29WNzCDVN7Ab0Gzk7hGXZL2pnrDOn0=
|
|
||||||
go.opentelemetry.io/collector/pdata/pprofile v0.140.0 h1:b9TZ6UnyzsT/ERQw2VKGi/NYLtKSmjG7cgQuc9wZt5s=
|
|
||||||
go.opentelemetry.io/collector/pdata/pprofile v0.140.0/go.mod h1:/2s/YBWGbu+r8MuKu5zas08iSqe+3P6xnbRpfE2DWAA=
|
|
||||||
go.opentelemetry.io/contrib/bridges/otelzap v0.12.0 h1:FGre0nZh5BSw7G73VpT3xs38HchsfPsa2aZtMp0NPOs=
|
|
||||||
go.opentelemetry.io/contrib/bridges/otelzap v0.12.0/go.mod h1:X2PYPViI2wTPIMIOBjG17KNybTzsrATnvPJ02kkz7LM=
|
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
|
||||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
||||||
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
||||||
go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls=
|
|
||||||
go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E=
|
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
|
||||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
|
||||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
|
||||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
|
||||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
|
||||||
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
|
|
||||||
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
|
||||||
go.uber.org/dig v1.19.0 h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4=
|
go.uber.org/dig v1.19.0 h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4=
|
||||||
go.uber.org/dig v1.19.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
go.uber.org/dig v1.19.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
||||||
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
|
|
||||||
go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU=
|
|
||||||
go.uber.org/fx v1.24.0 h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg=
|
go.uber.org/fx v1.24.0 h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg=
|
||||||
go.uber.org/fx v1.24.0/go.mod h1:AmDeGyS+ZARGKM4tlH4FY2Jr63VjbEDJHtqXTGP5hbo=
|
go.uber.org/fx v1.24.0/go.mod h1:AmDeGyS+ZARGKM4tlH4FY2Jr63VjbEDJHtqXTGP5hbo=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
|
||||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
|
||||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
@ -880,7 +568,6 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
|||||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
|
||||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||||
@ -894,13 +581,9 @@ golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPh
|
|||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
|
||||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
|
||||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
|
||||||
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||||
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@ -913,11 +596,8 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
|
|||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
|
||||||
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
|
||||||
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
|
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
|
||||||
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
|
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -932,30 +612,23 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
|
||||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
|
||||||
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||||
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
|
||||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
|
||||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -968,8 +641,6 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
|
||||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
|
||||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -982,8 +653,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -994,27 +663,18 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
|
||||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
|
||||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA=
|
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA=
|
||||||
@ -1025,7 +685,6 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
|||||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
|
||||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||||
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
||||||
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
||||||
@ -1033,20 +692,15 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
|
||||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
|
||||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
|
||||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@ -1056,28 +710,22 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm
|
|||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
|
||||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
|
||||||
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
|
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
|
||||||
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
|
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||||
google.golang.org/api v0.259.0 h1:90TaGVIxScrh1Vn/XI2426kRpBqHwWIzVBzJsVZ5XrQ=
|
|
||||||
google.golang.org/api v0.259.0/go.mod h1:LC2ISWGWbRoyQVpxGntWwLWN/vLNxxKBK9KuJRI8Te4=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
@ -1087,9 +735,6 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
|
|||||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934=
|
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
@ -1105,8 +750,6 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
|
|||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
|
||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
|
||||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
@ -1115,12 +758,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
|||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
|
||||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
@ -1135,29 +773,9 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd
|
|||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4=
|
|
||||||
k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk=
|
|
||||||
k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE=
|
|
||||||
k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
|
||||||
k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A=
|
|
||||||
k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM=
|
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
|
||||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=
|
|
||||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
|
|
||||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
|
|
||||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
|
||||||
lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
|
lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
|
||||||
lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=
|
lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs=
|
||||||
sigs.k8s.io/mcs-api v0.3.0 h1:LjRvgzjMrvO1904GP6XBJSnIX221DJMyQlZOYt9LAnM=
|
|
||||||
sigs.k8s.io/mcs-api v0.3.0/go.mod h1:zZ5CK8uS6HaLkxY4HqsmcBHfzHuNMrY2uJy8T7jffK4=
|
|
||||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
|
||||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
|
||||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
|
||||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
|
||||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||||
@ -1,4 +1,4 @@
|
|||||||
-- DeBros Gateway - Initial database schema (SQLite/RQLite dialect)
|
-- Orama Gateway - Initial database schema (SQLite/RQLite dialect)
|
||||||
-- This file scaffolds core tables used by the HTTP gateway for auth, observability, and namespacing.
|
-- This file scaffolds core tables used by the HTTP gateway for auth, observability, and namespacing.
|
||||||
-- Apply via your migration tooling or manual execution in RQLite.
|
-- Apply via your migration tooling or manual execution in RQLite.
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
-- DeBros Gateway - Core schema (Phase 2)
|
-- Orama Gateway - Core schema (Phase 2)
|
||||||
-- Adds apps, nonces, subscriptions, refresh_tokens, audit_events, namespace_ownership
|
-- Adds apps, nonces, subscriptions, refresh_tokens, audit_events, namespace_ownership
|
||||||
-- SQLite/RQLite dialect
|
-- SQLite/RQLite dialect
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
-- DeBros Gateway - Wallet to API Key linkage (Phase 3)
|
-- Orama Gateway - Wallet to API Key linkage (Phase 3)
|
||||||
-- Ensures one API key per (namespace, wallet) and enables lookup
|
-- Ensures one API key per (namespace, wallet) and enables lookup
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user