Add GoVPP integration and GetVPPInfo gRPC call
VPP client (internal/vpp/) - New package managing connections to both VPP API and stats sockets, treated as a unit: if either drops, both are torn down and re-established together. - Run() loop: connect, fetch version via vpe.ShowVersion, read /sys/boottime from the stats segment, log vpp-connect, then monitor with control_ping every 10s. On failure, disconnect both, retry after 5s. - Registers as client name "vpp-maglev" (visible in VPP's "show api clients"). - Flags: --vpp-api-addr (default /run/vpp/api.sock) and --vpp-stats-addr (default /run/vpp/stats.sock). Empty api addr disables VPP integration entirely. gRPC / proto - Add GetVPPInfo RPC returning VPPInfo: version, build_date, build_directory, pid, boottime_ns, connecttime_ns. Both times are unix timestamps in nanoseconds — the client computes durations locally for display. - Returns codes.Unavailable if VPP is disabled or not connected. maglevc - Add 'show vpp info' command displaying version, build-date, build-dir, vpp-pid, vpp-boottime (with duration), and connected time (with duration).
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"git.ipng.ch/ipng/vpp-maglev/internal/checker"
|
||||
"git.ipng.ch/ipng/vpp-maglev/internal/config"
|
||||
"git.ipng.ch/ipng/vpp-maglev/internal/health"
|
||||
"git.ipng.ch/ipng/vpp-maglev/internal/vpp"
|
||||
)
|
||||
|
||||
// Server implements the MaglevServer gRPC interface.
|
||||
@@ -22,16 +23,17 @@ type Server struct {
|
||||
checker *checker.Checker
|
||||
logs *LogBroadcaster
|
||||
configPath string
|
||||
vppClient *vpp.Client // nil when VPP integration is disabled
|
||||
}
|
||||
|
||||
// NewServer creates a Server backed by the given Checker. logs may be nil, in
|
||||
// which case log events are never sent to WatchEvents streams. configPath is
|
||||
// used by CheckConfig to reload and validate the configuration file on demand.
|
||||
// The provided context controls the lifetime of streaming RPCs: cancelling it
|
||||
// closes all active WatchEvents streams so that grpc.Server.GracefulStop can
|
||||
// complete.
|
||||
func NewServer(ctx context.Context, c *checker.Checker, logs *LogBroadcaster, configPath string) *Server {
|
||||
return &Server{ctx: ctx, checker: c, logs: logs, configPath: configPath}
|
||||
// vppClient may be nil if VPP integration is disabled. The provided context
|
||||
// controls the lifetime of streaming RPCs: cancelling it closes all active
|
||||
// WatchEvents streams so that grpc.Server.GracefulStop can complete.
|
||||
func NewServer(ctx context.Context, c *checker.Checker, logs *LogBroadcaster, configPath string, vppClient *vpp.Client) *Server {
|
||||
return &Server{ctx: ctx, checker: c, logs: logs, configPath: configPath, vppClient: vppClient}
|
||||
}
|
||||
|
||||
// ListFrontends returns the names of all configured frontends.
|
||||
@@ -257,6 +259,29 @@ func (s *Server) doReloadConfig() *ReloadConfigResponse {
|
||||
return &ReloadConfigResponse{Ok: true}
|
||||
}
|
||||
|
||||
// GetVPPInfo returns VPP version and runtime information.
|
||||
func (s *Server) GetVPPInfo(_ context.Context, _ *GetVPPInfoRequest) (*VPPInfo, error) {
|
||||
if s.vppClient == nil {
|
||||
return nil, status.Error(codes.Unavailable, "VPP integration is disabled")
|
||||
}
|
||||
info, err := s.vppClient.GetInfo()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unavailable, "%v", err)
|
||||
}
|
||||
var boottimeNs int64
|
||||
if !info.BootTime.IsZero() {
|
||||
boottimeNs = info.BootTime.UnixNano()
|
||||
}
|
||||
return &VPPInfo{
|
||||
Version: info.Version,
|
||||
BuildDate: info.BuildDate,
|
||||
BuildDirectory: info.BuildDirectory,
|
||||
Pid: info.PID,
|
||||
BoottimeNs: boottimeNs,
|
||||
ConnecttimeNs: info.ConnectedSince.UnixNano(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ---- conversion helpers ----------------------------------------------------
|
||||
|
||||
func frontendToProto(name string, fe config.Frontend) *FrontendInfo {
|
||||
|
||||
Reference in New Issue
Block a user