mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-10 13:58:24 +01:00
* vector: expose request metrics and registration-aware health endpoints * vector: report immutable read cache and storage fetch metrics * docs: describe vector engine health, metrics, and maintenance * vector: count canceled requests when their handler is dropped * vector: account for uncached large immutable storage reads * vector: reliably release the stalled credential reader in tests * vector: observe large reads as their streamed body is consumed * vector: bound heartbeats on established master registration streams * test: exercise hardened vector maintenance on Go and Rust volumes * vector: register engines in their configured filer group * vector: make retried index creation preserve compatible datasets * vector: allow registration to advertise a separate address * test: release stalled credential readers without blocking FIFO cleanup * test: allow hardened vector coverage in a named filer group * vector: discover engines in the same filer group as their gateway * vector: fall back when the advertised address is empty * admin: expose vector readiness, maintenance, and management tools (#12520) * s3vectors: share vector discovery with trusted management clients * admin: show vector engine readiness and recent maintenance activity * admin: suggest S3 Vectors IAM actions from the supported operations * admin: manage vector indexes, policies, tags, encryption, and query data * admin: validate SSE-S3 support before creating encrypted vector buckets * admin: discover vector engines in their registration group * admin: probe vector engines concurrently with independent time budgets * admin: verify encryption capability on the remote S3 gateway * admin: defer discovery until after the HTTP server can start * admin: distinguish unknown vector health services from failed engines * admin: count workers that can execute vector index maintenance * admin: allow read-only users to query vectors and inspect tags * vector: scope gateway and admin discovery to the configured filer group * admin: refresh policy state after mutations and serialize policy controls * vector: drain active RPCs before closing replaced discovery connections * vector: respect request cancellation while waiting for discovery * vector: prefer another registered engine after a transport failure * admin: check all masters before reporting no registered vector engines * iam: honor attached vector policies without broadening legacy grants * vector: allow short-lived discovery clients to close their connections * vector: refresh cached master addresses for each discovery lookup * iam: enforce vector bucket tag conditions in attached policies * iam: authorize vector bucket creation with the requested tags * test: exercise vector IAM grants and tag denies on Go and Rust volumes * admin: reject authenticated vector mutations without an admin role * test: run vector IAM assertions before the shared engine is stopped * vector: add native mini startup, shell tools, and a runnable Compose example (#12522) * s3vectors: share vector discovery with trusted management clients * admin: show vector engine readiness and recent maintenance activity * admin: suggest S3 Vectors IAM actions from the supported operations * admin: manage vector indexes, policies, tags, encryption, and query data * admin: validate SSE-S3 support before creating encrypted vector buckets * admin: discover vector engines in their registration group * admin: probe vector engines concurrently with independent time budgets * admin: verify encryption capability on the remote S3 gateway * admin: defer discovery until after the HTTP server can start * admin: distinguish unknown vector health services from failed engines * admin: count workers that can execute vector index maintenance * admin: allow read-only users to query vectors and inspect tags * vector: scope gateway and admin discovery to the configured filer group * admin: refresh policy state after mutations and serialize policy controls * vector: drain active RPCs before closing replaced discovery connections * vector: respect request cancellation while waiting for discovery * vector: prefer another registered engine after a transport failure * admin: check all masters before reporting no registered vector engines * iam: honor attached vector policies without broadening legacy grants * vector: allow short-lived discovery clients to close their connections * vector: refresh cached master addresses for each discovery lookup * iam: enforce vector bucket tag conditions in attached policies * iam: authorize vector bucket creation with the requested tags * test: exercise vector IAM grants and tag denies on Go and Rust volumes * admin: reject authenticated vector mutations without an admin role * test: run vector IAM assertions before the shared engine is stopped * mini: optionally start and supervise the vector engine * mini: bootstrap vector buckets with existing Lance catalog helpers * shell: manage vector buckets, indexes, and vector data * docs: provide a runnable vector and maintenance worker Compose stack * shell: scope vector discovery to the session and close its connections * mini: honor the bind address for vector and metrics listeners * mini: reserve vector ports before assigning gRPC and compatibility listeners * mini: wait for vector storage setup and master registration * mini: create requested vector buckets without requiring the Lance HTTP listener * shell: refresh master addresses during vector discovery * mini: resolve sibling vector executables with platform extensions * vector: preserve uncertain creates and fix mini listener allocation (#12525) * vector: retain catalog records when index creation has an unknown outcome * mini: keep chosen listener ports reserved throughout allocation * mini: resolve hostname binds before starting vector listeners * vector: fix integration test imports and recover interrupted index creation (#12533) * shell: register vector operations from the command package * s3vectors: resume interrupted index initialization safely * mini: exclude disabled WebDAV from listener allocation * s3vectors: retain uncertain creates across refused retries * s3vectors: claim pending indexes before retrying initialization * s3vectors: compare resolved distance metrics during recovery * s3vectors: preserve metadata keys when retrying initialization * s3vectors: verify ownership before initializing new catalog records
131 lines
3.9 KiB
Go
131 lines
3.9 KiB
Go
package command
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/glog"
|
|
"github.com/seaweedfs/seaweedfs/weed/pb"
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
|
|
"github.com/seaweedfs/seaweedfs/weed/security"
|
|
"github.com/seaweedfs/seaweedfs/weed/util"
|
|
)
|
|
|
|
func startMiniVector() error {
|
|
binary := *miniVectorBinary
|
|
if binary == "weed-vector" {
|
|
if executable, err := os.Executable(); err == nil {
|
|
candidate := filepath.Join(filepath.Dir(executable), binary)
|
|
if resolved, err := exec.LookPath(candidate); err == nil {
|
|
binary = resolved
|
|
}
|
|
}
|
|
}
|
|
if _, err := exec.LookPath(binary); err != nil {
|
|
return fmt.Errorf("%s is unavailable: install the vector component or set -vector.binary: %w", binary, err)
|
|
}
|
|
address := util.JoinHostPort(*miniIp, *miniVectorPort)
|
|
bindIP := *miniBindIp
|
|
if bindIP == "" {
|
|
bindIP = *miniIp
|
|
}
|
|
if net.ParseIP(bindIP) == nil {
|
|
ctx, cancel := context.WithTimeout(miniClientsCtx(), 5*time.Second)
|
|
addresses, err := net.DefaultResolver.LookupIPAddr(ctx, bindIP)
|
|
cancel()
|
|
if err != nil {
|
|
return fmt.Errorf("resolve vector bind address %s: %w", bindIP, err)
|
|
}
|
|
if len(addresses) == 0 {
|
|
return fmt.Errorf("vector bind address %s has no IP addresses", bindIP)
|
|
}
|
|
bindIP = addresses[0].String()
|
|
}
|
|
|
|
args := []string{"--listen=" + util.JoinHostPort(bindIP, *miniVectorPort), "--advertise=" + address, "--masters=" + string(pb.NewServerAddress(*miniIp, *miniMasterOptions.port, *miniMasterOptions.portGrpc))}
|
|
if miniFilerOptions.filerGroup != nil && *miniFilerOptions.filerGroup != "" {
|
|
args = append(args, "--filer-group="+*miniFilerOptions.filerGroup)
|
|
}
|
|
if *miniVectorMetricsPort > 0 {
|
|
args = append(args, fmt.Sprintf("--metrics-port=%d", *miniVectorMetricsPort), "--metrics-ip="+bindIP)
|
|
}
|
|
if directory := util.ConfigurationFileDirectory.String(); directory != "" {
|
|
args = append(args, "--config-dir="+util.ResolvePath(directory))
|
|
}
|
|
command := exec.CommandContext(miniClientsCtx(), binary, args...)
|
|
command.Stdout, command.Stderr = os.Stdout, os.Stderr
|
|
if err := command.Start(); err != nil {
|
|
return err
|
|
}
|
|
done := trackMiniClient()
|
|
exited := make(chan error, 1)
|
|
go func() {
|
|
defer done()
|
|
err := command.Wait()
|
|
exited <- err
|
|
if err != nil && miniClientsCtx().Err() == nil {
|
|
glog.Errorf("vector engine exited: %v", err)
|
|
}
|
|
}()
|
|
ctx, cancel := context.WithTimeout(miniClientsCtx(), 30*time.Second)
|
|
defer cancel()
|
|
ticker := time.NewTicker(100 * time.Millisecond)
|
|
defer ticker.Stop()
|
|
for {
|
|
select {
|
|
case err := <-exited:
|
|
return fmt.Errorf("vector engine exited before readiness: %v", err)
|
|
case <-ctx.Done():
|
|
_ = command.Process.Kill()
|
|
return ctx.Err()
|
|
case <-ticker.C:
|
|
conn, err := net.DialTimeout("tcp", miniVectorLocalAddress(bindIP, *miniVectorPort), 100*time.Millisecond)
|
|
if err == nil {
|
|
_ = conn.Close()
|
|
if !miniVectorRegistered(ctx, address) {
|
|
continue
|
|
}
|
|
glog.V(0).Infof("vector engine ready on %s", address)
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func miniVectorLocalAddress(bindIP string, port int) string {
|
|
if ip := net.ParseIP(bindIP); ip != nil && ip.IsUnspecified() {
|
|
if ip.To4() != nil {
|
|
bindIP = "127.0.0.1"
|
|
} else {
|
|
bindIP = "::1"
|
|
}
|
|
}
|
|
return util.JoinHostPort(bindIP, port)
|
|
}
|
|
|
|
func miniVectorRegistered(ctx context.Context, address string) bool {
|
|
ctx, cancel := context.WithTimeout(ctx, time.Second)
|
|
defer cancel()
|
|
master := pb.NewServerAddress(*miniIp, *miniMasterOptions.port, *miniMasterOptions.portGrpc)
|
|
ready := false
|
|
_ = pb.WithMasterClient(ctx, false, master, security.LoadClientTLS(util.GetViper(), "grpc.client"), false, func(client master_pb.SeaweedClient) error {
|
|
response, err := client.ListClusterNodes(ctx, &master_pb.ListClusterNodesRequest{ClientType: "vector", FilerGroup: *miniFilerOptions.filerGroup})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, node := range response.ClusterNodes {
|
|
if node.Address == address {
|
|
ready = true
|
|
break
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
return ready
|
|
}
|