Skip to content

Commit 745aae4

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 b008b96 commit 745aae4

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
@@ -1009,26 +1009,29 @@ def get_interface_b(self):
10091009

10101010

10111011
class BorderRouterManager(models.Manager):
1012-
def create(self, host):
1012+
def create(self, host, is_hsr=False):
10131013
"""
10141014
Create a BorderRouter object.
10151015
:param Host host: the host, defines the AS
1016+
:param bool is_hsr: this is a high-speed router instance
10161017
:returns: BorderRouter
10171018
"""
10181019
host.AS.hosts.bump_config()
10191020

10201021
return super().create(
10211022
AS=host.AS,
10221023
host=host,
1024+
is_hsr=is_hsr,
10231025
)
10241026

1025-
def first_or_create(self, host):
1027+
def first_or_create(self, host, is_hsr=False):
10261028
"""
10271029
Get the first border router related to this host, or create a new one with default settings.
10281030
:param Host host: the host, defines the AS
1031+
:param bool is_hsr: this is a high-speed router instance
10291032
:returns: BorderRouter
10301033
"""
1031-
return host.border_routers.first() or self.create(host=host)
1034+
return host.border_routers.first() or self.create(host=host, is_hsr=is_hsr)
10321035

10331036
def iterator_non_empty(self):
10341037
"""
@@ -1053,6 +1056,10 @@ class BorderRouter(models.Model):
10531056
related_name='border_routers',
10541057
on_delete=models.CASCADE
10551058
)
1059+
is_hsr = models.BooleanField(
1060+
default=False,
1061+
help_text="If true, this is a high-speed router instance with special configuration."
1062+
)
10561063

10571064
objects = BorderRouterManager()
10581065

@@ -1094,12 +1101,14 @@ def internal_port(self):
10941101
def metrics_port(self):
10951102
return BR_METRICS_PORT_BASE + self.instance_id
10961103

1097-
def update(self, host=_placeholder):
1104+
def update(self, host=_placeholder, is_hsr=_placeholder):
10981105
"""
10991106
Update the given fields
11001107
:param Host host: optional, the host. Must be in current AS.
1108+
:param bool is_hsr: optional, this is a high-speed router instance
11011109
"""
11021110
prev_host = self.host
1111+
prev_is_hsr = self.is_hsr
11031112

11041113
if host is not _placeholder:
11051114
if host.AS != self.AS:
@@ -1108,10 +1117,15 @@ def update(self, host=_placeholder):
11081117
raise RuntimeError('BorderRouter.update cannot change AS')
11091118
self.host = host
11101119

1120+
if is_hsr is not _placeholder:
1121+
self.is_hsr = is_hsr
1122+
11111123
self.save()
11121124

1113-
if host != prev_host:
1114-
host.AS.hosts.bump_config()
1125+
if self.host != prev_host:
1126+
self.AS.hosts.bump_config()
1127+
elif self.is_hsr != prev_is_hsr:
1128+
self.host.bump_config()
11151129

11161130

11171131
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)