mirror of
				https://github.com/ClusterCockpit/cc-backend
				synced 2025-10-31 16:05:06 +01:00 
			
		
		
		
	Update Node table code. Add simple unit test
This commit is contained in:
		| @@ -4,7 +4,7 @@ scalar Any | |||||||
| scalar NullableFloat | scalar NullableFloat | ||||||
| scalar MetricScope | scalar MetricScope | ||||||
| scalar JobState | scalar JobState | ||||||
| scalar NodeState | scalar SchedulerState | ||||||
| scalar MonitoringState | scalar MonitoringState | ||||||
|  |  | ||||||
| type Node { | type Node { | ||||||
| @@ -12,8 +12,11 @@ type Node { | |||||||
|   hostname: String! |   hostname: String! | ||||||
|   cluster: String! |   cluster: String! | ||||||
|   subCluster: String! |   subCluster: String! | ||||||
|   runningJobs: Int! |   jobsRunning: Int! | ||||||
|   nodeState: NodeState! |   cpusAllocated: Int | ||||||
|  |   memoryAllocated: Int | ||||||
|  |   gpusAllocated: Int | ||||||
|  |   schedulerState: SchedulerState! | ||||||
|   healthState: MonitoringState! |   healthState: MonitoringState! | ||||||
|   metaData: Any |   metaData: Any | ||||||
| } | } | ||||||
| @@ -399,7 +402,7 @@ input NodeFilter { | |||||||
|   hostname: StringInput |   hostname: StringInput | ||||||
|   cluster: StringInput |   cluster: StringInput | ||||||
|   subcluster: StringInput |   subcluster: StringInput | ||||||
|   nodeState: NodeState |   schedulerState: SchedulerState | ||||||
|   healthState: MonitoringState |   healthState: MonitoringState | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,18 +6,11 @@ | |||||||
|     "user": "clustercockpit", |     "user": "clustercockpit", | ||||||
|     "group": "clustercockpit", |     "group": "clustercockpit", | ||||||
|     "validate": false, |     "validate": false, | ||||||
|     "apiAllowedIPs": [ |     "apiAllowedIPs": ["*"], | ||||||
|       "*" |  | ||||||
|     ], |  | ||||||
|     "short-running-jobs-duration": 300, |     "short-running-jobs-duration": 300, | ||||||
|     "resampling": { |     "resampling": { | ||||||
|       "trigger": 30, |       "trigger": 30, | ||||||
|       "resolutions": [ |       "resolutions": [600, 300, 120, 60] | ||||||
|         600, |  | ||||||
|         300, |  | ||||||
|         120, |  | ||||||
|         60 |  | ||||||
|       ] |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "cron": { |   "cron": { | ||||||
| @@ -54,3 +47,4 @@ | |||||||
|     } |     } | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								go.mod
									
									
									
									
									
								
							| @@ -6,7 +6,7 @@ toolchain go1.24.1 | |||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	github.com/99designs/gqlgen v0.17.78 | 	github.com/99designs/gqlgen v0.17.78 | ||||||
| 	github.com/ClusterCockpit/cc-lib v0.9.1 | 	github.com/ClusterCockpit/cc-lib v0.10.0 | ||||||
| 	github.com/Masterminds/squirrel v1.5.4 | 	github.com/Masterminds/squirrel v1.5.4 | ||||||
| 	github.com/coreos/go-oidc/v3 v3.12.0 | 	github.com/coreos/go-oidc/v3 v3.12.0 | ||||||
| 	github.com/expr-lang/expr v1.17.6 | 	github.com/expr-lang/expr v1.17.6 | ||||||
| @@ -24,7 +24,7 @@ require ( | |||||||
| 	github.com/joho/godotenv v1.5.1 | 	github.com/joho/godotenv v1.5.1 | ||||||
| 	github.com/linkedin/goavro/v2 v2.14.0 | 	github.com/linkedin/goavro/v2 v2.14.0 | ||||||
| 	github.com/mattn/go-sqlite3 v1.14.24 | 	github.com/mattn/go-sqlite3 v1.14.24 | ||||||
| 	github.com/nats-io/nats.go v1.45.0 | 	github.com/nats-io/nats.go v1.46.1 | ||||||
| 	github.com/prometheus/client_golang v1.23.2 | 	github.com/prometheus/client_golang v1.23.2 | ||||||
| 	github.com/prometheus/common v0.66.1 | 	github.com/prometheus/common v0.66.1 | ||||||
| 	github.com/qustavo/sqlhooks/v2 v2.1.0 | 	github.com/qustavo/sqlhooks/v2 v2.1.0 | ||||||
| @@ -32,7 +32,7 @@ require ( | |||||||
| 	github.com/swaggo/http-swagger v1.3.4 | 	github.com/swaggo/http-swagger v1.3.4 | ||||||
| 	github.com/swaggo/swag v1.16.6 | 	github.com/swaggo/swag v1.16.6 | ||||||
| 	github.com/vektah/gqlparser/v2 v2.5.30 | 	github.com/vektah/gqlparser/v2 v2.5.30 | ||||||
| 	golang.org/x/crypto v0.41.0 | 	golang.org/x/crypto v0.42.0 | ||||||
| 	golang.org/x/oauth2 v0.30.0 | 	golang.org/x/oauth2 v0.30.0 | ||||||
| 	golang.org/x/time v0.13.0 | 	golang.org/x/time v0.13.0 | ||||||
| ) | ) | ||||||
| @@ -86,12 +86,12 @@ require ( | |||||||
| 	go.uber.org/atomic v1.11.0 // indirect | 	go.uber.org/atomic v1.11.0 // indirect | ||||||
| 	go.yaml.in/yaml/v2 v2.4.2 // indirect | 	go.yaml.in/yaml/v2 v2.4.2 // indirect | ||||||
| 	golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect | 	golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect | ||||||
| 	golang.org/x/mod v0.26.0 // indirect | 	golang.org/x/mod v0.27.0 // indirect | ||||||
| 	golang.org/x/net v0.43.0 // indirect | 	golang.org/x/net v0.43.0 // indirect | ||||||
| 	golang.org/x/sync v0.16.0 // indirect | 	golang.org/x/sync v0.17.0 // indirect | ||||||
| 	golang.org/x/sys v0.36.0 // indirect | 	golang.org/x/sys v0.36.0 // indirect | ||||||
| 	golang.org/x/text v0.28.0 // indirect | 	golang.org/x/text v0.29.0 // indirect | ||||||
| 	golang.org/x/tools v0.35.0 // indirect | 	golang.org/x/tools v0.36.0 // indirect | ||||||
| 	google.golang.org/protobuf v1.36.8 // indirect | 	google.golang.org/protobuf v1.36.8 // indirect | ||||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||||
| 	sigs.k8s.io/yaml v1.6.0 // indirect | 	sigs.k8s.io/yaml v1.6.0 // indirect | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								go.sum
									
									
									
									
									
								
							| @@ -6,8 +6,8 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25 | |||||||
| github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= | github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= | ||||||
| github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= | github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= | ||||||
| github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= | github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= | ||||||
| github.com/ClusterCockpit/cc-lib v0.9.1 h1:pcUbpcbD1o4u7gILiBFVnO9DyQpji/Lgq+pIQ/CwxQo= | github.com/ClusterCockpit/cc-lib v0.10.0 h1:Pa8mqVciCOipzXTO18ZL8vwMi2JJh/ZjQbCWXZl2R78= | ||||||
| github.com/ClusterCockpit/cc-lib v0.9.1/go.mod h1:RRud94Y5qXAvosww0LxbdBFKXndVN4FnwgS1PxVTKbc= | github.com/ClusterCockpit/cc-lib v0.10.0/go.mod h1:nvTZuxFCTwlos8I1rL5O1RPab7vRtkU8E/PGiaF6pQA= | ||||||
| github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= | github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= | ||||||
| github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= | github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= | ||||||
| github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= | github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= | ||||||
| @@ -207,8 +207,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq | |||||||
| github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= | ||||||
| github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= | ||||||
| github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | ||||||
| github.com/nats-io/nats.go v1.45.0 h1:/wGPbnYXDM0pLKFjZTX+2JOw9TQPoIgTFrUaH97giwA= | github.com/nats-io/nats.go v1.46.1 h1:bqQ2ZcxVd2lpYI97xYASeRTY3I5boe/IVmuUDPitHfo= | ||||||
| github.com/nats-io/nats.go v1.45.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= | github.com/nats-io/nats.go v1.46.1/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= | ||||||
| github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= | github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= | ||||||
| github.com/nats-io/nkeys v0.4.11/go.mod h1:szDimtgmfOi9n25JpfIdGw12tZFYXqhGxjhVxsatHVE= | github.com/nats-io/nkeys v0.4.11/go.mod h1:szDimtgmfOi9n25JpfIdGw12tZFYXqhGxjhVxsatHVE= | ||||||
| github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= | github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= | ||||||
| @@ -295,8 +295,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY | |||||||
| golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= | golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= | ||||||
| golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= | golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= | ||||||
| golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= | golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= | ||||||
| golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= | golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= | ||||||
| golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= | golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= | ||||||
| golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= | golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= | ||||||
| golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= | golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= | ||||||
| golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | ||||||
| @@ -304,8 +304,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | |||||||
| golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||||||
| golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= | golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= | ||||||
| golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= | golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= | ||||||
| golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= | golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= | ||||||
| golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= | golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= | ||||||
| golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
| @@ -328,8 +328,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= | |||||||
| golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | ||||||
| golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | ||||||
| golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | ||||||
| golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= | golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= | ||||||
| golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= | golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= | ||||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| @@ -361,8 +361,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= | |||||||
| golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= | ||||||
| golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= | golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= | ||||||
| golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= | golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= | ||||||
| golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= | golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= | ||||||
| golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= | golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= | ||||||
| golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= | golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= | ||||||
| golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= | golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= | ||||||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||||
| @@ -371,8 +371,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc | |||||||
| golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= | ||||||
| golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= | golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= | ||||||
| golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= | ||||||
| golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= | golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= | ||||||
| golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= | golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= | ||||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= | google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= | ||||||
|   | |||||||
| @@ -80,7 +80,8 @@ models: | |||||||
|   Tag: { model: "github.com/ClusterCockpit/cc-lib/schema.Tag" } |   Tag: { model: "github.com/ClusterCockpit/cc-lib/schema.Tag" } | ||||||
|   Resource: { model: "github.com/ClusterCockpit/cc-lib/schema.Resource" } |   Resource: { model: "github.com/ClusterCockpit/cc-lib/schema.Resource" } | ||||||
|   JobState: { model: "github.com/ClusterCockpit/cc-lib/schema.JobState" } |   JobState: { model: "github.com/ClusterCockpit/cc-lib/schema.JobState" } | ||||||
|   MonitoringState: |   Node: { model: "github.com/ClusterCockpit/cc-lib/schema.Node" } | ||||||
|  |   SchedulerState: | ||||||
|     { model: "github.com/ClusterCockpit/cc-lib/schema.SchedulerState" } |     { model: "github.com/ClusterCockpit/cc-lib/schema.SchedulerState" } | ||||||
|   HealthState: |   HealthState: | ||||||
|     { model: "github.com/ClusterCockpit/cc-lib/schema.MonitoringState" } |     { model: "github.com/ClusterCockpit/cc-lib/schema.MonitoringState" } | ||||||
|   | |||||||
| @@ -15,18 +15,9 @@ import ( | |||||||
| 	"github.com/ClusterCockpit/cc-lib/schema" | 	"github.com/ClusterCockpit/cc-lib/schema" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type Node struct { |  | ||||||
| 	Hostname        string   `json:"hostname"` |  | ||||||
| 	States          []string `json:"states"` |  | ||||||
| 	CpusAllocated   int      `json:"cpusAllocated"` |  | ||||||
| 	MemoryAllocated int      `json:"memoryAllocated"` |  | ||||||
| 	GpusAllocated   int      `json:"gpusAllocated"` |  | ||||||
| 	JobsRunning     int      `json:"jobsRunning"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type UpdateNodeStatesRequest struct { | type UpdateNodeStatesRequest struct { | ||||||
| 	Nodes   []Node `json:"nodes"` | 	Nodes   []schema.NodePayload `json:"nodes"` | ||||||
| 	Cluster string `json:"cluster" example:"fritz"` | 	Cluster string               `json:"cluster" example:"fritz"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // this routine assumes that only one of them exists per node | // this routine assumes that only one of them exists per node | ||||||
| @@ -75,7 +66,7 @@ func (api *RestApi) updateNodeStates(rw http.ResponseWriter, r *http.Request) { | |||||||
|  |  | ||||||
| 	for _, node := range req.Nodes { | 	for _, node := range req.Nodes { | ||||||
| 		state := determineState(node.States) | 		state := determineState(node.States) | ||||||
| 		nodeState := schema.NodeState{ | 		nodeState := schema.NodeStateDB{ | ||||||
| 			TimeStamp: time.Now().Unix(), NodeState: state, | 			TimeStamp: time.Now().Unix(), NodeState: state, | ||||||
| 			CpusAllocated:   node.CpusAllocated, | 			CpusAllocated:   node.CpusAllocated, | ||||||
| 			MemoryAllocated: node.MemoryAllocated, | 			MemoryAllocated: node.MemoryAllocated, | ||||||
|   | |||||||
| @@ -272,14 +272,17 @@ type ComplexityRoot struct { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Node struct { | 	Node struct { | ||||||
| 		Cluster     func(childComplexity int) int | 		Cluster         func(childComplexity int) int | ||||||
| 		HealthState func(childComplexity int) int | 		CpusAllocated   func(childComplexity int) int | ||||||
| 		Hostname    func(childComplexity int) int | 		GpusAllocated   func(childComplexity int) int | ||||||
| 		ID          func(childComplexity int) int | 		HealthState     func(childComplexity int) int | ||||||
| 		MetaData    func(childComplexity int) int | 		Hostname        func(childComplexity int) int | ||||||
| 		NodeState   func(childComplexity int) int | 		ID              func(childComplexity int) int | ||||||
| 		RunningJobs func(childComplexity int) int | 		JobsRunning     func(childComplexity int) int | ||||||
| 		SubCluster  func(childComplexity int) int | 		MemoryAllocated func(childComplexity int) int | ||||||
|  | 		MetaData        func(childComplexity int) int | ||||||
|  | 		SchedulerState  func(childComplexity int) int | ||||||
|  | 		SubCluster      func(childComplexity int) int | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	NodeMetrics struct { | 	NodeMetrics struct { | ||||||
| @@ -447,9 +450,11 @@ type MutationResolver interface { | |||||||
| 	UpdateConfiguration(ctx context.Context, name string, value string) (*string, error) | 	UpdateConfiguration(ctx context.Context, name string, value string) (*string, error) | ||||||
| } | } | ||||||
| type NodeResolver interface { | type NodeResolver interface { | ||||||
| 	NodeState(ctx context.Context, obj *model.Node) (string, error) | 	ID(ctx context.Context, obj *schema.Node) (string, error) | ||||||
| 	HealthState(ctx context.Context, obj *model.Node) (schema.SchedulerState, error) |  | ||||||
| 	MetaData(ctx context.Context, obj *model.Node) (any, error) | 	SchedulerState(ctx context.Context, obj *schema.Node) (schema.SchedulerState, error) | ||||||
|  | 	HealthState(ctx context.Context, obj *schema.Node) (string, error) | ||||||
|  | 	MetaData(ctx context.Context, obj *schema.Node) (any, error) | ||||||
| } | } | ||||||
| type QueryResolver interface { | type QueryResolver interface { | ||||||
| 	Clusters(ctx context.Context) ([]*schema.Cluster, error) | 	Clusters(ctx context.Context) ([]*schema.Cluster, error) | ||||||
| @@ -457,7 +462,7 @@ type QueryResolver interface { | |||||||
| 	GlobalMetrics(ctx context.Context) ([]*schema.GlobalMetricListItem, error) | 	GlobalMetrics(ctx context.Context) ([]*schema.GlobalMetricListItem, error) | ||||||
| 	User(ctx context.Context, username string) (*model.User, error) | 	User(ctx context.Context, username string) (*model.User, error) | ||||||
| 	AllocatedNodes(ctx context.Context, cluster string) ([]*model.Count, error) | 	AllocatedNodes(ctx context.Context, cluster string) ([]*model.Count, error) | ||||||
| 	Node(ctx context.Context, id string) (*model.Node, error) | 	Node(ctx context.Context, id string) (*schema.Node, error) | ||||||
| 	Nodes(ctx context.Context, filter []*model.NodeFilter, order *model.OrderByInput) (*model.NodeStateResultList, error) | 	Nodes(ctx context.Context, filter []*model.NodeFilter, order *model.OrderByInput) (*model.NodeStateResultList, error) | ||||||
| 	NodeStates(ctx context.Context, filter []*model.NodeFilter) ([]*model.NodeStates, error) | 	NodeStates(ctx context.Context, filter []*model.NodeFilter) ([]*model.NodeStates, error) | ||||||
| 	Job(ctx context.Context, id string) (*schema.Job, error) | 	Job(ctx context.Context, id string) (*schema.Job, error) | ||||||
| @@ -1484,6 +1489,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin | |||||||
|  |  | ||||||
| 		return e.complexity.Node.Cluster(childComplexity), true | 		return e.complexity.Node.Cluster(childComplexity), true | ||||||
|  |  | ||||||
|  | 	case "Node.cpusAllocated": | ||||||
|  | 		if e.complexity.Node.CpusAllocated == nil { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return e.complexity.Node.CpusAllocated(childComplexity), true | ||||||
|  |  | ||||||
|  | 	case "Node.gpusAllocated": | ||||||
|  | 		if e.complexity.Node.GpusAllocated == nil { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return e.complexity.Node.GpusAllocated(childComplexity), true | ||||||
|  |  | ||||||
| 	case "Node.healthState": | 	case "Node.healthState": | ||||||
| 		if e.complexity.Node.HealthState == nil { | 		if e.complexity.Node.HealthState == nil { | ||||||
| 			break | 			break | ||||||
| @@ -1505,6 +1524,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin | |||||||
|  |  | ||||||
| 		return e.complexity.Node.ID(childComplexity), true | 		return e.complexity.Node.ID(childComplexity), true | ||||||
|  |  | ||||||
|  | 	case "Node.jobsRunning": | ||||||
|  | 		if e.complexity.Node.JobsRunning == nil { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return e.complexity.Node.JobsRunning(childComplexity), true | ||||||
|  |  | ||||||
|  | 	case "Node.memoryAllocated": | ||||||
|  | 		if e.complexity.Node.MemoryAllocated == nil { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return e.complexity.Node.MemoryAllocated(childComplexity), true | ||||||
|  |  | ||||||
| 	case "Node.metaData": | 	case "Node.metaData": | ||||||
| 		if e.complexity.Node.MetaData == nil { | 		if e.complexity.Node.MetaData == nil { | ||||||
| 			break | 			break | ||||||
| @@ -1512,19 +1545,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin | |||||||
|  |  | ||||||
| 		return e.complexity.Node.MetaData(childComplexity), true | 		return e.complexity.Node.MetaData(childComplexity), true | ||||||
|  |  | ||||||
| 	case "Node.nodeState": | 	case "Node.schedulerState": | ||||||
| 		if e.complexity.Node.NodeState == nil { | 		if e.complexity.Node.SchedulerState == nil { | ||||||
| 			break | 			break | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return e.complexity.Node.NodeState(childComplexity), true | 		return e.complexity.Node.SchedulerState(childComplexity), true | ||||||
|  |  | ||||||
| 	case "Node.runningJobs": |  | ||||||
| 		if e.complexity.Node.RunningJobs == nil { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return e.complexity.Node.RunningJobs(childComplexity), true |  | ||||||
|  |  | ||||||
| 	case "Node.subCluster": | 	case "Node.subCluster": | ||||||
| 		if e.complexity.Node.SubCluster == nil { | 		if e.complexity.Node.SubCluster == nil { | ||||||
| @@ -2342,7 +2368,7 @@ scalar Any | |||||||
| scalar NullableFloat | scalar NullableFloat | ||||||
| scalar MetricScope | scalar MetricScope | ||||||
| scalar JobState | scalar JobState | ||||||
| scalar NodeState | scalar SchedulerState | ||||||
| scalar MonitoringState | scalar MonitoringState | ||||||
|  |  | ||||||
| type Node { | type Node { | ||||||
| @@ -2350,8 +2376,11 @@ type Node { | |||||||
|   hostname: String! |   hostname: String! | ||||||
|   cluster: String! |   cluster: String! | ||||||
|   subCluster: String! |   subCluster: String! | ||||||
|   runningJobs: Int! |   jobsRunning: Int! | ||||||
|   nodeState: NodeState! |   cpusAllocated: Int | ||||||
|  |   memoryAllocated: Int | ||||||
|  |   gpusAllocated: Int | ||||||
|  |   schedulerState: SchedulerState! | ||||||
|   healthState: MonitoringState! |   healthState: MonitoringState! | ||||||
|   metaData: Any |   metaData: Any | ||||||
| } | } | ||||||
| @@ -2737,7 +2766,7 @@ input NodeFilter { | |||||||
|   hostname: StringInput |   hostname: StringInput | ||||||
|   cluster: StringInput |   cluster: StringInput | ||||||
|   subcluster: StringInput |   subcluster: StringInput | ||||||
|   nodeState: NodeState |   schedulerState: SchedulerState | ||||||
|   healthState: MonitoringState |   healthState: MonitoringState | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -9679,7 +9708,7 @@ func (ec *executionContext) fieldContext_NamedStatsWithScope_stats(_ context.Con | |||||||
| 	return fc, nil | 	return fc, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) _Node_id(ctx context.Context, field graphql.CollectedField, obj *model.Node) (ret graphql.Marshaler) { | func (ec *executionContext) _Node_id(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
| 	fc, err := ec.fieldContext_Node_id(ctx, field) | 	fc, err := ec.fieldContext_Node_id(ctx, field) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| @@ -9693,7 +9722,7 @@ func (ec *executionContext) _Node_id(ctx context.Context, field graphql.Collecte | |||||||
| 	}() | 	}() | ||||||
| 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { | 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { | ||||||
| 		ctx = rctx // use context from middleware stack in children | 		ctx = rctx // use context from middleware stack in children | ||||||
| 		return obj.ID, nil | 		return ec.resolvers.Node().ID(rctx, obj) | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ec.Error(ctx, err) | 		ec.Error(ctx, err) | ||||||
| @@ -9705,17 +9734,17 @@ func (ec *executionContext) _Node_id(ctx context.Context, field graphql.Collecte | |||||||
| 		} | 		} | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| 	} | 	} | ||||||
| 	res := resTmp.(int64) | 	res := resTmp.(string) | ||||||
| 	fc.Result = res | 	fc.Result = res | ||||||
| 	return ec.marshalNID2int64(ctx, field.Selections, res) | 	return ec.marshalNID2string(ctx, field.Selections, res) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) fieldContext_Node_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | func (ec *executionContext) fieldContext_Node_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | ||||||
| 	fc = &graphql.FieldContext{ | 	fc = &graphql.FieldContext{ | ||||||
| 		Object:     "Node", | 		Object:     "Node", | ||||||
| 		Field:      field, | 		Field:      field, | ||||||
| 		IsMethod:   false, | 		IsMethod:   true, | ||||||
| 		IsResolver: false, | 		IsResolver: true, | ||||||
| 		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { | 		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { | ||||||
| 			return nil, errors.New("field of type ID does not have child fields") | 			return nil, errors.New("field of type ID does not have child fields") | ||||||
| 		}, | 		}, | ||||||
| @@ -9723,7 +9752,7 @@ func (ec *executionContext) fieldContext_Node_id(_ context.Context, field graphq | |||||||
| 	return fc, nil | 	return fc, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) _Node_hostname(ctx context.Context, field graphql.CollectedField, obj *model.Node) (ret graphql.Marshaler) { | func (ec *executionContext) _Node_hostname(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
| 	fc, err := ec.fieldContext_Node_hostname(ctx, field) | 	fc, err := ec.fieldContext_Node_hostname(ctx, field) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| @@ -9767,7 +9796,7 @@ func (ec *executionContext) fieldContext_Node_hostname(_ context.Context, field | |||||||
| 	return fc, nil | 	return fc, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) _Node_cluster(ctx context.Context, field graphql.CollectedField, obj *model.Node) (ret graphql.Marshaler) { | func (ec *executionContext) _Node_cluster(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
| 	fc, err := ec.fieldContext_Node_cluster(ctx, field) | 	fc, err := ec.fieldContext_Node_cluster(ctx, field) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| @@ -9811,7 +9840,7 @@ func (ec *executionContext) fieldContext_Node_cluster(_ context.Context, field g | |||||||
| 	return fc, nil | 	return fc, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) _Node_subCluster(ctx context.Context, field graphql.CollectedField, obj *model.Node) (ret graphql.Marshaler) { | func (ec *executionContext) _Node_subCluster(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
| 	fc, err := ec.fieldContext_Node_subCluster(ctx, field) | 	fc, err := ec.fieldContext_Node_subCluster(ctx, field) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| @@ -9855,8 +9884,8 @@ func (ec *executionContext) fieldContext_Node_subCluster(_ context.Context, fiel | |||||||
| 	return fc, nil | 	return fc, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) _Node_runningJobs(ctx context.Context, field graphql.CollectedField, obj *model.Node) (ret graphql.Marshaler) { | func (ec *executionContext) _Node_jobsRunning(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
| 	fc, err := ec.fieldContext_Node_runningJobs(ctx, field) | 	fc, err := ec.fieldContext_Node_jobsRunning(ctx, field) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| 	} | 	} | ||||||
| @@ -9869,7 +9898,7 @@ func (ec *executionContext) _Node_runningJobs(ctx context.Context, field graphql | |||||||
| 	}() | 	}() | ||||||
| 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { | 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { | ||||||
| 		ctx = rctx // use context from middleware stack in children | 		ctx = rctx // use context from middleware stack in children | ||||||
| 		return obj.RunningJobs, nil | 		return obj.JobsRunning, nil | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ec.Error(ctx, err) | 		ec.Error(ctx, err) | ||||||
| @@ -9886,7 +9915,7 @@ func (ec *executionContext) _Node_runningJobs(ctx context.Context, field graphql | |||||||
| 	return ec.marshalNInt2int(ctx, field.Selections, res) | 	return ec.marshalNInt2int(ctx, field.Selections, res) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) fieldContext_Node_runningJobs(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | func (ec *executionContext) fieldContext_Node_jobsRunning(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | ||||||
| 	fc = &graphql.FieldContext{ | 	fc = &graphql.FieldContext{ | ||||||
| 		Object:     "Node", | 		Object:     "Node", | ||||||
| 		Field:      field, | 		Field:      field, | ||||||
| @@ -9899,8 +9928,8 @@ func (ec *executionContext) fieldContext_Node_runningJobs(_ context.Context, fie | |||||||
| 	return fc, nil | 	return fc, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) _Node_nodeState(ctx context.Context, field graphql.CollectedField, obj *model.Node) (ret graphql.Marshaler) { | func (ec *executionContext) _Node_cpusAllocated(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
| 	fc, err := ec.fieldContext_Node_nodeState(ctx, field) | 	fc, err := ec.fieldContext_Node_cpusAllocated(ctx, field) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| 	} | 	} | ||||||
| @@ -9913,7 +9942,130 @@ func (ec *executionContext) _Node_nodeState(ctx context.Context, field graphql.C | |||||||
| 	}() | 	}() | ||||||
| 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { | 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { | ||||||
| 		ctx = rctx // use context from middleware stack in children | 		ctx = rctx // use context from middleware stack in children | ||||||
| 		return ec.resolvers.Node().NodeState(rctx, obj) | 		return obj.CpusAllocated, 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.marshalOInt2int(ctx, field.Selections, res) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ec *executionContext) fieldContext_Node_cpusAllocated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | ||||||
|  | 	fc = &graphql.FieldContext{ | ||||||
|  | 		Object:     "Node", | ||||||
|  | 		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) _Node_memoryAllocated(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
|  | 	fc, err := ec.fieldContext_Node_memoryAllocated(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.MemoryAllocated, 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.marshalOInt2int(ctx, field.Selections, res) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ec *executionContext) fieldContext_Node_memoryAllocated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | ||||||
|  | 	fc = &graphql.FieldContext{ | ||||||
|  | 		Object:     "Node", | ||||||
|  | 		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) _Node_gpusAllocated(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
|  | 	fc, err := ec.fieldContext_Node_gpusAllocated(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.GpusAllocated, 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.marshalOInt2int(ctx, field.Selections, res) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ec *executionContext) fieldContext_Node_gpusAllocated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | ||||||
|  | 	fc = &graphql.FieldContext{ | ||||||
|  | 		Object:     "Node", | ||||||
|  | 		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) _Node_schedulerState(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
|  | 	fc, err := ec.fieldContext_Node_schedulerState(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.Node().SchedulerState(rctx, obj) | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ec.Error(ctx, err) | 		ec.Error(ctx, err) | ||||||
| @@ -9925,25 +10077,25 @@ func (ec *executionContext) _Node_nodeState(ctx context.Context, field graphql.C | |||||||
| 		} | 		} | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| 	} | 	} | ||||||
| 	res := resTmp.(string) | 	res := resTmp.(schema.SchedulerState) | ||||||
| 	fc.Result = res | 	fc.Result = res | ||||||
| 	return ec.marshalNNodeState2string(ctx, field.Selections, res) | 	return ec.marshalNSchedulerState2githubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx, field.Selections, res) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) fieldContext_Node_nodeState(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | func (ec *executionContext) fieldContext_Node_schedulerState(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | ||||||
| 	fc = &graphql.FieldContext{ | 	fc = &graphql.FieldContext{ | ||||||
| 		Object:     "Node", | 		Object:     "Node", | ||||||
| 		Field:      field, | 		Field:      field, | ||||||
| 		IsMethod:   true, | 		IsMethod:   true, | ||||||
| 		IsResolver: true, | 		IsResolver: true, | ||||||
| 		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { | 		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { | ||||||
| 			return nil, errors.New("field of type NodeState does not have child fields") | 			return nil, errors.New("field of type SchedulerState does not have child fields") | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	return fc, nil | 	return fc, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) _Node_healthState(ctx context.Context, field graphql.CollectedField, obj *model.Node) (ret graphql.Marshaler) { | func (ec *executionContext) _Node_healthState(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
| 	fc, err := ec.fieldContext_Node_healthState(ctx, field) | 	fc, err := ec.fieldContext_Node_healthState(ctx, field) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| @@ -9969,9 +10121,9 @@ func (ec *executionContext) _Node_healthState(ctx context.Context, field graphql | |||||||
| 		} | 		} | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| 	} | 	} | ||||||
| 	res := resTmp.(schema.SchedulerState) | 	res := resTmp.(string) | ||||||
| 	fc.Result = res | 	fc.Result = res | ||||||
| 	return ec.marshalNMonitoringState2githubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx, field.Selections, res) | 	return ec.marshalNMonitoringState2string(ctx, field.Selections, res) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) fieldContext_Node_healthState(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | func (ec *executionContext) fieldContext_Node_healthState(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | ||||||
| @@ -9987,7 +10139,7 @@ func (ec *executionContext) fieldContext_Node_healthState(_ context.Context, fie | |||||||
| 	return fc, nil | 	return fc, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) _Node_metaData(ctx context.Context, field graphql.CollectedField, obj *model.Node) (ret graphql.Marshaler) { | func (ec *executionContext) _Node_metaData(ctx context.Context, field graphql.CollectedField, obj *schema.Node) (ret graphql.Marshaler) { | ||||||
| 	fc, err := ec.fieldContext_Node_metaData(ctx, field) | 	fc, err := ec.fieldContext_Node_metaData(ctx, field) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| @@ -10194,9 +10346,9 @@ func (ec *executionContext) _NodeStateResultList_items(ctx context.Context, fiel | |||||||
| 		} | 		} | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| 	} | 	} | ||||||
| 	res := resTmp.([]*model.Node) | 	res := resTmp.([]*schema.Node) | ||||||
| 	fc.Result = res | 	fc.Result = res | ||||||
| 	return ec.marshalNNode2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNodeᚄ(ctx, field.Selections, res) | 	return ec.marshalNNode2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐNodeᚄ(ctx, field.Selections, res) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) fieldContext_NodeStateResultList_items(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | func (ec *executionContext) fieldContext_NodeStateResultList_items(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | ||||||
| @@ -10215,10 +10367,16 @@ func (ec *executionContext) fieldContext_NodeStateResultList_items(_ context.Con | |||||||
| 				return ec.fieldContext_Node_cluster(ctx, field) | 				return ec.fieldContext_Node_cluster(ctx, field) | ||||||
| 			case "subCluster": | 			case "subCluster": | ||||||
| 				return ec.fieldContext_Node_subCluster(ctx, field) | 				return ec.fieldContext_Node_subCluster(ctx, field) | ||||||
| 			case "runningJobs": | 			case "jobsRunning": | ||||||
| 				return ec.fieldContext_Node_runningJobs(ctx, field) | 				return ec.fieldContext_Node_jobsRunning(ctx, field) | ||||||
| 			case "nodeState": | 			case "cpusAllocated": | ||||||
| 				return ec.fieldContext_Node_nodeState(ctx, field) | 				return ec.fieldContext_Node_cpusAllocated(ctx, field) | ||||||
|  | 			case "memoryAllocated": | ||||||
|  | 				return ec.fieldContext_Node_memoryAllocated(ctx, field) | ||||||
|  | 			case "gpusAllocated": | ||||||
|  | 				return ec.fieldContext_Node_gpusAllocated(ctx, field) | ||||||
|  | 			case "schedulerState": | ||||||
|  | 				return ec.fieldContext_Node_schedulerState(ctx, field) | ||||||
| 			case "healthState": | 			case "healthState": | ||||||
| 				return ec.fieldContext_Node_healthState(ctx, field) | 				return ec.fieldContext_Node_healthState(ctx, field) | ||||||
| 			case "metaData": | 			case "metaData": | ||||||
| @@ -10922,9 +11080,9 @@ func (ec *executionContext) _Query_node(ctx context.Context, field graphql.Colle | |||||||
| 	if resTmp == nil { | 	if resTmp == nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| 	} | 	} | ||||||
| 	res := resTmp.(*model.Node) | 	res := resTmp.(*schema.Node) | ||||||
| 	fc.Result = res | 	fc.Result = res | ||||||
| 	return ec.marshalONode2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNode(ctx, field.Selections, res) | 	return ec.marshalONode2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐNode(ctx, field.Selections, res) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) fieldContext_Query_node(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | func (ec *executionContext) fieldContext_Query_node(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { | ||||||
| @@ -10943,10 +11101,16 @@ func (ec *executionContext) fieldContext_Query_node(ctx context.Context, field g | |||||||
| 				return ec.fieldContext_Node_cluster(ctx, field) | 				return ec.fieldContext_Node_cluster(ctx, field) | ||||||
| 			case "subCluster": | 			case "subCluster": | ||||||
| 				return ec.fieldContext_Node_subCluster(ctx, field) | 				return ec.fieldContext_Node_subCluster(ctx, field) | ||||||
| 			case "runningJobs": | 			case "jobsRunning": | ||||||
| 				return ec.fieldContext_Node_runningJobs(ctx, field) | 				return ec.fieldContext_Node_jobsRunning(ctx, field) | ||||||
| 			case "nodeState": | 			case "cpusAllocated": | ||||||
| 				return ec.fieldContext_Node_nodeState(ctx, field) | 				return ec.fieldContext_Node_cpusAllocated(ctx, field) | ||||||
|  | 			case "memoryAllocated": | ||||||
|  | 				return ec.fieldContext_Node_memoryAllocated(ctx, field) | ||||||
|  | 			case "gpusAllocated": | ||||||
|  | 				return ec.fieldContext_Node_gpusAllocated(ctx, field) | ||||||
|  | 			case "schedulerState": | ||||||
|  | 				return ec.fieldContext_Node_schedulerState(ctx, field) | ||||||
| 			case "healthState": | 			case "healthState": | ||||||
| 				return ec.fieldContext_Node_healthState(ctx, field) | 				return ec.fieldContext_Node_healthState(ctx, field) | ||||||
| 			case "metaData": | 			case "metaData": | ||||||
| @@ -16666,7 +16830,7 @@ func (ec *executionContext) unmarshalInputNodeFilter(ctx context.Context, obj an | |||||||
| 		asMap[k] = v | 		asMap[k] = v | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fieldsInOrder := [...]string{"hostname", "cluster", "subcluster", "nodeState", "healthState"} | 	fieldsInOrder := [...]string{"hostname", "cluster", "subcluster", "schedulerState", "healthState"} | ||||||
| 	for _, k := range fieldsInOrder { | 	for _, k := range fieldsInOrder { | ||||||
| 		v, ok := asMap[k] | 		v, ok := asMap[k] | ||||||
| 		if !ok { | 		if !ok { | ||||||
| @@ -16694,16 +16858,16 @@ func (ec *executionContext) unmarshalInputNodeFilter(ctx context.Context, obj an | |||||||
| 				return it, err | 				return it, err | ||||||
| 			} | 			} | ||||||
| 			it.Subcluster = data | 			it.Subcluster = data | ||||||
| 		case "nodeState": | 		case "schedulerState": | ||||||
| 			ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("nodeState")) | 			ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("schedulerState")) | ||||||
| 			data, err := ec.unmarshalONodeState2ᚖstring(ctx, v) | 			data, err := ec.unmarshalOSchedulerState2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx, v) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return it, err | 				return it, err | ||||||
| 			} | 			} | ||||||
| 			it.NodeState = data | 			it.SchedulerState = data | ||||||
| 		case "healthState": | 		case "healthState": | ||||||
| 			ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("healthState")) | 			ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("healthState")) | ||||||
| 			data, err := ec.unmarshalOMonitoringState2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx, v) | 			data, err := ec.unmarshalOMonitoringState2ᚖstring(ctx, v) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return it, err | 				return it, err | ||||||
| 			} | 			} | ||||||
| @@ -18725,7 +18889,7 @@ func (ec *executionContext) _NamedStatsWithScope(ctx context.Context, sel ast.Se | |||||||
|  |  | ||||||
| var nodeImplementors = []string{"Node"} | var nodeImplementors = []string{"Node"} | ||||||
|  |  | ||||||
| func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj *model.Node) graphql.Marshaler { | func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj *schema.Node) graphql.Marshaler { | ||||||
| 	fields := graphql.CollectFields(ec.OperationContext, sel, nodeImplementors) | 	fields := graphql.CollectFields(ec.OperationContext, sel, nodeImplementors) | ||||||
|  |  | ||||||
| 	out := graphql.NewFieldSet(fields) | 	out := graphql.NewFieldSet(fields) | ||||||
| @@ -18735,10 +18899,41 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj | |||||||
| 		case "__typename": | 		case "__typename": | ||||||
| 			out.Values[i] = graphql.MarshalString("Node") | 			out.Values[i] = graphql.MarshalString("Node") | ||||||
| 		case "id": | 		case "id": | ||||||
| 			out.Values[i] = ec._Node_id(ctx, field, obj) | 			field := field | ||||||
| 			if out.Values[i] == graphql.Null { |  | ||||||
| 				atomic.AddUint32(&out.Invalids, 1) | 			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._Node_id(ctx, field, obj) | ||||||
|  | 				if res == graphql.Null { | ||||||
|  | 					atomic.AddUint32(&fs.Invalids, 1) | ||||||
|  | 				} | ||||||
|  | 				return res | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			if field.Deferrable != nil { | ||||||
|  | 				dfs, ok := deferred[field.Deferrable.Label] | ||||||
|  | 				di := 0 | ||||||
|  | 				if ok { | ||||||
|  | 					dfs.AddField(field) | ||||||
|  | 					di = len(dfs.Values) - 1 | ||||||
|  | 				} else { | ||||||
|  | 					dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) | ||||||
|  | 					deferred[field.Deferrable.Label] = dfs | ||||||
|  | 				} | ||||||
|  | 				dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { | ||||||
|  | 					return innerFunc(ctx, dfs) | ||||||
|  | 				}) | ||||||
|  |  | ||||||
|  | 				// don't run the out.Concurrently() call below | ||||||
|  | 				out.Values[i] = graphql.Null | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) | ||||||
| 		case "hostname": | 		case "hostname": | ||||||
| 			out.Values[i] = ec._Node_hostname(ctx, field, obj) | 			out.Values[i] = ec._Node_hostname(ctx, field, obj) | ||||||
| 			if out.Values[i] == graphql.Null { | 			if out.Values[i] == graphql.Null { | ||||||
| @@ -18754,12 +18949,18 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj | |||||||
| 			if out.Values[i] == graphql.Null { | 			if out.Values[i] == graphql.Null { | ||||||
| 				atomic.AddUint32(&out.Invalids, 1) | 				atomic.AddUint32(&out.Invalids, 1) | ||||||
| 			} | 			} | ||||||
| 		case "runningJobs": | 		case "jobsRunning": | ||||||
| 			out.Values[i] = ec._Node_runningJobs(ctx, field, obj) | 			out.Values[i] = ec._Node_jobsRunning(ctx, field, obj) | ||||||
| 			if out.Values[i] == graphql.Null { | 			if out.Values[i] == graphql.Null { | ||||||
| 				atomic.AddUint32(&out.Invalids, 1) | 				atomic.AddUint32(&out.Invalids, 1) | ||||||
| 			} | 			} | ||||||
| 		case "nodeState": | 		case "cpusAllocated": | ||||||
|  | 			out.Values[i] = ec._Node_cpusAllocated(ctx, field, obj) | ||||||
|  | 		case "memoryAllocated": | ||||||
|  | 			out.Values[i] = ec._Node_memoryAllocated(ctx, field, obj) | ||||||
|  | 		case "gpusAllocated": | ||||||
|  | 			out.Values[i] = ec._Node_gpusAllocated(ctx, field, obj) | ||||||
|  | 		case "schedulerState": | ||||||
| 			field := field | 			field := field | ||||||
|  |  | ||||||
| 			innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { | 			innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { | ||||||
| @@ -18768,7 +18969,7 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj | |||||||
| 						ec.Error(ctx, ec.Recover(ctx, r)) | 						ec.Error(ctx, ec.Recover(ctx, r)) | ||||||
| 					} | 					} | ||||||
| 				}() | 				}() | ||||||
| 				res = ec._Node_nodeState(ctx, field, obj) | 				res = ec._Node_schedulerState(ctx, field, obj) | ||||||
| 				if res == graphql.Null { | 				if res == graphql.Null { | ||||||
| 					atomic.AddUint32(&fs.Invalids, 1) | 					atomic.AddUint32(&fs.Invalids, 1) | ||||||
| 				} | 				} | ||||||
| @@ -21622,15 +21823,14 @@ func (ec *executionContext) marshalNMetricValue2githubᚗcomᚋClusterCockpitᚋ | |||||||
| 	return ec._MetricValue(ctx, sel, &v) | 	return ec._MetricValue(ctx, sel, &v) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) unmarshalNMonitoringState2githubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx context.Context, v any) (schema.SchedulerState, error) { | func (ec *executionContext) unmarshalNMonitoringState2string(ctx context.Context, v any) (string, error) { | ||||||
| 	tmp, err := graphql.UnmarshalString(v) | 	res, err := graphql.UnmarshalString(v) | ||||||
| 	res := schema.SchedulerState(tmp) |  | ||||||
| 	return res, graphql.ErrorOnPath(ctx, err) | 	return res, graphql.ErrorOnPath(ctx, err) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalNMonitoringState2githubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx context.Context, sel ast.SelectionSet, v schema.SchedulerState) graphql.Marshaler { | func (ec *executionContext) marshalNMonitoringState2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { | ||||||
| 	_ = sel | 	_ = sel | ||||||
| 	res := graphql.MarshalString(string(v)) | 	res := graphql.MarshalString(v) | ||||||
| 	if res == graphql.Null { | 	if res == graphql.Null { | ||||||
| 		if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { | 		if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { | ||||||
| 			ec.Errorf(ctx, "the requested element is null which the schema does not allow") | 			ec.Errorf(ctx, "the requested element is null which the schema does not allow") | ||||||
| @@ -21747,7 +21947,7 @@ func (ec *executionContext) marshalNNamedStatsWithScope2ᚖgithubᚗcomᚋCluste | |||||||
| 	return ec._NamedStatsWithScope(ctx, sel, v) | 	return ec._NamedStatsWithScope(ctx, sel, v) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalNNode2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNodeᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Node) graphql.Marshaler { | func (ec *executionContext) marshalNNode2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐNodeᚄ(ctx context.Context, sel ast.SelectionSet, v []*schema.Node) graphql.Marshaler { | ||||||
| 	ret := make(graphql.Array, len(v)) | 	ret := make(graphql.Array, len(v)) | ||||||
| 	var wg sync.WaitGroup | 	var wg sync.WaitGroup | ||||||
| 	isLen1 := len(v) == 1 | 	isLen1 := len(v) == 1 | ||||||
| @@ -21771,7 +21971,7 @@ func (ec *executionContext) marshalNNode2ᚕᚖgithubᚗcomᚋClusterCockpitᚋc | |||||||
| 			if !isLen1 { | 			if !isLen1 { | ||||||
| 				defer wg.Done() | 				defer wg.Done() | ||||||
| 			} | 			} | ||||||
| 			ret[i] = ec.marshalNNode2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNode(ctx, sel, v[i]) | 			ret[i] = ec.marshalNNode2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐNode(ctx, sel, v[i]) | ||||||
| 		} | 		} | ||||||
| 		if isLen1 { | 		if isLen1 { | ||||||
| 			f(i) | 			f(i) | ||||||
| @@ -21791,7 +21991,7 @@ func (ec *executionContext) marshalNNode2ᚕᚖgithubᚗcomᚋClusterCockpitᚋc | |||||||
| 	return ret | 	return ret | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalNNode2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNode(ctx context.Context, sel ast.SelectionSet, v *model.Node) graphql.Marshaler { | func (ec *executionContext) marshalNNode2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐNode(ctx context.Context, sel ast.SelectionSet, v *schema.Node) graphql.Marshaler { | ||||||
| 	if v == nil { | 	if v == nil { | ||||||
| 		if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { | 		if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { | ||||||
| 			ec.Errorf(ctx, "the requested element is null which the schema does not allow") | 			ec.Errorf(ctx, "the requested element is null which the schema does not allow") | ||||||
| @@ -21860,22 +22060,6 @@ func (ec *executionContext) marshalNNodeMetrics2ᚖgithubᚗcomᚋClusterCockpit | |||||||
| 	return ec._NodeMetrics(ctx, sel, v) | 	return ec._NodeMetrics(ctx, sel, v) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) unmarshalNNodeState2string(ctx context.Context, v any) (string, error) { |  | ||||||
| 	res, err := graphql.UnmarshalString(v) |  | ||||||
| 	return res, graphql.ErrorOnPath(ctx, err) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalNNodeState2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { |  | ||||||
| 	_ = sel |  | ||||||
| 	res := graphql.MarshalString(v) |  | ||||||
| 	if res == graphql.Null { |  | ||||||
| 		if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { |  | ||||||
| 			ec.Errorf(ctx, "the requested element is null which the schema does not allow") |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return res |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalNNodeStateResultList2githubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNodeStateResultList(ctx context.Context, sel ast.SelectionSet, v model.NodeStateResultList) graphql.Marshaler { | func (ec *executionContext) marshalNNodeStateResultList2githubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNodeStateResultList(ctx context.Context, sel ast.SelectionSet, v model.NodeStateResultList) graphql.Marshaler { | ||||||
| 	return ec._NodeStateResultList(ctx, sel, &v) | 	return ec._NodeStateResultList(ctx, sel, &v) | ||||||
| } | } | ||||||
| @@ -22052,6 +22236,23 @@ func (ec *executionContext) marshalNResource2ᚖgithubᚗcomᚋClusterCockpitᚋ | |||||||
| 	return ec._Resource(ctx, sel, v) | 	return ec._Resource(ctx, sel, v) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (ec *executionContext) unmarshalNSchedulerState2githubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx context.Context, v any) (schema.SchedulerState, error) { | ||||||
|  | 	tmp, err := graphql.UnmarshalString(v) | ||||||
|  | 	res := schema.SchedulerState(tmp) | ||||||
|  | 	return res, graphql.ErrorOnPath(ctx, err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ec *executionContext) marshalNSchedulerState2githubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx context.Context, sel ast.SelectionSet, v schema.SchedulerState) graphql.Marshaler { | ||||||
|  | 	_ = sel | ||||||
|  | 	res := graphql.MarshalString(string(v)) | ||||||
|  | 	if res == graphql.Null { | ||||||
|  | 		if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { | ||||||
|  | 			ec.Errorf(ctx, "the requested element is null which the schema does not allow") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return res | ||||||
|  | } | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalNScopedStats2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐScopedStatsᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.ScopedStats) graphql.Marshaler { | func (ec *executionContext) marshalNScopedStats2ᚕᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐScopedStatsᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.ScopedStats) graphql.Marshaler { | ||||||
| 	ret := make(graphql.Array, len(v)) | 	ret := make(graphql.Array, len(v)) | ||||||
| 	var wg sync.WaitGroup | 	var wg sync.WaitGroup | ||||||
| @@ -22910,6 +23111,18 @@ func (ec *executionContext) marshalOID2ᚕstringᚄ(ctx context.Context, sel ast | |||||||
| 	return ret | 	return ret | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (ec *executionContext) unmarshalOInt2int(ctx context.Context, v any) (int, error) { | ||||||
|  | 	res, err := graphql.UnmarshalInt(v) | ||||||
|  | 	return res, graphql.ErrorOnPath(ctx, err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ec *executionContext) marshalOInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { | ||||||
|  | 	_ = sel | ||||||
|  | 	_ = ctx | ||||||
|  | 	res := graphql.MarshalInt(v) | ||||||
|  | 	return res | ||||||
|  | } | ||||||
|  |  | ||||||
| func (ec *executionContext) unmarshalOInt2ᚕintᚄ(ctx context.Context, v any) ([]int, error) { | func (ec *executionContext) unmarshalOInt2ᚕintᚄ(ctx context.Context, v any) ([]int, error) { | ||||||
| 	if v == nil { | 	if v == nil { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| @@ -23217,26 +23430,25 @@ func (ec *executionContext) marshalOMetricStatistics2githubᚗcomᚋClusterCockp | |||||||
| 	return ec._MetricStatistics(ctx, sel, &v) | 	return ec._MetricStatistics(ctx, sel, &v) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) unmarshalOMonitoringState2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx context.Context, v any) (*schema.SchedulerState, error) { | func (ec *executionContext) unmarshalOMonitoringState2ᚖstring(ctx context.Context, v any) (*string, error) { | ||||||
| 	if v == nil { | 	if v == nil { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| 	tmp, err := graphql.UnmarshalString(v) | 	res, err := graphql.UnmarshalString(v) | ||||||
| 	res := schema.SchedulerState(tmp) |  | ||||||
| 	return &res, graphql.ErrorOnPath(ctx, err) | 	return &res, graphql.ErrorOnPath(ctx, err) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalOMonitoringState2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx context.Context, sel ast.SelectionSet, v *schema.SchedulerState) graphql.Marshaler { | func (ec *executionContext) marshalOMonitoringState2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { | ||||||
| 	if v == nil { | 	if v == nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| 	} | 	} | ||||||
| 	_ = sel | 	_ = sel | ||||||
| 	_ = ctx | 	_ = ctx | ||||||
| 	res := graphql.MarshalString(string(*v)) | 	res := graphql.MarshalString(*v) | ||||||
| 	return res | 	return res | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalONode2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐNode(ctx context.Context, sel ast.SelectionSet, v *model.Node) graphql.Marshaler { | func (ec *executionContext) marshalONode2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐNode(ctx context.Context, sel ast.SelectionSet, v *schema.Node) graphql.Marshaler { | ||||||
| 	if v == nil { | 	if v == nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
| 	} | 	} | ||||||
| @@ -23261,24 +23473,6 @@ func (ec *executionContext) unmarshalONodeFilter2ᚕᚖgithubᚗcomᚋClusterCoc | |||||||
| 	return res, nil | 	return res, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (ec *executionContext) unmarshalONodeState2ᚖstring(ctx context.Context, v any) (*string, error) { |  | ||||||
| 	if v == nil { |  | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 	res, err := graphql.UnmarshalString(v) |  | ||||||
| 	return &res, graphql.ErrorOnPath(ctx, err) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalONodeState2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { |  | ||||||
| 	if v == nil { |  | ||||||
| 		return graphql.Null |  | ||||||
| 	} |  | ||||||
| 	_ = sel |  | ||||||
| 	_ = ctx |  | ||||||
| 	res := graphql.MarshalString(*v) |  | ||||||
| 	return res |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (ec *executionContext) unmarshalOOrderByInput2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐOrderByInput(ctx context.Context, v any) (*model.OrderByInput, error) { | func (ec *executionContext) unmarshalOOrderByInput2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑbackendᚋinternalᚋgraphᚋmodelᚐOrderByInput(ctx context.Context, v any) (*model.OrderByInput, error) { | ||||||
| 	if v == nil { | 	if v == nil { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| @@ -23295,6 +23489,25 @@ func (ec *executionContext) unmarshalOPageRequest2ᚖgithubᚗcomᚋClusterCockp | |||||||
| 	return &res, graphql.ErrorOnPath(ctx, err) | 	return &res, graphql.ErrorOnPath(ctx, err) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (ec *executionContext) unmarshalOSchedulerState2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx context.Context, v any) (*schema.SchedulerState, error) { | ||||||
|  | 	if v == nil { | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  | 	tmp, err := graphql.UnmarshalString(v) | ||||||
|  | 	res := schema.SchedulerState(tmp) | ||||||
|  | 	return &res, graphql.ErrorOnPath(ctx, err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (ec *executionContext) marshalOSchedulerState2ᚖgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSchedulerState(ctx context.Context, sel ast.SelectionSet, v *schema.SchedulerState) graphql.Marshaler { | ||||||
|  | 	if v == nil { | ||||||
|  | 		return graphql.Null | ||||||
|  | 	} | ||||||
|  | 	_ = sel | ||||||
|  | 	_ = ctx | ||||||
|  | 	res := graphql.MarshalString(string(*v)) | ||||||
|  | 	return res | ||||||
|  | } | ||||||
|  |  | ||||||
| func (ec *executionContext) marshalOSeries2ᚕgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSeriesᚄ(ctx context.Context, sel ast.SelectionSet, v []schema.Series) graphql.Marshaler { | func (ec *executionContext) marshalOSeries2ᚕgithubᚗcomᚋClusterCockpitᚋccᚑlibᚋschemaᚐSeriesᚄ(ctx context.Context, sel ast.SelectionSet, v []schema.Series) graphql.Marshaler { | ||||||
| 	if v == nil { | 	if v == nil { | ||||||
| 		return graphql.Null | 		return graphql.Null | ||||||
|   | |||||||
| @@ -4,20 +4,3 @@ | |||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"github.com/ClusterCockpit/cc-lib/schema" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type Node struct { |  | ||||||
| 	ID              int64 |  | ||||||
| 	Hostname        string                 `json:"hostname"` |  | ||||||
| 	Cluster         string                 `json:"cluster"` |  | ||||||
| 	SubCluster      string                 `json:"subCluster"` |  | ||||||
| 	RunningJobs     int                    `json:"jobsRunning"` |  | ||||||
| 	CpusAllocated   int                    `json:"cpusAllocated"` |  | ||||||
| 	MemoryAllocated int                    `json:"memoryAllocated"` |  | ||||||
| 	GpusAllocated   int                    `json:"gpusAllocated"` |  | ||||||
| 	NodeState       schema.NodeState       `json:"nodeState"` |  | ||||||
| 	HealthState     schema.MonitoringState `json:"healthState"` |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -171,11 +171,11 @@ type NamedStatsWithScope struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| type NodeFilter struct { | type NodeFilter struct { | ||||||
| 	Hostname    *StringInput           `json:"hostname,omitempty"` | 	Hostname       *StringInput           `json:"hostname,omitempty"` | ||||||
| 	Cluster     *StringInput           `json:"cluster,omitempty"` | 	Cluster        *StringInput           `json:"cluster,omitempty"` | ||||||
| 	Subcluster  *StringInput           `json:"subcluster,omitempty"` | 	Subcluster     *StringInput           `json:"subcluster,omitempty"` | ||||||
| 	NodeState   *string                `json:"nodeState,omitempty"` | 	SchedulerState *schema.SchedulerState `json:"schedulerState,omitempty"` | ||||||
| 	HealthState *schema.SchedulerState `json:"healthState,omitempty"` | 	HealthState    *string                `json:"healthState,omitempty"` | ||||||
| } | } | ||||||
|  |  | ||||||
| type NodeMetrics struct { | type NodeMetrics struct { | ||||||
| @@ -185,8 +185,8 @@ type NodeMetrics struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| type NodeStateResultList struct { | type NodeStateResultList struct { | ||||||
| 	Items []*Node `json:"items"` | 	Items []*schema.Node `json:"items"` | ||||||
| 	Count *int    `json:"count,omitempty"` | 	Count *int           `json:"count,omitempty"` | ||||||
| } | } | ||||||
|  |  | ||||||
| type NodeStates struct { | type NodeStates struct { | ||||||
|   | |||||||
| @@ -305,18 +305,23 @@ func (r *mutationResolver) UpdateConfiguration(ctx context.Context, name string, | |||||||
| 	return nil, nil | 	return nil, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // NodeState is the resolver for the nodeState field. | // ID is the resolver for the id field. | ||||||
| func (r *nodeResolver) NodeState(ctx context.Context, obj *model.Node) (string, error) { | func (r *nodeResolver) ID(ctx context.Context, obj *schema.Node) (string, error) { | ||||||
| 	panic(fmt.Errorf("not implemented: NodeState - nodeState")) | 	panic(fmt.Errorf("not implemented: ID - id")) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SchedulerState is the resolver for the schedulerState field. | ||||||
|  | func (r *nodeResolver) SchedulerState(ctx context.Context, obj *schema.Node) (schema.SchedulerState, error) { | ||||||
|  | 	panic(fmt.Errorf("not implemented: SchedulerState - schedulerState")) | ||||||
| } | } | ||||||
|  |  | ||||||
| // HealthState is the resolver for the healthState field. | // HealthState is the resolver for the healthState field. | ||||||
| func (r *nodeResolver) HealthState(ctx context.Context, obj *model.Node) (schema.SchedulerState, error) { | func (r *nodeResolver) HealthState(ctx context.Context, obj *schema.Node) (string, error) { | ||||||
| 	panic(fmt.Errorf("not implemented: HealthState - healthState")) | 	panic(fmt.Errorf("not implemented: HealthState - healthState")) | ||||||
| } | } | ||||||
|  |  | ||||||
| // MetaData is the resolver for the metaData field. | // MetaData is the resolver for the metaData field. | ||||||
| func (r *nodeResolver) MetaData(ctx context.Context, obj *model.Node) (any, error) { | func (r *nodeResolver) MetaData(ctx context.Context, obj *schema.Node) (any, error) { | ||||||
| 	panic(fmt.Errorf("not implemented: MetaData - metaData")) | 	panic(fmt.Errorf("not implemented: MetaData - metaData")) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -360,7 +365,7 @@ func (r *queryResolver) AllocatedNodes(ctx context.Context, cluster string) ([]* | |||||||
| } | } | ||||||
|  |  | ||||||
| // Node is the resolver for the node field. | // Node is the resolver for the node field. | ||||||
| func (r *queryResolver) Node(ctx context.Context, id string) (*model.Node, error) { | func (r *queryResolver) Node(ctx context.Context, id string) (*schema.Node, error) { | ||||||
| 	panic(fmt.Errorf("not implemented: Node - node")) | 	panic(fmt.Errorf("not implemented: Node - node")) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -822,3 +827,15 @@ type mutationResolver struct{ *Resolver } | |||||||
| type nodeResolver struct{ *Resolver } | type nodeResolver struct{ *Resolver } | ||||||
| type queryResolver struct{ *Resolver } | type queryResolver struct{ *Resolver } | ||||||
| type subClusterResolver struct{ *Resolver } | type subClusterResolver struct{ *Resolver } | ||||||
|  |  | ||||||
|  | // !!! WARNING !!! | ||||||
|  | // The code below was going to be deleted when updating resolvers. It has been copied here so you have | ||||||
|  | // one last chance to move it out of harms way if you want. There are two reasons this happens: | ||||||
|  | //  - When renaming or deleting a resolver the old code will be put in here. You can safely delete | ||||||
|  | //    it when you're done. | ||||||
|  | //  - You have helper methods in this file. Move them out to keep these resolver files clean. | ||||||
|  | /* | ||||||
|  | 	func (r *nodeResolver) NodeState(ctx context.Context, obj *model.Node) (string, error) { | ||||||
|  | 	panic(fmt.Errorf("not implemented: NodeState - nodeState")) | ||||||
|  | } | ||||||
|  | */ | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| // All rights reserved. This file is part of cc-backend. | // All rights reserved. This file is part of cc-backend. | ||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package repository | package repository | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|   | |||||||
| @@ -10,7 +10,6 @@ import ( | |||||||
| 	"database/sql" | 	"database/sql" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"maps" |  | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| @@ -50,90 +49,91 @@ func GetNodeRepository() *NodeRepository { | |||||||
| 	return nodeRepoInstance | 	return nodeRepoInstance | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *NodeRepository) FetchMetadata(node *schema.Node) (map[string]string, error) { | func (r *NodeRepository) FetchMetadata(hostname string, cluster string) (map[string]string, error) { | ||||||
| 	start := time.Now() | 	start := time.Now() | ||||||
| 	cachekey := fmt.Sprintf("metadata:%d", node.ID) |  | ||||||
| 	if cached := r.cache.Get(cachekey, nil); cached != nil { |  | ||||||
| 		node.MetaData = cached.(map[string]string) |  | ||||||
| 		return node.MetaData, nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := sq.Select("node.meta_data").From("node").Where("node.id = ?", node.ID). | 	RawMetaData := make([]byte, 0) | ||||||
| 		RunWith(r.stmtCache).QueryRow().Scan(&node.RawMetaData); err != nil { |  | ||||||
|  | 	if err := sq.Select("node.meta_data").From("node"). | ||||||
|  | 		Where("node.hostname = ?", hostname). | ||||||
|  | 		Where("node.cluster = ?", cluster). | ||||||
|  | 		RunWith(r.stmtCache).QueryRow().Scan(&RawMetaData); err != nil { | ||||||
| 		cclog.Warn("Error while scanning for node metadata") | 		cclog.Warn("Error while scanning for node metadata") | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(node.RawMetaData) == 0 { | 	if len(RawMetaData) == 0 { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := json.Unmarshal(node.RawMetaData, &node.MetaData); err != nil { | 	MetaData := make(map[string]string) | ||||||
|  |  | ||||||
|  | 	if err := json.Unmarshal(RawMetaData, &MetaData); err != nil { | ||||||
| 		cclog.Warn("Error while unmarshaling raw metadata json") | 		cclog.Warn("Error while unmarshaling raw metadata json") | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	r.cache.Put(cachekey, node.MetaData, len(node.RawMetaData), 24*time.Hour) |  | ||||||
| 	cclog.Debugf("Timer FetchMetadata %s", time.Since(start)) | 	cclog.Debugf("Timer FetchMetadata %s", time.Since(start)) | ||||||
| 	return node.MetaData, nil | 	return MetaData, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *NodeRepository) UpdateMetadata(node *schema.Node, key, val string) (err error) { | // | ||||||
| 	cachekey := fmt.Sprintf("metadata:%d", node.ID) | // func (r *NodeRepository) UpdateMetadata(node *schema.Node, key, val string) (err error) { | ||||||
| 	r.cache.Del(cachekey) | // 	cachekey := fmt.Sprintf("metadata:%d", node.ID) | ||||||
| 	if node.MetaData == nil { | // 	r.cache.Del(cachekey) | ||||||
| 		if _, err = r.FetchMetadata(node); err != nil { | // 	if node.MetaData == nil { | ||||||
| 			cclog.Warnf("Error while fetching metadata for node, DB ID '%v'", node.ID) | // 		if _, err = r.FetchMetadata(node); err != nil { | ||||||
| 			return err | // 			cclog.Warnf("Error while fetching metadata for node, DB ID '%v'", node.ID) | ||||||
| 		} | // 			return err | ||||||
| 	} | // 		} | ||||||
|  | // 	} | ||||||
|  | // | ||||||
|  | // 	if node.MetaData != nil { | ||||||
|  | // 		cpy := make(map[string]string, len(node.MetaData)+1) | ||||||
|  | // 		maps.Copy(cpy, node.MetaData) | ||||||
|  | // 		cpy[key] = val | ||||||
|  | // 		node.MetaData = cpy | ||||||
|  | // 	} else { | ||||||
|  | // 		node.MetaData = map[string]string{key: val} | ||||||
|  | // 	} | ||||||
|  | // | ||||||
|  | // 	if node.RawMetaData, err = json.Marshal(node.MetaData); err != nil { | ||||||
|  | // 		cclog.Warnf("Error while marshaling metadata for node, DB ID '%v'", node.ID) | ||||||
|  | // 		return err | ||||||
|  | // 	} | ||||||
|  | // | ||||||
|  | // 	if _, err = sq.Update("node"). | ||||||
|  | // 		Set("meta_data", node.RawMetaData). | ||||||
|  | // 		Where("node.id = ?", node.ID). | ||||||
|  | // 		RunWith(r.stmtCache).Exec(); err != nil { | ||||||
|  | // 		cclog.Warnf("Error while updating metadata for node, DB ID '%v'", node.ID) | ||||||
|  | // 		return err | ||||||
|  | // 	} | ||||||
|  | // | ||||||
|  | // 	r.cache.Put(cachekey, node.MetaData, len(node.RawMetaData), 24*time.Hour) | ||||||
|  | // 	return nil | ||||||
|  | // } | ||||||
|  |  | ||||||
| 	if node.MetaData != nil { | func (r *NodeRepository) GetNode(hostname string, cluster string, withMeta bool) (*schema.Node, error) { | ||||||
| 		cpy := make(map[string]string, len(node.MetaData)+1) |  | ||||||
| 		maps.Copy(cpy, node.MetaData) |  | ||||||
| 		cpy[key] = val |  | ||||||
| 		node.MetaData = cpy |  | ||||||
| 	} else { |  | ||||||
| 		node.MetaData = map[string]string{key: val} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if node.RawMetaData, err = json.Marshal(node.MetaData); err != nil { |  | ||||||
| 		cclog.Warnf("Error while marshaling metadata for node, DB ID '%v'", node.ID) |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if _, err = sq.Update("node"). |  | ||||||
| 		Set("meta_data", node.RawMetaData). |  | ||||||
| 		Where("node.id = ?", node.ID). |  | ||||||
| 		RunWith(r.stmtCache).Exec(); err != nil { |  | ||||||
| 		cclog.Warnf("Error while updating metadata for node, DB ID '%v'", node.ID) |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	r.cache.Put(cachekey, node.MetaData, len(node.RawMetaData), 24*time.Hour) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *NodeRepository) GetNode(id int64, withMeta bool) (*schema.Node, error) { |  | ||||||
| 	node := &schema.Node{} | 	node := &schema.Node{} | ||||||
| 	// if err := sq.Select("id", "hostname", "cluster", "subcluster", "node_state", | 	if err := sq.Select("node.hostname", "node.cluster", "node.subcluster", "node_state.node_state", | ||||||
| 	// 	"health_state").From("node"). | 		"node_state.health_state", "MAX(node_state.time_stamp)").From("node_state"). | ||||||
| 	// 	Where("node.id = ?", id).RunWith(r.DB). | 		Join("node ON nodes_state.node_id = node.id").GroupBy("node_state.node_id"). | ||||||
| 	// 	QueryRow().Scan(&node.ID, &node.Hostname, &node.Cluster, &node.SubCluster, &node.NodeState, | 		Where("node.hostname = ?", hostname).Where("node.cluster = ?", cluster).RunWith(r.DB). | ||||||
| 	// 	&node.HealthState); err != nil { | 		QueryRow().Scan(&node.Hostname, &node.Cluster, &node.SubCluster, &node.NodeState, &node.HealthState); err != nil { | ||||||
| 	// 	cclog.Warnf("Error while querying node '%v' from database", id) | 		cclog.Warnf("Error while querying node '%s' from database: %v", hostname, err) | ||||||
| 	// 	return nil, err | 		return nil, err | ||||||
| 	// } | 	} | ||||||
| 	// |  | ||||||
| 	// if withMeta { | 	if withMeta { | ||||||
| 	// 	var err error | 		var err error | ||||||
| 	// 	var meta map[string]string | 		var meta map[string]string | ||||||
| 	// 	if meta, err = r.FetchMetadata(node); err != nil { | 		if meta, err = r.FetchMetadata(hostname, cluster); err != nil { | ||||||
| 	// 		cclog.Warnf("Error while fetching metadata for node '%v'", id) | 			cclog.Warnf("Error while fetching metadata for node '%s'", hostname) | ||||||
| 	// 		return nil, err | 			return nil, err | ||||||
| 	// 	} | 		} | ||||||
| 	// 	node.MetaData = meta | 		node.MetaData = meta | ||||||
| 	// } | 	} | ||||||
|  |  | ||||||
| 	return node, nil | 	return node, nil | ||||||
| } | } | ||||||
| @@ -151,7 +151,7 @@ INSERT INTO node (hostname, cluster, subcluster) | |||||||
|  |  | ||||||
| // AddNode adds a Node to the node table. This can be triggered by a node collector registration or | // AddNode adds a Node to the node table. This can be triggered by a node collector registration or | ||||||
| // from a nodestate update from the job scheduler. | // from a nodestate update from the job scheduler. | ||||||
| func (r *NodeRepository) AddNode(node *schema.Node) (int64, error) { | func (r *NodeRepository) AddNode(node *schema.NodeDB) (int64, error) { | ||||||
| 	var err error | 	var err error | ||||||
|  |  | ||||||
| 	res, err := r.DB.NamedExec(NamedNodeInsert, node) | 	res, err := r.DB.NamedExec(NamedNodeInsert, node) | ||||||
| @@ -168,30 +168,15 @@ func (r *NodeRepository) AddNode(node *schema.Node) (int64, error) { | |||||||
| 	return node.ID, nil | 	return node.ID, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *NodeRepository) InsertNodeState(nodeState *schema.Node) error { |  | ||||||
| 	subcluster, err := archive.GetSubClusterByNode(nodeState.Cluster, nodeState.Hostname) |  | ||||||
| 	if err != nil { |  | ||||||
| 		cclog.Errorf("Error while getting subcluster for node '%s' in cluster '%s': %v", nodeState.Hostname, nodeState.Cluster, err) |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	nodeState.SubCluster = subcluster |  | ||||||
|  |  | ||||||
| 	_, err = r.DB.NamedExec(NamedNodeInsert, nodeState) |  | ||||||
| 	if err != nil { |  | ||||||
| 		cclog.Errorf("Error while insert node '%v' to database", nodeState.Hostname) |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const NamedNodeStateInsert string = ` | const NamedNodeStateInsert string = ` | ||||||
| INSERT INTO node_state (time_stamp, node_state, health_state, cpus_allocated, | INSERT INTO node_state (time_stamp, node_state, health_state, cpus_allocated, | ||||||
| 	memory_allocated, gpus_allocated, jobs_running, node_id) | 	memory_allocated, gpus_allocated, jobs_running, node_id) | ||||||
| 	VALUES (:time_stamp, :node_state, :health_state, :cpus_allocated, :memory_allocated, :gpus_allocated, :jobs_running, :node_id);` | 	VALUES (:time_stamp, :node_state, :health_state, :cpus_allocated, :memory_allocated, :gpus_allocated, :jobs_running, :node_id);` | ||||||
|  |  | ||||||
| func (r *NodeRepository) UpdateNodeState(hostname string, cluster string, nodeState *schema.NodeState) error { | // TODO: Add real Monitoring Health State | ||||||
|  |  | ||||||
|  | // UpdateNodeState is called from the Node REST API to add a row in the node state table | ||||||
|  | func (r *NodeRepository) UpdateNodeState(hostname string, cluster string, nodeState *schema.NodeStateDB) error { | ||||||
| 	var id int64 | 	var id int64 | ||||||
|  |  | ||||||
| 	if err := sq.Select("id").From("node"). | 	if err := sq.Select("id").From("node"). | ||||||
| @@ -203,7 +188,7 @@ func (r *NodeRepository) UpdateNodeState(hostname string, cluster string, nodeSt | |||||||
| 				cclog.Errorf("Error while getting subcluster for node '%s' in cluster '%s': %v", hostname, cluster, err) | 				cclog.Errorf("Error while getting subcluster for node '%s' in cluster '%s': %v", hostname, cluster, err) | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 			node := schema.Node{ | 			node := schema.NodeDB{ | ||||||
| 				Hostname: hostname, Cluster: cluster, SubCluster: subcluster, | 				Hostname: hostname, Cluster: cluster, SubCluster: subcluster, | ||||||
| 			} | 			} | ||||||
| 			id, err = r.AddNode(&node) | 			id, err = r.AddNode(&node) | ||||||
| @@ -220,6 +205,8 @@ func (r *NodeRepository) UpdateNodeState(hostname string, cluster string, nodeSt | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	nodeState.NodeID = id | ||||||
|  |  | ||||||
| 	_, err := r.DB.NamedExec(NamedNodeStateInsert, nodeState) | 	_, err := r.DB.NamedExec(NamedNodeStateInsert, nodeState) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		cclog.Errorf("Error while adding node state for '%v' to database", hostname) | 		cclog.Errorf("Error while adding node state for '%v' to database", hostname) | ||||||
| @@ -254,9 +241,11 @@ func (r *NodeRepository) QueryNodes( | |||||||
| 	ctx context.Context, | 	ctx context.Context, | ||||||
| 	filters []*model.NodeFilter, | 	filters []*model.NodeFilter, | ||||||
| 	order *model.OrderByInput, // Currently unused! | 	order *model.OrderByInput, // Currently unused! | ||||||
| ) ([]*model.Node, error) { | ) ([]*schema.Node, error) { | ||||||
| 	query, qerr := AccessCheck(ctx, | 	query, qerr := AccessCheck(ctx, | ||||||
| 		sq.Select("node.hostname", "node.cluster", "node.subcluster", "node_state.node_state", "node_state.health_state", "MAX(node_state.time_stamp)").From("node_state").Join("node ON nodes_state.node_id = node.id").GroupBy("node_state.node_id")) | 		sq.Select("node.hostname", "node.cluster", "node.subcluster", "node_state.node_state", | ||||||
|  | 			"node_state.health_state", "MAX(node_state.time_stamp)").From("node_state"). | ||||||
|  | 			Join("node ON nodes_state.node_id = node.id").GroupBy("node_state.node_id")) | ||||||
| 	if qerr != nil { | 	if qerr != nil { | ||||||
| 		return nil, qerr | 		return nil, qerr | ||||||
| 	} | 	} | ||||||
| @@ -271,8 +260,8 @@ func (r *NodeRepository) QueryNodes( | |||||||
| 		if f.Subcluster != nil { | 		if f.Subcluster != nil { | ||||||
| 			query = buildStringCondition("node.subcluster", f.Subcluster, query) | 			query = buildStringCondition("node.subcluster", f.Subcluster, query) | ||||||
| 		} | 		} | ||||||
| 		if f.NodeState != nil { | 		if f.SchedulerState != nil { | ||||||
| 			query = query.Where("node.node_state = ?", f.NodeState) | 			query = query.Where("node.node_state = ?", f.SchedulerState) | ||||||
| 		} | 		} | ||||||
| 		if f.HealthState != nil { | 		if f.HealthState != nil { | ||||||
| 			query = query.Where("node.health_state = ?", f.HealthState) | 			query = query.Where("node.health_state = ?", f.HealthState) | ||||||
| @@ -286,9 +275,9 @@ func (r *NodeRepository) QueryNodes( | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	nodes := make([]*model.Node, 0, 50) | 	nodes := make([]*schema.Node, 0, 50) | ||||||
| 	for rows.Next() { | 	for rows.Next() { | ||||||
| 		node := model.Node{} | 		node := schema.Node{} | ||||||
|  |  | ||||||
| 		if err := rows.Scan(&node.Hostname, &node.Cluster, &node.SubCluster, | 		if err := rows.Scan(&node.Hostname, &node.Cluster, &node.SubCluster, | ||||||
| 			&node.NodeState, &node.HealthState); err != nil { | 			&node.NodeState, &node.HealthState); err != nil { | ||||||
|   | |||||||
							
								
								
									
										190
									
								
								internal/repository/node_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								internal/repository/node_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | |||||||
|  | // Copyright (C) NHR@FAU, University Erlangen-Nuremberg. | ||||||
|  | // All rights reserved. This file is part of cc-backend. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package repository | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/ClusterCockpit/cc-backend/internal/config" | ||||||
|  | 	"github.com/ClusterCockpit/cc-backend/pkg/archive" | ||||||
|  | 	ccconf "github.com/ClusterCockpit/cc-lib/ccConfig" | ||||||
|  | 	cclog "github.com/ClusterCockpit/cc-lib/ccLogger" | ||||||
|  | 	"github.com/ClusterCockpit/cc-lib/schema" | ||||||
|  | 	_ "github.com/mattn/go-sqlite3" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func nodeTestSetup(t *testing.T) { | ||||||
|  | 	const testconfig = `{ | ||||||
|  | 		"main": { | ||||||
|  | 	"addr":            "0.0.0.0:8080", | ||||||
|  | 	"validate": false, | ||||||
|  |   "apiAllowedIPs": [ | ||||||
|  |     "*" | ||||||
|  |   ] | ||||||
|  | 	}, | ||||||
|  | 	"archive": { | ||||||
|  | 		"kind": "file", | ||||||
|  | 		"path": "./var/job-archive" | ||||||
|  | 	}, | ||||||
|  | 	"auth": { | ||||||
|  |   "jwts": { | ||||||
|  |       "max-age": "2m" | ||||||
|  |   } | ||||||
|  | 	}, | ||||||
|  | 	"clusters": [ | ||||||
|  | 	{ | ||||||
|  | 	   "name": "testcluster", | ||||||
|  | 	   "metricDataRepository": {"kind": "test", "url": "bla:8081"}, | ||||||
|  | 	   "filterRanges": { | ||||||
|  | 		"numNodes": { "from": 1, "to": 64 }, | ||||||
|  | 		"duration": { "from": 0, "to": 86400 }, | ||||||
|  | 		"startTime": { "from": "2022-01-01T00:00:00Z", "to": null } | ||||||
|  | 	   } | ||||||
|  | 	} | ||||||
|  | 	] | ||||||
|  | }` | ||||||
|  | 	const testclusterJSON = `{ | ||||||
|  |         "name": "testcluster", | ||||||
|  | 		"subClusters": [ | ||||||
|  | 			{ | ||||||
|  | 				"name": "sc1", | ||||||
|  | 				"nodes": "host123,host124,host125", | ||||||
|  | 				"processorType": "Intel Core i7-4770", | ||||||
|  | 				"socketsPerNode": 1, | ||||||
|  | 				"coresPerSocket": 4, | ||||||
|  | 				"threadsPerCore": 2, | ||||||
|  |                 "flopRateScalar": { | ||||||
|  |                   "unit": { | ||||||
|  |                     "prefix": "G", | ||||||
|  |                     "base": "F/s" | ||||||
|  |                   }, | ||||||
|  |                   "value": 14 | ||||||
|  |                 }, | ||||||
|  |                 "flopRateSimd": { | ||||||
|  |                   "unit": { | ||||||
|  |                     "prefix": "G", | ||||||
|  |                     "base": "F/s" | ||||||
|  |                   }, | ||||||
|  |                   "value": 112 | ||||||
|  |                 }, | ||||||
|  |                 "memoryBandwidth": { | ||||||
|  |                   "unit": { | ||||||
|  |                     "prefix": "G", | ||||||
|  |                     "base": "B/s" | ||||||
|  |                   }, | ||||||
|  |                   "value": 24 | ||||||
|  |                 }, | ||||||
|  |                 "numberOfNodes": 70, | ||||||
|  | 				"topology": { | ||||||
|  | 					"node": [0, 1, 2, 3, 4, 5, 6, 7], | ||||||
|  | 					"socket": [[0, 1, 2, 3, 4, 5, 6, 7]], | ||||||
|  | 					"memoryDomain": [[0, 1, 2, 3, 4, 5, 6, 7]], | ||||||
|  | 					"die": [[0, 1, 2, 3, 4, 5, 6, 7]], | ||||||
|  | 					"core": [[0], [1], [2], [3], [4], [5], [6], [7]] | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		], | ||||||
|  | 		"metricConfig": [ | ||||||
|  | 			{ | ||||||
|  | 				"name": "load_one", | ||||||
|  | 			    "unit": { "base": ""}, | ||||||
|  | 				"scope": "node", | ||||||
|  | 				"timestep": 60, | ||||||
|  |         "aggregation": "avg", | ||||||
|  | 				"peak": 8, | ||||||
|  | 				"normal": 0, | ||||||
|  | 				"caution": 0, | ||||||
|  | 				"alert": 0 | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}` | ||||||
|  |  | ||||||
|  | 	cclog.Init("debug", true) | ||||||
|  | 	tmpdir := t.TempDir() | ||||||
|  | 	jobarchive := filepath.Join(tmpdir, "job-archive") | ||||||
|  | 	if err := os.Mkdir(jobarchive, 0o777); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := os.WriteFile(filepath.Join(jobarchive, "version.txt"), | ||||||
|  | 		fmt.Appendf(nil, "%d", 2), 0o666); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := os.Mkdir(filepath.Join(jobarchive, "testcluster"), | ||||||
|  | 		0o777); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := os.WriteFile(filepath.Join(jobarchive, "testcluster", "cluster.json"), | ||||||
|  | 		[]byte(testclusterJSON), 0o666); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbfilepath := filepath.Join(tmpdir, "test.db") | ||||||
|  | 	err := MigrateDB("sqlite3", dbfilepath) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	cfgFilePath := filepath.Join(tmpdir, "config.json") | ||||||
|  | 	if err := os.WriteFile(cfgFilePath, []byte(testconfig), 0o666); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ccconf.Init(cfgFilePath) | ||||||
|  |  | ||||||
|  | 	// Load and check main configuration | ||||||
|  | 	if cfg := ccconf.GetPackageConfig("main"); cfg != nil { | ||||||
|  | 		if clustercfg := ccconf.GetPackageConfig("clusters"); clustercfg != nil { | ||||||
|  | 			config.Init(cfg, clustercfg) | ||||||
|  | 		} else { | ||||||
|  | 			cclog.Abort("Cluster configuration must be present") | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		cclog.Abort("Main configuration must be present") | ||||||
|  | 	} | ||||||
|  | 	archiveCfg := fmt.Sprintf("{\"kind\": \"file\",\"path\": \"%s\"}", jobarchive) | ||||||
|  |  | ||||||
|  | 	Connect("sqlite3", dbfilepath) | ||||||
|  |  | ||||||
|  | 	if err := archive.Init(json.RawMessage(archiveCfg), config.Keys.DisableArchive); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestUpdateNodeState(t *testing.T) { | ||||||
|  | 	nodeTestSetup(t) | ||||||
|  |  | ||||||
|  | 	nodeState := schema.NodeStateDB{ | ||||||
|  | 		TimeStamp: time.Now().Unix(), NodeState: "allocated", | ||||||
|  | 		CpusAllocated:   72, | ||||||
|  | 		MemoryAllocated: 480, | ||||||
|  | 		GpusAllocated:   0, | ||||||
|  | 		HealthState:     schema.MonitoringStateFull, | ||||||
|  | 		JobsRunning:     1, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	repo := GetNodeRepository() | ||||||
|  | 	err := repo.UpdateNodeState("host124", "testcluster", &nodeState) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	node, err := repo.GetNode("host124", "testcluster", false) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if node.NodeState != "allocated" { | ||||||
|  | 		t.Errorf("wrong node state\ngot: %s \nwant: allocated ", node.NodeState) | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user