mid code commit
This commit is contained in:
parent
c293bd9880
commit
1ac70634bd
138
apps/DEVELOPMENT.md
Normal file
138
apps/DEVELOPMENT.md
Normal file
@ -0,0 +1,138 @@
|
||||
# Archipelago Apps - Development Guide
|
||||
|
||||
This directory contains all prepackaged containerized applications for Archipelago NodeOS.
|
||||
|
||||
## App Overview
|
||||
|
||||
### Bitcoin & Lightning
|
||||
- **bitcoin-core**: Full Bitcoin node (ports: 8332, 8333)
|
||||
- **lnd**: Lightning Network Daemon (ports: 9735, 10009, 8080)
|
||||
- **core-lightning**: Core Lightning implementation (ports: 9736, 9835)
|
||||
- **btcpay-server**: Bitcoin payment processor (ports: 80, 443)
|
||||
|
||||
### Nostr Relays
|
||||
- **nostr-rs-relay**: High-performance Rust relay (port: 8081)
|
||||
- **strfry**: Lightweight C++ relay (port: 8082)
|
||||
|
||||
### Web5 & Decentralized Protocols
|
||||
- **web5-dwn**: Decentralized Web Node (port: 3000)
|
||||
- **did-wallet**: Web5 DID Wallet (port: 8083)
|
||||
|
||||
### Mesh Networking
|
||||
- **router**: Mesh routing and network management (ports: 8084, 5353, 1900)
|
||||
- **meshtastic**: LoRa mesh networking (ports: 4403, 1883)
|
||||
|
||||
## Port Assignments
|
||||
|
||||
All apps use unique base ports. In development mode, ports are offset by 10000 (configurable).
|
||||
|
||||
| App | Base Ports | Dev Ports (offset +10000) |
|
||||
|-----|------------|---------------------------|
|
||||
| bitcoin-core | 8332, 8333 | 18332, 18333 |
|
||||
| lnd | 9735, 10009, 8080 | 19735, 20009, 18080 |
|
||||
| core-lightning | 9736, 9835 | 19736, 19835 |
|
||||
| btcpay-server | 80, 443 | 10080, 10443 |
|
||||
| nostr-rs-relay | 8081 | 18081 |
|
||||
| strfry | 8082 | 18082 |
|
||||
| did-wallet | 8083 | 18083 |
|
||||
| router | 8084, 5353, 1900 | 18084, 15353, 11900 |
|
||||
| web5-dwn | 3000 | 13000 |
|
||||
| meshtastic | 4403, 1883 | 14403, 11883 |
|
||||
|
||||
## Building Apps
|
||||
|
||||
### Build All Apps
|
||||
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
### Build Specific App
|
||||
|
||||
```bash
|
||||
./build.sh <app-id>
|
||||
```
|
||||
|
||||
### Build for Development
|
||||
|
||||
```bash
|
||||
./build.sh <app-id> --dev
|
||||
```
|
||||
|
||||
## App Structure
|
||||
|
||||
Each app directory contains:
|
||||
|
||||
- `manifest.yml` - App manifest defining container configuration
|
||||
- `Dockerfile` - Container image definition
|
||||
- `README.md` - App-specific documentation (for custom apps)
|
||||
- Source code (for custom apps: router, did-wallet, web5-dwn)
|
||||
|
||||
## Custom Apps
|
||||
|
||||
The following apps have custom implementations:
|
||||
|
||||
1. **router** - TypeScript/Node.js mesh router
|
||||
2. **did-wallet** - TypeScript/Node.js Web5 wallet
|
||||
3. **web5-dwn** - TypeScript/Node.js DWN server
|
||||
|
||||
These apps can be developed locally:
|
||||
|
||||
```bash
|
||||
cd apps/<app-id>
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Standard Apps
|
||||
|
||||
The following apps use official Docker images:
|
||||
|
||||
- bitcoin-core (bitcoin/bitcoin:26.0)
|
||||
- lnd (lightninglabs/lnd:v0.18.0)
|
||||
- core-lightning (elementsproject/lightningd:v23.08.2)
|
||||
- btcpay-server (btcpayserver/btcpayserver:1.12.0)
|
||||
- nostr-rs-relay (scsibug/nostr-rs-relay:latest)
|
||||
- strfry (strfry/strfry:latest)
|
||||
- meshtastic (meshtastic/meshtastic:latest)
|
||||
|
||||
## Running in Development
|
||||
|
||||
### Using Archipelago Backend
|
||||
|
||||
The Archipelago backend will automatically:
|
||||
1. Build local images if they don't exist
|
||||
2. Apply port offsets in dev mode
|
||||
3. Map volumes to `/tmp/archipelago-dev/<app-id>`
|
||||
4. Start containers with proper networking
|
||||
|
||||
### Manual Testing
|
||||
|
||||
You can test apps manually:
|
||||
|
||||
```bash
|
||||
# Build the app
|
||||
./build.sh <app-id>
|
||||
|
||||
# Run with Docker/Podman
|
||||
docker run -p <host-port>:<container-port> \
|
||||
-v /tmp/archipelago-dev/<app-id>:/data \
|
||||
archipelago/<app-id>:latest
|
||||
```
|
||||
|
||||
## Integration with Archipelago
|
||||
|
||||
Apps are integrated via:
|
||||
|
||||
1. **Manifest files** - Define app configuration
|
||||
2. **Container runtime** - Podman/Docker for execution
|
||||
3. **Port manager** - Handles port allocation and offsets
|
||||
4. **Dev orchestrator** - Manages containers in development
|
||||
|
||||
## Next Steps
|
||||
|
||||
When building the OS image, these apps will be:
|
||||
1. Built into container images
|
||||
2. Included in the OS image
|
||||
3. Available for installation via the UI
|
||||
4. Pre-configured with proper networking and security
|
||||
57
apps/PORTS.md
Normal file
57
apps/PORTS.md
Normal file
@ -0,0 +1,57 @@
|
||||
# Port Assignments Reference
|
||||
|
||||
This document lists all port assignments for Archipelago apps.
|
||||
|
||||
## Production Ports
|
||||
|
||||
| App | Port(s) | Protocol | Service |
|
||||
|-----|---------|----------|---------|
|
||||
| bitcoin-core | 8332, 8333 | TCP | RPC, P2P |
|
||||
| lnd | 9735, 10009, 8080 | TCP | P2P, gRPC, REST |
|
||||
| core-lightning | 9736, 9835 | TCP | P2P, gRPC |
|
||||
| btcpay-server | 80, 443 | TCP | HTTP, HTTPS |
|
||||
| nostr-rs-relay | 8081 | TCP | HTTP/WebSocket |
|
||||
| strfry | 8082 | TCP | HTTP/WebSocket |
|
||||
| did-wallet | 8083 | TCP | Web UI |
|
||||
| router | 8084, 5353, 1900 | TCP/UDP | Web UI, mDNS, SSDP |
|
||||
| web5-dwn | 3000 | TCP | HTTP API |
|
||||
| meshtastic | 4403, 1883 | TCP | HTTP API, MQTT |
|
||||
|
||||
## Development Ports (Offset: +10000)
|
||||
|
||||
In development mode, all ports are offset by 10000 to avoid conflicts with production services.
|
||||
|
||||
| App | Dev Port(s) | Access URL |
|
||||
|-----|-------------|------------|
|
||||
| bitcoin-core | 18332, 18333 | http://localhost:18332 |
|
||||
| lnd | 19735, 20009, 18080 | http://localhost:18080 |
|
||||
| core-lightning | 19736, 19835 | http://localhost:19835 |
|
||||
| btcpay-server | 10080, 10443 | http://localhost:10080 |
|
||||
| nostr-rs-relay | 18081 | http://localhost:18081 |
|
||||
| strfry | 18082 | http://localhost:18082 |
|
||||
| did-wallet | 18083 | http://localhost:18083 |
|
||||
| router | 18084, 15353, 11900 | http://localhost:18084 |
|
||||
| web5-dwn | 13000 | http://localhost:13000 |
|
||||
| meshtastic | 14403, 11883 | http://localhost:14403 |
|
||||
|
||||
## Port Conflict Resolution
|
||||
|
||||
All apps use unique base ports to prevent conflicts. The port offset system ensures:
|
||||
- No conflicts in production (each app has unique ports)
|
||||
- No conflicts in development (offset applied automatically)
|
||||
- Easy port management via PortManager
|
||||
|
||||
## Changing Port Offset
|
||||
|
||||
The port offset is configurable via environment variable:
|
||||
|
||||
```bash
|
||||
ARCHIPELAGO_PORT_OFFSET=10000
|
||||
```
|
||||
|
||||
Or in the Archipelago config:
|
||||
|
||||
```toml
|
||||
[dev]
|
||||
port_offset = 10000
|
||||
```
|
||||
109
apps/QUICKSTART.md
Normal file
109
apps/QUICKSTART.md
Normal file
@ -0,0 +1,109 @@
|
||||
# Quick Start Guide - Archipelago Apps
|
||||
|
||||
This guide will help you get all prepackaged apps running in your development environment.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Container Runtime**: Podman or Docker
|
||||
```bash
|
||||
# Check if available
|
||||
podman --version # or docker --version
|
||||
```
|
||||
|
||||
2. **Node.js** (for custom apps): v18+
|
||||
```bash
|
||||
node --version
|
||||
```
|
||||
|
||||
3. **Archipelago Backend**: Running in dev mode
|
||||
```bash
|
||||
cd core
|
||||
ARCHIPELAGO_DEV_MODE=true cargo run --bin archipelago
|
||||
```
|
||||
|
||||
## Building Apps
|
||||
|
||||
### Build All Apps
|
||||
|
||||
```bash
|
||||
cd apps
|
||||
./build.sh
|
||||
```
|
||||
|
||||
This will build all apps that have Dockerfiles. Standard apps (bitcoin-core, lnd, etc.) will use their official images, while custom apps (router, did-wallet, web5-dwn) will be built from source.
|
||||
|
||||
### Build Specific App
|
||||
|
||||
```bash
|
||||
./build.sh router
|
||||
./build.sh did-wallet
|
||||
./build.sh web5-dwn
|
||||
```
|
||||
|
||||
## Running Apps via Archipelago
|
||||
|
||||
Once the backend is running, you can install and start apps via:
|
||||
|
||||
1. **UI**: Navigate to http://localhost:8100 and use the Apps/Marketplace interface
|
||||
2. **RPC**: Use the container-install RPC method
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:5959/rpc/v1 \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"method": "container-install",
|
||||
"params": {
|
||||
"manifest_path": "apps/router/manifest.yml"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Port Access
|
||||
|
||||
In development mode, apps are accessible on offset ports:
|
||||
|
||||
- **Router**: http://localhost:18084
|
||||
- **DID Wallet**: http://localhost:18083
|
||||
- **Web5 DWN**: http://localhost:13000
|
||||
- **Nostr RS Relay**: http://localhost:18081
|
||||
- **Strfry**: http://localhost:18082
|
||||
|
||||
See [PORTS.md](./PORTS.md) for complete port mapping.
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### For Custom Apps (router, did-wallet, web5-dwn)
|
||||
|
||||
1. **Make changes** to source code in `apps/<app-id>/src/`
|
||||
2. **Rebuild** the container:
|
||||
```bash
|
||||
./build.sh <app-id>
|
||||
```
|
||||
3. **Restart** the container via Archipelago UI or RPC
|
||||
|
||||
### For Standard Apps
|
||||
|
||||
Standard apps use official images. To customize:
|
||||
1. Create a custom Dockerfile that extends the official image
|
||||
2. Add your customizations
|
||||
3. Update the manifest to use your custom image
|
||||
|
||||
## Testing Locally
|
||||
|
||||
You can test apps directly without Archipelago:
|
||||
|
||||
```bash
|
||||
# Build
|
||||
./build.sh router
|
||||
|
||||
# Run
|
||||
docker run -p 18084:8080 \
|
||||
-v /tmp/archipelago-dev/router:/app/data \
|
||||
archipelago/router:latest
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Read [DEVELOPMENT.md](./DEVELOPMENT.md) for detailed development information
|
||||
- Check [PORTS.md](./PORTS.md) for port assignments
|
||||
- Review individual app READMEs for app-specific details
|
||||
5
apps/bitcoin-core/Dockerfile
Normal file
5
apps/bitcoin-core/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Bitcoin Core - uses official image
|
||||
FROM bitcoin/bitcoin:24.0
|
||||
|
||||
# Default user is already 'bitcoin'
|
||||
# No additional setup needed
|
||||
@ -1,11 +1,11 @@
|
||||
app:
|
||||
id: bitcoin-core
|
||||
name: Bitcoin Core
|
||||
version: 26.0.0
|
||||
version: 24.0.0
|
||||
description: Full Bitcoin node implementation. The reference implementation of the Bitcoin protocol.
|
||||
|
||||
container:
|
||||
image: bitcoin/bitcoin:26.0
|
||||
image: bitcoin/bitcoin:24.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: verify-signature
|
||||
|
||||
|
||||
5
apps/btcpay-server/Dockerfile
Normal file
5
apps/btcpay-server/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# BTCPay Server - uses official image
|
||||
FROM btcpayserver/btcpayserver:1.12.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
85
apps/build.sh
Executable file
85
apps/build.sh
Executable file
@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
# Build script for Archipelago apps
|
||||
# Usage: ./build.sh [app-id] [--dev]
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
APPS_DIR="$SCRIPT_DIR"
|
||||
|
||||
# Determine container runtime
|
||||
RUNTIME="auto"
|
||||
if command -v podman >/dev/null 2>&1 && podman info >/dev/null 2>&1; then
|
||||
RUNTIME="podman"
|
||||
elif command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
|
||||
RUNTIME="docker"
|
||||
else
|
||||
echo "❌ No container runtime available (Podman or Docker required)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🐳 Using runtime: $RUNTIME"
|
||||
|
||||
# Build function
|
||||
build_app() {
|
||||
local app_id=$1
|
||||
local app_dir="$APPS_DIR/$app_id"
|
||||
local dev_mode=$2
|
||||
|
||||
if [ ! -d "$app_dir" ]; then
|
||||
echo "❌ App directory not found: $app_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$app_dir/Dockerfile" ]; then
|
||||
echo "⚠️ No Dockerfile found for $app_id, skipping..."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🔨 Building $app_id..."
|
||||
|
||||
local image_tag="archipelago/$app_id:latest"
|
||||
if [ "$dev_mode" = "--dev" ]; then
|
||||
image_tag="archipelago/$app_id:dev"
|
||||
fi
|
||||
|
||||
cd "$app_dir"
|
||||
|
||||
# For Node.js apps, install dependencies first
|
||||
if [ -f "package.json" ]; then
|
||||
echo " Installing Node.js dependencies..."
|
||||
npm install --production=false
|
||||
fi
|
||||
|
||||
# Build the image
|
||||
echo " Building container image: $image_tag"
|
||||
$RUNTIME build -t "$image_tag" .
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ $app_id built successfully: $image_tag"
|
||||
else
|
||||
echo "❌ Failed to build $app_id"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main logic
|
||||
if [ $# -eq 0 ]; then
|
||||
# Build all apps
|
||||
echo "🔨 Building all Archipelago apps..."
|
||||
for app_dir in "$APPS_DIR"/*/; do
|
||||
if [ -d "$app_dir" ] && [ -f "$app_dir/manifest.yml" ]; then
|
||||
app_id=$(basename "$app_dir")
|
||||
build_app "$app_id" "$@"
|
||||
fi
|
||||
done
|
||||
else
|
||||
# Build specific app
|
||||
app_id=$1
|
||||
shift
|
||||
build_app "$app_id" "$@"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Build complete!"
|
||||
5
apps/core-lightning/Dockerfile
Normal file
5
apps/core-lightning/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Core Lightning - uses official image
|
||||
FROM elementsproject/lightningd:v23.08.2
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@ -25,9 +25,9 @@ app:
|
||||
apparmor_profile: core-lightning
|
||||
|
||||
ports:
|
||||
- host: 9735
|
||||
- host: 9736
|
||||
container: 9735
|
||||
protocol: tcp # P2P
|
||||
protocol: tcp # P2P (using 9736 to avoid conflict with LND)
|
||||
- host: 9835
|
||||
container: 9835
|
||||
protocol: tcp # gRPC
|
||||
|
||||
6
apps/did-wallet/.dockerignore
Normal file
6
apps/did-wallet/.dockerignore
Normal file
@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
39
apps/did-wallet/Dockerfile
Normal file
39
apps/did-wallet/Dockerfile
Normal file
@ -0,0 +1,39 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
mkdir -p /app/wallet && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENV WALLET_STORAGE=/app/wallet
|
||||
ENV DWN_ENDPOINT=http://web5-dwn:3000
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
35
apps/did-wallet/README.md
Normal file
35
apps/did-wallet/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# DID Wallet
|
||||
|
||||
Web5 wallet with Decentralized Identifier (DID) support.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# From the apps directory
|
||||
./build.sh did-wallet
|
||||
|
||||
# Or manually
|
||||
cd did-wallet
|
||||
docker build -t archipelago/did-wallet:latest .
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
cd did-wallet
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Ports
|
||||
|
||||
- **8083**: Web UI (dev: 18083)
|
||||
|
||||
## Running Locally
|
||||
|
||||
```bash
|
||||
docker run -p 8083:8080 \
|
||||
-v /tmp/archipelago-dev/did-wallet:/app/wallet \
|
||||
-e DWN_ENDPOINT=http://localhost:13000 \
|
||||
archipelago/did-wallet:latest
|
||||
```
|
||||
@ -5,9 +5,9 @@ app:
|
||||
description: Web5 wallet with Decentralized Identifier (DID) support. Manage your digital identity and Web5 assets.
|
||||
|
||||
container:
|
||||
image: tbd/web5-wallet:latest
|
||||
image: archipelago/did-wallet:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: verify-signature
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- app_id: web5-dwn
|
||||
@ -26,7 +26,7 @@ app:
|
||||
apparmor_profile: did-wallet
|
||||
|
||||
ports:
|
||||
- host: 8080
|
||||
- host: 8083
|
||||
container: 8080
|
||||
protocol: tcp # Web UI
|
||||
|
||||
@ -42,7 +42,7 @@ app:
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8080
|
||||
endpoint: http://localhost:8083
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
|
||||
21
apps/did-wallet/package.json
Normal file
21
apps/did-wallet/package.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "did-wallet",
|
||||
"version": "1.0.0",
|
||||
"description": "Web5 DID Wallet for Archipelago",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"@web5/api": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
23
apps/did-wallet/public/index.html
Normal file
23
apps/did-wallet/public/index.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>DID Wallet</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Web5 DID Wallet</h1>
|
||||
<p>Decentralized Identity Wallet for Archipelago</p>
|
||||
<div id="app">
|
||||
<p>Wallet interface coming soon...</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
38
apps/did-wallet/src/index.ts
Normal file
38
apps/did-wallet/src/index.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
const port = 8080;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
app.use(express.static('public'));
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'did-wallet' });
|
||||
});
|
||||
|
||||
// Wallet API endpoints
|
||||
app.get('/api/wallet/info', (req, res) => {
|
||||
res.json({
|
||||
status: 'ok',
|
||||
wallet: {
|
||||
dids: [],
|
||||
balance: 0
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/api/wallet/did/create', async (req, res) => {
|
||||
// Placeholder for DID creation
|
||||
res.json({
|
||||
status: 'ok',
|
||||
did: 'did:key:placeholder'
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`DID Wallet listening on port ${port}`);
|
||||
console.log(`DWN endpoint: ${process.env.DWN_ENDPOINT || 'http://web5-dwn:3000'}`);
|
||||
});
|
||||
16
apps/did-wallet/tsconfig.json
Normal file
16
apps/did-wallet/tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
6
apps/endurain/.dockerignore
Normal file
6
apps/endurain/.dockerignore
Normal file
@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
37
apps/endurain/Dockerfile
Normal file
37
apps/endurain/Dockerfile
Normal file
@ -0,0 +1,37 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
mkdir -p /app/data && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENV ENDURAIN_DATA_DIR=/app/data
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
47
apps/endurain/manifest.yml
Normal file
47
apps/endurain/manifest.yml
Normal file
@ -0,0 +1,47 @@
|
||||
app:
|
||||
id: endurain
|
||||
name: Endurain
|
||||
version: 1.0.0
|
||||
description: Endurain application platform. Custom application runtime.
|
||||
|
||||
container:
|
||||
image: archipelago/endurain:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 2Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 1Gi
|
||||
disk_limit: 2Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: endurain
|
||||
|
||||
ports:
|
||||
- host: 8085
|
||||
container: 8080
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/endurain
|
||||
target: /app/data
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- ENDURAIN_ENV=production
|
||||
- ENDURAIN_DATA_DIR=/app/data
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8085
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
20
apps/endurain/package.json
Normal file
20
apps/endurain/package.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "endurain",
|
||||
"version": "1.0.0",
|
||||
"description": "Endurain application platform",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
27
apps/endurain/src/index.ts
Normal file
27
apps/endurain/src/index.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
const port = 8080;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'endurain', version: '1.0.0' });
|
||||
});
|
||||
|
||||
// API endpoints
|
||||
app.get('/api/info', (req, res) => {
|
||||
res.json({
|
||||
name: 'Endurain',
|
||||
version: '1.0.0',
|
||||
status: 'running'
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`Endurain listening on port ${port}`);
|
||||
console.log(`Data directory: ${process.env.ENDURAIN_DATA_DIR || '/app/data'}`);
|
||||
});
|
||||
16
apps/endurain/tsconfig.json
Normal file
16
apps/endurain/tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
5
apps/fedimint/Dockerfile
Normal file
5
apps/fedimint/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Fedimint - uses official image
|
||||
FROM fedimint/fedimint:0.3.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
58
apps/fedimint/manifest.yml
Normal file
58
apps/fedimint/manifest.yml
Normal file
@ -0,0 +1,58 @@
|
||||
app:
|
||||
id: fedimint
|
||||
name: Fedimint
|
||||
version: 0.3.0
|
||||
description: Federated Bitcoin minting service. Privacy-preserving Bitcoin custody.
|
||||
|
||||
container:
|
||||
image: fedimint/fedimint:0.3.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- app_id: bitcoin-core
|
||||
version: ">=24.0"
|
||||
- storage: 20Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 4
|
||||
memory_limit: 4Gi
|
||||
disk_limit: 20Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: fedimint
|
||||
|
||||
ports:
|
||||
- host: 8173
|
||||
container: 8173
|
||||
protocol: tcp # API
|
||||
- host: 8174
|
||||
container: 8174
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/fedimint
|
||||
target: /fedimint
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- FM_BITCOIND_RPC=http://bitcoin-core:8332
|
||||
- FM_BITCOIND_RPC_USER=${BITCOIN_RPC_USER}
|
||||
- FM_BITCOIND_RPC_PASS=${BITCOIN_RPC_PASSWORD}
|
||||
- FM_NETWORK=mainnet
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8174
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
bitcoin_integration:
|
||||
rpc_access: admin
|
||||
sync_required: true
|
||||
5
apps/grafana/Dockerfile
Normal file
5
apps/grafana/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Grafana - uses official image
|
||||
FROM grafana/grafana:10.2.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
49
apps/grafana/manifest.yml
Normal file
49
apps/grafana/manifest.yml
Normal file
@ -0,0 +1,49 @@
|
||||
app:
|
||||
id: grafana
|
||||
name: Grafana
|
||||
version: 10.2.0
|
||||
description: Analytics and monitoring platform. Visualize metrics and create dashboards.
|
||||
|
||||
container:
|
||||
image: grafana/grafana:10.2.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 5Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 1Gi
|
||||
disk_limit: 5Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: grafana
|
||||
|
||||
ports:
|
||||
- host: 3001
|
||||
container: 3000
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/grafana
|
||||
target: /var/lib/grafana
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_USER=admin
|
||||
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
|
||||
- GF_SERVER_ROOT_URL=http://localhost:3001
|
||||
- GF_INSTALL_PLUGINS=
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:3001
|
||||
path: /api/health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
5
apps/home-assistant/Dockerfile
Normal file
5
apps/home-assistant/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Home Assistant - uses official image
|
||||
FROM homeassistant/home-assistant:2024.1
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
56
apps/home-assistant/manifest.yml
Normal file
56
apps/home-assistant/manifest.yml
Normal file
@ -0,0 +1,56 @@
|
||||
app:
|
||||
id: home-assistant
|
||||
name: Home Assistant
|
||||
version: 2024.1.0
|
||||
description: Open source home automation platform. Control and monitor your smart home devices.
|
||||
|
||||
container:
|
||||
image: homeassistant/home-assistant:2024.1
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 10Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 2Gi
|
||||
disk_limit: 10Gi
|
||||
|
||||
security:
|
||||
capabilities: [NET_BIND_SERVICE]
|
||||
readonly_root: false # Home Assistant needs write access
|
||||
network_policy: host # Requires host network for device discovery
|
||||
apparmor_profile: home-assistant
|
||||
|
||||
ports:
|
||||
- host: 8123
|
||||
container: 8123
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/home-assistant
|
||||
target: /config
|
||||
options: [rw]
|
||||
- type: bind
|
||||
source: /var/run/dbus
|
||||
target: /var/run/dbus
|
||||
options: [ro]
|
||||
|
||||
devices:
|
||||
- /dev/ttyUSB0 # Serial devices
|
||||
- /dev/ttyACM0 # USB devices
|
||||
|
||||
environment:
|
||||
- TZ=UTC
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8123
|
||||
path: /api/
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
5
apps/lightning-stack/Dockerfile
Normal file
5
apps/lightning-stack/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Lightning Stack - uses official image
|
||||
FROM lightninglabs/lightning-stack:v0.12.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
65
apps/lightning-stack/manifest.yml
Normal file
65
apps/lightning-stack/manifest.yml
Normal file
@ -0,0 +1,65 @@
|
||||
app:
|
||||
id: lightning-stack
|
||||
name: Lightning Stack
|
||||
version: 0.12.0
|
||||
description: Complete Lightning Network implementation. Includes LND, CLN, and management tools.
|
||||
|
||||
container:
|
||||
image: lightninglabs/lightning-stack:v0.12.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- app_id: bitcoin-core
|
||||
version: ">=24.0"
|
||||
- storage: 50Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 4
|
||||
memory_limit: 4Gi
|
||||
disk_limit: 50Gi
|
||||
|
||||
security:
|
||||
capabilities: [NET_BIND_SERVICE]
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: lightning-stack
|
||||
|
||||
ports:
|
||||
- host: 9737
|
||||
container: 9735
|
||||
protocol: tcp # P2P
|
||||
- host: 10010
|
||||
container: 10009
|
||||
protocol: tcp # gRPC
|
||||
- host: 8087
|
||||
container: 8080
|
||||
protocol: tcp # REST/Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/lightning-stack
|
||||
target: /root/.lightning
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- BITCOIND_HOST=bitcoin-core
|
||||
- BITCOIND_RPCUSER=${BITCOIN_RPC_USER}
|
||||
- BITCOIND_RPCPASS=${BITCOIN_RPC_PASSWORD}
|
||||
- NETWORK=mainnet
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8087
|
||||
path: /v1/getinfo
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
bitcoin_integration:
|
||||
rpc_access: admin
|
||||
sync_required: true
|
||||
|
||||
lightning_integration:
|
||||
channel_management: true
|
||||
payment_routing: true
|
||||
5
apps/lnd/Dockerfile
Normal file
5
apps/lnd/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# LND - uses official image
|
||||
FROM lightninglabs/lnd:v0.18.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
5
apps/mempool/Dockerfile
Normal file
5
apps/mempool/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Mempool - uses official image
|
||||
FROM mempool/mempool:v2.5.0
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
56
apps/mempool/manifest.yml
Normal file
56
apps/mempool/manifest.yml
Normal file
@ -0,0 +1,56 @@
|
||||
app:
|
||||
id: mempool
|
||||
name: Mempool
|
||||
version: 2.5.0
|
||||
description: Bitcoin mempool and blockchain explorer. Real-time transaction and block visualization.
|
||||
|
||||
container:
|
||||
image: mempool/mempool:v2.5.0
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- app_id: bitcoin-core
|
||||
version: ">=24.0"
|
||||
- storage: 20Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 2Gi
|
||||
disk_limit: 20Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: mempool
|
||||
|
||||
ports:
|
||||
- host: 4080
|
||||
container: 4080
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/mempool
|
||||
target: /data
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- MEMPOOL_BACKEND=electrum
|
||||
- MEMPOOL_BITCOIN_HOST=bitcoin-core
|
||||
- MEMPOOL_BITCOIN_PORT=8332
|
||||
- MEMPOOL_BITCOIN_USER=${BITCOIN_RPC_USER}
|
||||
- MEMPOOL_BITCOIN_PASSWORD=${BITCOIN_RPC_PASSWORD}
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:4080
|
||||
path: /api/health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
bitcoin_integration:
|
||||
rpc_access: read-only
|
||||
sync_required: true
|
||||
5
apps/meshtastic/Dockerfile
Normal file
5
apps/meshtastic/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Meshtastic - uses official image
|
||||
FROM meshtastic/meshtastic:latest
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@ -24,8 +24,12 @@ app:
|
||||
apparmor_profile: meshtastic
|
||||
|
||||
ports:
|
||||
- 4403:4403 # HTTP API
|
||||
- 1883:1883 # MQTT (optional)
|
||||
- host: 4403
|
||||
container: 4403
|
||||
protocol: tcp # HTTP API
|
||||
- host: 1883
|
||||
container: 1883
|
||||
protocol: tcp # MQTT (optional)
|
||||
|
||||
devices:
|
||||
- /dev/ttyUSB0 # LoRa radio device (if connected)
|
||||
|
||||
6
apps/morphos-server/.dockerignore
Normal file
6
apps/morphos-server/.dockerignore
Normal file
@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
37
apps/morphos-server/Dockerfile
Normal file
37
apps/morphos-server/Dockerfile
Normal file
@ -0,0 +1,37 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
mkdir -p /app/data && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENV MORPHOS_DATA_DIR=/app/data
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
47
apps/morphos-server/manifest.yml
Normal file
47
apps/morphos-server/manifest.yml
Normal file
@ -0,0 +1,47 @@
|
||||
app:
|
||||
id: morphos-server
|
||||
name: MorphOS Server
|
||||
version: 1.0.0
|
||||
description: MorphOS server platform. Decentralized application server.
|
||||
|
||||
container:
|
||||
image: archipelago/morphos-server:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 5Gi
|
||||
|
||||
resources:
|
||||
cpu_limit: 2
|
||||
memory_limit: 2Gi
|
||||
disk_limit: 5Gi
|
||||
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
network_policy: isolated
|
||||
apparmor_profile: morphos-server
|
||||
|
||||
ports:
|
||||
- host: 8086
|
||||
container: 8080
|
||||
protocol: tcp # Web UI
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/morphos-server
|
||||
target: /app/data
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- MORPHOS_ENV=production
|
||||
- MORPHOS_DATA_DIR=/app/data
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8086
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
20
apps/morphos-server/package.json
Normal file
20
apps/morphos-server/package.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "morphos-server",
|
||||
"version": "1.0.0",
|
||||
"description": "MorphOS server platform",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
27
apps/morphos-server/src/index.ts
Normal file
27
apps/morphos-server/src/index.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
const port = 8080;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'morphos-server', version: '1.0.0' });
|
||||
});
|
||||
|
||||
// API endpoints
|
||||
app.get('/api/info', (req, res) => {
|
||||
res.json({
|
||||
name: 'MorphOS Server',
|
||||
version: '1.0.0',
|
||||
status: 'running'
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`MorphOS Server listening on port ${port}`);
|
||||
console.log(`Data directory: ${process.env.MORPHOS_DATA_DIR || '/app/data'}`);
|
||||
});
|
||||
16
apps/morphos-server/tsconfig.json
Normal file
16
apps/morphos-server/tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
5
apps/nostr-rs-relay/Dockerfile
Normal file
5
apps/nostr-rs-relay/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Nostr RS Relay - uses official image
|
||||
FROM scsibug/nostr-rs-relay:latest
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@ -24,7 +24,9 @@ app:
|
||||
apparmor_profile: nostr-relay
|
||||
|
||||
ports:
|
||||
- 8080:8080 # HTTP/WebSocket
|
||||
- host: 8081
|
||||
container: 8080
|
||||
protocol: tcp # HTTP/WebSocket
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
@ -40,7 +42,7 @@ app:
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8080
|
||||
endpoint: http://localhost:8081
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
|
||||
6
apps/router/.dockerignore
Normal file
6
apps/router/.dockerignore
Normal file
@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
40
apps/router/Dockerfile
Normal file
40
apps/router/Dockerfile
Normal file
@ -0,0 +1,40 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apk add --no-cache \
|
||||
dbus \
|
||||
avahi \
|
||||
avahi-tools
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080 5353 1900
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
38
apps/router/README.md
Normal file
38
apps/router/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Archipelago Router
|
||||
|
||||
Mesh routing and local network management for Archipelago.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# From the apps directory
|
||||
./build.sh router
|
||||
|
||||
# Or manually
|
||||
cd router
|
||||
docker build -t archipelago/router:latest .
|
||||
# or
|
||||
podman build -t archipelago/router:latest .
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
cd router
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Ports
|
||||
|
||||
- **8084**: Web UI (dev: 18084)
|
||||
- **5353**: mDNS/Bonjour (dev: 15353)
|
||||
- **1900**: SSDP (dev: 11900)
|
||||
|
||||
## Running Locally
|
||||
|
||||
```bash
|
||||
docker run -p 8084:8080 -p 5353:5353/udp -p 1900:1900/udp \
|
||||
-v /tmp/archipelago-dev/router:/app/data \
|
||||
archipelago/router:latest
|
||||
```
|
||||
@ -7,7 +7,7 @@ app:
|
||||
container:
|
||||
image: archipelago/router:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: verify-signature
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 500Mi
|
||||
@ -24,9 +24,15 @@ app:
|
||||
apparmor_profile: router
|
||||
|
||||
ports:
|
||||
- 8080:8080 # Web UI
|
||||
- 5353:5353 # mDNS/Bonjour
|
||||
- 1900:1900 # SSDP
|
||||
- host: 8084
|
||||
container: 8080
|
||||
protocol: tcp # Web UI
|
||||
- host: 5353
|
||||
container: 5353
|
||||
protocol: udp # mDNS/Bonjour
|
||||
- host: 1900
|
||||
container: 1900
|
||||
protocol: udp # SSDP
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
@ -45,7 +51,7 @@ app:
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8080
|
||||
endpoint: http://localhost:8084
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
|
||||
22
apps/router/package.json
Normal file
22
apps/router/package.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "archipelago-router",
|
||||
"version": "1.0.0",
|
||||
"description": "Mesh routing and local network management for Archipelago",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"bonjour": "^3.5.0",
|
||||
"network-interfaces": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
59
apps/router/src/index.ts
Normal file
59
apps/router/src/index.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import express from 'express';
|
||||
import bonjour from 'bonjour';
|
||||
|
||||
const app = express();
|
||||
const port = 8080;
|
||||
|
||||
// Initialize Bonjour for mDNS
|
||||
const bonjourInstance = bonjour();
|
||||
|
||||
// Publish Archipelago Router service
|
||||
bonjourInstance.publish({
|
||||
name: 'Archipelago Router',
|
||||
type: 'http',
|
||||
port: port,
|
||||
txt: {
|
||||
version: '1.0.0',
|
||||
mesh: 'enabled',
|
||||
discovery: 'enabled'
|
||||
}
|
||||
});
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'archipelago-router' });
|
||||
});
|
||||
|
||||
// Network topology endpoint
|
||||
app.get('/api/topology', (req, res) => {
|
||||
res.json({
|
||||
nodes: [],
|
||||
links: [],
|
||||
timestamp: Date.now()
|
||||
});
|
||||
});
|
||||
|
||||
// Device discovery endpoint
|
||||
app.get('/api/devices', (req, res) => {
|
||||
res.json({
|
||||
devices: [],
|
||||
count: 0
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`Archipelago Router listening on port ${port}`);
|
||||
console.log('mDNS service published');
|
||||
});
|
||||
|
||||
// Graceful shutdown
|
||||
process.on('SIGTERM', () => {
|
||||
console.log('Shutting down...');
|
||||
bonjourInstance.unpublishAll(() => {
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
16
apps/router/tsconfig.json
Normal file
16
apps/router/tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
5
apps/strfry/Dockerfile
Normal file
5
apps/strfry/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Strfry - uses official image
|
||||
FROM strfry/strfry:latest
|
||||
|
||||
# Default configuration is in the image
|
||||
# No additional setup needed
|
||||
@ -24,7 +24,9 @@ app:
|
||||
apparmor_profile: nostr-relay
|
||||
|
||||
ports:
|
||||
- 8080:8080 # HTTP/WebSocket
|
||||
- host: 8082
|
||||
container: 8080
|
||||
protocol: tcp # HTTP/WebSocket
|
||||
|
||||
volumes:
|
||||
- type: bind
|
||||
@ -37,7 +39,7 @@ app:
|
||||
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8080
|
||||
endpoint: http://localhost:8082
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
|
||||
6
apps/web5-dwn/.dockerignore
Normal file
6
apps/web5-dwn/.dockerignore
Normal file
@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
*.log
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
38
apps/web5-dwn/Dockerfile
Normal file
38
apps/web5-dwn/Dockerfile
Normal file
@ -0,0 +1,38 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1000 appuser && \
|
||||
adduser -D -u 1000 -G appuser appuser && \
|
||||
mkdir -p /app/data && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV DWN_STORAGE_PATH=/app/data
|
||||
ENV DID_METHOD=key
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
35
apps/web5-dwn/README.md
Normal file
35
apps/web5-dwn/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Web5 DWN (Decentralized Web Node)
|
||||
|
||||
Personal data store for Web5. Store and sync your decentralized data across devices.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# From the apps directory
|
||||
./build.sh web5-dwn
|
||||
|
||||
# Or manually
|
||||
cd web5-dwn
|
||||
docker build -t archipelago/web5-dwn:latest .
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
cd web5-dwn
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Ports
|
||||
|
||||
- **3000**: HTTP API (dev: 13000)
|
||||
|
||||
## Running Locally
|
||||
|
||||
```bash
|
||||
docker run -p 3000:3000 \
|
||||
-v /tmp/archipelago-dev/web5-dwn:/app/data \
|
||||
-e DWN_STORAGE_PATH=/app/data \
|
||||
archipelago/web5-dwn:latest
|
||||
```
|
||||
@ -5,9 +5,9 @@ app:
|
||||
description: Personal data store for Web5. Store and sync your decentralized data across devices.
|
||||
|
||||
container:
|
||||
image: tbd/web5-dwn:latest
|
||||
image: archipelago/web5-dwn:latest
|
||||
image_signature: cosign://...
|
||||
pull_policy: verify-signature
|
||||
pull_policy: if-not-present
|
||||
|
||||
dependencies:
|
||||
- storage: 5Gi
|
||||
|
||||
21
apps/web5-dwn/package.json
Normal file
21
apps/web5-dwn/package.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "web5-dwn",
|
||||
"version": "1.0.0",
|
||||
"description": "Decentralized Web Node for Web5",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"@web5/api": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^20.10.0",
|
||||
"typescript": "^5.3.3",
|
||||
"ts-node": "^10.9.2"
|
||||
}
|
||||
}
|
||||
34
apps/web5-dwn/src/index.ts
Normal file
34
apps/web5-dwn/src/index.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', service: 'web5-dwn' });
|
||||
});
|
||||
|
||||
// DWN API endpoints
|
||||
app.post('/dwn', async (req, res) => {
|
||||
// Placeholder for DWN protocol implementation
|
||||
res.json({
|
||||
status: 'ok',
|
||||
message: 'DWN protocol endpoint (placeholder)'
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/dwn', async (req, res) => {
|
||||
res.json({
|
||||
status: 'ok',
|
||||
message: 'DWN query endpoint (placeholder)'
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, '0.0.0.0', () => {
|
||||
console.log(`Web5 DWN listening on port ${port}`);
|
||||
console.log(`Storage path: ${process.env.DWN_STORAGE_PATH || '/app/data'}`);
|
||||
});
|
||||
16
apps/web5-dwn/tsconfig.json
Normal file
16
apps/web5-dwn/tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
1
core/Cargo.lock
generated
1
core/Cargo.lock
generated
@ -36,6 +36,7 @@ dependencies = [
|
||||
"archipelago-performance",
|
||||
"archipelago-security",
|
||||
"bcrypt",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"hyper 0.14.32",
|
||||
"hyper-util",
|
||||
|
||||
@ -23,6 +23,7 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
hyper = { version = "0.14", features = ["full", "http1"] }
|
||||
hyper-util = { version = "0.1", features = ["full", "http1"] }
|
||||
http-body-util = "0.1"
|
||||
http-body = "1.0"
|
||||
tower = "0.5"
|
||||
tower-http = { version = "0.6", features = ["cors", "trace"] }
|
||||
tokio-tungstenite = { version = "0.20", features = ["native-tls"] }
|
||||
|
||||
@ -3,7 +3,6 @@ use crate::config::Config;
|
||||
use anyhow::Result;
|
||||
use http_body_util::{BodyExt, Full};
|
||||
use hyper::body::Bytes;
|
||||
use hyper::body::Incoming;
|
||||
use hyper::{Method, Request, Response, StatusCode};
|
||||
use hyper_util::rt::TokioIo;
|
||||
use std::sync::Arc;
|
||||
@ -25,17 +24,19 @@ impl ApiHandler {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn handle_request(
|
||||
&self,
|
||||
req: Request<Incoming>,
|
||||
) -> Result<Response<Full<Bytes>>> {
|
||||
pub async fn handle_request<B>(&self, req: Request<B>) -> Result<Response<Full<Bytes>>>
|
||||
where
|
||||
B: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
B::Error: std::fmt::Display,
|
||||
{
|
||||
let path = req.uri().path();
|
||||
let method = req.method();
|
||||
|
||||
// Convert body to bytes
|
||||
// Convert Incoming body to bytes using http_body_util::BodyExt
|
||||
let (parts, body) = req.into_parts();
|
||||
// hyper::body::Incoming implements http_body::Body, and BodyExt extends it
|
||||
use http_body_util::BodyExt;
|
||||
let collected: http_body_util::Collected<Bytes> = body.collect().await
|
||||
let collected = body.collect().await
|
||||
.map_err(|_e| anyhow::anyhow!("Failed to read body"))?;
|
||||
let body_bytes = collected.to_bytes();
|
||||
|
||||
@ -46,10 +47,10 @@ impl ApiHandler {
|
||||
|
||||
// Route requests
|
||||
match (method, path.as_str()) {
|
||||
(Method::POST, "/rpc/v1") => {
|
||||
(&Method::POST, "/rpc/v1") => {
|
||||
self.rpc_handler.handle(req_with_bytes).await
|
||||
}
|
||||
(Method::GET, "/health") => {
|
||||
(&Method::GET, "/health") => {
|
||||
Ok(Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.body(Full::new(Bytes::from("OK")))
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{"$message_type":"diagnostic","message":"unresolved import `http_body_util::Incoming`","code":{"code":"E0432","explanation":"An import was unresolved.\n\nErroneous code example:\n\n```compile_fail,E0432\nuse something::Foo; // error: unresolved import `something::Foo`.\n```\n\nIn Rust 2015, paths in `use` statements are relative to the crate root. To\nimport items relative to the current and parent modules, use the `self::` and\n`super::` prefixes, respectively.\n\nIn Rust 2018 or later, paths in `use` statements are relative to the current\nmodule unless they begin with the name of a crate or a literal `crate::`, in\nwhich case they start from the crate root. As in Rust 2015 code, the `self::`\nand `super::` prefixes refer to the current and parent modules respectively.\n\nAlso verify that you didn't misspell the import name and that the import exists\nin the module from where you tried to import it. Example:\n\n```\nuse self::something::Foo; // Ok.\n\nmod something {\n pub struct Foo;\n}\n# fn main() {}\n```\n\nIf you tried to use a module from an external crate and are using Rust 2015,\nyou may have missed the `extern crate` declaration (which is usually placed in\nthe crate root):\n\n```edition2015\nextern crate core; // Required to use the `core` crate in Rust 2015.\n\nuse core::any;\n# fn main() {}\n```\n\nSince Rust 2018 the `extern crate` declaration is not required and\nyou can instead just `use` it:\n\n```edition2018\nuse core::any; // No extern crate required in Rust 2018.\n# fn main() {}\n```\n"},"level":"error","spans":[{"file_name":"archipelago/src/api/handler.rs","byte_start":197,"byte_end":221,"line_start":7,"line_end":7,"column_start":5,"column_end":29,"is_primary":true,"text":[{"text":"use http_body_util::Incoming;","highlight_start":5,"highlight_end":29}],"label":"no `Incoming` in the root","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"consider importing one of these structs instead","code":null,"level":"help","spans":[{"file_name":"archipelago/src/api/handler.rs","byte_start":197,"byte_end":221,"line_start":7,"line_end":7,"column_start":5,"column_end":29,"is_primary":true,"text":[{"text":"use http_body_util::Incoming;","highlight_start":5,"highlight_end":29}],"label":null,"suggested_replacement":"std::net::Incoming","suggestion_applicability":"MaybeIncorrect","expansion":null},{"file_name":"archipelago/src/api/handler.rs","byte_start":197,"byte_end":221,"line_start":7,"line_end":7,"column_start":5,"column_end":29,"is_primary":true,"text":[{"text":"use http_body_util::Incoming;","highlight_start":5,"highlight_end":29}],"label":null,"suggested_replacement":"std::os::unix::net::Incoming","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[91merror[E0432]\u001b[0m\u001b[1m: unresolved import `http_body_util::Incoming`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/api/handler.rs:7:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m7\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use http_body_util::Incoming;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[91m^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[91mno `Incoming` in the root\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[96mhelp\u001b[0m: consider importing one of these structs instead\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m7\u001b[0m \u001b[91m- \u001b[0muse \u001b[91mhttp_body_util::Incoming\u001b[0m;\n\u001b[1m\u001b[94m7\u001b[0m \u001b[92m+ \u001b[0muse \u001b[92mstd::net::Incoming\u001b[0m;\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m7\u001b[0m \u001b[91m- \u001b[0muse \u001b[91mhttp_body_util::Incoming\u001b[0m;\n\u001b[1m\u001b[94m7\u001b[0m \u001b[92m+ \u001b[0muse \u001b[92mstd::os::unix::net::Incoming\u001b[0m;\n \u001b[1m\u001b[94m|\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unresolved import `http_body`","code":{"code":"E0432","explanation":"An import was unresolved.\n\nErroneous code example:\n\n```compile_fail,E0432\nuse something::Foo; // error: unresolved import `something::Foo`.\n```\n\nIn Rust 2015, paths in `use` statements are relative to the crate root. To\nimport items relative to the current and parent modules, use the `self::` and\n`super::` prefixes, respectively.\n\nIn Rust 2018 or later, paths in `use` statements are relative to the current\nmodule unless they begin with the name of a crate or a literal `crate::`, in\nwhich case they start from the crate root. As in Rust 2015 code, the `self::`\nand `super::` prefixes refer to the current and parent modules respectively.\n\nAlso verify that you didn't misspell the import name and that the import exists\nin the module from where you tried to import it. Example:\n\n```\nuse self::something::Foo; // Ok.\n\nmod something {\n pub struct Foo;\n}\n# fn main() {}\n```\n\nIf you tried to use a module from an external crate and are using Rust 2015,\nyou may have missed the `extern crate` declaration (which is usually placed in\nthe crate root):\n\n```edition2015\nextern crate core; // Required to use the `core` crate in Rust 2015.\n\nuse core::any;\n# fn main() {}\n```\n\nSince Rust 2018 the `extern crate` declaration is not required and\nyou can instead just `use` it:\n\n```edition2018\nuse core::any; // No extern crate required in Rust 2018.\n# fn main() {}\n```\n"},"level":"error","spans":[{"file_name":"archipelago/src/api/handler.rs","byte_start":197,"byte_end":206,"line_start":7,"line_end":7,"column_start":5,"column_end":14,"is_primary":true,"text":[{"text":"use http_body::Body;","highlight_start":5,"highlight_end":14}],"label":"use of unresolved module or unlinked crate `http_body`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if you wanted to use a crate named `http_body`, use `cargo add http_body` to add it to your `Cargo.toml`","code":null,"level":"help","spans":[],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[91merror[E0432]\u001b[0m\u001b[1m: unresolved import `http_body`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/api/handler.rs:7:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m7\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use http_body::Body;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[91m^^^^^^^^^\u001b[0m \u001b[1m\u001b[91muse of unresolved module or unlinked crate `http_body`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mhelp\u001b[0m: if you wanted to use a crate named `http_body`, use `cargo add http_body` to add it to your `Cargo.toml`\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused import: `error`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/main.rs","byte_start":175,"byte_end":180,"line_start":6,"line_end":6,"column_start":21,"column_end":26,"is_primary":true,"text":[{"text":"use tracing::{info, error};","highlight_start":21,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"remove the unused import","code":null,"level":"help","spans":[{"file_name":"archipelago/src/main.rs","byte_start":173,"byte_end":180,"line_start":6,"line_end":6,"column_start":19,"column_end":26,"is_primary":true,"text":[{"text":"use tracing::{info, error};","highlight_start":19,"highlight_end":26}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"archipelago/src/main.rs","byte_start":168,"byte_end":169,"line_start":6,"line_end":6,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"use tracing::{info, error};","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"archipelago/src/main.rs","byte_start":180,"byte_end":181,"line_start":6,"line_end":6,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"use tracing::{info, error};","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `error`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/main.rs:6:21\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m6\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{info, error};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused import: `hyper_util::rt::TokioIo`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/api/handler.rs","byte_start":227,"byte_end":250,"line_start":8,"line_end":8,"column_start":5,"column_end":28,"is_primary":true,"text":[{"text":"use hyper_util::rt::TokioIo;","highlight_start":5,"highlight_end":28}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove the whole `use` item","code":null,"level":"help","spans":[{"file_name":"archipelago/src/api/handler.rs","byte_start":223,"byte_end":252,"line_start":8,"line_end":9,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"use hyper_util::rt::TokioIo;","highlight_start":1,"highlight_end":29},{"text":"use std::sync::Arc;","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `hyper_util::rt::TokioIo`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/api/handler.rs:8:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m8\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use hyper_util::rt::TokioIo;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused import: `hyper_util::rt::TokioIo`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/api/handler.rs","byte_start":218,"byte_end":241,"line_start":8,"line_end":8,"column_start":5,"column_end":28,"is_primary":true,"text":[{"text":"use hyper_util::rt::TokioIo;","highlight_start":5,"highlight_end":28}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove the whole `use` item","code":null,"level":"help","spans":[{"file_name":"archipelago/src/api/handler.rs","byte_start":214,"byte_end":243,"line_start":8,"line_end":9,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"use hyper_util::rt::TokioIo;","highlight_start":1,"highlight_end":29},{"text":"use std::sync::Arc;","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `hyper_util::rt::TokioIo`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/api/handler.rs:8:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m8\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use hyper_util::rt::TokioIo;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused import: `tokio::sync::RwLock`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/api/rpc.rs","byte_start":272,"byte_end":291,"line_start":9,"line_end":9,"column_start":5,"column_end":24,"is_primary":true,"text":[{"text":"use tokio::sync::RwLock;","highlight_start":5,"highlight_end":24}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove the whole `use` item","code":null,"level":"help","spans":[{"file_name":"archipelago/src/api/rpc.rs","byte_start":268,"byte_end":293,"line_start":9,"line_end":10,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"use tokio::sync::RwLock;","highlight_start":1,"highlight_end":25},{"text":"use tracing::{debug, error};","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `tokio::sync::RwLock`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/api/rpc.rs:9:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m9\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tokio::sync::RwLock;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused import: `rpc::RpcHandler`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/api/mod.rs","byte_start":60,"byte_end":75,"line_start":5,"line_end":5,"column_start":9,"column_end":24,"is_primary":true,"text":[{"text":"pub use rpc::RpcHandler;","highlight_start":9,"highlight_end":24}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove the whole `use` item","code":null,"level":"help","spans":[{"file_name":"archipelago/src/api/mod.rs","byte_start":52,"byte_end":77,"line_start":5,"line_end":5,"column_start":1,"column_end":26,"is_primary":true,"text":[{"text":"pub use rpc::RpcHandler;","highlight_start":1,"highlight_end":26}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `rpc::RpcHandler`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/api/mod.rs:5:9\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m5\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub use rpc::RpcHandler;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused import: `Path`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/container/data_manager.rs","byte_start":47,"byte_end":51,"line_start":2,"line_end":2,"column_start":17,"column_end":21,"is_primary":true,"text":[{"text":"use std::path::{Path, PathBuf};","highlight_start":17,"highlight_end":21}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove the unused import","code":null,"level":"help","spans":[{"file_name":"archipelago/src/container/data_manager.rs","byte_start":47,"byte_end":53,"line_start":2,"line_end":2,"column_start":17,"column_end":23,"is_primary":true,"text":[{"text":"use std::path::{Path, PathBuf};","highlight_start":17,"highlight_end":23}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"archipelago/src/container/data_manager.rs","byte_start":46,"byte_end":47,"line_start":2,"line_end":2,"column_start":16,"column_end":17,"is_primary":true,"text":[{"text":"use std::path::{Path, PathBuf};","highlight_start":16,"highlight_end":17}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"archipelago/src/container/data_manager.rs","byte_start":60,"byte_end":61,"line_start":2,"line_end":2,"column_start":30,"column_end":31,"is_primary":true,"text":[{"text":"use std::path::{Path, PathBuf};","highlight_start":30,"highlight_end":31}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `Path`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/container/data_manager.rs:2:17\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m2\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use std::path::{Path, PathBuf};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n"}
|
||||
@ -8,10 +8,5 @@
|
||||
{"$message_type":"diagnostic","message":"unused import: `tokio::sync::RwLock`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/container/dev_orchestrator.rs","byte_start":246,"byte_end":265,"line_start":8,"line_end":8,"column_start":5,"column_end":24,"is_primary":true,"text":[{"text":"use tokio::sync::RwLock;","highlight_start":5,"highlight_end":24}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove the whole `use` item","code":null,"level":"help","spans":[{"file_name":"archipelago/src/container/dev_orchestrator.rs","byte_start":242,"byte_end":267,"line_start":8,"line_end":9,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"use tokio::sync::RwLock;","highlight_start":1,"highlight_end":25},{"text":"","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `tokio::sync::RwLock`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/container/dev_orchestrator.rs:8:5\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m8\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tokio::sync::RwLock;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused import: `data_manager::DevDataManager`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/container/mod.rs","byte_start":57,"byte_end":85,"line_start":4,"line_end":4,"column_start":9,"column_end":37,"is_primary":true,"text":[{"text":"pub use data_manager::DevDataManager;","highlight_start":9,"highlight_end":37}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove the whole `use` item","code":null,"level":"help","spans":[{"file_name":"archipelago/src/container/mod.rs","byte_start":49,"byte_end":87,"line_start":4,"line_end":5,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"pub use data_manager::DevDataManager;","highlight_start":1,"highlight_end":38},{"text":"pub use dev_orchestrator::DevContainerOrchestrator;","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `data_manager::DevDataManager`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/container/mod.rs:4:9\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m4\u001b[0m \u001b[1m\u001b[94m|\u001b[0m pub use data_manager::DevDataManager;\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^^^^^^^^^^^^^^^^\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused import: `info`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/server.rs","byte_start":292,"byte_end":296,"line_start":10,"line_end":10,"column_start":22,"column_end":26,"is_primary":true,"text":[{"text":"use tracing::{error, info};","highlight_start":22,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove the unused import","code":null,"level":"help","spans":[{"file_name":"archipelago/src/server.rs","byte_start":290,"byte_end":296,"line_start":10,"line_end":10,"column_start":20,"column_end":26,"is_primary":true,"text":[{"text":"use tracing::{error, info};","highlight_start":20,"highlight_end":26}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"archipelago/src/server.rs","byte_start":284,"byte_end":285,"line_start":10,"line_end":10,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":"use tracing::{error, info};","highlight_start":14,"highlight_end":15}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"archipelago/src/server.rs","byte_start":296,"byte_end":297,"line_start":10,"line_end":10,"column_start":26,"column_end":27,"is_primary":true,"text":[{"text":"use tracing::{error, info};","highlight_start":26,"highlight_end":27}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `info`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/server.rs:10:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m10\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use tracing::{error, info};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"type annotations needed","code":{"code":"E0282","explanation":"The compiler could not infer a type and asked for a type annotation.\n\nErroneous code example:\n\n```compile_fail,E0282\nlet x = Vec::new();\n```\n\nThis error indicates that type inference did not result in one unique possible\ntype, and extra information is required. In most cases this can be provided\nby adding a type annotation. Sometimes you need to specify a generic type\nparameter manually.\n\nIn the example above, type `Vec` has a type parameter `T`. When calling\n`Vec::new`, barring any other later usage of the variable `x` that allows the\ncompiler to infer what type `T` is, the compiler needs to be told what it is.\n\nThe type can be specified on the variable:\n\n```\nlet x: Vec<i32> = Vec::new();\n```\n\nThe type can also be specified in the path of the expression:\n\n```\nlet x = Vec::<i32>::new();\n```\n\nIn cases with more complex types, it is not necessary to annotate the full\ntype. Once the ambiguity is resolved, the compiler can infer the rest:\n\n```\nlet x: Vec<_> = \"hello\".chars().rev().collect();\n```\n\nAnother way to provide the compiler with enough information, is to specify the\ngeneric type parameter:\n\n```\nlet x = \"hello\".chars().rev().collect::<Vec<char>>();\n```\n\nAgain, you need not specify the full type if the compiler can infer it:\n\n```\nlet x = \"hello\".chars().rev().collect::<Vec<_>>();\n```\n\nApart from a method or function with a generic type parameter, this error can\noccur when a type parameter of a struct or trait cannot be inferred. In that\ncase it is not always possible to use a type annotation, because all candidates\nhave the same return type. For instance:\n\n```compile_fail,E0282\nstruct Foo<T> {\n num: T,\n}\n\nimpl<T> Foo<T> {\n fn bar() -> i32 {\n 0\n }\n\n fn baz() {\n let number = Foo::bar();\n }\n}\n```\n\nThis will fail because the compiler does not know which instance of `Foo` to\ncall `bar` on. Change `Foo::bar()` to `Foo::<T>::bar()` to resolve the error.\n"},"level":"error","spans":[{"file_name":"archipelago/src/api/handler.rs","byte_start":1044,"byte_end":1048,"line_start":38,"line_end":38,"column_start":59,"column_end":63,"is_primary":true,"text":[{"text":" let collected: http_body_util::Collected<Bytes> = body.collect().await","highlight_start":59,"highlight_end":63}],"label":"cannot infer type","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"\u001b[1m\u001b[91merror[E0282]\u001b[0m\u001b[1m: type annotations needed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/api/handler.rs:38:59\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let collected: http_body_util::Collected<Bytes> = body.collect().await\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[91m^^^^\u001b[0m \u001b[1m\u001b[91mcannot infer type\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"type annotations needed","code":{"code":"E0282","explanation":"The compiler could not infer a type and asked for a type annotation.\n\nErroneous code example:\n\n```compile_fail,E0282\nlet x = Vec::new();\n```\n\nThis error indicates that type inference did not result in one unique possible\ntype, and extra information is required. In most cases this can be provided\nby adding a type annotation. Sometimes you need to specify a generic type\nparameter manually.\n\nIn the example above, type `Vec` has a type parameter `T`. When calling\n`Vec::new`, barring any other later usage of the variable `x` that allows the\ncompiler to infer what type `T` is, the compiler needs to be told what it is.\n\nThe type can be specified on the variable:\n\n```\nlet x: Vec<i32> = Vec::new();\n```\n\nThe type can also be specified in the path of the expression:\n\n```\nlet x = Vec::<i32>::new();\n```\n\nIn cases with more complex types, it is not necessary to annotate the full\ntype. Once the ambiguity is resolved, the compiler can infer the rest:\n\n```\nlet x: Vec<_> = \"hello\".chars().rev().collect();\n```\n\nAnother way to provide the compiler with enough information, is to specify the\ngeneric type parameter:\n\n```\nlet x = \"hello\".chars().rev().collect::<Vec<char>>();\n```\n\nAgain, you need not specify the full type if the compiler can infer it:\n\n```\nlet x = \"hello\".chars().rev().collect::<Vec<_>>();\n```\n\nApart from a method or function with a generic type parameter, this error can\noccur when a type parameter of a struct or trait cannot be inferred. In that\ncase it is not always possible to use a type annotation, because all candidates\nhave the same return type. For instance:\n\n```compile_fail,E0282\nstruct Foo<T> {\n num: T,\n}\n\nimpl<T> Foo<T> {\n fn bar() -> i32 {\n 0\n }\n\n fn baz() {\n let number = Foo::bar();\n }\n}\n```\n\nThis will fail because the compiler does not know which instance of `Foo` to\ncall `bar` on. Change `Foo::bar()` to `Foo::<T>::bar()` to resolve the error.\n"},"level":"error","spans":[{"file_name":"archipelago/src/api/handler.rs","byte_start":1044,"byte_end":1064,"line_start":38,"line_end":38,"column_start":59,"column_end":79,"is_primary":true,"text":[{"text":" let collected: http_body_util::Collected<Bytes> = body.collect().await","highlight_start":59,"highlight_end":79}],"label":"cannot infer type","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"\u001b[1m\u001b[91merror[E0282]\u001b[0m\u001b[1m: type annotations needed\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/api/handler.rs:38:59\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m38\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let collected: http_body_util::Collected<Bytes> = body.collect().await\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[91m^^^^^^^^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[91mcannot infer type\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused import: `BodyExt`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/api/rpc.rs","byte_start":127,"byte_end":134,"line_start":4,"line_end":4,"column_start":22,"column_end":29,"is_primary":true,"text":[{"text":"use http_body_util::{BodyExt, Full};","highlight_start":22,"highlight_end":29}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused import: `BodyExt`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/api/rpc.rs:4:22\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m4\u001b[0m \u001b[1m\u001b[94m|\u001b[0m use http_body_util::{BodyExt, Full};\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused variable: `manifest_path`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"archipelago/src/container/dev_orchestrator.rs","byte_start":2370,"byte_end":2383,"line_start":68,"line_end":68,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":" manifest_path: &str,","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"archipelago/src/container/dev_orchestrator.rs","byte_start":2370,"byte_end":2383,"line_start":68,"line_end":68,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":" manifest_path: &str,","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":"_manifest_path","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m: unused variable: `manifest_path`\u001b[0m\n \u001b[1m\u001b[94m--> \u001b[0marchipelago/src/container/dev_orchestrator.rs:68:9\n \u001b[1m\u001b[94m|\u001b[0m\n\u001b[1m\u001b[94m68\u001b[0m \u001b[1m\u001b[94m|\u001b[0m manifest_path: &str,\n \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m \u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_manifest_path`\u001b[0m\n \u001b[1m\u001b[94m|\u001b[0m\n \u001b[1m\u001b[94m= \u001b[0m\u001b[1mnote\u001b[0m: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default\n\n"}
|
||||
{"$message_type":"diagnostic","message":"aborting due to 3 previous errors; 11 warnings emitted","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[1m\u001b[91merror\u001b[0m\u001b[1m: aborting due to 3 previous errors; 11 warnings emitted\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"Some errors have detailed explanations: E0282, E0432.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"\u001b[1mSome errors have detailed explanations: E0282, E0432.\u001b[0m\n"}
|
||||
{"$message_type":"diagnostic","message":"For more information about an error, try `rustc --explain E0282`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"\u001b[1mFor more information about an error, try `rustc --explain E0282`.\u001b[0m\n"}
|
||||
{"$message_type":"diagnostic","message":"aborting due to 1 previous error; 9 warnings emitted","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[1m\u001b[91merror\u001b[0m\u001b[1m: aborting due to 1 previous error; 9 warnings emitted\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"For more information about this error, try `rustc --explain E0432`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"\u001b[1mFor more information about this error, try `rustc --explain E0432`.\u001b[0m\n"}
|
||||
|
||||
@ -0,0 +1 @@
|
||||
This file has an mtime of when this was started.
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
14
core/target/debug/deps/archipelago-d6e22276b7d151e0.d
Normal file
14
core/target/debug/deps/archipelago-d6e22276b7d151e0.d
Normal file
@ -0,0 +1,14 @@
|
||||
/Users/tx1138/Archipelago/core/target/debug/deps/archipelago-d6e22276b7d151e0.d: archipelago/src/main.rs archipelago/src/api/mod.rs archipelago/src/api/handler.rs archipelago/src/api/rpc.rs archipelago/src/auth.rs archipelago/src/config.rs archipelago/src/container/mod.rs archipelago/src/container/data_manager.rs archipelago/src/container/dev_orchestrator.rs archipelago/src/server.rs
|
||||
|
||||
/Users/tx1138/Archipelago/core/target/debug/deps/libarchipelago-d6e22276b7d151e0.rmeta: archipelago/src/main.rs archipelago/src/api/mod.rs archipelago/src/api/handler.rs archipelago/src/api/rpc.rs archipelago/src/auth.rs archipelago/src/config.rs archipelago/src/container/mod.rs archipelago/src/container/data_manager.rs archipelago/src/container/dev_orchestrator.rs archipelago/src/server.rs
|
||||
|
||||
archipelago/src/main.rs:
|
||||
archipelago/src/api/mod.rs:
|
||||
archipelago/src/api/handler.rs:
|
||||
archipelago/src/api/rpc.rs:
|
||||
archipelago/src/auth.rs:
|
||||
archipelago/src/config.rs:
|
||||
archipelago/src/container/mod.rs:
|
||||
archipelago/src/container/data_manager.rs:
|
||||
archipelago/src/container/dev_orchestrator.rs:
|
||||
archipelago/src/server.rs:
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,4 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper::service::service::Service<http::request::Request<ReqBody>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
@ -0,0 +1,2 @@
|
||||
hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>: hyper::service::service::Service<http::request::Request<hyper::body::incoming::Incoming>>
|
||||
hyper_util::server::conn::auto::Connection<'_, TokioIo<tokio::net::TcpStream>, hyper::service::util::ServiceFn<{closure@archipelago/src/server.rs:43:42: 43:52}, _>, TokioExecutor>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -82,7 +82,7 @@ define(['./workbox-21a80088'], (function (workbox) { 'use strict';
|
||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||
}, {
|
||||
"url": "index.html",
|
||||
"revision": "0.s5ijqrr5ss"
|
||||
"revision": "0.m9qtcesurjo"
|
||||
}], {});
|
||||
workbox.cleanupOutdatedCaches();
|
||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user