summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Vacek <patrickvacek@gmail.com>2019-05-02 14:25:25 +0200
committerGitHub <noreply@github.com>2019-05-02 14:25:25 +0200
commit438814dec075da891ed37a57c8b5138b43f56818 (patch)
treedb8d7522d1f46d2048d290e82a1205b5e302ad17
parent2d2e46834af68b1c22ad0a022001c117caa4929c (diff)
parent180f7c764ae9dbe85bfd281f62f6086cf95e5b7a (diff)
downloadmeta-updater-438814dec075da891ed37a57c8b5138b43f56818.tar.gz
Merge pull request #513 from advancedtelematic/fix/thud/backport
Fix/thud/backport
-rw-r--r--README.adoc32
-rw-r--r--classes/image_types_ostree.bbclass7
-rw-r--r--classes/sota.bbclass2
-rw-r--r--classes/sota_am335x-evm-wifi.bbclass1
-rw-r--r--classes/sota_m3ulcb.bbclass3
-rw-r--r--classes/sota_minnowboard.bbclass4
-rw-r--r--classes/sota_porter.bbclass2
-rw-r--r--classes/sota_qemux86-64.bbclass2
-rw-r--r--classes/sota_raspberrypi.bbclass4
-rw-r--r--conf/distro/poky-sota-systemd.conf3
-rw-r--r--conf/distro/poky-sota.conf2
-rw-r--r--lib/oeqa/selftest/cases/testutils.py128
-rw-r--r--lib/oeqa/selftest/cases/updater_minnowboard.py60
-rw-r--r--lib/oeqa/selftest/cases/updater_native.py47
-rw-r--r--lib/oeqa/selftest/cases/updater_qemux86_64.py (renamed from lib/oeqa/selftest/cases/updater.py)396
-rw-r--r--lib/oeqa/selftest/cases/updater_qemux86_64_ptest.py52
-rw-r--r--lib/oeqa/selftest/cases/updater_raspberrypi.py86
-rw-r--r--recipes-connectivity/connman/connman_%.bbappend1
-rw-r--r--recipes-connectivity/networkd-dhcp-conf/files/20-wired-dhcp.network5
-rw-r--r--recipes-connectivity/networkd-dhcp-conf/networkd-dhcp-conf.bb28
-rw-r--r--recipes-devtools/valgrind/files/bug344802-unhandled-0xec510f1e.patch250
-rw-r--r--recipes-devtools/valgrind/valgrind_%.bbappend4
-rw-r--r--recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb2
-rw-r--r--recipes-sota/aktualizr/aktualizr-auto-prov.bb2
-rw-r--r--recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb6
-rw-r--r--recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb5
-rw-r--r--recipes-sota/aktualizr/aktualizr-hsm-prov.bb2
-rw-r--r--recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb4
-rwxr-xr-xrecipes-sota/aktualizr/aktualizr_git.bb80
-rw-r--r--recipes-sota/aktualizr/files/10-resource-control.conf6
-rwxr-xr-xrecipes-sota/aktualizr/files/run-ptest18
-rw-r--r--recipes-sota/aktualizr/garage-sign-version.inc36
-rw-r--r--recipes-sota/config/aktualizr-auto-reboot.bb2
-rw-r--r--recipes-sota/config/aktualizr-disable-send-ip.bb2
-rw-r--r--recipes-sota/config/aktualizr-log-debug.bb2
-rw-r--r--recipes-sota/fit-conf/fit-conf.bb2
-rw-r--r--recipes-test/images/secondary-image.bb3
-rw-r--r--scripts/lib/wic/plugins/source/otaimage.py24
-rw-r--r--scripts/qemucommand.py2
39 files changed, 907 insertions, 410 deletions
diff --git a/README.adoc b/README.adoc
index d603ade..cc01612 100644
--- a/README.adoc
+++ b/README.adoc
@@ -74,6 +74,8 @@ You may take a look into https://github.com/advancedtelematic/meta-updater-minno
74 74
75Although we have used U-Boot so far, other boot loaders can be configured work with OSTree as well. 75Although we have used U-Boot so far, other boot loaders can be configured work with OSTree as well.
76 76
77Your images will also need network connectivity to be able to reach an actual OTA backend. Our 'poky-sota' distribution does not mandate or install a default network manager but our supported platforms use the `virtual/network-configuration` recipe, which can be used as a starting example.
78
77== SOTA-related variables in local.conf 79== SOTA-related variables in local.conf
78 80
79* `OSTREE_REPO` - path to your OSTree repository. Defaults to `$\{DEPLOY_DIR_IMAGE}/ostree_repo` 81* `OSTREE_REPO` - path to your OSTree repository. Defaults to `$\{DEPLOY_DIR_IMAGE}/ostree_repo`
@@ -82,6 +84,7 @@ Although we have used U-Boot so far, other boot loaders can be configured work w
82* `OSTREE_COMMIT_SUBJECT` - Commit subject used by OSTree. Defaults to `Commit-id: ${IMAGE_NAME}` 84* `OSTREE_COMMIT_SUBJECT` - Commit subject used by OSTree. Defaults to `Commit-id: ${IMAGE_NAME}`
83* `OSTREE_UPDATE_SUMMARY` - Set this to '1' to update summary of OSTree repository on each commit. '0' by default. 85* `OSTREE_UPDATE_SUMMARY` - Set this to '1' to update summary of OSTree repository on each commit. '0' by default.
84* `OSTREE_DEPLOY_DEVICETREE` - Set this to '1' to include devicetree(s) to boot 86* `OSTREE_DEPLOY_DEVICETREE` - Set this to '1' to include devicetree(s) to boot
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.
85* `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. 88* `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.
86* `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_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].
87* `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_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.
@@ -92,6 +95,7 @@ Although we have used U-Boot so far, other boot loaders can be configured work w
92* `SOTA_MAIN_DTB` - base device tree to use with the kernel. Used together with FIT images. You can change it, and the device tree will also be changed after the update. 95* `SOTA_MAIN_DTB` - base device tree to use with the kernel. Used together with FIT images. You can change it, and the device tree will also be changed after the update.
93* `SOTA_DT_OVERLAYS` - whitespace-separated list of used device tree overlays for FIT image. This list is OSTree-updateable as well. 96* `SOTA_DT_OVERLAYS` - whitespace-separated list of used device tree overlays for FIT image. This list is OSTree-updateable as well.
94* `SOTA_EXTRA_CONF_FRAGS` - extra https://lxr.missinglinkelectronics.com/uboot/doc/uImage.FIT/overlay-fdt-boot.txt[configuration fragments] for FIT image. 97* `SOTA_EXTRA_CONF_FRAGS` - extra https://lxr.missinglinkelectronics.com/uboot/doc/uImage.FIT/overlay-fdt-boot.txt[configuration fragments] for FIT image.
98* `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 99
96== Usage 100== Usage
97 101
@@ -157,6 +161,19 @@ Second, you can write recipes to install additional config files with customized
157 161
158To use these recipes, you will need to add them to your image with a line such as `IMAGE_INSTALL_append = " aktualizr-log-debug "` in your `local.conf`. 162To use these recipes, you will need to add them to your image with a line such as `IMAGE_INSTALL_append = " aktualizr-log-debug "` in your `local.conf`.
159 163
164=== aktualizr service resource control
165
166With systemd based images, it is possible to set resource policies for the aktualizr service. The main use case is to provide a safeguard against resource exhaustion during an unforeseen failure scenario.
167
168To enable it, install `aktualizr-resource-control` on the target image and optionally override the default resource limits set in link:recipes-sota/aktualizr/aktualizr_git.bb[aktualizr_git.bb], from your `local.conf`.
169
170For example:
171
172....
173IMAGE_INSTALL_append += " aktualizr-resource-control "
174RESOURCE_CPU_WEIGHT_pn-aktualizr = "50"
175....
176
160== Development configuration 177== Development configuration
161 178
162There are a few settings that can be controlled in `local.conf` to simplify the development process: 179There are a few settings that can be controlled in `local.conf` to simplify the development process:
@@ -211,11 +228,24 @@ sudo apt install ovmf
2115. Run oe-selftest: 2285. Run oe-selftest:
212+ 229+
213``` 230```
214oe-selftest --run-tests updater 231oe-selftest -r updater_native updater_qemux86_64 updater_minnowboard updater_raspberrypi
215``` 232```
216 233
217For more information about oe-selftest, including details about how to run individual test modules or classes, please refer to the https://wiki.yoctoproject.org/wiki/Oe-selftest[Yocto Project wiki]. 234For more information about oe-selftest, including details about how to run individual test modules or classes, please refer to the https://wiki.yoctoproject.org/wiki/Oe-selftest[Yocto Project wiki].
218 235
236== Aktualizr test suite with ptest
237
238The meta-updater layer includes support for running parts of the aktualizr test suite on deployed devices through link:https://wiki.yoctoproject.org/wiki/Ptest[Yocto's ptest functionality]. Since it adds significant build time cost, it is currently disabled by default. To enable it, add the following to your `conf/local.conf`:
239
240```
241PTEST_ENABLED_pn-aktualizr = "1"
242IMAGE_INSTALL_append += " aktualizr-ptest ptest-runner "
243```
244
245Be aware that it will add several hundreds of MB to the generated file system.
246
247The aktualizr tests will now be part of the deployed ptest suite, which can be run by calling `ptest-runner`. Alternatively, the required files and run script can be found in `/usr/lib/aktualizr/ptest`.
248
219== Manual provisoning 249== Manual provisoning
220 250
221As 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. 251As 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.
diff --git a/classes/image_types_ostree.bbclass b/classes/image_types_ostree.bbclass
index 41327e1..56d4d76 100644
--- a/classes/image_types_ostree.bbclass
+++ b/classes/image_types_ostree.bbclass
@@ -212,6 +212,11 @@ IMAGE_CMD_garagesign () {
212 # Push may fail due to race condition when multiple build machines try to push simultaneously 212 # Push may fail due to race condition when multiple build machines try to push simultaneously
213 # in which case targets.json should be pulled again and the whole procedure repeated 213 # in which case targets.json should be pulled again and the whole procedure repeated
214 push_success=0 214 push_success=0
215 target_url=""
216 if [ -n "${GARAGE_TARGET_URL}" ]; then
217 target_url='--url ${GARAGE_TARGET_URL}'
218 fi
219
215 for push_retries in $( seq 3 ); do 220 for push_retries in $( seq 3 ); do
216 garage-sign targets pull --repo tufrepo \ 221 garage-sign targets pull --repo tufrepo \
217 --home-dir ${GARAGE_SIGN_REPO} 222 --home-dir ${GARAGE_SIGN_REPO}
@@ -221,7 +226,7 @@ IMAGE_CMD_garagesign () {
221 --format OSTREE \ 226 --format OSTREE \
222 --version ${target_version} \ 227 --version ${target_version} \
223 --length 0 \ 228 --length 0 \
224 --url "${GARAGE_TARGET_URL}" \ 229 ${target_url} \
225 --sha256 ${ostree_target_hash} \ 230 --sha256 ${ostree_target_hash} \
226 --hardwareids ${SOTA_HARDWARE_ID} 231 --hardwareids ${SOTA_HARDWARE_ID}
227 garage-sign targets sign --repo tufrepo \ 232 garage-sign targets sign --repo tufrepo \
diff --git a/classes/sota.bbclass b/classes/sota.bbclass
index 92b4c43..7ffcd23 100644
--- a/classes/sota.bbclass
+++ b/classes/sota.bbclass
@@ -36,7 +36,7 @@ GARAGE_SIGN_REPO ?= "${DEPLOY_DIR_IMAGE}/garage_sign_repo"
36GARAGE_SIGN_KEYNAME ?= "garage-key" 36GARAGE_SIGN_KEYNAME ?= "garage-key"
37GARAGE_TARGET_NAME ?= "${OSTREE_BRANCHNAME}" 37GARAGE_TARGET_NAME ?= "${OSTREE_BRANCHNAME}"
38GARAGE_TARGET_VERSION ?= "" 38GARAGE_TARGET_VERSION ?= ""
39GARAGE_TARGET_URL ?= "https://example.com/" 39GARAGE_TARGET_URL ?= ""
40 40
41SOTA_MACHINE ??="none" 41SOTA_MACHINE ??="none"
42SOTA_MACHINE_rpi ?= "raspberrypi" 42SOTA_MACHINE_rpi ?= "raspberrypi"
diff --git a/classes/sota_am335x-evm-wifi.bbclass b/classes/sota_am335x-evm-wifi.bbclass
index adefb47..1458d44 100644
--- a/classes/sota_am335x-evm-wifi.bbclass
+++ b/classes/sota_am335x-evm-wifi.bbclass
@@ -7,7 +7,6 @@ IMAGE_BOOT_FILES_sota = "bootfiles/*"
7OSTREE_KERNEL_ARGS ?= "ramdisk_size=16384 root=/dev/ram0 rw rootfstype=ext4 rootwait rootdelay=2 ostree_root=/dev/mmcblk0p2 console=ttyO0,115200n8l" 7OSTREE_KERNEL_ARGS ?= "ramdisk_size=16384 root=/dev/ram0 rw rootfstype=ext4 rootwait rootdelay=2 ostree_root=/dev/mmcblk0p2 console=ttyO0,115200n8l"
8 8
9IMAGE_INSTALL_append_sota = " uim iw wl18xx-calibrator wlconf wl18xx-fw hostapd wpa-supplicant" 9IMAGE_INSTALL_append_sota = " uim iw wl18xx-calibrator wlconf wl18xx-fw hostapd wpa-supplicant"
10IMAGE_INSTALL_remove_sota = " connman connman-client"
11 10
12PREFERRED_VERSION_linux-ti-staging_sota = "4.4.54+gitAUTOINC+ecd4eada6f" 11PREFERRED_VERSION_linux-ti-staging_sota = "4.4.54+gitAUTOINC+ecd4eada6f"
13 12
diff --git a/classes/sota_m3ulcb.bbclass b/classes/sota_m3ulcb.bbclass
index 6b63af4..b93cc40 100644
--- a/classes/sota_m3ulcb.bbclass
+++ b/classes/sota_m3ulcb.bbclass
@@ -6,3 +6,6 @@ IMAGE_BOOT_FILES_sota += "m3ulcb-ota-bootfiles/*"
6 6
7OSTREE_BOOTLOADER ?= "u-boot" 7OSTREE_BOOTLOADER ?= "u-boot"
8UBOOT_MACHINE_sota = "m3ulcb_defconfig" 8UBOOT_MACHINE_sota = "m3ulcb_defconfig"
9
10PREFERRED_RPROVIDER_virtual/network-configuration ?= "connman"
11IMAGE_INSTALL_append_sota = " virtual/network-configuration "
diff --git a/classes/sota_minnowboard.bbclass b/classes/sota_minnowboard.bbclass
index 63510e3..a907217 100644
--- a/classes/sota_minnowboard.bbclass
+++ b/classes/sota_minnowboard.bbclass
@@ -6,5 +6,7 @@ IMAGE_BOOT_FILES_sota = ""
6 6
7IMAGE_FSTYPES_remove_sota = "live hddimg" 7IMAGE_FSTYPES_remove_sota = "live hddimg"
8OSTREE_KERNEL_ARGS ?= "ramdisk_size=16384 rw rootfstype=ext4 rootwait rootdelay=2 console=ttyS0,115200 console=tty0" 8OSTREE_KERNEL_ARGS ?= "ramdisk_size=16384 rw rootfstype=ext4 rootwait rootdelay=2 console=ttyS0,115200 console=tty0"
9
10IMAGE_INSTALL_append = " minnowboard-efi-startup" 9IMAGE_INSTALL_append = " minnowboard-efi-startup"
10
11PREFERRED_RPROVIDER_virtual/network-configuration ?= "connman"
12IMAGE_INSTALL_append_sota = " virtual/network-configuration "
diff --git a/classes/sota_porter.bbclass b/classes/sota_porter.bbclass
index 75ae579..80062e1 100644
--- a/classes/sota_porter.bbclass
+++ b/classes/sota_porter.bbclass
@@ -7,3 +7,5 @@ IMAGE_BOOT_FILES_sota += "porter-bootfiles/*"
7OSTREE_BOOTLOADER ?= "u-boot" 7OSTREE_BOOTLOADER ?= "u-boot"
8UBOOT_MACHINE_sota = "porter_config" 8UBOOT_MACHINE_sota = "porter_config"
9 9
10PREFERRED_RPROVIDER_virtual/network-configuration ?= "connman"
11IMAGE_INSTALL_append_sota = " virtual/network-configuration "
diff --git a/classes/sota_qemux86-64.bbclass b/classes/sota_qemux86-64.bbclass
index 0850af6..fc4aa7c 100644
--- a/classes/sota_qemux86-64.bbclass
+++ b/classes/sota_qemux86-64.bbclass
@@ -12,3 +12,5 @@ IMAGE_ROOTFS_EXTRA_SPACE = "${@bb.utils.contains('DISTRO_FEATURES', 'sota', '655
12 12
13# fix for u-boot/swig build issue 13# fix for u-boot/swig build issue
14HOSTTOOLS_NONFATAL += "x86_64-linux-gnu-gcc" 14HOSTTOOLS_NONFATAL += "x86_64-linux-gnu-gcc"
15
16IMAGE_INSTALL_append_sota = " virtual/network-configuration "
diff --git a/classes/sota_raspberrypi.bbclass b/classes/sota_raspberrypi.bbclass
index e1c0054..3add247 100644
--- a/classes/sota_raspberrypi.bbclass
+++ b/classes/sota_raspberrypi.bbclass
@@ -12,6 +12,9 @@ UBOOT_DTBO_LOADADDRESS = "0x06000000"
12# Deploy config fragment list to OSTree root fs 12# Deploy config fragment list to OSTree root fs
13IMAGE_INSTALL_append = " fit-conf" 13IMAGE_INSTALL_append = " fit-conf"
14 14
15DEV_MATCH_DIRECTIVE_pn-networkd-dhcp-conf = "Driver=smsc95xx lan78xx"
16IMAGE_INSTALL_append_sota = " virtual/network-configuration "
17
15PREFERRED_PROVIDER_virtual/bootloader_sota ?= "u-boot" 18PREFERRED_PROVIDER_virtual/bootloader_sota ?= "u-boot"
16UBOOT_ENTRYPOINT_sota ?= "0x00008000" 19UBOOT_ENTRYPOINT_sota ?= "0x00008000"
17 20
@@ -34,4 +37,3 @@ SOTA_DT_OVERLAYS_raspberrypi3 ?= "vc4-kms-v3d.dtbo rpi-ft5406.dtbo"
34OSTREE_KERNEL_ARGS_sota ?= " 8250.nr_uarts=1 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=614 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 dwc_otg.lpm_enable=0 console=ttyS0,115200 usbhid.mousepoll=0 " 37OSTREE_KERNEL_ARGS_sota ?= " 8250.nr_uarts=1 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=614 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 dwc_otg.lpm_enable=0 console=ttyS0,115200 usbhid.mousepoll=0 "
35 38
36SOTA_CLIENT_FEATURES_append = " ubootenv" 39SOTA_CLIENT_FEATURES_append = " ubootenv"
37
diff --git a/conf/distro/poky-sota-systemd.conf b/conf/distro/poky-sota-systemd.conf
index 7d008a9..b30b322 100644
--- a/conf/distro/poky-sota-systemd.conf
+++ b/conf/distro/poky-sota-systemd.conf
@@ -9,5 +9,4 @@ DISTRO_CODENAME = "sota"
9 9
10DISTRO_FEATURES_append = " systemd" 10DISTRO_FEATURES_append = " systemd"
11VIRTUAL-RUNTIME_init_manager = "systemd" 11VIRTUAL-RUNTIME_init_manager = "systemd"
12 12PREFERRED_RPROVIDER_virtual/network-configuration ??= "networkd-dhcp-conf"
13IMAGE_INSTALL_append = " connman connman-client"
diff --git a/conf/distro/poky-sota.conf b/conf/distro/poky-sota.conf
index 2bbc62b..3fb1d20 100644
--- a/conf/distro/poky-sota.conf
+++ b/conf/distro/poky-sota.conf
@@ -5,5 +5,3 @@ DISTRO = "poky-sota"
5DISTRO_NAME = "OTA-enabled Linux" 5DISTRO_NAME = "OTA-enabled Linux"
6DISTRO_VERSION = "1.0" 6DISTRO_VERSION = "1.0"
7DISTRO_CODENAME = "sota" 7DISTRO_CODENAME = "sota"
8
9IMAGE_INSTALL_append = " connman connman-client"
diff --git a/lib/oeqa/selftest/cases/testutils.py b/lib/oeqa/selftest/cases/testutils.py
new file mode 100644
index 0000000..2ad99ad
--- /dev/null
+++ b/lib/oeqa/selftest/cases/testutils.py
@@ -0,0 +1,128 @@
1import os
2import logging
3import re
4import subprocess
5from time import sleep
6
7from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
8from qemucommand import QemuCommand
9
10
11def qemu_launch(efi=False, machine=None, imagename=None):
12 logger = logging.getLogger("selftest")
13 if imagename is None:
14 imagename = 'core-image-minimal'
15 logger.info('Running bitbake to build {}'.format(imagename))
16 bitbake(imagename)
17 # Create empty object.
18 args = type('', (), {})()
19 args.imagename = imagename
20 args.mac = None
21 # Could use DEPLOY_DIR_IMAGE here but it's already in the machine
22 # subdirectory.
23 args.dir = 'tmp/deploy/images'
24 args.efi = efi
25 args.machine = machine
26 qemu_use_kvm = get_bb_var("QEMU_USE_KVM")
27 if qemu_use_kvm and \
28 (qemu_use_kvm == 'True' and 'x86' in machine or
29 get_bb_var('MACHINE') in qemu_use_kvm.split()):
30 args.kvm = True
31 else:
32 args.kvm = None # Autodetect
33 args.no_gui = True
34 args.gdb = False
35 args.pcap = None
36 args.overlay = None
37 args.dry_run = False
38 args.secondary_network = False
39
40 qemu = QemuCommand(args)
41 cmdline = qemu.command_line()
42 print('Booting image with run-qemu-ota...')
43 s = subprocess.Popen(cmdline)
44 sleep(10)
45 return qemu, s
46
47
48def qemu_terminate(s):
49 try:
50 s.terminate()
51 except KeyboardInterrupt:
52 pass
53
54
55def qemu_send_command(port, command, timeout=60):
56 command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' +
57 str(port) + ' "' + command + '"']
58 s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
59 stdout, stderr = s2.communicate(timeout=timeout)
60 return stdout, stderr, s2.returncode
61
62
63def akt_native_run(testInst, cmd, **kwargs):
64 # run a command supplied by aktualizr-native and checks that:
65 # - the executable exists
66 # - the command runs without error
67 # NOTE: the base test class must have built aktualizr-native (in
68 # setUpClass, for example)
69 bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'],
70 'aktualizr-native')
71 sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix']
72 sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir']
73 libdir = bb_vars['libdir']
74
75 program, *_ = cmd.split(' ')
76 p = '{}/{}'.format(sysrootbin, program)
77 testInst.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p))
78 env = dict(os.environ)
79 env['LD_LIBRARY_PATH'] = libdir
80 result = runCmd(cmd, env=env, native_sysroot=sysroot, ignore_status=True, **kwargs)
81 testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
82
83
84def verifyNotProvisioned(testInst, machine):
85 print('Checking output of aktualizr-info:')
86 ran_ok = False
87 for delay in [5, 5, 5, 5, 10, 10, 10, 10]:
88 stdout, stderr, retcode = testInst.qemu_command('aktualizr-info')
89 if retcode == 0 and stderr == b'':
90 ran_ok = True
91 break
92 sleep(delay)
93 testInst.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
94
95 # Verify that device has NOT yet provisioned.
96 testInst.assertIn(b'Couldn\'t load device ID', stdout,
97 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
98 testInst.assertIn(b'Couldn\'t load ECU serials', stdout,
99 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
100 testInst.assertIn(b'Provisioned on server: no', stdout,
101 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
102 testInst.assertIn(b'Fetched metadata: no', stdout,
103 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
104
105
106def verifyProvisioned(testInst, machine):
107 # Verify that device HAS provisioned.
108 ran_ok = False
109 for delay in [5, 5, 5, 5, 10, 10, 10, 10]:
110 stdout, stderr, retcode = testInst.qemu_command('aktualizr-info')
111 if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0:
112 ran_ok = True
113 break
114 sleep(delay)
115 testInst.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
116
117 testInst.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
118 testInst.assertIn(b'Primary ecu hardware ID: ' + machine.encode(), stdout,
119 'Provisioning failed: ' + stderr.decode() + stdout.decode())
120 testInst.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
121 p = re.compile(r'Device ID: ([a-z0-9-]*)\n')
122 m = p.search(stdout.decode())
123 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())
125 logger = logging.getLogger("selftest")
126 logger.info('Device successfully provisioned with ID: ' + m.group(1))
127
128# 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
new file mode 100644
index 0000000..f5df584
--- /dev/null
+++ b/lib/oeqa/selftest/cases/updater_minnowboard.py
@@ -0,0 +1,60 @@
1import os
2import re
3
4from oeqa.selftest.case import OESelftestTestCase
5from oeqa.utils.commands import runCmd, get_bb_var
6from testutils import qemu_launch, qemu_send_command, qemu_terminate, verifyProvisioned
7
8
9class MinnowTests(OESelftestTestCase):
10
11 def setUpLocal(self):
12 layer_intel = "meta-intel"
13 layer_minnow = "meta-updater-minnowboard"
14 result = runCmd('bitbake-layers show-layers')
15 # Assume the directory layout for finding other layers. We could also
16 # make assumptions by using 'show-layers', but either way, if the
17 # layers we need aren't where we expect them, we are out of luck.
18 path = os.path.abspath(os.path.dirname(__file__))
19 metadir = path + "/../../../../../"
20 if re.search(layer_intel, result.output) is None:
21 self.meta_intel = metadir + layer_intel
22 runCmd('bitbake-layers add-layer "%s"' % self.meta_intel)
23 else:
24 self.meta_intel = None
25 if re.search(layer_minnow, result.output) is None:
26 self.meta_minnow = metadir + layer_minnow
27 runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow)
28 else:
29 self.meta_minnow = None
30 self.append_config('MACHINE = "intel-corei7-64"')
31 self.append_config('OSTREE_BOOTLOADER = "grub"')
32 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
33 self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64')
34
35 def tearDownLocal(self):
36 qemu_terminate(self.s)
37 if self.meta_intel:
38 runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True)
39 if self.meta_minnow:
40 runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True)
41
42 def qemu_command(self, command):
43 return qemu_send_command(self.qemu.ssh_port, command)
44
45 def test_provisioning(self):
46 print('Checking machine name (hostname) of device:')
47 stdout, stderr, retcode = self.qemu_command('hostname')
48 self.assertEqual(retcode, 0, "Unable to check hostname. " +
49 "Is an ssh daemon (such as dropbear or openssh) installed on the device?")
50 machine = get_bb_var('MACHINE', 'core-image-minimal')
51 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
52 # Strip off line ending.
53 value = stdout.decode()[:-1]
54 self.assertEqual(value, machine,
55 'MACHINE does not match hostname: ' + machine + ', ' + value +
56 '\nIs TianoCore ovmf installed on your host machine?')
57
58 verifyProvisioned(self, machine)
59
60# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/oeqa/selftest/cases/updater_native.py b/lib/oeqa/selftest/cases/updater_native.py
new file mode 100644
index 0000000..1fc9cb8
--- /dev/null
+++ b/lib/oeqa/selftest/cases/updater_native.py
@@ -0,0 +1,47 @@
1# pylint: disable=C0111,C0325
2import logging
3
4from oeqa.selftest.case import OESelftestTestCase
5from oeqa.utils.commands import runCmd, bitbake, get_bb_var
6from testutils import akt_native_run
7
8
9class SotaToolsTests(OESelftestTestCase):
10
11 @classmethod
12 def setUpClass(cls):
13 super(SotaToolsTests, cls).setUpClass()
14 logger = logging.getLogger("selftest")
15 logger.info('Running bitbake to build aktualizr-native tools')
16 bitbake('aktualizr-native')
17
18 def test_push_help(self):
19 akt_native_run(self, 'garage-push --help')
20
21 def test_deploy_help(self):
22 akt_native_run(self, 'garage-deploy --help')
23
24 def test_garagesign_help(self):
25 akt_native_run(self, 'garage-sign --help')
26
27
28class GeneralTests(OESelftestTestCase):
29
30 def test_feature_sota(self):
31 result = get_bb_var('DISTRO_FEATURES').find('sota')
32 self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES')
33
34 def test_feature_usrmerge(self):
35 result = get_bb_var('DISTRO_FEATURES').find('usrmerge')
36 self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES')
37
38 def test_feature_systemd(self):
39 result = get_bb_var('DISTRO_FEATURES').find('systemd')
40 self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES')
41
42 def test_java(self):
43 result = runCmd('which java', ignore_status=True)
44 self.assertEqual(result.status, 0,
45 "Java not found. Do you have a JDK installed on your host machine?")
46
47# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/oeqa/selftest/cases/updater.py b/lib/oeqa/selftest/cases/updater_qemux86_64.py
index 550d9de..9f32bcf 100644
--- a/lib/oeqa/selftest/cases/updater.py
+++ b/lib/oeqa/selftest/cases/updater_qemux86_64.py
@@ -2,48 +2,16 @@
2import os 2import os
3import logging 3import logging
4import re 4import re
5import subprocess
6import unittest 5import unittest
7from time import sleep 6from time import sleep
8 7
9from oeqa.selftest.case import OESelftestTestCase 8from oeqa.selftest.case import OESelftestTestCase
10from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars 9from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
11from qemucommand import QemuCommand 10from testutils import qemu_launch, qemu_send_command, qemu_terminate, \
12 11 akt_native_run, verifyNotProvisioned, verifyProvisioned
13
14class SotaToolsTests(OESelftestTestCase):
15
16 @classmethod
17 def setUpClass(cls):
18 super(SotaToolsTests, cls).setUpClass()
19 logger = logging.getLogger("selftest")
20 logger.info('Running bitbake to build aktualizr-native tools')
21 bitbake('aktualizr-native')
22
23 def test_push_help(self):
24 akt_native_run(self, 'garage-push --help')
25
26 def test_deploy_help(self):
27 akt_native_run(self, 'garage-deploy --help')
28
29 def test_garagesign_help(self):
30 akt_native_run(self, 'garage-sign --help')
31 12
32 13
33class GeneralTests(OESelftestTestCase): 14class GeneralTests(OESelftestTestCase):
34
35 def test_feature_sota(self):
36 result = get_bb_var('DISTRO_FEATURES').find('sota')
37 self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES')
38
39 def test_feature_usrmerge(self):
40 result = get_bb_var('DISTRO_FEATURES').find('usrmerge')
41 self.assertNotEqual(result, -1, 'Feature "sota" not set at DISTRO_FEATURES')
42
43 def test_feature_systemd(self):
44 result = get_bb_var('DISTRO_FEATURES').find('systemd')
45 self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES')
46
47 def test_credentials(self): 15 def test_credentials(self):
48 logger = logging.getLogger("selftest") 16 logger = logging.getLogger("selftest")
49 logger.info('Running bitbake to build core-image-minimal') 17 logger.info('Running bitbake to build core-image-minimal')
@@ -62,11 +30,6 @@ class GeneralTests(OESelftestTestCase):
62 (deploydir, imagename), ignore_status=True) 30 (deploydir, imagename), ignore_status=True)
63 self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) 31 self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
64 32
65 def test_java(self):
66 result = runCmd('which java', ignore_status=True)
67 self.assertEqual(result.status, 0,
68 "Java not found. Do you have a JDK installed on your host machine?")
69
70 33
71class AktualizrToolsTests(OESelftestTestCase): 34class AktualizrToolsTests(OESelftestTestCase):
72 35
@@ -143,16 +106,6 @@ class AutoProvTests(OESelftestTestCase):
143 value = stdout.decode()[:-1] 106 value = stdout.decode()[:-1]
144 self.assertEqual(value, machine, 107 self.assertEqual(value, machine,
145 'MACHINE does not match hostname: ' + machine + ', ' + value) 108 'MACHINE does not match hostname: ' + machine + ', ' + value)
146 print(value)
147 print('Checking output of aktualizr-info:')
148 ran_ok = False
149 for delay in [1, 2, 5, 10, 15]:
150 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
151 if retcode == 0 and stderr == b'':
152 ran_ok = True
153 break
154 sleep(delay)
155 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
156 109
157 verifyProvisioned(self, machine) 110 verifyProvisioned(self, machine)
158 111
@@ -191,7 +144,7 @@ class ManualControlTests(OESelftestTestCase):
191 """ 144 """
192 sleep(20) 145 sleep(20)
193 stdout, stderr, retcode = self.qemu_command('aktualizr-info') 146 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
194 self.assertIn(b'Can\'t open database', stdout, 147 self.assertIn(b'Can\'t open database', stderr,
195 'Aktualizr should not have run yet' + stderr.decode() + stdout.decode()) 148 'Aktualizr should not have run yet' + stderr.decode() + stdout.decode())
196 149
197 stdout, stderr, retcode = self.qemu_command('aktualizr once') 150 stdout, stderr, retcode = self.qemu_command('aktualizr once')
@@ -201,144 +154,6 @@ class ManualControlTests(OESelftestTestCase):
201 'Aktualizr should have run' + stderr.decode() + stdout.decode()) 154 'Aktualizr should have run' + stderr.decode() + stdout.decode())
202 155
203 156
204class RpiTests(OESelftestTestCase):
205
206 def setUpLocal(self):
207 # Add layers before changing the machine type, otherwise the sanity
208 # checker complains loudly.
209 layer_python = "meta-openembedded/meta-python"
210 layer_rpi = "meta-raspberrypi"
211 layer_upd_rpi = "meta-updater-raspberrypi"
212 result = runCmd('bitbake-layers show-layers')
213 # Assume the directory layout for finding other layers. We could also
214 # make assumptions by using 'show-layers', but either way, if the
215 # layers we need aren't where we expect them, we are out of luck.
216 path = os.path.abspath(os.path.dirname(__file__))
217 metadir = path + "/../../../../../"
218 if re.search(layer_python, result.output) is None:
219 self.meta_python = metadir + layer_python
220 runCmd('bitbake-layers add-layer "%s"' % self.meta_python)
221 else:
222 self.meta_python = None
223 if re.search(layer_rpi, result.output) is None:
224 self.meta_rpi = metadir + layer_rpi
225 runCmd('bitbake-layers add-layer "%s"' % self.meta_rpi)
226 else:
227 self.meta_rpi = None
228 if re.search(layer_upd_rpi, result.output) is None:
229 self.meta_upd_rpi = metadir + layer_upd_rpi
230 runCmd('bitbake-layers add-layer "%s"' % self.meta_upd_rpi)
231 else:
232 self.meta_upd_rpi = None
233
234 # This is trickier that I would've thought. The fundamental problem is
235 # that the qemu layer changes the u-boot file extension to .rom, but
236 # raspberrypi still expects .bin. To prevent this, the qemu layer must
237 # be temporarily removed if it is present. It has to be removed by name
238 # without the complete path, but to add it back when we are done, we
239 # need the full path.
240 p = re.compile(r'meta-updater-qemux86-64\s*(\S*meta-updater-qemux86-64)\s')
241 m = p.search(result.output)
242 if m and m.lastindex > 0:
243 self.meta_qemu = m.group(1)
244 runCmd('bitbake-layers remove-layer meta-updater-qemux86-64')
245 else:
246 self.meta_qemu = None
247
248 self.append_config('MACHINE = "raspberrypi3"')
249 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
250
251 def tearDownLocal(self):
252 if self.meta_qemu:
253 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu, ignore_status=True)
254 if self.meta_upd_rpi:
255 runCmd('bitbake-layers remove-layer "%s"' % self.meta_upd_rpi, ignore_status=True)
256 if self.meta_rpi:
257 runCmd('bitbake-layers remove-layer "%s"' % self.meta_rpi, ignore_status=True)
258 if self.meta_python:
259 runCmd('bitbake-layers remove-layer "%s"' % self.meta_python, ignore_status=True)
260
261 def test_rpi(self):
262 logger = logging.getLogger("selftest")
263 logger.info('Running bitbake to build core-image-minimal')
264 self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"')
265 bitbake('core-image-minimal')
266 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS')
267 # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set.
268 if credentials is None:
269 raise unittest.SkipTest("Variable 'SOTA_PACKED_CREDENTIALS' not set.")
270 # Check if the file exists.
271 self.assertTrue(os.path.isfile(credentials), "File %s does not exist" % credentials)
272 deploydir = get_bb_var('DEPLOY_DIR_IMAGE')
273 imagename = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal')
274 # Check if the credentials are included in the output image.
275 result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' %
276 (deploydir, imagename), ignore_status=True)
277 self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
278
279
280class GrubTests(OESelftestTestCase):
281
282 def setUpLocal(self):
283 layer_intel = "meta-intel"
284 layer_minnow = "meta-updater-minnowboard"
285 result = runCmd('bitbake-layers show-layers')
286 # Assume the directory layout for finding other layers. We could also
287 # make assumptions by using 'show-layers', but either way, if the
288 # layers we need aren't where we expect them, we are out of luck.
289 path = os.path.abspath(os.path.dirname(__file__))
290 metadir = path + "/../../../../../"
291 if re.search(layer_intel, result.output) is None:
292 self.meta_intel = metadir + layer_intel
293 runCmd('bitbake-layers add-layer "%s"' % self.meta_intel)
294 else:
295 self.meta_intel = None
296 if re.search(layer_minnow, result.output) is None:
297 self.meta_minnow = metadir + layer_minnow
298 runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow)
299 else:
300 self.meta_minnow = None
301 self.append_config('MACHINE = "intel-corei7-64"')
302 self.append_config('OSTREE_BOOTLOADER = "grub"')
303 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
304 self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64')
305
306 def tearDownLocal(self):
307 qemu_terminate(self.s)
308 if self.meta_intel:
309 runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True)
310 if self.meta_minnow:
311 runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True)
312
313 def qemu_command(self, command):
314 return qemu_send_command(self.qemu.ssh_port, command)
315
316 def test_grub(self):
317 print('Checking machine name (hostname) of device:')
318 stdout, stderr, retcode = self.qemu_command('hostname')
319 self.assertEqual(retcode, 0, "Unable to check hostname. " +
320 "Is an ssh daemon (such as dropbear or openssh) installed on the device?")
321 machine = get_bb_var('MACHINE', 'core-image-minimal')
322 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
323 # Strip off line ending.
324 value = stdout.decode()[:-1]
325 self.assertEqual(value, machine,
326 'MACHINE does not match hostname: ' + machine + ', ' + value +
327 '\nIs TianoCore ovmf installed on your host machine?')
328 print(value)
329 print('Checking output of aktualizr-info:')
330 ran_ok = False
331 for delay in [1, 2, 5, 10, 15]:
332 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
333 if retcode == 0 and stderr == b'':
334 ran_ok = True
335 break
336 sleep(delay)
337 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
338
339 verifyProvisioned(self, machine)
340
341
342class ImplProvTests(OESelftestTestCase): 157class ImplProvTests(OESelftestTestCase):
343 158
344 def setUpLocal(self): 159 def setUpLocal(self):
@@ -379,25 +194,8 @@ class ImplProvTests(OESelftestTestCase):
379 value = stdout.decode()[:-1] 194 value = stdout.decode()[:-1]
380 self.assertEqual(value, machine, 195 self.assertEqual(value, machine,
381 'MACHINE does not match hostname: ' + machine + ', ' + value) 196 'MACHINE does not match hostname: ' + machine + ', ' + value)
382 print(value) 197
383 print('Checking output of aktualizr-info:') 198 verifyNotProvisioned(self, machine)
384 ran_ok = False
385 for delay in [1, 2, 5, 10, 15]:
386 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
387 if retcode == 0 and stderr == b'':
388 ran_ok = True
389 break
390 sleep(delay)
391 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
392 # Verify that device has NOT yet provisioned.
393 self.assertIn(b'Couldn\'t load device ID', stdout,
394 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
395 self.assertIn(b'Couldn\'t load ECU serials', stdout,
396 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
397 self.assertIn(b'Provisioned on server: no', stdout,
398 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
399 self.assertIn(b'Fetched metadata: no', stdout,
400 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
401 199
402 # Run aktualizr-cert-provider. 200 # Run aktualizr-cert-provider.
403 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') 201 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
@@ -454,25 +252,8 @@ class HsmTests(OESelftestTestCase):
454 value = stdout.decode()[:-1] 252 value = stdout.decode()[:-1]
455 self.assertEqual(value, machine, 253 self.assertEqual(value, machine,
456 'MACHINE does not match hostname: ' + machine + ', ' + value) 254 'MACHINE does not match hostname: ' + machine + ', ' + value)
457 print(value) 255
458 print('Checking output of aktualizr-info:') 256 verifyNotProvisioned(self, machine)
459 ran_ok = False
460 for delay in [1, 2, 5, 10, 15]:
461 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
462 if retcode == 0 and stderr == b'':
463 ran_ok = True
464 break
465 sleep(delay)
466 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
467 # Verify that device has NOT yet provisioned.
468 self.assertIn(b'Couldn\'t load device ID', stdout,
469 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
470 self.assertIn(b'Couldn\'t load ECU serials', stdout,
471 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
472 self.assertIn(b'Provisioned on server: no', stdout,
473 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
474 self.assertIn(b'Fetched metadata: no', stdout,
475 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
476 257
477 # Verify that HSM is not yet initialized. 258 # Verify that HSM is not yet initialized.
478 pkcs11_command = 'pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O' 259 pkcs11_command = 'pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O'
@@ -482,7 +263,7 @@ class HsmTests(OESelftestTestCase):
482 softhsm2_command = 'softhsm2-util --show-slots' 263 softhsm2_command = 'softhsm2-util --show-slots'
483 stdout, stderr, retcode = self.qemu_command(softhsm2_command) 264 stdout, stderr, retcode = self.qemu_command(softhsm2_command)
484 self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' + 265 self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' +
485 stdout.decode() + stderr.decode()) 266 stdout.decode() + stderr.decode())
486 267
487 # Run aktualizr-cert-provider. 268 # Run aktualizr-cert-provider.
488 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') 269 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
@@ -529,13 +310,6 @@ class HsmTests(OESelftestTestCase):
529 310
530 311
531class SecondaryTests(OESelftestTestCase): 312class SecondaryTests(OESelftestTestCase):
532 @classmethod
533 def setUpClass(cls):
534 super(SecondaryTests, cls).setUpClass()
535 logger = logging.getLogger("selftest")
536 logger.info('Running bitbake to build secondary-image')
537 bitbake('secondary-image')
538
539 def setUpLocal(self): 313 def setUpLocal(self):
540 layer = "meta-updater-qemux86-64" 314 layer = "meta-updater-qemux86-64"
541 result = runCmd('bitbake-layers show-layers') 315 result = runCmd('bitbake-layers show-layers')
@@ -567,20 +341,8 @@ class SecondaryTests(OESelftestTestCase):
567 self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help") 341 self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help")
568 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) 342 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
569 343
570 def test_secondary_listening(self):
571 print('Checking aktualizr-secondary service is listening')
572 stdout, stderr, retcode = self.qemu_command('aktualizr-check-discovery')
573 self.assertEqual(retcode, 0, "Unable to connect to secondary")
574
575 344
576class PrimaryTests(OESelftestTestCase): 345class PrimaryTests(OESelftestTestCase):
577 @classmethod
578 def setUpClass(cls):
579 super(PrimaryTests, cls).setUpClass()
580 logger = logging.getLogger("selftest")
581 logger.info('Running bitbake to build primary-image')
582 bitbake('primary-image')
583
584 def setUpLocal(self): 346 def setUpLocal(self):
585 layer = "meta-updater-qemux86-64" 347 layer = "meta-updater-qemux86-64"
586 result = runCmd('bitbake-layers show-layers') 348 result = runCmd('bitbake-layers show-layers')
@@ -614,99 +376,55 @@ class PrimaryTests(OESelftestTestCase):
614 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) 376 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
615 377
616 378
617def qemu_launch(efi=False, machine=None, imagename=None): 379class ResourceControlTests(OESelftestTestCase):
618 logger = logging.getLogger("selftest") 380 def setUpLocal(self):
619 logger.info('Running bitbake to build core-image-minimal') 381 layer = "meta-updater-qemux86-64"
620 bitbake('core-image-minimal') 382 result = runCmd('bitbake-layers show-layers')
621 # Create empty object. 383 if re.search(layer, result.output) is None:
622 args = type('', (), {})() 384 # Assume the directory layout for finding other layers. We could also
623 if imagename: 385 # make assumptions by using 'show-layers', but either way, if the
624 args.imagename = imagename 386 # layers we need aren't where we expect them, we are out of luck.
625 else: 387 path = os.path.abspath(os.path.dirname(__file__))
626 args.imagename = 'core-image-minimal' 388 metadir = path + "/../../../../../"
627 args.mac = None 389 self.meta_qemu = metadir + layer
628 # Could use DEPLOY_DIR_IMAGE here but it's already in the machine 390 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu)
629 # subdirectory. 391 else:
630 args.dir = 'tmp/deploy/images' 392 self.meta_qemu = None
631 args.efi = efi 393 self.append_config('MACHINE = "qemux86-64"')
632 args.machine = machine 394 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
633 qemu_use_kvm = get_bb_var("QEMU_USE_KVM") 395 self.append_config('IMAGE_INSTALL_append += " aktualizr-resource-control "')
634 if qemu_use_kvm and \ 396 self.append_config('RESOURCE_CPU_WEIGHT_pn-aktualizr = "1000"')
635 (qemu_use_kvm == 'True' and 'x86' in machine or \ 397 self.append_config('RESOURCE_MEMORY_HIGH_pn-aktualizr = "50M"')
636 get_bb_var('MACHINE') in qemu_use_kvm.split()): 398 self.append_config('RESOURCE_MEMORY_MAX_pn-aktualizr = "1M"')
637 args.kvm = True 399 self.qemu, self.s = qemu_launch(machine='qemux86-64')
638 else: 400
639 args.kvm = None # Autodetect 401 def tearDownLocal(self):
640 args.no_gui = True 402 qemu_terminate(self.s)
641 args.gdb = False 403 if self.meta_qemu:
642 args.pcap = None 404 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True)
643 args.overlay = None 405
644 args.dry_run = False 406 def qemu_command(self, command):
645 args.secondary_network = False 407 return qemu_send_command(self.qemu.ssh_port, command)
646 408
647 qemu = QemuCommand(args) 409 def test_aktualizr_resource_control(self):
648 cmdline = qemu.command_line() 410 print('Checking aktualizr was killed')
649 print('Booting image with run-qemu-ota...') 411 ran_ok = False
650 s = subprocess.Popen(cmdline) 412 for delay in [5, 5, 5, 5]:
651 sleep(10) 413 sleep(delay)
652 return qemu, s 414 stdout, stderr, retcode = self.qemu_command('systemctl --no-pager show aktualizr')
653 415 if retcode == 0 and b'ExecMainStatus=9' in stdout:
654 416 ran_ok = True
655def qemu_terminate(s): 417 break
656 try: 418 self.assertTrue(ran_ok, 'Aktualizr was not killed')
657 s.terminate() 419
658 except KeyboardInterrupt: 420 self.assertIn(b'CPUWeight=1000', stdout, 'CPUWeight was not set correctly')
659 pass 421 self.assertIn(b'MemoryHigh=52428800', stdout, 'MemoryHigh was not set correctly')
660 422 self.assertIn(b'MemoryMax=1048576', stdout, 'MemoryMax was not set correctly')
661 423
662def qemu_send_command(port, command): 424 self.qemu_command('systemctl --runtime set-property aktualizr MemoryMax=')
663 command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' + 425 self.qemu_command('systemctl restart aktualizr')
664 str(port) + ' "' + command + '"']
665 s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
666 stdout, stderr = s2.communicate(timeout=60)
667 return stdout, stderr, s2.returncode
668
669
670def akt_native_run(testInst, cmd, **kwargs):
671 # run a command supplied by aktualizr-native and checks that:
672 # - the executable exists
673 # - the command runs without error
674 # NOTE: the base test class must have built aktualizr-native (in
675 # setUpClass, for example)
676 bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'],
677 'aktualizr-native')
678 sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix']
679 sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir']
680 libdir = bb_vars['libdir']
681
682 program, *_ = cmd.split(' ')
683 p = '{}/{}'.format(sysrootbin, program)
684 testInst.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p))
685 env = dict(os.environ)
686 env['LD_LIBRARY_PATH'] = libdir
687 result = runCmd(cmd, env=env, native_sysroot=sysroot, ignore_status=True, **kwargs)
688 testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
689
690
691def verifyProvisioned(testInst, machine):
692 # Verify that device HAS provisioned.
693 ran_ok = False
694 for delay in [5, 5, 5, 5, 10, 10, 10, 10]:
695 stdout, stderr, retcode = testInst.qemu_command('aktualizr-info')
696 if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0:
697 ran_ok = True
698 break
699 sleep(delay)
700 testInst.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
701 testInst.assertIn(b'Primary ecu hardware ID: ' + machine.encode(), stdout,
702 'Provisioning failed: ' + stderr.decode() + stdout.decode())
703 testInst.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
704 p = re.compile(r'Device ID: ([a-z0-9-]*)\n')
705 m = p.search(stdout.decode())
706 testInst.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
707 testInst.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
708 logger = logging.getLogger("selftest")
709 logger.info('Device successfully provisioned with ID: ' + m.group(1))
710 426
427 stdout, stderr, retcode = self.qemu_command('systemctl --no-pager show --property=ExecMainStatus aktualizr')
428 self.assertIn(b'ExecMainStatus=0', stdout, 'Aktualizr did not restart')
711 429
712# vim:set ts=4 sw=4 sts=4 expandtab: 430# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/oeqa/selftest/cases/updater_qemux86_64_ptest.py b/lib/oeqa/selftest/cases/updater_qemux86_64_ptest.py
new file mode 100644
index 0000000..a04032c
--- /dev/null
+++ b/lib/oeqa/selftest/cases/updater_qemux86_64_ptest.py
@@ -0,0 +1,52 @@
1# pylint: disable=C0111,C0325
2import os
3import re
4
5from oeqa.selftest.case import OESelftestTestCase
6from oeqa.utils.commands import runCmd
7from testutils import qemu_launch, qemu_send_command, qemu_terminate
8
9
10class PtestTests(OESelftestTestCase):
11
12 def setUpLocal(self):
13 layer = "meta-updater-qemux86-64"
14 result = runCmd('bitbake-layers show-layers')
15 if re.search(layer, result.output) is None:
16 # Assume the directory layout for finding other layers. We could also
17 # make assumptions by using 'show-layers', but either way, if the
18 # layers we need aren't where we expect them, we are out of like.
19 path = os.path.abspath(os.path.dirname(__file__))
20 metadir = path + "/../../../../../"
21 self.meta_qemu = metadir + layer
22 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu)
23 else:
24 self.meta_qemu = None
25 self.append_config('MACHINE = "qemux86-64"')
26 self.append_config('SYSTEMD_AUTO_ENABLE_aktualizr = "disable"')
27 self.append_config('PTEST_ENABLED_pn-aktualizr = "1"')
28 self.append_config('IMAGE_INSTALL_append += "aktualizr-ptest ptest-runner "')
29 self.qemu, self.s = qemu_launch(machine='qemux86-64')
30
31 def tearDownLocal(self):
32 qemu_terminate(self.s)
33 if self.meta_qemu:
34 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True)
35
36 def qemu_command(self, command, timeout=60):
37 return qemu_send_command(self.qemu.ssh_port, command, timeout=timeout)
38
39 def test_run_ptests(self):
40 # simulate a login shell, so that /usr/sbin is in $PATH (from /etc/profile)
41 stdout, stderr, retcode = self.qemu_command('sh -l -c ptest-runner', timeout=None)
42 output = stdout.decode()
43 print(output)
44 self.assertEqual(retcode, 0)
45
46 has_failure = re.search('^FAIL', output, flags=re.MULTILINE) is not None
47 if has_failure:
48 print("Full test suite log:")
49 stdout, stderr, retcode = self.qemu_command('cat /tmp/aktualizr-ptest.log', timeout=None)
50 print(stdout.decode())
51
52 self.assertFalse(has_failure)
diff --git a/lib/oeqa/selftest/cases/updater_raspberrypi.py b/lib/oeqa/selftest/cases/updater_raspberrypi.py
new file mode 100644
index 0000000..785d703
--- /dev/null
+++ b/lib/oeqa/selftest/cases/updater_raspberrypi.py
@@ -0,0 +1,86 @@
1# pylint: disable=C0111,C0325
2import os
3import logging
4import re
5import unittest
6
7from oeqa.selftest.case import OESelftestTestCase
8from oeqa.utils.commands import runCmd, bitbake, get_bb_var
9
10
11class RpiTests(OESelftestTestCase):
12
13 def setUpLocal(self):
14 # Add layers before changing the machine type, otherwise the sanity
15 # checker complains loudly.
16 layer_python = "meta-openembedded/meta-python"
17 layer_rpi = "meta-raspberrypi"
18 layer_upd_rpi = "meta-updater-raspberrypi"
19 result = runCmd('bitbake-layers show-layers')
20 # Assume the directory layout for finding other layers. We could also
21 # make assumptions by using 'show-layers', but either way, if the
22 # layers we need aren't where we expect them, we are out of luck.
23 path = os.path.abspath(os.path.dirname(__file__))
24 metadir = path + "/../../../../../"
25 if re.search(layer_python, result.output) is None:
26 self.meta_python = metadir + layer_python
27 runCmd('bitbake-layers add-layer "%s"' % self.meta_python)
28 else:
29 self.meta_python = None
30 if re.search(layer_rpi, result.output) is None:
31 self.meta_rpi = metadir + layer_rpi
32 runCmd('bitbake-layers add-layer "%s"' % self.meta_rpi)
33 else:
34 self.meta_rpi = None
35 if re.search(layer_upd_rpi, result.output) is None:
36 self.meta_upd_rpi = metadir + layer_upd_rpi
37 runCmd('bitbake-layers add-layer "%s"' % self.meta_upd_rpi)
38 else:
39 self.meta_upd_rpi = None
40
41 # This is trickier that I would've thought. The fundamental problem is
42 # that the qemu layer changes the u-boot file extension to .rom, but
43 # raspberrypi still expects .bin. To prevent this, the qemu layer must
44 # be temporarily removed if it is present. It has to be removed by name
45 # without the complete path, but to add it back when we are done, we
46 # need the full path.
47 p = re.compile(r'meta-updater-qemux86-64\s*(\S*meta-updater-qemux86-64)\s')
48 m = p.search(result.output)
49 if m and m.lastindex > 0:
50 self.meta_qemu = m.group(1)
51 runCmd('bitbake-layers remove-layer meta-updater-qemux86-64')
52 else:
53 self.meta_qemu = None
54
55 self.append_config('MACHINE = "raspberrypi3"')
56 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
57
58 def tearDownLocal(self):
59 if self.meta_qemu:
60 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu, ignore_status=True)
61 if self.meta_upd_rpi:
62 runCmd('bitbake-layers remove-layer "%s"' % self.meta_upd_rpi, ignore_status=True)
63 if self.meta_rpi:
64 runCmd('bitbake-layers remove-layer "%s"' % self.meta_rpi, ignore_status=True)
65 if self.meta_python:
66 runCmd('bitbake-layers remove-layer "%s"' % self.meta_python, ignore_status=True)
67
68 def test_build(self):
69 logger = logging.getLogger("selftest")
70 logger.info('Running bitbake to build core-image-minimal')
71 self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"')
72 bitbake('core-image-minimal')
73 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS')
74 # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set.
75 if credentials is None:
76 raise unittest.SkipTest("Variable 'SOTA_PACKED_CREDENTIALS' not set.")
77 # Check if the file exists.
78 self.assertTrue(os.path.isfile(credentials), "File %s does not exist" % credentials)
79 deploydir = get_bb_var('DEPLOY_DIR_IMAGE')
80 imagename = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal')
81 # Check if the credentials are included in the output image.
82 result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' %
83 (deploydir, imagename), ignore_status=True)
84 self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
85
86# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-connectivity/connman/connman_%.bbappend b/recipes-connectivity/connman/connman_%.bbappend
new file mode 100644
index 0000000..b3633cc
--- /dev/null
+++ b/recipes-connectivity/connman/connman_%.bbappend
@@ -0,0 +1 @@
RPROVIDES_${PN} += "virtual/network-configuration"
diff --git a/recipes-connectivity/networkd-dhcp-conf/files/20-wired-dhcp.network b/recipes-connectivity/networkd-dhcp-conf/files/20-wired-dhcp.network
new file mode 100644
index 0000000..edb3678
--- /dev/null
+++ b/recipes-connectivity/networkd-dhcp-conf/files/20-wired-dhcp.network
@@ -0,0 +1,5 @@
1[Match]
2@MATCH_DIRECTIVE@
3
4[Network]
5DHCP=yes
diff --git a/recipes-connectivity/networkd-dhcp-conf/networkd-dhcp-conf.bb b/recipes-connectivity/networkd-dhcp-conf/networkd-dhcp-conf.bb
new file mode 100644
index 0000000..0700ac6
--- /dev/null
+++ b/recipes-connectivity/networkd-dhcp-conf/networkd-dhcp-conf.bb
@@ -0,0 +1,28 @@
1SUMMARY = "systemd-networkd config to setup wired interface with dhcp"
2DESCRIPTION = "Provides automatic dhcp network configuration for wired \
3interfaces through systemd-networkd"
4LICENSE = "MPL-2.0"
5LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
6
7inherit allarch systemd
8
9RPROVIDES_${PN} = "virtual/network-configuration"
10
11SRC_URI_append = " file://20-wired-dhcp.network"
12PR = "r1"
13
14RDEPENDS_${PN} = "systemd"
15
16S = "${WORKDIR}"
17
18PACKAGE_ARCH = "${MACHINE_ARCH}"
19
20FILES_${PN} = "${systemd_unitdir}/network/*"
21
22DEV_MATCH_DIRECTIVE ?= "Name=en*"
23
24do_install() {
25 install -d ${D}/${systemd_unitdir}/network
26 install -m 0644 ${WORKDIR}/20-wired-dhcp.network ${D}/${systemd_unitdir}/network
27 sed -i -e 's|@MATCH_DIRECTIVE@|${DEV_MATCH_DIRECTIVE}|g' ${D}${systemd_unitdir}/network/20-wired-dhcp.network
28}
diff --git a/recipes-devtools/valgrind/files/bug344802-unhandled-0xec510f1e.patch b/recipes-devtools/valgrind/files/bug344802-unhandled-0xec510f1e.patch
new file mode 100644
index 0000000..a25f541
--- /dev/null
+++ b/recipes-devtools/valgrind/files/bug344802-unhandled-0xec510f1e.patch
@@ -0,0 +1,250 @@
1diff --git a/VEX/priv/guest_arm_defs.h b/VEX/priv/guest_arm_defs.h
2index 2ccbe4398..90312fbd4 100644
3--- a/VEX/priv/guest_arm_defs.h
4+++ b/VEX/priv/guest_arm_defs.h
5@@ -350,6 +350,10 @@ typedef
6 }
7 ARMCondcode;
8
9+extern UInt arm_dirtyhelper_MRS_CNTFRQ ( void );
10+extern ULong arm_dirtyhelper_MRRS_CNTVCT ( void );
11+extern ULong arm_dirtyhelper_MRRS_CNTPCT ( void );
12+
13 #endif /* ndef __VEX_GUEST_ARM_DEFS_H */
14
15 /*---------------------------------------------------------------*/
16diff --git a/VEX/priv/guest_arm_helpers.c b/VEX/priv/guest_arm_helpers.c
17index 8a028736e..89b17ce7b 100644
18--- a/VEX/priv/guest_arm_helpers.c
19+++ b/VEX/priv/guest_arm_helpers.c
20@@ -1445,6 +1445,53 @@ VexGuestLayout
21 };
22
23
24+UInt arm_dirtyhelper_MRS_CNTFRQ ( void )
25+{
26+#if __ARM_ARCH_ISA_ARM //{
27+ UInt w = 0x55555555UL; /* overwritten */
28+ __asm__ __volatile__("mrc p15, 0, %0, c14, c0, 0" : "=r"(w));
29+ return w;
30+#elif __ARM_ARCH_ISA_A64 //}{
31+ UInt w;
32+ __asm__ __volatile__("mrs %0,cntfrq_el0": "=r"(w));
33+ return w;
34+#else //}{
35+ return 0;
36+#endif //}
37+}
38+
39+ULong arm_dirtyhelper_MRRS_CNTVCT ( void )
40+{
41+#if __ARM_ARCH_ISA_ARM //}{
42+ UInt w0;
43+ UInt w1;
44+ __asm__ __volatile__("mrrc p15, 1, %0, %1, c14" : "=r"(w0), "=r"(w1));
45+ return (((ULong)w1)<<32) | w0;
46+#elif __ARM_ARCH_ISA_A64 //{
47+ ULong w;
48+ __asm__ __volatile__("mrs %0, cntvct_el0" : "=r"(w));
49+ return w;
50+#else //}{
51+ return 0;
52+#endif //}
53+}
54+
55+ULong arm_dirtyhelper_MRRS_CNTPCT ( void )
56+{
57+#if __ARM_ARCH_ISA_ARM //}{
58+ UInt w0;
59+ UInt w1;
60+ __asm__ __volatile__("mrrc p15, 0, %0, %1, c14" : "=r"(w0), "=r"(w1));
61+ return (((ULong)w1)<<32) | w0;
62+#elif __ARM_ARCH_ISA_A64 //{
63+ ULong w;
64+ __asm__ __volatile__("mrs %0, cntpct_el0" : "=r"(w));
65+ return w;
66+#else //}{
67+ return 0;
68+#endif //}
69+}
70+
71 /*---------------------------------------------------------------*/
72 /*--- end guest_arm_helpers.c ---*/
73 /*---------------------------------------------------------------*/
74diff --git a/VEX/priv/guest_arm_toIR.c b/VEX/priv/guest_arm_toIR.c
75index d858c85e0..f96af92c4 100644
76--- a/VEX/priv/guest_arm_toIR.c
77+++ b/VEX/priv/guest_arm_toIR.c
78@@ -18755,6 +18755,87 @@ DisResult disInstr_ARM_WRK (
79 /* fall through */
80 }
81
82+ /* CNTFRQ: mrc p15, 0, rX, c14, c0, 0 */
83+ if (0x0e1e0f10 == (insn & 0x0FFF0FFF)) {
84+ UInt rD = INSN(15,12);
85+ if (rD <= 14) {
86+ /* skip r15, that's too stupid to handle */
87+ IRTemp val = newTemp(Ity_I32);
88+ IRExpr** args = mkIRExprVec_0();
89+ IRDirty* d = unsafeIRDirty_1_N(
90+ val,
91+ 0/*regparms*/,
92+ "arm_dirtyhelper_MRS_CNTFRQ",
93+ &arm_dirtyhelper_MRS_CNTFRQ,
94+ args
95+ );
96+ /* execute the dirty call, dumping the result in val. */
97+ stmt( IRStmt_Dirty(d) );
98+ putIRegA(rD, mkexpr(val), condT, Ijk_Boring);
99+ DIP("mrc%s p15, 0, r%u, c14, c0, 0\n", nCC(INSN_COND), rD);
100+ goto decode_success;
101+ }
102+ /* fall through */
103+ }
104+
105+ /* CNTPCT */
106+ if (0x0c500f0e == (insn & 0x0FF00FFF)) {
107+ UInt rDhi = INSN(19,16);
108+ UInt rDlo = INSN(15,12);
109+ if (rDhi <= 14 && rDlo <= 14) {
110+ /* skip r15, that's too stupid to handle */
111+ IRTemp resHi = newTemp(Ity_I32);
112+ IRTemp resLo = newTemp(Ity_I32);
113+ IRTemp val = newTemp(Ity_I64);
114+ IRExpr** args = mkIRExprVec_0();
115+ IRDirty* d = unsafeIRDirty_1_N(
116+ val,
117+ 0/*regparms*/,
118+ "arm_dirtyhelper_MRRS_CNTPCT",
119+ &arm_dirtyhelper_MRRS_CNTPCT,
120+ args
121+ );
122+ /* execute the dirty call, dumping the result in val. */
123+ stmt( IRStmt_Dirty(d) );
124+ assign( resHi, unop(Iop_64HIto32, mkexpr(val)) );
125+ assign( resLo, unop(Iop_64to32, mkexpr(val)) );
126+ putIRegA( rDhi, mkexpr(resHi), condT, Ijk_Boring );
127+ putIRegA( rDlo, mkexpr(resLo), condT, Ijk_Boring );
128+ DIP("mrrc%s p15, 0, r%u, r%u, c14\n", nCC(INSN_COND), rDlo, rDhi);
129+ goto decode_success;
130+ }
131+ /* fall through */
132+ }
133+
134+ /* CNTVCT */
135+ if (0x0c500f1e == (insn & 0x0FF00FFF)) {
136+ UInt rDhi = INSN(19,16);
137+ UInt rDlo = INSN(15,12);
138+ if (rDhi <= 14 && rDlo <= 14) {
139+ /* skip r15, that's too stupid to handle */
140+ IRTemp resHi = newTemp(Ity_I32);
141+ IRTemp resLo = newTemp(Ity_I32);
142+ IRTemp val = newTemp(Ity_I64);
143+ IRExpr** args = mkIRExprVec_0();
144+ IRDirty* d = unsafeIRDirty_1_N(
145+ val,
146+ 0/*regparms*/,
147+ "arm_dirtyhelper_MRRS_CNTVCT",
148+ &arm_dirtyhelper_MRRS_CNTVCT,
149+ args
150+ );
151+ /* execute the dirty call, dumping the result in val. */
152+ stmt( IRStmt_Dirty(d) );
153+ assign( resHi, unop(Iop_64HIto32, mkexpr(val)) );
154+ assign( resLo, unop(Iop_64to32, mkexpr(val)) );
155+ putIRegA( rDhi, mkexpr(resHi), condT, Ijk_Boring );
156+ putIRegA( rDlo, mkexpr(resLo), condT, Ijk_Boring );
157+ DIP("mrrc%s p15, 1, r%u, r%u, c14\n", nCC(INSN_COND), rDlo, rDhi);
158+ goto decode_success;
159+ }
160+ /* fall through */
161+ }
162+
163 /* Handle various kinds of barriers. This is rather indiscriminate
164 in the sense that they are all turned into an IR Fence, which
165 means we don't know which they are, so the back end has to
166@@ -23196,6 +23277,84 @@ DisResult disInstr_THUMB_WRK (
167 /* fall through */
168 }
169
170+ /* CNTFRQ: mrc p15, 0, rX, c14, c0, 0 */
171+ if ((INSN0(15,0) == 0xee1e) && (INSN1(11,0) == 0xf10)) {
172+ UInt rD = INSN1(15,12);
173+ if (!isBadRegT(rD)) {
174+ IRTemp val = newTemp(Ity_I32);
175+ IRExpr** args = mkIRExprVec_0();
176+ IRDirty* d = unsafeIRDirty_1_N(
177+ val,
178+ 0/*regparms*/,
179+ "arm_dirtyhelper_MRS_CNTFRQ",
180+ &arm_dirtyhelper_MRS_CNTFRQ,
181+ args
182+ );
183+ /* execute the dirty call, dumping the result in val. */
184+ stmt( IRStmt_Dirty(d) );
185+ putIRegT(rD, mkexpr(val), condT);
186+ DIP("mrc p15, 0, r%u, c14, c0, 0\n", rD);
187+ goto decode_success;
188+ }
189+ /* fall through */
190+ }
191+
192+ /* CNTPCT */
193+ if ((INSN0(15,4) == 0xec5) && (INSN1(11,0) == 0xf0e)) {
194+ UInt rDhi = INSN0(3,0);
195+ UInt rDlo = INSN1(15,12);
196+ if (!isBadRegT(rDhi) && !isBadRegT(rDlo)) {
197+ IRTemp resHi = newTemp(Ity_I32);
198+ IRTemp resLo = newTemp(Ity_I32);
199+ IRTemp val = newTemp(Ity_I64);
200+ IRExpr** args = mkIRExprVec_0();
201+ IRDirty* d = unsafeIRDirty_1_N(
202+ val,
203+ 0/*regparms*/,
204+ "arm_dirtyhelper_MRRS_CNTPCT",
205+ &arm_dirtyhelper_MRRS_CNTPCT,
206+ args
207+ );
208+ /* execute the dirty call, dumping the result in val. */
209+ stmt( IRStmt_Dirty(d) );
210+ assign( resHi, unop(Iop_64HIto32, mkexpr(val)) );
211+ assign( resLo, unop(Iop_64to32, mkexpr(val)) );
212+ putIRegT( rDhi, mkexpr(resHi), condT );
213+ putIRegT( rDlo, mkexpr(resLo), condT );
214+ DIP("mrrc p15, 0, r%u, r%u, c14\n", rDlo, rDhi);
215+ goto decode_success;
216+ }
217+ /* fall through */
218+ }
219+
220+ /* CNTVCT */
221+ if ((INSN0(15,4) == 0xec5) && (INSN1(11,0) == 0xf1e)) {
222+ UInt rDhi = INSN0(3,0);
223+ UInt rDlo = INSN1(15,12);
224+ if (!isBadRegT(rDhi) && !isBadRegT(rDlo)) {
225+ IRTemp resHi = newTemp(Ity_I32);
226+ IRTemp resLo = newTemp(Ity_I32);
227+ IRTemp val = newTemp(Ity_I64);
228+ IRExpr** args = mkIRExprVec_0();
229+ IRDirty* d = unsafeIRDirty_1_N(
230+ val,
231+ 0/*regparms*/,
232+ "arm_dirtyhelper_MRRS_CNTVCT",
233+ &arm_dirtyhelper_MRRS_CNTVCT,
234+ args
235+ );
236+ /* execute the dirty call, dumping the result in val. */
237+ stmt( IRStmt_Dirty(d) );
238+ assign( resHi, unop(Iop_64HIto32, mkexpr(val)) );
239+ assign( resLo, unop(Iop_64to32, mkexpr(val)) );
240+ putIRegT( rDhi, mkexpr(resHi), condT );
241+ putIRegT( rDlo, mkexpr(resLo), condT );
242+ DIP("mrrc p15, 1, r%u, r%u, c14\n", rDlo, rDhi);
243+ goto decode_success;
244+ }
245+ /* fall through */
246+ }
247+
248 /* ------------------- CLREX ------------------ */
249 if (INSN0(15,0) == 0xF3BF && INSN1(15,0) == 0x8F2F) {
250 /* AFAICS, this simply cancels a (all?) reservations made by a
diff --git a/recipes-devtools/valgrind/valgrind_%.bbappend b/recipes-devtools/valgrind/valgrind_%.bbappend
new file mode 100644
index 0000000..c5f7c31
--- /dev/null
+++ b/recipes-devtools/valgrind/valgrind_%.bbappend
@@ -0,0 +1,4 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3# from https://bugs.kde.org/show_bug.cgi?id=344802 (John Reiser)
4SRC_URI += "file://bug344802-unhandled-0xec510f1e.patch"
diff --git a/recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb b/recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb
index 0628a61..6b2dd27 100644
--- a/recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb
+++ b/recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb
@@ -3,6 +3,8 @@ SECTION = "base"
3LICENSE = "MPL-2.0" 3LICENSE = "MPL-2.0"
4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
5 5
6inherit allarch
7
6DEPENDS = "aktualizr-native zip-native" 8DEPENDS = "aktualizr-native zip-native"
7ALLOW_EMPTY_${PN} = "1" 9ALLOW_EMPTY_${PN} = "1"
8 10
diff --git a/recipes-sota/aktualizr/aktualizr-auto-prov.bb b/recipes-sota/aktualizr/aktualizr-auto-prov.bb
index 308f552..4b68491 100644
--- a/recipes-sota/aktualizr/aktualizr-auto-prov.bb
+++ b/recipes-sota/aktualizr/aktualizr-auto-prov.bb
@@ -5,6 +5,8 @@ SECTION = "base"
5LICENSE = "MPL-2.0" 5LICENSE = "MPL-2.0"
6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
7 7
8inherit allarch
9
8DEPENDS = "aktualizr-native zip-native" 10DEPENDS = "aktualizr-native zip-native"
9RDEPENDS_${PN}_append = "${@' aktualizr-auto-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS') == '1' else ''}" 11RDEPENDS_${PN}_append = "${@' aktualizr-auto-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS') == '1' else ''}"
10PV = "1.0" 12PV = "1.0"
diff --git a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb
index 7420983..da17d77 100644
--- a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb
+++ b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb
@@ -3,6 +3,12 @@ SECTION = "base"
3LICENSE = "MPL-2.0" 3LICENSE = "MPL-2.0"
4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 4LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
5 5
6inherit allarch
7
8# WARNING: it is NOT a production solution. The secure way to provision devices
9# is to create certificate request directly on the device (either with HSM/TPM
10# or with software) and then sign it with a CA stored on a disconnected machine.
11
6DEPENDS = "aktualizr aktualizr-native" 12DEPENDS = "aktualizr aktualizr-native"
7ALLOW_EMPTY_${PN} = "1" 13ALLOW_EMPTY_${PN} = "1"
8 14
diff --git a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb
index 8dcda99..414cb5e 100644
--- a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb
+++ b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb
@@ -1,14 +1,13 @@
1SUMMARY = "Aktualizr configuration for implicit provisioning with CA" 1SUMMARY = "Aktualizr configuration for implicit provisioning with CA"
2DESCRIPTION = "Configuration for implicitly provisioning Aktualizr using externally provided or generated CA" 2DESCRIPTION = "Configuration for implicitly provisioning Aktualizr using externally provided or generated CA"
3 3
4# WARNING: it is NOT a production solution. The secure way to provision devices is to create certificate request directly on the device
5# (either with HSM/TPM or with software) and then sign it with a CA stored on a disconnected machine
6
7HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" 4HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
8SECTION = "base" 5SECTION = "base"
9LICENSE = "MPL-2.0" 6LICENSE = "MPL-2.0"
10LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 7LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
11 8
9inherit allarch
10
12DEPENDS = "aktualizr aktualizr-native openssl-native" 11DEPENDS = "aktualizr aktualizr-native openssl-native"
13RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS') == '1' else ''}" 12RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS') == '1' else ''}"
14 13
diff --git a/recipes-sota/aktualizr/aktualizr-hsm-prov.bb b/recipes-sota/aktualizr/aktualizr-hsm-prov.bb
index 27aba0f..77c6720 100644
--- a/recipes-sota/aktualizr/aktualizr-hsm-prov.bb
+++ b/recipes-sota/aktualizr/aktualizr-hsm-prov.bb
@@ -5,6 +5,8 @@ SECTION = "base"
5LICENSE = "MPL-2.0" 5LICENSE = "MPL-2.0"
6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
7 7
8inherit allarch
9
8DEPENDS = "aktualizr aktualizr-native" 10DEPENDS = "aktualizr aktualizr-native"
9RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds softhsm-testtoken' if d.getVar('SOTA_DEPLOY_CREDENTIALS') == '1' else ''}" 11RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds softhsm-testtoken' if d.getVar('SOTA_DEPLOY_CREDENTIALS') == '1' else ''}"
10 12
diff --git a/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb b/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb
index 305b5e5..d962876 100644
--- a/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb
+++ b/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb
@@ -3,12 +3,14 @@ HOMEPAGE = "https://github.com/advancedtelematic/aktualizr"
3SECTION = "base" 3SECTION = "base"
4LICENSE = "MPL-2.0" 4LICENSE = "MPL-2.0"
5LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 5LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
6
7inherit allarch
8
6DEPENDS = "aktualizr-native" 9DEPENDS = "aktualizr-native"
7RDEPENDS_${PN} = "aktualizr" 10RDEPENDS_${PN} = "aktualizr"
8 11
9SRC_URI = "" 12SRC_URI = ""
10 13
11
12do_install() { 14do_install() {
13 install -m 0700 -d ${D}${libdir}/sota/conf.d 15 install -m 0700 -d ${D}${libdir}/sota/conf.d
14 install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/sota_uboot_env.toml ${D}${libdir}/sota/conf.d/30-rollback.toml 16 install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/sota_uboot_env.toml ${D}${libdir}/sota/conf.d/30-rollback.toml
diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb
index a8f40d6..c0e275d 100755
--- a/recipes-sota/aktualizr/aktualizr_git.bb
+++ b/recipes-sota/aktualizr/aktualizr_git.bb
@@ -5,40 +5,51 @@ SECTION = "base"
5LICENSE = "MPL-2.0" 5LICENSE = "MPL-2.0"
6LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=9741c346eef56131163e13b9db1241b3" 6LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=9741c346eef56131163e13b9db1241b3"
7 7
8require garage-sign-version.inc
9
10DEPENDS = "boost curl openssl libarchive libsodium sqlite3 asn1c-native" 8DEPENDS = "boost curl openssl libarchive libsodium sqlite3 asn1c-native"
11RDEPENDS_${PN}_class-target = "aktualizr-check-discovery aktualizr-configs lshw" 9DEPENDS_append = "${@bb.utils.contains('PTEST_ENABLED', '1', ' coreutils-native ostree-native aktualizr-native ', '', d)}"
12RDEPENDS_${PN}-secondary = "aktualizr-check-discovery" 10RDEPENDS_${PN}_class-target = "aktualizr-configs lshw"
13RDEPENDS_${PN}-host-tools = "aktualizr aktualizr-repo aktualizr-cert-provider ${@bb.utils.contains('PACKAGECONFIG', 'sota-tools', 'garage-deploy garage-push', '', d)}" 11RDEPENDS_${PN}-host-tools = "aktualizr aktualizr-repo aktualizr-cert-provider ${@bb.utils.contains('PACKAGECONFIG', 'sota-tools', 'garage-deploy garage-push', '', d)}"
14 12
13RDEPENDS_${PN}-ptest += "bash cmake curl python3-modules openssl-bin sqlite3 valgrind"
14
15PV = "1.0+git${SRCPV}" 15PV = "1.0+git${SRCPV}"
16PR = "7" 16PR = "7"
17 17
18GARAGE_SIGN_PV = "0.6.0-18-g5b8b259"
19
18SRC_URI = " \ 20SRC_URI = " \
19 gitsm://github.com/advancedtelematic/aktualizr;branch=${BRANCH} \ 21 gitsm://github.com/advancedtelematic/aktualizr;branch=${BRANCH} \
22 file://run-ptest \
20 file://aktualizr.service \ 23 file://aktualizr.service \
21 file://aktualizr-secondary.service \ 24 file://aktualizr-secondary.service \
22 file://aktualizr-secondary.socket \ 25 file://aktualizr-secondary.socket \
23 file://aktualizr-serialcan.service \ 26 file://aktualizr-serialcan.service \
27 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 ''} \
24 " 29 "
25 30
26SRCREV = "c71ec0a320d85a3e75ba37bff7dc40ad02e9d655" 31# for garage-sign archive
32SRC_URI[md5sum] = "c5e9968dfe78a7264ab9a8338c11725d"
33SRC_URI[sha256sum] = "3a19258d7a1825a308aca0da82f7a337985bec05e8951355c4c95f0fcf2444f4"
34
35SRCREV = "c50feb37034eceb1254429d3e3ed38e5b8a0dc60"
27BRANCH ?= "master" 36BRANCH ?= "master"
28 37
29S = "${WORKDIR}/git" 38S = "${WORKDIR}/git"
30 39
31inherit pkgconfig cmake systemd 40inherit cmake pkgconfig ptest systemd
41
42# disable ptest by default as it slows down builds quite a lot
43# can be enabled manually by setting 'PTEST_ENABLED_pn-aktualizr' to '1' in local.conf
44PTEST_ENABLED = "0"
32 45
33SYSTEMD_PACKAGES = "${PN} ${PN}-secondary" 46SYSTEMD_PACKAGES = "${PN} ${PN}-secondary"
34SYSTEMD_SERVICE_${PN} = "aktualizr.service" 47SYSTEMD_SERVICE_${PN} = "aktualizr.service"
35SYSTEMD_SERVICE_${PN}-secondary = "aktualizr-secondary.socket" 48SYSTEMD_SERVICE_${PN}-secondary = "aktualizr-secondary.socket"
36 49
37EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV}" 50EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV} ${@bb.utils.contains('PTEST_ENABLED', '1', '-DTESTSUITE_VALGRIND=on', '', d)}"
38 51
39GARAGE_SIGN_OPS = "${@ '-DGARAGE_SIGN_VERSION=%s' % d.getVar('GARAGE_SIGN_VERSION') if d.getVar('GARAGE_SIGN_VERSION') is not None else ''} \ 52GARAGE_SIGN_OPS = "${@ d.expand('-DGARAGE_SIGN_ARCHIVE=${WORKDIR}/cli-${GARAGE_SIGN_PV}.tgz') if d.getVar('GARAGE_SIGN_AUTOVERSION') != '1' else ''}"
40 ${@ '-DGARAGE_SIGN_SHA256=%s' % d.getVar('GARAGE_SIGN_SHA256') if d.getVar('GARAGE_SIGN_SHA256') is not None else ''} \
41 "
42 53
43PACKAGECONFIG ?= "ostree ${@bb.utils.filter('DISTRO_FEATURES', 'systemd', d)} ${@bb.utils.filter('SOTA_CLIENT_FEATURES', 'hsm serialcan ubootenv', d)}" 54PACKAGECONFIG ?= "ostree ${@bb.utils.filter('DISTRO_FEATURES', 'systemd', d)} ${@bb.utils.filter('SOTA_CLIENT_FEATURES', 'hsm serialcan ubootenv', d)}"
44PACKAGECONFIG_class-native = "sota-tools" 55PACKAGECONFIG_class-native = "sota-tools"
@@ -51,6 +62,35 @@ PACKAGECONFIG[load-tests] = "-DBUILD_LOAD_TESTS=ON,-DBUILD_LOAD_TESTS=OFF,"
51PACKAGECONFIG[serialcan] = ",,,slcand-start" 62PACKAGECONFIG[serialcan] = ",,,slcand-start"
52PACKAGECONFIG[ubootenv] = ",,,u-boot-fw-utils aktualizr-uboot-env-rollback" 63PACKAGECONFIG[ubootenv] = ",,,u-boot-fw-utils aktualizr-uboot-env-rollback"
53 64
65# can be overriden in configuration with `RESOURCE_xxx_pn-aktualizr`
66# see `man systemd.resource-control` for details
67
68# can be used to lower aktualizr priority, default is 100
69RESOURCE_CPU_WEIGHT = "100"
70# will be slowed down when it reaches 'high', killed when it reaches 'max'
71RESOURCE_MEMORY_HIGH = "100M"
72RESOURCE_MEMORY_MAX = "80%"
73
74do_compile_ptest() {
75 cmake_runcmake_build --target build_tests "${PARALLEL_MAKE}"
76}
77
78do_install_ptest() {
79 # copy the complete source directory (contains build)
80 cp -r ${B}/ ${D}/${PTEST_PATH}/build
81 cp -r ${S}/ ${D}/${PTEST_PATH}/src
82
83 # remove huge external unused repository
84 rm -rf ${D}/${PTEST_PATH}/src/partial/extern/RIOT
85
86 # remove huge build artifacts
87 find ${D}/${PTEST_PATH}/build/src -name "*.a" -delete
88
89 # fix the absolute paths
90 find ${D}/${PTEST_PATH}/build -name "CMakeFiles" | xargs rm -rf
91 find ${D}/${PTEST_PATH}/build -name "*.cmake" -or -name "DartConfiguration.tcl" -or -name "run-valgrind" | xargs sed -e "s|${S}|${PTEST_PATH}/src|g" -e "s|${B}|${PTEST_PATH}/build|g" -e "s|\"--gtest_output[^\"]*\"||g" -i
92}
93
54do_install_append () { 94do_install_append () {
55 install -d ${D}${libdir}/sota 95 install -d ${D}${libdir}/sota
56 install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml 96 install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml
@@ -66,14 +106,14 @@ do_install_append () {
66 install -m 0700 -d ${D}${sysconfdir}/sota/conf.d 106 install -m 0700 -d ${D}${sysconfdir}/sota/conf.d
67 107
68 if [ -n "${SOTA_HARDWARE_ID}" ]; then 108 if [ -n "${SOTA_HARDWARE_ID}" ]; then
69 echo "[provision]\nprimary_ecu_hardware_id = ${SOTA_HARDWARE_ID}\n" > ${D}${libdir}/sota/conf.d/40-hardware-id.toml 109 printf "[provision]\nprimary_ecu_hardware_id = ${SOTA_HARDWARE_ID}\n" > ${D}${libdir}/sota/conf.d/40-hardware-id.toml
70 fi 110 fi
71 111
72 if [ -n "${SOTA_SECONDARY_CONFIG_DIR}" ]; then 112 if [ -n "${SOTA_SECONDARY_CONFIG_DIR}" ]; then
73 if [ -d "${SOTA_SECONDARY_CONFIG_DIR}" ]; then 113 if [ -d "${SOTA_SECONDARY_CONFIG_DIR}" ]; then
74 install -m 0700 -d ${D}${sysconfdir}/sota/ecus 114 install -m 0700 -d ${D}${sysconfdir}/sota/ecus
75 install -m 0644 "${SOTA_SECONDARY_CONFIG_DIR}"/* ${D}${sysconfdir}/sota/ecus/ 115 install -m 0644 "${SOTA_SECONDARY_CONFIG_DIR}"/* ${D}${sysconfdir}/sota/ecus/
76 echo "[uptane]\nsecondary_configs_dir = /etc/sota/ecus/\n" > ${D}${libdir}/sota/conf.d/30-secondary-configs-dir.toml 116 printf "[uptane]\nsecondary_configs_dir = /etc/sota/ecus/\n" > ${D}${libdir}/sota/conf.d/30-secondary-configs-dir.toml
77 else 117 else
78 bbwarn "SOTA_SECONDARY_CONFIG_DIR is set to an invalid directory (${SOTA_SECONDARY_CONFIG_DIR})" 118 bbwarn "SOTA_SECONDARY_CONFIG_DIR is set to an invalid directory (${SOTA_SECONDARY_CONFIG_DIR})"
79 fi 119 fi
@@ -87,6 +127,15 @@ do_install_append () {
87 install -m 0755 ${B}/src/sota_tools/garage-sign/bin/* ${D}${bindir} 127 install -m 0755 ${B}/src/sota_tools/garage-sign/bin/* ${D}${bindir}
88 install -m 0644 ${B}/src/sota_tools/garage-sign/lib/* ${D}${libdir} 128 install -m 0644 ${B}/src/sota_tools/garage-sign/lib/* ${D}${libdir}
89 fi 129 fi
130
131 # resource control
132 install -d ${D}/${systemd_system_unitdir}/aktualizr.service.d
133 install -m 0644 ${WORKDIR}/10-resource-control.conf ${D}/${systemd_system_unitdir}/aktualizr.service.d
134
135 sed -i -e 's|@CPU_WEIGHT@|${RESOURCE_CPU_WEIGHT}|g' \
136 -e 's|@MEMORY_HIGH@|${RESOURCE_MEMORY_HIGH}|g' \
137 -e 's|@MEMORY_MAX@|${RESOURCE_MEMORY_MAX}|g' \
138 ${D}${systemd_system_unitdir}/aktualizr.service.d/10-resource-control.conf
90} 139}
91 140
92PACKAGESPLITFUNCS_prepend = "split_hosttools_packages " 141PACKAGESPLITFUNCS_prepend = "split_hosttools_packages "
@@ -101,7 +150,7 @@ python split_hosttools_packages () {
101 150
102PACKAGES_DYNAMIC = "^aktualizr-.* ^garage-.*" 151PACKAGES_DYNAMIC = "^aktualizr-.* ^garage-.*"
103 152
104PACKAGES =+ "${PN}-examples ${PN}-secondary ${PN}-configs ${PN}-host-tools" 153PACKAGES =+ "${PN}-resource-control ${PN}-examples ${PN}-secondary ${PN}-configs ${PN}-host-tools"
105 154
106ALLOW_EMPTY_${PN}-host-tools = "1" 155ALLOW_EMPTY_${PN}-host-tools = "1"
107 156
@@ -111,6 +160,10 @@ FILES_${PN} = " \
111 ${systemd_unitdir}/system/aktualizr.service \ 160 ${systemd_unitdir}/system/aktualizr.service \
112 " 161 "
113 162
163FILES_${PN}-resource-control = " \
164 ${systemd_system_unitdir}/aktualizr.service.d/10-resource-control.conf \
165 "
166
114FILES_${PN}-configs = " \ 167FILES_${PN}-configs = " \
115 ${sysconfdir}/sota/* \ 168 ${sysconfdir}/sota/* \
116 ${libdir}/sota/* \ 169 ${libdir}/sota/* \
@@ -126,6 +179,7 @@ FILES_${PN}-secondary = " \
126 ${systemd_unitdir}/system/aktualizr-secondary.socket \ 179 ${systemd_unitdir}/system/aktualizr-secondary.socket \
127 ${systemd_unitdir}/system/aktualizr-secondary.service \ 180 ${systemd_unitdir}/system/aktualizr-secondary.service \
128 " 181 "
182
129BBCLASSEXTEND = "native" 183BBCLASSEXTEND = "native"
130 184
131# vim:set ts=4 sw=4 sts=4 expandtab: 185# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-sota/aktualizr/files/10-resource-control.conf b/recipes-sota/aktualizr/files/10-resource-control.conf
new file mode 100644
index 0000000..254713c
--- /dev/null
+++ b/recipes-sota/aktualizr/files/10-resource-control.conf
@@ -0,0 +1,6 @@
1[Service]
2CPUAccounting=true
3CPUWeight=@CPU_WEIGHT@
4MemoryAccounting=true
5MemoryHigh=@MEMORY_HIGH@
6MemoryMax=@MEMORY_MAX@
diff --git a/recipes-sota/aktualizr/files/run-ptest b/recipes-sota/aktualizr/files/run-ptest
new file mode 100755
index 0000000..ff441f9
--- /dev/null
+++ b/recipes-sota/aktualizr/files/run-ptest
@@ -0,0 +1,18 @@
1#!/bin/sh
2
3set -eu
4
5AKTUALIZR_PTEST_PARALLEL_LEVEL=${AKTUALIZR_PTEST_PARALLEL_LEVEL:-2}
6
7filter_logs() {
8 awk '/^.*Test[[:space:]]*#[[:digit:]]+:/ {
9 a = gensub(/^.*Test[[:space:]]*#[[:digit:]]+:[[:space:]]*([^[:space:]]+).*(Passed|Skipped|Not Run|Failed|Timeout|Exception)[[:space:]:].*$/, "\\2: \\1", "g");
10 a = gensub(/^Passed/, "PASS", "g", a);
11 a = gensub(/^(Skipped|Disabled)/, "SKIP", "g", a);
12 a = gensub(/^(Not Run|Failed|Timeout|Exception)/, "FAIL", "g", a);
13 print a;
14 }'
15}
16
17cd build
18ctest -j "$AKTUALIZR_PTEST_PARALLEL_LEVEL" -O /tmp/aktualizr-ptest.log --output-on-failure -LE 'noptest' 2> /dev/null | filter_logs
diff --git a/recipes-sota/aktualizr/garage-sign-version.inc b/recipes-sota/aktualizr/garage-sign-version.inc
deleted file mode 100644
index 2cea6c9..0000000
--- a/recipes-sota/aktualizr/garage-sign-version.inc
+++ /dev/null
@@ -1,36 +0,0 @@
1
2python () {
3 if d.getVar("GARAGE_SIGN_VERSION") or not d.getVar("SOTA_PACKED_CREDENTIALS"):
4 return
5 import json
6 import urllib.request
7 import zipfile
8 with zipfile.ZipFile(d.getVar("SOTA_PACKED_CREDENTIALS"), 'r') as zip_ref:
9 try:
10 with zip_ref.open('tufrepo.url', mode='r') as url_file:
11 url = url_file.read().decode().strip(' \t\n') + '/health/version'
12 except (KeyError, ValueError, RuntimeError):
13 return
14 connected = False
15 tries = 3
16 for i in range(tries):
17 try:
18 r = urllib.request.urlopen(url)
19 if r.code == 200:
20 connected = True
21 break
22 else:
23 print('Bad return code from server ' + url + ': ' + str(r.code) +
24 ' (attempt ' + str(i + 1) + ' of ' + str(tries) + ')')
25 except urllib.error.URLError as e:
26 print('Error connecting to server ' + url + ': ' + str(e) +
27 ' (attempt ' + str(i + 1) + ' of ' + str(tries) + ')')
28 if not connected:
29 return
30 resp = r.read().decode('utf-8')
31 j = json.loads(resp)
32 version = 'cli-' + j['version'] + '.tgz'
33 d.setVar("GARAGE_SIGN_VERSION", version)
34}
35
36# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/recipes-sota/config/aktualizr-auto-reboot.bb b/recipes-sota/config/aktualizr-auto-reboot.bb
index ad4d17c..f360d9e 100644
--- a/recipes-sota/config/aktualizr-auto-reboot.bb
+++ b/recipes-sota/config/aktualizr-auto-reboot.bb
@@ -5,6 +5,8 @@ SECTION = "base"
5LICENSE = "MPL-2.0" 5LICENSE = "MPL-2.0"
6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
7 7
8inherit allarch
9
8SRC_URI = " \ 10SRC_URI = " \
9 file://35-enable-auto-reboot.toml \ 11 file://35-enable-auto-reboot.toml \
10 " 12 "
diff --git a/recipes-sota/config/aktualizr-disable-send-ip.bb b/recipes-sota/config/aktualizr-disable-send-ip.bb
index 8dd2647..07c12ca 100644
--- a/recipes-sota/config/aktualizr-disable-send-ip.bb
+++ b/recipes-sota/config/aktualizr-disable-send-ip.bb
@@ -5,6 +5,8 @@ SECTION = "base"
5LICENSE = "MPL-2.0" 5LICENSE = "MPL-2.0"
6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
7 7
8inherit allarch
9
8SRC_URI = " \ 10SRC_URI = " \
9 file://30-disable-send-ip.toml \ 11 file://30-disable-send-ip.toml \
10 " 12 "
diff --git a/recipes-sota/config/aktualizr-log-debug.bb b/recipes-sota/config/aktualizr-log-debug.bb
index 098faf4..0c03786 100644
--- a/recipes-sota/config/aktualizr-log-debug.bb
+++ b/recipes-sota/config/aktualizr-log-debug.bb
@@ -5,6 +5,8 @@ SECTION = "base"
5LICENSE = "MPL-2.0" 5LICENSE = "MPL-2.0"
6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" 6LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad"
7 7
8inherit allarch
9
8SRC_URI = " \ 10SRC_URI = " \
9 file://05-log-debug.toml \ 11 file://05-log-debug.toml \
10 " 12 "
diff --git a/recipes-sota/fit-conf/fit-conf.bb b/recipes-sota/fit-conf/fit-conf.bb
index c6cecec..f24a94a 100644
--- a/recipes-sota/fit-conf/fit-conf.bb
+++ b/recipes-sota/fit-conf/fit-conf.bb
@@ -2,6 +2,8 @@ SUMMARY = "FIT image configuration for u-boot to use"
2LICENSE = "MIT" 2LICENSE = "MIT"
3LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" 3LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
4 4
5PACKAGE_ARCH = "${MACHINE_ARCH}"
6
5do_install() { 7do_install() {
6 mkdir -p ${D}${libdir} 8 mkdir -p ${D}${libdir}
7 echo -n "fit_conf=" >${D}${libdir}/fit_conf 9 echo -n "fit_conf=" >${D}${libdir}/fit_conf
diff --git a/recipes-test/images/secondary-image.bb b/recipes-test/images/secondary-image.bb
index 1a41169..61df85b 100644
--- a/recipes-test/images/secondary-image.bb
+++ b/recipes-test/images/secondary-image.bb
@@ -15,8 +15,7 @@ IMAGE_INSTALL_remove = " \
15 aktualizr-ca-implicit-prov-creds \ 15 aktualizr-ca-implicit-prov-creds \
16 aktualizr-hsm-prov \ 16 aktualizr-hsm-prov \
17 aktualizr-uboot-env-rollback \ 17 aktualizr-uboot-env-rollback \
18 connman \ 18 virtual/network-configuration \
19 connman-client \
20 " 19 "
21 20
22IMAGE_INSTALL_append = " \ 21IMAGE_INSTALL_append = " \
diff --git a/scripts/lib/wic/plugins/source/otaimage.py b/scripts/lib/wic/plugins/source/otaimage.py
index 4b30776..1f82af7 100644
--- a/scripts/lib/wic/plugins/source/otaimage.py
+++ b/scripts/lib/wic/plugins/source/otaimage.py
@@ -19,6 +19,7 @@ import logging
19import os 19import os
20import sys 20import sys
21 21
22from wic import WicError
22from wic.plugins.source.rawcopy import RawCopyPlugin 23from wic.plugins.source.rawcopy import RawCopyPlugin
23from wic.misc import get_bitbake_var 24from wic.misc import get_bitbake_var
24 25
@@ -32,6 +33,18 @@ class OTAImagePlugin(RawCopyPlugin):
32 name = 'otaimage' 33 name = 'otaimage'
33 34
34 @classmethod 35 @classmethod
36 def _get_src_file(cls, image_dir_var):
37 """
38 Get OTA image file from image directory variable.
39 """
40 image_dir = get_bitbake_var(image_dir_var)
41 if not image_dir:
42 raise WicError("Couldn't find %s, exiting" % image_dir_var)
43
44 image_file = image_dir + "/" + get_bitbake_var("IMAGE_LINK_NAME") + ".ota-ext4"
45 return image_file if os.path.exists(image_file) else ""
46
47 @classmethod
35 def do_prepare_partition(cls, part, source_params, cr, cr_workdir, 48 def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
36 oe_builddir, bootimg_dir, kernel_dir, 49 oe_builddir, bootimg_dir, kernel_dir,
37 rootfs_dir, native_sysroot): 50 rootfs_dir, native_sysroot):
@@ -39,13 +52,12 @@ class OTAImagePlugin(RawCopyPlugin):
39 Called to do the actual content population for a partition i.e. it 52 Called to do the actual content population for a partition i.e. it
40 'prepares' the partition to be incorporated into the image. 53 'prepares' the partition to be incorporated into the image.
41 """ 54 """
42 bootimg_dir = get_bitbake_var("IMGDEPLOYDIR")
43 if not bootimg_dir:
44 logger.error("Couldn't find DEPLOY_DIR_IMAGE, exiting\n")
45
46 logger.debug('Bootimg dir: %s' % bootimg_dir)
47 55
48 src = bootimg_dir + "/" + get_bitbake_var("IMAGE_LINK_NAME") + ".ota-ext4" 56 src = cls._get_src_file("IMGDEPLOYDIR")
57 if not src:
58 src = cls._get_src_file("DEPLOY_DIR_IMAGE")
59 if not src:
60 raise WicError("Couldn't find ota image in IMGDEPLOYDIR or DEPLOY_DIR_IMAGE, exiting")
49 61
50 logger.debug('Preparing partition using image %s' % (src)) 62 logger.debug('Preparing partition using image %s' % (src))
51 source_params['file'] = src 63 source_params['file'] = src
diff --git a/scripts/qemucommand.py b/scripts/qemucommand.py
index 4abfd4e..cafab6d 100644
--- a/scripts/qemucommand.py
+++ b/scripts/qemucommand.py
@@ -97,6 +97,8 @@ class QemuCommand(object):
97 "-serial", "tcp:127.0.0.1:%d,server,nowait" % self.serial_port, 97 "-serial", "tcp:127.0.0.1:%d,server,nowait" % self.serial_port,
98 "-m", "1G", 98 "-m", "1G",
99 "-usb", 99 "-usb",
100 "-object", "rng-random,id=rng0,filename=/dev/urandom",
101 "-device", "virtio-rng-pci,rng=rng0",
100 "-device", "usb-tablet", 102 "-device", "usb-tablet",
101 "-show-cursor", 103 "-show-cursor",
102 "-vga", "std", 104 "-vga", "std",