mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-24 03:04:16 +00:00
begin embedded pds with xrpc endpoints and well-known
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
package pds
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/bluesky-social/indigo/carstore"
|
||||
"github.com/bluesky-social/indigo/models"
|
||||
"github.com/bluesky-social/indigo/repo"
|
||||
)
|
||||
|
||||
// HoldPDS is a minimal ATProto PDS implementation for a hold service
|
||||
type HoldPDS struct {
|
||||
did string
|
||||
publicURL string
|
||||
carstore carstore.CarStore
|
||||
session *carstore.DeltaSession
|
||||
repo *repo.Repo
|
||||
dbPath string
|
||||
uid models.Uid
|
||||
signingKey *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// NewHoldPDS creates or opens a hold PDS with SQLite carstore
|
||||
func NewHoldPDS(ctx context.Context, did, publicURL, dbPath, keyPath string) (*HoldPDS, error) {
|
||||
// Ensure directory exists
|
||||
dir := filepath.Dir(dbPath)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return nil, fmt.Errorf("failed to create database directory: %w", err)
|
||||
}
|
||||
|
||||
// Generate or load signing key
|
||||
signingKey, err := GenerateOrLoadKey(keyPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize signing key: %w", err)
|
||||
}
|
||||
|
||||
// Create and open SQLite-backed carstore
|
||||
// dbPath is the directory, carstore creates and opens db.sqlite3 inside it
|
||||
sqlStore, err := carstore.NewSqliteStore(dbPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create sqlite store: %w", err)
|
||||
}
|
||||
|
||||
cs := sqlStore.CarStore()
|
||||
|
||||
// For a single-user hold, we use a fixed UID (1)
|
||||
uid := models.Uid(1)
|
||||
|
||||
// Try to get existing repo head
|
||||
_, err = cs.GetUserRepoHead(ctx, uid)
|
||||
|
||||
var session *carstore.DeltaSession
|
||||
var r *repo.Repo
|
||||
|
||||
if err != nil {
|
||||
// Repo doesn't exist yet, create new delta session
|
||||
session, err = cs.NewDeltaSession(ctx, uid, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create delta session: %w", err)
|
||||
}
|
||||
|
||||
// Create new repo with session as blockstore (needs pointer)
|
||||
r = repo.NewRepo(ctx, did, session)
|
||||
} else {
|
||||
// TODO: Load existing repo
|
||||
// For now, just create a new session
|
||||
session, err = cs.NewDeltaSession(ctx, uid, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create delta session: %w", err)
|
||||
}
|
||||
|
||||
r = repo.NewRepo(ctx, did, session)
|
||||
}
|
||||
|
||||
return &HoldPDS{
|
||||
did: did,
|
||||
publicURL: publicURL,
|
||||
carstore: cs,
|
||||
session: session,
|
||||
repo: r,
|
||||
dbPath: dbPath,
|
||||
uid: uid,
|
||||
signingKey: signingKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DID returns the hold's DID
|
||||
func (p *HoldPDS) DID() string {
|
||||
return p.did
|
||||
}
|
||||
|
||||
// SigningKey returns the hold's signing key
|
||||
func (p *HoldPDS) SigningKey() *ecdsa.PrivateKey {
|
||||
return p.signingKey
|
||||
}
|
||||
|
||||
// Close closes the session and carstore
|
||||
func (p *HoldPDS) Close() error {
|
||||
// TODO: Close session properly
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user