summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Vacek <patrickvacek@gmail.com>2019-05-27 14:59:14 +0200
committerGitHub <noreply@github.com>2019-05-27 14:59:14 +0200
commitd1291df592cd0ea20a61b21228d45995e1766458 (patch)
tree1232bb0041816dffc09f3e118356b018725c161e
parenta6c241c31f0afbf762a230db4b92c1758db66158 (diff)
parent8e9bbe95badbc889f3cd69caff8a223f65e6042d (diff)
downloadmeta-updater-d1291df592cd0ea20a61b21228d45995e1766458.tar.gz
Merge pull request #520 from advancedtelematic/feat/OTA-2541/preconfigured-secondaries
Posix/IP Secondary and Primary Support
-rw-r--r--lib/oeqa/selftest/cases/testutils.py53
-rw-r--r--lib/oeqa/selftest/cases/updater_qemux86_64.py151
-rwxr-xr-xrecipes-sota/aktualizr/aktualizr_git.bb7
-rw-r--r--recipes-sota/aktualizr/files/aktualizr-secondary.service6
-rw-r--r--recipes-sota/aktualizr/files/aktualizr-secondary.socket6
-rw-r--r--recipes-test/big-update/big-update_1.0.bb2
-rw-r--r--recipes-test/big-update/big-update_2.0.bb2
-rw-r--r--recipes-test/demo-config/files/30-fake_pacman.toml2
-rw-r--r--recipes-test/demo-config/files/30-secondary_config.toml2
-rw-r--r--recipes-test/demo-config/files/35-network_config.toml4
-rw-r--r--recipes-test/demo-config/files/45-id_config.toml3
-rw-r--r--recipes-test/demo-config/files/ip_secondary_config.json7
-rw-r--r--recipes-test/demo-config/primary-config.bb68
-rw-r--r--recipes-test/demo-config/secondary-config.bb41
-rw-r--r--recipes-test/demo-config/shared-conf.inc5
-rw-r--r--recipes-test/demo-network-config/files/26-static-client.network7
-rw-r--r--recipes-test/demo-network-config/primary-network-config.bb17
-rw-r--r--recipes-test/demo-network-config/secondary-network-config.bb17
-rw-r--r--recipes-test/demo-network-config/static-network-config.inc16
-rw-r--r--recipes-test/images/primary-image.bb6
-rw-r--r--recipes-test/images/secondary-image.bb5
-rw-r--r--scripts/qemucommand.py4
22 files changed, 338 insertions, 93 deletions
diff --git a/lib/oeqa/selftest/cases/testutils.py b/lib/oeqa/selftest/cases/testutils.py
index 2ad99ad..f8b1904 100644
--- a/lib/oeqa/selftest/cases/testutils.py
+++ b/lib/oeqa/selftest/cases/testutils.py
@@ -7,49 +7,57 @@ from time import sleep
7from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars 7from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
8from qemucommand import QemuCommand 8from qemucommand import QemuCommand
9 9
10logger = logging.getLogger("selftest")
10 11
11def qemu_launch(efi=False, machine=None, imagename=None): 12
12 logger = logging.getLogger("selftest") 13def qemu_launch(efi=False, machine=None, imagename='core-image-minimal', **kwargs):
13 if imagename is None: 14 qemu_bake_image(imagename)
14 imagename = 'core-image-minimal' 15 return qemu_boot_image(efi=efi, machine=machine, imagename=imagename, **kwargs)
15 logger.info('Running bitbake to build {}'.format(imagename)) 16
16 bitbake(imagename) 17
18def qemu_terminate(s):
19 try:
20 s.terminate()
21 s.wait(timeout=10)
22 except KeyboardInterrupt:
23 pass
24
25
26def qemu_boot_image(imagename, **kwargs):
17 # Create empty object. 27 # Create empty object.
18 args = type('', (), {})() 28 args = type('', (), {})()
19 args.imagename = imagename 29 args.imagename = imagename
20 args.mac = None 30 args.mac = kwargs.get('mac', None)
21 # Could use DEPLOY_DIR_IMAGE here but it's already in the machine 31 # Could use DEPLOY_DIR_IMAGE here but it's already in the machine
22 # subdirectory. 32 # subdirectory.
23 args.dir = 'tmp/deploy/images' 33 args.dir = 'tmp/deploy/images'
24 args.efi = efi 34 args.efi = kwargs.get('efi', False)
25 args.machine = machine 35 args.machine = kwargs.get('machine', None)
26 qemu_use_kvm = get_bb_var("QEMU_USE_KVM") 36 qemu_use_kvm = get_bb_var("QEMU_USE_KVM")
27 if qemu_use_kvm and \ 37 if qemu_use_kvm and \
28 (qemu_use_kvm == 'True' and 'x86' in machine or 38 (qemu_use_kvm == 'True' and 'x86' in args.machine or
29 get_bb_var('MACHINE') in qemu_use_kvm.split()): 39 get_bb_var('MACHINE') in qemu_use_kvm.split()):
30 args.kvm = True 40 args.kvm = True
31 else: 41 else:
32 args.kvm = None # Autodetect 42 args.kvm = None # Autodetect
33 args.no_gui = True 43 args.no_gui = kwargs.get('no_gui', True)
34 args.gdb = False 44 args.gdb = kwargs.get('gdb', False)
35 args.pcap = None 45 args.pcap = kwargs.get('pcap', None)
36 args.overlay = None 46 args.overlay = kwargs.get('overlay', None)
37 args.dry_run = False 47 args.dry_run = kwargs.get('dry_run', False)
38 args.secondary_network = False 48 args.secondary_network = kwargs.get('secondary_network', False)
39 49
40 qemu = QemuCommand(args) 50 qemu = QemuCommand(args)
41 cmdline = qemu.command_line() 51 cmdline = qemu.command_line()
42 print('Booting image with run-qemu-ota...') 52 print('Booting image with run-qemu-ota...')
43 s = subprocess.Popen(cmdline) 53 s = subprocess.Popen(cmdline)
44 sleep(10) 54 sleep(kwargs.get('wait_for_boot_time', 10))
45 return qemu, s 55 return qemu, s
46 56
47 57
48def qemu_terminate(s): 58def qemu_bake_image(imagename):
49 try: 59 logger.info('Running bitbake to build {}'.format(imagename))
50 s.terminate() 60 bitbake(imagename)
51 except KeyboardInterrupt:
52 pass
53 61
54 62
55def qemu_send_command(port, command, timeout=60): 63def qemu_send_command(port, command, timeout=60):
@@ -122,7 +130,6 @@ def verifyProvisioned(testInst, machine):
122 m = p.search(stdout.decode()) 130 m = p.search(stdout.decode())
123 testInst.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) 131 testInst.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
124 testInst.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) 132 testInst.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
125 logger = logging.getLogger("selftest")
126 logger.info('Device successfully provisioned with ID: ' + m.group(1)) 133 logger.info('Device successfully provisioned with ID: ' + m.group(1))
127 134
128# vim:set ts=4 sw=4 sts=4 expandtab: 135# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/oeqa/selftest/cases/updater_qemux86_64.py b/lib/oeqa/selftest/cases/updater_qemux86_64.py
index 9f32bcf..f951bc7 100644
--- a/lib/oeqa/selftest/cases/updater_qemux86_64.py
+++ b/lib/oeqa/selftest/cases/updater_qemux86_64.py
@@ -4,11 +4,12 @@ import logging
4import re 4import re
5import unittest 5import unittest
6from time import sleep 6from time import sleep
7from uuid import uuid4
7 8
8from oeqa.selftest.case import OESelftestTestCase 9from oeqa.selftest.case import OESelftestTestCase
9from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars 10from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
10from testutils import qemu_launch, qemu_send_command, qemu_terminate, \ 11from testutils import qemu_launch, qemu_send_command, qemu_terminate, \
11 akt_native_run, verifyNotProvisioned, verifyProvisioned 12 akt_native_run, verifyNotProvisioned, verifyProvisioned, qemu_bake_image, qemu_boot_image
12 13
13 14
14class GeneralTests(OESelftestTestCase): 15class GeneralTests(OESelftestTestCase):
@@ -309,7 +310,91 @@ class HsmTests(OESelftestTestCase):
309 verifyProvisioned(self, machine) 310 verifyProvisioned(self, machine)
310 311
311 312
312class SecondaryTests(OESelftestTestCase): 313class IpSecondaryTests(OESelftestTestCase):
314
315 class Image:
316 def __init__(self, imagename, binaryname, machine='qemux86-64', bake=True, **kwargs):
317 self.machine = machine
318 self.imagename = imagename
319 self.boot_kwargs = kwargs
320 self.binaryname = binaryname
321 self.stdout = ''
322 self.stderr = ''
323 self.retcode = 0
324 if bake:
325 self.bake()
326
327 def bake(self):
328 self.configure()
329 qemu_bake_image(self.imagename)
330
331 def send_command(self, cmd):
332 stdout, stderr, retcode = qemu_send_command(self.qemu.ssh_port, cmd, timeout=60)
333 return str(stdout), str(stderr), retcode
334
335 def __enter__(self):
336 self.qemu, self.process = qemu_boot_image(machine=self.machine, imagename=self.imagename,
337 wait_for_boot_time=1, **self.boot_kwargs)
338 # wait until the VM is booted and is SSHable
339 self.wait_till_sshable()
340
341 def __exit__(self, exc_type, exc_val, exc_tb):
342 qemu_terminate(self.process)
343
344 def wait_till_sshable(self):
345 # qemu_send_command tries to ssh into the qemu VM and blocks until it gets there or timeout happens
346 # so it helps us to block q control flow until the VM is booted and a target binary/daemon is running there
347 self.stdout, self.stderr, self.retcode = self.send_command(self.binaryname + ' --help')
348
349 def was_successfully_booted(self):
350 return self.retcode == 0
351
352 class Secondary(Image):
353 def __init__(self, test_ctx):
354 self._test_ctx = test_ctx
355 self.sndry_serial = str(uuid4())
356 self.sndry_hw_id = 'qemux86-64-oeselftest-sndry'
357 self.id = (self.sndry_hw_id, self.sndry_serial)
358 super(IpSecondaryTests.Secondary, self).__init__('secondary-image', 'aktualizr-secondary',
359 secondary_network=True)
360
361 def configure(self):
362 self._test_ctx.append_config('SECONDARY_SERIAL_ID = "{}"'.format(self.sndry_serial))
363 self._test_ctx.append_config('SECONDARY_HARDWARE_ID = "{}"'.format(self.sndry_hw_id))
364
365 class Primary(Image):
366 def __init__(self, test_ctx):
367 self._test_ctx = test_ctx
368 super(IpSecondaryTests.Primary, self).__init__('primary-image', 'aktualizr', secondary_network=True)
369
370 def configure(self):
371 self._test_ctx.append_config('MACHINE = "qemux86-64"')
372 self._test_ctx.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
373
374 def is_ecu_registered(self, ecu_id):
375 max_number_of_tries = 20
376 try_counter = 0
377
378 # aktualizr-info is not always able to load ECU serials from DB
379 # so, let's run it a few times until it actually succeeds
380 while try_counter < max_number_of_tries:
381 device_status = self.get_info()
382 try_counter += 1
383 if device_status.find("load ECU serials") == -1:
384 break
385 sleep(1)
386
387 if not ((device_status.find(ecu_id[0]) != -1) and (device_status.find(ecu_id[1]) != -1)):
388 return False
389 not_registered_field = "Removed or not registered ecus:"
390 not_reg_start = device_status.find(not_registered_field)
391 return not_reg_start == -1 or (device_status.find(ecu_id[1], not_reg_start) == -1)
392
393 def get_info(self):
394 stdout, stderr, retcode = self.send_command('aktualizr-info')
395 self._test_ctx.assertEqual(retcode, 0, 'Unable to run aktualizr-info: {}'.format(stderr))
396 return stdout
397
313 def setUpLocal(self): 398 def setUpLocal(self):
314 layer = "meta-updater-qemux86-64" 399 layer = "meta-updater-qemux86-64"
315 result = runCmd('bitbake-layers show-layers') 400 result = runCmd('bitbake-layers show-layers')
@@ -323,57 +408,37 @@ class SecondaryTests(OESelftestTestCase):
323 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) 408 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu)
324 else: 409 else:
325 self.meta_qemu = None 410 self.meta_qemu = None
326 self.append_config('MACHINE = "qemux86-64"') 411
327 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 412 self.primary = IpSecondaryTests.Primary(self)
328 self.qemu, self.s = qemu_launch(machine='qemux86-64', imagename='secondary-image') 413 self.secondary = IpSecondaryTests.Secondary(self)
329 414
330 def tearDownLocal(self): 415 def tearDownLocal(self):
331 qemu_terminate(self.s)
332 if self.meta_qemu: 416 if self.meta_qemu:
333 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) 417 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True)
334 418
335 def qemu_command(self, command): 419 def test_ip_secondary_registration_if_secondary_starts_first(self):
336 return qemu_send_command(self.qemu.ssh_port, command) 420 with self.secondary:
421 self.assertTrue(self.secondary.was_successfully_booted(),
422 'The secondary failed to boot: {}'.format(self.secondary.stderr))
337 423
338 def test_secondary_present(self): 424 with self.primary:
339 print('Checking aktualizr-secondary is present') 425 self.assertTrue(self.primary.was_successfully_booted(),
340 stdout, stderr, retcode = self.qemu_command('aktualizr-secondary --help') 426 'The primary failed to boot: {}'.format(self.primary.stderr))
341 self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help")
342 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
343 427
428 self.assertTrue(self.primary.is_ecu_registered(self.secondary.id),
429 "The secondary wasn't registered at the primary: {}".format(self.primary.get_info()))
344 430
345class PrimaryTests(OESelftestTestCase): 431 def test_ip_secondary_registration_if_primary_starts_first(self):
346 def setUpLocal(self): 432 with self.primary:
347 layer = "meta-updater-qemux86-64" 433 self.assertTrue(self.primary.was_successfully_booted(),
348 result = runCmd('bitbake-layers show-layers') 434 'The primary failed to boot: {}'.format(self.primary.stderr))
349 if re.search(layer, result.output) is None:
350 # Assume the directory layout for finding other layers. We could also
351 # make assumptions by using 'show-layers', but either way, if the
352 # layers we need aren't where we expect them, we are out of luck.
353 path = os.path.abspath(os.path.dirname(__file__))
354 metadir = path + "/../../../../../"
355 self.meta_qemu = metadir + layer
356 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu)
357 else:
358 self.meta_qemu = None
359 self.append_config('MACHINE = "qemux86-64"')
360 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
361 self.append_config('SOTA_CLIENT_FEATURES = "secondary-network"')
362 self.qemu, self.s = qemu_launch(machine='qemux86-64', imagename='primary-image')
363 435
364 def tearDownLocal(self): 436 with self.secondary:
365 qemu_terminate(self.s) 437 self.assertTrue(self.secondary.was_successfully_booted(),
366 if self.meta_qemu: 438 'The secondary failed to boot: {}'.format(self.secondary.stderr))
367 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True)
368 439
369 def qemu_command(self, command): 440 self.assertTrue(self.primary.is_ecu_registered(self.secondary.id),
370 return qemu_send_command(self.qemu.ssh_port, command) 441 "The secondary wasn't registered at the primary: {}".format(self.primary.get_info()))
371
372 def test_aktualizr_present(self):
373 print('Checking aktualizr is present')
374 stdout, stderr, retcode = self.qemu_command('aktualizr --help')
375 self.assertEqual(retcode, 0, "Unable to run aktualizr --help")
376 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
377 442
378 443
379class ResourceControlTests(OESelftestTestCase): 444class ResourceControlTests(OESelftestTestCase):
diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb
index 903f2de..a97939e 100755
--- a/recipes-sota/aktualizr/aktualizr_git.bb
+++ b/recipes-sota/aktualizr/aktualizr_git.bb
@@ -22,7 +22,6 @@ SRC_URI = " \
22 file://run-ptest \ 22 file://run-ptest \
23 file://aktualizr.service \ 23 file://aktualizr.service \
24 file://aktualizr-secondary.service \ 24 file://aktualizr-secondary.service \
25 file://aktualizr-secondary.socket \
26 file://aktualizr-serialcan.service \ 25 file://aktualizr-serialcan.service \
27 file://10-resource-control.conf \ 26 file://10-resource-control.conf \
28 ${@ d.expand("https://ats-tuf-cli-releases.s3-eu-central-1.amazonaws.com/cli-${GARAGE_SIGN_PV}.tgz;unpack=0") if d.getVar('GARAGE_SIGN_AUTOVERSION') != '1' else ''} \ 27 ${@ d.expand("https://ats-tuf-cli-releases.s3-eu-central-1.amazonaws.com/cli-${GARAGE_SIGN_PV}.tgz;unpack=0") if d.getVar('GARAGE_SIGN_AUTOVERSION') != '1' else ''} \
@@ -32,7 +31,7 @@ SRC_URI = " \
32SRC_URI[md5sum] = "c5e9968dfe78a7264ab9a8338c11725d" 31SRC_URI[md5sum] = "c5e9968dfe78a7264ab9a8338c11725d"
33SRC_URI[sha256sum] = "3a19258d7a1825a308aca0da82f7a337985bec05e8951355c4c95f0fcf2444f4" 32SRC_URI[sha256sum] = "3a19258d7a1825a308aca0da82f7a337985bec05e8951355c4c95f0fcf2444f4"
34 33
35SRCREV = "c50feb37034eceb1254429d3e3ed38e5b8a0dc60" 34SRCREV = "8c523efc4c1f1e6d9dfd41b7e23a202ade4d9ff7"
36BRANCH ?= "master" 35BRANCH ?= "master"
37 36
38S = "${WORKDIR}/git" 37S = "${WORKDIR}/git"
@@ -45,7 +44,7 @@ PTEST_ENABLED = "0"
45 44
46SYSTEMD_PACKAGES = "${PN} ${PN}-secondary" 45SYSTEMD_PACKAGES = "${PN} ${PN}-secondary"
47SYSTEMD_SERVICE_${PN} = "aktualizr.service" 46SYSTEMD_SERVICE_${PN} = "aktualizr.service"
48SYSTEMD_SERVICE_${PN}-secondary = "aktualizr-secondary.socket" 47SYSTEMD_SERVICE_${PN}-secondary = "aktualizr-secondary.service"
49 48
50EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV} ${@bb.utils.contains('PTEST_ENABLED', '1', '-DTESTSUITE_VALGRIND=on', '', d)}" 49EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV} ${@bb.utils.contains('PTEST_ENABLED', '1', '-DTESTSUITE_VALGRIND=on', '', d)}"
51 50
@@ -100,7 +99,6 @@ do_install_append () {
100 install -m 0644 ${S}/config/sota_secondary.toml ${D}/${libdir}/sota/sota_secondary.toml 99 install -m 0644 ${S}/config/sota_secondary.toml ${D}/${libdir}/sota/sota_secondary.toml
101 install -m 0644 ${S}/config/sota_uboot_env.toml ${D}/${libdir}/sota/sota_uboot_env.toml 100 install -m 0644 ${S}/config/sota_uboot_env.toml ${D}/${libdir}/sota/sota_uboot_env.toml
102 install -d ${D}${systemd_unitdir}/system 101 install -d ${D}${systemd_unitdir}/system
103 install -m 0644 ${WORKDIR}/aktualizr-secondary.socket ${D}${systemd_unitdir}/system/aktualizr-secondary.socket
104 install -m 0644 ${WORKDIR}/aktualizr-secondary.service ${D}${systemd_unitdir}/system/aktualizr-secondary.service 102 install -m 0644 ${WORKDIR}/aktualizr-secondary.service ${D}${systemd_unitdir}/system/aktualizr-secondary.service
105 install -m 0700 -d ${D}${libdir}/sota/conf.d 103 install -m 0700 -d ${D}${libdir}/sota/conf.d
106 install -m 0700 -d ${D}${sysconfdir}/sota/conf.d 104 install -m 0700 -d ${D}${sysconfdir}/sota/conf.d
@@ -176,7 +174,6 @@ FILES_${PN}-examples = " \
176FILES_${PN}-secondary = " \ 174FILES_${PN}-secondary = " \
177 ${bindir}/aktualizr-secondary \ 175 ${bindir}/aktualizr-secondary \
178 ${libdir}/sota/sota_secondary.toml \ 176 ${libdir}/sota/sota_secondary.toml \
179 ${systemd_unitdir}/system/aktualizr-secondary.socket \
180 ${systemd_unitdir}/system/aktualizr-secondary.service \ 177 ${systemd_unitdir}/system/aktualizr-secondary.service \
181 " 178 "
182 179
diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.service b/recipes-sota/aktualizr/files/aktualizr-secondary.service
index 9628ee3..b577ae8 100644
--- a/recipes-sota/aktualizr/files/aktualizr-secondary.service
+++ b/recipes-sota/aktualizr/files/aktualizr-secondary.service
@@ -1,8 +1,12 @@
1[Unit] 1[Unit]
2Description=Aktualizr SOTA Client (UPTANE Secondary) 2Description=Aktualizr SOTA Client (UPTANE Secondary)
3After=network.target
3 4
4[Service] 5[Service]
5RestartSec=10 6RestartSec=10
6Restart=always 7Restart=always
7ExecStart=/usr/bin/aktualizr-secondary --config /usr/lib/sota/sota_secondary.toml 8ExecStart=/usr/bin/aktualizr-secondary
9
10[Install]
11WantedBy=multi-user.target
8 12
diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.socket b/recipes-sota/aktualizr/files/aktualizr-secondary.socket
deleted file mode 100644
index da0ee44..0000000
--- a/recipes-sota/aktualizr/files/aktualizr-secondary.socket
+++ /dev/null
@@ -1,6 +0,0 @@
1[Socket]
2ListenStream=9030
3ListenDatagram=9031
4
5[Install]
6WantedBy=sockets.target \ No newline at end of file
diff --git a/recipes-test/big-update/big-update_1.0.bb b/recipes-test/big-update/big-update_1.0.bb
index 68b9746..3b1d652 100644
--- a/recipes-test/big-update/big-update_1.0.bb
+++ b/recipes-test/big-update/big-update_1.0.bb
@@ -1,5 +1,5 @@
1DESCRIPTION = "Example Package with 10MB of random, seeded content" 1DESCRIPTION = "Example Package with 10MB of random, seeded content"
2LICENSE = "CLOSED" 2LICENSE = "MPL-2.0"
3 3
4SRC_URI = "file://rand_file.py" 4SRC_URI = "file://rand_file.py"
5 5
diff --git a/recipes-test/big-update/big-update_2.0.bb b/recipes-test/big-update/big-update_2.0.bb
index 20c8138..7cb6e94 100644
--- a/recipes-test/big-update/big-update_2.0.bb
+++ b/recipes-test/big-update/big-update_2.0.bb
@@ -1,5 +1,5 @@
1DESCRIPTION = "Example Package with 12MB of random, seeded content" 1DESCRIPTION = "Example Package with 12MB of random, seeded content"
2LICENSE = "CLOSED" 2LICENSE = "MPL-2.0"
3 3
4SRC_URI = "file://rand_file.py" 4SRC_URI = "file://rand_file.py"
5 5
diff --git a/recipes-test/demo-config/files/30-fake_pacman.toml b/recipes-test/demo-config/files/30-fake_pacman.toml
new file mode 100644
index 0000000..3fb5cf2
--- /dev/null
+++ b/recipes-test/demo-config/files/30-fake_pacman.toml
@@ -0,0 +1,2 @@
1[pacman]
2type = "fake"
diff --git a/recipes-test/demo-config/files/30-secondary_config.toml b/recipes-test/demo-config/files/30-secondary_config.toml
new file mode 100644
index 0000000..7714240
--- /dev/null
+++ b/recipes-test/demo-config/files/30-secondary_config.toml
@@ -0,0 +1,2 @@
1[uptane]
2secondary_config_file = "@CFG_FILEPATH@"
diff --git a/recipes-test/demo-config/files/35-network_config.toml b/recipes-test/demo-config/files/35-network_config.toml
new file mode 100644
index 0000000..db7a1bb
--- /dev/null
+++ b/recipes-test/demo-config/files/35-network_config.toml
@@ -0,0 +1,4 @@
1[network]
2port = @PORT@
3primary_ip = @PRIMARY_IP@
4primary_port = @PRIMARY_PORT@
diff --git a/recipes-test/demo-config/files/45-id_config.toml b/recipes-test/demo-config/files/45-id_config.toml
new file mode 100644
index 0000000..6cbd77f
--- /dev/null
+++ b/recipes-test/demo-config/files/45-id_config.toml
@@ -0,0 +1,3 @@
1[uptane]
2ecu_serial = @SERIAL@
3ecu_hardware_id = @HWID@
diff --git a/recipes-test/demo-config/files/ip_secondary_config.json b/recipes-test/demo-config/files/ip_secondary_config.json
new file mode 100644
index 0000000..690cf2e
--- /dev/null
+++ b/recipes-test/demo-config/files/ip_secondary_config.json
@@ -0,0 +1,7 @@
1{
2 "IP": {
3 "secondaries_wait_port": @PORT@,
4 "secondaries_wait_timeout": @TIMEOUT@,
5 "secondaries": @ADDR_ARRAY@
6 }
7}
diff --git a/recipes-test/demo-config/primary-config.bb b/recipes-test/demo-config/primary-config.bb
new file mode 100644
index 0000000..0cd9180
--- /dev/null
+++ b/recipes-test/demo-config/primary-config.bb
@@ -0,0 +1,68 @@
1DESCRIPTION = "Sample configuration for an Uptane Primary to support IP/Posix Secondary"
2LICENSE = "MPL-2.0"
3LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
4
5require shared-conf.inc
6
7PRIMARY_SECONDARIES ?= "${SECONDARY_IP}:${SECONDARY_PORT}"
8
9SRC_URI = "\
10 file://30-secondary_config.toml \
11 file://ip_secondary_config.json \
12 "
13
14def get_secondary_addrs(d):
15 import json
16
17 secondaries = d.getVar('PRIMARY_SECONDARIES')
18 sec_array = []
19 for secondary in secondaries.split():
20 sec_array.append({"addr": secondary})
21
22 return json.dumps(sec_array)
23
24do_install () {
25
26 if [ ! -n "${SOTA_SECONDARY_CONFIG}" ]; then
27 bbwarn "SOTA_SECONDARY_CONFIG hasn't been specified in the local config, generate a default one"
28
29 IP_SECONDARY_CONFIG_FILE=${WORKDIR}/ip_secondary_config.json
30 IP_SECONDARY_ADDRS='${@get_secondary_addrs(d)}'
31 else
32 bbwarn "SOTA_SECONDARY_CONFIG has been specified in the local config: ${SOTA_SECONDARY_CONFIG}"
33
34 IP_SECONDARY_CONFIG_FILE=${SOTA_SECONDARY_CONFIG}
35 fi
36
37 if [ ! -f $IP_SECONDARY_CONFIG_FILE ]; then
38 bbfatal "Secondary config file does not exist: $IP_SECONDARY_CONFIG_FILE"
39 fi
40
41 SECONDARY_CONFIG_DEST_DIR="${D}${sysconfdir}/sota/ecus"
42 SECONDARY_CONFIG_DEST_FILEPATH=$SECONDARY_CONFIG_DEST_DIR/$(basename -- $IP_SECONDARY_CONFIG_FILE)
43 SECONDARY_CONFIG_FILEPATH_ON_IMAGE="${sysconfdir}/sota/ecus/$(basename -- $IP_SECONDARY_CONFIG_FILE)"
44
45 # install the secondary configuration file (json)
46 install -m 0700 -d $SECONDARY_CONFIG_DEST_DIR
47 install -m 0644 $IP_SECONDARY_CONFIG_FILE $SECONDARY_CONFIG_DEST_DIR
48
49 # if SOTA_SECONDARY_CONFIG/secondary config file is not defined in the local conf
50 # then a default template is used and filled with corresponding configuration variable values
51 if [ ! -n "${SOTA_SECONDARY_CONFIG}" ]; then
52 sed -i -e "s|@PORT@|${PRIMARY_PORT}|g" \
53 -e "s|@TIMEOUT@|${PRIMARY_WAIT_TIMEOUT}|g" \
54 -e "s|@ADDR_ARRAY@|$IP_SECONDARY_ADDRS|g" $SECONDARY_CONFIG_DEST_FILEPATH
55 fi
56
57 # install aktualizr config file (toml) that points to the secondary config file, so aktualizr is aware about it
58 install -m 0700 -d ${D}${libdir}/sota/conf.d
59 install -m 0644 ${WORKDIR}/30-secondary_config.toml ${D}${libdir}/sota/conf.d
60 sed -i "s|@CFG_FILEPATH@|$SECONDARY_CONFIG_FILEPATH_ON_IMAGE|g" ${D}${libdir}/sota/conf.d/30-secondary_config.toml
61}
62
63FILES_${PN} = " \
64 ${libdir}/sota/conf.d/* \
65 ${sysconfdir}/sota/ecus/* \
66 "
67
68# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-test/demo-config/secondary-config.bb b/recipes-test/demo-config/secondary-config.bb
new file mode 100644
index 0000000..5b213d1
--- /dev/null
+++ b/recipes-test/demo-config/secondary-config.bb
@@ -0,0 +1,41 @@
1DESCRIPTION = "Sample configuration for an Uptane Secondary"
2LICENSE = "MPL-2.0"
3LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
4
5require shared-conf.inc
6
7SECONDARY_SERIAL_ID ?= ""
8SOTA_HARDWARE_ID ?= "${MACHINE}-sndry"
9SECONDARY_HARDWARE_ID ?= "${SOTA_HARDWARE_ID}"
10
11SRC_URI = "\
12 file://30-fake_pacman.toml \
13 file://35-network_config.toml \
14 file://45-id_config.toml \
15 "
16
17do_install () {
18 install -m 0700 -d ${D}${libdir}/sota/conf.d
19 install -m 0644 ${WORKDIR}/30-fake_pacman.toml ${D}/${libdir}/sota/conf.d/30-fake_pacman.toml
20
21 install -m 0644 ${WORKDIR}/35-network_config.toml ${D}/${libdir}/sota/conf.d/35-network_config.toml
22 sed -i -e 's|@PORT@|${SECONDARY_PORT}|g' \
23 -e 's|@PRIMARY_IP@|${PRIMARY_IP}|g' \
24 -e 's|@PRIMARY_PORT@|${PRIMARY_PORT}|g' \
25 ${D}/${libdir}/sota/conf.d/35-network_config.toml
26
27 install -m 0644 ${WORKDIR}/45-id_config.toml ${D}/${libdir}/sota/conf.d/45-id_config.toml
28 sed -i -e 's|@SERIAL@|${SECONDARY_SERIAL_ID}|g' \
29 -e 's|@HWID@|${SECONDARY_HARDWARE_ID}|g' \
30 ${D}/${libdir}/sota/conf.d/45-id_config.toml
31
32}
33
34FILES_${PN} = " \
35 ${libdir}/sota/conf.d \
36 ${libdir}/sota/conf.d/30-fake_pacman.toml \
37 ${libdir}/sota/conf.d/35-network_config.toml \
38 ${libdir}/sota/conf.d/45-id_config.toml \
39 "
40
41# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-test/demo-config/shared-conf.inc b/recipes-test/demo-config/shared-conf.inc
new file mode 100644
index 0000000..ce2bb44
--- /dev/null
+++ b/recipes-test/demo-config/shared-conf.inc
@@ -0,0 +1,5 @@
1SECONDARY_IP ?= "10.0.3.2"
2SECONDARY_PORT ?= "9050"
3PRIMARY_IP ?= "10.0.3.1"
4PRIMARY_PORT ?= "9040"
5PRIMARY_WAIT_TIMEOUT ?= "120"
diff --git a/recipes-test/demo-network-config/files/26-static-client.network b/recipes-test/demo-network-config/files/26-static-client.network
new file mode 100644
index 0000000..19a6b83
--- /dev/null
+++ b/recipes-test/demo-network-config/files/26-static-client.network
@@ -0,0 +1,7 @@
1[Match]
2Name=@IFNAME@
3
4[Network]
5Description=Private internal network between aktualizr Primary and Secondary nodes
6Address=@ADDR@
7DHCP=no
diff --git a/recipes-test/demo-network-config/primary-network-config.bb b/recipes-test/demo-network-config/primary-network-config.bb
index 78678a2..c7daa15 100644
--- a/recipes-test/demo-network-config/primary-network-config.bb
+++ b/recipes-test/demo-network-config/primary-network-config.bb
@@ -1,10 +1,12 @@
1DESCRIPTION = "Sample network configuration for an Uptane Primary" 1DESCRIPTION = "Sample network configuration for an Uptane Primary"
2LICENSE = "CLOSED" 2LICENSE = "MPL-2.0"
3LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
3 4
4inherit allarch 5inherit allarch
5 6
6SRC_URI = "file://25-dhcp-server.network" 7SRC_URI = "\
7 8 file://27-dhcp-client-external.network \
9 "
8 10
9FILES_${PN} = "/usr/lib/systemd/network" 11FILES_${PN} = "/usr/lib/systemd/network"
10 12
@@ -12,5 +14,12 @@ PR = "1"
12 14
13do_install() { 15do_install() {
14 install -d ${D}/usr/lib/systemd/network 16 install -d ${D}/usr/lib/systemd/network
15 install -m 0644 ${WORKDIR}/25-dhcp-server.network ${D}/usr/lib/systemd/network/ 17 install -m 0644 ${WORKDIR}/27-dhcp-client-external.network ${D}/usr/lib/systemd/network/
16} 18}
19
20PRIMARY_IP ?= "10.0.3.1"
21IP_ADDR = "${PRIMARY_IP}"
22
23require static-network-config.inc
24
25# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-test/demo-network-config/secondary-network-config.bb b/recipes-test/demo-network-config/secondary-network-config.bb
index 9091c65..c70d88a 100644
--- a/recipes-test/demo-network-config/secondary-network-config.bb
+++ b/recipes-test/demo-network-config/secondary-network-config.bb
@@ -1,20 +1,29 @@
1DESCRIPTION = "Sample network configuration for an Uptane Secondary" 1DESCRIPTION = "Sample network configuration for an Uptane Secondary"
2LICENSE = "CLOSED" 2LICENSE = "MPL-2.0"
3LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
3 4
4inherit allarch 5inherit allarch
5 6
7# TODO: It configures the 'user' interface in NAT mode and provides an access to public Inet via it
8# which is not desired for Secondary. It cannot be just removed since we get SSH access to Secondary
9# VM via this interface. So, the task is to configure the interface in such way that it does provide access
10# via SSH from a host machine and forbids an access to Inet
6SRC_URI = "\ 11SRC_URI = "\
7 file://26-dhcp-client.network \
8 file://27-dhcp-client-external.network \ 12 file://27-dhcp-client-external.network \
9 " 13 "
10 14
11
12FILES_${PN} = "/usr/lib/systemd/network" 15FILES_${PN} = "/usr/lib/systemd/network"
13 16
14PR = "1" 17PR = "1"
15 18
16do_install() { 19do_install() {
17 install -d ${D}/usr/lib/systemd/network 20 install -d ${D}/usr/lib/systemd/network
18 install -m 0644 ${WORKDIR}/26-dhcp-client.network ${D}/usr/lib/systemd/network/
19 install -m 0644 ${WORKDIR}/27-dhcp-client-external.network ${D}/usr/lib/systemd/network/ 21 install -m 0644 ${WORKDIR}/27-dhcp-client-external.network ${D}/usr/lib/systemd/network/
20} 22}
23
24SECONDARY_IP ?= "10.0.3.2"
25IP_ADDR = "${SECONDARY_IP}"
26
27require static-network-config.inc
28
29# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-test/demo-network-config/static-network-config.inc b/recipes-test/demo-network-config/static-network-config.inc
new file mode 100644
index 0000000..e64675e
--- /dev/null
+++ b/recipes-test/demo-network-config/static-network-config.inc
@@ -0,0 +1,16 @@
1SRC_URI_append = "\
2 file://26-static-client.network \
3 "
4
5SECONDARY_INTERFACE ?= "enp0s5"
6
7do_install_append() {
8 install -d ${D}/usr/lib/systemd/network
9 install -m 0644 ${WORKDIR}/26-static-client.network ${D}/usr/lib/systemd/network/
10 sed -i -e 's|@ADDR@|${IP_ADDR}|g' \
11 -e 's|@IFNAME@|${SECONDARY_INTERFACE}|g' \
12 ${D}/usr/lib/systemd/network/26-static-client.network
13
14}
15
16# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-test/images/primary-image.bb b/recipes-test/images/primary-image.bb
index 6d2df94..ba1dc1f 100644
--- a/recipes-test/images/primary-image.bb
+++ b/recipes-test/images/primary-image.bb
@@ -2,13 +2,15 @@ include recipes-core/images/core-image-minimal.bb
2 2
3SUMMARY = "A minimal Uptane Primary image running aktualizr, for testing with a Linux secondary" 3SUMMARY = "A minimal Uptane Primary image running aktualizr, for testing with a Linux secondary"
4 4
5LICENSE = "MIT" 5LICENSE = "MPL-2.0"
6 6
7IMAGE_INSTALL_remove = " \ 7IMAGE_INSTALL_remove = " \
8 virtual/network-configuration \
8 " 9 "
9 10
10IMAGE_INSTALL_append = " \ 11IMAGE_INSTALL_append = " \
11 primary-network-config \ 12 primary-network-config \
13 primary-config \
12 " 14 "
13 15
14# vim:set ts=4 sw=4 sts=4 expandtab: 16# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-test/images/secondary-image.bb b/recipes-test/images/secondary-image.bb
index 61df85b..4cae874 100644
--- a/recipes-test/images/secondary-image.bb
+++ b/recipes-test/images/secondary-image.bb
@@ -2,8 +2,10 @@ include recipes-core/images/core-image-minimal.bb
2 2
3SUMMARY = "A minimal Uptane Secondary image running aktualizr-secondary" 3SUMMARY = "A minimal Uptane Secondary image running aktualizr-secondary"
4 4
5LICENSE = "MIT" 5LICENSE = "MPL-2.0"
6 6
7SECONDARY_SERIAL_ID ?= ""
8SOTA_HARDWARE_ID ?= "${MACHINE}-sndry"
7 9
8# Remove default aktualizr primary, and the provisioning configuration (which 10# Remove default aktualizr primary, and the provisioning configuration (which
9# RDEPENDS on aktualizr) 11# RDEPENDS on aktualizr)
@@ -21,6 +23,7 @@ IMAGE_INSTALL_remove = " \
21IMAGE_INSTALL_append = " \ 23IMAGE_INSTALL_append = " \
22 aktualizr-secondary \ 24 aktualizr-secondary \
23 secondary-network-config \ 25 secondary-network-config \
26 secondary-config \
24 " 27 "
25 28
26# vim:set ts=4 sw=4 sts=4 expandtab: 29# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/scripts/qemucommand.py b/scripts/qemucommand.py
index cafab6d..1049d7c 100644
--- a/scripts/qemucommand.py
+++ b/scripts/qemucommand.py
@@ -109,8 +109,8 @@ class QemuCommand(object):
109 cmdline += ['-net', 'dump,file=' + self.pcap] 109 cmdline += ['-net', 'dump,file=' + self.pcap]
110 if self.secondary_network: 110 if self.secondary_network:
111 cmdline += [ 111 cmdline += [
112 '-net', 'nic,vlan=1,macaddr='+random_mac(), 112 '-netdev', 'socket,id=vlan1,mcast=230.0.0.1:1234,localaddr=127.0.0.1',
113 '-net', 'socket,vlan=1,mcast=230.0.0.1:1234,localaddr=127.0.0.1', 113 '-device', 'e1000,netdev=vlan1,mac='+random_mac(),
114 ] 114 ]
115 if self.gui: 115 if self.gui:
116 cmdline += ["-serial", "stdio"] 116 cmdline += ["-serial", "stdio"]