Skip to content

Commit b03782b

Browse files
authored
Merge branch 'master' into filippociandy/ow_zt-to-global
2 parents 5b5db6f + 8288c23 commit b03782b

File tree

24 files changed

+523
-367
lines changed

24 files changed

+523
-367
lines changed

.github/workflows/ci.yml

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,6 @@ jobs:
1515
name: Python==${{ matrix.python-version }} | ${{ matrix.django-version }}
1616
runs-on: ubuntu-22.04
1717

18-
services:
19-
redis:
20-
image: redis
21-
ports:
22-
- 6379:6379
23-
postgres:
24-
image: postgis/postgis:13-3.3-alpine
25-
env:
26-
POSTGRES_PASSWORD: openwisp2
27-
POSTGRES_USER: openwisp2
28-
POSTGRES_DB: openwisp2
29-
ports:
30-
- 5432:5432
31-
3218
strategy:
3319
fail-fast: false
3420
matrix:
@@ -46,6 +32,19 @@ jobs:
4632
with:
4733
ref: ${{ github.event.pull_request.head.sha }}
4834

35+
- name: Cache APT packages
36+
uses: actions/cache@v4
37+
with:
38+
path: /var/cache/apt/archives
39+
key: apt-${{ runner.os }}-${{ hashFiles('.github/workflows/ci.yml') }}
40+
restore-keys: |
41+
apt-${{ runner.os }}-
42+
43+
- name: Disable man page auto-update
44+
run: |
45+
echo 'set man-db/auto-update false' | sudo debconf-communicate >/dev/null
46+
sudo dpkg-reconfigure man-db
47+
4948
- name: Set up Python ${{ matrix.python-version }}
5049
uses: actions/setup-python@v5
5150
with:
@@ -54,19 +53,6 @@ jobs:
5453
cache-dependency-path: |
5554
**/requirements*.txt
5655
57-
- uses: browser-actions/setup-chrome@v1
58-
# Using a fixed version, see here for more information on why:
59-
# https://github.com/openwisp/openwisp-controller/issues/902#issuecomment-2266219715
60-
# TODO: find a solution to allow using recent versions
61-
with:
62-
chrome-version: 125
63-
install-chromedriver: true
64-
id: setup-chrome
65-
66-
- run: |
67-
${{ steps.setup-chrome.outputs.chrome-path }} --version
68-
chromedriver --version
69-
7056
- name: Install Dependencies
7157
id: deps
7258
run: |
@@ -80,23 +66,28 @@ jobs:
8066
pip install -U -e .
8167
pip install ${{ matrix.django-version }}
8268
69+
- name: Start postgres and redis
70+
if: ${{ !cancelled() && steps.deps.conclusion == 'success' }}
71+
run: docker compose up -d postgres redis
72+
8373
- name: QA checks
8474
run: ./run-qa-checks
8575

8676
- name: Tests
8777
if: ${{ !cancelled() && steps.deps.conclusion == 'success' }}
8878
run: |
8979
coverage run runtests.py --parallel
90-
# the following command runs tests with Postgres/PostGIS but
91-
# only for specific test cases which are tagged with "db_tests"
92-
POSTGRESQL=1 coverage run runtests.py --parallel --keepdb
9380
# tests the extension capability
94-
SAMPLE_APP=1 coverage run ./runtests.py --parallel --keepdb
81+
SAMPLE_APP=1 coverage run ./runtests.py --parallel --keepdb --exclude-tag=selenium_tests
9582
coverage combine
9683
coverage xml
9784
env:
9885
SELENIUM_HEADLESS: 1
99-
CHROME_BIN: ${{ steps.setup-chrome.outputs.chrome-path }}
86+
GECKO_LOG: 1
87+
88+
- name: Show gecko web driver log on failures
89+
if: ${{ failure() }}
90+
run: cat geckodriver.log
10091

10192
- name: Upload Coverage
10293
if: ${{ success() }}

docs/developer/installation.rst

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Launch Redis and PostgreSQL:
4141

4242
.. code-block:: shell
4343
44-
docker-compose up -d redis postgres
44+
docker compose up -d redis postgres
4545
4646
Setup and activate a virtual-environment (we'll be using `virtualenv
4747
<https://pypi.org/project/virtualenv/>`_):
@@ -92,7 +92,8 @@ Launch development server:
9292
9393
You can access the admin interface at ``http://127.0.0.1:8000/admin/``.
9494

95-
Run tests with:
95+
Run tests with (make sure you have the :ref:`selenium dependencies
96+
<selenium_dependencies>` installed locally first):
9697

9798
.. code-block:: shell
9899
@@ -106,9 +107,6 @@ specific tests as follows:
106107

107108
.. code-block:: shell
108109
109-
# Run database tests against PostgreSQL backend
110-
POSTGRESQL=1 ./runtests.py --parallel
111-
112110
# Run only specific selenium tests classes
113111
cd tests/
114112
DJANGO_SETTINGS_MODULE=openwisp2.postgresql_settings ./manage.py test openwisp_controller.config.tests.test_selenium.TestDeviceAdmin
@@ -162,13 +160,13 @@ Build from the Dockerfile:
162160

163161
.. code-block:: shell
164162
165-
docker-compose build
163+
docker compose build
166164
167165
Run the docker container:
168166

169167
.. code-block:: shell
170168
171-
docker-compose up
169+
docker compose up
172170
173171
Troubleshooting Steps for Common Installation Issues
174172
----------------------------------------------------

openwisp_controller/config/base/config.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -272,29 +272,26 @@ def manage_vpn_clients(cls, action, instance, pk_set, **kwargs):
272272
else:
273273
templates = pk_set
274274

275-
# Get current VPNs in use by any template
276-
current_vpns = set(
277-
instance.templates.filter(type='vpn').values_list('vpn_id', flat=True)
278-
)
275+
# Delete VPN clients that are not associated with current templates
276+
instance.vpnclient_set.exclude(
277+
template_id__in=instance.templates.values_list('id', flat=True)
278+
).delete()
279279

280-
# Handle template actions
281-
for template in templates.filter(type='vpn'):
282-
if action == 'post_add':
280+
if action == 'post_add':
281+
for template in templates.filter(type='vpn'):
283282
# Create VPN client if needed
284283
if not vpn_client_model.objects.filter(
285-
config=instance, vpn=template.vpn
284+
config=instance, vpn=template.vpn, template=template
286285
).exists():
287286
client = vpn_client_model(
288287
config=instance,
289288
vpn=template.vpn,
289+
template=template,
290290
auto_cert=template.auto_cert,
291291
)
292292
client.full_clean()
293293
client.save()
294294

295-
# Clean up any VPN clients that aren't associated with current templates
296-
instance.vpnclient_set.exclude(vpn_id__in=current_vpns).delete()
297-
298295
@classmethod
299296
def clean_templates_org(cls, action, instance, pk_set, raw_data=None, **kwargs):
300297
"""

openwisp_controller/config/base/vpn.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,10 @@ class AbstractVpnClient(models.Model):
796796
config = models.ForeignKey(
797797
get_model_name('config', 'Config'), on_delete=models.CASCADE
798798
)
799+
template = models.ForeignKey(
800+
get_model_name('config', 'Template'),
801+
on_delete=models.CASCADE,
802+
)
799803
vpn = models.ForeignKey(get_model_name('config', 'Vpn'), on_delete=models.CASCADE)
800804
cert = models.OneToOneField(
801805
get_model_name('django_x509', 'Cert'),
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Generated by Django 4.2.18 on 2025-03-18 15:53
2+
3+
import django.db.models.deletion
4+
from django.conf import settings
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
dependencies = [
10+
("config", "0055_alter_config_status"),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name="vpnclient",
16+
name="template",
17+
field=models.ForeignKey(
18+
default=None,
19+
null=True,
20+
on_delete=django.db.models.deletion.CASCADE,
21+
to=settings.CONFIG_TEMPLATE_MODEL,
22+
),
23+
),
24+
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Generated by Django 3.2.15 on 2022-09-16 11:45
2+
3+
4+
from django.db import migrations
5+
6+
7+
def populate_vpnclient_template(apps, schema_editor):
8+
VpnClient = apps.get_model('config', 'VpnClient')
9+
10+
for vpn_client in VpnClient.objects.iterator():
11+
if vpn_client.template is None:
12+
vpn_client.template = vpn_client.config.templates.get(
13+
vpn_id=vpn_client.vpn_id
14+
)
15+
vpn_client.save()
16+
17+
18+
class Migration(migrations.Migration):
19+
dependencies = [
20+
('config', '0056_vpnclient_template'),
21+
]
22+
23+
operations = [
24+
migrations.RunPython(populate_vpnclient_template, migrations.RunPython.noop)
25+
]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 4.2.18 on 2025-03-18 15:55
2+
3+
import django.db.models.deletion
4+
from django.conf import settings
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
dependencies = [
10+
("config", "0057_populate_vpnclient_template"),
11+
]
12+
13+
operations = [
14+
migrations.AlterField(
15+
model_name="vpnclient",
16+
name="template",
17+
field=models.ForeignKey(
18+
on_delete=django.db.models.deletion.CASCADE,
19+
to=settings.CONFIG_TEMPLATE_MODEL,
20+
),
21+
),
22+
]

openwisp_controller/config/static/config/css/device-delete-confirmation.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
#deactivating-warning .warning p {
22
margin-top: 0px;
33
}
4+
#deactivating-warning .messagelist button {
5+
font-size: 15px;
6+
vertical-align: middle;
7+
line-height: inherit !important;
8+
padding: 0.625rem 1rem;
9+
}
10+
#deactivating-warning .messagelist button + button {
11+
margin-left: 10px;
12+
}
413
#main ul.messagelist li.warning ul li {
514
display: list-item;
615
padding: 0px;

openwisp_controller/config/static/config/js/device-delete-confirmation.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
(function ($) {
44
$(document).ready(function () {
55
$("#warning-ack").click(function (event) {
6-
event.preventDefault();
76
$("#deactivating-warning").slideUp("fast");
87
$("#delete-confirm-container").slideDown("fast");
98
$('input[name="force_delete"]').val("true");

openwisp_controller/config/templates/admin/config/device/delete_confirmation.html

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@
4646
but its configuration will remain active.
4747
{% endblocktranslate %}
4848
</p>
49-
<form>
50-
<input type="submit" class="button danger-btn" id="warning-ack"
51-
value="{% translate 'I understand the risks, delete the device' %}">
52-
<a class="button cancel-link">{% translate 'No, take me back' %}</a>
53-
</form>
49+
<span>
50+
<button class="danger-btn" id="warning-ack">{% translate 'I understand the risks, delete the device' %}</button>
51+
<button class="button cancel-link">{% translate 'No, take me back' %}</button>
52+
</span>
5453
</li>
5554
</ul>
5655
</div>

0 commit comments

Comments
 (0)