Files
oikos/internal/core/ports/execution.go
dtoro 60c0432d8b feat: Phase 7 — SeedService, SecretsService, ProvisioningService + ssh Provisioner
Seed ingest/export moves behind ports.SeedRepository (SeedRepo in the
postgres adapter; knowledge ingest absorbed from internal/knowledge,
package deleted). pct_create flow (defaults, template/VMID/gateway
pre-flights, pct create, graph registration) moves from httpapi's
approved-execution path into app.ProvisioningService + the ssh
provisioner adapter; CLI seed/export/secret become adapters over the
services. EntityCreateInput gains EnrolledAt. Plan status corrected:
phases 0-7 shipped, 8 + 9 gates open. VERSION 0.34.1.
2026-08-16 09:11:26 +02:00

113 lines
3.3 KiB
Go

package ports
import (
"context"
"time"
"github.com/dtoro/oikos/internal/core/domain"
)
// Target is a resolved execution endpoint (mirrors remote.ExecTarget; the
// remote adapter maps between them). Wrap rewrites a plain command for
// transport: identity for a host, pct/qm wrapping for guests.
type Target struct {
Host string
User string
Wrap func(cmd string) string
}
// ExecOpts carries execution options; Sink, when non-nil, receives output
// chunks as they arrive (streaming path).
type ExecOpts struct {
Timeout time.Duration
Sink func(stream string, chunk []byte)
}
// ExecResult is the outcome of one command execution.
type ExecResult struct {
Output string
Duration time.Duration
Err error
}
// CommandExecutor runs a command on a resolved target over SSH. Implemented
// by the ssh adapter wrapping internal/actuator (dial pool + breaker).
type CommandExecutor interface {
Run(ctx context.Context, target Target, command string, opts ExecOpts) ExecResult
}
// TargetResolver resolves entity slugs/IDs to execution endpoints.
// Implemented by the remote adapter on top of EntityRepository.
type TargetResolver interface {
ResolveExecTarget(ctx context.Context, targetSlug string) (Target, error)
ResolveForCheck(ctx context.Context, targetID domain.UUID, targetType string) (Target, error)
ResolveHost(ctx context.Context, hostSlug, fallbackUser string) (addr, user string, err error)
// IsGuest reports whether an entity type is reached via pct/qm exec
// through a Proxmox host rather than by direct SSH.
IsGuest(entityType string) bool
}
// Provisioner creates guests via pct/qm on a Proxmox host. The ssh
// adapter implements it over CommandExecutor: template-cache resolution,
// cluster-wide VMID collision guard, gateway preflight, and the pct/qm
// create itself. DB registration of the created guest is NOT part of the
// port — ProvisioningService owns that over the entity/relationship
// repositories.
type Provisioner interface {
CreateLXC(ctx context.Context, input LXCInput) (ProvisionResult, error)
CreateVM(ctx context.Context, input VMInput) (ProvisionResult, error)
}
// LXCInput is a fully-defaulted LXC create spec (ProvisioningService
// applies defaults before calling). HostAddr/HostUser are the resolved
// SSH endpoint of the Proxmox host; Sink, when non-nil, receives the
// create command's output chunks as they arrive.
type LXCInput struct {
HostAddr string
HostUser string
HostSlug string
Hostname string
VMID int
Cores int
MemoryMB int
DiskGB int
IP string
GW string
Bridge string
Storage string
Template string
Privileged bool
Nesting bool
Mounts []string
Nameserver string
Searchdomain string
Sink func(stream string, chunk []byte)
}
// VMInput mirrors LXCInput for VM creation via qm.
type VMInput struct {
HostAddr string
HostUser string
HostSlug string
Name string
VMID int
TemplateID int
Cores int
MemoryMB int
DiskGB int
Sink func(stream string, chunk []byte)
}
// ProvisionResult reports what the provisioner actually did — the VMID
// may differ from the request (cluster collision guard reassigns), and
// the template is the concrete cache entry picked.
type ProvisionResult struct {
VMID int
Template string
Output string
}