mirror of
https://github.com/luxfi/vm.git
synced 2026-10-30 15:13:40 +00:00
luxd v1.26+ sets the unprefixed VM_RUNTIME_ENGINE_ADDR and VM_TRANSPORT
env vars when launching plugin VMs. The historical LUX_VM_RUNTIME_ENGINE_ADDR
and LUX_VM_TRANSPORT names came from a now-dropped luxd<->plugin compatibility
shim — the canonical names are the unprefixed ones.
Renames:
- rpc/runtime/runtime.go: EngineAddressKey constant
- rpc/factory_zap.go: LUX_VM_TRANSPORT -> VM_TRANSPORT
- rpc/runtime/README.md: documentation aligned with code
Plugins built against luxfi/vm <= v1.1.0 read the LUX_-prefixed names and
will fail handshake against post-v1.1.1 luxd. Those plugins must rebuild
against this release.
Cleanup:
- drop dead xsvm protobuf+connect tree (no callers; xsvm has been on ZAP
since v1.0.41)
- drop indirect corona dep (consensus moved to corona+pulsar in v1.0.41+)
- .gitignore: ignore .DS_Store at every level
97 lines
2.3 KiB
Go
97 lines
2.3 KiB
Go
//go:build !grpc
|
|
|
|
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
|
|
zapwire "github.com/luxfi/api/zap"
|
|
"github.com/luxfi/log"
|
|
"github.com/luxfi/metric"
|
|
"github.com/luxfi/resource"
|
|
"github.com/luxfi/vm/manager"
|
|
"github.com/luxfi/vm/rpc/runtime"
|
|
"github.com/luxfi/vm/rpc/runtime/subprocess"
|
|
)
|
|
|
|
var _ manager.Factory = (*factory)(nil)
|
|
|
|
type factory struct {
|
|
path string
|
|
processTracker resource.ProcessTracker
|
|
runtimeTracker runtime.Tracker
|
|
metricsGatherer metric.MultiGatherer
|
|
}
|
|
|
|
// NewFactory creates a new VM factory for external plugin VMs using ZAP transport.
|
|
func NewFactory(
|
|
path string,
|
|
processTracker resource.ProcessTracker,
|
|
runtimeTracker runtime.Tracker,
|
|
metricsGatherer metric.MultiGatherer,
|
|
) manager.Factory {
|
|
return &factory{
|
|
path: path,
|
|
processTracker: processTracker,
|
|
runtimeTracker: runtimeTracker,
|
|
metricsGatherer: metricsGatherer,
|
|
}
|
|
}
|
|
|
|
func (f *factory) New(logger log.Logger) (interface{}, error) {
|
|
config := &subprocess.Config{
|
|
Stderr: os.Stderr,
|
|
Stdout: os.Stdout,
|
|
HandshakeTimeout: runtime.DefaultHandshakeTimeout,
|
|
Log: logger,
|
|
}
|
|
|
|
// Create TCP listener for ZAP handshake
|
|
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create ZAP listener: %w", err)
|
|
}
|
|
|
|
// Tell subprocess to use ZAP transport
|
|
cmd := subprocess.NewCmd(f.path)
|
|
cmd.Env = append(cmd.Env, "VM_TRANSPORT=zap")
|
|
|
|
status, stopper, err := subprocess.Bootstrap(
|
|
context.TODO(),
|
|
listener,
|
|
cmd,
|
|
config,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Connect via ZAP
|
|
ctx, cancel := context.WithTimeout(context.Background(), runtime.DefaultHandshakeTimeout)
|
|
defer cancel()
|
|
|
|
zapConn, err := zapwire.Dial(ctx, status.Addr, nil)
|
|
if err != nil {
|
|
stopper.Stop(context.Background())
|
|
logger.Error("failed to dial VM ZAP service", "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
f.processTracker.TrackProcess(status.Pid)
|
|
f.runtimeTracker.TrackRuntime(stopper)
|
|
|
|
logger.Info("VM client connected via ZAP",
|
|
"path", f.path,
|
|
"addr", status.Addr,
|
|
"pid", status.Pid,
|
|
)
|
|
|
|
return NewZAPClient(zapConn, stopper, status.Pid, f.processTracker, f.metricsGatherer, logger), nil
|
|
}
|