Skip to content

Commit 4d23078

Browse files
committed
Add minimal support for HSR configuration
For the high-speed router (HSR) instances running in the SCIONLab infrastructure, we need a special configuration (.toml) and run a different systemd unit. Instead of adding the very specific configuration settings for the HSR to the coordinator DB, we just avoid emitting any configuration file for now, leaving this to the host provisioning (by ansible). So, if the HSR flag is set for a router, we only add this to the list of wanted systemd units, nothing else.
1 parent 3849079 commit 4d23078

File tree

8 files changed

+661
-19
lines changed

8 files changed

+661
-19
lines changed

scionlab/admin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,19 +301,21 @@ class BorderRouterAdminForm(_CreateUpdateModelForm):
301301
def create(self):
302302
return BorderRouter.objects.create(
303303
host=self.cleaned_data['host'],
304+
is_hsr=self.cleaned_data['is_hsr'],
304305
)
305306

306307
def update(self):
307308
self.instance.update(
308309
host=self.cleaned_data['host'],
310+
is_hsr=self.cleaned_data['is_hsr'],
309311
)
310312

311313

312314
class BorderRouterInline(admin.TabularInline):
313315
model = BorderRouter
314316
extra = 0
315317
form = BorderRouterAdminForm
316-
fields = ('host',)
318+
fields = ('host', 'is_hsr')
317319

318320
def formfield_for_foreignkey(self, db_field, request, **kwargs):
319321
if db_field.name == "host":

scionlab/fixtures/testdata.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4525,101 +4525,121 @@
45254525
fields:
45264526
AS: 1
45274527
host: 1
4528+
is_hsr: false
45284529
- model: scionlab.borderrouter
45294530
pk: 2
45304531
fields:
45314532
AS: 3
45324533
host: 3
4534+
is_hsr: false
45334535
- model: scionlab.borderrouter
45344536
pk: 3
45354537
fields:
45364538
AS: 2
45374539
host: 2
4540+
is_hsr: false
45384541
- model: scionlab.borderrouter
45394542
pk: 4
45404543
fields:
45414544
AS: 4
45424545
host: 4
4546+
is_hsr: false
45434547
- model: scionlab.borderrouter
45444548
pk: 5
45454549
fields:
45464550
AS: 5
45474551
host: 5
4552+
is_hsr: true
45484553
- model: scionlab.borderrouter
45494554
pk: 6
45504555
fields:
45514556
AS: 6
45524557
host: 6
4558+
is_hsr: true
45534559
- model: scionlab.borderrouter
45544560
pk: 7
45554561
fields:
45564562
AS: 7
45574563
host: 7
4564+
is_hsr: false
45584565
- model: scionlab.borderrouter
45594566
pk: 8
45604567
fields:
45614568
AS: 8
45624569
host: 8
4570+
is_hsr: false
45634571
- model: scionlab.borderrouter
45644572
pk: 9
45654573
fields:
45664574
AS: 9
45674575
host: 9
4576+
is_hsr: false
45684577
- model: scionlab.borderrouter
45694578
pk: 10
45704579
fields:
45714580
AS: 10
45724581
host: 10
4582+
is_hsr: false
45734583
- model: scionlab.borderrouter
45744584
pk: 11
45754585
fields:
45764586
AS: 11
45774587
host: 11
4588+
is_hsr: false
45784589
- model: scionlab.borderrouter
45794590
pk: 12
45804591
fields:
45814592
AS: 12
45824593
host: 12
4594+
is_hsr: false
45834595
- model: scionlab.borderrouter
45844596
pk: 13
45854597
fields:
45864598
AS: 13
45874599
host: 13
4600+
is_hsr: false
45884601
- model: scionlab.borderrouter
45894602
pk: 14
45904603
fields:
45914604
AS: 14
45924605
host: 14
4606+
is_hsr: false
45934607
- model: scionlab.borderrouter
45944608
pk: 15
45954609
fields:
45964610
AS: 15
45974611
host: 15
4612+
is_hsr: false
45984613
- model: scionlab.borderrouter
45994614
pk: 16
46004615
fields:
46014616
AS: 16
46024617
host: 16
4618+
is_hsr: false
46034619
- model: scionlab.borderrouter
46044620
pk: 18
46054621
fields:
46064622
AS: 17
46074623
host: 17
4624+
is_hsr: false
46084625
- model: scionlab.borderrouter
46094626
pk: 20
46104627
fields:
46114628
AS: 18
46124629
host: 18
4630+
is_hsr: false
46134631
- model: scionlab.borderrouter
46144632
pk: 22
46154633
fields:
46164634
AS: 19
46174635
host: 19
4636+
is_hsr: false
46184637
- model: scionlab.borderrouter
46194638
pk: 24
46204639
fields:
46214640
AS: 20
46224641
host: 20
4642+
is_hsr: false
46234643
- model: scionlab.service
46244644
pk: 1
46254645
fields:

scionlab/fixtures/testtopo.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
from collections import namedtuple
16-
from scionlab.models.core import ISD, AS, Link, Host, Service
16+
from scionlab.models.core import ISD, AS, Link, Host, Service, BorderRouter
1717
from scionlab.models.user_as import AttachmentPoint
1818
from scionlab.models.vpn import VPN
1919

@@ -110,6 +110,12 @@ def makeLinkDef(type, as_id_tail_a, as_id_tail_b):
110110
(_expand_as_id(0x1301), Service.SIG),
111111
]
112112

113+
# Router instances (AS ID, router instance ID) with high-speed router configuration
114+
hsrs = [
115+
(_expand_as_id(0x1301), 1),
116+
(_expand_as_id(0x1302), 1),
117+
]
118+
113119
# VPNs for APs, except 1303
114120
vpns = [
115121
VPNDef(_expand_as_id(0x1107), "10.0.8.1", 1194, "10.0.0.0/16"), # odd subnet, used in prod!
@@ -124,6 +130,7 @@ def create_testtopo():
124130
create_links()
125131
create_vpn()
126132
create_extraservices()
133+
setup_hsrs()
127134

128135

129136
def create_isds():
@@ -156,6 +163,13 @@ def create_extraservices():
156163
Service.objects.create(host=host, type=as_serv[1])
157164

158165

166+
def setup_hsrs():
167+
for as_id, brid in hsrs:
168+
br = BorderRouter.objects.filter(AS__as_id=as_id)[brid-1]
169+
br.is_hsr = True
170+
br.save()
171+
172+
159173
def _create_as(isd_id, as_id, label, public_ip, is_core=False, is_ap=False):
160174
isd = ISD.objects.get(isd_id=isd_id)
161175
as_ = AS.objects.create_with_default_services(

scionlab/migrations/0002_hsr.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 3.2 on 2021-09-14 13:45
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('scionlab', '0001_squashed_0011_pullap'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='borderrouter',
15+
name='is_hsr',
16+
field=models.BooleanField(default=False, help_text='If true, this is a high-speed router instance with special configuration.'),
17+
),
18+
migrations.AlterField(
19+
model_name='service',
20+
name='type',
21+
field=models.CharField(choices=[('CS', 'Control Service'), ('SIG', 'SCION IP Gateway'), ('BW', 'Bandwidth tester server'), ('PP', 'Pingpong server')], max_length=16),
22+
),
23+
]

scionlab/models/core.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -968,26 +968,29 @@ def get_interface_b(self):
968968

969969

970970
class BorderRouterManager(models.Manager):
971-
def create(self, host):
971+
def create(self, host, is_hsr=False):
972972
"""
973973
Create a BorderRouter object.
974974
:param Host host: the host, defines the AS
975+
:param bool is_hsr: this is a high-speed router instance
975976
:returns: BorderRouter
976977
"""
977978
host.AS.hosts.bump_config()
978979

979980
return super().create(
980981
AS=host.AS,
981982
host=host,
983+
is_hsr=is_hsr,
982984
)
983985

984-
def first_or_create(self, host):
986+
def first_or_create(self, host, is_hsr=False):
985987
"""
986988
Get the first border router related to this host, or create a new one with default settings.
987989
:param Host host: the host, defines the AS
990+
:param bool is_hsr: this is a high-speed router instance
988991
:returns: BorderRouter
989992
"""
990-
return host.border_routers.first() or self.create(host=host)
993+
return host.border_routers.first() or self.create(host=host, is_hsr=is_hsr)
991994

992995
def iterator_non_empty(self):
993996
"""
@@ -1012,6 +1015,10 @@ class BorderRouter(models.Model):
10121015
related_name='border_routers',
10131016
on_delete=models.CASCADE
10141017
)
1018+
is_hsr = models.BooleanField(
1019+
default=False,
1020+
help_text="If true, this is a high-speed router instance with special configuration."
1021+
)
10151022

10161023
objects = BorderRouterManager()
10171024

@@ -1053,12 +1060,14 @@ def internal_port(self):
10531060
def metrics_port(self):
10541061
return BR_METRICS_PORT_BASE + self.instance_id
10551062

1056-
def update(self, host=_placeholder):
1063+
def update(self, host=_placeholder, is_hsr=_placeholder):
10571064
"""
10581065
Update the given fields
10591066
:param Host host: optional, the host. Must be in current AS.
1067+
:param bool is_hsr: optional, this is a high-speed router instance
10601068
"""
10611069
prev_host = self.host
1070+
prev_is_hsr = self.is_hsr
10621071

10631072
if host is not _placeholder:
10641073
if host.AS != self.AS:
@@ -1067,10 +1076,15 @@ def update(self, host=_placeholder):
10671076
raise RuntimeError('BorderRouter.update cannot change AS')
10681077
self.host = host
10691078

1079+
if is_hsr is not _placeholder:
1080+
self.is_hsr = is_hsr
1081+
10701082
self.save()
10711083

1072-
if host != prev_host:
1073-
host.AS.hosts.bump_config()
1084+
if self.host != prev_host:
1085+
self.AS.hosts.bump_config()
1086+
elif self.is_hsr != prev_is_hsr:
1087+
self.host.bump_config()
10741088

10751089

10761090
class ServiceManager(models.Manager):

scionlab/scion/config.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
SERVICES_TO_SYSTEMD_NAMES = {
4545
Service.CS: 'scion-control-service',
4646
Service.BW: 'scion-bwtestserver',
47-
TYPE_BR: 'scion-border-router',
4847
}
4948

5049
DEFAULT_ENV = ['TZ=UTC']
@@ -97,8 +96,9 @@ def _write_as_config(self, cb: '_ConfigBuilder'):
9796
config_dir = cb.config_dir.lstrip('/') # don't use absolute paths in the archive
9897

9998
for router in self._routers():
100-
self.archive.write_toml((config_dir, f'{router.instance_name}.toml'),
101-
cb.build_br_conf(router))
99+
if not router.is_hsr:
100+
self.archive.write_toml((config_dir, f'{router.instance_name}.toml'),
101+
cb.build_br_conf(router))
102102

103103
for service in self._control_services():
104104
assert service.type == Service.CS
@@ -166,7 +166,11 @@ def generate(self):
166166
# dispatcher and sciond config files are installed with the package
167167

168168
def systemd_units(self):
169-
units = ["scion-border-router@%s.service" % router.instance_name
169+
router_systemd_name = {
170+
False: 'scion-border-router',
171+
True: 'scion-hsr',
172+
}
173+
units = ["%s@%s.service" % (router_systemd_name[router.is_hsr], router.instance_name)
170174
for router in self._routers()]
171175
units += ["%s@%s.service" % (SERVICES_TO_SYSTEMD_NAMES[service.type], service.instance_name)
172176
for service in self._control_services()]
@@ -205,12 +209,13 @@ def _cmd(binary_name, config_dir, config_file):
205209
as_dir = self._as_dir()
206210
config = configparser.ConfigParser()
207211
for router in self._routers():
208-
_add_supervisord_program_conf(
209-
config,
210-
router.instance_name,
211-
_cmd(CMDS[TYPE_BR], as_dir, router.instance_name + '.toml'),
212-
env=BORDER_ENV
213-
)
212+
if not router.is_hsr:
213+
_add_supervisord_program_conf(
214+
config,
215+
router.instance_name,
216+
_cmd(CMDS[TYPE_BR], as_dir, router.instance_name + '.toml'),
217+
env=BORDER_ENV
218+
)
214219
for service in self._control_services():
215220
_add_supervisord_program_conf(
216221
config,

0 commit comments

Comments
 (0)