From c0d6f4c7949ddfc01977096b985c46c28aa8ed4f Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Wed, 28 Feb 2018 10:27:01 +0100 Subject: oe-selftest improvements. * Check successful provisioning with autoprov and grub. * Refactor provisioning check into an independent function. * Rename QemuTests to AutoProvTests since that's what it is now. * Be more explicit about MACHINE. --- lib/oeqa/selftest/cases/updater.py | 111 +++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 60 deletions(-) (limited to 'lib/oeqa/selftest/cases/updater.py') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index b544762..fe18981 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -134,22 +134,20 @@ class AktualizrToolsTests(OESelftestTestCase): self.assertTrue(os.path.getsize(ca_path) > 0, "Client certificate at %s is empty." % ca_path) -class QemuTests(OESelftestTestCase): +class AutoProvTests(OESelftestTestCase): - @classmethod - def setUpClass(cls): - super(QemuTests, cls).setUpClass() - cls.qemu, cls.s = qemu_launch(machine='qemux86-64') + def setUpLocal(self): + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + self.qemu, self.s = qemu_launch(machine='qemux86-64') - @classmethod - def tearDownClass(cls): - qemu_terminate(cls.s) - super(QemuTests, cls).tearDownClass() + def tearDownLocal(self): + qemu_terminate(self.s) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) - def test_qemu(self): + def test_provisioning(self): print('Checking machine name (hostname) of device:') stdout, stderr, retcode = self.qemu_command('hostname') self.assertEqual(retcode, 0, "Unable to check hostname. " + @@ -157,10 +155,10 @@ class QemuTests(OESelftestTestCase): machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. - value_str = stdout.decode()[:-1] - self.assertEqual(value_str, machine, - 'MACHINE does not match hostname: ' + machine + ', ' + value_str) - print(value_str) + value = stdout.decode()[:-1] + self.assertEqual(value, machine, + 'MACHINE does not match hostname: ' + machine + ', ' + value) + print(value) print('Checking output of aktualizr-info:') ran_ok = False for delay in [0, 1, 2, 5, 10, 15]: @@ -171,15 +169,18 @@ class QemuTests(OESelftestTestCase): break self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) + verifyProvisioned(self, machine) + class GrubTests(OESelftestTestCase): def setUpLocal(self): + self.append_config('MACHINE = "intel-corei7-64"') + self.append_config('OSTREE_BOOTLOADER = "grub"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') # This is a bit of a hack but I can't see a better option. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" - grub_config = 'OSTREE_BOOTLOADER = "grub"\nMACHINE = "intel-corei7-64"' - self.append_config(grub_config) self.meta_intel = metadir + "meta-intel" self.meta_minnow = metadir + "meta-updater-minnowboard" runCmd('bitbake-layers add-layer "%s"' % self.meta_intel) @@ -218,10 +219,13 @@ class GrubTests(OESelftestTestCase): break self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode()) + verifyProvisioned(self, machine) + class ImplProvTests(OESelftestTestCase): def setUpLocal(self): + self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') # note: this will build aktualizr-native as a side-effect self.qemu, self.s = qemu_launch(machine='qemux86-64') @@ -240,10 +244,10 @@ class ImplProvTests(OESelftestTestCase): machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. - value_str = stdout.decode()[:-1] - self.assertEqual(value_str, machine, - 'MACHINE does not match hostname: ' + machine + ', ' + value_str) - print(value_str) + value = stdout.decode()[:-1] + self.assertEqual(value, machine, + 'MACHINE does not match hostname: ' + machine + ', ' + value) + print(value) print('Checking output of aktualizr-info:') ran_ok = False for delay in [0, 1, 2, 5, 10, 15]: @@ -271,29 +275,13 @@ class ImplProvTests(OESelftestTestCase): akt_native_run(self, 'aktualizr_cert_provider -c {creds} -t root@localhost -p {port} -s -g {config}' .format(creds=creds, port=self.qemu.ssh_port, config=config)) - # Verify that device HAS provisioned. - ran_ok = False - for delay in [5, 5, 5, 5, 10]: - sleep(delay) - stdout, stderr, retcode = self.qemu_command('aktualizr-info') - if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: - ran_ok = True - break - self.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - self.assertIn(b'Primary ecu hardware ID: qemux86-64', stdout, - 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - self.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - p = re.compile(r'Device ID: ([a-z0-9-]*)\n') - m = p.search(stdout.decode()) - self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - logger = logging.getLogger("selftest") - logger.info('Device successfully provisioned with ID: ' + m.group(1)) + verifyProvisioned(self, machine) class HsmTests(OESelftestTestCase): def setUpLocal(self): + self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') self.append_config('SOTA_CLIENT_FEATURES = "hsm"') # note: this will build aktualizr-native as a side-effect @@ -313,11 +301,11 @@ class HsmTests(OESelftestTestCase): machine = get_bb_var('MACHINE', 'core-image-minimal') self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) # Strip off line ending. - value_str = stdout.decode()[:-1] - self.assertEqual(value_str, machine, - 'MACHINE does not match hostname: ' + machine + ', ' + value_str + + value = stdout.decode()[:-1] + self.assertEqual(value, machine, + 'MACHINE does not match hostname: ' + machine + ', ' + value + '\nIs tianocore ovmf installed?') - print(value_str) + print(value) print('Checking output of aktualizr-info:') ran_ok = False for delay in [0, 1, 2, 5, 10, 15]: @@ -387,24 +375,7 @@ class HsmTests(OESelftestTestCase): self.assertEqual(p11_m.group(1), hsm_m.group(1), 'Slot number does not match: ' + p11_err.decode() + p11_out.decode() + hsm_err.decode() + hsm_out.decode()) - # Verify that device HAS provisioned. - ran_ok = False - for delay in [5, 5, 5, 5, 10]: - sleep(delay) - stdout, stderr, retcode = self.qemu_command('aktualizr-info') - if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: - ran_ok = True - break - self.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - self.assertIn(b'Primary ecu hardware ID: qemux86-64', stdout, - 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - self.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) - p = re.compile(r'Device ID: ([a-z0-9-]*)\n') - m = p.search(stdout.decode()) - self.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - self.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) - logger = logging.getLogger("selftest") - logger.info('Device successfully provisioned with ID: ' + m.group(1)) + verifyProvisioned(self, machine) def qemu_launch(efi=False, machine=None): @@ -471,5 +442,25 @@ def akt_native_run(testInst, cmd, **kwargs): testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) +def verifyProvisioned(testInst, machine): + # Verify that device HAS provisioned. + ran_ok = False + for delay in [5, 5, 5, 5, 10]: + sleep(delay) + stdout, stderr, retcode = testInst.qemu_command('aktualizr-info') + if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0: + ran_ok = True + break + testInst.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + testInst.assertIn(b'Primary ecu hardware ID: ' + machine.encode(), stdout, + 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + testInst.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode()) + p = re.compile(r'Device ID: ([a-z0-9-]*)\n') + m = p.search(stdout.decode()) + testInst.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) + testInst.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode()) + logger = logging.getLogger("selftest") + logger.info('Device successfully provisioned with ID: ' + m.group(1)) + # vim:set ts=4 sw=4 sts=4 expandtab: -- cgit v1.2.3-54-g00ecf From 0fb122d88290a7476d694547f4d05a15d5ec38d1 Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Wed, 28 Feb 2018 11:23:07 +0100 Subject: Add qemu layer for qemu tests if not present. The layers required for the grub test are now also only added if not already present. This should make the tests runnable from an environment configured for raspberry pi. --- lib/oeqa/selftest/cases/updater.py | 61 +++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) (limited to 'lib/oeqa/selftest/cases/updater.py') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index fe18981..a9c3206 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -139,10 +139,22 @@ class AutoProvTests(OESelftestTestCase): def setUpLocal(self): self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # This is a bit of a hack but I can't see a better option. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) @@ -178,19 +190,30 @@ class GrubTests(OESelftestTestCase): self.append_config('MACHINE = "intel-corei7-64"') self.append_config('OSTREE_BOOTLOADER = "grub"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + layer_intel = "meta-intel" + layer_minnow = "meta-updater-minnowboard" + result = runCmd('bitbake-layers show-layers') # This is a bit of a hack but I can't see a better option. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" - self.meta_intel = metadir + "meta-intel" - self.meta_minnow = metadir + "meta-updater-minnowboard" - runCmd('bitbake-layers add-layer "%s"' % self.meta_intel) - runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow) + if re.search(layer_intel, result.output) is None: + self.meta_intel = metadir + layer_intel + runCmd('bitbake-layers add-layer "%s"' % self.meta_intel) + else: + self.meta_intel = None + if re.search(layer_minnow, result.output) is None: + self.meta_minnow = metadir + layer_minnow + runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow) + else: + self.meta_minnow = None self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64') def tearDownLocal(self): qemu_terminate(self.s) - runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True) - runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True) + if self.meta_intel: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True) + if self.meta_minnow: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) @@ -227,11 +250,22 @@ class ImplProvTests(OESelftestTestCase): def setUpLocal(self): self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') - # note: this will build aktualizr-native as a side-effect + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # This is a bit of a hack but I can't see a better option. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) @@ -284,11 +318,22 @@ class HsmTests(OESelftestTestCase): self.append_config('MACHINE = "qemux86-64"') self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') self.append_config('SOTA_CLIENT_FEATURES = "hsm"') - # note: this will build aktualizr-native as a side-effect + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # This is a bit of a hack but I can't see a better option. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) def qemu_command(self, command): return qemu_send_command(self.qemu.ssh_port, command) -- cgit v1.2.3-54-g00ecf From 81b2fa6bf0b5d7d68dc81c83ecc1ba15cba2ac9b Mon Sep 17 00:00:00 2001 From: Patrick Vacek Date: Fri, 2 Mar 2018 09:39:39 +0100 Subject: Add a basic raspberry pi test. There's not much we can do, since booting the device via a test is not practical. Still, it's useful to make sure that we can build the image. If trying to build the image in an environment designed for qemu, this takes some trickery to set things up just right. Also consistently set up layers before setting the MACHINE, since the sanity checker sometimes complains otherwise. --- lib/oeqa/selftest/cases/updater.py | 114 +++++++++++++++++++++++++++++++------ 1 file changed, 98 insertions(+), 16 deletions(-) (limited to 'lib/oeqa/selftest/cases/updater.py') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index a9c3206..adb4061 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -64,7 +64,6 @@ class GeneralTests(OESelftestTestCase): "Java not found. Do you have a JDK installed on your host machine?") def test_add_package(self): - print('') deploydir = get_bb_var('DEPLOY_DIR_IMAGE') imagename = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal') image_path = deploydir + '/' + imagename + '.otaimg' @@ -137,18 +136,20 @@ class AktualizrToolsTests(OESelftestTestCase): class AutoProvTests(OESelftestTestCase): def setUpLocal(self): - self.append_config('MACHINE = "qemux86-64"') - self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') layer = "meta-updater-qemux86-64" result = runCmd('bitbake-layers show-layers') if re.search(layer, result.output) is None: - # This is a bit of a hack but I can't see a better option. + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" self.meta_qemu = metadir + layer runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) else: self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): @@ -184,16 +185,91 @@ class AutoProvTests(OESelftestTestCase): verifyProvisioned(self, machine) -class GrubTests(OESelftestTestCase): +class RpiTests(OESelftestTestCase): def setUpLocal(self): - self.append_config('MACHINE = "intel-corei7-64"') - self.append_config('OSTREE_BOOTLOADER = "grub"') + # Add layers before changing the machine type, otherwise the sanity + # checker complains loudly. + layer_python = "meta-openembedded/meta-python" + layer_rpi = "meta-raspberrypi" + layer_upd_rpi = "meta-updater-raspberrypi" + result = runCmd('bitbake-layers show-layers') + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + if re.search(layer_python, result.output) is None: + self.meta_python = metadir + layer_python + runCmd('bitbake-layers add-layer "%s"' % self.meta_python) + else: + self.meta_python = None + if re.search(layer_rpi, result.output) is None: + self.meta_rpi = metadir + layer_rpi + runCmd('bitbake-layers add-layer "%s"' % self.meta_rpi) + else: + self.meta_rpi = None + if re.search(layer_upd_rpi, result.output) is None: + self.meta_upd_rpi = metadir + layer_upd_rpi + runCmd('bitbake-layers add-layer "%s"' % self.meta_upd_rpi) + else: + self.meta_upd_rpi = None + + # This is trickier that I would've thought. The fundamental problem is + # that the qemu layer changes the u-boot file extension to .rom, but + # raspberrypi still expects .bin. To prevent this, the qemu layer must + # be temporarily removed if it is present. It has to be removed by name + # without the complete path, but to add it back when we are done, we + # need the full path. + p = re.compile(r'meta-updater-qemux86-64\s*(\S*meta-updater-qemux86-64)\s') + m = p.search(result.output) + if m and m.lastindex > 0: + self.meta_qemu = m.group(1) + runCmd('bitbake-layers remove-layer meta-updater-qemux86-64') + else: + self.meta_qemu = None + + self.append_config('MACHINE = "raspberrypi3"') self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + + def tearDownLocal(self): + if self.meta_qemu: + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu, ignore_status=True) + if self.meta_upd_rpi: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_upd_rpi, ignore_status=True) + if self.meta_rpi: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_rpi, ignore_status=True) + if self.meta_python: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_python, ignore_status=True) + + def test_rpi(self): + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build rpi-basic-image') + self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"') + bitbake('rpi-basic-image') + credentials = get_bb_var('SOTA_PACKED_CREDENTIALS') + # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set. + if credentials is None: + raise unittest.SkipTest("Variable 'SOTA_PACKED_CREDENTIALS' not set.") + # Check if the file exists. + self.assertTrue(os.path.isfile(credentials), "File %s does not exist" % credentials) + deploydir = get_bb_var('DEPLOY_DIR_IMAGE') + imagename = get_bb_var('IMAGE_LINK_NAME', 'rpi-basic-image') + # Check if the credentials are included in the output image. + result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' % + (deploydir, imagename), ignore_status=True) + self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) + + +class GrubTests(OESelftestTestCase): + + def setUpLocal(self): layer_intel = "meta-intel" layer_minnow = "meta-updater-minnowboard" result = runCmd('bitbake-layers show-layers') - # This is a bit of a hack but I can't see a better option. + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" if re.search(layer_intel, result.output) is None: @@ -206,6 +282,9 @@ class GrubTests(OESelftestTestCase): runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow) else: self.meta_minnow = None + self.append_config('MACHINE = "intel-corei7-64"') + self.append_config('OSTREE_BOOTLOADER = "grub"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64') def tearDownLocal(self): @@ -219,7 +298,6 @@ class GrubTests(OESelftestTestCase): return qemu_send_command(self.qemu.ssh_port, command) def test_grub(self): - print('') print('Checking machine name (hostname) of device:') stdout, stderr, retcode = self.qemu_command('hostname') self.assertEqual(retcode, 0, "Unable to check hostname. " + @@ -248,18 +326,20 @@ class GrubTests(OESelftestTestCase): class ImplProvTests(OESelftestTestCase): def setUpLocal(self): - self.append_config('MACHINE = "qemux86-64"') - self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') layer = "meta-updater-qemux86-64" result = runCmd('bitbake-layers show-layers') if re.search(layer, result.output) is None: - # This is a bit of a hack but I can't see a better option. + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" self.meta_qemu = metadir + layer runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) else: self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-implicit-prov "') self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): @@ -315,19 +395,21 @@ class ImplProvTests(OESelftestTestCase): class HsmTests(OESelftestTestCase): def setUpLocal(self): - self.append_config('MACHINE = "qemux86-64"') - self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') - self.append_config('SOTA_CLIENT_FEATURES = "hsm"') layer = "meta-updater-qemux86-64" result = runCmd('bitbake-layers show-layers') if re.search(layer, result.output) is None: - # This is a bit of a hack but I can't see a better option. + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. path = os.path.abspath(os.path.dirname(__file__)) metadir = path + "/../../../../../" self.meta_qemu = metadir + layer runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) else: self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') + self.append_config('SOTA_CLIENT_FEATURES = "hsm"') self.qemu, self.s = qemu_launch(machine='qemux86-64') def tearDownLocal(self): -- cgit v1.2.3-54-g00ecf From bbce1809a921e627678947e9585ea15223b181d9 Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Wed, 14 Mar 2018 11:44:26 +0100 Subject: Add secondary-image to meta-updater This required splitting the aktualizr package into several components, in order to be able to either install the primary 'aktualzr' or the secondary 'aktualizr-secondary'. --- README.adoc | 4 +-- lib/oeqa/selftest/cases/updater.py | 45 +++++++++++++++++++++++++++++++-- recipes-sota/aktualizr/aktualizr_git.bb | 42 +++++++++++++++++------------- recipes-test/images/secondary-image.bb | 18 +++++++++++++ 4 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 recipes-test/images/secondary-image.bb (limited to 'lib/oeqa/selftest/cases/updater.py') diff --git a/README.adoc b/README.adoc index 3562f52..980fa81 100644 --- a/README.adoc +++ b/README.adoc @@ -80,8 +80,8 @@ Although we have used U-Boot so far, other boot loaders can be configured work w * `OSTREE_INITRAMFS_IMAGE` - initramfs/initrd image that is used as a proxy while booting into OSTree deployment. Do not change this setting unless you are sure that your initramfs can serve as such a proxy. * `SOTA_PACKED_CREDENTIALS` - when set, your ostree commit will be pushed to a remote repo as a bitbake step. This should be the path to a zipped credentials file in https://github.com/advancedtelematic/aktualizr/blob/master/docs/credentials.adoc[the format accepted by garage-push]. * `SOTA_CLIENT_PROV` - which provisioning method to use. Valid options are https://github.com/advancedtelematic/aktualizr/blob/master/docs/automatic-provisioning.adoc[`aktualizr-auto-prov`], https://github.com/advancedtelematic/aktualizr/blob/master/docs/implicit-provisioning.adoc[`aktualizr-implicit-prov`], and `aktualizr-hsm-prov`. The default is `aktualizr-auto-prov`. This can also be set to an empty string to avoid using a provisioning recipe. -* `SOTA_CLIENT_FEATURES` - extensions to aktualizr. Multiple can be specified if separated by spaces. Valid options are `hsm` (to build with HSM support) and `secondary-example` (to install an example https://github.com/advancedtelematic/aktualizr/blob/master/docs/legacysecondary.adoc[legacy secondary interface] in the image). -* `SOTA_LEGACY_SECONDARY_INTERFACE` - path to a legacy secondary interface installed on the device. To use the example interface from the Aktualizr repo, use `/usr/bin/example-interface` and make sure `SOTA_CLIENT_FEATURES = "secondary-example"`. +* `SOTA_CLIENT_FEATURES` - extensions to aktualizr. The only valid option is `hsm` (to build with HSM support) +* `SOTA_LEGACY_SECONDARY_INTERFACE` - path to a https://github.com/advancedtelematic/aktualizr/blob/master/docs/legacysecondary.adoc[legacy secondary interface] installed on the device. To use the example interface from the Aktualizr repo, use `/usr/bin/example-interface` and make sure `IMAGE_INSTALL_append` includes `aktualizr-examples`. * `SOTA_SECONDARY_ECUS` - a list of paths separated by spaces of JSON configuration files for virtual secondaries on the host. These will be installed into `/var/sota/ecus` on the device. * `SOTA_VIRTUAL_SECONDARIES` - a list of paths separated by spaces of JSON configuration files for virtual secondaries installed on the device. If `SOTA_SECONDARY_ECUS` is used to install them, then you can expect them to be installed in `/var/sota/ecus`. diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index adb4061..a5072e8 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -504,14 +504,55 @@ class HsmTests(OESelftestTestCase): verifyProvisioned(self, machine) +class SecondaryTests(OESelftestTestCase): + @classmethod + def setUpClass(cls): + super(SecondaryTests, cls).setUpClass() + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build secondary-image') + bitbake('secondary-image') + + def setUpLocal(self): + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + self.qemu, self.s = qemu_launch(machine='qemux86-64', imagename='secondary-image') + + def tearDownLocal(self): + qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) + + def qemu_command(self, command): + return qemu_send_command(self.qemu.ssh_port, command) + + def test_secondary_present(self): + print('Checking aktualizr-secondary is present') + stdout, stderr, retcode = self.qemu_command('aktualizr-secondary --help') + self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help") + self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) -def qemu_launch(efi=False, machine=None): +def qemu_launch(efi=False, machine=None, imagename=None): logger = logging.getLogger("selftest") logger.info('Running bitbake to build core-image-minimal') bitbake('core-image-minimal') # Create empty object. args = type('', (), {})() - args.imagename = 'core-image-minimal' + if imagename: + args.imagename = imagename + else: + args.imagename = 'core-image-minimal' args.mac = None # Could use DEPLOY_DIR_IMAGE here but it's already in the machine # subdirectory. diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index 4c4e975..ad06339 100644 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -20,7 +20,7 @@ SRC_URI = " \ file://aktualizr.service \ file://aktualizr-serialcan.service \ " -SRCREV = "1a6432175b9fb7326173e8db35d326cc1a1011a1" +SRCREV = "dca6271f4ec06eb2272cc99b4b9cf76a9805f18d" BRANCH ?= "master" S = "${WORKDIR}/git" @@ -34,27 +34,19 @@ BBCLASSEXTEND =+ "native" EXTRA_OECMAKE = "-DWARNING_AS_ERROR=OFF -DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV} " EXTRA_OECMAKE_append_class-target = " -DBUILD_OSTREE=ON -DBUILD_ISOTP=ON ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', '-DBUILD_P11=ON', '', d)} " -EXTRA_OECMAKE_append_class-native = " -DBUILD_SOTA_TOOLS=ON -DBUILD_OSTREE=OFF " +EXTRA_OECMAKE_append_class-native = " -DBUILD_SOTA_TOOLS=ON -DBUILD_OSTREE=OFF -DBUILD_SYSTEMD=OFF " do_install_append () { rm -fr ${D}${libdir}/systemd + rm -f ${D}${libdir}/sota/sota.toml # Only needed for the Debian package } do_install_append_class-target () { - rm -f ${D}${bindir}/aktualizr_cert_provider - rm -f ${D}${bindir}/aktualizr_implicit_writer - rm -f ${D}${libdir}/sota/sota.toml - ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-example', '', 'rm -f ${D}${bindir}/example-interface', d)} - ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-isotp-example', '', 'rm -f ${D}${bindir}/isotp-test-interface', d)} - install -d ${D}${systemd_unitdir}/system aktualizr_service=${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'serialcan', '${WORKDIR}/aktualizr-serialcan.service', '${WORKDIR}/aktualizr.service', d)} install -m 0644 ${aktualizr_service} ${D}${systemd_unitdir}/system/aktualizr.service } do_install_append_class-native () { - rm -f ${D}${bindir}/aktualizr - rm -f ${D}${bindir}/aktualizr-info - rm -f ${D}${bindir}/example-interface install -d ${D}${libdir}/sota install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml install -m 0644 ${S}/config/sota_hsm_prov.toml ${D}/${libdir}/sota/sota_hsm_prov.toml @@ -65,23 +57,37 @@ do_install_append_class-native () { install -m 0644 ${B}/src/sota_tools/garage-sign-prefix/src/garage-sign/lib/* ${D}${libdir} } -FILES_${PN}_append = " \ - ${libdir}/sota \ - " +PACKAGES =+ " ${PN}-common ${PN}-examples ${PN}-host-tools ${PN}-secondary " -FILES_${PN}_class-target = " \ +FILES_${PN} = " \ ${bindir}/aktualizr \ ${bindir}/aktualizr-info \ ${systemd_unitdir}/system/aktualizr.service \ " -FILES_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-example', ' ${bindir}/example-interface', '', d)} " -FILES_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-isotp-example', ' ${bindir}/isotp-test-interface', '', d)} " -FILES_${PN}_class-native = " \ +FILES_${PN}-common = " \ + ${libdir}/sota/schemas \ + " + +FILES_${PN}-examples = " \ + ${libdir}/sota/demo_secondary.json \ + ${bindir}/example-interface \ + ${bindir}/isotp-test-interface \ + " + +FILES_${PN}-host-tools = " \ ${bindir}/aktualizr_cert_provider \ ${bindir}/aktualizr_implicit_writer \ ${bindir}/garage-deploy \ ${bindir}/garage-push \ " +FILES_${PN}-secondary = " \ + ${bindir}/aktualizr-secondary \ + " + +# Both primary and secondary need the SQL Schemas +RDEPENDS_${PN}_class-target =+ "${PN}-common" +RDEPENDS_${PN}-secondary_class-target =+ "${PN}-common" + # 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 new file mode 100644 index 0000000..c7a91db --- /dev/null +++ b/recipes-test/images/secondary-image.bb @@ -0,0 +1,18 @@ +include recipes-core/images/core-image-minimal.bb + +SUMMARY = "A minimal Uptane Secondary image running aktualizr-secondary" + +LICENSE = "MIT" + + +# Remove default aktualizr primary, and the provisioning configuration (which +# RDEPENDS on aktualizr) +IMAGE_INSTALL_remove = " \ + aktualizr \ + aktualizr-auto-prov \ + aktualizr-ca-implicit-prov \ + aktualizr-hsm-prov \ + aktualizr-implicit-prov \ + " + +IMAGE_INSTALL_append = " aktualizr-secondary " \ No newline at end of file -- cgit v1.2.3-54-g00ecf From 66a4721d0b7885a18db952d69f7ee385a95b2f2b Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Wed, 14 Mar 2018 16:00:53 +0100 Subject: Add systemd socket activation for secondary --- lib/oeqa/selftest/cases/updater.py | 5 +++++ recipes-sota/aktualizr/aktualizr_git.bb | 15 ++++++++++++++- recipes-sota/aktualizr/files/aktualizr-secondary.service | 9 +++++++++ recipes-sota/aktualizr/files/aktualizr-secondary.socket | 5 +++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 recipes-sota/aktualizr/files/aktualizr-secondary.service create mode 100644 recipes-sota/aktualizr/files/aktualizr-secondary.socket (limited to 'lib/oeqa/selftest/cases/updater.py') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index a5072e8..1850d98 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -543,6 +543,11 @@ class SecondaryTests(OESelftestTestCase): self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help") self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) + def test_secondary_listening(self): + print('Checking aktualizr-secondary is present') + stdout, stderr, retcode = self.qemu_command('echo test | nc localhost 9030') + self.assertEqual(retcode, 0, "Unable to connect to secondary") + def qemu_launch(efi=False, machine=None, imagename=None): logger = logging.getLogger("selftest") logger.info('Running bitbake to build core-image-minimal') diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index ad06339..5e683ac 100644 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -18,9 +18,11 @@ PR = "7" SRC_URI = " \ gitsm://github.com/advancedtelematic/aktualizr;branch=${BRANCH} \ file://aktualizr.service \ + file://aktualizr-secondary.service \ + file://aktualizr-secondary.socket \ file://aktualizr-serialcan.service \ " -SRCREV = "dca6271f4ec06eb2272cc99b4b9cf76a9805f18d" +SRCREV = "fbb3404824c4eb239455c7fa1a794c26e2ea954d" BRANCH ?= "master" S = "${WORKDIR}/git" @@ -28,7 +30,10 @@ S = "${WORKDIR}/git" inherit cmake inherit systemd + +SYSTEMD_PACKAGES = "${PN} ${PN}-secondary" SYSTEMD_SERVICE_${PN} = "aktualizr.service" +SYSTEMD_SERVICE_${PN}-secondary = "aktualizr-secondary.socket" BBCLASSEXTEND =+ "native" @@ -39,6 +44,11 @@ EXTRA_OECMAKE_append_class-native = " -DBUILD_SOTA_TOOLS=ON -DBUILD_OSTREE=OFF - do_install_append () { rm -fr ${D}${libdir}/systemd rm -f ${D}${libdir}/sota/sota.toml # Only needed for the Debian package + install -d ${D}${libdir}/sota + install -m 0644 ${S}/config/sota_secondary.toml ${D}/${libdir}/sota/sota_secondary.toml + install -d ${D}${systemd_unitdir}/system + install -m 0644 ${WORKDIR}/aktualizr-secondary.socket ${D}${systemd_unitdir}/system/aktualizr-secondary.socket + install -m 0644 ${WORKDIR}/aktualizr-secondary.service ${D}${systemd_unitdir}/system/aktualizr-secondary.service } do_install_append_class-target () { install -d ${D}${systemd_unitdir}/system @@ -84,6 +94,9 @@ FILES_${PN}-host-tools = " \ FILES_${PN}-secondary = " \ ${bindir}/aktualizr-secondary \ + ${libdir}/sota/sota_secondary.toml \ + ${systemd_unitdir}/system/aktualizr-secondary.socket \ + ${systemd_unitdir}/system/aktualizr-secondary.service \ " # Both primary and secondary need the SQL Schemas diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.service b/recipes-sota/aktualizr/files/aktualizr-secondary.service new file mode 100644 index 0000000..a1e0e1b --- /dev/null +++ b/recipes-sota/aktualizr/files/aktualizr-secondary.service @@ -0,0 +1,9 @@ +[Unit] +Description=Aktualizr SOTA Client (UPTANE Secondary) + +[Service] +RestartSec=10 +Restart=always +EnvironmentFile=-/etc/sota/sota.env +ExecStart=/usr/bin/aktualizr-secondary --config /usr/lib/sota/sota_secondary.toml + diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.socket b/recipes-sota/aktualizr/files/aktualizr-secondary.socket new file mode 100644 index 0000000..1cb4269 --- /dev/null +++ b/recipes-sota/aktualizr/files/aktualizr-secondary.socket @@ -0,0 +1,5 @@ +[Socket] +ListenStream=9030 + +[Install] +WantedBy=sockets.target \ No newline at end of file -- cgit v1.2.3-54-g00ecf From 046ac433f47b5a6cbacb95873e55f7d6c842a939 Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Tue, 20 Mar 2018 13:42:04 +0100 Subject: Fix up tests --- lib/oeqa/selftest/cases/updater.py | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/oeqa/selftest/cases/updater.py') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index 1850d98..0e7c11b 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -570,6 +570,7 @@ def qemu_launch(efi=False, machine=None, imagename=None): args.pcap = None args.overlay = None args.dry_run = False + args.secondary_network = False qemu = QemuCommand(args) cmdline = qemu.command_line() -- cgit v1.2.3-54-g00ecf From 1804d9f6cfcae158fcf1e5c9da90fdf8cbc6fc18 Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Fri, 23 Mar 2018 11:56:15 +0100 Subject: UDP Socket activation for discovery service Also, timeout communication to the DUT after 60s. --- lib/oeqa/selftest/cases/updater.py | 4 ++-- recipes-sota/aktualizr/files/aktualizr-secondary.socket | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/oeqa/selftest/cases/updater.py') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index 0e7c11b..06884e5 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -544,7 +544,7 @@ class SecondaryTests(OESelftestTestCase): self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) def test_secondary_listening(self): - print('Checking aktualizr-secondary is present') + print('Checking aktualizr-secondary service is listening') stdout, stderr, retcode = self.qemu_command('echo test | nc localhost 9030') self.assertEqual(retcode, 0, "Unable to connect to secondary") @@ -591,7 +591,7 @@ def qemu_send_command(port, command): command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' + str(port) + ' "' + command + '"'] s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = s2.communicate() + stdout, stderr = s2.communicate(timeout=60) return stdout, stderr, s2.returncode diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.socket b/recipes-sota/aktualizr/files/aktualizr-secondary.socket index 1cb4269..bda8cdb 100644 --- a/recipes-sota/aktualizr/files/aktualizr-secondary.socket +++ b/recipes-sota/aktualizr/files/aktualizr-secondary.socket @@ -1,5 +1,6 @@ [Socket] ListenStream=9030 +ListenDatagram=9030 [Install] WantedBy=sockets.target \ No newline at end of file -- cgit v1.2.3-54-g00ecf From de2b0f06546666aacf9dd2fce94e0134768c6a3b Mon Sep 17 00:00:00 2001 From: Phil Wise Date: Tue, 27 Mar 2018 14:06:38 +0200 Subject: Add SOTA client feature to enable secondary network Also add a test for the 'primary-image' --- lib/oeqa/selftest/cases/updater.py | 41 ++++++++++++++++++++++ recipes-sota/aktualizr/aktualizr-auto-prov.bb | 4 ++- recipes-sota/aktualizr/aktualizr_git.bb | 3 +- .../files/27-dhcp-client-external.network | 6 ++++ .../secondary-network-config.bb | 6 +++- recipes-test/images/secondary-image.bb | 2 ++ 6 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 recipes-test/demo-network-config/files/27-dhcp-client-external.network (limited to 'lib/oeqa/selftest/cases/updater.py') diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater.py index 06884e5..e459ffb 100644 --- a/lib/oeqa/selftest/cases/updater.py +++ b/lib/oeqa/selftest/cases/updater.py @@ -548,6 +548,47 @@ class SecondaryTests(OESelftestTestCase): stdout, stderr, retcode = self.qemu_command('echo test | nc localhost 9030') self.assertEqual(retcode, 0, "Unable to connect to secondary") + +class PrimaryTests(OESelftestTestCase): + @classmethod + def setUpClass(cls): + super(PrimaryTests, cls).setUpClass() + logger = logging.getLogger("selftest") + logger.info('Running bitbake to build primary-image') + bitbake('primary-image') + + def setUpLocal(self): + layer = "meta-updater-qemux86-64" + result = runCmd('bitbake-layers show-layers') + if re.search(layer, result.output) is None: + # Assume the directory layout for finding other layers. We could also + # make assumptions by using 'show-layers', but either way, if the + # layers we need aren't where we expect them, we are out of like. + path = os.path.abspath(os.path.dirname(__file__)) + metadir = path + "/../../../../../" + self.meta_qemu = metadir + layer + runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu) + else: + self.meta_qemu = None + self.append_config('MACHINE = "qemux86-64"') + self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') + self.append_config('SOTA_CLIENT_FEATURES = "secondary-network"') + self.qemu, self.s = qemu_launch(machine='qemux86-64', imagename='primary-image') + + def tearDownLocal(self): + qemu_terminate(self.s) + if self.meta_qemu: + runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True) + + def qemu_command(self, command): + return qemu_send_command(self.qemu.ssh_port, command) + + def test_aktualizr_present(self): + print('Checking aktualizr is present') + stdout, stderr, retcode = self.qemu_command('aktualizr --help') + self.assertEqual(retcode, 0, "Unable to run aktualizr --help") + self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) + def qemu_launch(efi=False, machine=None, imagename=None): logger = logging.getLogger("selftest") logger.info('Running bitbake to build core-image-minimal') diff --git a/recipes-sota/aktualizr/aktualizr-auto-prov.bb b/recipes-sota/aktualizr/aktualizr-auto-prov.bb index 2190512..07e5bb8 100644 --- a/recipes-sota/aktualizr/aktualizr-auto-prov.bb +++ b/recipes-sota/aktualizr/aktualizr-auto-prov.bb @@ -35,7 +35,9 @@ do_install() { install -d ${D}${libdir}/sota install -d ${D}${localstatedir}/sota if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then - install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/sota_autoprov.toml ${D}${libdir}/sota/sota.toml + aktualizr_toml=${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-network', 'sota_autoprov_primary.toml', 'sota_autoprov.toml', d)} + + install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/${aktualizr_toml} ${D}${libdir}/sota/sota.toml # deploy SOTA credentials if [ -e ${SOTA_PACKED_CREDENTIALS} ]; then diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index 79a89ef..ba0a261 100644 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -22,7 +22,7 @@ SRC_URI = " \ file://aktualizr-secondary.socket \ file://aktualizr-serialcan.service \ " -SRCREV = "7d1d71a28a9ff0b14240b98600de3d541835b278" +SRCREV = "3fc94e7ed20a486da0067f01906250e9d4868931" BRANCH ?= "master" S = "${WORKDIR}/git" @@ -59,6 +59,7 @@ do_install_append_class-target () { do_install_append_class-native () { install -d ${D}${libdir}/sota install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml + install -m 0644 ${S}/config/sota_autoprov_primary.toml ${D}/${libdir}/sota/sota_autoprov_primary.toml install -m 0644 ${S}/config/sota_hsm_prov.toml ${D}/${libdir}/sota/sota_hsm_prov.toml install -m 0644 ${S}/config/sota_implicit_prov.toml ${D}/${libdir}/sota/sota_implicit_prov.toml install -m 0644 ${S}/config/sota_implicit_prov_ca.toml ${D}/${libdir}/sota/sota_implicit_prov_ca.toml diff --git a/recipes-test/demo-network-config/files/27-dhcp-client-external.network b/recipes-test/demo-network-config/files/27-dhcp-client-external.network new file mode 100644 index 0000000..ba49593 --- /dev/null +++ b/recipes-test/demo-network-config/files/27-dhcp-client-external.network @@ -0,0 +1,6 @@ +[Match] +Name=enp0s3 + +[Network] +Description=External network for secondary +DHCP=yes diff --git a/recipes-test/demo-network-config/secondary-network-config.bb b/recipes-test/demo-network-config/secondary-network-config.bb index 492d3ca..9091c65 100644 --- a/recipes-test/demo-network-config/secondary-network-config.bb +++ b/recipes-test/demo-network-config/secondary-network-config.bb @@ -3,7 +3,10 @@ LICENSE = "CLOSED" inherit allarch -SRC_URI = "file://26-dhcp-client.network" +SRC_URI = "\ + file://26-dhcp-client.network \ + file://27-dhcp-client-external.network \ + " FILES_${PN} = "/usr/lib/systemd/network" @@ -13,4 +16,5 @@ PR = "1" do_install() { install -d ${D}/usr/lib/systemd/network install -m 0644 ${WORKDIR}/26-dhcp-client.network ${D}/usr/lib/systemd/network/ + install -m 0644 ${WORKDIR}/27-dhcp-client-external.network ${D}/usr/lib/systemd/network/ } diff --git a/recipes-test/images/secondary-image.bb b/recipes-test/images/secondary-image.bb index c1ce57a..02153d0 100644 --- a/recipes-test/images/secondary-image.bb +++ b/recipes-test/images/secondary-image.bb @@ -13,6 +13,8 @@ IMAGE_INSTALL_remove = " \ aktualizr-ca-implicit-prov \ aktualizr-hsm-prov \ aktualizr-implicit-prov \ + connman \ + connman-client \ " IMAGE_INSTALL_append = " \ -- cgit v1.2.3-54-g00ecf