Skip to content

Commit

Permalink
Merge pull request #1 from l1997i/v0_ui
Browse files Browse the repository at this point in the history
V0 UI
  • Loading branch information
l1997i authored Apr 23, 2024
2 parents 74a46ef + d6a2abd commit 30fbd81
Show file tree
Hide file tree
Showing 8 changed files with 647 additions and 286 deletions.
46 changes: 32 additions & 14 deletions src/slurm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from flask import Blueprint,render_template,session, request, redirect,url_for, escape
from flask import Blueprint, render_template, session, escape, request
from flask_login import login_required
import flask
import subprocess
import threading
import shutil
Expand Down Expand Up @@ -44,12 +43,15 @@ def slurm():
@bp.route('/attach_job', methods=['POST'])
@login_required
def attachJob():
if 'g_selected_job_id' not in globals():
return ('', 204)
job_id = globals()['g_selected_job_id']
name = request.form['name']
job_id = g_selected_job_id
script = request.form['job_script']
manager.attachJob(job_id, name, script)
return ('', 204)


@bp.route('/load_json_job', methods=['POST'])
@login_required
def loadJsonJob():
Expand Down Expand Up @@ -124,11 +126,11 @@ def submitJob():
with open(user_sh_loc, 'w') as file:
file.write(request.form['job_script'].replace('\r\n','\n'))
shutil.copy(user_sh_loc, temp_sh_loc)
job_script += f"python ${{PY_SCRIPT_PATH}}/run_script.py {temp_sh_loc} ${{SLURM_JOB_ID}}_1"
job_script += f"python3 ${{PY_SCRIPT_PATH}}/run_script.py {temp_sh_loc} ${{SLURM_JOB_ID}}_1"

if final_stage_enabled:
job_script += '\n########################### 2nd STAGE <<<<<<<<<<<<<<<<<<<<<<<<<<<<\n'
job_script += f"python ${{PY_SCRIPT_PATH}}/run_script.py ${{SH_SCRIPT_PATH}}/{final_sh_loc} ${{SLURM_JOB_ID}}_2"
job_script += f"python3 ${{PY_SCRIPT_PATH}}/run_script.py ${{SH_SCRIPT_PATH}}/{final_sh_loc} ${{SLURM_JOB_ID}}_2"
if is_wait:
job_script += '\nwait'

Expand Down Expand Up @@ -381,48 +383,64 @@ def cli(command,return_err = False):
return out[0].decode("latin-1")

def formatSinfo(sinfo):
res = '<tr><th>Partition</th><th>Availability</th><th>Timelimit</th><th>Nodes</th><th>State</th><th>Nodelist</th></tr>'
res = '<table class="w-full text-sm text-center rtl:text-center text-gray-500 dark:text-gray-400">'
res += '<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">'
res += '<tr><th>Partition</th><th>Avail</th><th>Timelimit</th><th>Nodes</th><th>State</th><th>Nodelist</th></tr>'
res += '</thead>'
res += '<tbody>'
for idx, line in enumerate(sinfo.split('\n')):
if idx:
fields = line.split()
l = "<tr>"
l = '<tr class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800">'
for f in fields:
if 'drain' in f or 'alloc' in f or 'down' in f or 'drng' in f:
l += f'<td style="color:#FE5F58">{f}</td>'
l += f'<td><span class="bg-red-100 text-red-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded dark:bg-red-900 dark:text-red-300">{f}</span></td>'
continue
if 'idle' in f:
l += f'<td style="color:#28C73F">{f}</td>'
l += f'<td><span class="bg-green-100 text-green-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded dark:bg-green-900 dark:text-green-300">{f}</span></td>'
continue
elif 'mix' in f or 'comp' in f:
l += f'<td style="color:#FEBB2C">{f}</td>'
l += f'<td><span class="bg-yellow-100 text-yellow-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded dark:bg-yellow-900 dark:text-yellow-300">{f}</span></td>'
continue
else:
l += f'<td>{f}</td>'
continue
l += "</tr>"
res += l
res += line
res += '</tbody>'
res += '</table>'
return res

def formatSacct(sacct):
res = '<tr><th>JOBID</th><th>Partition</th><th>Name</th><th>User</th><th>ST</th><th>Time</th><th>Nodes</th><th>Nodelist</th></tr>'
res = '<table class="w-full text-sm text-center rtl:text-center text-gray-500 dark:text-gray-400">'
res += '<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">'
res += '<tr><th>JOBID</th><th>Partition</th><th>Name</th><th>User</th><th>ST</th><th>Time</th><th>Nodes</th><th>Nodelist</th></tr>'
res += '</thead>'
res += '<tbody>'
for idx, line in enumerate(sacct.split('\n')):
if idx:
fields = line.split()
l = "<tr>"
l = '<tr class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700">'
for f in fields:
l += f'<td>{f}</td>'
l += "</tr>"
res += l
res += '</tbody>'
res += '</table>'
return res

def generateJobList(jobs):
res = '<tr><th>JOBID</th><th>Nodelist</th><th>Name</th><th>State</th><th>SubmitOn</th><th>PID_1</th><th>PID_2</th></tr>'
res = '<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">'
res += f'<tr><th>JOBID</th><th>Nodelist</th><th>Name</th><th>State</th><th>SubmitOn</th><th>PID_1</th><th>PID_2</th></tr>'
res += f'</thead>'
res += '<tbody>'
for job in jobs.values():
if job["state"] == 'R' or job["state"] == 'PD':
timestamp = os.path.basename(job["ts"])
dt = datetime.fromtimestamp(int(timestamp)).strftime('%m-%d %H:%M:%S')
res += f'<tr class="selectable" id="{job["id"]}"><td>{job["id"]}</td><td>{job["node"]}</td><td>{job["name"]}</td><td>{job["state"]}</td><td>{dt}</td><td style="color:#28C73F">{job["pid_1"]}</td><td style="color:#FE5F58">{job["pid_2"]}</td></tr>'
res += f'</tbody>'
res += f'</table>'
return res

manager = SlurmManager()
161 changes: 100 additions & 61 deletions src/static/style.css
Original file line number Diff line number Diff line change
@@ -1,48 +1,83 @@
body {
background-color: #282A36;
color: #ffffff;
font-family: "Raleway", "Microsoft JhengHei";
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
margin: 50px;
background-image: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
/* background-image: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url("https://i.imgur.com/pkiX69L.jpeg"); */
:root {
/* Light theme colors */
--color-hover-light: #cce1ff; /* Light blue for hover states on light background */
--color-active-light: #99c2ff; /* Slightly darker blue for active states on light background */
--color-hover-dark: #1a4d8f; /* Dark blue for hover states on dark background */
--color-active-dark: #003366; /* Even darker blue for active states on dark background */
--color-selected-light: #e0f0ff; /* Very light blue for selected items on light background */
--color-selected-dark: #336699; /* Mid-tone blue for selected items on dark background */
--color-bg-dark: #0A0F18;
--color-bg-light: #FFFFFF;
}

input,
textarea {
background-color: #282A36;
color: #ffffff;
html, body {
height: auto;
overflow-y: auto;
}

table tr {
height: 40px;
}

/*input,*/
/*textarea {*/
/* background-color: #282A36;*/
/* color: #ffffff;*/
/*}*/

button,
select {
background-color: #282A36;
color: #ffffff;
font-family: "Raleway", "Microsoft JhengHei";
border: 1px solid #ffffff6c;
border-radius: 5px;
/* background-color: #282A36;*/
/* color: #ffffff;*/
/* font-family: "Raleway", "Microsoft JhengHei", serif;*/
/* border: 1px solid #ffffff6c;*/
/* border-radius: 5px;*/
padding: 5px;
margin: 0px;
}

button:hover,
select:hover {
background-color: #002a69;
th, td {
text-align: center; !important;
}

button:active,
select:active {
background-color: #000e22;
/* Base styles for hover and active states */
/*button:hover,*/
select:hover, .hover {
background-color: var(--color-hover-light);
}

.hover {
background-color: #111;
/*button:active,*/
select:active {
background-color: var(--color-active-light);
}

.selected {
background-color: rgb(11, 37, 68);
background-color: var(--color-selected-light);
}

html {
background-color: var(--color-bg-light);
}

/* Dark theme styles */
@media (prefers-color-scheme: dark) {
/*button:hover,*/
select:hover, .hover {
background-color: var(--color-hover-dark);
}

/*button:active,*/
select:active {
background-color: var(--color-active-dark);
}

.selected {
background-color: var(--color-selected-dark);
}

html {
background-color: var(--color-bg-dark);
}
}

::-webkit-scrollbar {
Expand All @@ -51,20 +86,21 @@ select:active {

table {
padding: 1em;
border: 1px solid rgb(114, 114, 114);
/* border: 1px solid rgb(114, 114, 114);*/
border-collapse: collapse;
}

th,
td {
font-size: 15px;
text-align: left;
padding: 0.3em;
min-width: 100px;
}

th {
color: #3BF;
}
/*th {*/
/* color: #3BF;*/
/*}*/

table.form_table {
border: none;
Expand All @@ -82,16 +118,20 @@ nav {
text-align: center;
}

input {
font-family: Consolas, 'Courier New', Courier;
font-size: 14px;
line-height: 1.3em;
/*input {*/
/* font-family: Consolas, 'Courier New', Courier;*/
/* font-size: 14px;*/
/* line-height: 1.3em;*/
/*}*/

tr.selectable td, tr.selectable th {
border: none !important;
}

.console {
padding: 10px;
margin: 10px;
background-color: #282A36;
/* padding: 10px;*/
/* margin: 10px;*/
/* background-color: #282A36;*/
font-family: Consolas, 'Courier New', Courier;
font-size: 14px;
line-height: 1.3em;
Expand Down Expand Up @@ -127,38 +167,37 @@ h4:after {
bottom: 0;
width: 5px;
border-radius: 2px;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5), 0 1px 1px rgba(255, 255, 255, 0.3);
/* box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5), 0 1px 1px rgba(255, 255, 255, 0.3);*/
}

h2:after {
background: #0AF;
}
/*h2:after {*/
/* background: #0AF;*/
/*}*/

h3:after {
background: #3BF;
}
/*h3:after {*/
/* background: #3BF;*/
/*}*/

h4:after {
background: #6Cf;
}
/*h4:after {*/
/* background: #6Cf;*/
/*}*/

h1 {
font-size: 36px;
line-height: 30px;
margin: 1em 0 .6em 0;
font-weight: normal;
color: white;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
/* text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);*/
position: relative;
color: #6Cf;
}

h2 {
margin: 1em 0 .6em 0;
padding: 0 0 0 20px;
font-weight: normal;
color: white;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
/* text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);*/
position: relative;
font-size: 30px;
line-height: 30px;
Expand All @@ -169,7 +208,7 @@ h3 {
padding: 0 0 0 20px;
font-weight: normal;
color: white;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
/* text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);*/
position: relative;
font-size: 24px;
line-height: 25px;
Expand All @@ -180,7 +219,7 @@ h4 {
padding: 0 0 0 20px;
font-weight: normal;
color: white;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
/* text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);*/
position: relative;
font-size: 18px;
line-height: 20px;
Expand All @@ -190,13 +229,13 @@ h4 {
display: flex;
}

.footer-text {
min-width: 100%;
max-height: 15px;
text-align: center;
font-size: small;
margin-top: 20px;
}
/*.footer-text {*/
/* min-width: 100%;*/
/* max-height: 15px;*/
/* text-align: center;*/
/* font-size: small;*/
/* margin-top: 20px;*/
/*}*/


.column {
Expand Down
Loading

0 comments on commit 30fbd81

Please sign in to comment.