Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env.darwin.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ JWT_SECRET=dev-secret-change-me
DATA_DIR=~/Library/Application Support/hypeman

# Server configuration
PORT=8080
PORT=4973

# Logging
LOG_LEVEL=debug
Expand Down Expand Up @@ -63,7 +63,7 @@ CADDY_STOP_ON_SHUTDOWN=false
# Desktop-specific hostname. Use the NAT gateway IP instead.
#
# Registry URL (the host's hypeman API, accessible from VMs)
REGISTRY_URL=192.168.64.1:8080
REGISTRY_URL=192.168.64.1:4973
# Use HTTP (not HTTPS) since hypeman's internal registry uses plaintext
REGISTRY_INSECURE=true

Expand Down
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ JWT_SECRET=
DATA_DIR=/var/lib/hypeman

# Server configuration
# PORT=8080
# PORT=4973

# Network configuration
# BRIDGE_NAME=vmbr0
Expand Down
6 changes: 3 additions & 3 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Common settings:

| Key | Description | Default |
|-----|-------------|---------|
| `port` | HTTP server port | `8080` |
| `port` | HTTP server port | `4973` |
| `data_dir` | Data directory for VM images, volumes, etc. | `/var/lib/hypeman` |
| `jwt_secret` | Secret key for JWT authentication (required) | _(empty)_ |
| `env` | Deployment environment (filters telemetry) | `unset` |
Expand Down Expand Up @@ -200,7 +200,7 @@ acme:
2. Create an ingress with TLS enabled:

```bash
curl -X POST http://localhost:8080/v1/ingresses \
curl -X POST http://localhost:4973/v1/ingresses \
-H "Content-Type: application/json" \
-d '{
"name": "my-https-app",
Expand Down Expand Up @@ -261,7 +261,7 @@ make gen-jwt
make dev
```

The server will start on port 8080 (configurable via `port` in config.yaml).
The server will start on port 4973 (configurable via `port` in config.yaml).

### Shared-Machine Local Config

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ go install 'github.com/kernel/hypeman-cli/cmd/hypeman@latest'
Then create a CLI config file at `~/.config/hypeman/cli.yaml`:

```yaml
base_url: http://<server-host>:8080
base_url: http://<server-host>:4973
api_key: "<token>"
```

Expand Down
2 changes: 1 addition & 1 deletion cli.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# =============================================================================

# Hypeman API URL
base_url: http://localhost:8080
base_url: http://localhost:4973

# API authentication token (generated by hypeman-token)
api_key: ""
4 changes: 2 additions & 2 deletions cmd/api/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func GetDefaultConfigPaths() []string {
// defaultConfig returns a Config struct with all default values set.
func defaultConfig() *Config {
return &Config{
Port: "8080",
Port: "4973",
DataDir: "/var/lib/hypeman",
JwtSecret: "",
Env: "unset",
Expand Down Expand Up @@ -420,7 +420,7 @@ func defaultConfig() *Config {
},

Registry: RegistryConfig{
URL: "localhost:8080",
URL: "localhost:4973",
Insecure: false,
CACertFile: "",
},
Expand Down
11 changes: 11 additions & 0 deletions cmd/api/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ import (
"github.com/kernel/hypeman/lib/guestmemory"
)

func TestDefaultConfigUsesHypemanPort(t *testing.T) {
cfg := defaultConfig()

if cfg.Port != "4973" {
t.Fatalf("expected default port to be 4973, got %q", cfg.Port)
}
if cfg.Registry.URL != "localhost:4973" {
t.Fatalf("expected default registry URL to use port 4973, got %q", cfg.Registry.URL)
}
}

func TestDefaultConfigIncludesMetricsSettings(t *testing.T) {
cfg := defaultConfig()

Expand Down
4 changes: 2 additions & 2 deletions config.example.darwin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jwt_secret: dev-secret-change-me
data_dir: ~/Library/Application Support/hypeman

# Server configuration
port: "8080"
port: "4973"

# =============================================================================
# Hypervisor Configuration (IMPORTANT FOR MACOS)
Expand Down Expand Up @@ -104,7 +104,7 @@ caddy:
# IMPORTANT: "host.docker.internal" does NOT work in vz VMs - that's a Docker
# Desktop-specific hostname. Use the NAT gateway IP instead.
registry:
url: 192.168.64.1:8080
url: 192.168.64.1:4973
insecure: true

build:
Expand Down
2 changes: 1 addition & 1 deletion config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jwt_secret: ""
data_dir: /var/lib/hypeman

# Server configuration
# port: 8080
# port: 4973

# =============================================================================
# Hypervisor Configuration
Expand Down
10 changes: 5 additions & 5 deletions lib/builds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ Registry-based caching with tenant isolation:
```

```go
gen := NewCacheKeyGenerator("localhost:8080")
gen := NewCacheKeyGenerator("localhost:4973")
key, _ := gen.GenerateCacheKey("my-tenant", "myapp", lockfileHashes)
// key.ImportCacheArg() → "type=registry,ref=localhost:8080/cache/my-tenant/myapp/abc123"
// key.ExportCacheArg() → "type=registry,ref=localhost:8080/cache/my-tenant/myapp/abc123,mode=max"
// key.ImportCacheArg() → "type=registry,ref=localhost:4973/cache/my-tenant/myapp/abc123"
// key.ExportCacheArg() → "type=registry,ref=localhost:4973/cache/my-tenant/myapp/abc123,mode=max"
```

### Registry Token System (`registry_token.go`)
Expand Down Expand Up @@ -207,7 +207,7 @@ CMD [\"node\", \"index.js\"]" \
|---------------------|---------|-------------|
| `MAX_CONCURRENT_SOURCE_BUILDS` | `2` | Max parallel builds |
| `BUILDER_IMAGE` | `hypeman/builder:latest` | Builder VM image |
| `REGISTRY_URL` | `localhost:8080` | Registry for built images |
| `REGISTRY_URL` | `localhost:4973` | Registry for built images |
| `BUILD_TIMEOUT` | `600` | Default timeout (seconds) |

### Registry URL Configuration
Expand Down Expand Up @@ -419,7 +419,7 @@ go test ./lib/builds/registry_token_test.go ./lib/builds/registry_token.go -v
| `image not found` | Builder image not imported | Import image using `POST /images` endpoint |
| `no cgroup mount found` | Cgroups not mounted in VM | Update init script to mount cgroups |
| `http: server gave HTTP response to HTTPS client` | BuildKit using HTTPS for HTTP registry | Add `registry.insecure=true` to output flags |
| `connection refused` to localhost:8080 | Registry URL not accessible from VM | Use gateway IP (10.102.0.1) instead of localhost |
| `connection refused` to localhost:4973 | Registry URL not accessible from VM | Use gateway IP (10.102.0.1) instead of localhost |
| `401 Unauthorized` | Registry auth issue | Check registry_token in config.json; verify middleware handles Basic auth |
| `No space left on device` | Instance memory too small for image | Use at least 1GB RAM for Node.js images |
| `can't enable NoProcessSandbox without Rootless` | Wrong BUILDKITD_FLAGS | Use empty flags or remove the flag |
Expand Down
2 changes: 1 addition & 1 deletion lib/builds/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ type Config struct {
func DefaultConfig() Config {
return Config{
MaxConcurrentBuilds: 2,
RegistryURL: "localhost:8080",
RegistryURL: "localhost:4973",
DefaultTimeout: 600, // 10 minutes
}
}
Expand Down
14 changes: 7 additions & 7 deletions lib/devices/GPU.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ vGPU mode uses NVIDIA's SR-IOV technology to create Virtual Functions (VFs), eac
Query available profiles via the resources API:

```bash
curl -s http://localhost:8080/resources | jq .gpu
curl -s http://localhost:4973/resources | jq .gpu
```

```json
Expand All @@ -61,7 +61,7 @@ curl -s http://localhost:8080/resources | jq .gpu
Request a vGPU by specifying the profile name:

```bash
curl -X POST http://localhost:8080/instances \
curl -X POST http://localhost:4973/instances \
-H "Content-Type: application/json" \
-d '{
"name": "ml-training",
Expand Down Expand Up @@ -108,7 +108,7 @@ Passthrough mode assigns entire physical GPUs to instances via VFIO.
### Checking Available GPUs

```bash
curl -s http://localhost:8080/resources | jq .gpu
curl -s http://localhost:4973/resources | jq .gpu
```

```json
Expand All @@ -129,11 +129,11 @@ For whole-GPU passthrough, use the devices API (see [README.md](README.md)):

```bash
# Register GPU
curl -X POST http://localhost:8080/devices \
curl -X POST http://localhost:4973/devices \
-d '{"pci_address": "0000:82:00.0", "name": "gpu-0"}'

# Create instance with GPU
curl -X POST http://localhost:8080/instances \
curl -X POST http://localhost:4973/instances \
-d '{"name": "ml-job", "image": "nvidia/cuda:12.4", "devices": ["gpu-0"]}'
```

Expand Down Expand Up @@ -253,7 +253,7 @@ To upgrade the NVIDIA driver version:

The requested profile may require more VRAM than available. Check:
```bash
curl -s http://localhost:8080/resources | jq '.gpu.profiles'
curl -s http://localhost:4973/resources | jq '.gpu.profiles'
```

### nvidia-smi fails in guest
Expand All @@ -262,7 +262,7 @@ curl -s http://localhost:8080/resources | jq '.gpu.profiles'
2. Check driver version compatibility with vGPU Manager
3. Inspect guest boot logs:
```bash
curl http://localhost:8080/instances/<id>/logs?source=app
curl http://localhost:4973/instances/<id>/logs?source=app
```

### mdev creation fails
Expand Down
14 changes: 7 additions & 7 deletions lib/devices/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ lib/devices/

```bash
# Check available profiles
curl localhost:8080/resources | jq .gpu
curl localhost:4973/resources | jq .gpu

# Create instance with vGPU
curl -X POST localhost:8080/instances \
curl -X POST localhost:4973/instances \
-H "Content-Type: application/json" \
-d '{
"name": "ml-training",
Expand All @@ -56,21 +56,21 @@ nvidia-smi

```bash
# Discover available devices
curl localhost:8080/devices/available
curl localhost:4973/devices/available

# Register the GPU
curl -X POST localhost:8080/devices \
curl -X POST localhost:4973/devices \
-d '{"name": "l4-gpu", "pci_address": "0000:a2:00.0"}'

# Create instance with GPU
curl -X POST localhost:8080/instances \
curl -X POST localhost:4973/instances \
-d '{"name": "ml-training", "image": "nvidia/cuda:12.0-base", "devices": ["l4-gpu"]}'

# Inside VM: verify GPU
nvidia-smi

# Delete instance (auto-unbinds from VFIO)
curl -X DELETE localhost:8080/instances/{id}
curl -X DELETE localhost:4973/instances/{id}
```

## Device Lifecycle
Expand Down Expand Up @@ -194,7 +194,7 @@ sudo systemctl start nvidia-persistenced

Check available slots:
```bash
curl localhost:8080/resources | jq '.gpu.profiles'
curl localhost:4973/resources | jq '.gpu.profiles'
```

### Running the E2E Test
Expand Down
4 changes: 2 additions & 2 deletions lib/providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func ProvideIngressManager(p *paths.Paths, cfg *config.Config, instanceManager i
}

// Parse API port from config
apiPort := 8080 // default
apiPort := 4973 // default
if cfg.Port != "" {
if p, err := strconv.Atoi(cfg.Port); err == nil {
apiPort = p
Expand Down Expand Up @@ -408,7 +408,7 @@ func ProvideBuildManager(p *paths.Paths, cfg *config.Config, instanceManager ins
// Inside a VM, "localhost" refers to the VM itself, not the host.
registryURL := cfg.Registry.URL
if registryURL == "" {
registryURL = "localhost:8080"
registryURL = "localhost:4973"
}
if strings.HasPrefix(registryURL, "localhost:") || strings.HasPrefix(registryURL, "127.0.0.1:") {
gateway := cfg.Network.SubnetGateway
Expand Down
4 changes: 2 additions & 2 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ openapi: 3.1.0
info:
title: Hypeman API
description: Generic API for managing VM lifecycle using Cloud Hypervisor with OCI-based workloads
version: 0.2.0
version: 0.3.0
servers:
- url: http://localhost:8080
- url: http://localhost:4973
description: Local development server
components:
securitySchemes:
Expand Down
2 changes: 1 addition & 1 deletion scripts/e2e-install-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ BRANCH="$BRANCH" CLI_BRANCH="${CLI_BRANCH:-}" bash scripts/install.sh
# =============================================================================
info "Phase 3: Waiting for service to be healthy..."

PORT=8080
PORT=4973
TIMEOUT=60
ELAPSED=0

Expand Down
15 changes: 14 additions & 1 deletion scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,20 @@ if [ "$CLI_INSTALLED" = true ]; then
mkdir -p "$CLI_CONFIG_DIR"

# Determine the port from config
CLI_PORT="8080"
CLI_PORT="4973"
Comment thread
cursor[bot] marked this conversation as resolved.
DEFAULT_CONFIG_FILE="${TMP_DIR}/config.example.yaml"
if [ "$OS" = "darwin" ]; then
DEFAULT_CONFIG_FILE="${TMP_DIR}/config.example.darwin.yaml"
fi
if [ -f "$DEFAULT_CONFIG_FILE" ]; then
PARSED_PORT=$(grep -E '^[[:space:]]*port[[:space:]]*:' "$DEFAULT_CONFIG_FILE" 2>/dev/null | head -1 | sed 's/^[[:space:]]*port[[:space:]]*:[[:space:]]*//' | tr -d "\"'" | sed 's/[[:space:]]*$//' || true)
if [ -z "$PARSED_PORT" ]; then
PARSED_PORT=$(grep -E '^[[:space:]]*#[[:space:]]*port[[:space:]]*:' "$DEFAULT_CONFIG_FILE" 2>/dev/null | head -1 | sed 's/^[[:space:]]*#[[:space:]]*port[[:space:]]*:[[:space:]]*//' | tr -d "\"'" | sed 's/[[:space:]]*$//' || true)
fi
Comment thread
cursor[bot] marked this conversation as resolved.
if [ -n "$PARSED_PORT" ]; then
CLI_PORT="$PARSED_PORT"
fi
fi
if [ -f "$CONFIG_FILE" ]; then
PARSED_PORT=$(grep -E '^[[:space:]]*port[[:space:]]*:' "$CONFIG_FILE" 2>/dev/null | head -1 | sed 's/^[[:space:]]*port[[:space:]]*:[[:space:]]*//' | tr -d "\"'" | sed 's/[[:space:]]*$//' || true)
if [ -n "$PARSED_PORT" ]; then
Expand Down
2 changes: 1 addition & 1 deletion scripts/utm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ make gen-jwt

# on the host machine
export HYPEMAN_API_KEY="<token-from-vm>"
export HYPEMAN_BASE_URL="http://hypemman.local:8080"
export HYPEMAN_BASE_URL="http://hypemman.local:4973"

# then try out some commands
hypeman pull debian:13-slim
Expand Down
2 changes: 1 addition & 1 deletion stainless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ targets:
# `environments` are a map of the name of the environment (e.g. "sandbox",
# "production") to the corresponding url to use.
environments:
production: http://localhost:8080
production: http://localhost:4973

# `resources` define the structure and organization for your API, such as how
# methods and models are grouped together and accessed. See the [configuration
Expand Down
Loading