mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-10-02 20:54:32 +02:00
Refactor variable namings and doc comments
This commit is contained in:
@@ -185,7 +185,7 @@ func serverInit() {
|
||||
})
|
||||
|
||||
securedapi.Use(func(next http.Handler) http.Handler {
|
||||
return authHandle.AuthApi(
|
||||
return authHandle.AuthAPI(
|
||||
// On success;
|
||||
next,
|
||||
// On failure: JSON Response
|
||||
@@ -193,7 +193,7 @@ func serverInit() {
|
||||
})
|
||||
|
||||
userapi.Use(func(next http.Handler) http.Handler {
|
||||
return authHandle.AuthUserApi(
|
||||
return authHandle.AuthUserAPI(
|
||||
// On success;
|
||||
next,
|
||||
// On failure: JSON Response
|
||||
@@ -201,7 +201,7 @@ func serverInit() {
|
||||
})
|
||||
|
||||
metricstoreapi.Use(func(next http.Handler) http.Handler {
|
||||
return authHandle.AuthMetricStoreApi(
|
||||
return authHandle.AuthMetricStoreAPI(
|
||||
// On success;
|
||||
next,
|
||||
// On failure: JSON Response
|
||||
@@ -209,7 +209,7 @@ func serverInit() {
|
||||
})
|
||||
|
||||
configapi.Use(func(next http.Handler) http.Handler {
|
||||
return authHandle.AuthConfigApi(
|
||||
return authHandle.AuthConfigAPI(
|
||||
// On success;
|
||||
next,
|
||||
// On failure: JSON Response
|
||||
@@ -217,7 +217,7 @@ func serverInit() {
|
||||
})
|
||||
|
||||
frontendapi.Use(func(next http.Handler) http.Handler {
|
||||
return authHandle.AuthFrontendApi(
|
||||
return authHandle.AuthFrontendAPI(
|
||||
// On success;
|
||||
next,
|
||||
// On failure: JSON Response
|
||||
@@ -255,7 +255,7 @@ func serverInit() {
|
||||
router.PathPrefix("/img/").Handler(http.StripPrefix("/img/", http.FileServer(http.Dir("./var/img"))))
|
||||
}
|
||||
}
|
||||
router.PathPrefix("/").Handler(web.ServeFiles())
|
||||
router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", web.ServeFiles()))
|
||||
} else {
|
||||
router.PathPrefix("/").Handler(http.FileServer(http.Dir(config.Keys.StaticFiles)))
|
||||
}
|
||||
@@ -267,6 +267,35 @@ func serverInit() {
|
||||
handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization", "Origin"}),
|
||||
handlers.AllowedMethods([]string{"GET", "POST", "HEAD", "OPTIONS"}),
|
||||
handlers.AllowedOrigins([]string{"*"})))
|
||||
|
||||
secured.NotFoundHandler = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
page := web.Page{
|
||||
Title: "ClusterCockpit - Not Found",
|
||||
Build: buildInfo,
|
||||
}
|
||||
rw.Header().Add("Content-Type", "text/html; charset=utf-8")
|
||||
web.RenderTemplate(rw, "404.tmpl", &page)
|
||||
})
|
||||
|
||||
// secured.NotFoundHandler = http.HandlerFunc(http.NotFound)
|
||||
// router.NotFoundHandler = router.NewRoute().HandlerFunc(http.NotFound).GetHandler()
|
||||
|
||||
// printEndpoints(router)
|
||||
}
|
||||
|
||||
func printEndpoints(r *mux.Router) {
|
||||
r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
|
||||
path, err := route.GetPathTemplate()
|
||||
if err != nil {
|
||||
path = "nopath"
|
||||
}
|
||||
methods, err := route.GetMethods()
|
||||
if err != nil {
|
||||
methods = append(methods, "nomethod")
|
||||
}
|
||||
fmt.Printf("%v %s\n", methods, path)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func serverStart() {
|
||||
@@ -339,7 +368,7 @@ func serverShutdown() {
|
||||
// First shut down the server gracefully (waiting for all ongoing requests)
|
||||
server.Shutdown(context.Background())
|
||||
|
||||
//Archive all the metric store data
|
||||
// Archive all the metric store data
|
||||
if config.InternalCCMSFlag {
|
||||
memorystore.Shutdown()
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@
|
||||
// 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 auth implements various authentication methods
|
||||
package auth
|
||||
|
||||
import (
|
||||
@@ -338,7 +340,7 @@ func (auth *Authentication) Auth(
|
||||
})
|
||||
}
|
||||
|
||||
func (auth *Authentication) AuthApi(
|
||||
func (auth *Authentication) AuthAPI(
|
||||
onsuccess http.Handler,
|
||||
onfailure func(rw http.ResponseWriter, r *http.Request, authErr error),
|
||||
) http.Handler {
|
||||
@@ -381,7 +383,7 @@ func (auth *Authentication) AuthApi(
|
||||
})
|
||||
}
|
||||
|
||||
func (auth *Authentication) AuthUserApi(
|
||||
func (auth *Authentication) AuthUserAPI(
|
||||
onsuccess http.Handler,
|
||||
onfailure func(rw http.ResponseWriter, r *http.Request, authErr error),
|
||||
) http.Handler {
|
||||
@@ -417,7 +419,7 @@ func (auth *Authentication) AuthUserApi(
|
||||
})
|
||||
}
|
||||
|
||||
func (auth *Authentication) AuthMetricStoreApi(
|
||||
func (auth *Authentication) AuthMetricStoreAPI(
|
||||
onsuccess http.Handler,
|
||||
onfailure func(rw http.ResponseWriter, r *http.Request, authErr error),
|
||||
) http.Handler {
|
||||
@@ -453,7 +455,7 @@ func (auth *Authentication) AuthMetricStoreApi(
|
||||
})
|
||||
}
|
||||
|
||||
func (auth *Authentication) AuthConfigApi(
|
||||
func (auth *Authentication) AuthConfigAPI(
|
||||
onsuccess http.Handler,
|
||||
onfailure func(rw http.ResponseWriter, r *http.Request, authErr error),
|
||||
) http.Handler {
|
||||
@@ -474,7 +476,7 @@ func (auth *Authentication) AuthConfigApi(
|
||||
})
|
||||
}
|
||||
|
||||
func (auth *Authentication) AuthFrontendApi(
|
||||
func (auth *Authentication) AuthFrontendAPI(
|
||||
onsuccess http.Handler,
|
||||
onfailure func(rw http.ResponseWriter, r *http.Request, authErr error),
|
||||
) http.Handler {
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 auth
|
||||
|
||||
import (
|
||||
@@ -135,7 +136,7 @@ func (ja *JWTAuthenticator) AuthViaJWT(
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Generate a new JWT that can be used for authentication
|
||||
// ProvideJWT generates a new JWT that can be used for authentication
|
||||
func (ja *JWTAuthenticator) ProvideJWT(user *schema.User) (string, error) {
|
||||
if ja.privateKey == nil {
|
||||
return "", errors.New("environment variable 'JWT_PRIVATE_KEY' not set")
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 auth
|
||||
|
||||
import (
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 auth
|
||||
|
||||
import (
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 auth
|
||||
|
||||
import (
|
||||
@@ -18,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
type LdapConfig struct {
|
||||
Url string `json:"url"`
|
||||
URL string `json:"url"`
|
||||
UserBase string `json:"user_base"`
|
||||
SearchDN string `json:"search_dn"`
|
||||
UserBind string `json:"user_bind"`
|
||||
@@ -130,7 +131,7 @@ func (la *LdapAuthenticator) Login(
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
userDn := strings.Replace(Keys.LdapConfig.UserBind, "{username}", user.Username, -1)
|
||||
userDn := strings.ReplaceAll(Keys.LdapConfig.UserBind, "{username}", user.Username)
|
||||
if err := l.Bind(userDn, r.FormValue("password")); err != nil {
|
||||
cclog.Errorf("AUTH/LDAP > Authentication for user %s failed: %v",
|
||||
user.Username, err)
|
||||
@@ -141,9 +142,9 @@ func (la *LdapAuthenticator) Login(
|
||||
}
|
||||
|
||||
func (la *LdapAuthenticator) Sync() error {
|
||||
const IN_DB int = 1
|
||||
const IN_LDAP int = 2
|
||||
const IN_BOTH int = 3
|
||||
const InDB int = 1
|
||||
const InLdap int = 2
|
||||
const InBoth int = 3
|
||||
ur := repository.GetUserRepository()
|
||||
lc := Keys.LdapConfig
|
||||
|
||||
@@ -154,7 +155,7 @@ func (la *LdapAuthenticator) Sync() error {
|
||||
}
|
||||
|
||||
for _, username := range usernames {
|
||||
users[username] = IN_DB
|
||||
users[username] = InDB
|
||||
}
|
||||
|
||||
l, err := la.getLdapConnection(true)
|
||||
@@ -183,18 +184,18 @@ func (la *LdapAuthenticator) Sync() error {
|
||||
|
||||
_, ok := users[username]
|
||||
if !ok {
|
||||
users[username] = IN_LDAP
|
||||
users[username] = InLdap
|
||||
newnames[username] = entry.GetAttributeValue(la.UserAttr)
|
||||
} else {
|
||||
users[username] = IN_BOTH
|
||||
users[username] = InBoth
|
||||
}
|
||||
}
|
||||
|
||||
for username, where := range users {
|
||||
if where == IN_DB && lc.SyncDelOldUsers {
|
||||
if where == InDB && lc.SyncDelOldUsers {
|
||||
ur.DelUser(username)
|
||||
cclog.Debugf("sync: remove %v (does not show up in LDAP anymore)", username)
|
||||
} else if where == IN_LDAP {
|
||||
} else if where == InLdap {
|
||||
name := newnames[username]
|
||||
|
||||
var roles []string
|
||||
@@ -222,7 +223,7 @@ func (la *LdapAuthenticator) Sync() error {
|
||||
|
||||
func (la *LdapAuthenticator) getLdapConnection(admin bool) (*ldap.Conn, error) {
|
||||
lc := Keys.LdapConfig
|
||||
conn, err := ldap.DialURL(lc.Url)
|
||||
conn, err := ldap.DialURL(lc.URL)
|
||||
if err != nil {
|
||||
cclog.Warn("LDAP URL dial failed")
|
||||
return nil, err
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 auth
|
||||
|
||||
import (
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 auth
|
||||
|
||||
import (
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 auth
|
||||
|
||||
var configSchema = `
|
||||
|
@@ -2,6 +2,8 @@
|
||||
// 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 config implements the program configuration data structures, validation and parsing
|
||||
package config
|
||||
|
||||
import (
|
||||
@@ -12,20 +14,12 @@ import (
|
||||
cclog "github.com/ClusterCockpit/cc-lib/ccLogger"
|
||||
)
|
||||
|
||||
type ResampleConfig struct {
|
||||
// Array of resampling target resolutions, in seconds; Example: [600,300,60]
|
||||
Resolutions []int `json:"resolutions"`
|
||||
// Trigger next zoom level at less than this many visible datapoints
|
||||
Trigger int `json:"trigger"`
|
||||
}
|
||||
|
||||
// Format of the configuration (file). See below for the defaults.
|
||||
type ProgramConfig struct {
|
||||
// Address where the http (or https) server will listen on (for example: 'localhost:80').
|
||||
Addr string `json:"addr"`
|
||||
|
||||
// Addresses from which secured admin API endpoints can be reached, can be wildcard "*"
|
||||
ApiAllowedIPs []string `json:"apiAllowedIPs"`
|
||||
APIAllowedIPs []string `json:"apiAllowedIPs"`
|
||||
|
||||
// Drop root permissions once .env was read and the port was taken.
|
||||
User string `json:"user"`
|
||||
@@ -59,16 +53,12 @@ type ProgramConfig struct {
|
||||
SessionMaxAge string `json:"session-max-age"`
|
||||
|
||||
// If both those options are not empty, use HTTPS using those certificates.
|
||||
HttpsCertFile string `json:"https-cert-file"`
|
||||
HttpsKeyFile string `json:"https-key-file"`
|
||||
HTTPSCertFile string `json:"https-cert-file"`
|
||||
HTTPSKeyFile string `json:"https-key-file"`
|
||||
|
||||
// If not the empty string and `addr` does not end in ":80",
|
||||
// redirect every request incoming at port 80 to that url.
|
||||
RedirectHttpTo string `json:"redirect-http-to"`
|
||||
|
||||
// If overwritten, at least all the options in the defaults below must
|
||||
// be provided! Most options here can be overwritten by the user.
|
||||
UiDefaults map[string]any `json:"ui-defaults"`
|
||||
RedirectHTTPTo string `json:"redirect-http-to"`
|
||||
|
||||
// Where to store MachineState files
|
||||
MachineStateDir string `json:"machine-state-dir"`
|
||||
@@ -87,6 +77,13 @@ type ProgramConfig struct {
|
||||
EnableResampling *ResampleConfig `json:"resampling"`
|
||||
}
|
||||
|
||||
type ResampleConfig struct {
|
||||
// Array of resampling target resolutions, in seconds; Example: [600,300,60]
|
||||
Resolutions []int `json:"resolutions"`
|
||||
// Trigger next zoom level at less than this many visible datapoints
|
||||
Trigger int `json:"trigger"`
|
||||
}
|
||||
|
||||
type IntRange struct {
|
||||
From int `json:"from"`
|
||||
To int `json:"to"`
|
||||
@@ -123,28 +120,6 @@ var Keys ProgramConfig = ProgramConfig{
|
||||
SessionMaxAge: "168h",
|
||||
StopJobsExceedingWalltime: 0,
|
||||
ShortRunningJobsDuration: 5 * 60,
|
||||
UiDefaults: map[string]any{
|
||||
"analysis_view_histogramMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
||||
"analysis_view_scatterPlotMetrics": [][]string{{"flops_any", "mem_bw"}, {"flops_any", "cpu_load"}, {"cpu_load", "mem_bw"}},
|
||||
"job_view_nodestats_selectedMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
||||
"job_view_selectedMetrics": []string{"flops_any", "mem_bw", "mem_used"},
|
||||
"job_view_showFootprint": true,
|
||||
"job_list_usePaging": false,
|
||||
"plot_general_colorBackground": true,
|
||||
"plot_general_colorscheme": []string{"#00bfff", "#0000ff", "#ff00ff", "#ff0000", "#ff8000", "#ffff00", "#80ff00"},
|
||||
"plot_general_lineWidth": 3,
|
||||
"plot_list_jobsPerPage": 50,
|
||||
"plot_list_selectedMetrics": []string{"cpu_load", "mem_used", "flops_any", "mem_bw"},
|
||||
"plot_view_plotsPerRow": 3,
|
||||
"plot_view_showPolarplot": true,
|
||||
"plot_view_showRoofline": true,
|
||||
"plot_view_showStatTable": true,
|
||||
"system_view_selectedMetric": "cpu_load",
|
||||
"analysis_view_selectedTopEntity": "user",
|
||||
"analysis_view_selectedTopCategory": "totalWalltime",
|
||||
"status_view_selectedTopUserCategory": "totalJobs",
|
||||
"status_view_selectedTopProjectCategory": "totalJobs",
|
||||
},
|
||||
}
|
||||
|
||||
func Init(mainConfig json.RawMessage, clusterConfig json.RawMessage) {
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
|
@@ -10,9 +10,6 @@ import (
|
||||
|
||||
var InternalCCMSFlag bool = false
|
||||
|
||||
// --------------------
|
||||
// Metric Store config
|
||||
// --------------------
|
||||
type MetricStoreConfig struct {
|
||||
Checkpoints struct {
|
||||
FileFormat string `json:"file-format"`
|
||||
@@ -41,7 +38,7 @@ type NatsConfig struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
|
||||
//Creds file path
|
||||
// Creds file path
|
||||
Credsfilepath string `json:"creds-file-path"`
|
||||
|
||||
Subscriptions []struct {
|
||||
@@ -55,7 +52,7 @@ type NatsConfig struct {
|
||||
|
||||
var MetricStoreKeys MetricStoreConfig
|
||||
|
||||
// For aggregation over multiple values at different cpus/sockets/..., not time!
|
||||
// AggregationStrategy for aggregation over multiple values at different cpus/sockets/..., not time!
|
||||
type AggregationStrategy int
|
||||
|
||||
const (
|
||||
@@ -93,7 +90,7 @@ var Metrics map[string]MetricConfig
|
||||
func InitMetricStore(msConfig json.RawMessage) {
|
||||
// Validate(msConfigSchema, msConfig)
|
||||
dec := json.NewDecoder(bytes.NewReader(msConfig))
|
||||
dec.DisallowUnknownFields()
|
||||
// dec.DisallowUnknownFields()
|
||||
if err := dec.Decode(&MetricStoreKeys); err != nil {
|
||||
cclog.Abortf("[METRICSTORE]> Metric Store Config Init: Could not decode config file '%s'.\nError: %s\n", msConfig, err.Error())
|
||||
}
|
||||
@@ -106,11 +103,10 @@ func GetMetricFrequency(metricName string) (int64, error) {
|
||||
return 0, fmt.Errorf("[METRICSTORE]> metric %s not found", metricName)
|
||||
}
|
||||
|
||||
// add logic to add metrics. Redundant metrics should be updated with max frequency.
|
||||
// AddMetric adds logic to add metrics. Redundant metrics should be updated with max frequency.
|
||||
// use metric.Name to check if the metric already exists.
|
||||
// if not, add it to the Metrics map.
|
||||
func AddMetric(name string, metric MetricConfig) error {
|
||||
|
||||
if Metrics == nil {
|
||||
Metrics = make(map[string]MetricConfig, 0)
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 config
|
||||
|
||||
var configSchema = `
|
||||
@@ -119,177 +120,6 @@ var configSchema = `
|
||||
"required": ["apiAllowedIPs"]
|
||||
}`
|
||||
|
||||
var uiConfigSchema = `
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"jobList": {
|
||||
"description": "Job list defaults. Applies to user- and jobs views.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"usePaging": {
|
||||
"description": "If classic paging is used instead of continuous scrolling by default.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"showFootprint": {
|
||||
"description": "If footprint bars are shown as first column by default.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": ["usePaging", "showFootprint"]
|
||||
},
|
||||
"nodeList": {
|
||||
"description": "Node list defaults. Applies to node list view.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"usePaging": {
|
||||
"description": "If classic paging is used instead of continuous scrolling by default.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": ["usePaging"]
|
||||
},
|
||||
"jobView": {
|
||||
"description": "Job view defaults.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"showPolarPlot": {
|
||||
"description": "If the job metric footprints polar plot is shown by default.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"showFootprint": {
|
||||
"description": "If the annotated job metric footprint bars are shown by default.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"showRoofline": {
|
||||
"description": "If the job roofline plot is shown by default.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"showStatTable": {
|
||||
"description": "If the job metric statistics table is shown by default.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": ["showFootprint"]
|
||||
},
|
||||
"metricConfig": {
|
||||
"description": "Global initial metric selections for primary views of all clusters.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"jobListMetrics": {
|
||||
"description": "Initial metrics shown for new users in job lists (User and jobs view).",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"jobViewPlotMetrics": {
|
||||
"description": "Initial metrics shown for new users as job view metric plots.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"jobViewTableMetrics": {
|
||||
"description": "Initial metrics shown for new users in job view statistics table.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"clusters": {
|
||||
"description": "Overrides for global defaults by cluster and subcluster.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "The name of the cluster.",
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"enum": ["influxdb", "prometheus", "cc-metric-store", "cc-metric-store-internal", "test"]
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"subClusters" {
|
||||
"description": "The array of overrides per subcluster.",
|
||||
"type":"array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "The name of the subcluster.",
|
||||
"type": "string"
|
||||
},
|
||||
"jobListMetrics": {
|
||||
"description": "Initial metrics shown for new users in job lists (User and jobs view) for subcluster.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"jobViewPlotMetrics": {
|
||||
"description": "Initial metrics shown for new users as job view timeplots for subcluster.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"jobViewTableMetrics": {
|
||||
"description": "Initial metrics shown for new users in job view statistics table for subcluster.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minItems": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["name"],
|
||||
"minItems": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["name", "subClusters"],
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["jobListMetrics", "jobViewPlotMetrics", "jobViewTableMetrics"]
|
||||
}
|
||||
},
|
||||
"plotConfiguration": {
|
||||
"description": "Initial settings for plot render options.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"colorBackground": {
|
||||
"description": "If the metric plot backgrounds are initially colored by threshold limits.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"plotsPerRow": {
|
||||
"description": "How many plots are initially rendered in per row. Applies to job, single node, and analysis views.",
|
||||
"type": "integer"
|
||||
},
|
||||
"lineWidth": {
|
||||
"description": "Initial thickness of rendered plotlines. Applies to metric plot, job compare plot and roofline.",
|
||||
"type": "integer"
|
||||
},
|
||||
"colorScheme": {
|
||||
"description": "Initial colorScheme to be used for metric plots.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["colorBackground", "plotsPerRow", "lineWidth"]
|
||||
}
|
||||
}`
|
||||
|
||||
var clustersSchema = `
|
||||
{
|
||||
"type": "array",
|
||||
@@ -306,7 +136,7 @@ var clustersSchema = `
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"enum": ["influxdb", "prometheus", "cc-metric-store", "test"]
|
||||
"enum": ["influxdb", "prometheus", "cc-metric-store", "cc-metric-store-internal", "test"]
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
@@ -315,7 +145,7 @@ var clustersSchema = `
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["kind", "url"]
|
||||
"required": ["kind"]
|
||||
},
|
||||
"filterRanges": {
|
||||
"description": "This option controls the slider ranges for the UI controls of numNodes, duration, and startTime.",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 config
|
||||
|
||||
import (
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 metricdata
|
||||
|
||||
import (
|
||||
@@ -33,12 +34,10 @@ type CCMetricStoreConfigInternal struct {
|
||||
}
|
||||
|
||||
// Bloat Code
|
||||
type CCMetricStoreInternal struct {
|
||||
}
|
||||
type CCMetricStoreInternal struct{}
|
||||
|
||||
// Bloat Code
|
||||
func (ccms *CCMetricStoreInternal) Init(rawConfig json.RawMessage) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 metricdata
|
||||
|
||||
import (
|
||||
@@ -17,7 +18,7 @@ var TestLoadDataCallback func(job *schema.Job, metrics []string, scopes []schema
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
// Only a mock for unit-testing.
|
||||
// TestMetricDataRepository is only a mock for unit-testing.
|
||||
type TestMetricDataRepository struct{}
|
||||
|
||||
func (tmdr *TestMetricDataRepository) Init(_ json.RawMessage) error {
|
||||
@@ -73,11 +74,10 @@ func (tmdr *TestMetricDataRepository) LoadNodeListData(
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
func DeepCopy(jd_temp schema.JobData) schema.JobData {
|
||||
|
||||
jd := make(schema.JobData, len(jd_temp))
|
||||
for k, v := range jd_temp {
|
||||
jd[k] = make(map[schema.MetricScope]*schema.JobMetric, len(jd_temp[k]))
|
||||
func DeepCopy(jdTemp schema.JobData) schema.JobData {
|
||||
jd := make(schema.JobData, len(jdTemp))
|
||||
for k, v := range jdTemp {
|
||||
jd[k] = make(map[schema.MetricScope]*schema.JobMetric, len(jdTemp[k]))
|
||||
for k_, v_ := range v {
|
||||
jd[k][k_] = new(schema.JobMetric)
|
||||
jd[k][k_].Series = make([]schema.Series, len(v_.Series))
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 archive
|
||||
|
||||
var configSchema = `
|
||||
|
@@ -2,6 +2,8 @@
|
||||
// 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 archive implements the job archive interface and various backend implementations
|
||||
package archive
|
||||
|
||||
import (
|
||||
@@ -108,7 +110,6 @@ func GetHandle() ArchiveBackend {
|
||||
return ar
|
||||
}
|
||||
|
||||
// Helper to metricdataloader.LoadAverages().
|
||||
func LoadAveragesFromArchive(
|
||||
job *schema.Job,
|
||||
metrics []string,
|
||||
@@ -131,7 +132,6 @@ func LoadAveragesFromArchive(
|
||||
return nil
|
||||
}
|
||||
|
||||
// Helper to metricdataloader.LoadJobStats().
|
||||
func LoadStatsFromArchive(
|
||||
job *schema.Job,
|
||||
metrics []string,
|
||||
@@ -160,7 +160,6 @@ func LoadStatsFromArchive(
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Helper to metricdataloader.LoadScopedJobStats().
|
||||
func LoadScopedStatsFromArchive(
|
||||
job *schema.Job,
|
||||
metrics []string,
|
||||
@@ -185,7 +184,7 @@ func GetStatistics(job *schema.Job) (map[string]schema.JobStatistics, error) {
|
||||
return metaFile.Statistics, nil
|
||||
}
|
||||
|
||||
// If the job is archived, find its `meta.json` file and override the Metadata
|
||||
// UpdateMetadata checks if the job is archived, find its `meta.json` file and override the Metadata
|
||||
// in that JSON file. If the job is not archived, nothing is done.
|
||||
func UpdateMetadata(job *schema.Job, metadata map[string]string) error {
|
||||
mutex.Lock()
|
||||
@@ -206,7 +205,7 @@ func UpdateMetadata(job *schema.Job, metadata map[string]string) error {
|
||||
return ar.StoreJobMeta(jobMeta)
|
||||
}
|
||||
|
||||
// If the job is archived, find its `meta.json` file and override the tags list
|
||||
// UpdateTags checks if the job is archived, find its `meta.json` file and override the tags list
|
||||
// in that JSON file. If the job is not archived, nothing is done.
|
||||
func UpdateTags(job *schema.Job, tags []*schema.Tag) error {
|
||||
mutex.Lock()
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 archive
|
||||
|
||||
import (
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 archive
|
||||
|
||||
import (
|
||||
@@ -336,7 +337,7 @@ func (fsa *FsArchive) Move(jobs []*schema.Job, path string) {
|
||||
source := getDirectory(job, fsa.path)
|
||||
target := getDirectory(job, path)
|
||||
|
||||
if err := os.MkdirAll(filepath.Clean(filepath.Join(target, "..")), 0777); err != nil {
|
||||
if err := os.MkdirAll(filepath.Clean(filepath.Join(target, "..")), 0o777); err != nil {
|
||||
cclog.Errorf("JobArchive Move MkDir error: %v", err)
|
||||
}
|
||||
if err := os.Rename(source, target); err != nil {
|
||||
@@ -395,7 +396,7 @@ func (fsa *FsArchive) CompressLast(starttime int64) int64 {
|
||||
b, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
cclog.Errorf("fsBackend Compress - %v", err)
|
||||
os.WriteFile(filename, []byte(fmt.Sprintf("%d", starttime)), 0644)
|
||||
os.WriteFile(filename, fmt.Appendf(nil, "%d", starttime), 0o644)
|
||||
return starttime
|
||||
}
|
||||
last, err := strconv.ParseInt(strings.TrimSuffix(string(b), "\n"), 10, 64)
|
||||
@@ -405,12 +406,12 @@ func (fsa *FsArchive) CompressLast(starttime int64) int64 {
|
||||
}
|
||||
|
||||
cclog.Infof("fsBackend Compress - start %d last %d", starttime, last)
|
||||
os.WriteFile(filename, []byte(fmt.Sprintf("%d", starttime)), 0644)
|
||||
os.WriteFile(filename, fmt.Appendf(nil, "%d", starttime), 0o644)
|
||||
return last
|
||||
}
|
||||
|
||||
func (fsa *FsArchive) LoadJobData(job *schema.Job) (schema.JobData, error) {
|
||||
var isCompressed bool = true
|
||||
isCompressed := true
|
||||
filename := getPath(job, fsa.path, "data.json.gz")
|
||||
|
||||
if !util.CheckFileExists(filename) {
|
||||
@@ -422,7 +423,7 @@ func (fsa *FsArchive) LoadJobData(job *schema.Job) (schema.JobData, error) {
|
||||
}
|
||||
|
||||
func (fsa *FsArchive) LoadJobStats(job *schema.Job) (schema.ScopedJobStats, error) {
|
||||
var isCompressed bool = true
|
||||
isCompressed := true
|
||||
filename := getPath(job, fsa.path, "data.json.gz")
|
||||
|
||||
if !util.CheckFileExists(filename) {
|
||||
@@ -495,7 +496,7 @@ func (fsa *FsArchive) Iter(loadMetricData bool) <-chan JobContainer {
|
||||
}
|
||||
|
||||
if loadMetricData {
|
||||
var isCompressed bool = true
|
||||
isCompressed := true
|
||||
filename := filepath.Join(dirpath, startTimeDir.Name(), "data.json.gz")
|
||||
|
||||
if !util.CheckFileExists(filename) {
|
||||
@@ -549,7 +550,7 @@ func (fsa *FsArchive) ImportJob(
|
||||
jobData *schema.JobData,
|
||||
) error {
|
||||
dir := getPath(jobMeta, fsa.path, "")
|
||||
if err := os.MkdirAll(dir, 0777); err != nil {
|
||||
if err := os.MkdirAll(dir, 0o777); err != nil {
|
||||
cclog.Error("Error while creating job archive path")
|
||||
return err
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 archive
|
||||
|
||||
import (
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
func DecodeJobData(r io.Reader, k string) (schema.JobData, error) {
|
||||
data := cache.Get(k, func() (value interface{}, ttl time.Duration, size int) {
|
||||
data := cache.Get(k, func() (value any, ttl time.Duration, size int) {
|
||||
var d schema.JobData
|
||||
if err := json.NewDecoder(r).Decode(&d); err != nil {
|
||||
cclog.Warn("Error while decoding raw job data json")
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 archive
|
||||
|
||||
import (
|
||||
@@ -79,8 +80,8 @@ type NLExprString string
|
||||
|
||||
func (nle NLExprString) consume(input string) (next string, ok bool) {
|
||||
str := string(nle)
|
||||
if strings.HasPrefix(input, str) {
|
||||
return strings.TrimPrefix(input, str), true
|
||||
if after, ok0 := strings.CutPrefix(input, str); ok0 {
|
||||
return after, true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// 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 archive
|
||||
|
||||
type S3ArchiveConfig struct {
|
||||
|
Reference in New Issue
Block a user