Merge branch 'master' into 40_45_82_update_roles

This commit is contained in:
Christoph Kluge
2023-02-21 17:17:41 +01:00
66 changed files with 3132 additions and 826 deletions

View File

@@ -1,7 +1,7 @@
<script>
import { Icon, Button, InputGroup, Input, Collapse,
Navbar, NavbarBrand, Nav, NavItem, NavLink, NavbarToggler,
Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'sveltestrap'
Dropdown, DropdownToggle, DropdownMenu, DropdownItem, InputGroupText } from 'sveltestrap'
export let username // empty string if auth. is disabled, otherwise the username as string
export let authlevel // integer
@@ -93,6 +93,7 @@
<InputGroup>
<Input type="text" placeholder={(authlevel >= 4) ? "Search jobId / username" : "Search jobId"} name="searchId"/>
<Button outline type="submit"><Icon name="search"/></Button>
<InputGroupText style="cursor:help;" title={isAdmin ? "Example: 'projectId:a100cd', Types are: jobId | jobName | projectId | username" | "name" : "Example: 'jobName:myjob', Types are jobId | jobName"}><Icon name="info-circle"/></InputGroupText>
</InputGroup>
</form>
{#if username}

View File

@@ -20,6 +20,7 @@
const stats = operationStore(`query($filter: [JobFilter!]!) {
rows: jobsStatistics(filter: $filter, groupBy: ${type}) {
id
name
totalJobs
totalWalltime
totalCoreHours
@@ -93,6 +94,15 @@
<Icon name="sort-numeric-down" />
</Button>
</th>
{#if type == 'USER'}
<th scope="col">
Name
<Button color="{sorting.field == 'name' ? 'primary' : 'light'}"
size="sm" on:click={e => changeSorting(e, 'name')}>
<Icon name="sort-numeric-down" />
</Button>
</th>
{/if}
<th scope="col">
Total Jobs
<Button color="{sorting.field == 'totalJobs' ? 'primary' : 'light'}"
@@ -137,6 +147,9 @@
{row.id}
{/if}
</td>
{#if type == 'USER'}
<td>{row?.name ? row.name : ''}</td>
{/if}
<td>{row.totalJobs}</td>
<td>{row.totalWalltime}</td>
<td>{row.totalCoreHours}</td>

View File

@@ -35,16 +35,17 @@
projectMatch: filterPresets.projectMatch || 'contains',
userMatch: filterPresets.userMatch || 'contains',
cluster: filterPresets.cluster || null,
partition: filterPresets.partition || null,
states: filterPresets.states || filterPresets.state ? [filterPresets.state].flat() : allJobStates,
startTime: filterPresets.startTime || { from: null, to: null },
tags: filterPresets.tags || [],
duration: filterPresets.duration || { from: null, to: null },
jobId: filterPresets.jobId || '',
arrayJobId: filterPresets.arrayJobId || null,
user: filterPresets.user || '',
project: filterPresets.project || '',
cluster: filterPresets.cluster || null,
partition: filterPresets.partition || null,
states: filterPresets.states || filterPresets.state ? [filterPresets.state].flat() : allJobStates,
startTime: filterPresets.startTime || { from: null, to: null },
tags: filterPresets.tags || [],
duration: filterPresets.duration || { from: null, to: null },
jobId: filterPresets.jobId || '',
arrayJobId: filterPresets.arrayJobId || null,
user: filterPresets.user || '',
project: filterPresets.project || '',
jobName: filterPresets.jobName || '',
numNodes: filterPresets.numNodes || { from: null, to: null },
numHWThreads: filterPresets.numHWThreads || { from: null, to: null },
@@ -94,6 +95,8 @@
items.push({ user: { [filters.userMatch]: filters.user } })
if (filters.project)
items.push({ project: { [filters.projectMatch]: filters.project } })
if (filters.jobName)
items.push({ jobName: { contains: filters.jobName } })
for (let stat of filters.stats)
items.push({ [stat.field]: { from: stat.from, to: stat.to } })
@@ -123,12 +126,19 @@
opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`)
if (filters.numAccelerators.from && filters.numAccelerators.to)
opts.push(`numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`)
if (filters.user)
opts.push(`user=${filters.user}`)
if (filters.user.length != 0)
if (filters.userMatch != 'in') {
opts.push(`user=${filters.user}`)
} else {
for (let singleUser of filters.user)
opts.push(`user=${singleUser}`)
}
if (filters.userMatch != 'contains')
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')
opts.push(`projectMatch=${filters.projectMatch}`)

View File

@@ -52,7 +52,10 @@
{/if}
{#if job.project && job.project != 'no project'}
<br/>
<Icon name="people-fill"/> {job.project}
<Icon name="people-fill"/>
<a class="fst-italic" href="/monitoring/jobs/?project={job.project}&projectMatch=eq" target="_blank">
{scrambleNames ? scramble(job.project) : job.project}
</a>
{/if}
</p>

View File

@@ -33,7 +33,7 @@
query($filter: [JobFilter!]!, $sorting: OrderByInput!, $paging: PageRequest! ){
jobs(filter: $filter, order: $sorting, page: $paging) {
items {
id, jobId, user, project, cluster, subCluster, startTime,
id, jobId, user, project, jobName, cluster, subCluster, startTime,
duration, numNodes, numHWThreads, numAcc, walltime,
SMT, exclusive, partition, arrayJobId,
monitoringStatus, state,

View File

@@ -230,7 +230,7 @@ commondir@^1.0.1:
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
deepmerge@^4.2.2:
version "4.2.2"
@@ -365,9 +365,9 @@ merge-stream@^2.0.0:
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"

View File

@@ -24,6 +24,7 @@ var frontendFiles embed.FS
func ServeFiles() http.Handler {
publicFiles, err := fs.Sub(frontendFiles, "frontend/public")
if err != nil {
log.Fatalf("WEB/WEB > cannot find frontend public files")
panic(err)
}
return http.FileServer(http.FS(publicFiles))
@@ -47,6 +48,7 @@ func init() {
templates[strings.TrimPrefix(path, "templates/")] = template.Must(template.Must(base.Clone()).ParseFS(templateFiles, path))
return nil
}); err != nil {
log.Fatalf("WEB/WEB > cannot find frontend template files")
panic(err)
}
@@ -79,6 +81,7 @@ type Page struct {
func RenderTemplate(rw http.ResponseWriter, r *http.Request, file string, page *Page) {
t, ok := templates[file]
if !ok {
log.Fatalf("WEB/WEB > template '%s' not found", file)
panic("template not found")
}
@@ -88,8 +91,8 @@ func RenderTemplate(rw http.ResponseWriter, r *http.Request, file string, page *
}
}
log.Infof("%v\n", page.Config)
log.Infof("Page config : %v\n", page.Config)
if err := t.Execute(rw, page); err != nil {
log.Errorf("template error: %s", err.Error())
log.Errorf("Template error: %s", err.Error())
}
}