mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 13:29:05 +01:00
Check validity of cluster.json files
This commit is contained in:
parent
e11507de5a
commit
6ad74e918e
@ -3,6 +3,7 @@ package config
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -12,6 +13,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ClusterCockpit/cc-backend/auth"
|
"github.com/ClusterCockpit/cc-backend/auth"
|
||||||
"github.com/ClusterCockpit/cc-backend/graph/model"
|
"github.com/ClusterCockpit/cc-backend/graph/model"
|
||||||
|
"github.com/ClusterCockpit/cc-backend/schema"
|
||||||
"github.com/iamlouk/lrucache"
|
"github.com/iamlouk/lrucache"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
)
|
)
|
||||||
@ -33,22 +35,51 @@ func Init(usersdb *sqlx.DB, authEnabled bool, uiConfig map[string]interface{}, j
|
|||||||
|
|
||||||
Clusters = []*model.Cluster{}
|
Clusters = []*model.Cluster{}
|
||||||
for _, de := range entries {
|
for _, de := range entries {
|
||||||
bytes, err := os.ReadFile(filepath.Join(jobArchive, de.Name(), "cluster.json"))
|
raw, err := os.ReadFile(filepath.Join(jobArchive, de.Name(), "cluster.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var cluster model.Cluster
|
var cluster model.Cluster
|
||||||
if err := json.Unmarshal(bytes, &cluster); err != nil {
|
|
||||||
|
// Disabled because of the historic 'measurement' field.
|
||||||
|
// dec := json.NewDecoder(bytes.NewBuffer(raw))
|
||||||
|
// dec.DisallowUnknownFields()
|
||||||
|
// if err := dec.Decode(&cluster); err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
if err := json.Unmarshal(raw, &cluster); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(cluster.Name) == 0 || len(cluster.MetricConfig) == 0 || len(cluster.Partitions) == 0 {
|
||||||
|
return errors.New("cluster.name, cluster.metricConfig and cluster.Partitions should not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mc := range cluster.MetricConfig {
|
||||||
|
if len(mc.Name) == 0 {
|
||||||
|
return errors.New("cluster.metricConfig.name should not be empty")
|
||||||
|
}
|
||||||
|
if mc.Timestep < 1 {
|
||||||
|
return errors.New("cluster.metricConfig.timestep should not be smaller than one")
|
||||||
|
}
|
||||||
|
|
||||||
|
// For backwards compability...
|
||||||
|
if mc.Scope == "" {
|
||||||
|
mc.Scope = schema.MetricScopeNode
|
||||||
|
}
|
||||||
|
if !mc.Scope.Valid() {
|
||||||
|
return errors.New("cluster.metricConfig.scope must be a valid scope ('node', 'scocket', ...)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if cluster.FilterRanges.StartTime.To.IsZero() {
|
if cluster.FilterRanges.StartTime.To.IsZero() {
|
||||||
cluster.FilterRanges.StartTime.To = time.Unix(0, 0)
|
cluster.FilterRanges.StartTime.To = time.Unix(0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cluster.Name != de.Name() {
|
if cluster.Name != de.Name() {
|
||||||
return fmt.Errorf("the file '%s/cluster.json' contains the clusterId '%s'", de.Name(), cluster.Name)
|
return fmt.Errorf("the file '.../%s/cluster.json' contains the clusterId '%s'", de.Name(), cluster.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
Clusters = append(Clusters, &cluster)
|
Clusters = append(Clusters, &cluster)
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ClusterCockpit/cc-backend/auth"
|
"github.com/ClusterCockpit/cc-backend/auth"
|
||||||
"github.com/ClusterCockpit/cc-backend/graph/model"
|
"github.com/ClusterCockpit/cc-backend/graph/model"
|
||||||
@ -122,7 +123,8 @@ func BuildWhereClause(filter *model.JobFilter, query sq.SelectBuilder) sq.Select
|
|||||||
query = buildTimeCondition("job.start_time", filter.StartTime, query)
|
query = buildTimeCondition("job.start_time", filter.StartTime, query)
|
||||||
}
|
}
|
||||||
if filter.Duration != nil {
|
if filter.Duration != nil {
|
||||||
query = buildIntCondition("job.duration", filter.Duration, query)
|
now := time.Now().Unix() // There does not seam to be a portable way to get the current unix timestamp accross different DBs.
|
||||||
|
query = query.Where("(CASE job.job_state = 'running' THEN (? - job.start_time) ELSE job.duration END) BETWEEN ? AND ?", now, filter.Duration.From, filter.Duration.To)
|
||||||
}
|
}
|
||||||
if filter.State != nil {
|
if filter.State != nil {
|
||||||
states := make([]string, len(filter.State))
|
states := make([]string, len(filter.State))
|
||||||
|
@ -92,7 +92,7 @@ func (e *MetricScope) UnmarshalGQL(v interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*e = MetricScope(str)
|
*e = MetricScope(str)
|
||||||
if _, ok := metricScopeGranularity[*e]; !ok {
|
if !e.Valid() {
|
||||||
return fmt.Errorf("%s is not a valid MetricScope", str)
|
return fmt.Errorf("%s is not a valid MetricScope", str)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -102,6 +102,11 @@ func (e MetricScope) MarshalGQL(w io.Writer) {
|
|||||||
fmt.Fprintf(w, "\"%s\"", e)
|
fmt.Fprintf(w, "\"%s\"", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e MetricScope) Valid() bool {
|
||||||
|
gran, ok := metricScopeGranularity[e]
|
||||||
|
return ok && gran > 0
|
||||||
|
}
|
||||||
|
|
||||||
func (jd *JobData) Size() int {
|
func (jd *JobData) Size() int {
|
||||||
n := 128
|
n := 128
|
||||||
for _, scopes := range *jd {
|
for _, scopes := range *jd {
|
||||||
|
Loading…
Reference in New Issue
Block a user