Skip to content

Commit

Permalink
Merge pull request #268 from ClusterCockpit/hotfix
Browse files Browse the repository at this point in the history
Hotfix
  • Loading branch information
moebiusband73 authored Jun 14, 2024
2 parents 0b2f221 + 70e6376 commit e1c1c06
Show file tree
Hide file tree
Showing 14 changed files with 201 additions and 128 deletions.
9 changes: 6 additions & 3 deletions cmd/cc-backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ const configString = `
"kind": "file",
"path": "./var/job-archive"
},
"jwts": {
"max-age": "2000h"
},
"clusters": [
{
"name": "name",
Expand Down Expand Up @@ -115,15 +118,15 @@ func initEnv() {
os.Exit(0)
}

if err := os.WriteFile("config.json", []byte(configString), 0666); err != nil {
if err := os.WriteFile("config.json", []byte(configString), 0o666); err != nil {
log.Fatalf("Writing config.json failed: %s", err.Error())
}

if err := os.WriteFile(".env", []byte(envString), 0666); err != nil {
if err := os.WriteFile(".env", []byte(envString), 0o666); err != nil {
log.Fatalf("Writing .env failed: %s", err.Error())
}

if err := os.Mkdir("var", 0777); err != nil {
if err := os.Mkdir("var", 0o777); err != nil {
log.Fatalf("Mkdir var failed: %s", err.Error())
}

Expand Down
4 changes: 2 additions & 2 deletions internal/metricdata/metricdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ func LoadData(job *schema.Job,
jd, err = repo.LoadData(job, metrics, scopes, ctx)
if err != nil {
if len(jd) != 0 {
log.Errorf("partial error: %s", err.Error())
return err, 0, 0
log.Warnf("partial error: %s", err.Error())
// return err, 0, 0 // Reactivating will block archiving on one partial error
} else {
log.Error("Error while loading job data from metric repository")
return err, 0, 0
Expand Down
6 changes: 3 additions & 3 deletions internal/repository/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ func (r *JobRepository) archivingWorker() {
// not using meta data, called to load JobMeta into Cache?
// will fail if job meta not in repository
if _, err := r.FetchMetadata(job); err != nil {
log.Errorf("archiving job (dbid: %d) failed: %s", job.ID, err.Error())
log.Errorf("archiving job (dbid: %d) failed at check metadata step: %s", job.ID, err.Error())
r.UpdateMonitoringStatus(job.ID, schema.MonitoringStatusArchivingFailed)
continue
}
Expand All @@ -529,14 +529,14 @@ func (r *JobRepository) archivingWorker() {
// TODO: Maybe use context with cancel/timeout here
jobMeta, err := metricdata.ArchiveJob(job, context.Background())
if err != nil {
log.Errorf("archiving job (dbid: %d) failed: %s", job.ID, err.Error())
log.Errorf("archiving job (dbid: %d) failed at archiving job step: %s", job.ID, err.Error())
r.UpdateMonitoringStatus(job.ID, schema.MonitoringStatusArchivingFailed)
continue
}

// Update the jobs database entry one last time:
if err := r.MarkArchived(job.ID, schema.MonitoringStatusArchivingSuccessful, jobMeta.Statistics); err != nil {
log.Errorf("archiving job (dbid: %d) failed: %s", job.ID, err.Error())
log.Errorf("archiving job (dbid: %d) failed at marking archived step: %s", job.ID, err.Error())
continue
}
log.Debugf("archiving job %d took %s", job.JobID, time.Since(start))
Expand Down
3 changes: 3 additions & 0 deletions internal/repository/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ func buildStringCondition(field string, cond *model.StringInput, query sq.Select
}

func buildMetaJsonCondition(jsonField string, cond *model.StringInput, query sq.SelectBuilder) sq.SelectBuilder {
// Verify and Search Only in Valid Jsons
query = query.Where("JSON_VALID(meta_data)")
// add "AND" Sql query Block for field match
if cond.Eq != nil {
return query.Where("JSON_EXTRACT(meta_data, \"$."+jsonField+"\") = ?", *cond.Eq)
}
Expand Down
18 changes: 15 additions & 3 deletions internal/routerConfig/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,19 @@ func HandleSearchBar(rw http.ResponseWriter, r *http.Request, buildInfo web.Buil
case "jobId":
http.Redirect(rw, r, "/monitoring/jobs/?jobId="+url.QueryEscape(strings.Trim(splitSearch[1], " ")), http.StatusFound) // All Users: Redirect to Tablequery
case "jobName":
http.Redirect(rw, r, "/monitoring/jobs/?jobName="+url.QueryEscape(strings.Trim(splitSearch[1], " ")), http.StatusFound) // All Users: Redirect to Tablequery
// Add Last 30 Days to migitate timeouts
untilTime := strconv.FormatInt(time.Now().Unix(), 10)
fromTime := strconv.FormatInt((time.Now().Unix() - int64(30*24*3600)), 10)

http.Redirect(rw, r, "/monitoring/jobs/?startTime="+fromTime+"-"+untilTime+"&jobName="+url.QueryEscape(strings.Trim(splitSearch[1], " ")), http.StatusFound) // All Users: Redirect to Tablequery
case "projectId":
http.Redirect(rw, r, "/monitoring/jobs/?projectMatch=eq&project="+url.QueryEscape(strings.Trim(splitSearch[1], " ")), http.StatusFound) // All Users: Redirect to Tablequery
case "arrayJobId":
http.Redirect(rw, r, "/monitoring/jobs/?arrayJobId="+url.QueryEscape(strings.Trim(splitSearch[1], " ")), http.StatusFound) // All Users: Redirect to Tablequery
// Add Last 30 Days to migitate timeouts
untilTime := strconv.FormatInt(time.Now().Unix(), 10)
fromTime := strconv.FormatInt((time.Now().Unix() - int64(30*24*3600)), 10)

http.Redirect(rw, r, "/monitoring/jobs/?startTime="+fromTime+"-"+untilTime+"&arrayJobId="+url.QueryEscape(strings.Trim(splitSearch[1], " ")), http.StatusFound) // All Users: Redirect to Tablequery
case "username":
if user.HasAnyRole([]schema.Role{schema.RoleAdmin, schema.RoleSupport, schema.RoleManager}) {
http.Redirect(rw, r, "/monitoring/users/?user="+url.QueryEscape(strings.Trim(splitSearch[1], " ")), http.StatusFound)
Expand Down Expand Up @@ -339,7 +347,11 @@ func HandleSearchBar(rw http.ResponseWriter, r *http.Request, buildInfo web.Buil
} else if project != "" {
http.Redirect(rw, r, "/monitoring/jobs/?projectMatch=eq&project="+url.QueryEscape(project), http.StatusFound) // projectId (equal)
} else if jobname != "" {
http.Redirect(rw, r, "/monitoring/jobs/?jobName="+url.QueryEscape(jobname), http.StatusFound) // JobName (contains)
// Add Last 30 Days to migitate timeouts
untilTime := strconv.FormatInt(time.Now().Unix(), 10)
fromTime := strconv.FormatInt((time.Now().Unix() - int64(30*24*3600)), 10)

http.Redirect(rw, r, "/monitoring/jobs/?startTime="+fromTime+"-"+untilTime+"&jobName="+url.QueryEscape(jobname), http.StatusFound) // 30D Fitler + JobName (contains)
} else {
web.RenderTemplate(rw, "message.tmpl", &web.Page{Title: "Info", MsgType: "alert-info", Message: "Search without result", User: *user, Roles: availableRoles, Build: buildInfo})
}
Expand Down
6 changes: 2 additions & 4 deletions web/frontend/src/Job.root.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,11 @@
.find((c) => c.name == job.cluster)
.metricConfig.map((mc) => mc.name);
// Metric not found in JobMetrics && Metric not explicitly disabled: Was expected, but is Missing
// Metric not found in JobMetrics && Metric not explicitly disabled in config or deselected: Was expected, but is Missing
missingMetrics = metricNames.filter(
(metric) =>
!metrics.some((jm) => jm.name == metric) &&
selectedMetrics.includes(metric) &&
!checkMetricDisabled(
metric,
$initq.data.job.cluster,
Expand Down Expand Up @@ -306,9 +307,6 @@
</Button>
{/if}
</Col>
<!-- <Col xs="auto">
<Zoom timeseriesPlots={plots} />
</Col> -->
</Row>
<Row>
<Col>
Expand Down
6 changes: 4 additions & 2 deletions web/frontend/src/Jobs.root.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import Refresher from "./joblist/Refresher.svelte";
import Sorting from "./joblist/SortSelection.svelte";
import MetricSelection from "./MetricSelection.svelte";
import UserOrProject from "./filters/UserOrProject.svelte";
import TextFilter from "./filters/TextFilter.svelte";
const { query: initq } = init();
Expand All @@ -38,6 +38,7 @@
? !!ccconfig[`plot_list_showFootprint:${filterPresets.cluster}`]
: !!ccconfig.plot_list_showFootprint;
let selectedCluster = filterPresets?.cluster ? filterPresets.cluster : null;
let presetProject = filterPresets?.project ? filterPresets.project : ""
// The filterPresets are handled by the Filters component,
// so we need to wait for it to be ready before we can start a query.
Expand Down Expand Up @@ -86,7 +87,8 @@
</Col>
<Col xs="3" style="margin-left: auto;">
<UserOrProject
<TextFilter
{presetProject}
bind:authlevel
bind:roles
on:update={({ detail }) => filterComponent.update(detail)}
Expand Down
37 changes: 33 additions & 4 deletions web/frontend/src/Metric.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,17 @@
error = null;
let selectedScope = minScope(scopes);
let statsPattern = /(.*)-stats$/
let statsSeries = rawData.map((data) => data?.statisticsSeries ? data.statisticsSeries : null)
let selectedScopeIndex
$: availableScopes = scopes;
$: selectedScopeIndex = scopes.findIndex((s) => s == selectedScope);
$: patternMatches = statsPattern.exec(selectedScope)
$: if (!patternMatches) {
selectedScopeIndex = scopes.findIndex((s) => s == selectedScope);
} else {
selectedScopeIndex = scopes.findIndex((s) => s == patternMatches[1]);
}
$: data = rawData[selectedScopeIndex];
$: series = data?.series.filter(
(series) => selectedHost == null || series.hostname == selectedHost,
Expand Down Expand Up @@ -62,6 +71,7 @@
if (jm.scope != "node") {
scopes = [...scopes, jm.scope];
rawData.push(jm.metric);
statsSeries = rawData.map((data) => data?.statisticsSeries ? data.statisticsSeries : null)
selectedScope = jm.scope;
selectedScopeIndex = scopes.findIndex((s) => s == jm.scope);
dispatch("more-loaded", jm);
Expand All @@ -79,15 +89,18 @@
: "") + (metricConfig?.unit?.base ? metricConfig.unit.base : "")})
</InputGroupText>
<select class="form-select" bind:value={selectedScope}>
{#each availableScopes as scope}
{#each availableScopes as scope, index}
<option value={scope}>{scope}</option>
{#if statsSeries[index]}
<option value={scope + '-stats'}>stats series ({scope})</option>
{/if}
{/each}
{#if availableScopes.length == 1 && metricConfig?.scope != "node"}
<option value={"load-more"}>Load more...</option>
{/if}
</select>
{#if job.resources.length > 1}
<select class="form-select" bind:value={selectedHost}>
<select class="form-select" bind:value={selectedHost} disabled={patternMatches}>
<option value={null}>All Hosts</option>
{#each job.resources as { hostname }}
<option value={hostname}>{hostname}</option>
Expand All @@ -100,7 +113,21 @@
<Spinner />
{:else if error != null}
<Card body color="danger">{error.message}</Card>
{:else if series != null}
{:else if series != null && !patternMatches}
<Timeseries
bind:this={plot}
{width}
height={300}
{cluster}
{subCluster}
timestep={data.timestep}
scope={selectedScope}
metric={metricName}
{series}
{isShared}
resources={job.resources}
/>
{:else if statsSeries[selectedScopeIndex] != null && patternMatches}
<Timeseries
bind:this={plot}
{width}
Expand All @@ -113,6 +140,8 @@
{series}
{isShared}
resources={job.resources}
statisticsSeries={statsSeries[selectedScopeIndex]}
useStatsSeries={!!statsSeries[selectedScopeIndex]}
/>
{/if}
{/key}
44 changes: 23 additions & 21 deletions web/frontend/src/Status.root.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -315,20 +315,11 @@
<!-- Loading indicator & Refresh -->
<Row cols={3}>
<Col xs="auto" style="align-self: flex-end;">
<Row cols={{ lg: 3, md: 3, sm: 1 }}>
<Col style="">
<h4 class="mb-0">Current utilization of cluster "{cluster}"</h4>
</Col>
<Col xs="auto" style="margin-left: 0.25rem;">
{#if $initq.fetching || $mainQuery.fetching}
<Spinner />
{:else if $initq.error}
<Card body color="danger">{$initq.error.message}</Card>
{:else}
<!-- ... -->
{/if}
</Col>
<Col xs="auto" style="margin-left: auto;">
<Col class="mt-2 mt-md-0 text-md-end">
<Button
outline
color="secondary"
Expand All @@ -337,7 +328,7 @@
<Icon name="bar-chart-line" /> Select Histograms
</Button>
</Col>
<Col xs="auto" style="margin-left: 0.25rem;">
<Col class="mt-2 mt-md-0">
<Refresher
initially={120}
on:reload={() => {
Expand All @@ -347,6 +338,17 @@
/>
</Col>
</Row>
<Row cols={1} class="text-center mt-3">
<Col>
{#if $initq.fetching || $mainQuery.fetching}
<Spinner />
{:else if $initq.error}
<Card body color="danger">{$initq.error.message}</Card>
{:else}
<!-- ... -->
{/if}
</Col>
</Row>
{#if $mainQuery.error}
<Row cols={1}>
<Col>
Expand All @@ -361,8 +363,8 @@
{#if $initq.data && $mainQuery.data}
{#each $initq.data.clusters.find((c) => c.name == cluster).subClusters as subCluster, i}
<Row cols={2} class="mb-3 justify-content-center">
<Col md="4" class="px-3">
<Row cols={{ lg: 2, md: 1 , sm: 1}} class="mb-3 justify-content-center">
<Col class="px-3">
<Card class="h-auto mt-1">
<CardHeader>
<CardTitle class="mb-0">SubCluster "{subCluster.name}"</CardTitle>
Expand Down Expand Up @@ -433,7 +435,7 @@
</CardBody>
</Card>
</Col>
<Col class="px-3">
<Col class="px-3 mt-2 mt-lg-0">
<div bind:clientWidth={plotWidths[i]}>
{#key $mainQuery.data.nodeMetrics}
<Roofline
Expand All @@ -457,7 +459,7 @@
<!-- Usage Stats as Histograms -->
<Row cols={4}>
<Row cols={{ lg: 4, md: 2, sm: 1 }}>
<Col class="p-2">
<div bind:clientWidth={colWidth1}>
<h4 class="text-center">
Expand Down Expand Up @@ -580,7 +582,7 @@
</Col>
</Row>
<hr class="my-2" />
<Row cols={2}>
<Row cols={{ lg: 2, md: 1 }}>
<Col class="p-2">
<div bind:clientWidth={colWidth2}>
{#key $mainQuery.data.stats}
Expand Down Expand Up @@ -610,7 +612,7 @@
{/key}
</Col>
</Row>
<Row cols={2}>
<Row cols={{ lg: 2, md: 1 }}>
<Col class="p-2">
<div bind:clientWidth={colWidth2}>
{#key $mainQuery.data.stats}
Expand Down Expand Up @@ -642,15 +644,15 @@
</Row>
<hr class="my-2" />
{#if metricsInHistograms}
<Row>
<Row cols={1}>
<Col>
{#key $mainQuery.data.stats[0].histMetrics}
<PlotTable
let:item
let:width
renderFor="user"
items={$mainQuery.data.stats[0].histMetrics}
itemsPerRow={3}
itemsPerRow={2}
>
<Histogram
data={convert2uplot(item.data)}
Expand Down
6 changes: 6 additions & 0 deletions web/frontend/src/User.root.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
} from "@sveltestrap/sveltestrap";
import { queryStore, gql, getContextClient } from "@urql/svelte";
import Filters from "./filters/Filters.svelte";
import TextFilter from "./filters/TextFilter.svelte"
import JobList from "./joblist/JobList.svelte";
import Sorting from "./joblist/SortSelection.svelte";
import Refresher from "./joblist/Refresher.svelte";
Expand Down Expand Up @@ -132,6 +133,11 @@
/>
</Col>
<Col xs="auto" style="margin-left: auto;">
<TextFilter
on:update={({ detail }) => filterComponent.update(detail)}
/>
</Col>
<Col xs="auto">
<Refresher on:reload={() => jobList.refresh()} />
</Col>
</Row>
Expand Down
2 changes: 1 addition & 1 deletion web/frontend/src/config/admin/ShowUsersRow.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

<td>{user.username}</td>
<td>{user.name}</td>
<td>{user.projects}</td>
<td style="max-width: 200px;">{user.projects}</td>
<td>{user.email}</td>
<td><code>{user?.roles ? user.roles.join(", ") : "No Roles"}</code></td>
<td>
Expand Down
3 changes: 2 additions & 1 deletion web/frontend/src/filters/Filters.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@
opts.push(`userMatch=${filters.userMatch}`);
if (filters.project) opts.push(`project=${filters.project}`);
if (filters.jobName) opts.push(`jobName=${filters.jobName}`);
if (filters.projectMatch != "contains")
if (filters.arrayJobId) opts.push(`arrayJobId=${filters.arrayJobId}`);
if (filters.project && filters.projectMatch != "contains")
opts.push(`projectMatch=${filters.projectMatch}`);
if (opts.length == 0 && window.location.search.length <= 1) return;
Expand Down
Loading

0 comments on commit e1c1c06

Please sign in to comment.