mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-25 12:59:06 +01:00
Merge branch 'master' of github.com:ClusterCockpit/cc-backend
This commit is contained in:
commit
45359cca9d
@ -8,6 +8,29 @@ import (
|
|||||||
"github.com/ClusterCockpit/cc-backend/log"
|
"github.com/ClusterCockpit/cc-backend/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type NodeList [][]interface {
|
||||||
|
consume(input string) (next string, ok bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nl *NodeList) Contains(name string) bool {
|
||||||
|
var ok bool
|
||||||
|
for _, term := range *nl {
|
||||||
|
str := name
|
||||||
|
for _, expr := range term {
|
||||||
|
str, ok = expr.consume(str)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok && str == "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type NLExprString string
|
type NLExprString string
|
||||||
|
|
||||||
func (nle NLExprString) consume(input string) (next string, ok bool) {
|
func (nle NLExprString) consume(input string) (next string, ok bool) {
|
||||||
@ -18,6 +41,17 @@ func (nle NLExprString) consume(input string) (next string, ok bool) {
|
|||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NLExprIntRanges []NLExprIntRange
|
||||||
|
|
||||||
|
func (nles NLExprIntRanges) consume(input string) (next string, ok bool) {
|
||||||
|
for _, nle := range nles {
|
||||||
|
if next, ok := nle.consume(input); ok {
|
||||||
|
return next, ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
type NLExprIntRange struct {
|
type NLExprIntRange struct {
|
||||||
start, end int64
|
start, end int64
|
||||||
zeroPadded bool
|
zeroPadded bool
|
||||||
@ -51,36 +85,31 @@ func (nle NLExprIntRange) consume(input string) (next string, ok bool) {
|
|||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeList [][]interface {
|
|
||||||
consume(input string) (next string, ok bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (nl *NodeList) Contains(name string) bool {
|
|
||||||
var ok bool
|
|
||||||
for _, term := range *nl {
|
|
||||||
str := name
|
|
||||||
for _, expr := range term {
|
|
||||||
str, ok = expr.consume(str)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok && str == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseNodeList(raw string) (NodeList, error) {
|
func ParseNodeList(raw string) (NodeList, error) {
|
||||||
nl := NodeList{}
|
|
||||||
|
|
||||||
isLetter := func(r byte) bool { return ('a' <= r && r <= 'z') || ('A' <= r && r <= 'Z') }
|
isLetter := func(r byte) bool { return ('a' <= r && r <= 'z') || ('A' <= r && r <= 'Z') }
|
||||||
isDigit := func(r byte) bool { return '0' <= r && r <= '9' }
|
isDigit := func(r byte) bool { return '0' <= r && r <= '9' }
|
||||||
|
|
||||||
for _, rawterm := range strings.Split(raw, ",") {
|
rawterms := []string{}
|
||||||
|
prevterm := 0
|
||||||
|
for i := 0; i < len(raw); i++ {
|
||||||
|
if raw[i] == '[' {
|
||||||
|
for i < len(raw) && raw[i] != ']' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if i == len(raw) {
|
||||||
|
return nil, fmt.Errorf("node list: unclosed '['")
|
||||||
|
}
|
||||||
|
} else if raw[i] == ',' {
|
||||||
|
rawterms = append(rawterms, raw[prevterm:i])
|
||||||
|
prevterm = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if prevterm != len(raw) {
|
||||||
|
rawterms = append(rawterms, raw[prevterm:])
|
||||||
|
}
|
||||||
|
|
||||||
|
nl := NodeList{}
|
||||||
|
for _, rawterm := range rawterms {
|
||||||
exprs := []interface {
|
exprs := []interface {
|
||||||
consume(input string) (next string, ok bool)
|
consume(input string) (next string, ok bool)
|
||||||
}{}
|
}{}
|
||||||
@ -99,31 +128,37 @@ func ParseNodeList(raw string) (NodeList, error) {
|
|||||||
return nil, fmt.Errorf("node list: unclosed '['")
|
return nil, fmt.Errorf("node list: unclosed '['")
|
||||||
}
|
}
|
||||||
|
|
||||||
minus := strings.Index(rawterm[i:i+end], "-")
|
parts := strings.Split(rawterm[i+1:i+end], ",")
|
||||||
if minus == -1 {
|
nles := NLExprIntRanges{}
|
||||||
return nil, fmt.Errorf("node list: no '-' found inside '[...]'")
|
for _, part := range parts {
|
||||||
|
minus := strings.Index(part, "-")
|
||||||
|
if minus == -1 {
|
||||||
|
return nil, fmt.Errorf("node list: no '-' found inside '[...]'")
|
||||||
|
}
|
||||||
|
|
||||||
|
s1, s2 := part[0:minus], part[minus+1:]
|
||||||
|
if len(s1) != len(s2) || len(s1) == 0 {
|
||||||
|
return nil, fmt.Errorf("node list: %#v and %#v are not of equal length or of length zero", s1, s2)
|
||||||
|
}
|
||||||
|
|
||||||
|
x1, err := strconv.ParseInt(s1, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("node list: %w", err)
|
||||||
|
}
|
||||||
|
x2, err := strconv.ParseInt(s2, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("node list: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nles = append(nles, NLExprIntRange{
|
||||||
|
start: x1,
|
||||||
|
end: x2,
|
||||||
|
digits: len(s1),
|
||||||
|
zeroPadded: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
s1, s2 := rawterm[i+1:i+minus], rawterm[i+minus+1:i+end]
|
exprs = append(exprs, nles)
|
||||||
if len(s1) != len(s2) || len(s1) == 0 {
|
|
||||||
return nil, fmt.Errorf("node list: %#v and %#v are not of equal length or of length zero", s1, s2)
|
|
||||||
}
|
|
||||||
|
|
||||||
x1, err := strconv.ParseInt(s1, 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("node list: %w", err)
|
|
||||||
}
|
|
||||||
x2, err := strconv.ParseInt(s2, 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("node list: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
exprs = append(exprs, NLExprIntRange{
|
|
||||||
start: x1,
|
|
||||||
end: x2,
|
|
||||||
digits: len(s1),
|
|
||||||
zeroPadded: true,
|
|
||||||
})
|
|
||||||
i += end
|
i += end
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("node list: invalid character: %#v", rune(c))
|
return nil, fmt.Errorf("node list: invalid character: %#v", rune(c))
|
||||||
|
@ -10,11 +10,6 @@ func TestNodeList(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fmt.Printf("terms\n")
|
|
||||||
// for i, term := range nl.terms {
|
|
||||||
// fmt.Printf("term %d: %#v\n", i, term)
|
|
||||||
// }
|
|
||||||
|
|
||||||
if nl.Contains("hello") || nl.Contains("woody") {
|
if nl.Contains("hello") || nl.Contains("woody") {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@ -35,3 +30,26 @@ func TestNodeList(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNodeListCommasInBrackets(t *testing.T) {
|
||||||
|
nl, err := ParseNodeList("a[1000-2000,2010-2090,3000-5000]")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if nl.Contains("hello") || nl.Contains("woody") {
|
||||||
|
t.Fatal("1")
|
||||||
|
}
|
||||||
|
|
||||||
|
if nl.Contains("a0") || nl.Contains("a0000") || nl.Contains("a5001") || nl.Contains("a2005") {
|
||||||
|
t.Fatal("2")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !nl.Contains("a1001") || !nl.Contains("a2000") {
|
||||||
|
t.Fatal("3")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !nl.Contains("a2042") || !nl.Contains("a4321") || !nl.Contains("a3000") {
|
||||||
|
t.Fatal("4")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
frontend
2
frontend
@ -1 +1 @@
|
|||||||
Subproject commit 4b0d020dd416e6b6b2a70b476b158804e62b3d7c
|
Subproject commit 94ef11aa9fc3c194f1df497e3e06c60a7125883d
|
@ -150,6 +150,7 @@ type ComplexityRoot struct {
|
|||||||
Normal func(childComplexity int) int
|
Normal func(childComplexity int) int
|
||||||
Peak func(childComplexity int) int
|
Peak func(childComplexity int) int
|
||||||
Scope func(childComplexity int) int
|
Scope func(childComplexity int) int
|
||||||
|
SubClusters func(childComplexity int) int
|
||||||
Timestep func(childComplexity int) int
|
Timestep func(childComplexity int) int
|
||||||
Unit func(childComplexity int) int
|
Unit func(childComplexity int) int
|
||||||
}
|
}
|
||||||
@ -228,6 +229,14 @@ type ComplexityRoot struct {
|
|||||||
Topology func(childComplexity int) int
|
Topology func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubClusterConfig struct {
|
||||||
|
Alert func(childComplexity int) int
|
||||||
|
Caution func(childComplexity int) int
|
||||||
|
Name func(childComplexity int) int
|
||||||
|
Normal func(childComplexity int) int
|
||||||
|
Peak func(childComplexity int) int
|
||||||
|
}
|
||||||
|
|
||||||
Tag struct {
|
Tag struct {
|
||||||
ID func(childComplexity int) int
|
ID func(childComplexity int) int
|
||||||
Name func(childComplexity int) int
|
Name func(childComplexity int) int
|
||||||
@ -763,6 +772,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||||||
|
|
||||||
return e.complexity.MetricConfig.Scope(childComplexity), true
|
return e.complexity.MetricConfig.Scope(childComplexity), true
|
||||||
|
|
||||||
|
case "MetricConfig.subClusters":
|
||||||
|
if e.complexity.MetricConfig.SubClusters == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.MetricConfig.SubClusters(childComplexity), true
|
||||||
|
|
||||||
case "MetricConfig.timestep":
|
case "MetricConfig.timestep":
|
||||||
if e.complexity.MetricConfig.Timestep == nil {
|
if e.complexity.MetricConfig.Timestep == nil {
|
||||||
break
|
break
|
||||||
@ -1181,6 +1197,41 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||||||
|
|
||||||
return e.complexity.SubCluster.Topology(childComplexity), true
|
return e.complexity.SubCluster.Topology(childComplexity), true
|
||||||
|
|
||||||
|
case "SubClusterConfig.alert":
|
||||||
|
if e.complexity.SubClusterConfig.Alert == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.SubClusterConfig.Alert(childComplexity), true
|
||||||
|
|
||||||
|
case "SubClusterConfig.caution":
|
||||||
|
if e.complexity.SubClusterConfig.Caution == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.SubClusterConfig.Caution(childComplexity), true
|
||||||
|
|
||||||
|
case "SubClusterConfig.name":
|
||||||
|
if e.complexity.SubClusterConfig.Name == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.SubClusterConfig.Name(childComplexity), true
|
||||||
|
|
||||||
|
case "SubClusterConfig.normal":
|
||||||
|
if e.complexity.SubClusterConfig.Normal == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.SubClusterConfig.Normal(childComplexity), true
|
||||||
|
|
||||||
|
case "SubClusterConfig.peak":
|
||||||
|
if e.complexity.SubClusterConfig.Peak == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.SubClusterConfig.Peak(childComplexity), true
|
||||||
|
|
||||||
case "Tag.id":
|
case "Tag.id":
|
||||||
if e.complexity.Tag.ID == nil {
|
if e.complexity.Tag.ID == nil {
|
||||||
break
|
break
|
||||||
@ -1413,16 +1464,25 @@ type Accelerator {
|
|||||||
model: String!
|
model: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SubClusterConfig {
|
||||||
|
name: String!
|
||||||
|
peak: Float!
|
||||||
|
normal: Float!
|
||||||
|
caution: Float!
|
||||||
|
alert: Float!
|
||||||
|
}
|
||||||
|
|
||||||
type MetricConfig {
|
type MetricConfig {
|
||||||
name: String!
|
name: String!
|
||||||
unit: String!
|
unit: String!
|
||||||
scope: MetricScope!
|
scope: MetricScope!
|
||||||
aggregation: String
|
aggregation: String
|
||||||
timestep: Int!
|
timestep: Int!
|
||||||
peak: Float!
|
peak: Float
|
||||||
normal: Float!
|
normal: Float
|
||||||
caution: Float!
|
caution: Float
|
||||||
alert: Float!
|
alert: Float
|
||||||
|
subClusters: [SubClusterConfig]
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tag {
|
type Tag {
|
||||||
@ -4352,14 +4412,11 @@ func (ec *executionContext) _MetricConfig_peak(ctx context.Context, field graphq
|
|||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
if resTmp == nil {
|
if resTmp == nil {
|
||||||
if !graphql.HasFieldError(ctx, fc) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
res := resTmp.(float64)
|
res := resTmp.(*float64)
|
||||||
fc.Result = res
|
fc.Result = res
|
||||||
return ec.marshalNFloat2float64(ctx, field.Selections, res)
|
return ec.marshalOFloat2ᚖfloat64(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _MetricConfig_normal(ctx context.Context, field graphql.CollectedField, obj *model.MetricConfig) (ret graphql.Marshaler) {
|
func (ec *executionContext) _MetricConfig_normal(ctx context.Context, field graphql.CollectedField, obj *model.MetricConfig) (ret graphql.Marshaler) {
|
||||||
@ -4387,14 +4444,11 @@ func (ec *executionContext) _MetricConfig_normal(ctx context.Context, field grap
|
|||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
if resTmp == nil {
|
if resTmp == nil {
|
||||||
if !graphql.HasFieldError(ctx, fc) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
res := resTmp.(float64)
|
res := resTmp.(*float64)
|
||||||
fc.Result = res
|
fc.Result = res
|
||||||
return ec.marshalNFloat2float64(ctx, field.Selections, res)
|
return ec.marshalOFloat2ᚖfloat64(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _MetricConfig_caution(ctx context.Context, field graphql.CollectedField, obj *model.MetricConfig) (ret graphql.Marshaler) {
|
func (ec *executionContext) _MetricConfig_caution(ctx context.Context, field graphql.CollectedField, obj *model.MetricConfig) (ret graphql.Marshaler) {
|
||||||
@ -4422,14 +4476,11 @@ func (ec *executionContext) _MetricConfig_caution(ctx context.Context, field gra
|
|||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
if resTmp == nil {
|
if resTmp == nil {
|
||||||
if !graphql.HasFieldError(ctx, fc) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
res := resTmp.(float64)
|
res := resTmp.(*float64)
|
||||||
fc.Result = res
|
fc.Result = res
|
||||||
return ec.marshalNFloat2float64(ctx, field.Selections, res)
|
return ec.marshalOFloat2ᚖfloat64(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _MetricConfig_alert(ctx context.Context, field graphql.CollectedField, obj *model.MetricConfig) (ret graphql.Marshaler) {
|
func (ec *executionContext) _MetricConfig_alert(ctx context.Context, field graphql.CollectedField, obj *model.MetricConfig) (ret graphql.Marshaler) {
|
||||||
@ -4457,14 +4508,43 @@ func (ec *executionContext) _MetricConfig_alert(ctx context.Context, field graph
|
|||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
if resTmp == nil {
|
if resTmp == nil {
|
||||||
if !graphql.HasFieldError(ctx, fc) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
res := resTmp.(float64)
|
res := resTmp.(*float64)
|
||||||
fc.Result = res
|
fc.Result = res
|
||||||
return ec.marshalNFloat2float64(ctx, field.Selections, res)
|
return ec.marshalOFloat2ᚖfloat64(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _MetricConfig_subClusters(ctx context.Context, field graphql.CollectedField, obj *model.MetricConfig) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "MetricConfig",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.SubClusters, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.([]*model.SubClusterConfig)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOSubClusterConfig2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋgraphᚋmodelᚐSubClusterConfig(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _MetricFootprints_metric(ctx context.Context, field graphql.CollectedField, obj *model.MetricFootprints) (ret graphql.Marshaler) {
|
func (ec *executionContext) _MetricFootprints_metric(ctx context.Context, field graphql.CollectedField, obj *model.MetricFootprints) (ret graphql.Marshaler) {
|
||||||
@ -6261,6 +6341,181 @@ func (ec *executionContext) _SubCluster_topology(ctx context.Context, field grap
|
|||||||
return ec.marshalNTopology2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋgraphᚋmodelᚐTopology(ctx, field.Selections, res)
|
return ec.marshalNTopology2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋgraphᚋmodelᚐTopology(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _SubClusterConfig_name(ctx context.Context, field graphql.CollectedField, obj *model.SubClusterConfig) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "SubClusterConfig",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, 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) _SubClusterConfig_peak(ctx context.Context, field graphql.CollectedField, obj *model.SubClusterConfig) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "SubClusterConfig",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Peak, 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.(float64)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNFloat2float64(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _SubClusterConfig_normal(ctx context.Context, field graphql.CollectedField, obj *model.SubClusterConfig) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "SubClusterConfig",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Normal, 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.(float64)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNFloat2float64(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _SubClusterConfig_caution(ctx context.Context, field graphql.CollectedField, obj *model.SubClusterConfig) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "SubClusterConfig",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Caution, 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.(float64)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNFloat2float64(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _SubClusterConfig_alert(ctx context.Context, field graphql.CollectedField, obj *model.SubClusterConfig) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "SubClusterConfig",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Alert, 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.(float64)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNFloat2float64(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Tag_id(ctx context.Context, field graphql.CollectedField, obj *schema.Tag) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Tag_id(ctx context.Context, field graphql.CollectedField, obj *schema.Tag) (ret graphql.Marshaler) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
@ -9217,9 +9472,6 @@ func (ec *executionContext) _MetricConfig(ctx context.Context, sel ast.Selection
|
|||||||
|
|
||||||
out.Values[i] = innerFunc(ctx)
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
if out.Values[i] == graphql.Null {
|
|
||||||
invalids++
|
|
||||||
}
|
|
||||||
case "normal":
|
case "normal":
|
||||||
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
return ec._MetricConfig_normal(ctx, field, obj)
|
return ec._MetricConfig_normal(ctx, field, obj)
|
||||||
@ -9227,9 +9479,6 @@ func (ec *executionContext) _MetricConfig(ctx context.Context, sel ast.Selection
|
|||||||
|
|
||||||
out.Values[i] = innerFunc(ctx)
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
if out.Values[i] == graphql.Null {
|
|
||||||
invalids++
|
|
||||||
}
|
|
||||||
case "caution":
|
case "caution":
|
||||||
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
return ec._MetricConfig_caution(ctx, field, obj)
|
return ec._MetricConfig_caution(ctx, field, obj)
|
||||||
@ -9237,9 +9486,6 @@ func (ec *executionContext) _MetricConfig(ctx context.Context, sel ast.Selection
|
|||||||
|
|
||||||
out.Values[i] = innerFunc(ctx)
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
if out.Values[i] == graphql.Null {
|
|
||||||
invalids++
|
|
||||||
}
|
|
||||||
case "alert":
|
case "alert":
|
||||||
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
return ec._MetricConfig_alert(ctx, field, obj)
|
return ec._MetricConfig_alert(ctx, field, obj)
|
||||||
@ -9247,9 +9493,13 @@ func (ec *executionContext) _MetricConfig(ctx context.Context, sel ast.Selection
|
|||||||
|
|
||||||
out.Values[i] = innerFunc(ctx)
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
if out.Values[i] == graphql.Null {
|
case "subClusters":
|
||||||
invalids++
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._MetricConfig_subClusters(ctx, field, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
}
|
}
|
||||||
@ -10081,6 +10331,77 @@ func (ec *executionContext) _SubCluster(ctx context.Context, sel ast.SelectionSe
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var subClusterConfigImplementors = []string{"SubClusterConfig"}
|
||||||
|
|
||||||
|
func (ec *executionContext) _SubClusterConfig(ctx context.Context, sel ast.SelectionSet, obj *model.SubClusterConfig) graphql.Marshaler {
|
||||||
|
fields := graphql.CollectFields(ec.OperationContext, sel, subClusterConfigImplementors)
|
||||||
|
out := graphql.NewFieldSet(fields)
|
||||||
|
var invalids uint32
|
||||||
|
for i, field := range fields {
|
||||||
|
switch field.Name {
|
||||||
|
case "__typename":
|
||||||
|
out.Values[i] = graphql.MarshalString("SubClusterConfig")
|
||||||
|
case "name":
|
||||||
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._SubClusterConfig_name(ctx, field, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
|
case "peak":
|
||||||
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._SubClusterConfig_peak(ctx, field, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
|
case "normal":
|
||||||
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._SubClusterConfig_normal(ctx, field, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
|
case "caution":
|
||||||
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._SubClusterConfig_caution(ctx, field, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
|
case "alert":
|
||||||
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._SubClusterConfig_alert(ctx, field, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Values[i] = innerFunc(ctx)
|
||||||
|
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.Dispatch()
|
||||||
|
if invalids > 0 {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
var tagImplementors = []string{"Tag"}
|
var tagImplementors = []string{"Tag"}
|
||||||
|
|
||||||
func (ec *executionContext) _Tag(ctx context.Context, sel ast.SelectionSet, obj *schema.Tag) graphql.Marshaler {
|
func (ec *executionContext) _Tag(ctx context.Context, sel ast.SelectionSet, obj *schema.Tag) graphql.Marshaler {
|
||||||
@ -12214,6 +12535,22 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalOFloat2ᚖfloat64(ctx context.Context, v interface{}) (*float64, error) {
|
||||||
|
if v == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
res, err := graphql.UnmarshalFloatContext(ctx, v)
|
||||||
|
return &res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalOFloat2ᚖfloat64(ctx context.Context, sel ast.SelectionSet, v *float64) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := graphql.MarshalFloatContext(*v)
|
||||||
|
return graphql.WrapContextMarshaler(ctx, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalOFloatRange2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋgraphᚋmodelᚐFloatRange(ctx context.Context, v interface{}) (*model.FloatRange, error) {
|
func (ec *executionContext) unmarshalOFloatRange2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋgraphᚋmodelᚐFloatRange(ctx context.Context, v interface{}) (*model.FloatRange, error) {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -12627,6 +12964,54 @@ func (ec *executionContext) unmarshalOStringInput2ᚖgithubᚗcomᚋClusterCockp
|
|||||||
return &res, graphql.ErrorOnPath(ctx, err)
|
return &res, graphql.ErrorOnPath(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalOSubClusterConfig2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋgraphᚋmodelᚐSubClusterConfig(ctx context.Context, sel ast.SelectionSet, v []*model.SubClusterConfig) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
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.marshalOSubClusterConfig2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋgraphᚋmodelᚐSubClusterConfig(ctx, sel, v[i])
|
||||||
|
}
|
||||||
|
if isLen1 {
|
||||||
|
f(i)
|
||||||
|
} else {
|
||||||
|
go f(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalOSubClusterConfig2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋgraphᚋmodelᚐSubClusterConfig(ctx context.Context, sel ast.SelectionSet, v *model.SubClusterConfig) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return ec._SubClusterConfig(ctx, sel, v)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalOTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) {
|
func (ec *executionContext) unmarshalOTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -97,15 +97,16 @@ type JobsStatistics struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MetricConfig struct {
|
type MetricConfig struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Unit string `json:"unit"`
|
Unit string `json:"unit"`
|
||||||
Scope schema.MetricScope `json:"scope"`
|
Scope schema.MetricScope `json:"scope"`
|
||||||
Aggregation *string `json:"aggregation"`
|
Aggregation *string `json:"aggregation"`
|
||||||
Timestep int `json:"timestep"`
|
Timestep int `json:"timestep"`
|
||||||
Peak float64 `json:"peak"`
|
Peak *float64 `json:"peak"`
|
||||||
Normal float64 `json:"normal"`
|
Normal *float64 `json:"normal"`
|
||||||
Caution float64 `json:"caution"`
|
Caution *float64 `json:"caution"`
|
||||||
Alert float64 `json:"alert"`
|
Alert *float64 `json:"alert"`
|
||||||
|
SubClusters []*SubClusterConfig `json:"subClusters"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MetricFootprints struct {
|
type MetricFootprints struct {
|
||||||
@ -150,6 +151,14 @@ type SubCluster struct {
|
|||||||
Topology *Topology `json:"topology"`
|
Topology *Topology `json:"topology"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SubClusterConfig struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Peak float64 `json:"peak"`
|
||||||
|
Normal float64 `json:"normal"`
|
||||||
|
Caution float64 `json:"caution"`
|
||||||
|
Alert float64 `json:"alert"`
|
||||||
|
}
|
||||||
|
|
||||||
type TimeRange struct {
|
type TimeRange struct {
|
||||||
From *time.Time `json:"from"`
|
From *time.Time `json:"from"`
|
||||||
To *time.Time `json:"to"`
|
To *time.Time `json:"to"`
|
||||||
|
@ -68,16 +68,25 @@ type Accelerator {
|
|||||||
model: String!
|
model: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SubClusterConfig {
|
||||||
|
name: String!
|
||||||
|
peak: Float!
|
||||||
|
normal: Float!
|
||||||
|
caution: Float!
|
||||||
|
alert: Float!
|
||||||
|
}
|
||||||
|
|
||||||
type MetricConfig {
|
type MetricConfig {
|
||||||
name: String!
|
name: String!
|
||||||
unit: String!
|
unit: String!
|
||||||
scope: MetricScope!
|
scope: MetricScope!
|
||||||
aggregation: String
|
aggregation: String
|
||||||
timestep: Int!
|
timestep: Int!
|
||||||
peak: Float!
|
peak: Float
|
||||||
normal: Float!
|
normal: Float
|
||||||
caution: Float!
|
caution: Float
|
||||||
alert: Float!
|
alert: Float
|
||||||
|
subClusters: [SubClusterConfig]
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tag {
|
type Tag {
|
||||||
|
@ -1 +0,0 @@
|
|||||||
# Helper scripts
|
|
@ -1,40 +0,0 @@
|
|||||||
import fetch from 'node-fetch'
|
|
||||||
|
|
||||||
// Just for testing
|
|
||||||
|
|
||||||
const job = {
|
|
||||||
jobId: 123,
|
|
||||||
user: 'lou',
|
|
||||||
project: 'testproj',
|
|
||||||
cluster: 'heidi',
|
|
||||||
partition: 'default',
|
|
||||||
arrayJobId: 0,
|
|
||||||
numNodes: 1,
|
|
||||||
numHwthreads: 8,
|
|
||||||
numAcc: 0,
|
|
||||||
exclusive: 1,
|
|
||||||
monitoringStatus: 1,
|
|
||||||
smt: 1,
|
|
||||||
jobState: 'running',
|
|
||||||
duration: 2*60*60,
|
|
||||||
tags: [],
|
|
||||||
resources: [
|
|
||||||
{
|
|
||||||
hostname: 'heidi',
|
|
||||||
hwthreads: [0, 1, 2, 3, 4, 5, 6, 7]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metaData: null,
|
|
||||||
startTime: 1641427200
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch('http://localhost:8080/api/jobs/start_job/', {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify(job),
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': 'Bearer eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc19hZG1pbiI6dHJ1ZSwiaXNfYXBpIjpmYWxzZSwic3ViIjoibG91In0.nY6dCgLSdm7zXz1xPkrb_3JnnUCgExXeXcrTlAAySs4p72VKJhmzzC1RxgkJE26l8tDYUilM-o-urzlaqK5aDA'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(res => res.status == 200 ? res.json() : res.text())
|
|
||||||
.then(res => console.log(res))
|
|
@ -1,22 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ed25519"
|
|
||||||
"crypto/rand"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// rand.Reader uses /dev/urandom on Linux
|
|
||||||
pub, priv, err := ed25519.GenerateKey(rand.Reader)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "error: %s\n", err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stdout, "JWT_PUBLIC_KEY=%#v\nJWT_PRIVATE_KEY=%#v\n",
|
|
||||||
base64.StdEncoding.EncodeToString(pub),
|
|
||||||
base64.StdEncoding.EncodeToString(priv))
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
# How to run this as a systemd deamon
|
|
||||||
|
|
||||||
The files in this directory assume that you install the Golang version of ClusterCockpit to `/var/clustercockpit`. If you do not like that, you can choose any other location, but make sure to replace all paths that begin with `/var/clustercockpit` in the `clustercockpit.service` file!
|
|
||||||
|
|
||||||
If you have not installed [yarn](https://yarnpkg.com/getting-started/install) and [go](https://go.dev/doc/install) already, do that (Golang is available in most package managers).
|
|
||||||
|
|
||||||
The `config.json` can have the optional fields *user* and *group*. If provided, the application will call [setuid](https://man7.org/linux/man-pages/man2/setuid.2.html) and [setgid](https://man7.org/linux/man-pages/man2/setgid.2.html) after having read the config file and having bound to a TCP port (so that it can take a privileged port), but before it starts accepting any connections. This is good for security, but means that the directories `frontend/public`, `var/` and `templates/` must be readable by that user and `var/` writable as well (All paths relative to the repos root). The `.env` and `config.json` files might contain secrets and should not be readable by that user. If those files are changed, the server has to be restarted.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# 1.: Clone this repository to /var/clustercockpit
|
|
||||||
git clone git@github.com:ClusterCockpit/cc-backend.git /var/clustercockpit
|
|
||||||
|
|
||||||
# 2.: Install all dependencies and build everything
|
|
||||||
cd /var/clustercockpit
|
|
||||||
go get && go build && (cd ./frontend && yarn install && yarn build)
|
|
||||||
|
|
||||||
# 3.: Modify the `./config.json` file from the directory which contains this README.md to your liking and put it in the repo root
|
|
||||||
cp ./utils/systemd/config.json ./config.json
|
|
||||||
vim ./config.json # do your thing...
|
|
||||||
|
|
||||||
# 4.: Add the systemd service unit file
|
|
||||||
sudo ln -s /var/clustercockpit/utils/systemd/clustercockpit.service /etc/systemd/system/clustercockpit.service
|
|
||||||
|
|
||||||
# 5.: Enable and start the server
|
|
||||||
sudo systemctl enable clustercockpit.service # optional (if done, (re-)starts automatically)
|
|
||||||
sudo systemctl start clustercockpit.service
|
|
||||||
|
|
||||||
# Check whats going on:
|
|
||||||
sudo journalctl -u clustercockpit.service
|
|
||||||
```
|
|
Loading…
Reference in New Issue
Block a user