Skip to content

Commit e577760

Browse files
author
Søren Howe Gersager
committed
Merge branch 'release/5.6.3' into 'master'
Release/5.6.3 - master See merge request os2borgerpc/os2borgerpc-admin-site!286
2 parents 52dbd12 + ec6a692 commit e577760

File tree

17 files changed

+334
-1552
lines changed

17 files changed

+334
-1552
lines changed

.gitlab-ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ Lint Python:
5353
script:
5454
- cd admin_site
5555
- black --check --diff --exclude=migrations .
56-
- flake8 . --exclude=migrations
5756

5857
Lint Dockerfiles:
5958
<<: *lint-default

NEWS.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
Version 5.6.3, June 8, 2022
2+
---------------------------
3+
4+
New in this version:
5+
6+
- Add maintenance script support (scripts run as superuser)
7+
- Add a database index on PC uid field
8+
- Move print_db_files management command to the correct place
9+
- Remove flake8 from linters
10+
111
Version 5.6.2, June 2, 2022
212
---------------------------
313

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.6.2
1+
5.6.3

admin_site/requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ django-crispy-forms==1.13.0
88
django-extensions==3.1.5
99
django-storages==1.12.3
1010
django-xmlrpc==0.1.8
11-
flake8==4.0.1
1211
google-api-core==2.2.2
1312
google-auth==2.3.3
1413
google-cloud-core==2.2.1

admin_site/static/js/jobs_list.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ $(function(){
3434
}
3535
var script_link = '<a href="' + this.script_url + '">' + this.script_name + '</a>'
3636
var pc_link = '<a href="' + this.pc_url + '">' + this.pc_name + '</a>'
37+
var user_link = '<a href="' + this.user_url + '">' + this.user + '</a>'
3738
var item = $(BibOS.expandTemplate(
3839
'job-entry',
3940
$.extend(this, {
4041
'jobinfobutton': info_button,
4142
'script_link' : script_link,
42-
'pc_link' : pc_link
43+
'pc_link' : pc_link,
44+
'user_link': user_link
4345
})
4446
))
4547
item.find('input:checkbox').on("click", function() {

admin_site/system/admin.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
from hashlib import md5
2+
13
from django.contrib import admin
24
from django.db.models import Count
35
from django.utils import timezone
46
from django.utils.html import format_html_join, escape, mark_safe
57
from django.utils.translation import ugettext_lazy as _
68
from django.urls import reverse
7-
from hashlib import md5
89

910
from system.models import (
1011
Configuration,
@@ -218,6 +219,10 @@ class PCAdmin(admin.ModelAdmin):
218219
"last_seen",
219220
"created",
220221
)
222+
list_filter = (
223+
"site",
224+
"is_activated",
225+
)
221226
search_fields = ("name", "uid")
222227
readonly_fields = ("created",)
223228

@@ -242,7 +247,16 @@ def get_search_results(self, request, queryset, search_term):
242247

243248

244249
class JobAdmin(admin.ModelAdmin):
245-
list_display = ("__str__", "status", "user", "pc", "created", "started", "finished")
250+
list_display = (
251+
"__str__",
252+
"status",
253+
"user",
254+
"pc",
255+
"created",
256+
"started",
257+
"finished",
258+
)
259+
list_filter = ("status",)
246260
search_fields = ("batch__name", "user__username", "pc__name")
247261
readonly_fields = ("created", "started", "finished")
248262

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Copyright (C) 2021 Magenta ApS, https://magenta.dk.
2+
# Contact: [email protected].
3+
4+
from django.core.management.base import (
5+
BaseCommand,
6+
CommandError,
7+
)
8+
from django.db import transaction
9+
from django.contrib.auth import get_user_model
10+
from system.models import (
11+
Site,
12+
Script,
13+
Batch,
14+
Job,
15+
PCGroup,
16+
PC,
17+
)
18+
19+
User = get_user_model()
20+
21+
22+
class Command(BaseCommand):
23+
"""
24+
Run a script on pcs, group or site as maintenance jobs.
25+
26+
Notes:
27+
Only scripts without arguments are supported for now.
28+
Sites and Groups arguments take UID's while the PC argument takes ID's.
29+
The script does not validate that a given group, site or PC exists. In case one doesn't match, it's silently ignored.
30+
31+
Form:
32+
$ python manage.py run_maintenance_script <user_username> <script_uid_to_run> <batch_site_uid> {--pcs <target_pc_ids...> | --groups <target_group_uids...>| --sites <target_site_uids...>}
33+
Examples:
34+
35+
$ python manage.py run_maintenance_script shg 1 magenta --pcs 1 4
36+
$ python manage.py run_maintenance_script jabbi 3 magenta-test --groups group1
37+
$ python manage.py run_maintenance_script gitte 2 magenta --sites magenta mag test
38+
39+
40+
"""
41+
42+
help = "Run a maintenance job script on pcs, groups or sites"
43+
44+
def add_arguments(self, parser):
45+
parser.add_argument(
46+
"username", nargs="?", type=str, help="username of the user"
47+
)
48+
parser.add_argument("script", nargs="?", type=int, help="the id of the script")
49+
parser.add_argument(
50+
"script_site", nargs="?", type=str, help="the uid of the site"
51+
)
52+
parser.add_argument("--pcs", nargs="*", type=int, help="a list of pc uids")
53+
parser.add_argument("--sites", nargs="*", type=str, help="the uid of a site")
54+
parser.add_argument("--groups", nargs="*", type=str, help="the uid of a group")
55+
56+
@transaction.atomic
57+
def handle(self, *args, **options):
58+
script_id = options["script"]
59+
script_site_uid = options["script_site"]
60+
username = options["username"]
61+
62+
user = User.objects.filter(is_superuser=True, username=username).first()
63+
if not user:
64+
raise CommandError(f"User with username: {username} does not exist")
65+
66+
script = Script.objects.filter(id=script_id).first()
67+
if not script:
68+
raise CommandError(f"Script with ID: {script_id} does not exist")
69+
70+
script_site = Site.objects.filter(uid=script_site_uid).first()
71+
if not script_site:
72+
raise CommandError(f"Site with UID: {script_site_uid} does not exist")
73+
74+
if options["pcs"]:
75+
pcs = PC.objects.filter(id__in=options["pcs"])
76+
elif options["sites"]:
77+
site_uids = options["sites"]
78+
sites = Site.objects.filter(uid__in=site_uids)
79+
pcs = PC.objects.filter(site__in=sites)
80+
elif options["groups"]:
81+
group_ids = options["groups"]
82+
pc_groups = PCGroup.objects.filter(uid__in=group_ids)
83+
pcs = PC.objects.filter(pc_groups__in=pc_groups)
84+
else:
85+
raise CommandError("--pcs, --site or --group needs to be given")
86+
87+
self.stdout.write(
88+
self.style.SUCCESS(
89+
f"Do you want to run {script} on site {script_site}"
90+
f" as user {username} for {pcs.count()} PCs? (Y/y for yes)"
91+
)
92+
)
93+
confirmation = input()
94+
if confirmation in ["y", "Y"]:
95+
batch = Batch.objects.create(site=script_site, script=script, name="")
96+
for pc in pcs:
97+
Job.objects.create(user=user, batch=batch, pc=pc)
98+
self.stdout.write(
99+
self.style.SUCCESS(
100+
f"Maintenance job was created for pc: {pc}"
101+
f" for site: {script_site}"
102+
)
103+
)
104+
else:
105+
self.stdout.write(self.style.WARNING("Aborting"))
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 3.2.12 on 2022-06-07 14:01
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("system", "0053_auto_20220602_1522"),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name="pc",
15+
name="uid",
16+
field=models.CharField(verbose_name="UID", max_length=255, db_index=True),
17+
),
18+
]

admin_site/system/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ class PC(models.Model):
336336

337337
mac = models.CharField(verbose_name=_("MAC"), max_length=255, blank=True)
338338
name = models.CharField(verbose_name=_("name"), max_length=255)
339-
uid = models.CharField(verbose_name=_("UID"), max_length=255)
339+
uid = models.CharField(verbose_name=_("UID"), max_length=255, db_index=True)
340340
description = models.CharField(
341341
verbose_name=_("description"), max_length=1024, blank=True
342342
)

0 commit comments

Comments
 (0)