Skip to content

Commit

Permalink
Allow service.Host to return services (#6348)
Browse files Browse the repository at this point in the history
Signed-off-by: Paschalis Tsilias <[email protected]>
  • Loading branch information
tpaschalis authored Feb 13, 2024
1 parent abbf2dc commit 1f3943d
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 13 deletions.
2 changes: 0 additions & 2 deletions cmd/internal/flowmode/cmd_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"github.com/grafana/agent/pkg/flow/tracing"
"github.com/grafana/agent/pkg/usagestats"
"github.com/grafana/agent/service"
"github.com/grafana/agent/service/cluster"
httpservice "github.com/grafana/agent/service/http"
"github.com/grafana/agent/service/labelstore"
otel_service "github.com/grafana/agent/service/otel"
Expand Down Expand Up @@ -254,7 +253,6 @@ func (fr *flowRun) Run(configPath string) error {

uiService := uiservice.New(uiservice.Options{
UIPrefix: fr.uiPrefix,
Cluster: clusterService.Data().(cluster.Cluster),
})

otelService := otel_service.New(l)
Expand Down
11 changes: 11 additions & 0 deletions pkg/flow/flow_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ func (f *Flow) GetServiceConsumers(serviceName string) []service.Consumer {
return consumers
}

// GetService implements [service.Host]. It looks up a [service.Service] by
// name.
func (f *Flow) GetService(name string) (service.Service, bool) {
for _, svc := range f.opts.Services {
if svc.Definition().Name == name {
return svc, true
}
}
return nil, false
}

func serviceConsumersForGraph(graph *dag.Graph, serviceName string, includePeerServices bool) []service.Consumer {
serviceNode, _ := graph.GetByID(serviceName).(*controller.ServiceNode)
if serviceNode == nil {
Expand Down
2 changes: 2 additions & 0 deletions service/http/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,5 @@ func (fakeHost) ListComponents(moduleID string, opts component.InfoOptions) ([]*
func (fakeHost) GetServiceConsumers(serviceName string) []service.Consumer { return nil }

func (fakeHost) NewController(id string) service.Controller { return nil }

func (fakeHost) GetService(_ string) (service.Service, bool) { return nil, false }
3 changes: 2 additions & 1 deletion service/remotecfg/remotecfg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ func (fakeHost) ListComponents(moduleID string, opts component.InfoOptions) ([]*
return nil, fmt.Errorf("no such module %q", moduleID)
}

func (fakeHost) GetServiceConsumers(serviceName string) []service.Consumer { return nil }
func (fakeHost) GetServiceConsumers(_ string) []service.Consumer { return nil }
func (fakeHost) GetService(_ string) (service.Service, bool) { return nil, false }

func (f fakeHost) NewController(id string) service.Controller {
logger, _ := logging.New(io.Discard, logging.DefaultOptions)
Expand Down
3 changes: 3 additions & 0 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ type Host interface {
// exist.
ListComponents(moduleID string, opts component.InfoOptions) ([]*component.Info, error)

// GetService gets a running service using its name.
GetService(name string) (Service, bool)

// GetServiceConsumers gets the list of services which depend on a service by
// name.
GetServiceConsumers(serviceName string) []Consumer
Expand Down
6 changes: 1 addition & 5 deletions service/ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/gorilla/mux"
"github.com/grafana/agent/service"
"github.com/grafana/agent/service/cluster"
http_service "github.com/grafana/agent/service/http"
"github.com/grafana/agent/web/api"
"github.com/grafana/agent/web/ui"
Expand All @@ -21,7 +20,6 @@ const ServiceName = "ui"
// Options are used to configure the UI service. Options are constant for the
// lifetime of the UI service.
type Options struct {
Cluster cluster.Cluster
UIPrefix string // Path prefix to host the UI at.
}

Expand Down Expand Up @@ -75,9 +73,7 @@ func (s *Service) Data() any {
func (s *Service) ServiceHandler(host service.Host) (base string, handler http.Handler) {
r := mux.NewRouter()

// TODO(rfratto): allow service.Host to return services so we don't have to
// pass the clustering service in Options.
fa := api.NewFlowAPI(host, s.opts.Cluster)
fa := api.NewFlowAPI(host)
fa.RegisterRoutes(path.Join(s.opts.UIPrefix, "/api/v0/web"), r)
ui.RegisterRoutes(s.opts.UIPrefix, r)

Expand Down
15 changes: 10 additions & 5 deletions web/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ import (

"github.com/gorilla/mux"
"github.com/grafana/agent/component"
"github.com/grafana/agent/service"
"github.com/grafana/agent/service/cluster"
"github.com/prometheus/prometheus/util/httputil"
)

// FlowAPI is a wrapper around the component API.
type FlowAPI struct {
flow component.Provider
cluster cluster.Cluster
flow service.Host
}

// NewFlowAPI instantiates a new Flow API.
func NewFlowAPI(flow component.Provider, cluster cluster.Cluster) *FlowAPI {
return &FlowAPI{flow: flow, cluster: cluster}
func NewFlowAPI(flow service.Host) *FlowAPI {
return &FlowAPI{flow: flow}
}

// RegisterRoutes registers all the API's routes.
Expand Down Expand Up @@ -93,7 +93,12 @@ func (f *FlowAPI) getClusteringPeersHandler() http.HandlerFunc {
return func(w http.ResponseWriter, _ *http.Request) {
// TODO(@tpaschalis) Detect if clustering is disabled and propagate to
// the Typescript code (eg. via the returned status code?).
peers := f.cluster.Peers()
svc, found := f.flow.GetService(cluster.ServiceName)
if !found {
http.Error(w, "cluster service not running", http.StatusInternalServerError)
return
}
peers := svc.Data().(cluster.Cluster).Peers()
bb, err := json.Marshal(peers)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
Expand Down

0 comments on commit 1f3943d

Please sign in to comment.