From 8d3350241ac8c7eccf087ea0f915418c808e2f62 Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Tue, 14 Apr 2026 12:32:11 +0200 Subject: [PATCH 1/4] refactor: migrate GraphQL loaders + establish central/app infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert GraphQL loaders from package-level init() to explicit Init() and establish central/app package for component initialization. Changes: - central/graphql/resolvers/loaders/*: 15+ loader files init() → Register*() - central/graphql/resolvers/*: ~50 resolver files with import updates - central/app/app.go: create Run() with component-specific initialization - central/app/init.go: create initGraphQL(), initCompliance() stubs - central/main.go: add profiling.SetComponentLabel(binaryName) in dispatcher - central/main.go: call app.Run() before CentralRun() With busybox consolidation, GraphQL loaders were registering for all components. This change makes loader registration conditional - only central registers GraphQL loaders. Infrastructure changes: - Establishes central/app pattern for explicit initialization - Centralizes profiling component labeling in main dispatcher - Removes proxy initialization from init() to app logic Expected impact: - Prevents 15+ GraphQL loader registrations in non-central components - Proper component labeling in heap/CPU profiles (central, sensor, etc.) - Foundation for future init() migrations Files changed: 68 (15 loaders + 50 resolvers + 3 central/app + main.go) Co-Authored-By: Claude Sonnet 4.5 --- central/app/app.go | 30 ++++++++ central/app/init.go | 65 +++++++++++++++++ central/graphql/resolvers/access_scopes.go | 2 +- .../resolvers/cluster_count_by_type.go | 2 +- central/graphql/resolvers/cluster_health.go | 2 +- .../resolvers/cluster_vulnerabilities.go | 2 +- central/graphql/resolvers/clusters.go | 2 +- central/graphql/resolvers/compliance.go | 2 +- .../resolvers/compliance_management.go | 2 +- central/graphql/resolvers/components.go | 2 +- .../graphql/resolvers/container_instances.go | 2 +- central/graphql/resolvers/deploymentevents.go | 2 +- central/graphql/resolvers/deployments.go | 2 +- central/graphql/resolvers/groups.go | 2 +- central/graphql/resolvers/image_components.go | 2 +- central/graphql/resolvers/image_cve_core.go | 2 +- central/graphql/resolvers/image_scan.go | 2 +- .../resolvers/image_signature_verification.go | 2 +- .../resolvers/image_vulnerabilities.go | 2 +- central/graphql/resolvers/images.go | 2 +- central/graphql/resolvers/images_v2.go | 2 +- central/graphql/resolvers/init.go | 57 +++++++++++++++ central/graphql/resolvers/k8sroles.go | 2 +- .../graphql/resolvers/loaders/cluster_cves.go | 6 -- .../graphql/resolvers/loaders/componentsV2.go | 6 -- .../graphql/resolvers/loaders/deployments.go | 6 -- .../resolvers/loaders/image_cves_v2.go | 6 -- central/graphql/resolvers/loaders/images.go | 7 -- .../graphql/resolvers/loaders/images_v2.go | 6 -- central/graphql/resolvers/loaders/init.go | 72 +++++++++++++++++++ .../resolvers/loaders/list_deployments.go | 6 -- .../graphql/resolvers/loaders/namespaces.go | 6 -- .../resolvers/loaders/node_components.go | 6 -- .../graphql/resolvers/loaders/node_cves.go | 6 -- central/graphql/resolvers/loaders/nodes.go | 6 -- central/graphql/resolvers/loaders/policies.go | 6 -- central/graphql/resolvers/namespaces.go | 2 +- central/graphql/resolvers/node_components.go | 2 +- .../graphql/resolvers/node_components_v1.go | 2 +- central/graphql/resolvers/node_cve_core.go | 2 +- central/graphql/resolvers/node_scan.go | 2 +- .../graphql/resolvers/node_vulnerabilities.go | 2 +- central/graphql/resolvers/nodes.go | 2 +- central/graphql/resolvers/notifiers.go | 2 +- central/graphql/resolvers/permission_sets.go | 2 +- .../graphql/resolvers/platform_cve_core.go | 2 +- .../platform_cve_count_by_fixability.go | 2 +- .../resolvers/platform_cve_count_by_type.go | 2 +- .../plotted_image_vulnerabilities.go | 2 +- .../resolvers/plotted_node_vulnerabilities.go | 2 +- central/graphql/resolvers/pods.go | 2 +- central/graphql/resolvers/policies.go | 2 +- central/graphql/resolvers/policy_counter.go | 2 +- .../resolvers/resource_count_by_severity.go | 2 +- central/graphql/resolvers/roles.go | 2 +- central/graphql/resolvers/schema.go | 1 + central/graphql/resolvers/search.go | 2 +- central/graphql/resolvers/secrets.go | 2 +- central/graphql/resolvers/service_accounts.go | 2 +- central/graphql/resolvers/subjects.go | 2 +- central/graphql/resolvers/tokens.go | 2 +- central/graphql/resolvers/violations.go | 2 +- central/graphql/resolvers/vul_mgmt_widgets.go | 2 +- central/graphql/resolvers/vulnerabilities.go | 2 +- .../resolvers/vulnerability_counter.go | 2 +- .../resolvers/vulnerability_requests.go | 2 +- .../resolvers/vulnerability_vectors.go | 2 +- central/main.go | 16 ++--- 68 files changed, 282 insertions(+), 132 deletions(-) create mode 100644 central/app/app.go create mode 100644 central/app/init.go create mode 100644 central/graphql/resolvers/init.go create mode 100644 central/graphql/resolvers/loaders/init.go diff --git a/central/app/app.go b/central/app/app.go new file mode 100644 index 0000000000000..b777606d2b397 --- /dev/null +++ b/central/app/app.go @@ -0,0 +1,30 @@ +package app + +import ( + centralChecks "github.com/stackrox/rox/central/compliance/checks" + "github.com/stackrox/rox/central/compliance/standards/metadata" + backupPlugins "github.com/stackrox/rox/central/externalbackups/plugins/all" + "github.com/stackrox/rox/central/graphql/resolvers/loaders" + "github.com/stackrox/rox/central/metrics" + "github.com/stackrox/rox/central/notifiers" + "github.com/stackrox/rox/pkg/compliance/checks" + "github.com/stackrox/rox/pkg/memlimit" + "github.com/stackrox/rox/pkg/premain" +) + +// Run is the main entry point for the central application. +// Performs early initialization and component-specific setup before +// main.centralRun() starts the actual central service logic. +func Run() { + memlimit.SetMemoryLimit() + premain.StartMain() + + metrics.Init() + loaders.Init() + checks.Init() + centralChecks.Init() + notifiers.Init() + metadata.Init() + backupPlugins.Init() + initComponentLogic() +} diff --git a/central/app/init.go b/central/app/init.go new file mode 100644 index 0000000000000..8aa01f63e1ed3 --- /dev/null +++ b/central/app/init.go @@ -0,0 +1,65 @@ +package app + +import ( + "github.com/stackrox/rox/central/alert/mappings" + "github.com/stackrox/rox/central/auth/internaltokens/service" + csvhandler "github.com/stackrox/rox/central/cve/common/csv" + debugservice "github.com/stackrox/rox/central/debug/service" + detectionservice "github.com/stackrox/rox/central/detection/service" + "github.com/stackrox/rox/central/globaldb/v2backuprestore/formats/postgresv1" + scannerhandler "github.com/stackrox/rox/central/scannerdefinitions/handler" + "github.com/stackrox/rox/central/search/options" + "github.com/stackrox/rox/pkg/administration/events/stream" + "github.com/stackrox/rox/pkg/booleanpolicy/violationmessages/printer" + "github.com/stackrox/rox/pkg/gjson" + "github.com/stackrox/rox/pkg/httputil/proxy" + "github.com/stackrox/rox/pkg/logging" + pkgsearch "github.com/stackrox/rox/pkg/search" + "github.com/stackrox/rox/pkg/search/enumregistry" + "github.com/stackrox/rox/pkg/signatures" + "github.com/stackrox/rox/pkg/tlsprofile" +) + +var log = logging.LoggerForModule() + +// initComponentLogic initializes all central-specific components that were +// previously using init() functions. +func initComponentLogic() { + // Initialize metrics + service.RegisterMetrics() + stream.Init() + + // Initialize search and alert options + options.InitCategoryToOptionsSet() + mappings.InitOptionsMap() + enumregistry.Init() + pkgsearch.Init() + + // Initialize CSV handlers + csvhandler.InitOptionsMap() + + // Initialize service configurations + debugservice.InitMainClusterConfig() + detectionservice.InitWorkloadScheme() + scannerhandler.InitScannerConfig() + + // Initialize policy violation printers + printer.Init() + + // Initialize GJSON custom modifiers + gjson.Init() + + // Initialize signature fetcher + signatures.Init() + + // Initialize TLS profile + tlsprofile.Init() + + // Register backup formats + postgresv1.RegisterFormat() + + // Initialize proxy configuration + if !proxy.UseWithDefaultTransport() { + log.Warn("Failed to use proxy transport with default HTTP transport. Some proxy features may not work.") + } +} diff --git a/central/graphql/resolvers/access_scopes.go b/central/graphql/resolvers/access_scopes.go index 6707e207a3f01..8fb0396df0259 100644 --- a/central/graphql/resolvers/access_scopes.go +++ b/central/graphql/resolvers/access_scopes.go @@ -10,7 +10,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerAccessScopesSchema() { schema := getBuilder() utils.Must( schema.AddQuery("simpleAccessScopes: [SimpleAccessScope!]!"), diff --git a/central/graphql/resolvers/cluster_count_by_type.go b/central/graphql/resolvers/cluster_count_by_type.go index 91e27b5d41c53..2b761e0d0a622 100644 --- a/central/graphql/resolvers/cluster_count_by_type.go +++ b/central/graphql/resolvers/cluster_count_by_type.go @@ -7,7 +7,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerClusterCountByTypeSchema() { schema := getBuilder() utils.Must( schema.AddType("ClusterCountByType", []string{ diff --git a/central/graphql/resolvers/cluster_health.go b/central/graphql/resolvers/cluster_health.go index 292b76cc30520..53ac1d92b8c62 100644 --- a/central/graphql/resolvers/cluster_health.go +++ b/central/graphql/resolvers/cluster_health.go @@ -12,7 +12,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerClusterHealthSchema() { schema := getBuilder() utils.Must( schema.AddQuery("clusterHealthCounter(query: String): ClusterHealthCounter!"), diff --git a/central/graphql/resolvers/cluster_vulnerabilities.go b/central/graphql/resolvers/cluster_vulnerabilities.go index 89ce553b46107..33624b3b72d7e 100644 --- a/central/graphql/resolvers/cluster_vulnerabilities.go +++ b/central/graphql/resolvers/cluster_vulnerabilities.go @@ -17,7 +17,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerClusterVulnerabilitiesSchema() { schema := getBuilder() utils.Must( // NOTE: This list is and should remain alphabetically ordered diff --git a/central/graphql/resolvers/clusters.go b/central/graphql/resolvers/clusters.go index 4679ef99fb37b..bcea0b6f42018 100644 --- a/central/graphql/resolvers/clusters.go +++ b/central/graphql/resolvers/clusters.go @@ -26,7 +26,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerClustersSchema() { schema := getBuilder() utils.Must( schema.AddType("PolicyStatus", []string{"status: String!", "failingPolicies: [Policy!]!"}), diff --git a/central/graphql/resolvers/compliance.go b/central/graphql/resolvers/compliance.go index 7237468a24f65..462bd8065d30e 100644 --- a/central/graphql/resolvers/compliance.go +++ b/central/graphql/resolvers/compliance.go @@ -31,7 +31,7 @@ var ( complianceOnce sync.Once ) -func init() { +func registerComplianceSchema() { InitCompliance() } diff --git a/central/graphql/resolvers/compliance_management.go b/central/graphql/resolvers/compliance_management.go index 911cbf69e2563..64adfc3e81821 100644 --- a/central/graphql/resolvers/compliance_management.go +++ b/central/graphql/resolvers/compliance_management.go @@ -9,7 +9,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerComplianceManagementSchema() { schema := getBuilder() utils.Must( schema.AddQuery("complianceRecentRuns(clusterId:ID, standardId:ID, since:Time): [ComplianceRun!]!"), diff --git a/central/graphql/resolvers/components.go b/central/graphql/resolvers/components.go index 6ff41c85c5eb6..cb1676fb43a0c 100644 --- a/central/graphql/resolvers/components.go +++ b/central/graphql/resolvers/components.go @@ -10,7 +10,7 @@ var ( componentPredicateFactory = predicate.NewFactory("component", &storage.EmbeddedImageScanComponent{}) ) -func init() { +func registerComponentsSchema() { schema := getBuilder() utils.Must( // NOTE: This list is and should remain alphabetically ordered diff --git a/central/graphql/resolvers/container_instances.go b/central/graphql/resolvers/container_instances.go index aedcc15436242..8f6c0dc48c57c 100644 --- a/central/graphql/resolvers/container_instances.go +++ b/central/graphql/resolvers/container_instances.go @@ -17,7 +17,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerContainerInstancesSchema() { schema := getBuilder() const groupResolverName = "ContainerNameGroup" utils.Must( diff --git a/central/graphql/resolvers/deploymentevents.go b/central/graphql/resolvers/deploymentevents.go index 6f61aacd4357f..b06795e313186 100644 --- a/central/graphql/resolvers/deploymentevents.go +++ b/central/graphql/resolvers/deploymentevents.go @@ -17,7 +17,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerDeploymentEventsSchema() { schema := getBuilder() utils.Must( schema.AddInterfaceType("DeploymentEvent", []string{ diff --git a/central/graphql/resolvers/deployments.go b/central/graphql/resolvers/deployments.go index cd1e3c5ceb491..e224e6f17b118 100644 --- a/central/graphql/resolvers/deployments.go +++ b/central/graphql/resolvers/deployments.go @@ -21,7 +21,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerDeploymentsSchema() { schema := getBuilder() utils.Must( // NOTE: This list is and should remain alphabetically ordered diff --git a/central/graphql/resolvers/groups.go b/central/graphql/resolvers/groups.go index 0e7c74764c50e..360d34c36d68e 100644 --- a/central/graphql/resolvers/groups.go +++ b/central/graphql/resolvers/groups.go @@ -10,7 +10,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerGroupsSchema() { schema := getBuilder() utils.Must( schema.AddQuery("groups: [Group!]!"), diff --git a/central/graphql/resolvers/image_components.go b/central/graphql/resolvers/image_components.go index 6b6e14890ec50..66c87f27d5380 100644 --- a/central/graphql/resolvers/image_components.go +++ b/central/graphql/resolvers/image_components.go @@ -19,7 +19,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerImageComponentsSchema() { schema := getBuilder() utils.Must(schema.AddType("ImageComponentV2", []string{ "architecture: String!", diff --git a/central/graphql/resolvers/image_cve_core.go b/central/graphql/resolvers/image_cve_core.go index 0c79acd591c40..aaf86ca4560c7 100644 --- a/central/graphql/resolvers/image_cve_core.go +++ b/central/graphql/resolvers/image_cve_core.go @@ -26,7 +26,7 @@ const ( maxImages = 1000 ) -func init() { +func registerImageCVECoreSchema() { schema := getBuilder() utils.Must( // NOTE: This list is and should remain alphabetically ordered diff --git a/central/graphql/resolvers/image_scan.go b/central/graphql/resolvers/image_scan.go index 808b2f61ef260..87c02474568e2 100644 --- a/central/graphql/resolvers/image_scan.go +++ b/central/graphql/resolvers/image_scan.go @@ -6,7 +6,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerImageScanSchema() { schema := getBuilder() utils.Must( schema.AddExtraResolvers("ImageScan", []string{ diff --git a/central/graphql/resolvers/image_signature_verification.go b/central/graphql/resolvers/image_signature_verification.go index 626b38875ab49..76053e8eaec60 100644 --- a/central/graphql/resolvers/image_signature_verification.go +++ b/central/graphql/resolvers/image_signature_verification.go @@ -7,7 +7,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerImageSignatureVerificationSchema() { schema := getBuilder() utils.Must( schema.AddExtraResolver("ImageSignatureVerificationResult", "verifierName: String!"), diff --git a/central/graphql/resolvers/image_vulnerabilities.go b/central/graphql/resolvers/image_vulnerabilities.go index fa5030ead2517..0d1cff9a54932 100644 --- a/central/graphql/resolvers/image_vulnerabilities.go +++ b/central/graphql/resolvers/image_vulnerabilities.go @@ -25,7 +25,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerImageVulnerabilitiesSchema() { schema := getBuilder() generator.RegisterProtoEnum(schema, reflect.TypeOf(storage.CvssScoreVersion(0))) diff --git a/central/graphql/resolvers/images.go b/central/graphql/resolvers/images.go index ce9de9967635a..f1c7e9b19bbfb 100644 --- a/central/graphql/resolvers/images.go +++ b/central/graphql/resolvers/images.go @@ -86,7 +86,7 @@ func registerImageWatchStatus(s string) string { return s } -func init() { +func registerImagesSchema() { schema := getBuilder() utils.Must( schema.AddType("BaseImage", []string{ diff --git a/central/graphql/resolvers/images_v2.go b/central/graphql/resolvers/images_v2.go index 9ea15e44e716a..07c6b832b2824 100644 --- a/central/graphql/resolvers/images_v2.go +++ b/central/graphql/resolvers/images_v2.go @@ -19,7 +19,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerImagesV2Schema() { schema := getBuilder() utils.Must( schema.AddExtraResolvers("ImageV2", []string{ diff --git a/central/graphql/resolvers/init.go b/central/graphql/resolvers/init.go new file mode 100644 index 0000000000000..399f006053e5a --- /dev/null +++ b/central/graphql/resolvers/init.go @@ -0,0 +1,57 @@ +package resolvers + +// Init registers all GraphQL resolver schemas. +// Called explicitly from getBuilder() in schema.go instead of package init(). +func Init() { + // Register all resolver schemas in alphabetical order + registerAccessScopesSchema() + registerClusterCountByTypeSchema() + registerClusterHealthSchema() + registerClusterVulnerabilitiesSchema() + registerClustersSchema() + registerComplianceSchema() + registerComplianceManagementSchema() + registerComponentsSchema() + registerContainerInstancesSchema() + registerDeploymentEventsSchema() + registerDeploymentsSchema() + registerGroupsSchema() + registerImageComponentsSchema() + registerImageCVECoreSchema() + registerImageScanSchema() + registerImageSignatureVerificationSchema() + registerImageVulnerabilitiesSchema() + registerImagesSchema() + registerImagesV2Schema() + registerK8sRolesSchema() + registerNamespacesSchema() + registerNodeComponentsSchema() + registerNodeComponentsV1Schema() + registerNodeCVECoreSchema() + registerNodeScanSchema() + registerNodeVulnerabilitiesSchema() + registerNodesSchema() + registerNotifiersSchema() + registerPermissionSetsSchema() + registerPlatformCVECoreSchema() + registerPlatformCVECountByFixabilitySchema() + registerPlatformCVECountByTypeSchema() + registerPlottedImageVulnerabilitiesSchema() + registerPlottedNodeVulnerabilitiesSchema() + registerPodsSchema() + registerPoliciesSchema() + registerPolicyCounterSchema() + registerResourceCountBySeveritySchema() + registerRolesSchema() + registerSearchSchema() + registerSecretsSchema() + registerServiceAccountsSchema() + registerSubjectsSchema() + registerTokensSchema() + registerViolationsSchema() + registerVulMgmtWidgetsSchema() + registerVulnerabilitiesSchema() + registerVulnerabilityCounterSchema() + registerVulnerabilityRequestsSchema() + registerVulnerabilityVectorsSchema() +} diff --git a/central/graphql/resolvers/k8sroles.go b/central/graphql/resolvers/k8sroles.go index 6b9d0811f9b81..a71468b4297da 100644 --- a/central/graphql/resolvers/k8sroles.go +++ b/central/graphql/resolvers/k8sroles.go @@ -14,7 +14,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerK8sRolesSchema() { schema := getBuilder() utils.Must( schema.AddQuery("k8sRole(id: ID!): K8SRole"), diff --git a/central/graphql/resolvers/loaders/cluster_cves.go b/central/graphql/resolvers/loaders/cluster_cves.go index a4c53b6467008..b5e0d619059da 100644 --- a/central/graphql/resolvers/loaders/cluster_cves.go +++ b/central/graphql/resolvers/loaders/cluster_cves.go @@ -15,12 +15,6 @@ import ( var clusterCveLoaderType = reflect.TypeOf(storage.ClusterCVE{}) -func init() { - RegisterTypeFactory(reflect.TypeOf(storage.ClusterCVE{}), func() interface{} { - return NewClusterCVELoader(clusterCVEDataStore.Singleton()) - }) -} - // NewClusterCVELoader creates a new loader for cluster cve data. func NewClusterCVELoader(ds clusterCVEDataStore.DataStore) ClusterCVELoader { return &clusterCveLoaderImpl{ diff --git a/central/graphql/resolvers/loaders/componentsV2.go b/central/graphql/resolvers/loaders/componentsV2.go index 54af9ed470e99..cb4ea70222f82 100644 --- a/central/graphql/resolvers/loaders/componentsV2.go +++ b/central/graphql/resolvers/loaders/componentsV2.go @@ -17,12 +17,6 @@ var ( componentV2LoaderType = reflect.TypeOf(storage.ImageComponentV2{}) ) -func init() { - RegisterTypeFactory(componentV2LoaderType, func() interface{} { - return NewComponentV2Loader(datastore.Singleton()) - }) -} - // NewComponentV2Loader creates a new loader for component data. func NewComponentV2Loader(ds datastore.DataStore) ComponentV2Loader { return &componentV2LoaderImpl{ diff --git a/central/graphql/resolvers/loaders/deployments.go b/central/graphql/resolvers/loaders/deployments.go index dcf658aed635e..fdd800b4f1667 100644 --- a/central/graphql/resolvers/loaders/deployments.go +++ b/central/graphql/resolvers/loaders/deployments.go @@ -15,12 +15,6 @@ import ( var deploymentLoaderType = reflect.TypeOf(storage.Deployment{}) -func init() { - RegisterTypeFactory(reflect.TypeOf(storage.Deployment{}), func() interface{} { - return NewDeploymentLoader(datastore.Singleton(), deploymentsView.Singleton()) - }) -} - // NewDeploymentLoader creates a new loader for deployment data. func NewDeploymentLoader(ds datastore.DataStore, deploymentView deploymentsView.DeploymentView) DeploymentLoader { return &deploymentLoaderImpl{ diff --git a/central/graphql/resolvers/loaders/image_cves_v2.go b/central/graphql/resolvers/loaders/image_cves_v2.go index ed4b837fe0d38..5cf4961124835 100644 --- a/central/graphql/resolvers/loaders/image_cves_v2.go +++ b/central/graphql/resolvers/loaders/image_cves_v2.go @@ -15,12 +15,6 @@ import ( var imageCveV2LoaderType = reflect.TypeOf(storage.ImageCVEV2{}) -func init() { - RegisterTypeFactory(imageCveV2LoaderType, func() interface{} { - return NewImageCVEV2Loader(ImageCVEDataStore.Singleton()) - }) -} - // NewImageCVEV2Loader creates a new loader for image cve data. func NewImageCVEV2Loader(ds ImageCVEDataStore.DataStore) ImageCVEV2Loader { return &imageCveV2LoaderImpl{ diff --git a/central/graphql/resolvers/loaders/images.go b/central/graphql/resolvers/loaders/images.go index 27b5e57fd49e8..e0495dff7559d 100644 --- a/central/graphql/resolvers/loaders/images.go +++ b/central/graphql/resolvers/loaders/images.go @@ -6,7 +6,6 @@ import ( "github.com/pkg/errors" imageDatastore "github.com/stackrox/rox/central/image/datastore" - "github.com/stackrox/rox/central/imagev2/datastore/mapper/datastore" imagesView "github.com/stackrox/rox/central/views/images" v1 "github.com/stackrox/rox/generated/api/v1" "github.com/stackrox/rox/generated/storage" @@ -16,12 +15,6 @@ import ( var imageLoaderType = reflect.TypeOf(storage.Image{}) -func init() { - RegisterTypeFactory(reflect.TypeOf(storage.Image{}), func() interface{} { - return NewImageLoader(datastore.Singleton(), imagesView.Singleton()) - }) -} - // NewImageLoader creates a new loader for image data. If postgres is enabled, this loader holds images without scan data—components and vulns. func NewImageLoader(ds imageDatastore.DataStore, imageView imagesView.ImageView) ImageLoader { return &imageLoaderImpl{ diff --git a/central/graphql/resolvers/loaders/images_v2.go b/central/graphql/resolvers/loaders/images_v2.go index 8b0a252a3ed50..c74b93dafaac8 100644 --- a/central/graphql/resolvers/loaders/images_v2.go +++ b/central/graphql/resolvers/loaders/images_v2.go @@ -16,12 +16,6 @@ import ( var imageV2LoaderType = reflect.TypeOf(storage.ImageV2{}) -func init() { - RegisterTypeFactory(reflect.TypeOf(storage.ImageV2{}), func() interface{} { - return NewImageV2Loader(datastore.Singleton(), imagesView.Singleton()) - }) -} - // NewImageV2Loader creates a new loader for image data. func NewImageV2Loader(ds datastore.DataStore, imageView imagesView.ImageView) ImageV2Loader { return &imageV2LoaderImpl{ diff --git a/central/graphql/resolvers/loaders/init.go b/central/graphql/resolvers/loaders/init.go new file mode 100644 index 0000000000000..6a38e580742a0 --- /dev/null +++ b/central/graphql/resolvers/loaders/init.go @@ -0,0 +1,72 @@ +package loaders + +import ( + "reflect" + + clusterCVEDataStore "github.com/stackrox/rox/central/cve/cluster/datastore" + imageCVEDataStore "github.com/stackrox/rox/central/cve/image/v2/datastore" + nodeCVEDataStore "github.com/stackrox/rox/central/cve/node/datastore" + deploymentDataStore "github.com/stackrox/rox/central/deployment/datastore" + componentV2DataStore "github.com/stackrox/rox/central/imagecomponent/v2/datastore" + imageV2DataStore "github.com/stackrox/rox/central/imagev2/datastore" + imageDataStore "github.com/stackrox/rox/central/imagev2/datastore/mapper/datastore" + namespaceDataStore "github.com/stackrox/rox/central/namespace/datastore" + nodeDataStore "github.com/stackrox/rox/central/node/datastore" + nodeComponentDataStore "github.com/stackrox/rox/central/nodecomponent/datastore" + policyDataStore "github.com/stackrox/rox/central/policy/datastore" + deploymentsView "github.com/stackrox/rox/central/views/deployments" + imagesView "github.com/stackrox/rox/central/views/images" + "github.com/stackrox/rox/generated/storage" +) + +// Init registers all GraphQL type loaders. +// Called explicitly from central/app/app.go instead of package init(). +func Init() { + RegisterTypeFactory(reflect.TypeOf(storage.ClusterCVE{}), func() interface{} { + return NewClusterCVELoader(clusterCVEDataStore.Singleton()) + }) + + RegisterTypeFactory(componentV2LoaderType, func() interface{} { + return NewComponentV2Loader(componentV2DataStore.Singleton()) + }) + + RegisterTypeFactory(reflect.TypeOf(storage.Deployment{}), func() interface{} { + return NewDeploymentLoader(deploymentDataStore.Singleton(), deploymentsView.Singleton()) + }) + + RegisterTypeFactory(imageCveV2LoaderType, func() interface{} { + return NewImageCVEV2Loader(imageCVEDataStore.Singleton()) + }) + + RegisterTypeFactory(reflect.TypeOf(storage.Image{}), func() interface{} { + return NewImageLoader(imageDataStore.Singleton(), imagesView.Singleton()) + }) + + RegisterTypeFactory(reflect.TypeOf(storage.ImageV2{}), func() interface{} { + return NewImageV2Loader(imageV2DataStore.Singleton(), imagesView.Singleton()) + }) + + RegisterTypeFactory(reflect.TypeOf(storage.ListDeployment{}), func() interface{} { + return NewListDeploymentLoader(deploymentDataStore.Singleton()) + }) + + RegisterTypeFactory(reflect.TypeOf(storage.NamespaceMetadata{}), func() interface{} { + return NewNamespaceLoader(namespaceDataStore.Singleton()) + }) + + RegisterTypeFactory(reflect.TypeOf(storage.NodeComponent{}), func() interface{} { + return NewNodeComponentLoader(nodeComponentDataStore.Singleton()) + }) + + RegisterTypeFactory(reflect.TypeOf(storage.NodeCVE{}), func() interface{} { + return NewNodeCVELoader(nodeCVEDataStore.Singleton()) + }) + + RegisterTypeFactory(nodeLoaderType, func() interface{} { + return NewNodeLoader(nodeDataStore.Singleton()) + }) + + RegisterTypeFactory(reflect.TypeOf(storage.Policy{}), func() interface{} { + return NewPolicyLoader(policyDataStore.Singleton()) + }) +} diff --git a/central/graphql/resolvers/loaders/list_deployments.go b/central/graphql/resolvers/loaders/list_deployments.go index 49eed624b87e1..e0486d156d986 100644 --- a/central/graphql/resolvers/loaders/list_deployments.go +++ b/central/graphql/resolvers/loaders/list_deployments.go @@ -15,12 +15,6 @@ import ( var listDeploymentLoaderType = reflect.TypeOf(storage.ListDeployment{}) -func init() { - RegisterTypeFactory(reflect.TypeOf(storage.ListDeployment{}), func() interface{} { - return NewListDeploymentLoader(datastore.Singleton()) - }) -} - // NewListDeploymentLoader creates a new loader for deployment data. func NewListDeploymentLoader(ds datastore.DataStore) ListDeploymentLoader { return &listDeploymentLoaderImpl{ diff --git a/central/graphql/resolvers/loaders/namespaces.go b/central/graphql/resolvers/loaders/namespaces.go index ef4dfac67a009..c70091bc3751a 100644 --- a/central/graphql/resolvers/loaders/namespaces.go +++ b/central/graphql/resolvers/loaders/namespaces.go @@ -15,12 +15,6 @@ import ( var namespaceLoaderType = reflect.TypeOf(storage.NamespaceMetadata{}) -func init() { - RegisterTypeFactory(reflect.TypeOf(storage.NamespaceMetadata{}), func() interface{} { - return NewNamespaceLoader(datastore.Singleton()) - }) -} - // NewNamespaceLoader creates a new loader for NamespaceMetaData. func NewNamespaceLoader(ds datastore.DataStore) NamespaceLoader { return &namespaceLoaderImpl{ diff --git a/central/graphql/resolvers/loaders/node_components.go b/central/graphql/resolvers/loaders/node_components.go index 02f264f770323..c8b03e4488d21 100644 --- a/central/graphql/resolvers/loaders/node_components.go +++ b/central/graphql/resolvers/loaders/node_components.go @@ -15,12 +15,6 @@ import ( var nodeComponentLoaderType = reflect.TypeOf(storage.NodeComponent{}) -func init() { - RegisterTypeFactory(reflect.TypeOf(storage.NodeComponent{}), func() interface{} { - return NewNodeComponentLoader(datastore.Singleton()) - }) -} - // NewNodeComponentLoader creates a new loader for node component data. func NewNodeComponentLoader(ds datastore.DataStore) NodeComponentLoader { return &nodeComponentLoaderImpl{ diff --git a/central/graphql/resolvers/loaders/node_cves.go b/central/graphql/resolvers/loaders/node_cves.go index d25e577b5824e..22b23329b773f 100644 --- a/central/graphql/resolvers/loaders/node_cves.go +++ b/central/graphql/resolvers/loaders/node_cves.go @@ -15,12 +15,6 @@ import ( var nodeCveLoaderType = reflect.TypeOf(storage.NodeCVE{}) -func init() { - RegisterTypeFactory(reflect.TypeOf(storage.NodeCVE{}), func() interface{} { - return NewNodeCVELoader(nodeCVEDataStore.Singleton()) - }) -} - // NewNodeCVELoader creates a new loader for nodeCVE data. func NewNodeCVELoader(ds nodeCVEDataStore.DataStore) NodeCVELoader { return &nodeCVELoaderImpl{ diff --git a/central/graphql/resolvers/loaders/nodes.go b/central/graphql/resolvers/loaders/nodes.go index c79672c94e994..846db51c2a216 100644 --- a/central/graphql/resolvers/loaders/nodes.go +++ b/central/graphql/resolvers/loaders/nodes.go @@ -16,12 +16,6 @@ import ( var nodeLoaderType = reflect.TypeOf(storage.Node{}) -func init() { - RegisterTypeFactory(nodeLoaderType, func() interface{} { - return NewNodeLoader(nodeDatastore.Singleton()) - }) -} - // NewNodeLoader creates a new loader for node data. func NewNodeLoader(ds nodeDatastore.DataStore) NodeLoader { return &nodeLoaderImpl{ diff --git a/central/graphql/resolvers/loaders/policies.go b/central/graphql/resolvers/loaders/policies.go index 28bdfa0ddd1ae..e434050c187ee 100644 --- a/central/graphql/resolvers/loaders/policies.go +++ b/central/graphql/resolvers/loaders/policies.go @@ -15,12 +15,6 @@ import ( var policyLoaderType = reflect.TypeOf(storage.Policy{}) -func init() { - RegisterTypeFactory(reflect.TypeOf(storage.Policy{}), func() interface{} { - return NewPolicyLoader(policyDataStore.Singleton()) - }) -} - // NewPolicyLoader creates a new loader for policy data. func NewPolicyLoader(ds policyDataStore.DataStore) PolicyLoader { return &policyLoaderImpl{ diff --git a/central/graphql/resolvers/namespaces.go b/central/graphql/resolvers/namespaces.go index cbde5703ff071..fc53162932915 100644 --- a/central/graphql/resolvers/namespaces.go +++ b/central/graphql/resolvers/namespaces.go @@ -21,7 +21,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerNamespacesSchema() { schema := getBuilder() utils.Must( // NOTE: This list is and should remain alphabetically ordered diff --git a/central/graphql/resolvers/node_components.go b/central/graphql/resolvers/node_components.go index f54f8404851ab..f836309e2154c 100644 --- a/central/graphql/resolvers/node_components.go +++ b/central/graphql/resolvers/node_components.go @@ -27,7 +27,7 @@ var ( nodeVulnerabilityPredicateFactory = predicate.NewFactory("vulnerability", &storage.NodeVulnerability{}) ) -func init() { +func registerNodeComponentsSchema() { schema := getBuilder() utils.Must( // Resolvers for fields in storage.NodeComponent are autogenerated and located in generated.go diff --git a/central/graphql/resolvers/node_components_v1.go b/central/graphql/resolvers/node_components_v1.go index 28e78b724b2a9..1c3f83dc7bd9a 100644 --- a/central/graphql/resolvers/node_components_v1.go +++ b/central/graphql/resolvers/node_components_v1.go @@ -17,7 +17,7 @@ import ( // Resolvers on Embedded Scan Object. ///////////////////////////////////// -func init() { +func registerNodeComponentsV1Schema() { schema := getBuilder() utils.Must( schema.AddType("EmbeddedNodeScanComponent", []string{ diff --git a/central/graphql/resolvers/node_cve_core.go b/central/graphql/resolvers/node_cve_core.go index ca8092891113f..493dbbef7292e 100644 --- a/central/graphql/resolvers/node_cve_core.go +++ b/central/graphql/resolvers/node_cve_core.go @@ -22,7 +22,7 @@ const ( maxNodes = 1000 ) -func init() { +func registerNodeCVECoreSchema() { schema := getBuilder() utils.Must( // NOTE: This list is and should remain alphabetically ordered diff --git a/central/graphql/resolvers/node_scan.go b/central/graphql/resolvers/node_scan.go index 0f95e36b84d28..c203e8ead190f 100644 --- a/central/graphql/resolvers/node_scan.go +++ b/central/graphql/resolvers/node_scan.go @@ -20,7 +20,7 @@ var ( nodeComponentPredicateFactory = predicate.NewFactory("component", &storage.EmbeddedNodeScanComponent{}) ) -func init() { +func registerNodeScanSchema() { schema := getBuilder() utils.Must( schema.AddExtraResolvers("NodeScan", []string{ diff --git a/central/graphql/resolvers/node_vulnerabilities.go b/central/graphql/resolvers/node_vulnerabilities.go index 0e4ef66d3b0c9..8c273d1312219 100644 --- a/central/graphql/resolvers/node_vulnerabilities.go +++ b/central/graphql/resolvers/node_vulnerabilities.go @@ -19,7 +19,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerNodeVulnerabilitiesSchema() { schema := getBuilder() utils.Must( // NOTE: This list is and should remain alphabetically ordered diff --git a/central/graphql/resolvers/nodes.go b/central/graphql/resolvers/nodes.go index 40ad434fd069b..274ed24178023 100644 --- a/central/graphql/resolvers/nodes.go +++ b/central/graphql/resolvers/nodes.go @@ -19,7 +19,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerNodesSchema() { schema := getBuilder() utils.Must( schema.AddQuery("node(id:ID!): Node"), diff --git a/central/graphql/resolvers/notifiers.go b/central/graphql/resolvers/notifiers.go index 85c7d68fb793d..370efed751f44 100644 --- a/central/graphql/resolvers/notifiers.go +++ b/central/graphql/resolvers/notifiers.go @@ -11,7 +11,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerNotifiersSchema() { schema := getBuilder() utils.Must( schema.AddQuery("notifiers: [Notifier!]!"), diff --git a/central/graphql/resolvers/permission_sets.go b/central/graphql/resolvers/permission_sets.go index 481e3edd4f6be..d592653071b0c 100644 --- a/central/graphql/resolvers/permission_sets.go +++ b/central/graphql/resolvers/permission_sets.go @@ -12,7 +12,7 @@ import ( "google.golang.org/grpc/status" ) -func init() { +func registerPermissionSetsSchema() { schema := getBuilder() utils.Must( schema.AddQuery("permissionSets: [PermissionSet!]!"), diff --git a/central/graphql/resolvers/platform_cve_core.go b/central/graphql/resolvers/platform_cve_core.go index 1061743031268..957be7ccb4a01 100644 --- a/central/graphql/resolvers/platform_cve_core.go +++ b/central/graphql/resolvers/platform_cve_core.go @@ -20,7 +20,7 @@ const ( maxClusters = 1000 ) -func init() { +func registerPlatformCVECoreSchema() { schema := getBuilder() utils.Must( // NOTE: This list is and should remain alphabetically ordered diff --git a/central/graphql/resolvers/platform_cve_count_by_fixability.go b/central/graphql/resolvers/platform_cve_count_by_fixability.go index 4ec0a2f016440..b1c568b02733b 100644 --- a/central/graphql/resolvers/platform_cve_count_by_fixability.go +++ b/central/graphql/resolvers/platform_cve_count_by_fixability.go @@ -8,7 +8,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerPlatformCVECountByFixabilitySchema() { schema := getBuilder() utils.Must( schema.AddType("PlatformCVECountByFixability", []string{ diff --git a/central/graphql/resolvers/platform_cve_count_by_type.go b/central/graphql/resolvers/platform_cve_count_by_type.go index 9380ae8fe54eb..45e6df3e0c208 100644 --- a/central/graphql/resolvers/platform_cve_count_by_type.go +++ b/central/graphql/resolvers/platform_cve_count_by_type.go @@ -7,7 +7,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerPlatformCVECountByTypeSchema() { schema := getBuilder() utils.Must( schema.AddType("PlatformCVECountByType", []string{ diff --git a/central/graphql/resolvers/plotted_image_vulnerabilities.go b/central/graphql/resolvers/plotted_image_vulnerabilities.go index 8e0955dea760f..23033dd9bf4ed 100644 --- a/central/graphql/resolvers/plotted_image_vulnerabilities.go +++ b/central/graphql/resolvers/plotted_image_vulnerabilities.go @@ -9,7 +9,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerPlottedImageVulnerabilitiesSchema() { schema := getBuilder() utils.Must( schema.AddType("PlottedImageVulnerabilities", []string{ diff --git a/central/graphql/resolvers/plotted_node_vulnerabilities.go b/central/graphql/resolvers/plotted_node_vulnerabilities.go index 32285c2c97aa9..61944da18827e 100644 --- a/central/graphql/resolvers/plotted_node_vulnerabilities.go +++ b/central/graphql/resolvers/plotted_node_vulnerabilities.go @@ -10,7 +10,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerPlottedNodeVulnerabilitiesSchema() { schema := getBuilder() utils.Must( schema.AddType("PlottedNodeVulnerabilities", []string{ diff --git a/central/graphql/resolvers/pods.go b/central/graphql/resolvers/pods.go index e469058634dfd..c14a4775110c7 100644 --- a/central/graphql/resolvers/pods.go +++ b/central/graphql/resolvers/pods.go @@ -15,7 +15,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerPodsSchema() { const resolverName = "Pod" schema := getBuilder() utils.Must( diff --git a/central/graphql/resolvers/policies.go b/central/graphql/resolvers/policies.go index 1bea72a663a26..72637787fccbe 100644 --- a/central/graphql/resolvers/policies.go +++ b/central/graphql/resolvers/policies.go @@ -17,7 +17,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerPoliciesSchema() { schema := getBuilder() utils.Must( diff --git a/central/graphql/resolvers/policy_counter.go b/central/graphql/resolvers/policy_counter.go index a53d26ffb24f0..b9b5e50620a5b 100644 --- a/central/graphql/resolvers/policy_counter.go +++ b/central/graphql/resolvers/policy_counter.go @@ -9,7 +9,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerPolicyCounterSchema() { schema := getBuilder() utils.Must( schema.AddType("PolicyCounter", []string{ diff --git a/central/graphql/resolvers/resource_count_by_severity.go b/central/graphql/resolvers/resource_count_by_severity.go index 8f5471650eda1..70262598d3b33 100644 --- a/central/graphql/resolvers/resource_count_by_severity.go +++ b/central/graphql/resolvers/resource_count_by_severity.go @@ -7,7 +7,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerResourceCountBySeveritySchema() { schema := getBuilder() utils.Must( schema.AddType("ResourceCountByCVESeverity", []string{ diff --git a/central/graphql/resolvers/roles.go b/central/graphql/resolvers/roles.go index f6b63e795f2fa..ba6b087570929 100644 --- a/central/graphql/resolvers/roles.go +++ b/central/graphql/resolvers/roles.go @@ -12,7 +12,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerRolesSchema() { schema := getBuilder() utils.Must( schema.AddQuery("roles: [Role!]!"), diff --git a/central/graphql/resolvers/schema.go b/central/graphql/resolvers/schema.go index ef67dbaf13de6..5af31593d882a 100644 --- a/central/graphql/resolvers/schema.go +++ b/central/graphql/resolvers/schema.go @@ -14,6 +14,7 @@ func getBuilder() generator.SchemaBuilder { builderOnce.Do(func() { builderInstance = generator.NewSchemaBuilder() registerGeneratedTypes(builderInstance) + Init() }) return builderInstance } diff --git a/central/graphql/resolvers/search.go b/central/graphql/resolvers/search.go index 21e36a2d2eff5..5237c5ae28f70 100644 --- a/central/graphql/resolvers/search.go +++ b/central/graphql/resolvers/search.go @@ -16,7 +16,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerSearchSchema() { schema := getBuilder() utils.Must( schema.AddQuery("searchOptions(categories: [SearchCategory!]): [String!]!"), diff --git a/central/graphql/resolvers/secrets.go b/central/graphql/resolvers/secrets.go index 2cf74bbf0336c..0eb0ac0fd16d6 100644 --- a/central/graphql/resolvers/secrets.go +++ b/central/graphql/resolvers/secrets.go @@ -15,7 +15,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerSecretsSchema() { schema := getBuilder() utils.Must( schema.AddQuery("secret(id:ID!): Secret"), diff --git a/central/graphql/resolvers/service_accounts.go b/central/graphql/resolvers/service_accounts.go index efac3790d1392..baab1f4013349 100644 --- a/central/graphql/resolvers/service_accounts.go +++ b/central/graphql/resolvers/service_accounts.go @@ -17,7 +17,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerServiceAccountsSchema() { schema := getBuilder() utils.Must( schema.AddQuery("serviceAccount(id: ID!): ServiceAccount"), diff --git a/central/graphql/resolvers/subjects.go b/central/graphql/resolvers/subjects.go index d73106e5c0c73..a7c24d7b45756 100644 --- a/central/graphql/resolvers/subjects.go +++ b/central/graphql/resolvers/subjects.go @@ -17,7 +17,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerSubjectsSchema() { schema := getBuilder() utils.Must( schema.AddQuery("subject(id: ID): Subject"), diff --git a/central/graphql/resolvers/tokens.go b/central/graphql/resolvers/tokens.go index b06959baa6da3..1097be2e70d82 100644 --- a/central/graphql/resolvers/tokens.go +++ b/central/graphql/resolvers/tokens.go @@ -11,7 +11,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerTokensSchema() { schema := getBuilder() utils.Must( schema.AddQuery("tokens(revoked:Boolean): [TokenMetadata!]!"), diff --git a/central/graphql/resolvers/violations.go b/central/graphql/resolvers/violations.go index 17dc271479cd5..0bc380fa8c804 100644 --- a/central/graphql/resolvers/violations.go +++ b/central/graphql/resolvers/violations.go @@ -15,7 +15,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerViolationsSchema() { schema := getBuilder() utils.Must( schema.AddQuery("violations(query: String, pagination: Pagination): [Alert!]!"), diff --git a/central/graphql/resolvers/vul_mgmt_widgets.go b/central/graphql/resolvers/vul_mgmt_widgets.go index 1d2d20c310aee..6c51a7978bf60 100644 --- a/central/graphql/resolvers/vul_mgmt_widgets.go +++ b/central/graphql/resolvers/vul_mgmt_widgets.go @@ -15,7 +15,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerVulMgmtWidgetsSchema() { schema := getBuilder() utils.Must( schema.AddType("DeploymentsWithMostSevereViolations", []string{ diff --git a/central/graphql/resolvers/vulnerabilities.go b/central/graphql/resolvers/vulnerabilities.go index d3bf28833a6a2..09407c831141d 100644 --- a/central/graphql/resolvers/vulnerabilities.go +++ b/central/graphql/resolvers/vulnerabilities.go @@ -9,7 +9,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerVulnerabilitiesSchema() { schema := getBuilder() utils.Must( schema.AddType("EmbeddedVulnerability", []string{ diff --git a/central/graphql/resolvers/vulnerability_counter.go b/central/graphql/resolvers/vulnerability_counter.go index 93ea1b02d5971..e30ace2c8e406 100644 --- a/central/graphql/resolvers/vulnerability_counter.go +++ b/central/graphql/resolvers/vulnerability_counter.go @@ -8,7 +8,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerVulnerabilityCounterSchema() { schema := getBuilder() utils.Must( schema.AddType("VulnerabilityCounter", []string{ diff --git a/central/graphql/resolvers/vulnerability_requests.go b/central/graphql/resolvers/vulnerability_requests.go index 82d2fddb6b0ae..031546f9f91a9 100644 --- a/central/graphql/resolvers/vulnerability_requests.go +++ b/central/graphql/resolvers/vulnerability_requests.go @@ -24,7 +24,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerVulnerabilityRequestsSchema() { schema := getBuilder() utils.Must( schema.AddInput("VulnReqExpiry", []string{ diff --git a/central/graphql/resolvers/vulnerability_vectors.go b/central/graphql/resolvers/vulnerability_vectors.go index da10df24d38ac..70cac7f8b765d 100644 --- a/central/graphql/resolvers/vulnerability_vectors.go +++ b/central/graphql/resolvers/vulnerability_vectors.go @@ -4,7 +4,7 @@ import ( "github.com/stackrox/rox/pkg/utils" ) -func init() { +func registerVulnerabilityVectorsSchema() { schema := getBuilder() utils.Must(schema.AddUnionType("EmbeddedVulnerabilityVectors", []string{ diff --git a/central/main.go b/central/main.go index 37804b291b4c3..90f93cc8b75e0 100644 --- a/central/main.go +++ b/central/main.go @@ -218,13 +218,13 @@ import ( "github.com/stackrox/rox/pkg/grpc/routes" "github.com/stackrox/rox/pkg/httputil/proxy" "github.com/stackrox/rox/pkg/logging" - "github.com/stackrox/rox/pkg/memlimit" pkgMetrics "github.com/stackrox/rox/pkg/metrics" "github.com/stackrox/rox/pkg/migrations" "github.com/stackrox/rox/pkg/osutils" "github.com/stackrox/rox/pkg/postgres/pgadmin" "github.com/stackrox/rox/pkg/postgres/pgconfig" "github.com/stackrox/rox/pkg/premain" + "github.com/stackrox/rox/pkg/profiling" "github.com/stackrox/rox/pkg/sac" "github.com/stackrox/rox/pkg/sac/observe" "github.com/stackrox/rox/pkg/sac/resources" @@ -233,6 +233,7 @@ import ( pkgVersion "github.com/stackrox/rox/pkg/version" // BusyBox-style consolidation - import app packages + app "github.com/stackrox/rox/central/app" complianceapp "github.com/stackrox/rox/compliance/cmd/compliance/app" roxagentapp "github.com/stackrox/rox/compliance/virtualmachines/roxagent/app" configcontrollerapp "github.com/stackrox/rox/config-controller/app" @@ -262,14 +263,6 @@ const ( proxyConfigFile = "config.yaml" ) -func init() { - if !proxy.UseWithDefaultTransport() { - log.Warn("Failed to use proxy transport with default HTTP transport. Some proxy features may not work.") - } - - memlimit.SetMemoryLimit() -} - func runSafeMode() { log.Info("Started Central up in safe mode. Sleeping forever...") @@ -281,6 +274,7 @@ func runSafeMode() { log.Info("Central terminated") } +// centralRun is the main central application logic. func centralRun() { defer utils.IgnoreError(log.InnerLogger.Sync) @@ -1084,8 +1078,12 @@ func main() { // BusyBox-style dispatcher: check how we were called binaryName := filepath.Base(os.Args[0]) + // Set component label for profiling + profiling.SetComponentLabel(binaryName) + switch binaryName { case "central": + app.Run() centralRun() case "migrator": migratorapp.Run() From c1d2c6a1a7f8a3069a8e382719d6f2b036d06953 Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Tue, 14 Apr 2026 17:16:24 +0200 Subject: [PATCH 2/4] fix: simplify central/app to only GraphQL loaders (remove other PRs' changes) - Remove metrics.Init() (belongs in metrics PR) - Remove compliance, notifiers, backup Init() calls (belong in other PRs) - Remove initComponentLogic (belongs in remaining PR) - Remove central/app/init.go (belongs in remaining PR) This PR only introduces GraphQL loaders infrastructure. --- central/app/app.go | 13 --------- central/app/init.go | 65 --------------------------------------------- 2 files changed, 78 deletions(-) delete mode 100644 central/app/init.go diff --git a/central/app/app.go b/central/app/app.go index b777606d2b397..11c1e18b25169 100644 --- a/central/app/app.go +++ b/central/app/app.go @@ -1,13 +1,7 @@ package app import ( - centralChecks "github.com/stackrox/rox/central/compliance/checks" - "github.com/stackrox/rox/central/compliance/standards/metadata" - backupPlugins "github.com/stackrox/rox/central/externalbackups/plugins/all" "github.com/stackrox/rox/central/graphql/resolvers/loaders" - "github.com/stackrox/rox/central/metrics" - "github.com/stackrox/rox/central/notifiers" - "github.com/stackrox/rox/pkg/compliance/checks" "github.com/stackrox/rox/pkg/memlimit" "github.com/stackrox/rox/pkg/premain" ) @@ -19,12 +13,5 @@ func Run() { memlimit.SetMemoryLimit() premain.StartMain() - metrics.Init() loaders.Init() - checks.Init() - centralChecks.Init() - notifiers.Init() - metadata.Init() - backupPlugins.Init() - initComponentLogic() } diff --git a/central/app/init.go b/central/app/init.go deleted file mode 100644 index 8aa01f63e1ed3..0000000000000 --- a/central/app/init.go +++ /dev/null @@ -1,65 +0,0 @@ -package app - -import ( - "github.com/stackrox/rox/central/alert/mappings" - "github.com/stackrox/rox/central/auth/internaltokens/service" - csvhandler "github.com/stackrox/rox/central/cve/common/csv" - debugservice "github.com/stackrox/rox/central/debug/service" - detectionservice "github.com/stackrox/rox/central/detection/service" - "github.com/stackrox/rox/central/globaldb/v2backuprestore/formats/postgresv1" - scannerhandler "github.com/stackrox/rox/central/scannerdefinitions/handler" - "github.com/stackrox/rox/central/search/options" - "github.com/stackrox/rox/pkg/administration/events/stream" - "github.com/stackrox/rox/pkg/booleanpolicy/violationmessages/printer" - "github.com/stackrox/rox/pkg/gjson" - "github.com/stackrox/rox/pkg/httputil/proxy" - "github.com/stackrox/rox/pkg/logging" - pkgsearch "github.com/stackrox/rox/pkg/search" - "github.com/stackrox/rox/pkg/search/enumregistry" - "github.com/stackrox/rox/pkg/signatures" - "github.com/stackrox/rox/pkg/tlsprofile" -) - -var log = logging.LoggerForModule() - -// initComponentLogic initializes all central-specific components that were -// previously using init() functions. -func initComponentLogic() { - // Initialize metrics - service.RegisterMetrics() - stream.Init() - - // Initialize search and alert options - options.InitCategoryToOptionsSet() - mappings.InitOptionsMap() - enumregistry.Init() - pkgsearch.Init() - - // Initialize CSV handlers - csvhandler.InitOptionsMap() - - // Initialize service configurations - debugservice.InitMainClusterConfig() - detectionservice.InitWorkloadScheme() - scannerhandler.InitScannerConfig() - - // Initialize policy violation printers - printer.Init() - - // Initialize GJSON custom modifiers - gjson.Init() - - // Initialize signature fetcher - signatures.Init() - - // Initialize TLS profile - tlsprofile.Init() - - // Register backup formats - postgresv1.RegisterFormat() - - // Initialize proxy configuration - if !proxy.UseWithDefaultTransport() { - log.Warn("Failed to use proxy transport with default HTTP transport. Some proxy features may not work.") - } -} From 6054d2f9f37a26c715474459f3ab5cdc4a3d9979 Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Tue, 14 Apr 2026 17:31:20 +0200 Subject: [PATCH 3/4] fix: remove profiling.SetComponentLabel (not in this PR scope) The profiling changes belong in a different PR. This PR only adds GraphQL loaders. --- central/main.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/central/main.go b/central/main.go index 90f93cc8b75e0..1019340dae379 100644 --- a/central/main.go +++ b/central/main.go @@ -224,7 +224,6 @@ import ( "github.com/stackrox/rox/pkg/postgres/pgadmin" "github.com/stackrox/rox/pkg/postgres/pgconfig" "github.com/stackrox/rox/pkg/premain" - "github.com/stackrox/rox/pkg/profiling" "github.com/stackrox/rox/pkg/sac" "github.com/stackrox/rox/pkg/sac/observe" "github.com/stackrox/rox/pkg/sac/resources" @@ -1078,9 +1077,6 @@ func main() { // BusyBox-style dispatcher: check how we were called binaryName := filepath.Base(os.Args[0]) - // Set component label for profiling - profiling.SetComponentLabel(binaryName) - switch binaryName { case "central": app.Run() From 99c6ae0881ef7c3ee67c5dfb706a28896328ccb1 Mon Sep 17 00:00:00 2001 From: Tomasz Janiszewski Date: Wed, 15 Apr 2026 09:38:44 +0200 Subject: [PATCH 4/4] fix: resolve GraphQL schema initialization deadlock Move Init() call from getBuilder() to package init() to prevent deadlock. Problem: getBuilder() called Init() inside once.Do(), but Init() calls registerXXXSchema() functions which call getBuilder(), creating a circular dependency that deadlocked on sync.Once. Solution: Add package init() that calls Init(), and remove Init() call from getBuilder(). Also change Schema() to call getBuilder().Render() instead of builderInstance.Render() to ensure builder is initialized. This matches the original master pattern where each schema file had init() that called getBuilder(). Co-Authored-By: Claude Sonnet 4.5 --- central/graphql/resolvers/schema.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/central/graphql/resolvers/schema.go b/central/graphql/resolvers/schema.go index 5af31593d882a..c445db4583173 100644 --- a/central/graphql/resolvers/schema.go +++ b/central/graphql/resolvers/schema.go @@ -10,18 +10,21 @@ var ( builderInstance generator.SchemaBuilder ) +func init() { + Init() +} + func getBuilder() generator.SchemaBuilder { builderOnce.Do(func() { builderInstance = generator.NewSchemaBuilder() registerGeneratedTypes(builderInstance) - Init() }) return builderInstance } // Schema outputs the generated schema from the package level state func Schema() string { - s, err := builderInstance.Render() + s, err := getBuilder().Render() if err == nil { return s }