diff --git a/api/schema.graphqls b/api/schema.graphqls index 9092b4f..268a579 100644 --- a/api/schema.graphqls +++ b/api/schema.graphqls @@ -158,7 +158,7 @@ type StatsSeries { max: [NullableFloat!]! } -type JobStatsWithScope { +type NamedStatsWithScope { name: String! scope: MetricScope! stats: [ScopedStats!]! @@ -171,8 +171,21 @@ type ScopedStats { } type JobStats { - name: String! - stats: MetricStatistics! + id: Int! + jobId: String! + startTime: Int! + duration: Int! + cluster: String! + subCluster: String! + numNodes: Int! + numHWThreads: Int + numAccelerators: Int + stats: [NamedStats!]! +} + +type NamedStats { + name: String! + data: MetricStatistics! } type Unit { @@ -259,12 +272,13 @@ type Query { job(id: ID!): Job jobMetrics(id: ID!, metrics: [String!], scopes: [MetricScope!], resolution: Int): [JobMetricWithName!]! - jobStats(id: ID!, metrics: [String!]): [JobStats!]! - scopedJobStats(id: ID!, metrics: [String!], scopes: [MetricScope!]): [JobStatsWithScope!]! - jobsFootprints(filter: [JobFilter!], metrics: [String!]!): Footprints + jobStats(id: ID!, metrics: [String!]): [NamedStats!]! + scopedJobStats(id: ID!, metrics: [String!], scopes: [MetricScope!]): [NamedStatsWithScope!]! jobs(filter: [JobFilter!], page: PageRequest, order: OrderByInput): JobResultList! jobsStatistics(filter: [JobFilter!], metrics: [String!], page: PageRequest, sortBy: SortByAggregate, groupBy: Aggregate, numDurationBins: String, numMetricBins: Int): [JobsStatistics!]! + jobsMetricStats(filter: [JobFilter!], metrics: [String!]): [JobStats!]! + jobsFootprints(filter: [JobFilter!], metrics: [String!]!): Footprints rooflineHeatmap(filter: [JobFilter!]!, rows: Int!, cols: Int!, minX: Float!, minY: Float!, maxX: Float!, maxY: Float!): [[Float!]!]! @@ -287,6 +301,7 @@ type TimeRangeOutput { range: String, from: Time!, to: Time! } input JobFilter { tags: [ID!] + dbId: [ID!] jobId: StringInput arrayJobId: Int user: StringInput diff --git a/internal/graph/generated/generated.go b/internal/graph/generated/generated.go index 5dbdfd9..e73bcf1 100644 --- a/internal/graph/generated/generated.go +++ b/internal/graph/generated/generated.go @@ -171,14 +171,16 @@ type ComplexityRoot struct { } JobStats struct { - Name func(childComplexity int) int - Stats func(childComplexity int) int - } - - JobStatsWithScope struct { - Name func(childComplexity int) int - Scope func(childComplexity int) int - Stats func(childComplexity int) int + Cluster func(childComplexity int) int + Duration func(childComplexity int) int + ID func(childComplexity int) int + JobID func(childComplexity int) int + NumAccelerators func(childComplexity int) int + NumHWThreads func(childComplexity int) int + NumNodes func(childComplexity int) int + StartTime func(childComplexity int) int + Stats func(childComplexity int) int + SubCluster func(childComplexity int) int } JobsStatistics struct { @@ -255,6 +257,17 @@ type ComplexityRoot struct { UpdateConfiguration func(childComplexity int, name string, value string) int } + NamedStats struct { + Data func(childComplexity int) int + Name func(childComplexity int) int + } + + NamedStatsWithScope struct { + Name func(childComplexity int) int + Scope func(childComplexity int) int + Stats func(childComplexity int) int + } + NodeMetrics struct { Host func(childComplexity int) int Metrics func(childComplexity int) int @@ -279,6 +292,7 @@ type ComplexityRoot struct { JobStats func(childComplexity int, id string, metrics []string) int Jobs func(childComplexity int, filter []*model.JobFilter, page *model.PageRequest, order *model.OrderByInput) int JobsFootprints func(childComplexity int, filter []*model.JobFilter, metrics []string) int + JobsMetricStats func(childComplexity int, filter []*model.JobFilter, metrics []string) int JobsStatistics func(childComplexity int, filter []*model.JobFilter, metrics []string, page *model.PageRequest, sortBy *model.SortByAggregate, groupBy *model.Aggregate, numDurationBins *string, numMetricBins *int) int NodeMetrics func(childComplexity int, cluster string, nodes []string, scopes []schema.MetricScope, metrics []string, from time.Time, to time.Time) int NodeMetricsList func(childComplexity int, cluster string, subCluster string, nodeFilter string, scopes []schema.MetricScope, metrics []string, from time.Time, to time.Time, page *model.PageRequest, resolution *int) int @@ -411,11 +425,12 @@ type QueryResolver interface { AllocatedNodes(ctx context.Context, cluster string) ([]*model.Count, error) Job(ctx context.Context, id string) (*schema.Job, error) JobMetrics(ctx context.Context, id string, metrics []string, scopes []schema.MetricScope, resolution *int) ([]*model.JobMetricWithName, error) - JobStats(ctx context.Context, id string, metrics []string) ([]*model.JobStats, error) - ScopedJobStats(ctx context.Context, id string, metrics []string, scopes []schema.MetricScope) ([]*model.JobStatsWithScope, error) - JobsFootprints(ctx context.Context, filter []*model.JobFilter, metrics []string) (*model.Footprints, error) + JobStats(ctx context.Context, id string, metrics []string) ([]*model.NamedStats, error) + ScopedJobStats(ctx context.Context, id string, metrics []string, scopes []schema.MetricScope) ([]*model.NamedStatsWithScope, error) Jobs(ctx context.Context, filter []*model.JobFilter, page *model.PageRequest, order *model.OrderByInput) (*model.JobResultList, error) JobsStatistics(ctx context.Context, filter []*model.JobFilter, metrics []string, page *model.PageRequest, sortBy *model.SortByAggregate, groupBy *model.Aggregate, numDurationBins *string, numMetricBins *int) ([]*model.JobsStatistics, error) + JobsMetricStats(ctx context.Context, filter []*model.JobFilter, metrics []string) ([]*model.JobStats, error) + JobsFootprints(ctx context.Context, filter []*model.JobFilter, metrics []string) (*model.Footprints, error) RooflineHeatmap(ctx context.Context, filter []*model.JobFilter, rows int, cols int, minX float64, minY float64, maxX float64, maxY float64) ([][]float64, error) NodeMetrics(ctx context.Context, cluster string, nodes []string, scopes []schema.MetricScope, metrics []string, from time.Time, to time.Time) ([]*model.NodeMetrics, error) NodeMetricsList(ctx context.Context, cluster string, subCluster string, nodeFilter string, scopes []schema.MetricScope, metrics []string, from time.Time, to time.Time, page *model.PageRequest, resolution *int) (*model.NodesResultList, error) @@ -933,12 +948,61 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.JobResultList.Offset(childComplexity), true - case "JobStats.name": - if e.complexity.JobStats.Name == nil { + case "JobStats.cluster": + if e.complexity.JobStats.Cluster == nil { break } - return e.complexity.JobStats.Name(childComplexity), true + return e.complexity.JobStats.Cluster(childComplexity), true + + case "JobStats.duration": + if e.complexity.JobStats.Duration == nil { + break + } + + return e.complexity.JobStats.Duration(childComplexity), true + + case "JobStats.id": + if e.complexity.JobStats.ID == nil { + break + } + + return e.complexity.JobStats.ID(childComplexity), true + + case "JobStats.jobId": + if e.complexity.JobStats.JobID == nil { + break + } + + return e.complexity.JobStats.JobID(childComplexity), true + + case "JobStats.numAccelerators": + if e.complexity.JobStats.NumAccelerators == nil { + break + } + + return e.complexity.JobStats.NumAccelerators(childComplexity), true + + case "JobStats.numHWThreads": + if e.complexity.JobStats.NumHWThreads == nil { + break + } + + return e.complexity.JobStats.NumHWThreads(childComplexity), true + + case "JobStats.numNodes": + if e.complexity.JobStats.NumNodes == nil { + break + } + + return e.complexity.JobStats.NumNodes(childComplexity), true + + case "JobStats.startTime": + if e.complexity.JobStats.StartTime == nil { + break + } + + return e.complexity.JobStats.StartTime(childComplexity), true case "JobStats.stats": if e.complexity.JobStats.Stats == nil { @@ -947,26 +1011,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.JobStats.Stats(childComplexity), true - case "JobStatsWithScope.name": - if e.complexity.JobStatsWithScope.Name == nil { + case "JobStats.subCluster": + if e.complexity.JobStats.SubCluster == nil { break } - return e.complexity.JobStatsWithScope.Name(childComplexity), true - - case "JobStatsWithScope.scope": - if e.complexity.JobStatsWithScope.Scope == nil { - break - } - - return e.complexity.JobStatsWithScope.Scope(childComplexity), true - - case "JobStatsWithScope.stats": - if e.complexity.JobStatsWithScope.Stats == nil { - break - } - - return e.complexity.JobStatsWithScope.Stats(childComplexity), true + return e.complexity.JobStats.SubCluster(childComplexity), true case "JobsStatistics.histDuration": if e.complexity.JobsStatistics.HistDuration == nil { @@ -1348,6 +1398,41 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.UpdateConfiguration(childComplexity, args["name"].(string), args["value"].(string)), true + case "NamedStats.data": + if e.complexity.NamedStats.Data == nil { + break + } + + return e.complexity.NamedStats.Data(childComplexity), true + + case "NamedStats.name": + if e.complexity.NamedStats.Name == nil { + break + } + + return e.complexity.NamedStats.Name(childComplexity), true + + case "NamedStatsWithScope.name": + if e.complexity.NamedStatsWithScope.Name == nil { + break + } + + return e.complexity.NamedStatsWithScope.Name(childComplexity), true + + case "NamedStatsWithScope.scope": + if e.complexity.NamedStatsWithScope.Scope == nil { + break + } + + return e.complexity.NamedStatsWithScope.Scope(childComplexity), true + + case "NamedStatsWithScope.stats": + if e.complexity.NamedStatsWithScope.Stats == nil { + break + } + + return e.complexity.NamedStatsWithScope.Stats(childComplexity), true + case "NodeMetrics.host": if e.complexity.NodeMetrics.Host == nil { break @@ -1497,6 +1582,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.JobsFootprints(childComplexity, args["filter"].([]*model.JobFilter), args["metrics"].([]string)), true + case "Query.jobsMetricStats": + if e.complexity.Query.JobsMetricStats == nil { + break + } + + args, err := ec.field_Query_jobsMetricStats_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.JobsMetricStats(childComplexity, args["filter"].([]*model.JobFilter), args["metrics"].([]string)), true + case "Query.jobsStatistics": if e.complexity.Query.JobsStatistics == nil { break @@ -2234,7 +2331,7 @@ type StatsSeries { max: [NullableFloat!]! } -type JobStatsWithScope { +type NamedStatsWithScope { name: String! scope: MetricScope! stats: [ScopedStats!]! @@ -2247,8 +2344,21 @@ type ScopedStats { } type JobStats { - name: String! - stats: MetricStatistics! + id: Int! + jobId: String! + startTime: Int! + duration: Int! + cluster: String! + subCluster: String! + numNodes: Int! + numHWThreads: Int + numAccelerators: Int + stats: [NamedStats!]! +} + +type NamedStats { + name: String! + data: MetricStatistics! } type Unit { @@ -2335,12 +2445,13 @@ type Query { job(id: ID!): Job jobMetrics(id: ID!, metrics: [String!], scopes: [MetricScope!], resolution: Int): [JobMetricWithName!]! - jobStats(id: ID!, metrics: [String!]): [JobStats!]! - scopedJobStats(id: ID!, metrics: [String!], scopes: [MetricScope!]): [JobStatsWithScope!]! - jobsFootprints(filter: [JobFilter!], metrics: [String!]!): Footprints + jobStats(id: ID!, metrics: [String!]): [NamedStats!]! + scopedJobStats(id: ID!, metrics: [String!], scopes: [MetricScope!]): [NamedStatsWithScope!]! jobs(filter: [JobFilter!], page: PageRequest, order: OrderByInput): JobResultList! jobsStatistics(filter: [JobFilter!], metrics: [String!], page: PageRequest, sortBy: SortByAggregate, groupBy: Aggregate, numDurationBins: String, numMetricBins: Int): [JobsStatistics!]! + jobsMetricStats(filter: [JobFilter!], metrics: [String!]): [JobStats!]! + jobsFootprints(filter: [JobFilter!], metrics: [String!]!): Footprints rooflineHeatmap(filter: [JobFilter!]!, rows: Int!, cols: Int!, minX: Float!, minY: Float!, maxX: Float!, maxY: Float!): [[Float!]!]! @@ -2363,6 +2474,7 @@ type TimeRangeOutput { range: String, from: Time!, to: Time! } input JobFilter { tags: [ID!] + dbId: [ID!] jobId: StringInput arrayJobId: Int user: StringInput @@ -3045,6 +3157,57 @@ func (ec *executionContext) field_Query_jobsFootprints_argsMetrics( return zeroVal, nil } +func (ec *executionContext) field_Query_jobsMetricStats_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Query_jobsMetricStats_argsFilter(ctx, rawArgs) + if err != nil { + return nil, err + } + args["filter"] = arg0 + arg1, err := ec.field_Query_jobsMetricStats_argsMetrics(ctx, rawArgs) + if err != nil { + return nil, err + } + args["metrics"] = arg1 + return args, nil +} +func (ec *executionContext) field_Query_jobsMetricStats_argsFilter( + ctx context.Context, + rawArgs map[string]any, +) ([]*model.JobFilter, error) { + if _, ok := rawArgs["filter"]; !ok { + var zeroVal []*model.JobFilter + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + if tmp, ok := rawArgs["filter"]; ok { + return ec.unmarshalOJobFilter2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐJobFilterᚄ(ctx, tmp) + } + + var zeroVal []*model.JobFilter + return zeroVal, nil +} + +func (ec *executionContext) field_Query_jobsMetricStats_argsMetrics( + ctx context.Context, + rawArgs map[string]any, +) ([]string, error) { + if _, ok := rawArgs["metrics"]; !ok { + var zeroVal []string + return zeroVal, nil + } + + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("metrics")) + if tmp, ok := rawArgs["metrics"]; ok { + return ec.unmarshalOString2ᚕstringᚄ(ctx, tmp) + } + + var zeroVal []string + return zeroVal, nil +} + func (ec *executionContext) field_Query_jobsStatistics_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -7265,8 +7428,8 @@ func (ec *executionContext) fieldContext_JobResultList_hasNextPage(_ context.Con return fc, nil } -func (ec *executionContext) _JobStats_name(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_JobStats_name(ctx, field) +func (ec *executionContext) _JobStats_id(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_id(ctx, field) if err != nil { return graphql.Null } @@ -7279,7 +7442,51 @@ func (ec *executionContext) _JobStats_name(ctx context.Context, field graphql.Co }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { ctx = rctx // use context from middleware stack in children - return obj.Name, nil + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_JobStats_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _JobStats_jobId(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_jobId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.JobID, nil }) if err != nil { ec.Error(ctx, err) @@ -7296,7 +7503,7 @@ func (ec *executionContext) _JobStats_name(ctx context.Context, field graphql.Co return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_JobStats_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_JobStats_jobId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "JobStats", Field: field, @@ -7309,6 +7516,308 @@ func (ec *executionContext) fieldContext_JobStats_name(_ context.Context, field return fc, nil } +func (ec *executionContext) _JobStats_startTime(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_startTime(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.StartTime, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_JobStats_startTime(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _JobStats_duration(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_duration(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Duration, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_JobStats_duration(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _JobStats_cluster(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_cluster(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Cluster, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_JobStats_cluster(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _JobStats_subCluster(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_subCluster(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubCluster, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_JobStats_subCluster(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _JobStats_numNodes(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_numNodes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.NumNodes, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_JobStats_numNodes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _JobStats_numHWThreads(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_numHWThreads(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.NumHWThreads, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*int) + fc.Result = res + return ec.marshalOInt2ᚖint(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_JobStats_numHWThreads(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _JobStats_numAccelerators(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_numAccelerators(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.NumAccelerators, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*int) + fc.Result = res + return ec.marshalOInt2ᚖint(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_JobStats_numAccelerators(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _JobStats_stats(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { fc, err := ec.fieldContext_JobStats_stats(ctx, field) if err != nil { @@ -7335,9 +7844,9 @@ func (ec *executionContext) _JobStats_stats(ctx context.Context, field graphql.C } return graphql.Null } - res := resTmp.(*schema.MetricStatistics) + res := resTmp.([]*model.NamedStats) fc.Result = res - return ec.marshalNMetricStatistics2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋpkgᚋschemaᚐMetricStatistics(ctx, field.Selections, res) + return ec.marshalNNamedStats2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNamedStatsᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_JobStats_stats(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7348,154 +7857,12 @@ func (ec *executionContext) fieldContext_JobStats_stats(_ context.Context, field IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "avg": - return ec.fieldContext_MetricStatistics_avg(ctx, field) - case "min": - return ec.fieldContext_MetricStatistics_min(ctx, field) - case "max": - return ec.fieldContext_MetricStatistics_max(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type MetricStatistics", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _JobStatsWithScope_name(ctx context.Context, field graphql.CollectedField, obj *model.JobStatsWithScope) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_JobStatsWithScope_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_JobStatsWithScope_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "JobStatsWithScope", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _JobStatsWithScope_scope(ctx context.Context, field graphql.CollectedField, obj *model.JobStatsWithScope) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_JobStatsWithScope_scope(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { - ctx = rctx // use context from middleware stack in children - return obj.Scope, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(schema.MetricScope) - fc.Result = res - return ec.marshalNMetricScope2githubᚗcomᚋClusterCockpitᚋccᚑbackendᚋpkgᚋschemaᚐMetricScope(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_JobStatsWithScope_scope(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "JobStatsWithScope", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type MetricScope does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _JobStatsWithScope_stats(ctx context.Context, field graphql.CollectedField, obj *model.JobStatsWithScope) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_JobStatsWithScope_stats(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { - ctx = rctx // use context from middleware stack in children - return obj.Stats, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.([]*model.ScopedStats) - fc.Result = res - return ec.marshalNScopedStats2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐScopedStatsᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_JobStatsWithScope_stats(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "JobStatsWithScope", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "hostname": - return ec.fieldContext_ScopedStats_hostname(ctx, field) - case "id": - return ec.fieldContext_ScopedStats_id(ctx, field) + case "name": + return ec.fieldContext_NamedStats_name(ctx, field) case "data": - return ec.fieldContext_ScopedStats_data(ctx, field) + return ec.fieldContext_NamedStats_data(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type ScopedStats", field.Name) + return nil, fmt.Errorf("no field named %q was found under type NamedStats", field.Name) }, } return fc, nil @@ -9840,6 +10207,242 @@ func (ec *executionContext) fieldContext_Mutation_updateConfiguration(ctx contex return fc, nil } +func (ec *executionContext) _NamedStats_name(ctx context.Context, field graphql.CollectedField, obj *model.NamedStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_NamedStats_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_NamedStats_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "NamedStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _NamedStats_data(ctx context.Context, field graphql.CollectedField, obj *model.NamedStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_NamedStats_data(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Data, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*schema.MetricStatistics) + fc.Result = res + return ec.marshalNMetricStatistics2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋpkgᚋschemaᚐMetricStatistics(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_NamedStats_data(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "NamedStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "avg": + return ec.fieldContext_MetricStatistics_avg(ctx, field) + case "min": + return ec.fieldContext_MetricStatistics_min(ctx, field) + case "max": + return ec.fieldContext_MetricStatistics_max(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type MetricStatistics", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _NamedStatsWithScope_name(ctx context.Context, field graphql.CollectedField, obj *model.NamedStatsWithScope) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_NamedStatsWithScope_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_NamedStatsWithScope_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "NamedStatsWithScope", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _NamedStatsWithScope_scope(ctx context.Context, field graphql.CollectedField, obj *model.NamedStatsWithScope) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_NamedStatsWithScope_scope(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Scope, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(schema.MetricScope) + fc.Result = res + return ec.marshalNMetricScope2githubᚗcomᚋClusterCockpitᚋccᚑbackendᚋpkgᚋschemaᚐMetricScope(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_NamedStatsWithScope_scope(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "NamedStatsWithScope", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type MetricScope does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _NamedStatsWithScope_stats(ctx context.Context, field graphql.CollectedField, obj *model.NamedStatsWithScope) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_NamedStatsWithScope_stats(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Stats, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.ScopedStats) + fc.Result = res + return ec.marshalNScopedStats2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐScopedStatsᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_NamedStatsWithScope_stats(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "NamedStatsWithScope", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "hostname": + return ec.fieldContext_ScopedStats_hostname(ctx, field) + case "id": + return ec.fieldContext_ScopedStats_id(ctx, field) + case "data": + return ec.fieldContext_ScopedStats_data(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ScopedStats", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _NodeMetrics_host(ctx context.Context, field graphql.CollectedField, obj *model.NodeMetrics) (ret graphql.Marshaler) { fc, err := ec.fieldContext_NodeMetrics_host(ctx, field) if err != nil { @@ -10715,9 +11318,9 @@ func (ec *executionContext) _Query_jobStats(ctx context.Context, field graphql.C } return graphql.Null } - res := resTmp.([]*model.JobStats) + res := resTmp.([]*model.NamedStats) fc.Result = res - return ec.marshalNJobStats2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐJobStatsᚄ(ctx, field.Selections, res) + return ec.marshalNNamedStats2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNamedStatsᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_jobStats(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -10729,11 +11332,11 @@ func (ec *executionContext) fieldContext_Query_jobStats(ctx context.Context, fie Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "name": - return ec.fieldContext_JobStats_name(ctx, field) - case "stats": - return ec.fieldContext_JobStats_stats(ctx, field) + return ec.fieldContext_NamedStats_name(ctx, field) + case "data": + return ec.fieldContext_NamedStats_data(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type JobStats", field.Name) + return nil, fmt.Errorf("no field named %q was found under type NamedStats", field.Name) }, } defer func() { @@ -10776,9 +11379,9 @@ func (ec *executionContext) _Query_scopedJobStats(ctx context.Context, field gra } return graphql.Null } - res := resTmp.([]*model.JobStatsWithScope) + res := resTmp.([]*model.NamedStatsWithScope) fc.Result = res - return ec.marshalNJobStatsWithScope2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐJobStatsWithScopeᚄ(ctx, field.Selections, res) + return ec.marshalNNamedStatsWithScope2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNamedStatsWithScopeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_scopedJobStats(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -10790,13 +11393,13 @@ func (ec *executionContext) fieldContext_Query_scopedJobStats(ctx context.Contex Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "name": - return ec.fieldContext_JobStatsWithScope_name(ctx, field) + return ec.fieldContext_NamedStatsWithScope_name(ctx, field) case "scope": - return ec.fieldContext_JobStatsWithScope_scope(ctx, field) + return ec.fieldContext_NamedStatsWithScope_scope(ctx, field) case "stats": - return ec.fieldContext_JobStatsWithScope_stats(ctx, field) + return ec.fieldContext_NamedStatsWithScope_stats(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type JobStatsWithScope", field.Name) + return nil, fmt.Errorf("no field named %q was found under type NamedStatsWithScope", field.Name) }, } defer func() { @@ -10813,64 +11416,6 @@ func (ec *executionContext) fieldContext_Query_scopedJobStats(ctx context.Contex return fc, nil } -func (ec *executionContext) _Query_jobsFootprints(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_jobsFootprints(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().JobsFootprints(rctx, fc.Args["filter"].([]*model.JobFilter), fc.Args["metrics"].([]string)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*model.Footprints) - fc.Result = res - return ec.marshalOFootprints2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐFootprints(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_jobsFootprints(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "timeWeights": - return ec.fieldContext_Footprints_timeWeights(ctx, field) - case "metrics": - return ec.fieldContext_Footprints_metrics(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Footprints", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_jobsFootprints_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - func (ec *executionContext) _Query_jobs(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Query_jobs(ctx, field) if err != nil { @@ -11029,6 +11574,141 @@ func (ec *executionContext) fieldContext_Query_jobsStatistics(ctx context.Contex return fc, nil } +func (ec *executionContext) _Query_jobsMetricStats(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_jobsMetricStats(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().JobsMetricStats(rctx, fc.Args["filter"].([]*model.JobFilter), fc.Args["metrics"].([]string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.JobStats) + fc.Result = res + return ec.marshalNJobStats2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐJobStatsᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_jobsMetricStats(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_JobStats_id(ctx, field) + case "jobId": + return ec.fieldContext_JobStats_jobId(ctx, field) + case "startTime": + return ec.fieldContext_JobStats_startTime(ctx, field) + case "duration": + return ec.fieldContext_JobStats_duration(ctx, field) + case "cluster": + return ec.fieldContext_JobStats_cluster(ctx, field) + case "subCluster": + return ec.fieldContext_JobStats_subCluster(ctx, field) + case "numNodes": + return ec.fieldContext_JobStats_numNodes(ctx, field) + case "numHWThreads": + return ec.fieldContext_JobStats_numHWThreads(ctx, field) + case "numAccelerators": + return ec.fieldContext_JobStats_numAccelerators(ctx, field) + case "stats": + return ec.fieldContext_JobStats_stats(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type JobStats", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_jobsMetricStats_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_jobsFootprints(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_jobsFootprints(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().JobsFootprints(rctx, fc.Args["filter"].([]*model.JobFilter), fc.Args["metrics"].([]string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Footprints) + fc.Result = res + return ec.marshalOFootprints2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐFootprints(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_jobsFootprints(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "timeWeights": + return ec.fieldContext_Footprints_timeWeights(ctx, field) + case "metrics": + return ec.fieldContext_Footprints_metrics(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Footprints", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_jobsFootprints_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Query_rooflineHeatmap(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Query_rooflineHeatmap(ctx, field) if err != nil { @@ -15822,7 +16502,7 @@ func (ec *executionContext) unmarshalInputJobFilter(ctx context.Context, obj any asMap[k] = v } - fieldsInOrder := [...]string{"tags", "jobId", "arrayJobId", "user", "project", "jobName", "cluster", "partition", "duration", "energy", "minRunningFor", "numNodes", "numAccelerators", "numHWThreads", "startTime", "state", "metricStats", "exclusive", "node"} + fieldsInOrder := [...]string{"tags", "dbId", "jobId", "arrayJobId", "user", "project", "jobName", "cluster", "partition", "duration", "energy", "minRunningFor", "numNodes", "numAccelerators", "numHWThreads", "startTime", "state", "metricStats", "exclusive", "node"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -15836,6 +16516,13 @@ func (ec *executionContext) unmarshalInputJobFilter(ctx context.Context, obj any return it, err } it.Tags = data + case "dbId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("dbId")) + data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.DbID = data case "jobId": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("jobId")) data, err := ec.unmarshalOStringInput2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐStringInput(ctx, v) @@ -17269,11 +17956,45 @@ func (ec *executionContext) _JobStats(ctx context.Context, sel ast.SelectionSet, switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("JobStats") - case "name": - out.Values[i] = ec._JobStats_name(ctx, field, obj) + case "id": + out.Values[i] = ec._JobStats_id(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } + case "jobId": + out.Values[i] = ec._JobStats_jobId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "startTime": + out.Values[i] = ec._JobStats_startTime(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "duration": + out.Values[i] = ec._JobStats_duration(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "cluster": + out.Values[i] = ec._JobStats_cluster(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "subCluster": + out.Values[i] = ec._JobStats_subCluster(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "numNodes": + out.Values[i] = ec._JobStats_numNodes(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "numHWThreads": + out.Values[i] = ec._JobStats_numHWThreads(ctx, field, obj) + case "numAccelerators": + out.Values[i] = ec._JobStats_numAccelerators(ctx, field, obj) case "stats": out.Values[i] = ec._JobStats_stats(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -17302,55 +18023,6 @@ func (ec *executionContext) _JobStats(ctx context.Context, sel ast.SelectionSet, return out } -var jobStatsWithScopeImplementors = []string{"JobStatsWithScope"} - -func (ec *executionContext) _JobStatsWithScope(ctx context.Context, sel ast.SelectionSet, obj *model.JobStatsWithScope) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, jobStatsWithScopeImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("JobStatsWithScope") - case "name": - out.Values[i] = ec._JobStatsWithScope_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "scope": - out.Values[i] = ec._JobStatsWithScope_scope(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "stats": - out.Values[i] = ec._JobStatsWithScope_stats(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - var jobsStatisticsImplementors = []string{"JobsStatistics"} func (ec *executionContext) _JobsStatistics(ctx context.Context, sel ast.SelectionSet, obj *model.JobsStatistics) graphql.Marshaler { @@ -17897,6 +18569,99 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) return out } +var namedStatsImplementors = []string{"NamedStats"} + +func (ec *executionContext) _NamedStats(ctx context.Context, sel ast.SelectionSet, obj *model.NamedStats) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, namedStatsImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("NamedStats") + case "name": + out.Values[i] = ec._NamedStats_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "data": + out.Values[i] = ec._NamedStats_data(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var namedStatsWithScopeImplementors = []string{"NamedStatsWithScope"} + +func (ec *executionContext) _NamedStatsWithScope(ctx context.Context, sel ast.SelectionSet, obj *model.NamedStatsWithScope) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, namedStatsWithScopeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("NamedStatsWithScope") + case "name": + out.Values[i] = ec._NamedStatsWithScope_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "scope": + out.Values[i] = ec._NamedStatsWithScope_scope(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "stats": + out.Values[i] = ec._NamedStatsWithScope_stats(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var nodeMetricsImplementors = []string{"NodeMetrics"} func (ec *executionContext) _NodeMetrics(ctx context.Context, sel ast.SelectionSet, obj *model.NodeMetrics) graphql.Marshaler { @@ -18205,25 +18970,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "jobsFootprints": - field := field - - innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_jobsFootprints(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "jobs": field := field @@ -18268,6 +19014,47 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "jobsMetricStats": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_jobsMetricStats(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "jobsFootprints": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_jobsFootprints(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "rooflineHeatmap": field := field @@ -20195,60 +20982,6 @@ func (ec *executionContext) marshalNJobStats2ᚖgithubᚗcomᚋClusterCockpitᚋ return ec._JobStats(ctx, sel, v) } -func (ec *executionContext) marshalNJobStatsWithScope2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐJobStatsWithScopeᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.JobStatsWithScope) graphql.Marshaler { - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNJobStatsWithScope2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐJobStatsWithScope(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalNJobStatsWithScope2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐJobStatsWithScope(ctx context.Context, sel ast.SelectionSet, v *model.JobStatsWithScope) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._JobStatsWithScope(ctx, sel, v) -} - func (ec *executionContext) marshalNJobsStatistics2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐJobsStatisticsᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.JobsStatistics) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup @@ -20498,6 +21231,114 @@ func (ec *executionContext) marshalNMetricValue2githubᚗcomᚋClusterCockpitᚋ return ec._MetricValue(ctx, sel, &v) } +func (ec *executionContext) marshalNNamedStats2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNamedStatsᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.NamedStats) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNNamedStats2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNamedStats(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNNamedStats2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNamedStats(ctx context.Context, sel ast.SelectionSet, v *model.NamedStats) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._NamedStats(ctx, sel, v) +} + +func (ec *executionContext) marshalNNamedStatsWithScope2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNamedStatsWithScopeᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.NamedStatsWithScope) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNNamedStatsWithScope2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNamedStatsWithScope(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNNamedStatsWithScope2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNamedStatsWithScope(ctx context.Context, sel ast.SelectionSet, v *model.NamedStatsWithScope) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._NamedStatsWithScope(ctx, sel, v) +} + func (ec *executionContext) marshalNNodeMetrics2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNodeMetricsᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.NodeMetrics) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup diff --git a/internal/graph/model/models_gen.go b/internal/graph/model/models_gen.go index 43c4e37..5c50ff9 100644 --- a/internal/graph/model/models_gen.go +++ b/internal/graph/model/models_gen.go @@ -50,6 +50,7 @@ type IntRangeOutput struct { type JobFilter struct { Tags []string `json:"tags,omitempty"` + DbID []string `json:"dbId,omitempty"` JobID *StringInput `json:"jobId,omitempty"` ArrayJobID *int `json:"arrayJobId,omitempty"` User *StringInput `json:"user,omitempty"` @@ -96,14 +97,16 @@ type JobResultList struct { } type JobStats struct { - Name string `json:"name"` - Stats *schema.MetricStatistics `json:"stats"` -} - -type JobStatsWithScope struct { - Name string `json:"name"` - Scope schema.MetricScope `json:"scope"` - Stats []*ScopedStats `json:"stats"` + ID int `json:"id"` + JobID string `json:"jobId"` + StartTime int `json:"startTime"` + Duration int `json:"duration"` + Cluster string `json:"cluster"` + SubCluster string `json:"subCluster"` + NumNodes int `json:"numNodes"` + NumHWThreads *int `json:"numHWThreads,omitempty"` + NumAccelerators *int `json:"numAccelerators,omitempty"` + Stats []*NamedStats `json:"stats"` } type JobsStatistics struct { @@ -153,6 +156,17 @@ type MetricStatItem struct { type Mutation struct { } +type NamedStats struct { + Name string `json:"name"` + Data *schema.MetricStatistics `json:"data"` +} + +type NamedStatsWithScope struct { + Name string `json:"name"` + Scope schema.MetricScope `json:"scope"` + Stats []*ScopedStats `json:"stats"` +} + type NodeMetrics struct { Host string `json:"host"` SubCluster string `json:"subCluster"` diff --git a/internal/graph/schema.resolvers.go b/internal/graph/schema.resolvers.go index 10e1b55..f3fc389 100644 --- a/internal/graph/schema.resolvers.go +++ b/internal/graph/schema.resolvers.go @@ -400,7 +400,7 @@ func (r *queryResolver) JobMetrics(ctx context.Context, id string, metrics []str } // JobStats is the resolver for the jobStats field. -func (r *queryResolver) JobStats(ctx context.Context, id string, metrics []string) ([]*model.JobStats, error) { +func (r *queryResolver) JobStats(ctx context.Context, id string, metrics []string) ([]*model.NamedStats, error) { job, err := r.Query().Job(ctx, id) if err != nil { log.Warnf("Error while querying job %s for metadata", id) @@ -413,11 +413,11 @@ func (r *queryResolver) JobStats(ctx context.Context, id string, metrics []strin return nil, err } - res := []*model.JobStats{} + res := []*model.NamedStats{} for name, md := range data { - res = append(res, &model.JobStats{ - Name: name, - Stats: &md, + res = append(res, &model.NamedStats{ + Name: name, + Data: &md, }) } @@ -425,7 +425,7 @@ func (r *queryResolver) JobStats(ctx context.Context, id string, metrics []strin } // ScopedJobStats is the resolver for the scopedJobStats field. -func (r *queryResolver) ScopedJobStats(ctx context.Context, id string, metrics []string, scopes []schema.MetricScope) ([]*model.JobStatsWithScope, error) { +func (r *queryResolver) ScopedJobStats(ctx context.Context, id string, metrics []string, scopes []schema.MetricScope) ([]*model.NamedStatsWithScope, error) { job, err := r.Query().Job(ctx, id) if err != nil { log.Warnf("Error while querying job %s for metadata", id) @@ -438,7 +438,7 @@ func (r *queryResolver) ScopedJobStats(ctx context.Context, id string, metrics [ return nil, err } - res := make([]*model.JobStatsWithScope, 0) + res := make([]*model.NamedStatsWithScope, 0) for name, scoped := range data { for scope, stats := range scoped { @@ -451,7 +451,7 @@ func (r *queryResolver) ScopedJobStats(ctx context.Context, id string, metrics [ }) } - res = append(res, &model.JobStatsWithScope{ + res = append(res, &model.NamedStatsWithScope{ Name: name, Scope: scope, Stats: mdlStats, @@ -462,12 +462,6 @@ func (r *queryResolver) ScopedJobStats(ctx context.Context, id string, metrics [ return res, nil } -// JobsFootprints is the resolver for the jobsFootprints field. -func (r *queryResolver) JobsFootprints(ctx context.Context, filter []*model.JobFilter, metrics []string) (*model.Footprints, error) { - // NOTE: Legacy Naming! This resolver is for normalized histograms in analysis view only - *Not* related to DB "footprint" column! - return r.jobsFootprints(ctx, filter, metrics) -} - // Jobs is the resolver for the jobs field. func (r *queryResolver) Jobs(ctx context.Context, filter []*model.JobFilter, page *model.PageRequest, order *model.OrderByInput) (*model.JobResultList, error) { if page == nil { @@ -589,6 +583,62 @@ func (r *queryResolver) JobsStatistics(ctx context.Context, filter []*model.JobF return stats, nil } +// JobsMetricStats is the resolver for the jobsMetricStats field. +func (r *queryResolver) JobsMetricStats(ctx context.Context, filter []*model.JobFilter, metrics []string) ([]*model.JobStats, error) { + // No Paging, Fixed Order by StartTime ASC + order := &model.OrderByInput{ + Field: "startTime", + Type: "col", + Order: "ASC", + } + + jobs, err := r.Repo.QueryJobs(ctx, filter, nil, order) + if err != nil { + log.Warn("Error while querying jobs for comparison") + return nil, err + } + + res := []*model.JobStats{} + for _, job := range jobs { + data, err := metricDataDispatcher.LoadJobStats(job, metrics, ctx) + if err != nil { + log.Warnf("Error while loading comparison jobStats data for job id %d", job.JobID) + continue + // return nil, err + } + + sres := []*model.NamedStats{} + for name, md := range data { + sres = append(sres, &model.NamedStats{ + Name: name, + Data: &md, + }) + } + + numThreadsInt := int(job.NumHWThreads) + numAccsInt := int(job.NumAcc) + res = append(res, &model.JobStats{ + ID: int(job.ID), + JobID: strconv.Itoa(int(job.JobID)), + StartTime: int(job.StartTime.Unix()), + Duration: int(job.Duration), + Cluster: job.Cluster, + SubCluster: job.SubCluster, + NumNodes: int(job.NumNodes), + NumHWThreads: &numThreadsInt, + NumAccelerators: &numAccsInt, + Stats: sres, + }) + } + return res, err +} + +// JobsFootprints is the resolver for the jobsFootprints field. +func (r *queryResolver) JobsFootprints(ctx context.Context, filter []*model.JobFilter, metrics []string) (*model.Footprints, error) { + // NOTE: Legacy Naming! This resolver is for normalized histograms in analysis view only - *Not* related to DB "footprint" column! + return r.jobsFootprints(ctx, filter, metrics) +} + // RooflineHeatmap is the resolver for the rooflineHeatmap field. func (r *queryResolver) RooflineHeatmap(ctx context.Context, filter []*model.JobFilter, rows int, cols int, minX float64, minY float64, maxX float64, maxY float64) ([][]float64, error) { return r.rooflineHeatmap(ctx, filter, rows, cols, minX, minY, maxX, maxY) diff --git a/internal/repository/jobQuery.go b/internal/repository/jobQuery.go index d169b6f..6a2ddec 100644 --- a/internal/repository/jobQuery.go +++ b/internal/repository/jobQuery.go @@ -146,6 +146,13 @@ func BuildWhereClause(filter *model.JobFilter, query sq.SelectBuilder) sq.Select // This is an OR-Logic query: Returns all distinct jobs with at least one of the requested tags; TODO: AND-Logic query? query = query.Join("jobtag ON jobtag.job_id = job.id").Where(sq.Eq{"jobtag.tag_id": filter.Tags}).Distinct() } + if filter.DbID != nil { + dbIDs := make([]string, len(filter.DbID)) + for i, val := range filter.DbID { + dbIDs[i] = val + } + query = query.Where(sq.Eq{"job.id": dbIDs}) + } if filter.JobID != nil { query = buildStringCondition("job.job_id", filter.JobID, query) } diff --git a/internal/routerConfig/routes.go b/internal/routerConfig/routes.go index bf74391..5386553 100644 --- a/internal/routerConfig/routes.go +++ b/internal/routerConfig/routes.go @@ -297,6 +297,9 @@ func buildFilterPresets(query url.Values) map[string]interface{} { } } } + if len(query["dbId"]) != 0 { + filterPresets["dbId"] = query["dbId"] + } if query.Get("jobId") != "" { if len(query["jobId"]) == 1 { filterPresets["jobId"] = query.Get("jobId") diff --git a/web/frontend/src/Jobs.root.svelte b/web/frontend/src/Jobs.root.svelte index 7faa8b8..1e7f96d 100644 --- a/web/frontend/src/Jobs.root.svelte +++ b/web/frontend/src/Jobs.root.svelte @@ -21,6 +21,7 @@ import { init } from "./generic/utils.js"; import Filters from "./generic/Filters.svelte"; import JobList from "./generic/JobList.svelte"; + import JobCompare from "./generic/JobCompare.svelte"; import TextFilter from "./generic/helper/TextFilter.svelte"; import Refresher from "./generic/helper/Refresher.svelte"; import Sorting from "./generic/select/SortSelection.svelte"; @@ -35,8 +36,12 @@ export let roles; let filterComponent; // see why here: https://stackoverflow.com/questions/58287729/how-can-i-export-a-function-from-a-svelte-component-that-changes-a-value-in-the + let filterBuffer = []; + let selectedJobs = []; let jobList, - matchedJobs = null; + jobCompare, + matchedListJobs, + matchedCompareJobs = null; let sorting = { field: "startTime", type: "col", order: "DESC" }, isSortingOpen = false, isMetricsSelectionOpen = false; @@ -49,11 +54,16 @@ : !!ccconfig.plot_list_showFootprint; let selectedCluster = filterPresets?.cluster ? filterPresets.cluster : null; let presetProject = filterPresets?.project ? filterPresets.project : "" + let showCompare = false; // The filterPresets are handled by the Filters component, // so we need to wait for it to be ready before we can start a query. // This is also why JobList component starts out with a paused query. onMount(() => filterComponent.updateFilters()); + + $: if (filterComponent && selectedJobs.length == 0) { + filterComponent.updateFilters({dbId: []}) + } @@ -72,10 +82,10 @@ {/if} - + - + {#if !showCompare && selectedJobs.length != 0} + + {/if} + - + - + {#if !showCompare} + + {:else} + + {/if} - + Math.floor(Date.parse(rfc3339) / 1000); - let opts = []; + if (filters.cluster) opts.push(`cluster=${filters.cluster}`); if (filters.node) opts.push(`node=${filters.node}`); if (filters.node && filters.nodeMatch != "eq") // "eq" is default-case @@ -196,6 +240,11 @@ if (filters.startTime.range) { opts.push(`startTime=${filters.startTime.range}`) } + if (filters.dbId.length != 0) { + for (let dbi of filters.dbId) { + opts.push(`dbId=${dbi}`); + } + } if (filters.jobId.length != 0) if (filters.jobIdMatch != "in") { opts.push(`jobId=${filters.jobId}`); @@ -237,8 +286,8 @@ for (let stat of filters.stats) { opts.push(`stat=${stat.field}-${stat.from}-${stat.to}`); } + if (opts.length == 0 && window.location.search.length <= 1) return; - let newurl = `${window.location.pathname}?${opts.join("&")}`; window.history.replaceState(null, "", newurl); } @@ -246,60 +295,63 @@ - - - - Filters - - - Manage Filters - {#if menuText} - {menuText} - - {/if} - (isClusterOpen = true)}> - Cluster/Partition - - (isJobStatesOpen = true)}> - Job States - - (isStartTimeOpen = true)}> - Start Time - - (isDurationOpen = true)}> - Duration - - (isTagsOpen = true)}> - Tags - - (isResourcesOpen = true)}> - Resources - - (isEnergyOpen = true)}> - Energy - - (isStatsOpen = true)}> - (isStatsOpen = true)} /> Statistics - - {#if startTimeQuickSelect} - - Start Time Quick Selection - {#each startTimeSelectOptions.filter((stso) => stso.range !== "") as { rangeLabel, range }} - { - filters.startTime.from = null - filters.startTime.to = null - filters.startTime.range = range; - updateFilters(); - }} - > - - {rangeLabel} - - {/each} - {/if} - - + {#if showFilter} + + + + Filters + + + Manage Filters + {#if menuText} + {menuText} + + {/if} + (isClusterOpen = true)}> + Cluster/Partition + + (isJobStatesOpen = true)}> + Job States + + (isStartTimeOpen = true)}> + Start Time + + (isDurationOpen = true)}> + Duration + + (isTagsOpen = true)}> + Tags + + (isResourcesOpen = true)}> + Resources + + (isEnergyOpen = true)}> + Energy + + (isStatsOpen = true)}> + (isStatsOpen = true)} /> Statistics + + {#if startTimeQuickSelect} + + Start Time Quick Selection + {#each startTimeSelectOptions.filter((stso) => stso.range !== "") as { rangeLabel, range }} + { + filters.startTime.from = null + filters.startTime.to = null + filters.startTime.range = range; + updateFilters(); + }} + > + + {rangeLabel} + + {/each} + {/if} + + + {/if} + {#if matchedJobs >= -1} + + { 'Add or Remove Job to/from Comparison Selection' } + {/if} - - - { displayCheck ? 'Copied!' : 'Copy Job ID to Clipboard' } - + + + { displayCheck ? 'Copied!' : 'Copy Job ID to Clipboard' } + + {#if job.metaData?.jobName} {#if job.metaData?.jobName.length <= 25} diff --git a/web/frontend/src/generic/joblist/JobListRow.svelte b/web/frontend/src/generic/joblist/JobListRow.svelte index 82cf2ed..7d94943 100644 --- a/web/frontend/src/generic/joblist/JobListRow.svelte +++ b/web/frontend/src/generic/joblist/JobListRow.svelte @@ -12,7 +12,7 @@ + + +{#if data && data[0].length > 0} +
+{:else} + Cannot render plot: No series data returned for {metric?metric:'job resources'} +{/if} diff --git a/web/frontend/src/generic/plots/Histogram.svelte b/web/frontend/src/generic/plots/Histogram.svelte index fbc5a33..4408112 100644 --- a/web/frontend/src/generic/plots/Histogram.svelte +++ b/web/frontend/src/generic/plots/Histogram.svelte @@ -16,7 +16,7 @@