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 }