Merge branch 'master' into dev

This commit is contained in:
Jan Eitzinger 2025-03-20 12:51:23 +01:00
commit d6b132e3a6
4 changed files with 45 additions and 46 deletions

View File

@ -2,7 +2,7 @@ TARGET = ./cc-backend
VAR = ./var VAR = ./var
CFG = config.json .env CFG = config.json .env
FRONTEND = ./web/frontend FRONTEND = ./web/frontend
VERSION = 1.4.2 VERSION = 1.4.3
GIT_HASH := $(shell git rev-parse --short HEAD || echo 'development') GIT_HASH := $(shell git rev-parse --short HEAD || echo 'development')
CURRENT_TIME = $(shell date +"%Y-%m-%d:T%H:%M:%S") CURRENT_TIME = $(shell date +"%Y-%m-%d:T%H:%M:%S")
LD_FLAGS = '-s -X main.date=${CURRENT_TIME} -X main.version=${VERSION} -X main.commit=${GIT_HASH}' LD_FLAGS = '-s -X main.date=${CURRENT_TIME} -X main.version=${VERSION} -X main.commit=${GIT_HASH}'

View File

@ -1,12 +1,12 @@
# `cc-backend` version 1.4.2 # `cc-backend` version 1.4.3
Supports job archive version 2 and database version 8. Supports job archive version 2 and database version 8.
This is a small bug fix release of `cc-backend`, the API backend and frontend This is a bug fix release of `cc-backend`, the API backend and frontend
implementation of ClusterCockpit. implementation of ClusterCockpit.
For release specific notes visit the [ClusterCockpit Documentation](https://clusterockpit.org/docs/release/). For release specific notes visit the [ClusterCockpit Documentation](https://clusterockpit.org/docs/release/).
## Breaking changes ## Breaking changes for minor release 1.4.x
- You need to perform a database migration. Depending on your database size the - You need to perform a database migration. Depending on your database size the
migration might require several hours! migration might require several hours!
@ -22,20 +22,21 @@ For release specific notes visit the [ClusterCockpit Documentation](https://clus
## New features ## New features
- Tags have a scope now. Tags created by a basic user are only visible by that - Detailed Node List
user. Tags created by an admin/support role can be configured to be visible by - Adds new routes `/systems/list/$cluster` and `/systems/list/$cluster/$subcluster`
all users (global scope) or only be admin/support role. - Displays live, scoped metric data requested from the nodes indepenent of jobs
- Re-sampling support for running (requires a recent `cc-metric-store`) and - Color Blind Mode
archived jobs. This greatly speeds up loading of large or very long jobs. You - Set on a per-user basis in options
need to add the new configuration key `enable-resampling` to the `config.json` - Applies to plot data, plot background color, statsseries colors, roofline timescale
file. - Job-View metric selection is now persisted based on the jobs subcluster.
- For finished jobs a total job energy is shown in the job view. Helpful for heterogeneous subcluster configurations.
- Continuous scrolling in job lists is default now. - Histogram Bin Select in User-View
- All database queries (especially for sqlite) were optimized resulting in - Metric-Histograms: `10 Bins` now default, selectable options `20, 50, 100`
dramatically faster load times. - Job-Duration-Histogram: `48h in 1h Bins` now default, selectable options:
- A performance and energy footprint can be freely configured on a per - `60 minutes in 1 minute Bins`
subcluster base. One can filter for footprint statistics for running and - `12 hours in 10 minute Bins`
finished jobs. - `3 days in 6 hour Bins`
- `7 days in 12 hour Bins`
## Known issues ## Known issues

View File

@ -391,30 +391,28 @@ func (r *queryResolver) Jobs(ctx context.Context, filter []*model.JobFilter, pag
return nil, err return nil, err
} }
if !config.Keys.UiDefaults["job_list_usePaging"].(bool) { // Note: Even if App-Default 'config.Keys.UiDefaults["job_list_usePaging"]' is set, always return hasNextPage boolean.
hasNextPage := false // Users can decide in frontend to use continuous scroll, even if app-default is paging!
// page.Page += 1 : Simple, but expensive /*
// Example Page 4 @ 10 IpP : Does item 41 exist? Example Page 4 @ 10 IpP : Does item 41 exist?
// Minimal Page 41 @ 1 IpP : If len(result) is 1, Page 5 @ 10 IpP exists. Minimal Page 41 @ 1 IpP : If len(result) is 1, Page 5 @ 10 IpP exists.
nextPage := &model.PageRequest{ */
ItemsPerPage: 1, nextPage := &model.PageRequest{
Page: ((page.Page * page.ItemsPerPage) + 1), ItemsPerPage: 1,
} Page: ((page.Page * page.ItemsPerPage) + 1),
nextJobs, err := r.Repo.QueryJobs(ctx, filter, nextPage, order)
if err != nil {
log.Warn("Error while querying next jobs")
return nil, err
}
if len(nextJobs) == 1 {
hasNextPage = true
}
return &model.JobResultList{Items: jobs, Count: &count, HasNextPage: &hasNextPage}, nil
} else {
return &model.JobResultList{Items: jobs, Count: &count}, nil
} }
nextJobs, err := r.Repo.QueryJobs(ctx, filter, nextPage, order)
if err != nil {
log.Warn("Error while querying next jobs")
return nil, err
}
hasNextPage := false
if len(nextJobs) == 1 {
hasNextPage = true
}
return &model.JobResultList{Items: jobs, Count: &count, HasNextPage: &hasNextPage}, nil
} }
// JobsStatistics is the resolver for the jobsStatistics field. // JobsStatistics is the resolver for the jobsStatistics field.

View File

@ -218,7 +218,7 @@
<Col xs={12} md={6} xl={3} class="mb-3 mb-xxl-0"> <Col xs={12} md={6} xl={3} class="mb-3 mb-xxl-0">
{#if $initq.error} {#if $initq.error}
<Card body color="danger">{$initq.error.message}</Card> <Card body color="danger">{$initq.error.message}</Card>
{:else if $initq.data} {:else if $initq?.data}
<Card class="overflow-auto" style="height: 400px;"> <Card class="overflow-auto" style="height: 400px;">
<TabContent> <!-- on:tab={(e) => (status = e.detail)} --> <TabContent> <!-- on:tab={(e) => (status = e.detail)} -->
{#if $initq.data?.job?.metaData?.message} {#if $initq.data?.job?.metaData?.message}
@ -292,7 +292,7 @@
<Card class="mb-3"> <Card class="mb-3">
<CardBody> <CardBody>
<Row class="mb-2"> <Row class="mb-2">
{#if $initq.data} {#if $initq?.data}
<Col xs="auto"> <Col xs="auto">
<Button outline on:click={() => (isMetricsSelectionOpen = true)} color="primary"> <Button outline on:click={() => (isMetricsSelectionOpen = true)} color="primary">
Select Metrics (Selected {selectedMetrics.length} of {availableMetrics.size} available) Select Metrics (Selected {selectedMetrics.length} of {availableMetrics.size} available)
@ -305,7 +305,7 @@
{#if $jobMetrics.error} {#if $jobMetrics.error}
<Row class="mt-2"> <Row class="mt-2">
<Col> <Col>
{#if $initq.data.job.monitoringStatus == 0 || $initq.data.job.monitoringStatus == 2} {#if $initq?.data && ($initq.data.job?.monitoringStatus == 0 || $initq.data.job?.monitoringStatus == 2)}
<Card body color="warning">Not monitored or archiving failed</Card> <Card body color="warning">Not monitored or archiving failed</Card>
<br /> <br />
{/if} {/if}
@ -351,7 +351,7 @@
<!-- Statistcics Table --> <!-- Statistcics Table -->
<Row class="mb-3"> <Row class="mb-3">
<Col> <Col>
{#if $initq.data} {#if $initq?.data}
<Card> <Card>
<TabContent> <TabContent>
{#if somethingMissing} {#if somethingMissing}
@ -412,7 +412,7 @@
</Col> </Col>
</Row> </Row>
{#if $initq.data} {#if $initq?.data}
<MetricSelection <MetricSelection
cluster={$initq.data.job.cluster} cluster={$initq.data.job.cluster}
subCluster={$initq.data.job.subCluster} subCluster={$initq.data.job.subCluster}