summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Vacek <patrickvacek@gmail.com>2019-05-20 17:47:50 +0200
committerGitHub <noreply@github.com>2019-05-20 17:47:50 +0200
commitcdf070e20556a13ecda308833fd5c314d20547ab (patch)
treef62f36ca4b7b2f26644f9d7f2fdb7e6fdee0154d
parent195135f3d01fecc099bfec43d56b87c28c9aa8a0 (diff)
parent99992959999ce9f6ad5fdae5a96262a5e0e59b5e (diff)
downloadmeta-updater-cdf070e20556a13ecda308833fd5c314d20547ab.tar.gz
Merge pull request #514 from advancedtelematic/fix/rocko/backport
Fix/rocko/backport
-rw-r--r--README.adoc34
-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.bbclass3
-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.py43
-rw-r--r--lib/oeqa/selftest/cases/updater_qemux86_64.py (renamed from lib/oeqa/selftest/cases/updater.py)392
-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.bb3
-rwxr-xr-xrecipes-sota/aktualizr/aktualizr_git.bb81
-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-test/images/secondary-image.bb3
-rw-r--r--scripts/lib/wic/plugins/source/otaimage.py24
-rw-r--r--scripts/qemucommand.py2
38 files changed, 904 insertions, 404 deletions
diff --git a/README.adoc b/README.adoc
index 9f7d485..01f1c85 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,12 +84,14 @@ Although we have used U-Boot so far, other boot loaders can be configured work w
82* `OSTREE_COMMIT_BODY` - Message attached to OSTree commit. Empty by default. 84* `OSTREE_COMMIT_BODY` - Message attached to OSTree commit. Empty by default.
83* `OSTREE_COMMIT_SUBJECT` - Commit subject used by OSTree. Defaults to `Commit-id: ${IMAGE_NAME}` 85* `OSTREE_COMMIT_SUBJECT` - Commit subject used by OSTree. Defaults to `Commit-id: ${IMAGE_NAME}`
84* `OSTREE_UPDATE_SUMMARY` - Set this to '1' to update summary of OSTree repository on each commit. '0' by default. 86* `OSTREE_UPDATE_SUMMARY` - Set this to '1' to update summary of OSTree repository on each commit. '0' by default.
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* `SOTA_PACKED_CREDENTIALS` - when set, your ostree commit will be pushed to a remote repo as a bitbake step. This should be the path to a zipped credentials file in https://github.com/advancedtelematic/aktualizr/blob/master/docs/credentials.adoc[the format accepted by garage-push]. 88* `SOTA_PACKED_CREDENTIALS` - when set, your ostree commit will be pushed to a remote repo as a bitbake step. This should be the path to a zipped credentials file in https://github.com/advancedtelematic/aktualizr/blob/master/docs/credentials.adoc[the format accepted by garage-push].
86* `SOTA_DEPLOY_CREDENTIALS` - when set to '1' (default value), deploys credentials to the built image. Override it in `local.conf` to built a generic image that can be provisioned manually after the build. 89* `SOTA_DEPLOY_CREDENTIALS` - when set to '1' (default value), deploys credentials to the built image. Override it in `local.conf` to built a generic image that can be provisioned manually after the build.
87* `SOTA_CLIENT_PROV` - which provisioning method to use. Valid options are https://github.com/advancedtelematic/aktualizr/blob/master/docs/automatic-provisioning.adoc[`aktualizr-auto-prov`], https://github.com/advancedtelematic/aktualizr/blob/master/docs/implicit-provisioning.adoc[`aktualizr-ca-implicit-prov`], and https://github.com/advancedtelematic/aktualizr/blob/master/docs/hsm-provisioning.adoc[`aktualizr-hsm-prov`]. The default is `aktualizr-auto-prov`. This can also be set to an empty string to avoid using a provisioning recipe. 90* `SOTA_CLIENT_PROV` - which provisioning method to use. Valid options are https://github.com/advancedtelematic/aktualizr/blob/master/docs/automatic-provisioning.adoc[`aktualizr-auto-prov`], https://github.com/advancedtelematic/aktualizr/blob/master/docs/implicit-provisioning.adoc[`aktualizr-ca-implicit-prov`], and https://github.com/advancedtelematic/aktualizr/blob/master/docs/hsm-provisioning.adoc[`aktualizr-hsm-prov`]. The default is `aktualizr-auto-prov`. This can also be set to an empty string to avoid using a provisioning recipe.
88* `SOTA_CLIENT_FEATURES` - extensions to aktualizr. The only valid options are `hsm` (to build with HSM support) and `secondary-network` (to set up a simulated 'in-vehicle' network with support for a primary node with a DHCP server and a secondary node with a DHCP client). 91* `SOTA_CLIENT_FEATURES` - extensions to aktualizr. The only valid options are `hsm` (to build with HSM support) and `secondary-network` (to set up a simulated 'in-vehicle' network with support for a primary node with a DHCP server and a secondary node with a DHCP client).
89* `SOTA_SECONDARY_CONFIG_DIR` - a directory containing JSON configuration files for virtual secondaries on the host. These will be installed into `/etc/sota/ecus` on the device and automatically provided to aktualizr. 92* `SOTA_SECONDARY_CONFIG_DIR` - a directory containing JSON configuration files for virtual secondaries on the host. These will be installed into `/etc/sota/ecus` on the device and automatically provided to aktualizr.
90* `SOTA_HARDWARE_ID` - a custom hardware ID that will be written to the aktualizr config. Defaults to MACHINE if not set. 93* `SOTA_HARDWARE_ID` - a custom hardware ID that will be written to the aktualizr config. Defaults to MACHINE if not set.
94* `RESOURCE_xxx_pn-aktualizr` - controls maximum resource usage of the aktualizr service, when `aktualizr-resource-control` is installed on the image. See <<aktualizr service resource control>> for details.
91 95
92== Usage 96== Usage
93 97
@@ -153,6 +157,19 @@ Second, you can write recipes to install additional config files with customized
153 157
154To 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`. 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`.
155 159
160=== aktualizr service resource control
161
162With 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.
163
164To 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`.
165
166For example:
167
168....
169IMAGE_INSTALL_append += " aktualizr-resource-control "
170RESOURCE_CPU_WEIGHT_pn-aktualizr = "50"
171....
172
156== Development configuration 173== Development configuration
157 174
158There are a few settings that can be controlled in `local.conf` to simplify the development process: 175There are a few settings that can be controlled in `local.conf` to simplify the development process:
@@ -207,11 +224,26 @@ sudo apt install ovmf
2075. Run oe-selftest: 2245. Run oe-selftest:
208+ 225+
209``` 226```
210oe-selftest --run-tests updater 227oe-selftest -r updater_native updater_qemux86_64 updater_minnowboard updater_raspberrypi
211``` 228```
212 229
213For 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]. 230For 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].
214 231
232== Aktualizr test suite with ptest
233
234The 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`:
235
236```
237PTEST_ENABLED_pn-aktualizr = "1"
238IMAGE_INSTALL_append += " aktualizr-ptest ptest-runner "
239```
240
241Be aware that it will add several hundreds of MB to the generated file system.
242
243The 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`.
244
245The aktualizr ptests can be run via oe-selftest with `oe-selftest -r updater_qemux86_64_ptest`, but in the rocko and sumo branches, this is not fully supported due to valgrind issues with openssl 1.0.2 and issues with ptest timing out.
246
215== Manual provisoning 247== Manual provisoning
216 248
217As 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. 249As described in <<sota-related-variables-in-localconf,SOTA-related variables in local.conf>> section you can set `SOTA_DEPLOY_CREDENTIALS` to `0` to prevent deploying credentials to the built `wic` image. In this case you get a generic image that you can use e.g. on a production line to flash a series of devices. The cost of this approach is that this image is half-baked and should be provisioned before it can connect to the backend.
diff --git a/classes/image_types_ostree.bbclass b/classes/image_types_ostree.bbclass
index f3b1b33..134f5f5 100644
--- a/classes/image_types_ostree.bbclass
+++ b/classes/image_types_ostree.bbclass
@@ -224,6 +224,11 @@ IMAGE_CMD_garagesign () {
224 # Push may fail due to race condition when multiple build machines try to push simultaneously 224 # Push may fail due to race condition when multiple build machines try to push simultaneously
225 # in which case targets.json should be pulled again and the whole procedure repeated 225 # in which case targets.json should be pulled again and the whole procedure repeated
226 push_success=0 226 push_success=0
227 target_url=""
228 if [ -n "${GARAGE_TARGET_URL}" ]; then
229 target_url='--url ${GARAGE_TARGET_URL}'
230 fi
231
227 for push_retries in $( seq 3 ); do 232 for push_retries in $( seq 3 ); do
228 garage-sign targets pull --repo tufrepo \ 233 garage-sign targets pull --repo tufrepo \
229 --home-dir ${GARAGE_SIGN_REPO} 234 --home-dir ${GARAGE_SIGN_REPO}
@@ -233,7 +238,7 @@ IMAGE_CMD_garagesign () {
233 --format OSTREE \ 238 --format OSTREE \
234 --version ${target_version} \ 239 --version ${target_version} \
235 --length 0 \ 240 --length 0 \
236 --url "${GARAGE_TARGET_URL}" \ 241 ${target_url} \
237 --sha256 ${ostree_target_hash} \ 242 --sha256 ${ostree_target_hash} \
238 --hardwareids ${SOTA_HARDWARE_ID} 243 --hardwareids ${SOTA_HARDWARE_ID}
239 garage-sign targets sign --repo tufrepo \ 244 garage-sign targets sign --repo tufrepo \
diff --git a/classes/sota.bbclass b/classes/sota.bbclass
index 1517ceb..cb00a80 100644
--- a/classes/sota.bbclass
+++ b/classes/sota.bbclass
@@ -38,7 +38,7 @@ GARAGE_SIGN_REPO ?= "${DEPLOY_DIR_IMAGE}/garage_sign_repo"
38GARAGE_SIGN_KEYNAME ?= "garage-key" 38GARAGE_SIGN_KEYNAME ?= "garage-key"
39GARAGE_TARGET_NAME ?= "${OSTREE_BRANCHNAME}" 39GARAGE_TARGET_NAME ?= "${OSTREE_BRANCHNAME}"
40GARAGE_TARGET_VERSION ?= "" 40GARAGE_TARGET_VERSION ?= ""
41GARAGE_TARGET_URL ?= "https://example.com/" 41GARAGE_TARGET_URL ?= ""
42 42
43SOTA_MACHINE ??="none" 43SOTA_MACHINE ??="none"
44SOTA_MACHINE_rpi ?= "raspberrypi" 44SOTA_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 4ddcf9e..7c57ae5 100644
--- a/classes/sota_m3ulcb.bbclass
+++ b/classes/sota_m3ulcb.bbclass
@@ -6,3 +6,6 @@ IMAGE_BOOT_FILES_sota += "renesas-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 82efe52..8acb976 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 49aa298..5cbf4c0 100644
--- a/classes/sota_raspberrypi.bbclass
+++ b/classes/sota_raspberrypi.bbclass
@@ -3,6 +3,9 @@ RPI_USE_U_BOOT_sota = "1"
3KERNEL_CLASSES_append_sota = " kernel-fitimage" 3KERNEL_CLASSES_append_sota = " kernel-fitimage"
4KERNEL_IMAGETYPE_sota = "fitImage" 4KERNEL_IMAGETYPE_sota = "fitImage"
5 5
6DEV_MATCH_DIRECTIVE_pn-networkd-dhcp-conf = "Driver=smsc95xx lan78xx"
7IMAGE_INSTALL_append_sota = " virtual/network-configuration "
8
6PREFERRED_PROVIDER_virtual/bootloader_sota ?= "u-boot" 9PREFERRED_PROVIDER_virtual/bootloader_sota ?= "u-boot"
7UBOOT_ENTRYPOINT_sota ?= "0x00008000" 10UBOOT_ENTRYPOINT_sota ?= "0x00008000"
8 11
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..de98a09
--- /dev/null
+++ b/lib/oeqa/selftest/cases/updater_native.py
@@ -0,0 +1,43 @@
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_systemd(self):
35 result = get_bb_var('DISTRO_FEATURES').find('systemd')
36 self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES')
37
38 def test_java(self):
39 result = runCmd('which java', ignore_status=True)
40 self.assertEqual(result.status, 0,
41 "Java not found. Do you have a JDK installed on your host machine?")
42
43# 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 07232d7..bad7a87 100644
--- a/lib/oeqa/selftest/cases/updater.py
+++ b/lib/oeqa/selftest/cases/updater_qemux86_64.py
@@ -2,44 +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_systemd(self):
40 result = get_bb_var('DISTRO_FEATURES').find('systemd')
41 self.assertNotEqual(result, -1, 'Feature "systemd" not set at DISTRO_FEATURES')
42
43 def test_credentials(self): 15 def test_credentials(self):
44 logger = logging.getLogger("selftest") 16 logger = logging.getLogger("selftest")
45 logger.info('Running bitbake to build core-image-minimal') 17 logger.info('Running bitbake to build core-image-minimal')
@@ -58,11 +30,6 @@ class GeneralTests(OESelftestTestCase):
58 (deploydir, imagename), ignore_status=True) 30 (deploydir, imagename), ignore_status=True)
59 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)
60 32
61 def test_java(self):
62 result = runCmd('which java', ignore_status=True)
63 self.assertEqual(result.status, 0,
64 "Java not found. Do you have a JDK installed on your host machine?")
65
66 33
67class AktualizrToolsTests(OESelftestTestCase): 34class AktualizrToolsTests(OESelftestTestCase):
68 35
@@ -139,16 +106,6 @@ class AutoProvTests(OESelftestTestCase):
139 value = stdout.decode()[:-1] 106 value = stdout.decode()[:-1]
140 self.assertEqual(value, machine, 107 self.assertEqual(value, machine,
141 'MACHINE does not match hostname: ' + machine + ', ' + value) 108 'MACHINE does not match hostname: ' + machine + ', ' + value)
142 print(value)
143 print('Checking output of aktualizr-info:')
144 ran_ok = False
145 for delay in [1, 2, 5, 10, 15]:
146 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
147 if retcode == 0 and stderr == b'':
148 ran_ok = True
149 break
150 sleep(delay)
151 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
152 109
153 verifyProvisioned(self, machine) 110 verifyProvisioned(self, machine)
154 111
@@ -187,7 +144,7 @@ class ManualControlTests(OESelftestTestCase):
187 """ 144 """
188 sleep(20) 145 sleep(20)
189 stdout, stderr, retcode = self.qemu_command('aktualizr-info') 146 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
190 self.assertIn(b'Can\'t open database', stdout, 147 self.assertIn(b'Can\'t open database', stderr,
191 'Aktualizr should not have run yet' + stderr.decode() + stdout.decode()) 148 'Aktualizr should not have run yet' + stderr.decode() + stdout.decode())
192 149
193 stdout, stderr, retcode = self.qemu_command('aktualizr once') 150 stdout, stderr, retcode = self.qemu_command('aktualizr once')
@@ -197,144 +154,6 @@ class ManualControlTests(OESelftestTestCase):
197 'Aktualizr should have run' + stderr.decode() + stdout.decode()) 154 'Aktualizr should have run' + stderr.decode() + stdout.decode())
198 155
199 156
200class RpiTests(OESelftestTestCase):
201
202 def setUpLocal(self):
203 # Add layers before changing the machine type, otherwise the sanity
204 # checker complains loudly.
205 layer_python = "meta-openembedded/meta-python"
206 layer_rpi = "meta-raspberrypi"
207 layer_upd_rpi = "meta-updater-raspberrypi"
208 result = runCmd('bitbake-layers show-layers')
209 # Assume the directory layout for finding other layers. We could also
210 # make assumptions by using 'show-layers', but either way, if the
211 # layers we need aren't where we expect them, we are out of luck.
212 path = os.path.abspath(os.path.dirname(__file__))
213 metadir = path + "/../../../../../"
214 if re.search(layer_python, result.output) is None:
215 self.meta_python = metadir + layer_python
216 runCmd('bitbake-layers add-layer "%s"' % self.meta_python)
217 else:
218 self.meta_python = None
219 if re.search(layer_rpi, result.output) is None:
220 self.meta_rpi = metadir + layer_rpi
221 runCmd('bitbake-layers add-layer "%s"' % self.meta_rpi)
222 else:
223 self.meta_rpi = None
224 if re.search(layer_upd_rpi, result.output) is None:
225 self.meta_upd_rpi = metadir + layer_upd_rpi
226 runCmd('bitbake-layers add-layer "%s"' % self.meta_upd_rpi)
227 else:
228 self.meta_upd_rpi = None
229
230 # This is trickier that I would've thought. The fundamental problem is
231 # that the qemu layer changes the u-boot file extension to .rom, but
232 # raspberrypi still expects .bin. To prevent this, the qemu layer must
233 # be temporarily removed if it is present. It has to be removed by name
234 # without the complete path, but to add it back when we are done, we
235 # need the full path.
236 p = re.compile(r'meta-updater-qemux86-64\s*(\S*meta-updater-qemux86-64)\s')
237 m = p.search(result.output)
238 if m and m.lastindex > 0:
239 self.meta_qemu = m.group(1)
240 runCmd('bitbake-layers remove-layer meta-updater-qemux86-64')
241 else:
242 self.meta_qemu = None
243
244 self.append_config('MACHINE = "raspberrypi3"')
245 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
246
247 def tearDownLocal(self):
248 if self.meta_qemu:
249 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu, ignore_status=True)
250 if self.meta_upd_rpi:
251 runCmd('bitbake-layers remove-layer "%s"' % self.meta_upd_rpi, ignore_status=True)
252 if self.meta_rpi:
253 runCmd('bitbake-layers remove-layer "%s"' % self.meta_rpi, ignore_status=True)
254 if self.meta_python:
255 runCmd('bitbake-layers remove-layer "%s"' % self.meta_python, ignore_status=True)
256
257 def test_rpi(self):
258 logger = logging.getLogger("selftest")
259 logger.info('Running bitbake to build rpi-basic-image')
260 self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"')
261 bitbake('rpi-basic-image')
262 credentials = get_bb_var('SOTA_PACKED_CREDENTIALS')
263 # Skip the test if the variable SOTA_PACKED_CREDENTIALS is not set.
264 if credentials is None:
265 raise unittest.SkipTest("Variable 'SOTA_PACKED_CREDENTIALS' not set.")
266 # Check if the file exists.
267 self.assertTrue(os.path.isfile(credentials), "File %s does not exist" % credentials)
268 deploydir = get_bb_var('DEPLOY_DIR_IMAGE')
269 imagename = get_bb_var('IMAGE_LINK_NAME', 'rpi-basic-image')
270 # Check if the credentials are included in the output image.
271 result = runCmd('tar -jtvf %s/%s.tar.bz2 | grep sota_provisioning_credentials.zip' %
272 (deploydir, imagename), ignore_status=True)
273 self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
274
275
276class GrubTests(OESelftestTestCase):
277
278 def setUpLocal(self):
279 layer_intel = "meta-intel"
280 layer_minnow = "meta-updater-minnowboard"
281 result = runCmd('bitbake-layers show-layers')
282 # Assume the directory layout for finding other layers. We could also
283 # make assumptions by using 'show-layers', but either way, if the
284 # layers we need aren't where we expect them, we are out of luck.
285 path = os.path.abspath(os.path.dirname(__file__))
286 metadir = path + "/../../../../../"
287 if re.search(layer_intel, result.output) is None:
288 self.meta_intel = metadir + layer_intel
289 runCmd('bitbake-layers add-layer "%s"' % self.meta_intel)
290 else:
291 self.meta_intel = None
292 if re.search(layer_minnow, result.output) is None:
293 self.meta_minnow = metadir + layer_minnow
294 runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow)
295 else:
296 self.meta_minnow = None
297 self.append_config('MACHINE = "intel-corei7-64"')
298 self.append_config('OSTREE_BOOTLOADER = "grub"')
299 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
300 self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64')
301
302 def tearDownLocal(self):
303 qemu_terminate(self.s)
304 if self.meta_intel:
305 runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True)
306 if self.meta_minnow:
307 runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True)
308
309 def qemu_command(self, command):
310 return qemu_send_command(self.qemu.ssh_port, command)
311
312 def test_grub(self):
313 print('Checking machine name (hostname) of device:')
314 stdout, stderr, retcode = self.qemu_command('hostname')
315 self.assertEqual(retcode, 0, "Unable to check hostname. " +
316 "Is an ssh daemon (such as dropbear or openssh) installed on the device?")
317 machine = get_bb_var('MACHINE', 'core-image-minimal')
318 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
319 # Strip off line ending.
320 value = stdout.decode()[:-1]
321 self.assertEqual(value, machine,
322 'MACHINE does not match hostname: ' + machine + ', ' + value +
323 '\nIs TianoCore ovmf installed on your host machine?')
324 print(value)
325 print('Checking output of aktualizr-info:')
326 ran_ok = False
327 for delay in [1, 2, 5, 10, 15]:
328 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
329 if retcode == 0 and stderr == b'':
330 ran_ok = True
331 break
332 sleep(delay)
333 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
334
335 verifyProvisioned(self, machine)
336
337
338class ImplProvTests(OESelftestTestCase): 157class ImplProvTests(OESelftestTestCase):
339 158
340 def setUpLocal(self): 159 def setUpLocal(self):
@@ -375,25 +194,8 @@ class ImplProvTests(OESelftestTestCase):
375 value = stdout.decode()[:-1] 194 value = stdout.decode()[:-1]
376 self.assertEqual(value, machine, 195 self.assertEqual(value, machine,
377 'MACHINE does not match hostname: ' + machine + ', ' + value) 196 'MACHINE does not match hostname: ' + machine + ', ' + value)
378 print(value) 197
379 print('Checking output of aktualizr-info:') 198 verifyNotProvisioned(self, machine)
380 ran_ok = False
381 for delay in [1, 2, 5, 10, 15]:
382 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
383 if retcode == 0 and stderr == b'':
384 ran_ok = True
385 break
386 sleep(delay)
387 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
388 # Verify that device has NOT yet provisioned.
389 self.assertIn(b'Couldn\'t load device ID', stdout,
390 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
391 self.assertIn(b'Couldn\'t load ECU serials', stdout,
392 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
393 self.assertIn(b'Provisioned on server: no', stdout,
394 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
395 self.assertIn(b'Fetched metadata: no', stdout,
396 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
397 199
398 # Run aktualizr-cert-provider. 200 # Run aktualizr-cert-provider.
399 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') 201 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
@@ -450,25 +252,8 @@ class HsmTests(OESelftestTestCase):
450 value = stdout.decode()[:-1] 252 value = stdout.decode()[:-1]
451 self.assertEqual(value, machine, 253 self.assertEqual(value, machine,
452 'MACHINE does not match hostname: ' + machine + ', ' + value) 254 'MACHINE does not match hostname: ' + machine + ', ' + value)
453 print(value) 255
454 print('Checking output of aktualizr-info:') 256 verifyNotProvisioned(self, machine)
455 ran_ok = False
456 for delay in [1, 2, 5, 10, 15]:
457 stdout, stderr, retcode = self.qemu_command('aktualizr-info')
458 if retcode == 0 and stderr == b'':
459 ran_ok = True
460 break
461 sleep(delay)
462 self.assertTrue(ran_ok, 'aktualizr-info failed: ' + stderr.decode() + stdout.decode())
463 # Verify that device has NOT yet provisioned.
464 self.assertIn(b'Couldn\'t load device ID', stdout,
465 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
466 self.assertIn(b'Couldn\'t load ECU serials', stdout,
467 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
468 self.assertIn(b'Provisioned on server: no', stdout,
469 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
470 self.assertIn(b'Fetched metadata: no', stdout,
471 'Device already provisioned!? ' + stderr.decode() + stdout.decode())
472 257
473 # Verify that HSM is not yet initialized. 258 # Verify that HSM is not yet initialized.
474 pkcs11_command = 'pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O' 259 pkcs11_command = 'pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O'
@@ -478,7 +263,7 @@ class HsmTests(OESelftestTestCase):
478 softhsm2_command = 'softhsm2-util --show-slots' 263 softhsm2_command = 'softhsm2-util --show-slots'
479 stdout, stderr, retcode = self.qemu_command(softhsm2_command) 264 stdout, stderr, retcode = self.qemu_command(softhsm2_command)
480 self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' + 265 self.assertNotEqual(retcode, 0, 'softhsm2-tool succeeded before initialization: ' +
481 stdout.decode() + stderr.decode()) 266 stdout.decode() + stderr.decode())
482 267
483 # Run aktualizr-cert-provider. 268 # Run aktualizr-cert-provider.
484 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native') 269 bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
@@ -525,13 +310,6 @@ class HsmTests(OESelftestTestCase):
525 310
526 311
527class SecondaryTests(OESelftestTestCase): 312class SecondaryTests(OESelftestTestCase):
528 @classmethod
529 def setUpClass(cls):
530 super(SecondaryTests, cls).setUpClass()
531 logger = logging.getLogger("selftest")
532 logger.info('Running bitbake to build secondary-image')
533 bitbake('secondary-image')
534
535 def setUpLocal(self): 313 def setUpLocal(self):
536 layer = "meta-updater-qemux86-64" 314 layer = "meta-updater-qemux86-64"
537 result = runCmd('bitbake-layers show-layers') 315 result = runCmd('bitbake-layers show-layers')
@@ -563,20 +341,8 @@ class SecondaryTests(OESelftestTestCase):
563 self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help") 341 self.assertEqual(retcode, 0, "Unable to run aktualizr-secondary --help")
564 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) 342 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
565 343
566 def test_secondary_listening(self):
567 print('Checking aktualizr-secondary service is listening')
568 stdout, stderr, retcode = self.qemu_command('aktualizr-check-discovery')
569 self.assertEqual(retcode, 0, "Unable to connect to secondary")
570
571 344
572class PrimaryTests(OESelftestTestCase): 345class PrimaryTests(OESelftestTestCase):
573 @classmethod
574 def setUpClass(cls):
575 super(PrimaryTests, cls).setUpClass()
576 logger = logging.getLogger("selftest")
577 logger.info('Running bitbake to build primary-image')
578 bitbake('primary-image')
579
580 def setUpLocal(self): 346 def setUpLocal(self):
581 layer = "meta-updater-qemux86-64" 347 layer = "meta-updater-qemux86-64"
582 result = runCmd('bitbake-layers show-layers') 348 result = runCmd('bitbake-layers show-layers')
@@ -610,99 +376,55 @@ class PrimaryTests(OESelftestTestCase):
610 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode()) 376 self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
611 377
612 378
613def qemu_launch(efi=False, machine=None, imagename=None): 379class ResourceControlTests(OESelftestTestCase):
614 logger = logging.getLogger("selftest") 380 def setUpLocal(self):
615 logger.info('Running bitbake to build core-image-minimal') 381 layer = "meta-updater-qemux86-64"
616 bitbake('core-image-minimal') 382 result = runCmd('bitbake-layers show-layers')
617 # Create empty object. 383 if re.search(layer, result.output) is None:
618 args = type('', (), {})() 384 # Assume the directory layout for finding other layers. We could also
619 if imagename: 385 # make assumptions by using 'show-layers', but either way, if the
620 args.imagename = imagename 386 # layers we need aren't where we expect them, we are out of luck.
621 else: 387 path = os.path.abspath(os.path.dirname(__file__))
622 args.imagename = 'core-image-minimal' 388 metadir = path + "/../../../../../"
623 args.mac = None 389 self.meta_qemu = metadir + layer
624 # Could use DEPLOY_DIR_IMAGE here but it's already in the machine 390 runCmd('bitbake-layers add-layer "%s"' % self.meta_qemu)
625 # subdirectory. 391 else:
626 args.dir = 'tmp/deploy/images' 392 self.meta_qemu = None
627 args.efi = efi 393 self.append_config('MACHINE = "qemux86-64"')
628 args.machine = machine 394 self.append_config('SOTA_CLIENT_PROV = " aktualizr-auto-prov "')
629 qemu_use_kvm = get_bb_var("QEMU_USE_KVM") 395 self.append_config('IMAGE_INSTALL_append += " aktualizr-resource-control "')
630 if qemu_use_kvm and \ 396 self.append_config('RESOURCE_CPU_WEIGHT_pn-aktualizr = "1000"')
631 (qemu_use_kvm == 'True' and 'x86' in machine or \ 397 self.append_config('RESOURCE_MEMORY_HIGH_pn-aktualizr = "50M"')
632 get_bb_var('MACHINE') in qemu_use_kvm.split()): 398 self.append_config('RESOURCE_MEMORY_MAX_pn-aktualizr = "1M"')
633 args.kvm = True 399 self.qemu, self.s = qemu_launch(machine='qemux86-64')
634 else: 400
635 args.kvm = None # Autodetect 401 def tearDownLocal(self):
636 args.no_gui = True 402 qemu_terminate(self.s)
637 args.gdb = False 403 if self.meta_qemu:
638 args.pcap = None 404 runCmd('bitbake-layers remove-layer "%s"' % self.meta_qemu, ignore_status=True)
639 args.overlay = None 405
640 args.dry_run = False 406 def qemu_command(self, command):
641 args.secondary_network = False 407 return qemu_send_command(self.qemu.ssh_port, command)
642 408
643 qemu = QemuCommand(args) 409 def test_aktualizr_resource_control(self):
644 cmdline = qemu.command_line() 410 print('Checking aktualizr was killed')
645 print('Booting image with run-qemu-ota...') 411 ran_ok = False
646 s = subprocess.Popen(cmdline) 412 for delay in [5, 5, 5, 5]:
647 sleep(10) 413 sleep(delay)
648 return qemu, s 414 stdout, stderr, retcode = self.qemu_command('systemctl --no-pager show aktualizr')
649 415 if retcode == 0 and b'ExecMainStatus=9' in stdout:
650 416 ran_ok = True
651def qemu_terminate(s): 417 break
652 try: 418 self.assertTrue(ran_ok, 'Aktualizr was not killed')
653 s.terminate() 419
654 except KeyboardInterrupt: 420 self.assertIn(b'CPUWeight=1000', stdout, 'CPUWeight was not set correctly')
655 pass 421 self.assertIn(b'MemoryHigh=52428800', stdout, 'MemoryHigh was not set correctly')
656 422 self.assertIn(b'MemoryMax=1048576', stdout, 'MemoryMax was not set correctly')
657 423
658def qemu_send_command(port, command): 424 self.qemu_command('systemctl --runtime set-property aktualizr MemoryMax=')
659 command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' + 425 self.qemu_command('systemctl restart aktualizr')
660 str(port) + ' "' + command + '"']
661 s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
662 stdout, stderr = s2.communicate(timeout=60)
663 return stdout, stderr, s2.returncode
664
665
666def akt_native_run(testInst, cmd, **kwargs):
667 # run a command supplied by aktualizr-native and checks that:
668 # - the executable exists
669 # - the command runs without error
670 # NOTE: the base test class must have built aktualizr-native (in
671 # setUpClass, for example)
672 bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'base_prefix', 'libdir', 'bindir'],
673 'aktualizr-native')
674 sysroot = bb_vars['SYSROOT_DESTDIR'] + bb_vars['base_prefix']
675 sysrootbin = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir']
676 libdir = bb_vars['libdir']
677
678 program, *_ = cmd.split(' ')
679 p = '{}/{}'.format(sysrootbin, program)
680 testInst.assertTrue(os.path.isfile(p), msg="No {} found ({})".format(program, p))
681 env = dict(os.environ)
682 env['LD_LIBRARY_PATH'] = libdir
683 result = runCmd(cmd, env=env, native_sysroot=sysroot, ignore_status=True, **kwargs)
684 testInst.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output)
685
686
687def verifyProvisioned(testInst, machine):
688 # Verify that device HAS provisioned.
689 ran_ok = False
690 for delay in [5, 5, 5, 5, 10, 10, 10, 10]:
691 stdout, stderr, retcode = testInst.qemu_command('aktualizr-info')
692 if retcode == 0 and stderr == b'' and stdout.decode().find('Fetched metadata: yes') >= 0:
693 ran_ok = True
694 break
695 sleep(delay)
696 testInst.assertIn(b'Device ID: ', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
697 testInst.assertIn(b'Primary ecu hardware ID: ' + machine.encode(), stdout,
698 'Provisioning failed: ' + stderr.decode() + stdout.decode())
699 testInst.assertIn(b'Fetched metadata: yes', stdout, 'Provisioning failed: ' + stderr.decode() + stdout.decode())
700 p = re.compile(r'Device ID: ([a-z0-9-]*)\n')
701 m = p.search(stdout.decode())
702 testInst.assertTrue(m, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
703 testInst.assertGreater(m.lastindex, 0, 'Device ID could not be read: ' + stderr.decode() + stdout.decode())
704 logger = logging.getLogger("selftest")
705 logger.info('Device successfully provisioned with ID: ' + m.group(1))
706 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')
707 429
708# 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..0f0f491
--- /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
45 has_failure = re.search('^FAIL', output, flags=re.MULTILINE) is not None
46 if has_failure:
47 print("Full test suite log:")
48 stdout, _, _ = self.qemu_command('cat /tmp/aktualizr-ptest.log || cat /tmp/aktualizr-ptest.log.tmp', timeout=None)
49 print(stdout.decode())
50
51 self.assertEqual(retcode, 0)
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..1cab2b8
--- /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 rpi-basic-image')
71 self.append_config('SOTA_CLIENT_PROV = "aktualizr-auto-prov"')
72 bitbake('rpi-basic-image')
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', 'rpi-basic-image')
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 be12a59..3e4c208 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', True) == '1' else ''}" 11RDEPENDS_${PN}_append = "${@' aktualizr-auto-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '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 5893ed2..0d1c860 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', True) == '1' else ''}" 12RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}"
14 13
diff --git a/recipes-sota/aktualizr/aktualizr-hsm-prov.bb b/recipes-sota/aktualizr/aktualizr-hsm-prov.bb
index dfe397c..f738f3e 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', True) == '1' else ''}" 11RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds softhsm-testtoken' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '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 6702d29..ed1e3a8 100644
--- a/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb
+++ b/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb
@@ -3,6 +3,9 @@ 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
diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb
index fef12b8..a49095a 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-misc python3-modules 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} -Dgtest_disable_pthreads=ON" 50EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV} -Dgtest_disable_pthreads=ON ${@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,36 @@ 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 bbnote VERBOSE=1 cmake --build '${B}' --target build_tests -- ${EXTRA_OECMAKE_BUILD} ${PARALLEL_MAKE}
76 VERBOSE=1 cmake --build '${B}' --target build_tests -- ${EXTRA_OECMAKE_BUILD} ${PARALLEL_MAKE}
77}
78
79do_install_ptest() {
80 # copy the complete source directory (contains build)
81 cp -r ${B}/ ${D}/${PTEST_PATH}/build
82 cp -r ${S}/ ${D}/${PTEST_PATH}/src
83
84 # remove huge external unused repository
85 rm -rf ${D}/${PTEST_PATH}/src/partial/extern/RIOT
86
87 # remove huge build artifacts
88 find ${D}/${PTEST_PATH}/build/src -name "*.a" -delete
89
90 # fix the absolute paths
91 find ${D}/${PTEST_PATH}/build -name "CMakeFiles" | xargs rm -rf
92 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
93}
94
54do_install_append () { 95do_install_append () {
55 install -d ${D}${libdir}/sota 96 install -d ${D}${libdir}/sota
56 install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml 97 install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml
@@ -66,14 +107,14 @@ do_install_append () {
66 install -m 0700 -d ${D}${sysconfdir}/sota/conf.d 107 install -m 0700 -d ${D}${sysconfdir}/sota/conf.d
67 108
68 if [ -n "${SOTA_HARDWARE_ID}" ]; then 109 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 110 printf "[provision]\nprimary_ecu_hardware_id = ${SOTA_HARDWARE_ID}\n" > ${D}${libdir}/sota/conf.d/40-hardware-id.toml
70 fi 111 fi
71 112
72 if [ -n "${SOTA_SECONDARY_CONFIG_DIR}" ]; then 113 if [ -n "${SOTA_SECONDARY_CONFIG_DIR}" ]; then
73 if [ -d "${SOTA_SECONDARY_CONFIG_DIR}" ]; then 114 if [ -d "${SOTA_SECONDARY_CONFIG_DIR}" ]; then
74 install -m 0700 -d ${D}${sysconfdir}/sota/ecus 115 install -m 0700 -d ${D}${sysconfdir}/sota/ecus
75 install -m 0644 "${SOTA_SECONDARY_CONFIG_DIR}"/* ${D}${sysconfdir}/sota/ecus/ 116 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 117 printf "[uptane]\nsecondary_configs_dir = /etc/sota/ecus/\n" > ${D}${libdir}/sota/conf.d/30-secondary-configs-dir.toml
77 else 118 else
78 bbwarn "SOTA_SECONDARY_CONFIG_DIR is set to an invalid directory (${SOTA_SECONDARY_CONFIG_DIR})" 119 bbwarn "SOTA_SECONDARY_CONFIG_DIR is set to an invalid directory (${SOTA_SECONDARY_CONFIG_DIR})"
79 fi 120 fi
@@ -87,6 +128,15 @@ do_install_append () {
87 install -m 0755 ${B}/src/sota_tools/garage-sign/bin/* ${D}${bindir} 128 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} 129 install -m 0644 ${B}/src/sota_tools/garage-sign/lib/* ${D}${libdir}
89 fi 130 fi
131
132 # resource control
133 install -d ${D}/${systemd_system_unitdir}/aktualizr.service.d
134 install -m 0644 ${WORKDIR}/10-resource-control.conf ${D}/${systemd_system_unitdir}/aktualizr.service.d
135
136 sed -i -e 's|@CPU_WEIGHT@|${RESOURCE_CPU_WEIGHT}|g' \
137 -e 's|@MEMORY_HIGH@|${RESOURCE_MEMORY_HIGH}|g' \
138 -e 's|@MEMORY_MAX@|${RESOURCE_MEMORY_MAX}|g' \
139 ${D}${systemd_system_unitdir}/aktualizr.service.d/10-resource-control.conf
90} 140}
91 141
92PACKAGESPLITFUNCS_prepend = "split_hosttools_packages " 142PACKAGESPLITFUNCS_prepend = "split_hosttools_packages "
@@ -101,7 +151,7 @@ python split_hosttools_packages () {
101 151
102PACKAGES_DYNAMIC = "^aktualizr-.* ^garage-.*" 152PACKAGES_DYNAMIC = "^aktualizr-.* ^garage-.*"
103 153
104PACKAGES =+ "${PN}-examples ${PN}-secondary ${PN}-configs ${PN}-host-tools" 154PACKAGES =+ "${PN}-resource-control ${PN}-examples ${PN}-secondary ${PN}-configs ${PN}-host-tools"
105 155
106ALLOW_EMPTY_${PN}-host-tools = "1" 156ALLOW_EMPTY_${PN}-host-tools = "1"
107 157
@@ -111,6 +161,10 @@ FILES_${PN} = " \
111 ${systemd_unitdir}/system/aktualizr.service \ 161 ${systemd_unitdir}/system/aktualizr.service \
112 " 162 "
113 163
164FILES_${PN}-resource-control = " \
165 ${systemd_system_unitdir}/aktualizr.service.d/10-resource-control.conf \
166 "
167
114FILES_${PN}-configs = " \ 168FILES_${PN}-configs = " \
115 ${sysconfdir}/sota/* \ 169 ${sysconfdir}/sota/* \
116 ${libdir}/sota/* \ 170 ${libdir}/sota/* \
@@ -126,6 +180,7 @@ FILES_${PN}-secondary = " \
126 ${systemd_unitdir}/system/aktualizr-secondary.socket \ 180 ${systemd_unitdir}/system/aktualizr-secondary.socket \
127 ${systemd_unitdir}/system/aktualizr-secondary.service \ 181 ${systemd_unitdir}/system/aktualizr-secondary.service \
128 " 182 "
183
129BBCLASSEXTEND = "native" 184BBCLASSEXTEND = "native"
130 185
131# vim:set ts=4 sw=4 sts=4 expandtab: 186# 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 1b89a3d..0000000
--- a/recipes-sota/aktualizr/garage-sign-version.inc
+++ /dev/null
@@ -1,36 +0,0 @@
1
2python () {
3 if d.getVar("GARAGE_SIGN_VERSION", True) or not d.getVar("SOTA_PACKED_CREDENTIALS", True):
4 return
5 import json
6 import urllib.request
7 import zipfile
8 with zipfile.ZipFile(d.getVar("SOTA_PACKED_CREDENTIALS", True), '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-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 ee8088b..e7f3e75 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") + ".otaimg"
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("DEPLOY_DIR_IMAGE")
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") + ".otaimg" 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 86362f7..9b21a66 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",