- Consolidate DialRemote/DialTunnel common logic into buildResources + dialEnv interface - Remove strict capability check that prevented ConnResources creation for host-exec-only nodes - Merge gRPC-discovered capabilities with registration-declared capabilities in DialTunnel - Replace requireKubeConfig hard-fail with graceful skip when kubeconfig is absent - Introduce tai/types package for shared Ports/Capabilities/SystemInfo/AuthInfo/NodeMeta - Add tai/conn.go (ConnResources) and tai/dial.go (DialRemote/DialTunnel/DialLocal) - Rename tai/sandbox → tai/runtime for clarity - Update sandbox/v2, workspace, agent/sandbox/v2 test utilities for build-tag isolation Made-with: Cursor
124 lines
2.4 KiB
Go
124 lines
2.4 KiB
Go
package tai
|
|
|
|
import (
|
|
"github.com/yaoapp/yao/tai/registry"
|
|
"github.com/yaoapp/yao/tai/types"
|
|
"github.com/yaoapp/yao/tai/volume"
|
|
)
|
|
|
|
// Type aliases kept at package level for convenience.
|
|
type Runtime = types.Runtime
|
|
type Ports = types.Ports
|
|
|
|
// Option configures RegisterLocal.
|
|
type Option interface {
|
|
apply(*config)
|
|
}
|
|
|
|
type optionFunc func(*config)
|
|
|
|
func (f optionFunc) apply(c *config) { f(c) }
|
|
|
|
// WithDataDir sets the workspace root directory for Local mode.
|
|
func WithDataDir(dir string) Option {
|
|
return optionFunc(func(c *config) { c.dataDir = dir })
|
|
}
|
|
|
|
// WithVolume injects a custom Volume implementation (useful for testing).
|
|
func WithVolume(vol volume.Volume) Option {
|
|
return optionFunc(func(c *config) { c.volume = vol })
|
|
}
|
|
|
|
type config struct {
|
|
dataDir string
|
|
volume volume.Volume
|
|
}
|
|
|
|
func defaultPorts() Ports {
|
|
return Ports{
|
|
GRPC: 19100,
|
|
HTTP: 8099,
|
|
VNC: 16080,
|
|
}
|
|
}
|
|
|
|
func mergedPorts(p Ports) Ports {
|
|
d := defaultPorts()
|
|
if p.GRPC != 0 {
|
|
d.GRPC = p.GRPC
|
|
}
|
|
if p.HTTP != 0 {
|
|
d.HTTP = p.HTTP
|
|
}
|
|
if p.VNC != 0 {
|
|
d.VNC = p.VNC
|
|
}
|
|
if p.Docker != 0 {
|
|
d.Docker = p.Docker
|
|
}
|
|
if p.K8s != 0 {
|
|
d.K8s = p.K8s
|
|
}
|
|
return d
|
|
}
|
|
|
|
func intOr(v, fallback int) int {
|
|
if v > 0 {
|
|
return v
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
// RegisterLocal probes the local Docker environment and, if reachable,
|
|
// registers it as the "local" node in the registry with ConnResources.
|
|
// Returns true if a local node was successfully registered.
|
|
// Silently returns false if Docker is not available — this is not an error.
|
|
func RegisterLocal(opts ...Option) bool {
|
|
reg := registry.Global()
|
|
if reg == nil {
|
|
return false
|
|
}
|
|
if _, ok := reg.Get("local"); ok {
|
|
return true
|
|
}
|
|
|
|
cfg := &config{}
|
|
for _, o := range opts {
|
|
o.apply(cfg)
|
|
}
|
|
|
|
res, err := DialLocal("", cfg.dataDir, cfg.volume)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
reg.Register(®istry.TaiNode{
|
|
TaiID: "local",
|
|
Mode: "local",
|
|
})
|
|
reg.SetResources("local", res)
|
|
return true
|
|
}
|
|
|
|
// GetResources returns the ConnResources for a registered Tai node.
|
|
func GetResources(taiID string) (*ConnResources, bool) {
|
|
reg := registry.Global()
|
|
if reg == nil {
|
|
return nil, false
|
|
}
|
|
raw, ok := reg.GetResources(taiID)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
res, ok := raw.(*ConnResources)
|
|
return res, ok && res != nil
|
|
}
|
|
|
|
// GetNodeMeta returns the metadata for a registered Tai node by ID.
|
|
func GetNodeMeta(taiID string) (*types.NodeMeta, bool) {
|
|
reg := registry.Global()
|
|
if reg == nil {
|
|
return nil, false
|
|
}
|
|
return reg.Get(taiID)
|
|
}
|