summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.adoc11
-rw-r--r--classes/sota.bbclass18
-rw-r--r--lib/oeqa/selftest/cases/testutils.py53
-rw-r--r--lib/oeqa/selftest/cases/updater_minnowboard.py2
-rw-r--r--lib/oeqa/selftest/cases/updater_qemux86_64.py189
-rw-r--r--lib/oeqa/selftest/cases/updater_raspberrypi.py3
-rw-r--r--recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb30
-rw-r--r--recipes-sota/aktualizr/aktualizr-device-prov-creds.bb (renamed from recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb)13
-rw-r--r--recipes-sota/aktualizr/aktualizr-device-prov-hsm.bb (renamed from recipes-sota/aktualizr/aktualizr-hsm-prov.bb)12
-rw-r--r--recipes-sota/aktualizr/aktualizr-device-prov.bb29
-rw-r--r--recipes-sota/aktualizr/aktualizr-shared-prov-creds.bb (renamed from recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb)3
-rw-r--r--recipes-sota/aktualizr/aktualizr-shared-prov.bb (renamed from recipes-sota/aktualizr/aktualizr-auto-prov.bb)14
-rw-r--r--recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb2
-rw-r--r--[-rwxr-xr-x]recipes-sota/aktualizr/aktualizr_git.bb26
-rw-r--r--recipes-sota/aktualizr/files/aktualizr-secondary.service6
-rw-r--r--recipes-sota/aktualizr/files/aktualizr-secondary.socket6
-rw-r--r--recipes-sota/config/aktualizr-polling-interval.bb29
-rw-r--r--recipes-sota/config/files/60-polling-interval.toml2
-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.bb15
-rw-r--r--scripts/qemucommand.py4
35 files changed, 478 insertions, 188 deletions
diff --git a/README.adoc b/README.adoc
index 01f1c85..5c4e5bc 100644
--- a/README.adoc
+++ b/README.adoc
@@ -87,11 +87,12 @@ Your images will also need network connectivity to be able to reach an actual OT
87* `GARAGE_SIGN_AUTOVERSION` - Set this to '1' to automatically fetch the last version of the garage tools installed by the aktualizr-native. Otherwise use the fixed version specified in the recipe. 87* `GARAGE_SIGN_AUTOVERSION` - Set this to '1' to automatically fetch the last version of the garage tools installed by the aktualizr-native. Otherwise use the fixed version specified in the recipe.
88* `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]. 88* `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].
89* `SOTA_DEPLOY_CREDENTIALS` - when set to '1' (default value), deploys credentials to the built image. Override it in `local.conf` to built a generic image that can be provisioned manually after the build. 89* `SOTA_DEPLOY_CREDENTIALS` - when set to '1' (default value), deploys credentials to the built image. Override it in `local.conf` to built a generic image that can be provisioned manually after the build.
90* `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-ca-implicit-prov`], and https://github.com/advancedtelematic/aktualizr/blob/master/docs/hsm-provisioning.adoc[`aktualizr-hsm-prov`]. The default is `aktualizr-auto-prov`. This can also be set to an empty string to avoid using a provisioning recipe. 90* `SOTA_CLIENT_PROV` - which provisioning method to use. Valid options are `aktualizr-shared-prov`, `aktualizr-device-prov`, and `aktualizr-device-prov-hsm`. For more information on these provisioning methods, see the https://docs.ota.here.com/client-config/client-provisioning-methods.html[OTA Connect documentation]. The default is `aktualizr-shared-prov`. This can also be set to an empty string to avoid using a provisioning recipe.
91* `SOTA_CLIENT_FEATURES` - extensions to aktualizr. The only valid options are `hsm` (to build with HSM support) and `secondary-network` (to set up a simulated 'in-vehicle' network with support for a primary node with a DHCP server and a secondary node with a DHCP client). 91* `SOTA_CLIENT_FEATURES` - extensions to aktualizr. The only valid options are `hsm` (to build with HSM support) and `secondary-network` (to set up a simulated 'in-vehicle' network with support for a primary node with a DHCP server and a secondary node with a DHCP client).
92* `SOTA_SECONDARY_CONFIG_DIR` - a directory containing JSON configuration files for virtual secondaries on the host. These will be installed into `/etc/sota/ecus` on the device and automatically provided to aktualizr. 92* `SOTA_SECONDARY_CONFIG_DIR` - a directory containing JSON configuration files for virtual secondaries on the host. These will be installed into `/etc/sota/ecus` on the device and automatically provided to aktualizr.
93* `SOTA_HARDWARE_ID` - a custom hardware ID that will be written to the aktualizr config. Defaults to MACHINE if not set. 93* `SOTA_HARDWARE_ID` - a custom hardware ID that will be written to the aktualizr config. Defaults to MACHINE if not set.
94* `RESOURCE_xxx_pn-aktualizr` - controls maximum resource usage of the aktualizr service, when `aktualizr-resource-control` is installed on the image. See <<aktualizr service resource control>> for details. 94* `RESOURCE_xxx_pn-aktualizr` - controls maximum resource usage of the aktualizr service, when `aktualizr-resource-control` is installed on the image. See <<aktualizr service resource control>> for details.
95* `SOTA_POLLING_SEC` - sets polling interval for aktualizr to check for updates if aktualizr-polling-sec is included in the image.
95 96
96== Usage 97== Usage
97 98
@@ -248,13 +249,13 @@ The aktualizr ptests can be run via oe-selftest with `oe-selftest -r updater_qem
248 249
249As described in <<sota-related-variables-in-localconf,SOTA-related variables in local.conf>> section you can set `SOTA_DEPLOY_CREDENTIALS` to `0` to prevent deploying credentials to the built `wic` image. In this case you get a generic image that you can use e.g. on a production line to flash a series of devices. The cost of this approach is that this image is half-baked and should be provisioned before it can connect to the backend. 250As described in <<sota-related-variables-in-localconf,SOTA-related variables in local.conf>> section you can set `SOTA_DEPLOY_CREDENTIALS` to `0` to prevent deploying credentials to the built `wic` image. In this case you get a generic image that you can use e.g. on a production line to flash a series of devices. The cost of this approach is that this image is half-baked and should be provisioned before it can connect to the backend.
250 251
251Provisioning procedure depends on your provisioning recipe, i.e. the value of `SOTA_CLIENT_PROV` (equal to `aktualizr-auto-prov` by default): 252Provisioning procedure depends on your provisioning recipe, i.e. the value of `SOTA_CLIENT_PROV` (equal to `aktualizr-shared-prov` by default):
252 253
253* For `aktualizr-auto-prov` put your `credentials.zip` to `/var/sota/sota_provisioning_credentials.zip` on the filesystem of a running device. If you have the filesystem of our device mounted to your build machine, prefix all paths with `/ostree/deploy/poky` as in `/ostree/deploy/poky/var/sota/sota_provisioning_credentials.zip`. 254* For `aktualizr-shared-prov` put your `credentials.zip` to `/var/sota/sota_provisioning_credentials.zip` on the filesystem of a running device. If you have the filesystem of our device mounted to your build machine, prefix all paths with `/ostree/deploy/poky` as in `/ostree/deploy/poky/var/sota/sota_provisioning_credentials.zip`.
254* For `aktualizr-ca-implicit-prov` 255* For `aktualizr-device-prov`
255** put URL to the backend server (together with protocol prefix and port number) at `/var/sota/gateway.url`. If you're using HERE OTA Connect, you can find the URL in the `autoprov.url` file in your credentials archive. 256** put URL to the backend server (together with protocol prefix and port number) at `/var/sota/gateway.url`. If you're using HERE OTA Connect, you can find the URL in the `autoprov.url` file in your credentials archive.
256** put client certificate, private key and root CA certificate (for the *server*, not for the *device*) at `/var/sota/import/client.pem`, `/var/sota/import/pkey.pem` and `/var/sota/import/root.crt` respectively. 257** put client certificate, private key and root CA certificate (for the *server*, not for the *device*) at `/var/sota/import/client.pem`, `/var/sota/import/pkey.pem` and `/var/sota/import/root.crt` respectively.
257* For `aktualizr-hsm-prov` 258* For `aktualizr-device-prov-hsm`
258** put URL to the server backend (together with protocol prefix and port number) at `/var/sota/gateway.url`. If you're using HERE OTA Connect, you can find the URL in the `autoprov.url` file in your credentials archive. 259** put URL to the server backend (together with protocol prefix and port number) at `/var/sota/gateway.url`. If you're using HERE OTA Connect, you can find the URL in the `autoprov.url` file in your credentials archive.
259** put root CA certificate (for the *server*, not for the *device*) at `/var/sota/import/root.crt`. 260** put root CA certificate (for the *server*, not for the *device*) at `/var/sota/import/root.crt`.
260** put client certificate and private key to slots 1 and 2 of the PKCS#11-compatible device. 261** put client certificate and private key to slots 1 and 2 of the PKCS#11-compatible device.
diff --git a/classes/sota.bbclass b/classes/sota.bbclass
index cb00a80..82278b2 100644
--- a/classes/sota.bbclass
+++ b/classes/sota.bbclass
@@ -3,15 +3,29 @@ python __anonymous() {
3 d.appendVarFlag("do_image_wic", "depends", " %s:do_image_otaimg" % d.getVar("IMAGE_BASENAME", True)) 3 d.appendVarFlag("do_image_wic", "depends", " %s:do_image_otaimg" % d.getVar("IMAGE_BASENAME", True))
4} 4}
5 5
6OVERRIDES .= "${@bb.utils.contains('DISTRO_FEATURES', 'sota', ':sota', '', d)}" 6DISTROOVERRIDES .= "${@bb.utils.contains('DISTRO_FEATURES', 'sota', ':sota', '', d)}"
7 7
8HOSTTOOLS_NONFATAL += "java" 8HOSTTOOLS_NONFATAL += "java"
9 9
10SOTA_CLIENT ??= "aktualizr" 10SOTA_CLIENT ??= "aktualizr"
11SOTA_CLIENT_PROV ??= "aktualizr-auto-prov" 11SOTA_CLIENT_PROV ??= "aktualizr-shared-prov"
12SOTA_DEPLOY_CREDENTIALS ?= "1" 12SOTA_DEPLOY_CREDENTIALS ?= "1"
13SOTA_HARDWARE_ID ??= "${MACHINE}" 13SOTA_HARDWARE_ID ??= "${MACHINE}"
14 14
15# Translate old provisioning recipe names into the new versions.
16python () {
17 prov = d.getVar("SOTA_CLIENT_PROV")
18 if prov == "aktualizr-auto-prov":
19 bb.warn('aktualizr-auto-prov is deprecated. Please use aktualizr-shared-prov instead.')
20 d.setVar("SOTA_CLIENT_PROV", "aktualizr-shared-prov")
21 elif prov == "aktualizr-ca-implicit-prov":
22 bb.warn('aktualizr-ca-implicit-prov is deprecated. Please use aktualizr-device-prov instead.')
23 d.setVar("SOTA_CLIENT_PROV", "aktualizr-device-prov")
24 elif prov == "aktualizr-hsm-prov":
25 bb.warn('aktualizr-hsm-prov is deprecated. Please use aktualizr-device-prov-hsm instead.')
26 d.setVar("SOTA_CLIENT_PROV", "aktualizr-device-prov-hsm")
27}
28
15IMAGE_INSTALL_append_sota = " ostree os-release ${SOTA_CLIENT} ${SOTA_CLIENT_PROV}" 29IMAGE_INSTALL_append_sota = " ostree os-release ${SOTA_CLIENT} ${SOTA_CLIENT_PROV}"
16IMAGE_CLASSES += " image_types_ostree image_types_ota" 30IMAGE_CLASSES += " image_types_ostree image_types_ota"
17IMAGE_FSTYPES += "${@bb.utils.contains('DISTRO_FEATURES', 'sota', 'ostreepush garagesign garagecheck otaimg wic', ' ', d)}" 31IMAGE_FSTYPES += "${@bb.utils.contains('DISTRO_FEATURES', 'sota', 'ostreepush garagesign garagecheck otaimg wic', ' ', d)}"
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_minnowboard.py b/lib/oeqa/selftest/cases/updater_minnowboard.py
index f5df584..267445b 100644
--- a/lib/oeqa/selftest/cases/updater_minnowboard.py
+++ b/lib/oeqa/selftest/cases/updater_minnowboard.py
@@ -29,7 +29,7 @@ class MinnowTests(OESelftestTestCase):
29 self.meta_minnow = None 29 self.meta_minnow = None
30 self.append_config('MACHINE = "intel-corei7-64"') 30 self.append_config('MACHINE = "intel-corei7-64"')
31 self.append_config('OSTREE_BOOTLOADER = "grub"') 31 self.append_config('OSTREE_BOOTLOADER = "grub"')
32 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 32 self.append_config('SOTA_CLIENT_PROV = " aktualizr-shared-prov "')
33 self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64') 33 self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64')
34 34
35 def tearDownLocal(self): 35 def tearDownLocal(self):
diff --git a/lib/oeqa/selftest/cases/updater_qemux86_64.py b/lib/oeqa/selftest/cases/updater_qemux86_64.py
index bad7a87..218d361 100644
--- a/lib/oeqa/selftest/cases/updater_qemux86_64.py
+++ b/lib/oeqa/selftest/cases/updater_qemux86_64.py
@@ -4,18 +4,19 @@ 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):
15 def test_credentials(self): 16 def test_credentials(self):
16 logger = logging.getLogger("selftest") 17 logger = logging.getLogger("selftest")
17 logger.info('Running bitbake to build core-image-minimal') 18 logger.info('Running bitbake to build core-image-minimal')
18 self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"') 19 self.append_config('SOTA_CLIENT_PROV = "aktualizr-shared-prov"')
19 bitbake('core-image-minimal') 20 bitbake('core-image-minimal')
20 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS') 21 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS')
21 # skip the test if the variable SOTA_PACKED_CREDENTIALS is not set 22 # skip the test if the variable SOTA_PACKED_CREDENTIALS is not set
@@ -45,13 +46,13 @@ class AktualizrToolsTests(OESelftestTestCase):
45 46
46 def test_cert_provider_local_output(self): 47 def test_cert_provider_local_output(self):
47 logger = logging.getLogger("selftest") 48 logger = logging.getLogger("selftest")
48 logger.info('Running bitbake to build aktualizr-ca-implicit-prov') 49 logger.info('Running bitbake to build aktualizr-device-prov')
49 bitbake('aktualizr-ca-implicit-prov') 50 bitbake('aktualizr-device-prov')
50 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS', 'T'], 'aktualizr-native') 51 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS', 'T'], 'aktualizr-native')
51 creds = bb_vars['SOTA_PACKED_CREDENTIALS'] 52 creds = bb_vars['SOTA_PACKED_CREDENTIALS']
52 temp_dir = bb_vars['T'] 53 temp_dir = bb_vars['T']
53 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-ca-implicit-prov') 54 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-device-prov')
54 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov_ca.toml' 55 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota-device-cred.toml'
55 56
56 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -r -l {temp} -g {config}' 57 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -r -l {temp} -g {config}'
57 .format(creds=creds, temp=temp_dir, config=config)) 58 .format(creds=creds, temp=temp_dir, config=config))
@@ -68,7 +69,7 @@ class AktualizrToolsTests(OESelftestTestCase):
68 self.assertTrue(os.path.getsize(ca_path) > 0, "Client certificate at %s is empty." % ca_path) 69 self.assertTrue(os.path.getsize(ca_path) > 0, "Client certificate at %s is empty." % ca_path)
69 70
70 71
71class AutoProvTests(OESelftestTestCase): 72class SharedCredProvTests(OESelftestTestCase):
72 73
73 def setUpLocal(self): 74 def setUpLocal(self):
74 layer = "meta-updater-qemux86-64" 75 layer = "meta-updater-qemux86-64"
@@ -84,7 +85,7 @@ class AutoProvTests(OESelftestTestCase):
84 else: 85 else:
85 self.meta_qemu = None 86 self.meta_qemu = None
86 self.append_config('MACHINE = "qemux86-64"') 87 self.append_config('MACHINE = "qemux86-64"')
87 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 88 self.append_config('SOTA_CLIENT_PROV = " aktualizr-shared-prov "')
88 self.qemu, self.s = qemu_launch(machine='qemux86-64') 89 self.qemu, self.s = qemu_launch(machine='qemux86-64')
89 90
90 def tearDownLocal(self): 91 def tearDownLocal(self):
@@ -126,7 +127,7 @@ class ManualControlTests(OESelftestTestCase):
126 else: 127 else:
127 self.meta_qemu = None 128 self.meta_qemu = None
128 self.append_config('MACHINE = "qemux86-64"') 129 self.append_config('MACHINE = "qemux86-64"')
129 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 130 self.append_config('SOTA_CLIENT_PROV = " aktualizr-shared-prov "')
130 self.append_config('SYSTEMD_AUTO_ENABLE_aktualizr = "disable"') 131 self.append_config('SYSTEMD_AUTO_ENABLE_aktualizr = "disable"')
131 self.qemu, self.s = qemu_launch(machine='qemux86-64') 132 self.qemu, self.s = qemu_launch(machine='qemux86-64')
132 133
@@ -154,7 +155,7 @@ class ManualControlTests(OESelftestTestCase):
154 'Aktualizr should have run' + stderr.decode() + stdout.decode()) 155 'Aktualizr should have run' + stderr.decode() + stdout.decode())
155 156
156 157
157class ImplProvTests(OESelftestTestCase): 158class DeviceCredProvTests(OESelftestTestCase):
158 159
159 def setUpLocal(self): 160 def setUpLocal(self):
160 layer = "meta-updater-qemux86-64" 161 layer = "meta-updater-qemux86-64"
@@ -170,9 +171,9 @@ class ImplProvTests(OESelftestTestCase):
170 else: 171 else:
171 self.meta_qemu = None 172 self.meta_qemu = None
172 self.append_config('MACHINE = "qemux86-64"') 173 self.append_config('MACHINE = "qemux86-64"')
173 self.append_config('SOTA_CLIENT_PROV = " aktualizr-ca-implicit-prov "') 174 self.append_config('SOTA_CLIENT_PROV = " aktualizr-device-prov "')
174 self.append_config('SOTA_DEPLOY_CREDENTIALS = "0"') 175 self.append_config('SOTA_DEPLOY_CREDENTIALS = "0"')
175 runCmd('bitbake -c cleanall aktualizr aktualizr-ca-implicit-prov') 176 runCmd('bitbake -c cleanall aktualizr aktualizr-device-prov')
176 self.qemu, self.s = qemu_launch(machine='qemux86-64') 177 self.qemu, self.s = qemu_launch(machine='qemux86-64')
177 178
178 def tearDownLocal(self): 179 def tearDownLocal(self):
@@ -200,8 +201,8 @@ class ImplProvTests(OESelftestTestCase):
200 # Run aktualizr-cert-provider. 201 # Run aktualizr-cert-provider.
201 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') 202 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
202 creds = bb_vars['SOTA_PACKED_CREDENTIALS'] 203 creds = bb_vars['SOTA_PACKED_CREDENTIALS']
203 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-ca-implicit-prov') 204 bb_vars_prov = get_bb_vars(['STAGING_DIR_HOST', 'libdir'], 'aktualizr-device-prov')
204 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota_implicit_prov_ca.toml' 205 config = bb_vars_prov['STAGING_DIR_HOST'] + bb_vars_prov['libdir'] + '/sota/sota-device-cred.toml'
205 206
206 print('Provisining at root@localhost:%d' % self.qemu.ssh_port) 207 print('Provisining at root@localhost:%d' % self.qemu.ssh_port)
207 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -t root@localhost -p {port} -s -u -r -g {config}' 208 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -t root@localhost -p {port} -s -u -r -g {config}'
@@ -210,7 +211,7 @@ class ImplProvTests(OESelftestTestCase):
210 verifyProvisioned(self, machine) 211 verifyProvisioned(self, machine)
211 212
212 213
213class HsmTests(OESelftestTestCase): 214class DeviceCredProvHsmTests(OESelftestTestCase):
214 215
215 def setUpLocal(self): 216 def setUpLocal(self):
216 layer = "meta-updater-qemux86-64" 217 layer = "meta-updater-qemux86-64"
@@ -226,11 +227,11 @@ class HsmTests(OESelftestTestCase):
226 else: 227 else:
227 self.meta_qemu = None 228 self.meta_qemu = None
228 self.append_config('MACHINE = "qemux86-64"') 229 self.append_config('MACHINE = "qemux86-64"')
229 self.append_config('SOTA_CLIENT_PROV = "aktualizr-hsm-prov"') 230 self.append_config('SOTA_CLIENT_PROV = "aktualizr-device-prov-hsm"')
230 self.append_config('SOTA_DEPLOY_CREDENTIALS = "0"') 231 self.append_config('SOTA_DEPLOY_CREDENTIALS = "0"')
231 self.append_config('SOTA_CLIENT_FEATURES = "hsm"') 232 self.append_config('SOTA_CLIENT_FEATURES = "hsm"')
232 self.append_config('IMAGE_INSTALL_append = " softhsm-testtoken"') 233 self.append_config('IMAGE_INSTALL_append = " softhsm-testtoken"')
233 runCmd('bitbake -c cleanall aktualizr aktualizr-hsm-prov') 234 runCmd('bitbake -c cleanall aktualizr aktualizr-device-prov-hsm')
234 self.qemu, self.s = qemu_launch(machine='qemux86-64') 235 self.qemu, self.s = qemu_launch(machine='qemux86-64')
235 236
236 def tearDownLocal(self): 237 def tearDownLocal(self):
@@ -268,8 +269,8 @@ class HsmTests(OESelftestTestCase):
268 # Run aktualizr-cert-provider. 269 # Run aktualizr-cert-provider.
269 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') 270 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
270 creds = bb_vars['SOTA_PACKED_CREDENTIALS'] 271 creds = bb_vars['SOTA_PACKED_CREDENTIALS']
271 bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-hsm-prov') 272 bb_vars_prov = get_bb_vars(['STAGING_DIR_NATIVE', 'libdir'], 'aktualizr-device-prov-hsm')
272 config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota_hsm_prov.toml' 273 config = bb_vars_prov['STAGING_DIR_NATIVE'] + bb_vars_prov['libdir'] + '/sota/sota-device-cred-hsm.toml'
273 274
274 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -t root@localhost -p {port} -r -s -u -g {config}' 275 akt_native_run(self, 'aktualizr-cert-provider -c {creds} -t root@localhost -p {port} -r -s -u -g {config}'
275 .format(creds=creds, port=self.qemu.ssh_port, config=config)) 276 .format(creds=creds, port=self.qemu.ssh_port, config=config))
@@ -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-shared-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
364 def tearDownLocal(self):
365 qemu_terminate(self.s)
366 if self.meta_qemu:
367 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True)
368 435
369 def qemu_command(self, command): 436 with self.secondary:
370 return qemu_send_command(self.qemu.ssh_port, command) 437 self.assertTrue(self.secondary.was_successfully_booted(),
438 'The secondary failed to boot: {}'.format(self.secondary.stderr))
371 439
372 def test_aktualizr_present(self): 440 self.assertTrue(self.primary.is_ecu_registered(self.secondary.id),
373 print('Checking aktualizr is present') 441 "The secondary wasn't registered at the primary: {}".format(self.primary.get_info()))
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):
@@ -391,7 +456,7 @@ class ResourceControlTests(OESelftestTestCase):
391 else: 456 else:
392 self.meta_qemu = None 457 self.meta_qemu = None
393 self.append_config('MACHINE = "qemux86-64"') 458 self.append_config('MACHINE = "qemux86-64"')
394 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 459 self.append_config('SOTA_CLIENT_PROV = " aktualizr-shared-prov "')
395 self.append_config('IMAGE_INSTALL_append += " aktualizr-resource-control "') 460 self.append_config('IMAGE_INSTALL_append += " aktualizr-resource-control "')
396 self.append_config('RESOURCE_CPU_WEIGHT_pn-aktualizr = "1000"') 461 self.append_config('RESOURCE_CPU_WEIGHT_pn-aktualizr = "1000"')
397 self.append_config('RESOURCE_MEMORY_HIGH_pn-aktualizr = "50M"') 462 self.append_config('RESOURCE_MEMORY_HIGH_pn-aktualizr = "50M"')
diff --git a/lib/oeqa/selftest/cases/updater_raspberrypi.py b/lib/oeqa/selftest/cases/updater_raspberrypi.py
index 1cab2b8..6b71a03 100644
--- a/lib/oeqa/selftest/cases/updater_raspberrypi.py
+++ b/lib/oeqa/selftest/cases/updater_raspberrypi.py
@@ -53,7 +53,7 @@ class RpiTests(OESelftestTestCase):
53 self.meta_qemu = None 53 self.meta_qemu = None
54 54
55 self.append_config('MACHINE = "raspberrypi3"') 55 self.append_config('MACHINE = "raspberrypi3"')
56 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "') 56 self.append_config('SOTA_CLIENT_PROV = " aktualizr-shared-prov "')
57 57
58 def tearDownLocal(self): 58 def tearDownLocal(self):
59 if self.meta_qemu: 59 if self.meta_qemu:
@@ -68,7 +68,6 @@ class RpiTests(OESelftestTestCase):
68 def test_build(self): 68 def test_build(self):
69 logger = logging.getLogger("selftest") 69 logger = logging.getLogger("selftest")
70 logger.info('Running bitbake to build rpi-basic-image') 70 logger.info('Running bitbake to build rpi-basic-image')
71 self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"')
72 bitbake('rpi-basic-image') 71 bitbake('rpi-basic-image')
73 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS') 72 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS')
74 # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set. 73 # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set.
diff --git a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb
deleted file mode 100644
index 0d1c860..0000000
--- a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb
+++ /dev/null
@@ -1,30 +0,0 @@
1SUMMARY = "Aktualizr configuration for implicit provisioning with CA"
2DESCRIPTION = "Configuration for implicitly provisioning Aktualizr using externally provided or generated CA"
3
4HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
5SECTION = "base"
6LICENSE = "MPL-2.0"
7LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
8
9inherit allarch
10
11DEPENDS = "aktualizr aktualizr-native openssl-native"
12RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}"
13
14PV = "1.0"
15PR = "1"
16
17require credentials.inc
18
19do_install() {
20 install -m 0700 -d ${D}${libdir}/sota/conf.d
21
22 install -m 0644 ${STAGING_DIR_HOST}${libdir}/sota/sota_implicit_prov_ca.toml \
23 ${D}${libdir}/sota/conf.d/20-sota_implicit_prov_ca.toml
24}
25
26FILES_${PN} = " \
27 ${libdir}/sota/conf.d/20-sota_implicit_prov_ca.toml \
28 "
29
30# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb b/recipes-sota/aktualizr/aktualizr-device-prov-creds.bb
index da17d77..6e02a50 100644
--- a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb
+++ b/recipes-sota/aktualizr/aktualizr-device-prov-creds.bb
@@ -1,4 +1,5 @@
1SUMMARY = "Credentials for implicit provisioning with CA certificate" 1SUMMARY = "Credentials for device provisioning with fleet CA certificate"
2HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
2SECTION = "base" 3SECTION = "base"
3LICENSE = "MPL-2.0" 4LICENSE = "MPL-2.0"
4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 5LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
@@ -13,8 +14,8 @@ DEPENDS = "aktualizr aktualizr-native"
13ALLOW_EMPTY_${PN} = "1" 14ALLOW_EMPTY_${PN} = "1"
14 15
15SRC_URI = " \ 16SRC_URI = " \
16 file://ca.cnf \ 17 file://ca.cnf \
17 " 18 "
18 19
19require credentials.inc 20require credentials.inc
20 21
@@ -39,7 +40,7 @@ do_install() {
39 fi 40 fi
40 41
41 if [ -z ${SOTA_CAKEY_PATH} ]; then 42 if [ -z ${SOTA_CAKEY_PATH} ]; then
42 bbfatal "SOTA_CAKEY_PATH should be set when using implicit provisioning" 43 bbfatal "SOTA_CAKEY_PATH should be set when using device credential provisioning"
43 fi 44 fi
44 45
45 install -m 0700 -d ${D}${localstatedir}/sota 46 install -m 0700 -d ${D}${localstatedir}/sota
@@ -49,9 +50,11 @@ do_install() {
49 --root-ca \ 50 --root-ca \
50 --server-url \ 51 --server-url \
51 --local ${D} \ 52 --local ${D} \
52 --config ${STAGING_DIR_HOST}${libdir}/sota/sota_implicit_prov_ca.toml 53 --config ${STAGING_DIR_HOST}${libdir}/sota/sota-device-cred.toml
53 fi 54 fi
54} 55}
55 56
56FILES_${PN} = " \ 57FILES_${PN} = " \
57 ${localstatedir}/sota/*" 58 ${localstatedir}/sota/*"
59
60# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-sota/aktualizr/aktualizr-hsm-prov.bb b/recipes-sota/aktualizr/aktualizr-device-prov-hsm.bb
index f738f3e..83840e5 100644
--- a/recipes-sota/aktualizr/aktualizr-hsm-prov.bb
+++ b/recipes-sota/aktualizr/aktualizr-device-prov-hsm.bb
@@ -1,5 +1,5 @@
1SUMMARY = "Aktualizr configuration with HSM support" 1SUMMARY = "Aktualizr configuration for device credential provisioning with HSM support"
2DESCRIPTION = "Configuration for HSM provisioning with Aktualizr, the SOTA Client application written in C++" 2DESCRIPTION = "Configuration for provisioning Aktualizr with device credentials using externally provided or generated CA with HSM support"
3HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" 3HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
4SECTION = "base" 4SECTION = "base"
5LICENSE = "MPL-2.0" 5LICENSE = "MPL-2.0"
@@ -8,7 +8,7 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7
8inherit allarch 8inherit allarch
9 9
10DEPENDS = "aktualizr aktualizr-native" 10DEPENDS = "aktualizr aktualizr-native"
11RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds softhsm-testtoken' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}" 11RDEPENDS_${PN}_append = "${@' aktualizr-device-prov-creds softhsm-testtoken' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}"
12 12
13SRC_URI = "" 13SRC_URI = ""
14PV = "1.0" 14PV = "1.0"
@@ -18,13 +18,13 @@ require credentials.inc
18 18
19do_install() { 19do_install() {
20 install -m 0700 -d ${D}${libdir}/sota/conf.d 20 install -m 0700 -d ${D}${libdir}/sota/conf.d
21 install -m 0644 ${STAGING_DIR_NATIVE}${libdir_native}/sota/sota_hsm_prov.toml \ 21 install -m 0644 ${STAGING_DIR_NATIVE}${libdir_native}/sota/sota-device-cred-hsm.toml \
22 ${D}${libdir}/sota/conf.d/20-sota_hsm_prov.toml 22 ${D}${libdir}/sota/conf.d/20-sota-device-cred-hsm.toml
23} 23}
24 24
25FILES_${PN} = " \ 25FILES_${PN} = " \
26 ${libdir}/sota/conf.d \ 26 ${libdir}/sota/conf.d \
27 ${libdir}/sota/conf.d/20-sota_hsm_prov.toml \ 27 ${libdir}/sota/conf.d/20-sota-device-cred-hsm.toml \
28 " 28 "
29 29
30# vim:set ts=4 sw=4 sts=4 expandtab: 30# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-sota/aktualizr/aktualizr-device-prov.bb b/recipes-sota/aktualizr/aktualizr-device-prov.bb
new file mode 100644
index 0000000..be0f5c8
--- /dev/null
+++ b/recipes-sota/aktualizr/aktualizr-device-prov.bb
@@ -0,0 +1,29 @@
1SUMMARY = "Aktualizr configuration for device credential provisioning"
2DESCRIPTION = "Configuration for provisioning Aktualizr with device credentials using externally provided or generated CA"
3HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
4SECTION = "base"
5LICENSE = "MPL-2.0"
6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
7
8inherit allarch
9
10DEPENDS = "aktualizr aktualizr-native openssl-native"
11RDEPENDS_${PN}_append = "${@' aktualizr-device-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}"
12
13PV = "1.0"
14PR = "1"
15
16require credentials.inc
17
18do_install() {
19 install -m 0700 -d ${D}${libdir}/sota/conf.d
20 install -m 0644 ${STAGING_DIR_NATIVE}${libdir_native}/sota/sota-device-cred.toml \
21 ${D}${libdir}/sota/conf.d/20-sota-device-cred.toml
22}
23
24FILES_${PN} = " \
25 ${libdir}/sota/conf.d \
26 ${libdir}/sota/conf.d/20-sota-device-cred.toml \
27 "
28
29# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb b/recipes-sota/aktualizr/aktualizr-shared-prov-creds.bb
index 6b2dd27..dbb5fde 100644
--- a/recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb
+++ b/recipes-sota/aktualizr/aktualizr-shared-prov-creds.bb
@@ -1,4 +1,5 @@
1SUMMARY = "Credentials for autoprovisioning scenario" 1SUMMARY = "Credentials for shared provisioning"
2HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
2SECTION = "base" 3SECTION = "base"
3LICENSE = "MPL-2.0" 4LICENSE = "MPL-2.0"
4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 5LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
diff --git a/recipes-sota/aktualizr/aktualizr-auto-prov.bb b/recipes-sota/aktualizr/aktualizr-shared-prov.bb
index 3e4c208..c42546c 100644
--- a/recipes-sota/aktualizr/aktualizr-auto-prov.bb
+++ b/recipes-sota/aktualizr/aktualizr-shared-prov.bb
@@ -1,5 +1,5 @@
1SUMMARY = "Aktualizr configuration for autoprovisioning" 1SUMMARY = "Aktualizr configuration for shared credential provisioning"
2DESCRIPTION = "Configuration for automatically provisioning Aktualizr, the SOTA Client application written in C++" 2DESCRIPTION = "Configuration for provisioning Aktualizr with shared credentials"
3HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" 3HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
4SECTION = "base" 4SECTION = "base"
5LICENSE = "MPL-2.0" 5LICENSE = "MPL-2.0"
@@ -8,7 +8,7 @@ LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7
8inherit allarch 8inherit allarch
9 9
10DEPENDS = "aktualizr-native zip-native" 10DEPENDS = "aktualizr-native zip-native"
11RDEPENDS_${PN}_append = "${@' aktualizr-auto-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}" 11RDEPENDS_${PN}_append = "${@' aktualizr-shared-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}"
12PV = "1.0" 12PV = "1.0"
13PR = "6" 13PR = "6"
14 14
@@ -31,15 +31,13 @@ do_install() {
31 fi 31 fi
32 32
33 install -m 0700 -d ${D}${libdir}/sota/conf.d 33 install -m 0700 -d ${D}${libdir}/sota/conf.d
34 aktualizr_toml=${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-network', 'sota_autoprov_primary.toml', 'sota_autoprov.toml', d)} 34 install -m 0644 ${STAGING_DIR_NATIVE}${libdir_native}/sota/sota-shared-cred.toml \
35 35 ${D}${libdir}/sota/conf.d/20-sota-shared-cred.toml
36 install -m 0644 ${STAGING_DIR_NATIVE}${libdir_native}/sota/${aktualizr_toml} \
37 ${D}${libdir}/sota/conf.d/20-${aktualizr_toml}
38} 36}
39 37
40FILES_${PN} = " \ 38FILES_${PN} = " \
41 ${libdir}/sota/conf.d \ 39 ${libdir}/sota/conf.d \
42 ${libdir}/sota/conf.d/20-${aktualizr_toml} \ 40 ${libdir}/sota/conf.d/20-sota-shared-cred.toml \
43 " 41 "
44 42
45# vim:set ts=4 sw=4 sts=4 expandtab: 43# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb b/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb
index ed1e3a8..2bc2e3f 100644
--- a/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb
+++ b/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb
@@ -11,7 +11,7 @@ RDEPENDS_${PN} = "aktualizr"
11 11
12do_install() { 12do_install() {
13 install -m 0700 -d ${D}${libdir}/sota/conf.d 13 install -m 0700 -d ${D}${libdir}/sota/conf.d
14 install -m 0644 ${STAGING_DIR_NATIVE}${libdir_native}/sota/sota_uboot_env.toml ${D}${libdir}/sota/conf.d/30-rollback.toml 14 install -m 0644 ${STAGING_DIR_NATIVE}${libdir_native}/sota/sota-uboot-env.toml ${D}${libdir}/sota/conf.d/30-rollback.toml
15} 15}
16 16
17FILES_${PN} = " \ 17FILES_${PN} = " \
diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb
index a49095a..4dbfb06 100755..100644
--- a/recipes-sota/aktualizr/aktualizr_git.bb
+++ b/recipes-sota/aktualizr/aktualizr_git.bb
@@ -15,24 +15,23 @@ RDEPENDS_${PN}-ptest += "bash cmake curl python3-misc python3-modules sqlite3 va
15PV = "1.0+git${SRCPV}" 15PV = "1.0+git${SRCPV}"
16PR = "7" 16PR = "7"
17 17
18GARAGE_SIGN_PV = "0.6.0-18-g5b8b259" 18GARAGE_SIGN_PV = "0.7.0-3-gf5ba640"
19 19
20SRC_URI = " \ 20SRC_URI = " \
21 gitsm://github.com/advancedtelematic/aktualizr;branch=${BRANCH} \ 21 gitsm://github.com/advancedtelematic/aktualizr;branch=${BRANCH} \
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 ''} \
29 " 28 "
30 29
31# for garage-sign archive 30# for garage-sign archive
32SRC_URI[md5sum] = "c5e9968dfe78a7264ab9a8338c11725d" 31SRC_URI[md5sum] = "e104ccd4f32e52571a5fc0e5042db050"
33SRC_URI[sha256sum] = "3a19258d7a1825a308aca0da82f7a337985bec05e8951355c4c95f0fcf2444f4" 32SRC_URI[sha256sum] = "c590be1a57523bfe097af82279eda5c97cf40ae47fb27162cf33c469702c8a9b"
34 33
35SRCREV = "c50feb37034eceb1254429d3e3ed38e5b8a0dc60" 34SRCREV = "fce5854ff10e7efd52d69bbaf68dc2af990d5746"
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} -Dgtest_disable_pthreads=ON ${@bb.utils.contains('PTEST_ENABLED', '1', '-DTESTSUITE_VALGRIND=on', '', d)}" 49EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV} -Dgtest_disable_pthreads=ON ${@bb.utils.contains('PTEST_ENABLED', '1', '-DTESTSUITE_VALGRIND=on', '', d)}"
51 50
@@ -94,14 +93,12 @@ do_install_ptest() {
94 93
95do_install_append () { 94do_install_append () {
96 install -d ${D}${libdir}/sota 95 install -d ${D}${libdir}/sota
97 install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml 96 install -m 0644 ${S}/config/sota-shared-cred.toml ${D}/${libdir}/sota/sota-shared-cred.toml
98 install -m 0644 ${S}/config/sota_autoprov_primary.toml ${D}/${libdir}/sota/sota_autoprov_primary.toml 97 install -m 0644 ${S}/config/sota-device-cred-hsm.toml ${D}/${libdir}/sota/sota-device-cred-hsm.toml
99 install -m 0644 ${S}/config/sota_hsm_prov.toml ${D}/${libdir}/sota/sota_hsm_prov.toml 98 install -m 0644 ${S}/config/sota-device-cred.toml ${D}/${libdir}/sota/sota-device-cred.toml
100 install -m 0644 ${S}/config/sota_implicit_prov_ca.toml ${D}/${libdir}/sota/sota_implicit_prov_ca.toml 99 install -m 0644 ${S}/config/sota-secondary.toml ${D}/${libdir}/sota/sota-secondary.toml
101 install -m 0644 ${S}/config/sota_secondary.toml ${D}/${libdir}/sota/sota_secondary.toml 100 install -m 0644 ${S}/config/sota-uboot-env.toml ${D}/${libdir}/sota/sota-uboot-env.toml
102 install -m 0644 ${S}/config/sota_uboot_env.toml ${D}/${libdir}/sota/sota_uboot_env.toml
103 install -d ${D}${systemd_unitdir}/system 101 install -d ${D}${systemd_unitdir}/system
104 install -m 0644 ${WORKDIR}/aktualizr-secondary.socket ${D}${systemd_unitdir}/system/aktualizr-secondary.socket
105 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
106 install -m 0700 -d ${D}${libdir}/sota/conf.d 103 install -m 0700 -d ${D}${libdir}/sota/conf.d
107 install -m 0700 -d ${D}${sysconfdir}/sota/conf.d 104 install -m 0700 -d ${D}${sysconfdir}/sota/conf.d
@@ -176,8 +173,7 @@ FILES_${PN}-examples = " \
176 173
177FILES_${PN}-secondary = " \ 174FILES_${PN}-secondary = " \
178 ${bindir}/aktualizr-secondary \ 175 ${bindir}/aktualizr-secondary \
179 ${libdir}/sota/sota_secondary.toml \ 176 ${libdir}/sota/sota-secondary.toml \
180 ${systemd_unitdir}/system/aktualizr-secondary.socket \
181 ${systemd_unitdir}/system/aktualizr-secondary.service \ 177 ${systemd_unitdir}/system/aktualizr-secondary.service \
182 " 178 "
183 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-sota/config/aktualizr-polling-interval.bb b/recipes-sota/config/aktualizr-polling-interval.bb
new file mode 100644
index 0000000..53c008a
--- /dev/null
+++ b/recipes-sota/config/aktualizr-polling-interval.bb
@@ -0,0 +1,29 @@
1SUMMARY = "Set polling interval in Aktualizr"
2DESCRIPTION = "Configures aktualizr to poll at a custom frequency (suitable for testing or other purposes)"
3HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
4SECTION = "base"
5LICENSE = "MPL-2.0"
6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
7
8inherit allarch
9
10SRC_URI = " \
11 file://60-polling-interval.toml \
12 "
13
14SOTA_POLLING_SEC ?= "30"
15
16do_install_append () {
17 install -m 0700 -d ${D}${libdir}/sota/conf.d
18 install -m 0644 ${WORKDIR}/60-polling-interval.toml ${D}${libdir}/sota/conf.d/60-polling-interval.toml
19
20 sed -i -e 's|@POLLING_SEC@|${SOTA_POLLING_SEC}|g' \
21 ${D}${libdir}/sota/conf.d/60-polling-interval.toml
22}
23
24FILES_${PN} = " \
25 ${libdir}/sota/conf.d/60-polling-interval.toml \
26 "
27
28# vim:set ts=4 sw=4 sts=4 expandtab:
29
diff --git a/recipes-sota/config/files/60-polling-interval.toml b/recipes-sota/config/files/60-polling-interval.toml
new file mode 100644
index 0000000..7d25d05
--- /dev/null
+++ b/recipes-sota/config/files/60-polling-interval.toml
@@ -0,0 +1,2 @@
1[uptane]
2polling_sec = @POLLING_SEC@
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..27cb553
--- /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..9411646
--- /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..27d1e3f 100644
--- a/recipes-test/images/secondary-image.bb
+++ b/recipes-test/images/secondary-image.bb
@@ -2,18 +2,20 @@ 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)
10IMAGE_INSTALL_remove = " \ 12IMAGE_INSTALL_remove = " \
11 aktualizr \ 13 aktualizr \
12 aktualizr-auto-prov \ 14 aktualizr-shared-prov \
13 aktualizr-auto-prov-creds \ 15 aktualizr-shared-prov-creds \
14 aktualizr-ca-implicit-prov \ 16 aktualizr-device-prov \
15 aktualizr-ca-implicit-prov-creds \ 17 aktualizr-device-prov-creds \
16 aktualizr-hsm-prov \ 18 aktualizr-device-prov-hsm \
17 aktualizr-uboot-env-rollback \ 19 aktualizr-uboot-env-rollback \
18 virtual/network-configuration \ 20 virtual/network-configuration \
19 " 21 "
@@ -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 9b21a66..532e331 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"]