diff --git a/backend/amuman/settings_manager.py b/backend/amuman/settings_manager.py
index 1cf9a9f..cd3b464 100644
--- a/backend/amuman/settings_manager.py
+++ b/backend/amuman/settings_manager.py
@@ -29,4 +29,5 @@
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'manager/static'),
-]
\ No newline at end of file
+]
+URL_MODE_PREFIX = "manager"
\ No newline at end of file
diff --git a/backend/common_models/migrations/0001_initial.py b/backend/common_models/migrations/0001_initial.py
index d6cf854..c730a20 100644
--- a/backend/common_models/migrations/0001_initial.py
+++ b/backend/common_models/migrations/0001_initial.py
@@ -1,6 +1,8 @@
-# Generated by Django 5.0 on 2024-01-24 11:45
+# Generated by Django 4.2.9 on 2024-01-28 20:32
from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
class Migration(migrations.Migration):
@@ -9,26 +11,143 @@ class Migration(migrations.Migration):
dependencies = []
operations = [
+ migrations.CreateModel(
+ name="Nodes",
+ fields=[
+ ("id", models.AutoField(primary_key=True, serialize=False)),
+ ("ip", models.CharField(max_length=15, unique=True)),
+ (
+ "name",
+ models.CharField(blank=True, max_length=15, null=True, unique=True),
+ ),
+ ("port", models.IntegerField(blank=True, null=True)),
+ (
+ "number_of_gpus",
+ models.CharField(blank=True, max_length=15, null=True),
+ ),
+ ("gpu_info", models.TextField(blank=True, null=True)),
+ ("status", models.CharField(default="free", max_length=10)),
+ (
+ "last_seen",
+ models.DateTimeField(
+ blank=True, default=django.utils.timezone.now, null=True
+ ),
+ ),
+ ],
+ ),
migrations.CreateModel(
name="Task",
fields=[
(
"id",
- models.BigAutoField(
- auto_created=True,
- primary_key=True,
- serialize=False,
- verbose_name="ID",
- ),
+ models.AutoField(primary_key=True, serialize=False, unique=True),
),
- ("path", models.CharField(max_length=500)),
+ ("user", models.CharField(blank=True, max_length=100, null=True)),
+ ("path", models.TextField()),
("node_name", models.CharField(blank=True, max_length=100, null=True)),
("port", models.IntegerField(blank=True, null=True)),
+ ("submit_time", models.DateTimeField(blank=True, null=True)),
("start_time", models.DateTimeField(blank=True, null=True)),
("end_time", models.DateTimeField(blank=True, null=True)),
("error_time", models.DateTimeField(blank=True, null=True)),
- ("priority", models.IntegerField(default=0)),
- ("status", models.CharField(default="waiting", max_length=50)),
+ (
+ "priority",
+ models.CharField(
+ choices=[
+ ("slow", "Slow"),
+ ("normal", "Normal"),
+ ("fast", "Fast"),
+ ],
+ default="normal",
+ max_length=6,
+ ),
+ ),
+ (
+ "gpu_partition",
+ models.CharField(
+ choices=[
+ ("slow", "Slow"),
+ ("normal", "Normal"),
+ ("fast", "Fast"),
+ ],
+ default="normal",
+ max_length=6,
+ ),
+ ),
+ ("est", models.DurationField(blank=True, null=True)),
+ (
+ "status",
+ models.CharField(
+ choices=[
+ ("Waiting", "Waiting"),
+ ("Pending", "Pending"),
+ ("Running", "Running"),
+ ("Finished", "Finished"),
+ ("Interrupted", "Interrupted"),
+ ],
+ default="Free",
+ max_length=50,
+ ),
+ ),
+ (
+ "assigned_node_id",
+ models.CharField(blank=True, max_length=10, null=True),
+ ),
+ (
+ "assigned_gpu_id",
+ models.CharField(blank=True, max_length=10, null=True),
+ ),
+ ],
+ ),
+ migrations.CreateModel(
+ name="Gpus",
+ fields=[
+ (
+ "id",
+ models.AutoField(primary_key=True, serialize=False, unique=True),
+ ),
+ ("gpu_uuid", models.TextField(blank=True, null=True, unique=True)),
+ ("brand_name", models.TextField(blank=True, null=True)),
+ ("gpu_speed", models.TextField(blank=True, null=True)),
+ ("gpu_util", models.TextField(blank=True, null=True)),
+ ("is_running_amumax", models.TextField(blank=True, null=True)),
+ ("gpu_info", models.TextField(blank=True, null=True)),
+ (
+ "status",
+ models.CharField(
+ choices=[
+ ("Free", "Free"),
+ ("Running", "Running"),
+ ("Reserved", "Reserved"),
+ ("Unavailable", "Unavailable"),
+ ],
+ default="Free",
+ max_length=50,
+ ),
+ ),
+ (
+ "last_update",
+ models.DateTimeField(
+ blank=True, default=django.utils.timezone.now, null=True
+ ),
+ ),
+ (
+ "node_id",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ to="common_models.nodes",
+ ),
+ ),
+ (
+ "task_id",
+ models.ForeignKey(
+ blank=True,
+ null=True,
+ on_delete=django.db.models.deletion.SET_NULL,
+ related_name="gpu_tasks",
+ to="common_models.task",
+ ),
+ ),
],
),
]
diff --git a/backend/common_models/migrations/0002_alter_gpus_status_alter_nodes_status_and_more.py b/backend/common_models/migrations/0002_alter_gpus_status_alter_nodes_status_and_more.py
new file mode 100644
index 0000000..dca4e82
--- /dev/null
+++ b/backend/common_models/migrations/0002_alter_gpus_status_alter_nodes_status_and_more.py
@@ -0,0 +1,55 @@
+# Generated by Django 4.2.9 on 2024-01-28 21:05
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("common_models", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="gpus",
+ name="status",
+ field=models.CharField(
+ choices=[
+ ("Waiting", "Waiting"),
+ ("Running", "Running"),
+ ("Reserved", "Reserved"),
+ ("Unavailable", "Unavailable"),
+ ],
+ default="Waiting",
+ max_length=50,
+ ),
+ ),
+ migrations.AlterField(
+ model_name="nodes",
+ name="status",
+ field=models.CharField(
+ choices=[
+ ("Waiting", "Waiting"),
+ ("Running", "Running"),
+ ("Reserved", "Reserved"),
+ ("Unavailable", "Unavailable"),
+ ],
+ default="Waiting",
+ max_length=50,
+ ),
+ ),
+ migrations.AlterField(
+ model_name="task",
+ name="status",
+ field=models.CharField(
+ choices=[
+ ("Waiting", "Waiting"),
+ ("Pending", "Pending"),
+ ("Running", "Running"),
+ ("Finished", "Finished"),
+ ("Interrupted", "Interrupted"),
+ ],
+ default="Waiting",
+ max_length=50,
+ ),
+ ),
+ ]
diff --git a/backend/common_models/migrations/0002_task_submit_time_task_user.py b/backend/common_models/migrations/0002_task_submit_time_task_user.py
deleted file mode 100644
index 1764657..0000000
--- a/backend/common_models/migrations/0002_task_submit_time_task_user.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Generated by Django 5.0 on 2024-01-24 21:41
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0001_initial"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="task",
- name="submit_time",
- field=models.DateTimeField(blank=True, null=True),
- ),
- migrations.AddField(
- model_name="task",
- name="user",
- field=models.CharField(blank=True, max_length=100, null=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0010_alter_task_est.py b/backend/common_models/migrations/0003_alter_task_est.py
similarity index 53%
rename from backend/common_models/migrations/0010_alter_task_est.py
rename to backend/common_models/migrations/0003_alter_task_est.py
index dc833bd..406417e 100644
--- a/backend/common_models/migrations/0010_alter_task_est.py
+++ b/backend/common_models/migrations/0003_alter_task_est.py
@@ -1,17 +1,17 @@
-# Generated by Django 4.2.9 on 2024-01-27 14:44
+# Generated by Django 4.2.9 on 2024-01-28 22:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ("common_models", "0009_task_est_task_gpu_partition_alter_task_id"),
+ ("common_models", "0002_alter_gpus_status_alter_nodes_status_and_more"),
]
operations = [
migrations.AlterField(
model_name="task",
name="est",
- field=models.DurationField(blank=True, null=True),
+ field=models.CharField(blank=True, max_length=100, null=True),
),
]
diff --git a/backend/common_models/migrations/0003_nodes_gpus.py b/backend/common_models/migrations/0003_nodes_gpus.py
deleted file mode 100644
index eaceb96..0000000
--- a/backend/common_models/migrations/0003_nodes_gpus.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-25 11:41
-
-from django.db import migrations, models
-import django.db.models.deletion
-import django.utils.timezone
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0002_task_submit_time_task_user"),
- ]
-
- operations = [
- migrations.CreateModel(
- name="Nodes",
- fields=[
- ("id", models.AutoField(primary_key=True, serialize=False)),
- ("ip", models.CharField(max_length=15, unique=True)),
- (
- "name",
- models.CharField(blank=True, max_length=15, null=True, unique=True),
- ),
- ("port", models.IntegerField(blank=True, null=True)),
- ("gpu_info", models.TextField(blank=True, null=True)),
- ("status", models.CharField(default="free", max_length=10)),
- (
- "last_seen",
- models.DateTimeField(
- blank=True, default=django.utils.timezone.now, null=True
- ),
- ),
- ],
- ),
- migrations.CreateModel(
- name="Gpus",
- fields=[
- ("id", models.AutoField(primary_key=True, serialize=False)),
- ("brand_name", models.TextField(blank=True, null=True)),
- ("gpu_speed", models.TextField(blank=True, null=True)),
- ("gpu_info", models.TextField(blank=True, null=True)),
- ("status", models.CharField(default="free", max_length=10)),
- (
- "nodeid",
- models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE,
- to="common_models.nodes",
- ),
- ),
- ],
- ),
- ]
diff --git a/backend/common_models/migrations/0004_gpus_no_alter_task_gpu_partition_alter_task_priority.py b/backend/common_models/migrations/0004_gpus_no_alter_task_gpu_partition_alter_task_priority.py
new file mode 100644
index 0000000..4de880d
--- /dev/null
+++ b/backend/common_models/migrations/0004_gpus_no_alter_task_gpu_partition_alter_task_priority.py
@@ -0,0 +1,35 @@
+# Generated by Django 4.2.9 on 2024-01-29 10:36
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("common_models", "0003_alter_task_est"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="gpus",
+ name="no",
+ field=models.IntegerField(blank=True, default=0, null=True),
+ ),
+ migrations.AlterField(
+ model_name="task",
+ name="gpu_partition",
+ field=models.CharField(
+ choices=[("Slow", "Slow"), ("Normal", "Normal"), ("Fast", "Fast")],
+ default="normal",
+ max_length=6,
+ ),
+ ),
+ migrations.AlterField(
+ model_name="task",
+ name="priority",
+ field=models.CharField(
+ choices=[("Slow", "Slow"), ("Normal", "Normal"), ("Fast", "Fast")],
+ default="normal",
+ max_length=6,
+ ),
+ ),
+ ]
diff --git a/backend/common_models/migrations/0004_nodes_number_of_gpus.py b/backend/common_models/migrations/0004_nodes_number_of_gpus.py
deleted file mode 100644
index 638b863..0000000
--- a/backend/common_models/migrations/0004_nodes_number_of_gpus.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-25 11:47
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0003_nodes_gpus"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="nodes",
- name="number_of_gpus",
- field=models.CharField(blank=True, max_length=15, null=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0005_gpus_last_update.py b/backend/common_models/migrations/0005_gpus_last_update.py
deleted file mode 100644
index fd4fe40..0000000
--- a/backend/common_models/migrations/0005_gpus_last_update.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-25 13:20
-
-from django.db import migrations, models
-import django.utils.timezone
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0004_nodes_number_of_gpus"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="gpus",
- name="last_update",
- field=models.DateTimeField(
- blank=True, default=django.utils.timezone.now, null=True
- ),
- ),
- ]
diff --git a/backend/common_models/migrations/0006_gpus_gpu_util_gpus_is_running_amumax.py b/backend/common_models/migrations/0006_gpus_gpu_util_gpus_is_running_amumax.py
deleted file mode 100644
index ef965cb..0000000
--- a/backend/common_models/migrations/0006_gpus_gpu_util_gpus_is_running_amumax.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-25 13:29
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0005_gpus_last_update"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="gpus",
- name="gpu_util",
- field=models.TextField(blank=True, null=True),
- ),
- migrations.AddField(
- model_name="gpus",
- name="is_running_amumax",
- field=models.TextField(blank=True, null=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0007_gpus_gpu_id.py b/backend/common_models/migrations/0007_gpus_gpu_id.py
deleted file mode 100644
index 72000b3..0000000
--- a/backend/common_models/migrations/0007_gpus_gpu_id.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-25 13:42
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0006_gpus_gpu_util_gpus_is_running_amumax"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="gpus",
- name="gpu_id",
- field=models.CharField(default=0, max_length=2, unique=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0008_rename_nodeid_gpus_node_id.py b/backend/common_models/migrations/0008_rename_nodeid_gpus_node_id.py
deleted file mode 100644
index f88be18..0000000
--- a/backend/common_models/migrations/0008_rename_nodeid_gpus_node_id.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-25 16:12
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0007_gpus_gpu_id"),
- ]
-
- operations = [
- migrations.RenameField(
- model_name="gpus",
- old_name="nodeid",
- new_name="node_id",
- ),
- ]
diff --git a/backend/common_models/migrations/0009_task_est_task_gpu_partition_alter_task_id.py b/backend/common_models/migrations/0009_task_est_task_gpu_partition_alter_task_id.py
deleted file mode 100644
index 2e55564..0000000
--- a/backend/common_models/migrations/0009_task_est_task_gpu_partition_alter_task_id.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-27 14:16
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0008_rename_nodeid_gpus_node_id"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="task",
- name="est",
- field=models.CharField(blank=True, max_length=15, null=True),
- ),
- migrations.AddField(
- model_name="task",
- name="gpu_partition",
- field=models.CharField(
- blank=True, default="normal", max_length=15, null=True, unique=True
- ),
- ),
- migrations.AlterField(
- model_name="task",
- name="id",
- field=models.AutoField(primary_key=True, serialize=False),
- ),
- ]
diff --git a/backend/common_models/migrations/0011_task_assigned_gpu_task_assigned_node.py b/backend/common_models/migrations/0011_task_assigned_gpu_task_assigned_node.py
deleted file mode 100644
index f6bbf3c..0000000
--- a/backend/common_models/migrations/0011_task_assigned_gpu_task_assigned_node.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-27 15:02
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0010_alter_task_est"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="task",
- name="assigned_gpu",
- field=models.CharField(blank=True, max_length=10, null=True),
- ),
- migrations.AddField(
- model_name="task",
- name="assigned_node",
- field=models.CharField(blank=True, max_length=10, null=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0012_gpus_task_id_alter_gpus_gpu_id.py b/backend/common_models/migrations/0012_gpus_task_id_alter_gpus_gpu_id.py
deleted file mode 100644
index 43dbebf..0000000
--- a/backend/common_models/migrations/0012_gpus_task_id_alter_gpus_gpu_id.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-27 15:42
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0011_task_assigned_gpu_task_assigned_node"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="gpus",
- name="task_id",
- field=models.CharField(blank=True, max_length=10, null=True),
- ),
- migrations.AlterField(
- model_name="gpus",
- name="gpu_id",
- field=models.CharField(default="", max_length=2, unique=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0013_task_gpu_id.py b/backend/common_models/migrations/0013_task_gpu_id.py
deleted file mode 100644
index a410762..0000000
--- a/backend/common_models/migrations/0013_task_gpu_id.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-27 15:42
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0012_gpus_task_id_alter_gpus_gpu_id"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="task",
- name="gpu_id",
- field=models.CharField(blank=True, max_length=10, null=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0014_remove_gpus_gpu_id_remove_task_gpu_id_alter_gpus_id_and_more.py b/backend/common_models/migrations/0014_remove_gpus_gpu_id_remove_task_gpu_id_alter_gpus_id_and_more.py
deleted file mode 100644
index e466ec1..0000000
--- a/backend/common_models/migrations/0014_remove_gpus_gpu_id_remove_task_gpu_id_alter_gpus_id_and_more.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-27 17:17
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0013_task_gpu_id"),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name="gpus",
- name="gpu_id",
- ),
- migrations.RemoveField(
- model_name="task",
- name="gpu_id",
- ),
- migrations.AlterField(
- model_name="gpus",
- name="id",
- field=models.AutoField(primary_key=True, serialize=False, unique=True),
- ),
- migrations.AlterField(
- model_name="task",
- name="id",
- field=models.AutoField(primary_key=True, serialize=False, unique=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0015_gpus_gpu_uuid.py b/backend/common_models/migrations/0015_gpus_gpu_uuid.py
deleted file mode 100644
index 6d72d41..0000000
--- a/backend/common_models/migrations/0015_gpus_gpu_uuid.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-27 21:08
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- (
- "common_models",
- "0014_remove_gpus_gpu_id_remove_task_gpu_id_alter_gpus_id_and_more",
- ),
- ]
-
- operations = [
- migrations.AddField(
- model_name="gpus",
- name="gpu_uuid",
- field=models.TextField(blank=True, null=True, unique=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0016_alter_task_gpu_partition_alter_task_priority.py b/backend/common_models/migrations/0016_alter_task_gpu_partition_alter_task_priority.py
deleted file mode 100644
index 25603c1..0000000
--- a/backend/common_models/migrations/0016_alter_task_gpu_partition_alter_task_priority.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-28 11:14
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0015_gpus_gpu_uuid"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="task",
- name="gpu_partition",
- field=models.CharField(
- blank=True, default="normal", max_length=15, null=True
- ),
- ),
- migrations.AlterField(
- model_name="task",
- name="priority",
- field=models.IntegerField(blank=True, default=0, null=True),
- ),
- ]
diff --git a/backend/common_models/migrations/0017_alter_task_path.py b/backend/common_models/migrations/0017_alter_task_path.py
deleted file mode 100644
index e115cef..0000000
--- a/backend/common_models/migrations/0017_alter_task_path.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-28 11:18
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0016_alter_task_gpu_partition_alter_task_priority"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="task",
- name="path",
- field=models.TextField(),
- ),
- ]
diff --git a/backend/common_models/migrations/0018_alter_task_priority.py b/backend/common_models/migrations/0018_alter_task_priority.py
deleted file mode 100644
index 97c84f3..0000000
--- a/backend/common_models/migrations/0018_alter_task_priority.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-28 11:44
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0017_alter_task_path"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="task",
- name="priority",
- field=models.CharField(
- choices=[("slow", "Slow"), ("normal", "Normal"), ("fast", "Fast")],
- default="normal",
- max_length=6,
- ),
- ),
- ]
diff --git a/backend/common_models/migrations/0019_alter_task_gpu_partition.py b/backend/common_models/migrations/0019_alter_task_gpu_partition.py
deleted file mode 100644
index 3063be3..0000000
--- a/backend/common_models/migrations/0019_alter_task_gpu_partition.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-28 11:47
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("common_models", "0018_alter_task_priority"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="task",
- name="gpu_partition",
- field=models.CharField(
- choices=[("slow", "Slow"), ("normal", "Normal"), ("fast", "Fast")],
- default="normal",
- max_length=6,
- ),
- ),
- ]
diff --git a/backend/common_models/models.py b/backend/common_models/models.py
index 3076d40..2b8f543 100644
--- a/backend/common_models/models.py
+++ b/backend/common_models/models.py
@@ -1,3 +1,4 @@
+
from django.db import models
from django.utils import timezone
@@ -14,34 +15,27 @@ class Task(models.Model):
start_time = models.DateTimeField(null=True, blank=True)
end_time = models.DateTimeField(null=True, blank=True)
error_time = models.DateTimeField(null=True, blank=True)
-
- PRIORITY_CHOICES = [
- ('slow', 'Slow'),
- ('normal', 'Normal'),
- ('fast', 'Fast')
- ]
+
+ PRIORITY_CHOICES = [("Slow", "Slow"), ("Normal", "Normal"), ("Fast", "Fast")]
priority = models.CharField(
- max_length=6,
- choices=PRIORITY_CHOICES,
- default='normal'
+ max_length=6, choices=PRIORITY_CHOICES, default="normal"
)
-
- GPU_PARTITION_CHOICES = [
- ('slow', 'Slow'),
- ('normal', 'Normal'),
- ('fast', 'Fast')
- ]
+
+ GPU_PARTITION_CHOICES = [("Slow", "Slow"), ("Normal", "Normal"), ("Fast", "Fast")]
gpu_partition = models.CharField(
- max_length=6,
- choices=GPU_PARTITION_CHOICES,
- default='normal'
+ max_length=6, choices=GPU_PARTITION_CHOICES, default="normal"
)
- est = models.DurationField(null=True, blank=True)
- status = models.CharField(
- max_length=50, default="waiting"
- ) # ['waiting', 'running', 'finished']
- assigned_node = models.CharField(max_length=10, null=True, blank=True)
- assigned_gpu = models.CharField(max_length=10, null=True, blank=True)
+ est = models.CharField(max_length=100, null=True, blank=True)
+ STATUS_CHOICES = [
+ ("Waiting", "Waiting"),
+ ("Pending", "Pending"),
+ ("Running", "Running"),
+ ("Finished", "Finished"),
+ ("Interrupted", "Interrupted"),
+ ]
+ status = models.CharField(max_length=50, choices=STATUS_CHOICES, default="Waiting")
+ assigned_node_id = models.CharField(max_length=10, null=True, blank=True)
+ assigned_gpu_id = models.CharField(max_length=10, null=True, blank=True)
class Nodes(models.Model):
@@ -53,9 +47,13 @@ class Nodes(models.Model):
port = models.IntegerField(null=True, blank=True)
number_of_gpus = models.CharField(max_length=15, null=True, blank=True)
gpu_info = models.TextField(null=True, blank=True)
- status = models.CharField(
- max_length=10, default="free"
- ) # np. 'active', 'disconnected'
+ STATUS_CHOICES = [
+ ("Waiting", "Waiting"),
+ ("Running", "Running"),
+ ("Reserved", "Reserved"),
+ ("Unavailable", "Unavailable"),
+ ]
+ status = models.CharField(max_length=50, choices=STATUS_CHOICES, default="Waiting")
last_seen = models.DateTimeField(default=timezone.now, null=True, blank=True)
def __str__(self):
@@ -63,19 +61,29 @@ def __str__(self):
class Gpus(models.Model):
- id = models.AutoField(
- primary_key=True, unique=True
- )
- gpu_uuid=models.TextField(unique=True,null=True, blank=True)
+ id = models.AutoField(primary_key=True, unique=True)
+ no = models.IntegerField(null=True, blank=True, default=0)
+ gpu_uuid = models.TextField(unique=True, null=True, blank=True)
node_id = models.ForeignKey(Nodes, on_delete=models.CASCADE)
brand_name = models.TextField(null=True, blank=True)
gpu_speed = models.TextField(null=True, blank=True)
gpu_util = models.TextField(null=True, blank=True)
is_running_amumax = models.TextField(null=True, blank=True)
gpu_info = models.TextField(null=True, blank=True)
- status = models.CharField(max_length=10, default="free")
+ STATUS_CHOICES = [
+ ("Waiting", "Waiting"),
+ ("Running", "Running"),
+ ("Reserved", "Reserved"),
+ ("Unavailable", "Unavailable"),
+ ]
+ status = models.CharField(max_length=50, choices=STATUS_CHOICES, default="Waiting")
last_update = models.DateTimeField(default=timezone.now, null=True, blank=True)
- task_id = models.CharField(max_length=10, null=True, blank=True)
-
+ task_id = models.ForeignKey(
+ Task,
+ on_delete=models.SET_NULL,
+ null=True,
+ blank=True,
+ related_name="gpu_tasks" # Changed related_name to avoid conflict
+ )
def __str__(self):
return f"GPU-{self.id}, {self.node_id}/{self.id}"
diff --git a/backend/manager/__init__.py b/backend/manager/__init__.py
index 481c2d0..e69de29 100644
--- a/backend/manager/__init__.py
+++ b/backend/manager/__init__.py
@@ -1,3 +0,0 @@
-from manager.scheduler import start_scheduler
-
-# start_scheduler()
diff --git a/backend/manager/components/forms.py b/backend/manager/components/forms.py
index 0153a73..049d0ee 100644
--- a/backend/manager/components/forms.py
+++ b/backend/manager/components/forms.py
@@ -8,7 +8,7 @@ class EditTaskForm(forms.ModelForm):
pass
class Meta:
model = Task
- fields = ['path', 'node_name', 'port', 'start_time', 'end_time', 'error_time', 'priority', 'status']
+ fields = ['path', 'node_name', 'port', 'priority', 'status']
widgets = {
'path': forms.TextInput(attrs={'class': 'form-control'}),
'node_name': forms.TextInput(attrs={'class': 'form-control'}),
@@ -16,17 +16,13 @@ class Meta:
'start_time': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}),
'end_time': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}),
'error_time': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}),
- 'priority': forms.NumberInput(attrs={'class': 'form-control'}),
+ 'priority': forms.Select(attrs={'class': 'form-control'}),
'status': forms.Select(attrs={'class': 'form-control'}),
}
def __init__(self, *args, **kwargs):
super(EditTaskForm, self).__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].required = False
- self.fields['status'].disabled = True
- self.fields['end_time'].disabled = True
- self.fields['error_time'].disabled = True
- self.fields['start_time'].disabled = True
self.fields['node_name'].disabled = True
self.fields['port'].disabled = True
@@ -47,18 +43,4 @@ class Meta:
def __init__(self, *args, **kwargs):
super(AddTaskForm, self).__init__(*args, **kwargs)
for field in self.fields:
- self.fields[field].required = False
-
-
- # def clean_est(self):
- # est = self.cleaned_data['est']
- # # Sprawdź, czy est jest już obiektem timedelta
- # if isinstance(est, timedelta):
- # return est
- # # Jeśli est jest ciągiem znaków, przetwórz go
- # try:
- # hours, minutes, seconds = [int(part) for part in est.split(':')]
- # return timedelta(hours=hours, minutes=minutes, seconds=seconds)
- # except ValueError:
- # # Możesz tu dodać jakąś logikę obsługi błędów lub po prostu zwrócić None
- # return None
+ self.fields[field].required = False
\ No newline at end of file
diff --git a/backend/manager/components/job_queue.py b/backend/manager/components/job_queue.py
index b52845c..2292cc6 100644
--- a/backend/manager/components/job_queue.py
+++ b/backend/manager/components/job_queue.py
@@ -31,9 +31,9 @@ def assign_tasks_to_gpus():
# for gpu in free_gpus:
# for task in waiting_tasks:
- # task.assigned_gpu = gpu.id
+ # task.assigned_gpu_id = gpu.id
# task.status = "running"
- # task.assigned_node = gpu.node_id
+ # task.assigned_node_id = gpu.node_id
# task.save()
# gpu.task_id = task.id
diff --git a/backend/manager/migrations/0001_initial.py b/backend/manager/migrations/0001_initial.py
deleted file mode 100644
index 48564e0..0000000
--- a/backend/manager/migrations/0001_initial.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Generated by Django 5.0 on 2024-01-23 20:39
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- initial = True
-
- dependencies = []
-
- operations = [
- migrations.CreateModel(
- name="Task",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True,
- primary_key=True,
- serialize=False,
- verbose_name="ID",
- ),
- ),
- ("path", models.CharField(max_length=500)),
- ("node_name", models.CharField(blank=True, max_length=100, null=True)),
- ("port", models.IntegerField(blank=True, null=True)),
- ("start_time", models.DateTimeField(blank=True, null=True)),
- ("end_time", models.DateTimeField(blank=True, null=True)),
- ("error_time", models.DateTimeField(blank=True, null=True)),
- ("priority", models.IntegerField(default=0)),
- ("status", models.CharField(default="waiting", max_length=50)),
- ],
- ),
- ]
diff --git a/backend/manager/migrations/0002_nodes.py b/backend/manager/migrations/0002_nodes.py
deleted file mode 100644
index 2f6716d..0000000
--- a/backend/manager/migrations/0002_nodes.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Generated by Django 5.0 on 2024-01-23 22:16
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("manager", "0001_initial"),
- ]
-
- operations = [
- migrations.CreateModel(
- name="Nodes",
- fields=[
- (
- "id",
- models.BigAutoField(
- auto_created=True,
- primary_key=True,
- serialize=False,
- verbose_name="ID",
- ),
- ),
- ("ip", models.CharField(max_length=15)),
- ("port", models.CharField(max_length=5)),
- ("gpu_info", models.TextField()),
- ("is_active", models.BooleanField(default=True)),
- ],
- ),
- ]
diff --git a/backend/manager/migrations/0003_delete_task.py b/backend/manager/migrations/0003_delete_task.py
deleted file mode 100644
index 9f290ff..0000000
--- a/backend/manager/migrations/0003_delete_task.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated by Django 5.0 on 2024-01-24 18:59
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("manager", "0002_nodes"),
- ]
-
- operations = [
- migrations.DeleteModel(
- name="Task",
- ),
- ]
diff --git a/backend/manager/migrations/0004_remove_nodes_is_active_nodes_last_seen_nodes_status_and_more.py b/backend/manager/migrations/0004_remove_nodes_is_active_nodes_last_seen_nodes_status_and_more.py
deleted file mode 100644
index 7d13c7d..0000000
--- a/backend/manager/migrations/0004_remove_nodes_is_active_nodes_last_seen_nodes_status_and_more.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Generated by Django 5.0 on 2024-01-25 09:36
-
-import django.utils.timezone
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("manager", "0003_delete_task"),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name="nodes",
- name="is_active",
- ),
- migrations.AddField(
- model_name="nodes",
- name="last_seen",
- field=models.DateTimeField(
- blank=True, default=django.utils.timezone.now, null=True
- ),
- ),
- migrations.AddField(
- model_name="nodes",
- name="status",
- field=models.CharField(default="free", max_length=10),
- ),
- migrations.AlterField(
- model_name="nodes",
- name="gpu_info",
- field=models.TextField(blank=True, null=True),
- ),
- migrations.AlterField(
- model_name="nodes",
- name="ip",
- field=models.CharField(max_length=15, unique=True),
- ),
- migrations.AlterField(
- model_name="nodes",
- name="port",
- field=models.IntegerField(blank=True, null=True),
- ),
- ]
diff --git a/backend/manager/migrations/0005_nodes_name.py b/backend/manager/migrations/0005_nodes_name.py
deleted file mode 100644
index e37699a..0000000
--- a/backend/manager/migrations/0005_nodes_name.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 5.0 on 2024-01-25 10:42
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("manager", "0004_remove_nodes_is_active_nodes_last_seen_nodes_status_and_more"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="nodes",
- name="name",
- field=models.CharField(blank=True, max_length=15, null=True, unique=True),
- ),
- ]
diff --git a/backend/manager/migrations/0006_delete_nodes.py b/backend/manager/migrations/0006_delete_nodes.py
deleted file mode 100644
index ccc63c8..0000000
--- a/backend/manager/migrations/0006_delete_nodes.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-25 11:41
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("manager", "0005_nodes_name"),
- ]
-
- operations = [
- migrations.DeleteModel(
- name="Nodes",
- ),
- ]
diff --git a/backend/manager/templates/manager/base.html b/backend/manager/templates/manager/base.html
index 4b1a8ad..91f42b7 100644
--- a/backend/manager/templates/manager/base.html
+++ b/backend/manager/templates/manager/base.html
@@ -17,9 +17,7 @@
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous">
-
+
diff --git a/backend/manager/tests/__init__.py b/backend/manager/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/backend/manager/tests/test_views.py b/backend/manager/tests/test_views.py
new file mode 100644
index 0000000..08116fc
--- /dev/null
+++ b/backend/manager/tests/test_views.py
@@ -0,0 +1,39 @@
+from django.test import TestCase, Client
+from django.urls import reverse
+from common_models.models import Task # Załóżmy, że mamy model Task
+
+class AddTaskFormTest(TestCase):
+
+ def setUp(self):
+ # Ustawienie klienta testowego
+ self.client = Client()
+ # self.add_task_url = reverse('/manager/task/add_task/') # Nazwa URL powiązana z widokiem add_task_form
+ self.add_task_url = '/manager/task/add_task/'
+ def test_add_task_form_get(self):
+ # Testowanie odpowiedzi na żądanie GET
+ response = self.client.get(self.add_task_url)
+ self.assertEqual(response.status_code, 200)
+
+ def test_add_task_form_post(self):
+ post_data = {
+ 'path': 'ścieżka/do/pliku.mx3',
+ 'priority': 'normal',
+ 'gpu_partition': 'normal',
+ 'est': '1', # Przesyłanie liczby godzin jako ciąg znaków
+ }
+
+ response = self.client.post(self.add_task_url, post_data)
+ self.assertEqual(response.status_code, 302) # Przekierowanie po pomyślnym dodaniu
+
+ self.assertEqual(Task.objects.count(), 1)
+ task = Task.objects.first()
+ self.assertEqual(task.path, post_data['path'])
+ self.assertEqual(task.priority, post_data['priority'])
+ self.assertEqual(task.gpu_partition, post_data['gpu_partition'])
+
+ # Sprawdzenie, czy 'est' jest ustawione i porównanie wartości
+ if task.est is not None:
+ self.assertEqual(task.est, post_data['est'])
+ else:
+ # Jeśli 'est' jest None, upewnij się, że przesłane 'est' było puste
+ self.assertEqual(post_data['est'], '')
\ No newline at end of file
diff --git a/backend/manager/urls.py b/backend/manager/urls.py
index edba760..5857216 100644
--- a/backend/manager/urls.py
+++ b/backend/manager/urls.py
@@ -7,24 +7,10 @@
router.register(r'tasks', TaskViewSet)
urlpatterns = [
-
- #OLD LINK TO FIX:
- path('get_task/', views.get_task, name='get_task'),
- path('finish_task/', views.finish_task, name='finish_task'),
- # path('send_command/', views.send_command, name='send_command'),
-
- path('tasks/', task_list, name='task_list'),
- path('task/add_new_task/', TaskManagerView.as_view(), name='add_task_form'),
- path('task/edit//', TaskManagerView.as_view(), name='edit_task'),
- path('task/delete//', TaskManagerView.as_view(), name='delete_task'),
-
-
- path('task//pause/', views.pause_task, name='pause_task'),
- path('task//resume/', views.resume_task, name='resume_task'),
- # path('task//priority//', views.update_priority, name='update_priority'),
-
-
-
+
+ path('task/', TaskListView.as_view(), name='task_list'),
+ path('task///', TaskManagerView.as_view(), name='task_action_id'),
+ path('task//', TaskManagerView.as_view(), name='task_action'),
# path('', include(router.urls)),
# path('', views.index, name='index'),
@@ -41,8 +27,6 @@
####NODE-MANAGEMENT####
path('node-management/', NodeManagementView.as_view(), name='node_management'),
- ####TASK-RUN####
- path('task//', TaskRunView.as_view(), name='task_action'),
]
\ No newline at end of file
diff --git a/backend/manager/views.py b/backend/manager/views.py
index ef2a5e8..21842cb 100644
--- a/backend/manager/views.py
+++ b/backend/manager/views.py
@@ -6,27 +6,24 @@
from django.shortcuts import get_object_or_404, redirect
from django.http import HttpResponse
from django.db.models import Q
-
-from rest_framework import viewsets
-from common_models.models import *
-from .serializers import TaskSerializer
-from .components.nodes_monitor import NodesMonitor
-# Tymczasowe wyłączenie tokenów
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
+from django.contrib import messages
+from django.urls import reverse
+from rest_framework.renderers import TemplateHTMLRenderer, JSONRenderer
+from rest_framework.parsers import JSONParser
+from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
-# from .s import Nodes
+from common_models.models import *
+from .components.forms import EditTaskForm, AddTaskForm
+from .serializers import TaskSerializer
+from .components.nodes_monitor import NodesMonitor
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
-from .components.forms import EditTaskForm, AddTaskForm
-
-from django.urls import reverse
-# @csrf_exempt
-
from datetime import timedelta
@csrf_exempt
@@ -50,9 +47,9 @@ def add_task(request):
@csrf_exempt
def get_task(request):
if request.method == "GET":
- task = Task.objects.filter(status="waiting").order_by("id").first()
+ task = Task.objects.filter(status="Waiting").order_by("id").first()
if task:
- task.status = "running"
+ task.status = "Running"
task.start_time = timezone.now() # Ustaw czas rozpoczęcia zadania
task.save()
return JsonResponse(
@@ -72,8 +69,8 @@ def finish_task(request):
task_id = request.POST.get("task_id")
if task_id:
try:
- task = Task.objects.get(id=task_id, status="running")
- task.status = "finished"
+ task = Task.objects.get(id=task_id, status="Running")
+ task.status = "Finished"
task.end_time = timezone.now() # Ustaw czas zakończenia zadania
task.save()
return JsonResponse({"status": "success", "message": "Task finished"})
@@ -87,56 +84,11 @@ def finish_task(request):
return JsonResponse(
{"status": "error", "message": "Only POST method is allowed"}
)
-
-
-def index(request):
- tasks = Task.objects.all()
- return render(request, "scheduler/index.html", {"tasks": tasks})
-
-
-@csrf_exempt
-def pause_task(request, task_id):
- task = get_object_or_404(Task, id=task_id)
- task.status = "paused"
- task.save()
- return redirect("index") # Powrót do strony głównej
-
-
-@csrf_exempt
-def resume_task(request, task_id):
- task = get_object_or_404(Task, id=task_id)
- if task.status == "paused":
- task.status = "waiting"
- task.save()
- return redirect("index")
-
-
class TaskViewSet(viewsets.ModelViewSet):
queryset = Task.objects.all()
serializer_class = TaskSerializer
-def task_list(request):
-
- waiting_tasks = Task.objects.filter(status='waiting')
- active_tasks = Task.objects.filter(status='pending')
- finished_tasks = Task.objects.filter(status='finished')
-
- tasks = Task.objects.all()
- for task in tasks:
- task.est = format_timedelta(task.est) if task.est else None
-
- return render(request, "manager/task_list.html", {"tasks": waiting_tasks,"active_tasks": active_tasks})
-
-def format_timedelta(td):
- total_seconds = int(td.total_seconds())
- hours = total_seconds // 3600
- minutes = (total_seconds % 3600) // 60
- seconds = total_seconds % 60
- return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
-
-
-
# @csrf_exempt
# async def send_command(request):
@@ -388,124 +340,185 @@ def get(self, request, *args, **kwargs):
gpus = Gpus.objects.all()
return render(request, "manager/gpus_list.html", {"gpus": gpus})
-
class TaskManagerView(APIView):
+ renderer_classes = [TemplateHTMLRenderer, JSONRenderer]
- def get(self, request, *args, **kwargs):
- path = request.path_info.split("/")[-3]
+ def get(self, request, action, *args, **kwargs):
task_id = kwargs.get("task_id")
- if path == "edit":
- # Return the response from the edit_task method
- return self.edit_task(request, task_id=task_id)
- elif path == "delete":
- # Return the response from the edit_task method
- return self.delete_task(request, task_id=task_id)
+ methods = {
+ "edit": self.edit_task,
+ "delete": self.delete_task,
+ "run": self.run_task,
+ "cancel": self.cancel_task,
+ "redo": self.redo_task,
+ "add_task": self.add_task_form
+ }
+
+ if action in methods:
+ return methods[action](request, task_id=task_id)
else:
- form = AddTaskForm()
- return render(request, 'manager/task_form.html', {'form': form})
+ # Redirect or return JSON response for invalid action
+ if request.accepted_renderer.format == 'json':
+ return Response({"error": "Invalid action"}, status=400)
+ else:
+ return redirect("task_list")
+
def post(self, request, *args, **kwargs):
- form = AddTaskForm(request.POST)
- if form.is_valid():
- form.save()
- return redirect("task_list")
+ action = kwargs.get("action")
+ if action == "add_task":
+ return self.add_task_form(request)
+ elif action == "edit_task":
+ return self.edit_task(request, task_id=kwargs.get("task_id"))
else:
- return render(request, 'manager/task_form.html', {'form': form})
+ if request.accepted_renderer.format == 'json':
+ return Response({"error": "Invalid action"}, status=400)
+ else:
+ return redirect("task_list")
@csrf_exempt
- def edit_task(self, request, task_id):
+ def edit_task(self, request, task_id=None):
task = get_object_or_404(Task, pk=task_id)
if request.method == "POST":
form = EditTaskForm(request.POST, instance=task)
if form.is_valid():
form.save()
- return redirect("task_list")
+ if request.accepted_renderer.format == 'json':
+ return Response({"message": "Task updated successfully!"})
+ elif request.accepted_renderer.format == 'html':
+ messages.success(request, "Task updated successfully!",extra_tags='primary')
+ return redirect("task_list")
+ else:
+ return redirect("task_list")
else:
form = EditTaskForm(instance=task)
-
- return render(request, "manager/edit_task.html", {"form": form})
+
+ if request.accepted_renderer.format == 'json':
+ return Response(form.errors, status=400)
+ else:
+ return render(request, "manager/edit_task.html", {"form": form, "task": task})
@csrf_exempt
- def delete_task(self, request, task_id):
+ def delete_task(self, request, task_id=None):
task = get_object_or_404(Task, pk=task_id)
task.delete()
- return redirect("task_list")
-
-
-class TaskRunView(APIView):
- def get(self, request, task_id,action):
- # Wybór odpowiedniej akcji na podstawie ścieżki
- if action == 'run':
- return self.run_task(task_id,request)
- elif action == 'cancel':
- return self.cancel_task(task_id,request)
- elif action == 'redo':
- return self.redo_task(task_id,request)
+ if request.accepted_renderer.format == 'json':
+ return Response({"message": "Task deleted successfully"})
+ elif request.accepted_renderer.format == 'html':
+ messages.success(request, "Task canceled successfully!",extra_tags='primary')
+ return redirect("task_list")
else:
- return HttpResponse("Invalid action", status=400)
- def get_task_list(self,request):
- waiting_tasks = Task.objects.filter(status='waiting')
- pending_tasks = Task.objects.filter(
- Q(status='pending') | Q(status='running')
- )
- # finished_tasks = Task.objects.filter(status='finished')
-
- tasks = Task.objects.all()
- for task in tasks:
- task.est = format_timedelta(task.est) if task.est else None
-
- return render(request, "manager/task_list.html", {"tasks": waiting_tasks,"active_tasks": pending_tasks})
+ return redirect("task_list")
def select_gpu_for_task(self):
- # Przykładowa funkcja do wyboru GPU na podstawie wymagań zadania
- # Tutaj można dodać bardziej złożoną logikę dopasowania GPU do zadania
return Gpus.objects.filter(status=0).first()
def get_priority_task(self):
- # Przykładowa funkcja do wyboru najwyższego priorytetu zadania
return Task.objects.filter(status='waiting').order_by('-priority').first()
-
- def run_task(self, task_id, request = None):
- task = self.get_priority_task() if task_id is None else Task.objects.get(id=task_id)
- if not task:
- return HttpResponse("No task available or specified task does not exist.", status=404)
-
+
+ def run_task(self, request, task_id=None):
+ task = self.get_priority_task() if task_id is None else get_object_or_404(Task, id=task_id)
gpu = self.select_gpu_for_task()
if not gpu:
- return HttpResponse("No available GPUs.", status=503)
+ message = "No available GPUs."
+ if request.accepted_renderer.format == 'json':
+ return Response({"error": message}, status=400)
+ elif request.accepted_renderer.format == 'html':
+ messages.success(request, message ,extra_tags='danger')
+ return redirect("task_list")
+ else:
+ return redirect("task_list") ############ PROPABLY IT's the same as above
- # Przydzielenie GPU do zadania i aktualizacja statusów
- task.assigned_gpu = f"N{gpu.node_id.id}/G{gpu.id}"
- task.assigned_node = f"{gpu.node_id.ip}" # Convert gpu.node_id to a string
- task.status = 'pending'
+ task.assigned_gpu_id = f"N{gpu.node_id.id}/G{gpu.id}"
+ task.assigned_node_id = f"{gpu.node_id.ip}"
+ task.status = 'Pending'
task.save()
- gpu.status = 'Bussy'
- gpu.task_id = str(task.id) # Convert task.id to a string
+ gpu.status = 'Running'
+ gpu.task_id = task
gpu.save()
- # Logika uruchomienia zadania na GPU
- redirect("task_list")
- # return self.get_task_list(request)
- def cancel_task(self,task_id, request=None):
- task = Task.objects.get(id=task_id)
- task.assigned_gpu = None
- task.assigned_node = None
- task.status = 'waiting'
+ if request.accepted_renderer.format == 'json':
+ return Response({"message": "Task is running"})
+ else:
+ return redirect("task_list")
+
+ def cancel_task(self, request, task_id=None):
+ task = get_object_or_404(Task, id=task_id)
+ task.assigned_gpu_id = None
+ task.assigned_node_id = None
+ task.status = "Waiting"
task.save()
gpu = Gpus.objects.get(id=task_id)
- gpu.status = 0
+ gpu.status = "Waiting"
gpu.task_id = None
+ gpu.last_update = timezone.now()
gpu.save()
+
+ if request.accepted_renderer.format == 'json':
+ return Response({"message": "Task cancelled"})
+ else:
+ return redirect("task_list")
+
+ def redo_task(self, request, task_id=None):
+ # Logic to redo the task
+ # ...
+
+ if request.accepted_renderer.format == 'json':
+ return Response({"message": f"Task {task_id} redo initiated"})
+ else:
+ return HttpResponse(f"Task {task_id} redo initiated")
- if request:
- return self.get_task_list(request)
- else:
- return HttpResponse(f"Task {task_id} canceled.")
+ def add_task_form(self, request,task_id=None):
+ if request.method == 'GET':
+ form = AddTaskForm()
+ if request.accepted_renderer.format == 'json':
+ # W przypadku odpowiedzi JSON, zwracamy pustą strukturę formularza
+ serializer = TaskSerializer(data=request.data)
+ return Response(serializer.data)
+ else:
+ # W przypadku odpowiedzi HTML, renderujemy formularz HTML
+ return render(request, 'manager/task_form.html', {'form': form})
+
+ elif request.method == 'POST':
+ # Obsługa żądania POST dla tworzenia nowego zadania
+ if request.accepted_renderer.format == 'json':
+ data = JSONParser().parse(request)
+ serializer = TaskSerializer(data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data, status=201)
+ return Response(serializer.errors, status=400)
+ else:
+ form = AddTaskForm(request.POST)
+ if form.is_valid():
+ form.save()
+ return redirect("task_list")
+ else:
+ return render(request, 'manager/task_form.html', {'form': form})
+
+class TaskListView(APIView):
+ renderer_classes = [TemplateHTMLRenderer, JSONRenderer]
+ def get(self, request):
+ waiting_tasks = Task.objects.filter(
+ Q(status='Waiting') | Q(status='Waiting') | Q(status='Interrupted') | Q(status=None)
+ )
+ pending_tasks = Task.objects.filter(
+ Q(status='Pending') | Q(status='Running') | Q(status=None)
+ )
+
+ tasks = Task.objects.all()
+ data = {
+ "tasks": waiting_tasks,
+ # "tasks": tasks,
+ "active_tasks": pending_tasks
+ }
+ # Return a JSON response if the request is for API
+ if request.accepted_renderer.format == 'json':
+ return Response(data)
- def redo_task(self, task_id,request=None):
- # Logika ponownego uruchamiania zadania
- return HttpResponse(f"Task {task_id} redo initiated.")
\ No newline at end of file
+ # Otherwise, render the HTML template
+ return Response(data, template_name="manager/task_list.html")
\ No newline at end of file
diff --git a/backend/node/functions/gpu_monitor.py b/backend/node/functions/gpu_monitor.py
index 13b7ca4..ae2a8a7 100644
--- a/backend/node/functions/gpu_monitor.py
+++ b/backend/node/functions/gpu_monitor.py
@@ -140,6 +140,7 @@ def assign_gpus(self, node_id):
for gpu_key, gpu in self.gpus_status.items():
data = {
"action": "assign_node_gpu",
+ "no": gpu_key,
"brand_name": gpu["name"],
"gpu_util": gpu["gpu_util"],
"status": gpu["status"],
@@ -177,6 +178,7 @@ def submit_update_gpu_status(self,node_id):
for gpu_key, gpu in self.gpus_status.items():
data = {
"action": "update_node_gpu_status",
+ "no": gpu_key,
"brand_name": gpu["name"],
"gpu_util": gpu["gpu_util"],
"status": gpu["status"],
diff --git a/backend/node/migrations/0001_initial.py b/backend/node/migrations/0001_initial.py
index a357a29..61a8ca5 100644
--- a/backend/node/migrations/0001_initial.py
+++ b/backend/node/migrations/0001_initial.py
@@ -1,4 +1,4 @@
-# Generated by Django 4.2.9 on 2024-01-25 22:43
+# Generated by Django 4.2.9 on 2024-01-28 20:39
from django.db import migrations, models
@@ -12,16 +12,21 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name="Local",
fields=[
+ ("id", models.IntegerField(primary_key=True, serialize=False)),
+ ("node_id", models.CharField(max_length=15, unique=True)),
(
- "id",
- models.BigAutoField(
- auto_created=True,
- primary_key=True,
- serialize=False,
- verbose_name="ID",
+ "managerNmUrl",
+ models.CharField(
+ default="http://localhost:8000/manager/node-management/",
+ max_length=15,
+ ),
+ ),
+ (
+ "managerWsUrl",
+ models.CharField(
+ default="ws://localhost:8000/ws/node/", max_length=15
),
),
- ("node_id", models.CharField(max_length=15, unique=True)),
],
),
]
diff --git a/backend/node/migrations/0002_alter_local_id.py b/backend/node/migrations/0002_alter_local_id.py
deleted file mode 100644
index 7603ab4..0000000
--- a/backend/node/migrations/0002_alter_local_id.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-25 22:50
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("node", "0001_initial"),
- ]
-
- operations = [
- migrations.AlterField(
- model_name="local",
- name="id",
- field=models.IntegerField(primary_key=True, serialize=False),
- ),
- ]
diff --git a/backend/node/migrations/0003_local_url.py b/backend/node/migrations/0003_local_url.py
deleted file mode 100644
index 89bd002..0000000
--- a/backend/node/migrations/0003_local_url.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-26 11:45
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("node", "0002_alter_local_id"),
- ]
-
- operations = [
- migrations.AddField(
- model_name="local",
- name="url",
- field=models.CharField(
- default="http://localhost:8000/manager/node-management/", max_length=15
- ),
- ),
- ]
diff --git a/backend/node/migrations/0004_rename_url_local_managernmurl_local_managerwsurl.py b/backend/node/migrations/0004_rename_url_local_managernmurl_local_managerwsurl.py
deleted file mode 100644
index fc2a9c2..0000000
--- a/backend/node/migrations/0004_rename_url_local_managernmurl_local_managerwsurl.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Generated by Django 4.2.9 on 2024-01-27 09:28
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ("node", "0003_local_url"),
- ]
-
- operations = [
- migrations.RenameField(
- model_name="local",
- old_name="url",
- new_name="managerNmUrl",
- ),
- migrations.AddField(
- model_name="local",
- name="managerWsUrl",
- field=models.CharField(
- default="ws://localhost:8000/ws/node/", max_length=15
- ),
- ),
- ]
diff --git a/backend/node/node_websocket_client.py b/backend/node/node_websocket_client.py
index 30dc185..95c8df0 100644
--- a/backend/node/node_websocket_client.py
+++ b/backend/node/node_websocket_client.py
@@ -2,6 +2,7 @@
import websockets
import json
from asgiref.sync import sync_to_async
+import logging
async def get_node_id():
from node.models import Local
@@ -10,7 +11,7 @@ async def get_node_id():
return node_id.id
async def connect_to_manager():
- uri = "ws://manager:8000/ws/node/"
+ uri = "ws://localhost:8000/ws/node/"
while True:
try:
async with websockets.connect(uri) as websocket:
diff --git a/backend/node/views.py b/backend/node/views.py
index ef467d2..d334a7b 100644
--- a/backend/node/views.py
+++ b/backend/node/views.py
@@ -103,6 +103,7 @@ def get(self, request, task_id=None,action=None):
return self.redo_task(task_id,request)
else:
return self.get_task_list(request)
+
async def get_task_list(self,request):
node_id = await sync_to_async(Local.objects.get, thread_sensitive=True)(id=1)
waiting_tasks = Task.objects.filter(status='pending',node_id=node_id)
@@ -133,9 +134,9 @@ def run_task(self, task_id, request = None):
return HttpResponse("No available GPUs.", status=503)
# Przydzielenie GPU do zadania i aktualizacja statusów
- task.assigned_gpu = f"N{gpu.node_id.id}/G{gpu.id}"
- task.assigned_node = f"{gpu.node_id.ip}" # Convert gpu.node_id to a string
- task.status = 'running'
+ task.assigned_gpu_id = f"N{gpu.node_id.id}/G{gpu.id}"
+ task.assigned_node_id = f"{gpu.node_id.ip}" # Convert gpu.node_id to a string
+ task.status = 'Running'
task.save()
gpu.status = 'Bussy'
@@ -148,8 +149,8 @@ def run_task(self, task_id, request = None):
def cancel_task(self,task_id, request=None):
task = Task.objects.get(id=task_id)
- task.assigned_gpu = None
- task.assigned_node = None
+ task.assigned_gpu_id = None
+ task.assigned_node_id = None
task.status = 'waiting'
task.save()