diff options
27 files changed, 275 insertions, 243 deletions
diff --git a/COPYING.MIT b/COPYING.MIT new file mode 100644 index 0000000..fb950dc --- /dev/null +++ b/COPYING.MIT | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 2 | of this software and associated documentation files (the "Software"), to deal | ||
| 3 | in the Software without restriction, including without limitation the rights | ||
| 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 5 | copies of the Software, and to permit persons to whom the Software is | ||
| 6 | furnished to do so, subject to the following conditions: | ||
| 7 | |||
| 8 | The above copyright notice and this permission notice shall be included in | ||
| 9 | all copies or substantial portions of the Software. | ||
| 10 | |||
| 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 17 | THE SOFTWARE. | ||
diff --git a/README.adoc b/README.adoc index b4608d5..0917e45 100644 --- a/README.adoc +++ b/README.adoc | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | = meta-updater | 1 | = meta-updater |
| 2 | 2 | ||
| 3 | This layer enables over-the-air updates (OTA) with https://github.com/ostreedev/ostree[OSTree] and https://github.com/advancedtelematic/rvi_sota_client[RVI SOTA client]. | 3 | This layer enables over-the-air updates (OTA) with https://github.com/ostreedev/ostree[OSTree] and https://github.com/advancedtelematic/aktualizr[Aktualizr]. |
| 4 | 4 | ||
| 5 | https://github.com/ostreedev/ostree[OSTree] is a tool for atomic full file system upgrades with rollback capability. OSTree has several advantages over traditional dual-bank systems, but the most important one is that it minimizes network bandwidth and data storage footprint by sharing files with the same contents across file system deployments. | 5 | https://github.com/ostreedev/ostree[OSTree] is a tool for atomic full file system upgrades with rollback capability. OSTree has several advantages over traditional dual-bank systems, but the most important one is that it minimizes network bandwidth and data storage footprint by sharing files with the same contents across file system deployments. |
| 6 | 6 | ||
| 7 | https://github.com/advancedtelematic/rvi_sota_client[RVI SOTA client] and/or https://github.com/advancedtelematic/aktualizr[aktualizr] add authentication and provisioning capabilities to OTA and are integrated with OSTree. You can connect with the open-source https://github.com/advancedtelematic/rvi_sota_server[RVI SOTA server] or sign up for a free account at https://app.atsgarage.com[ATS Garage] to get started. | 7 | https://github.com/advancedtelematic/aktualizr[Aktualizr] (and https://github.com/advancedtelematic/rvi_sota_client[RVI SOTA client]) add authentication and provisioning capabilities to OTA and are integrated with OSTree. You can connect with the open-source https://github.com/advancedtelematic/rvi_sota_server[RVI SOTA server] or sign up for a free account at https://app.atsgarage.com[ATS Garage] to get started. |
| 8 | 8 | ||
| 9 | == Build | 9 | == Build |
| 10 | 10 | ||
| @@ -22,8 +22,6 @@ If you already have a Yocto-based project and you want to add atomic filesystem | |||
| 22 | 22 | ||
| 23 | You can then build your image as usual, with bitbake. After building the root file system, bitbake will then create an https://ostree.readthedocs.io/en/latest/manual/adapting-existing/[OSTree-enabled version] of it, commit it to your local OSTree repo and (optionally) push it to a remote server. Additionally, a live disk image will be created (normally named $\{IMAGE_NAME}.-sdimg-ota e.g. core-image-raspberrypi3.rpi-sdimg-ota). You can control this behaviour through <<variables in your local.conf,OSTree-related variables in your local.conf>>. | 23 | You can then build your image as usual, with bitbake. After building the root file system, bitbake will then create an https://ostree.readthedocs.io/en/latest/manual/adapting-existing/[OSTree-enabled version] of it, commit it to your local OSTree repo and (optionally) push it to a remote server. Additionally, a live disk image will be created (normally named $\{IMAGE_NAME}.-sdimg-ota e.g. core-image-raspberrypi3.rpi-sdimg-ota). You can control this behaviour through <<variables in your local.conf,OSTree-related variables in your local.conf>>. |
| 24 | 24 | ||
| 25 | === Build with OpenIVI | ||
| 26 | |||
| 27 | === Build in AGL | 25 | === Build in AGL |
| 28 | 26 | ||
| 29 | With AGL you can just add agl-sota feature while configuring your build environment: | 27 | With AGL you can just add agl-sota feature while configuring your build environment: |
| @@ -67,11 +65,15 @@ Although we have used U-Boot so far, other boot loaders can be configured work w | |||
| 67 | 65 | ||
| 68 | == SOTA-related variables in local.conf | 66 | == SOTA-related variables in local.conf |
| 69 | 67 | ||
| 70 | * OSTREE_REPO - path to your OSTree repository. Defaults to "$\{DEPLOY_DIR_IMAGE}/ostree_repo" | 68 | * `OSTREE_REPO` - path to your OSTree repository. Defaults to `$\{DEPLOY_DIR_IMAGE}/ostree_repo` |
| 71 | * OSTREE_BRANCHNAME - the branch your rootfs will be committed to. Defaults to "ota" | 69 | * `OSTREE_OSNAME` - OS deployment name on your target device. For more information about deployments and osnames see the https://ostree.readthedocs.io/en/latest/manual/deployment/[OSTree documentation]. Defaults to "poky". |
| 72 | * OSTREE_OSNAME - OS deployment name on your target device. For more information about deployments and osnames see the https://ostree.readthedocs.io/en/latest/manual/deployment/[OSTree documentation]. Defaults to "poky". | 70 | * `OSTREE_INITRAMFS_IMAGE` - initramfs/initrd image that is used as a proxy while booting into OSTree deployment. Do not change this setting unless you are sure that your initramfs can serve as such a proxy. |
| 73 | * OSTREE_INITRAMFS_IMAGE - initramfs/initrd image that is used as a proxy while booting into OSTree deployment. Do not change this setting unless you are sure that your initramfs can serve as such a proxy. | 71 | * `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]. |
| 74 | * 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 JSON credentials file in https://github.com/advancedtelematic/sota-tools#credentials[the format accepted by garage-push]. | 72 | * `SOTA_CLIENT_PROV` - which provisioning method to use. Valid options are https://github.com/advancedtelematic/aktualizr/blob/master/docs/automatic-provisioning.adoc[`aktualizr-auto-prov`], https://github.com/advancedtelematic/aktualizr/blob/master/docs/implicit-provisioning.adoc[`aktualizr-implicit-prov`], and `aktualizr-hsm-test-prov`. The default is `aktualizr-auto-prov`. This can also be set to an empty string to avoid using a provisioning recipe. |
| 73 | * `SOTA_CLIENT_FEATURES` - extensions to aktualizr. Multiple can be specified if separated by spaces. Valid options are `hsm` (to build with HSM support) and `secondary-example` (to install an example https://github.com/advancedtelematic/aktualizr/blob/master/docs/legacysecondary.adoc[legacy secondary interface] in the image). | ||
| 74 | * `SOTA_LEGACY_SECONDARY_INTERFACE` - path to a legacy secondary interface installed on the device. To use the example interface from the Aktualizr repo, use `/usr/bin/example-interface` and make sure `SOTA_CLIENT_FEATURES = "secondary-example"`. | ||
| 75 | * `SOTA_SECONDARY_ECUS` - a list of paths separated by spaces of JSON configuration files for virtual secondaries on the host. These will be installed into `/var/sota/ecus` on the device. | ||
| 76 | * `SOTA_VIRTUAL_SECONDARIES` - a list of paths separated by spaces of JSON configuration files for virtual secondaries installed on the device. If `SOTA_SECONDARY_ECUS` is used to install them, then you can expect them to be installed in `/var/sota/ecus`. | ||
| 75 | 77 | ||
| 76 | == Usage | 78 | == Usage |
| 77 | 79 | ||
diff --git a/classes/image_repo_manifest.bbclass b/classes/image_repo_manifest.bbclass index 7f41a97..467fd9a 100644 --- a/classes/image_repo_manifest.bbclass +++ b/classes/image_repo_manifest.bbclass | |||
| @@ -16,7 +16,7 @@ buildinfo () { | |||
| 16 | if [ $(which repo) ]; then | 16 | if [ $(which repo) ]; then |
| 17 | repo manifest --revision-as-HEAD -o ${IMAGE_ROOTFS}${sysconfdir}/manifest.xml || bbwarn "Android repo tool failed to run; manifest not copied" | 17 | repo manifest --revision-as-HEAD -o ${IMAGE_ROOTFS}${sysconfdir}/manifest.xml || bbwarn "Android repo tool failed to run; manifest not copied" |
| 18 | else | 18 | else |
| 19 | bbwarn "Android repo tool not food; manifest not copied." | 19 | bbwarn "Android repo tool not found; manifest not copied." |
| 20 | fi | 20 | fi |
| 21 | } | 21 | } |
| 22 | 22 | ||
diff --git a/classes/image_types_ostree.bbclass b/classes/image_types_ostree.bbclass index e6bea76..f350449 100644 --- a/classes/image_types_ostree.bbclass +++ b/classes/image_types_ostree.bbclass | |||
| @@ -119,6 +119,7 @@ IMAGE_CMD_ostree () { | |||
| 119 | fi | 119 | fi |
| 120 | 120 | ||
| 121 | if [ -n "${SOTA_SECONDARY_ECUS}" ]; then | 121 | if [ -n "${SOTA_SECONDARY_ECUS}" ]; then |
| 122 | mkdir -p var/sota/ecus | ||
| 122 | cp ${SOTA_SECONDARY_ECUS} var/sota/ecus | 123 | cp ${SOTA_SECONDARY_ECUS} var/sota/ecus |
| 123 | fi | 124 | fi |
| 124 | 125 | ||
| @@ -179,11 +180,11 @@ IMAGE_CMD_ostreepush () { | |||
| 179 | } | 180 | } |
| 180 | 181 | ||
| 181 | IMAGE_TYPEDEP_garagesign = "ostreepush" | 182 | IMAGE_TYPEDEP_garagesign = "ostreepush" |
| 182 | do_image_ostreepush[depends] += "garage-sign-native:do_populate_sysroot" | 183 | do_image_garage_sign[depends] += "aktualizr-native:do_populate_sysroot" |
| 183 | IMAGE_CMD_garagesign () { | 184 | IMAGE_CMD_garagesign () { |
| 184 | if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then | 185 | if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then |
| 185 | # if credentials are issued by a server that doesn't support offline signing, exit silently | 186 | # if credentials are issued by a server that doesn't support offline signing, exit silently |
| 186 | unzip -p ${SOTA_PACKED_CREDENTIALS} root.json targets.pub targets.sec 2>&1 >/dev/null || exit 0 | 187 | unzip -p ${SOTA_PACKED_CREDENTIALS} root.json targets.pub targets.sec tufrepo.url 2>&1 >/dev/null || exit 0 |
| 187 | 188 | ||
| 188 | java_version=$( java -version 2>&1 | awk -F '"' '/version/ {print $2}' ) | 189 | java_version=$( java -version 2>&1 | awk -F '"' '/version/ {print $2}' ) |
| 189 | if [ "${java_version}" = "" ]; then | 190 | if [ "${java_version}" = "" ]; then |
| @@ -194,15 +195,8 @@ IMAGE_CMD_garagesign () { | |||
| 194 | exit 1 | 195 | exit 1 |
| 195 | fi | 196 | fi |
| 196 | 197 | ||
| 197 | if [ ! -d "${GARAGE_SIGN_REPO}" ]; then | 198 | rm -rf ${GARAGE_SIGN_REPO} |
| 198 | garage-sign init --repo ${GARAGE_SIGN_REPO} --home-dir ${GARAGE_SIGN_REPO} --credentials ${SOTA_PACKED_CREDENTIALS} | 199 | garage-sign init --repo tufrepo --home-dir ${GARAGE_SIGN_REPO} --credentials ${SOTA_PACKED_CREDENTIALS} |
| 199 | fi | ||
| 200 | |||
| 201 | if [ -n "${GARAGE_SIGN_REPOSERVER}" ]; then | ||
| 202 | reposerver_args="--reposerver ${GARAGE_SIGN_REPOSERVER}" | ||
| 203 | else | ||
| 204 | reposerver_args="" | ||
| 205 | fi | ||
| 206 | 200 | ||
| 207 | ostree_target_hash=$(cat ${OSTREE_REPO}/refs/heads/${OSTREE_BRANCHNAME}) | 201 | ostree_target_hash=$(cat ${OSTREE_REPO}/refs/heads/${OSTREE_BRANCHNAME}) |
| 208 | 202 | ||
| @@ -210,11 +204,11 @@ IMAGE_CMD_garagesign () { | |||
| 210 | # in which case targets.json should be pulled again and the whole procedure repeated | 204 | # in which case targets.json should be pulled again and the whole procedure repeated |
| 211 | push_success=0 | 205 | push_success=0 |
| 212 | for push_retries in $( seq 3 ); do | 206 | for push_retries in $( seq 3 ); do |
| 213 | garage-sign targets pull --repo ${GARAGE_SIGN_REPO} --home-dir ${GARAGE_SIGN_REPO} ${reposerver_args} | 207 | garage-sign targets pull --repo tufrepo --home-dir ${GARAGE_SIGN_REPO} |
| 214 | garage-sign targets add --repo ${GARAGE_SIGN_REPO} --home-dir ${GARAGE_SIGN_REPO} --name ${OSTREE_BRANCHNAME} --format OSTREE --version ${OSTREE_BRANCHNAME} --length 0 --url "https://example.com/" --sha256 ${ostree_target_hash} --hardwareids ${MACHINE} | 208 | garage-sign targets add --repo tufrepo --home-dir ${GARAGE_SIGN_REPO} --name ${OSTREE_BRANCHNAME} --format OSTREE --version ${ostree_target_hash} --length 0 --url "https://example.com/" --sha256 ${ostree_target_hash} --hardwareids ${MACHINE} |
| 215 | garage-sign targets sign --repo ${GARAGE_SIGN_REPO} --home-dir ${GARAGE_SIGN_REPO} --key-name=targets | 209 | garage-sign targets sign --repo tufrepo --home-dir ${GARAGE_SIGN_REPO} --key-name=targets |
| 216 | errcode=0 | 210 | errcode=0 |
| 217 | garage-sign targets push --repo ${GARAGE_SIGN_REPO} --home-dir ${GARAGE_SIGN_REPO} ${reposerver_args} || errcode=$? | 211 | garage-sign targets push --repo tufrepo --home-dir ${GARAGE_SIGN_REPO} || errcode=$? |
| 218 | if [ "$errcode" -eq "0" ]; then | 212 | if [ "$errcode" -eq "0" ]; then |
| 219 | push_success=1 | 213 | push_success=1 |
| 220 | break | 214 | break |
| @@ -227,9 +221,20 @@ IMAGE_CMD_garagesign () { | |||
| 227 | bberror "Couldn't push to garage repository" | 221 | bberror "Couldn't push to garage repository" |
| 228 | exit 1 | 222 | exit 1 |
| 229 | fi | 223 | fi |
| 230 | else | ||
| 231 | bbwarn "SOTA_PACKED_CREDENTIALS not set. Please add SOTA_PACKED_CREDENTIALS." | ||
| 232 | fi | 224 | fi |
| 233 | } | 225 | } |
| 234 | 226 | ||
| 227 | IMAGE_TYPEDEP_garagecheck = "ostreepush garagesign" | ||
| 228 | do_image_garagecheck[depends] += "aktualizr-native:do_populate_sysroot" | ||
| 229 | IMAGE_CMD_garagecheck () { | ||
| 230 | if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then | ||
| 231 | # if credentials are issued by a server that doesn't support offline signing, exit silently | ||
| 232 | unzip -p ${SOTA_PACKED_CREDENTIALS} root.json targets.pub targets.sec tufrepo.url 2>&1 >/dev/null || exit 0 | ||
| 233 | ostree_target_hash=$(cat ${OSTREE_REPO}/refs/heads/${OSTREE_BRANCHNAME}) | ||
| 234 | |||
| 235 | garage-check --ref=${ostree_target_hash} \ | ||
| 236 | --credentials=${SOTA_PACKED_CREDENTIALS} \ | ||
| 237 | --cacert=${STAGING_ETCDIR_NATIVE}/ssl/certs/ca-certificates.crt | ||
| 238 | fi | ||
| 239 | } | ||
| 235 | # vim:set ts=4 sw=4 sts=4 expandtab: | 240 | # vim:set ts=4 sw=4 sts=4 expandtab: |
diff --git a/classes/image_types_ota.bbclass b/classes/image_types_ota.bbclass index b15178a..b827444 100644 --- a/classes/image_types_ota.bbclass +++ b/classes/image_types_ota.bbclass | |||
| @@ -85,14 +85,16 @@ IMAGE_CMD_otaimg () { | |||
| 85 | bberror "Invalid bootloader: ${OSTREE_BOOTLOADER}" | 85 | bberror "Invalid bootloader: ${OSTREE_BOOTLOADER}" |
| 86 | fi; | 86 | fi; |
| 87 | 87 | ||
| 88 | ostree --repo=${PHYS_SYSROOT}/ostree/repo pull-local --remote=${OSTREE_OSNAME} ${OSTREE_REPO} ${OSTREE_BRANCHNAME} | 88 | ostree_target_hash=$(cat ${OSTREE_REPO}/refs/heads/${OSTREE_BRANCHNAME}) |
| 89 | |||
| 90 | ostree --repo=${PHYS_SYSROOT}/ostree/repo pull-local --remote=${OSTREE_OSNAME} ${OSTREE_REPO} ${ostree_target_hash} | ||
| 89 | export OSTREE_BOOT_PARTITION="/boot" | 91 | export OSTREE_BOOT_PARTITION="/boot" |
| 90 | kargs_list="" | 92 | kargs_list="" |
| 91 | for arg in ${OSTREE_KERNEL_ARGS}; do | 93 | for arg in ${OSTREE_KERNEL_ARGS}; do |
| 92 | kargs_list="${kargs_list} --karg-append=$arg" | 94 | kargs_list="${kargs_list} --karg-append=$arg" |
| 93 | done | 95 | done |
| 94 | 96 | ||
| 95 | ostree admin --sysroot=${PHYS_SYSROOT} deploy ${kargs_list} --os=${OSTREE_OSNAME} ${OSTREE_BRANCHNAME} | 97 | ostree admin --sysroot=${PHYS_SYSROOT} deploy ${kargs_list} --os=${OSTREE_OSNAME} ${ostree_target_hash} |
| 96 | 98 | ||
| 97 | # Copy deployment /home and /var/sota to sysroot | 99 | # Copy deployment /home and /var/sota to sysroot |
| 98 | HOME_TMP=`mktemp -d ${WORKDIR}/home-tmp-XXXXX` | 100 | HOME_TMP=`mktemp -d ${WORKDIR}/home-tmp-XXXXX` |
diff --git a/classes/sota.bbclass b/classes/sota.bbclass index f5a42c1..bbb9ac9 100644 --- a/classes/sota.bbclass +++ b/classes/sota.bbclass | |||
| @@ -11,10 +11,10 @@ SOTA_CLIENT ??= "aktualizr" | |||
| 11 | SOTA_CLIENT_PROV ??= "aktualizr-auto-prov" | 11 | SOTA_CLIENT_PROV ??= "aktualizr-auto-prov" |
| 12 | IMAGE_INSTALL_append_sota = " ostree os-release ${SOTA_CLIENT} ${SOTA_CLIENT_PROV}" | 12 | IMAGE_INSTALL_append_sota = " ostree os-release ${SOTA_CLIENT} ${SOTA_CLIENT_PROV}" |
| 13 | IMAGE_CLASSES += " image_types_ostree image_types_ota" | 13 | IMAGE_CLASSES += " image_types_ostree image_types_ota" |
| 14 | IMAGE_FSTYPES += "${@bb.utils.contains('DISTRO_FEATURES', 'sota', 'ostreepush garagesign otaimg wic', ' ', d)}" | 14 | IMAGE_FSTYPES += "${@bb.utils.contains('DISTRO_FEATURES', 'sota', 'ostreepush garagesign garagecheck otaimg wic', ' ', d)}" |
| 15 | 15 | ||
| 16 | PACKAGECONFIG_append_pn-curl = "${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', " ssl", " ", d)}" | 16 | PACKAGECONFIG_append_pn-curl = " ssl" |
| 17 | PACKAGECONFIG_remove_pn-curl = "${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', " gnutls", " ", d)}" | 17 | PACKAGECONFIG_remove_pn-curl = "gnutls" |
| 18 | 18 | ||
| 19 | WKS_FILE_sota ?= "sdimage-sota.wks" | 19 | WKS_FILE_sota ?= "sdimage-sota.wks" |
| 20 | 20 | ||
diff --git a/lib/oeqa/selftest/updater.py b/lib/oeqa/selftest/updater.py index ad99964..f28349f 100644 --- a/lib/oeqa/selftest/updater.py +++ b/lib/oeqa/selftest/updater.py | |||
| @@ -31,27 +31,17 @@ class SotaToolsTests(oeSelfTest): | |||
| 31 | result = runCmd('%s --help' % p, ignore_status=True) | 31 | result = runCmd('%s --help' % p, ignore_status=True) |
| 32 | self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) | 32 | self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) |
| 33 | 33 | ||
| 34 | 34 | def test_garagesign_help(self): | |
| 35 | class GarageSignTests(oeSelfTest): | 35 | bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'aktualizr-native') |
| 36 | |||
| 37 | @classmethod | ||
| 38 | def setUpClass(cls): | ||
| 39 | logger = logging.getLogger("selftest") | ||
| 40 | logger.info('Running bitbake to build garage-sign-native') | ||
| 41 | bitbake('garage-sign-native') | ||
| 42 | |||
| 43 | def test_help(self): | ||
| 44 | bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'garage-sign-native') | ||
| 45 | p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/" + "garage-sign" | 36 | p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/" + "garage-sign" |
| 46 | self.assertTrue(os.path.isfile(p), msg = "No garage-sign found (%s)" % p) | 37 | self.assertTrue(os.path.isfile(p), msg = "No garage-sign found (%s)" % p) |
| 47 | result = runCmd('%s --help' % p, ignore_status=True) | 38 | result = runCmd('%s --help' % p, ignore_status=True) |
| 48 | self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) | 39 | self.assertEqual(result.status, 0, "Status not equal to 0. output: %s" % result.output) |
| 49 | 40 | ||
| 50 | |||
| 51 | class HsmTests(oeSelfTest): | 41 | class HsmTests(oeSelfTest): |
| 52 | 42 | ||
| 53 | def test_hsm(self): | 43 | def test_hsm(self): |
| 54 | self.write_config('SOTA_CLIENT_FEATURES="hsm hsm-test"') | 44 | self.write_config('SOTA_CLIENT_FEATURES="hsm"') |
| 55 | bitbake('core-image-minimal') | 45 | bitbake('core-image-minimal') |
| 56 | 46 | ||
| 57 | 47 | ||
| @@ -118,49 +108,16 @@ class QemuTests(oeSelfTest): | |||
| 118 | 108 | ||
| 119 | @classmethod | 109 | @classmethod |
| 120 | def setUpClass(cls): | 110 | def setUpClass(cls): |
| 121 | logger = logging.getLogger("selftest") | 111 | cls.qemu, cls.s = qemu_launch(machine='qemux86-64') |
| 122 | logger.info('Running bitbake to build core-image-minimal') | ||
| 123 | bitbake('core-image-minimal') | ||
| 124 | # Create empty object. | ||
| 125 | args = type('', (), {})() | ||
| 126 | args.imagename = 'core-image-minimal' | ||
| 127 | args.mac = None | ||
| 128 | # Could use DEPLOY_DIR_IMAGE here but it's already in the machine | ||
| 129 | # subdirectory. | ||
| 130 | args.dir = 'tmp/deploy/images' | ||
| 131 | args.efi = False | ||
| 132 | args.machine = None | ||
| 133 | args.kvm = None # Autodetect | ||
| 134 | args.no_gui = True | ||
| 135 | args.gdb = False | ||
| 136 | args.pcap = None | ||
| 137 | args.overlay = None | ||
| 138 | args.dry_run = False | ||
| 139 | |||
| 140 | cls.qemu = QemuCommand(args) | ||
| 141 | cmdline = cls.qemu.command_line() | ||
| 142 | print('Booting image with run-qemu-ota...') | ||
| 143 | cls.s = subprocess.Popen(cmdline) | ||
| 144 | time.sleep(10) | ||
| 145 | 112 | ||
| 146 | @classmethod | 113 | @classmethod |
| 147 | def tearDownClass(cls): | 114 | def tearDownClass(cls): |
| 148 | try: | 115 | qemu_terminate(cls.s) |
| 149 | cls.s.terminate() | ||
| 150 | except KeyboardInterrupt: | ||
| 151 | pass | ||
| 152 | |||
| 153 | def run_test_qemu(self, command): | ||
| 154 | command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' + | ||
| 155 | str(self.qemu.ssh_port) + ' "' + command + '"'] | ||
| 156 | s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
| 157 | value, err = s2.communicate() | ||
| 158 | return value, err | ||
| 159 | 116 | ||
| 160 | def test_hostname(self): | 117 | def test_hostname(self): |
| 161 | print('') | 118 | print('') |
| 162 | print('Checking machine name (hostname) of device:') | 119 | print('Checking machine name (hostname) of device:') |
| 163 | value, err = self.run_test_qemu('hostname') | 120 | value, err = qemu_send_command(self.qemu.ssh_port, 'hostname') |
| 164 | machine = get_bb_var('MACHINE', 'core-image-minimal') | 121 | machine = get_bb_var('MACHINE', 'core-image-minimal') |
| 165 | self.assertEqual(err, b'', 'Error: ' + err.decode()) | 122 | self.assertEqual(err, b'', 'Error: ' + err.decode()) |
| 166 | # Strip off line ending. | 123 | # Strip off line ending. |
| @@ -172,8 +129,79 @@ class QemuTests(oeSelfTest): | |||
| 172 | def test_var_sota(self): | 129 | def test_var_sota(self): |
| 173 | print('') | 130 | print('') |
| 174 | print('Checking contents of /var/sota:') | 131 | print('Checking contents of /var/sota:') |
| 175 | value, err = self.run_test_qemu('ls /var/sota') | 132 | value, err = qemu_send_command(self.qemu.ssh_port, 'ls /var/sota') |
| 176 | self.assertEqual(err, b'', 'Error: ' + err.decode()) | 133 | self.assertEqual(err, b'', 'Error: ' + err.decode()) |
| 177 | print(value.decode()) | 134 | print(value.decode()) |
| 178 | 135 | ||
| 136 | class GrubTests(oeSelfTest): | ||
| 137 | |||
| 138 | def setUpLocal(self): | ||
| 139 | # This is a bit of a hack but I can't see a better option. | ||
| 140 | path = os.path.abspath(os.path.dirname(__file__)) | ||
| 141 | metadir = path + "/../../../../" | ||
| 142 | grub_config = 'OSTREE_BOOTLOADER = "grub"\nMACHINE = "intel-corei7-64"' | ||
| 143 | self.append_config(grub_config) | ||
| 144 | self.meta_intel = metadir + "meta-intel" | ||
| 145 | self.meta_minnow = metadir + "meta-updater-minnowboard" | ||
| 146 | runCmd('bitbake-layers add-layer "%s"' % self.meta_intel) | ||
| 147 | runCmd('bitbake-layers add-layer "%s"' % self.meta_minnow) | ||
| 148 | self.qemu, self.s = qemu_launch(efi=True, machine='intel-corei7-64') | ||
| 149 | |||
| 150 | def tearDownLocal(self): | ||
| 151 | qemu_terminate(self.s) | ||
| 152 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_intel, ignore_status=True) | ||
| 153 | runCmd('bitbake-layers remove-layer "%s"' % self.meta_minnow, ignore_status=True) | ||
| 154 | |||
| 155 | def test_grub(self): | ||
| 156 | print('') | ||
| 157 | print('Checking machine name (hostname) of device:') | ||
| 158 | value, err = qemu_send_command(self.qemu.ssh_port, 'hostname') | ||
| 159 | machine = get_bb_var('MACHINE', 'core-image-minimal') | ||
| 160 | self.assertEqual(err, b'', 'Error: ' + err.decode()) | ||
| 161 | # Strip off line ending. | ||
| 162 | value_str = value.decode()[:-1] | ||
| 163 | self.assertEqual(value_str, machine, | ||
| 164 | 'MACHINE does not match hostname: ' + machine + ', ' + value_str) | ||
| 165 | print(value_str) | ||
| 166 | |||
| 167 | |||
| 168 | def qemu_launch(efi=False, machine=None): | ||
| 169 | logger = logging.getLogger("selftest") | ||
| 170 | logger.info('Running bitbake to build core-image-minimal') | ||
| 171 | bitbake('core-image-minimal') | ||
| 172 | # Create empty object. | ||
| 173 | args = type('', (), {})() | ||
| 174 | args.imagename = 'core-image-minimal' | ||
| 175 | args.mac = None | ||
| 176 | # Could use DEPLOY_DIR_IMAGE here but it's already in the machine | ||
| 177 | # subdirectory. | ||
| 178 | args.dir = 'tmp/deploy/images' | ||
| 179 | args.efi = efi | ||
| 180 | args.machine = machine | ||
| 181 | args.kvm = None # Autodetect | ||
| 182 | args.no_gui = True | ||
| 183 | args.gdb = False | ||
| 184 | args.pcap = None | ||
| 185 | args.overlay = None | ||
| 186 | args.dry_run = False | ||
| 187 | |||
| 188 | qemu = QemuCommand(args) | ||
| 189 | cmdline = qemu.command_line() | ||
| 190 | print('Booting image with run-qemu-ota...') | ||
| 191 | s = subprocess.Popen(cmdline) | ||
| 192 | time.sleep(10) | ||
| 193 | return qemu, s | ||
| 194 | |||
| 195 | def qemu_terminate(s): | ||
| 196 | try: | ||
| 197 | s.terminate() | ||
| 198 | except KeyboardInterrupt: | ||
| 199 | pass | ||
| 200 | |||
| 201 | def qemu_send_command(port, command): | ||
| 202 | command = ['ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p ' + | ||
| 203 | str(port) + ' "' + command + '"'] | ||
| 204 | s2 = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
| 205 | value, err = s2.communicate() | ||
| 206 | return value, err | ||
| 179 | 207 | ||
diff --git a/recipes-sota/aktualizr/aktualizr-auto-prov.bb b/recipes-sota/aktualizr/aktualizr-auto-prov.bb index 4f9fe4f..2190512 100644 --- a/recipes-sota/aktualizr/aktualizr-auto-prov.bb +++ b/recipes-sota/aktualizr/aktualizr-auto-prov.bb | |||
| @@ -1,28 +1,24 @@ | |||
| 1 | SUMMARY = "Aktualizr systemd service and configurations" | 1 | SUMMARY = "Aktualizr configuration for autoprovisioning" |
| 2 | DESCRIPTION = "Systemd service and configurations for autoprovisioning Aktualizr, the SOTA Client application written in C++" | 2 | DESCRIPTION = "Systemd service and configurations for autoprovisioning Aktualizr, the SOTA Client application written in C++" |
| 3 | HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" | 3 | HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" |
| 4 | SECTION = "base" | 4 | SECTION = "base" |
| 5 | LICENSE = "MPL-2.0" | 5 | LICENSE = "MPL-2.0" |
| 6 | LIC_FILES_CHKSUM = "file://${WORKDIR}/LICENSE;md5=9741c346eef56131163e13b9db1241b3" | 6 | LIC_FILES_CHKSUM = "file://${WORKDIR}/LICENSE;md5=9741c346eef56131163e13b9db1241b3" |
| 7 | DEPENDS = "zip-native" | 7 | DEPENDS = "aktualizr-native zip-native" |
| 8 | RDEPENDS_${PN} = "aktualizr" | 8 | RDEPENDS_${PN} = "aktualizr" |
| 9 | PV = "1.0" | 9 | PV = "1.0" |
| 10 | PR = "6" | 10 | PR = "6" |
| 11 | 11 | ||
| 12 | SRC_URI = " \ | 12 | SRC_URI = " \ |
| 13 | file://LICENSE \ | 13 | file://LICENSE \ |
| 14 | file://aktualizr-manual-provision.service \ | ||
| 15 | file://aktualizr-autoprovision.service \ | ||
| 16 | file://sota_autoprov.toml \ | ||
| 17 | " | 14 | " |
| 18 | 15 | ||
| 19 | SYSTEMD_SERVICE_${PN} = "aktualizr.service" | 16 | require environment.inc |
| 20 | 17 | require credentials.inc | |
| 21 | inherit systemd | ||
| 22 | 18 | ||
| 23 | export SOTA_PACKED_CREDENTIALS | 19 | export SOTA_PACKED_CREDENTIALS |
| 24 | 20 | ||
| 25 | do_install_append() { | 21 | do_install() { |
| 26 | if [ -n "${SOTA_AUTOPROVISION_CREDENTIALS}" ]; then | 22 | if [ -n "${SOTA_AUTOPROVISION_CREDENTIALS}" ]; then |
| 27 | bbwarn "SOTA_AUTOPROVISION_CREDENTIALS are ignored. Please use SOTA_PACKED_CREDENTIALS" | 23 | bbwarn "SOTA_AUTOPROVISION_CREDENTIALS are ignored. Please use SOTA_PACKED_CREDENTIALS" |
| 28 | fi | 24 | fi |
| @@ -36,27 +32,24 @@ do_install_append() { | |||
| 36 | bbwarn "OSTREE_PUSH_CREDENTIALS is ignored. Please use SOTA_PACKED_CREDENTIALS" | 32 | bbwarn "OSTREE_PUSH_CREDENTIALS is ignored. Please use SOTA_PACKED_CREDENTIALS" |
| 37 | fi | 33 | fi |
| 38 | 34 | ||
| 35 | install -d ${D}${libdir}/sota | ||
| 36 | install -d ${D}${localstatedir}/sota | ||
| 39 | if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then | 37 | if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then |
| 40 | install -d ${D}/${systemd_unitdir}/system | 38 | install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/sota_autoprov.toml ${D}${libdir}/sota/sota.toml |
| 41 | install -m 0644 ${WORKDIR}/aktualizr-autoprovision.service ${D}/${systemd_unitdir}/system/aktualizr.service | 39 | |
| 42 | install -d ${D}${libdir}/sota | 40 | # deploy SOTA credentials |
| 43 | install -m "0644" ${WORKDIR}/sota_autoprov.toml ${D}${libdir}/sota/sota.toml | 41 | if [ -e ${SOTA_PACKED_CREDENTIALS} ]; then |
| 44 | 42 | cp ${SOTA_PACKED_CREDENTIALS} ${D}${localstatedir}/sota/sota_provisioning_credentials.zip | |
| 45 | # deploy SOTA credentials | 43 | # Device should not be able to push data to treehub |
| 46 | if [ -e ${SOTA_PACKED_CREDENTIALS} ]; then | 44 | zip -d ${D}${localstatedir}/sota/sota_provisioning_credentials.zip treehub.json |
| 47 | mkdir -p ${D}/var/sota | 45 | fi |
| 48 | cp ${SOTA_PACKED_CREDENTIALS} ${D}/var/sota/sota_provisioning_credentials.zip | ||
| 49 | # Device should not be able to push data to treehub | ||
| 50 | zip -d ${D}/var/sota/sota_provisioning_credentials.zip treehub.json | ||
| 51 | fi | ||
| 52 | else | ||
| 53 | install -d ${D}/${systemd_unitdir}/system | ||
| 54 | install -m 0644 ${WORKDIR}/aktualizr-manual-provision.service ${D}/${systemd_unitdir}/system/aktualizr.service | ||
| 55 | fi | 46 | fi |
| 56 | } | 47 | } |
| 57 | 48 | ||
| 58 | FILES_${PN} = " \ | 49 | FILES_${PN} = " \ |
| 59 | ${systemd_unitdir}/system/aktualizr.service \ | ||
| 60 | ${libdir}/sota/sota.toml \ | 50 | ${libdir}/sota/sota.toml \ |
| 61 | /var/sota/sota_provisioning_credentials.zip \ | 51 | ${localstatedir}/sota \ |
| 52 | ${localstatedir}/sota/sota_provisioning_credentials.zip \ | ||
| 62 | " | 53 | " |
| 54 | |||
| 55 | # vim:set ts=4 sw=4 sts=4 expandtab: | ||
diff --git a/recipes-sota/aktualizr/aktualizr-hsm-test-prov.bb b/recipes-sota/aktualizr/aktualizr-hsm-test-prov.bb index c443c56..1e893fa 100644 --- a/recipes-sota/aktualizr/aktualizr-hsm-test-prov.bb +++ b/recipes-sota/aktualizr/aktualizr-hsm-test-prov.bb | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | SUMMARY = "Aktualizr systemd service and configuration with HSM support" | 1 | SUMMARY = "Aktualizr configuration with HSM support" |
| 2 | DESCRIPTION = "Systemd service and configurations for Aktualizr, the SOTA Client application written in C++" | 2 | DESCRIPTION = "Systemd service and configurations for Aktualizr, the SOTA Client application written in C++" |
| 3 | HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" | 3 | HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" |
| 4 | SECTION = "base" | 4 | SECTION = "base" |
| @@ -10,25 +10,22 @@ RDEPENDS_${PN} = "aktualizr softhsm softhsm-testtoken" | |||
| 10 | 10 | ||
| 11 | SRC_URI = " \ | 11 | SRC_URI = " \ |
| 12 | file://LICENSE \ | 12 | file://LICENSE \ |
| 13 | file://aktualizr-autoprovision.service \ | ||
| 14 | file://sota_hsm_test.toml \ | ||
| 15 | " | 13 | " |
| 16 | PV = "1.0" | 14 | PV = "1.0" |
| 17 | PR = "6" | 15 | PR = "6" |
| 18 | 16 | ||
| 19 | SYSTEMD_SERVICE_${PN} = "aktualizr.service" | ||
| 20 | 17 | ||
| 21 | inherit systemd | 18 | require environment.inc |
| 19 | require credentials.inc | ||
| 22 | 20 | ||
| 23 | do_install() { | 21 | do_install() { |
| 24 | install -d ${D}/${systemd_unitdir}/system | ||
| 25 | install -m 0644 ${WORKDIR}/aktualizr-autoprovision.service ${D}/${systemd_unitdir}/system/aktualizr.service | ||
| 26 | install -d ${D}${libdir}/sota | 22 | install -d ${D}${libdir}/sota |
| 27 | aktualizr_implicit_writer -c ${SOTA_PACKED_CREDENTIALS} --no-root-ca \ | 23 | aktualizr_implicit_writer -c ${SOTA_PACKED_CREDENTIALS} --no-root-ca \ |
| 28 | -i ${WORKDIR}/sota_hsm_test.toml -o ${D}${libdir}/sota/sota.toml -p ${D} | 24 | -i ${STAGING_DIR_NATIVE}${libdir}/sota/sota_hsm_test.toml -o ${D}${libdir}/sota/sota.toml -p ${D} |
| 29 | } | 25 | } |
| 30 | 26 | ||
| 31 | FILES_${PN} = " \ | 27 | FILES_${PN} = " \ |
| 32 | ${systemd_unitdir}/system/aktualizr.service \ | ||
| 33 | ${libdir}/sota/sota.toml \ | 28 | ${libdir}/sota/sota.toml \ |
| 34 | " | 29 | " |
| 30 | |||
| 31 | # vim:set ts=4 sw=4 sts=4 expandtab: | ||
diff --git a/recipes-sota/aktualizr/aktualizr-implicit-prov.bb b/recipes-sota/aktualizr/aktualizr-implicit-prov.bb index 21e38c9..b5bf420 100644 --- a/recipes-sota/aktualizr/aktualizr-implicit-prov.bb +++ b/recipes-sota/aktualizr/aktualizr-implicit-prov.bb | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | SUMMARY = "Aktualizr systemd service and configurations" | 1 | SUMMARY = "Aktualizr configuration for implicit provisioning" |
| 2 | DESCRIPTION = "Systemd service and configurations for implicitly provisioning Aktualizr, the SOTA Client application written in C++" | 2 | DESCRIPTION = "Systemd service and configurations for implicitly provisioning Aktualizr, the SOTA Client application written in C++" |
| 3 | HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" | 3 | HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" |
| 4 | SECTION = "base" | 4 | SECTION = "base" |
| @@ -11,24 +11,23 @@ PR = "1" | |||
| 11 | 11 | ||
| 12 | SRC_URI = " \ | 12 | SRC_URI = " \ |
| 13 | file://LICENSE \ | 13 | file://LICENSE \ |
| 14 | file://aktualizr-autoprovision.service \ | ||
| 15 | file://sota_implicit_prov.toml \ | ||
| 16 | " | 14 | " |
| 17 | 15 | ||
| 18 | SYSTEMD_SERVICE_${PN} = "aktualizr.service" | ||
| 19 | 16 | ||
| 20 | inherit systemd | 17 | require environment.inc |
| 18 | require credentials.inc | ||
| 21 | 19 | ||
| 22 | do_install() { | 20 | do_install() { |
| 23 | install -d ${D}/${systemd_unitdir}/system | ||
| 24 | install -m 0644 ${WORKDIR}/aktualizr-autoprovision.service ${D}/${systemd_unitdir}/system/aktualizr.service | ||
| 25 | install -d ${D}${libdir}/sota | 21 | install -d ${D}${libdir}/sota |
| 26 | aktualizr_implicit_writer -c ${SOTA_PACKED_CREDENTIALS} \ | 22 | if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then |
| 27 | -i ${WORKDIR}/sota_implicit_prov.toml -o ${D}${libdir}/sota/sota.toml -p ${D} | 23 | aktualizr_implicit_writer -c ${SOTA_PACKED_CREDENTIALS} \ |
| 24 | -i ${STAGING_DIR_NATIVE}${libdir}/sota/sota_implicit_prov.toml -o ${D}${libdir}/sota/sota.toml -p ${D} | ||
| 25 | fi | ||
| 28 | } | 26 | } |
| 29 | 27 | ||
| 30 | FILES_${PN} = " \ | 28 | FILES_${PN} = " \ |
| 31 | ${systemd_unitdir}/system/aktualizr.service \ | ||
| 32 | ${libdir}/sota/sota.toml \ | 29 | ${libdir}/sota/sota.toml \ |
| 33 | ${libdir}/sota/root.crt \ | 30 | ${libdir}/sota/root.crt \ |
| 34 | " | 31 | " |
| 32 | |||
| 33 | # vim:set ts=4 sw=4 sts=4 expandtab: | ||
diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index 162065e..48ed652 100644 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb | |||
| @@ -11,41 +11,69 @@ DEPENDS_append_class-native = "glib-2.0-native " | |||
| 11 | 11 | ||
| 12 | RDEPENDS_${PN}_class-target = "lshw " | 12 | RDEPENDS_${PN}_class-target = "lshw " |
| 13 | RDEPENDS_${PN}_append_class-target = "${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', ' engine-pkcs11', '', d)} " | 13 | RDEPENDS_${PN}_append_class-target = "${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', ' engine-pkcs11', '', d)} " |
| 14 | RDEPENDS_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'serialcan', ' slcand-start', '', d)} " | ||
| 14 | 15 | ||
| 15 | PV = "1.0+git${SRCPV}" | 16 | PV = "1.0+git${SRCPV}" |
| 16 | PR = "7" | 17 | PR = "7" |
| 17 | 18 | ||
| 18 | SRC_URI = " \ | 19 | SRC_URI = " \ |
| 19 | git://github.com/advancedtelematic/aktualizr;branch=${BRANCH} \ | 20 | gitsm://github.com/advancedtelematic/aktualizr;branch=${BRANCH} \ |
| 21 | file://aktualizr.service \ | ||
| 22 | file://aktualizr-serialcan.service \ | ||
| 20 | " | 23 | " |
| 21 | SRCREV = "f043191ae622a96cf2f4d48f9073d5cfa9f16e3f" | 24 | SRCREV = "e53f2a5747bba3e4f40609aa27f3d89e80c2d784" |
| 22 | BRANCH ?= "master" | 25 | BRANCH ?= "master" |
| 23 | 26 | ||
| 24 | S = "${WORKDIR}/git" | 27 | S = "${WORKDIR}/git" |
| 25 | 28 | ||
| 26 | inherit cmake | 29 | inherit cmake |
| 27 | 30 | ||
| 31 | inherit systemd | ||
| 32 | SYSTEMD_SERVICE_${PN} = "aktualizr.service" | ||
| 33 | |||
| 28 | BBCLASSEXTEND =+ "native" | 34 | BBCLASSEXTEND =+ "native" |
| 29 | 35 | ||
| 30 | EXTRA_OECMAKE = "-DWARNING_AS_ERROR=OFF -DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV} " | 36 | EXTRA_OECMAKE = "-DWARNING_AS_ERROR=OFF -DCMAKE_BUILD_TYPE=Release -DAKTUALIZR_VERSION=${PV} " |
| 31 | EXTRA_OECMAKE_append_class-target = "-DBUILD_OSTREE=ON ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', '-DBUILD_P11=ON', '', d)} " | 37 | EXTRA_OECMAKE_append_class-target = " -DBUILD_OSTREE=ON -DBUILD_ISOTP=ON ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', '-DBUILD_P11=ON', '', d)} " |
| 32 | EXTRA_OECMAKE_append_class-native = "-DBUILD_SOTA_TOOLS=ON -DBUILD_OSTREE=OFF " | 38 | EXTRA_OECMAKE_append_class-native = " -DBUILD_SOTA_TOOLS=ON -DBUILD_OSTREE=OFF " |
| 33 | 39 | ||
| 34 | do_install_append () { | 40 | do_install_append () { |
| 35 | rm -f ${D}${bindir}/aktualizr_cert_provider | 41 | rm -f ${D}${bindir}/aktualizr_cert_provider |
| 36 | } | 42 | } |
| 37 | do_install_append_class-target () { | 43 | do_install_append_class-target () { |
| 38 | rm -f ${D}${bindir}/aktualizr_implicit_writer | 44 | rm -f ${D}${bindir}/aktualizr_implicit_writer |
| 45 | ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-example', '', 'rm -f ${D}${bindir}/example-interface', d)} | ||
| 46 | ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-isotp-example', '', 'rm -f ${D}${bindir}/isotp-test-interface', d)} | ||
| 47 | |||
| 48 | install -d ${D}${systemd_unitdir}/system | ||
| 49 | aktualizr_service=${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'serialcan', '${WORKDIR}/aktualizr-serialcan.service', '${WORKDIR}/aktualizr.service', d)} | ||
| 50 | install -m 0644 ${aktualizr_service} ${D}${systemd_unitdir}/system/aktualizr.service | ||
| 39 | } | 51 | } |
| 40 | do_install_append_class-native () { | 52 | do_install_append_class-native () { |
| 41 | rm -f ${D}${bindir}/aktualizr | 53 | rm -f ${D}${bindir}/aktualizr |
| 54 | rm -f ${D}${bindir}/aktualizr-info | ||
| 55 | rm -f ${D}${bindir}/example-interface | ||
| 56 | install -d ${D}${libdir}/sota | ||
| 57 | install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml | ||
| 58 | install -m 0644 ${S}/config/sota_hsm_test.toml ${D}/${libdir}/sota/sota_hsm_test.toml | ||
| 59 | install -m 0644 ${S}/config/sota_implicit_prov.toml ${D}/${libdir}/sota/sota_implicit_prov.toml | ||
| 60 | |||
| 61 | install -m 0755 ${B}/src/sota_tools/garage-sign-prefix/src/garage-sign/bin/* ${D}${bindir} | ||
| 62 | install -m 0644 ${B}/src/sota_tools/garage-sign-prefix/src/garage-sign/lib/* ${D}${libdir} | ||
| 42 | } | 63 | } |
| 43 | 64 | ||
| 44 | FILES_${PN}_class-target = " \ | 65 | FILES_${PN}_class-target = " \ |
| 45 | ${bindir}/aktualizr \ | 66 | ${bindir}/aktualizr \ |
| 67 | ${bindir}/aktualizr-info \ | ||
| 68 | ${systemd_unitdir}/system/aktualizr.service \ | ||
| 46 | " | 69 | " |
| 70 | FILES_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-example', ' ${bindir}/example-interface', '', d)} " | ||
| 71 | FILES_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-isotp-example', ' ${bindir}/isotp-test-interface', '', d)} " | ||
| 47 | FILES_${PN}_class-native = " \ | 72 | FILES_${PN}_class-native = " \ |
| 48 | ${bindir}/aktualizr_implicit_writer \ | 73 | ${bindir}/aktualizr_implicit_writer \ |
| 49 | ${bindir}/garage-deploy \ | 74 | ${bindir}/garage-deploy \ |
| 50 | ${bindir}/garage-push \ | 75 | ${bindir}/garage-push \ |
| 76 | ${libdir}/sota/* \ | ||
| 51 | " | 77 | " |
| 78 | |||
| 79 | # vim:set ts=4 sw=4 sts=4 expandtab: | ||
diff --git a/recipes-sota/aktualizr/credentials.inc b/recipes-sota/aktualizr/credentials.inc new file mode 100644 index 0000000..256c8ff --- /dev/null +++ b/recipes-sota/aktualizr/credentials.inc | |||
| @@ -0,0 +1 @@ | |||
| SRC_URI_append = "${@('file://' + d.getVar('SOTA_PACKED_CREDENTIALS', True)) if d.getVar('SOTA_PACKED_CREDENTIALS', True) else ''}" | |||
diff --git a/recipes-sota/aktualizr/environment.inc b/recipes-sota/aktualizr/environment.inc new file mode 100644 index 0000000..cba77e7 --- /dev/null +++ b/recipes-sota/aktualizr/environment.inc | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | export SOTA_LEGACY_SECONDARY_INTERFACE | ||
| 2 | export SOTA_VIRTUAL_SECONDARIES | ||
| 3 | |||
| 4 | do_install_append() { | ||
| 5 | if [ -n "${SOTA_LEGACY_SECONDARY_INTERFACE}" ]; then | ||
| 6 | AKTUALIZR_PARAMETERS_LEGACYSEC="--legacy-interface ${SOTA_LEGACY_SECONDARY_INTERFACE}"; | ||
| 7 | fi | ||
| 8 | |||
| 9 | AKTUALIZR_PARAMETERS_CONFIGFILE="--config /usr/lib/sota/sota.toml" | ||
| 10 | for sec in ${SOTA_VIRTUAL_SECONDARIES}; do | ||
| 11 | AKTUALIZR_PARAMETERS_VIRTUALSECS="${AKTUALIZR_PARAMETERS_VIRTUALSECS} --secondary-config $sec" | ||
| 12 | done | ||
| 13 | |||
| 14 | echo "AKTUALIZR_CMDLINE_PARAMETERS=${AKTUALIZR_PARAMETERS_CONFIGFILE} ${AKTUALIZR_PARAMETERS_LEGACYSEC} ${AKTUALIZR_PARAMETERS_VIRTUALSECS}" > ${D}${libdir}/sota/sota.env | ||
| 15 | } | ||
| 16 | |||
| 17 | FILES_${PN}_append = " ${libdir}/sota/sota.env" | ||
diff --git a/recipes-sota/aktualizr/files/aktualizr-manual-provision.service b/recipes-sota/aktualizr/files/aktualizr-manual-provision.service deleted file mode 100644 index a70f2f9..0000000 --- a/recipes-sota/aktualizr/files/aktualizr-manual-provision.service +++ /dev/null | |||
| @@ -1,13 +0,0 @@ | |||
| 1 | [Unit] | ||
| 2 | Description=Aktualizr SOTA Client | ||
| 3 | Wants=network-online.target | ||
| 4 | After=network.target network-online.target | ||
| 5 | Requires=network-online.target | ||
| 6 | |||
| 7 | [Service] | ||
| 8 | RestartSec=10 | ||
| 9 | Restart=always | ||
| 10 | ExecStart=/usr/bin/aktualizr --config /sysroot/boot/sota.toml --loglevel 2 | ||
| 11 | |||
| 12 | [Install] | ||
| 13 | WantedBy=multi-user.target | ||
diff --git a/recipes-sota/aktualizr/files/aktualizr-serialcan.service b/recipes-sota/aktualizr/files/aktualizr-serialcan.service new file mode 100644 index 0000000..b42f348 --- /dev/null +++ b/recipes-sota/aktualizr/files/aktualizr-serialcan.service | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | [Unit] | ||
| 2 | Description=Aktualizr SOTA Client | ||
| 3 | Wants=network-online.target slcand@ttyACM0.service | ||
| 4 | After=network.target network-online.target slcand@ttyACM0.service | ||
| 5 | |||
| 6 | Requires=network-online.target | ||
| 7 | |||
| 8 | [Service] | ||
| 9 | RestartSec=10 | ||
| 10 | Restart=always | ||
| 11 | EnvironmentFile=/usr/lib/sota/sota.env | ||
| 12 | ExecStart=/bin/sh -c "(ip addr | grep can0) && /usr/bin/aktualizr $AKTUALIZR_CMDLINE_PARAMETERS" | ||
| 13 | |||
| 14 | [Install] | ||
| 15 | WantedBy=multi-user.target | ||
diff --git a/recipes-sota/aktualizr/files/aktualizr-autoprovision.service b/recipes-sota/aktualizr/files/aktualizr.service index 8cb8d78..b6df9d7 100644 --- a/recipes-sota/aktualizr/files/aktualizr-autoprovision.service +++ b/recipes-sota/aktualizr/files/aktualizr.service | |||
| @@ -7,7 +7,8 @@ Requires=network-online.target | |||
| 7 | [Service] | 7 | [Service] |
| 8 | RestartSec=10 | 8 | RestartSec=10 |
| 9 | Restart=always | 9 | Restart=always |
| 10 | ExecStart=/usr/bin/aktualizr --config /usr/lib/sota/sota.toml | 10 | EnvironmentFile=/usr/lib/sota/sota.env |
| 11 | ExecStart=/usr/bin/aktualizr $AKTUALIZR_CMDLINE_PARAMETERS | ||
| 11 | 12 | ||
| 12 | [Install] | 13 | [Install] |
| 13 | WantedBy=multi-user.target | 14 | WantedBy=multi-user.target |
diff --git a/recipes-sota/aktualizr/files/sota_autoprov.toml b/recipes-sota/aktualizr/files/sota_autoprov.toml deleted file mode 100644 index 9fbb093..0000000 --- a/recipes-sota/aktualizr/files/sota_autoprov.toml +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | [tls] | ||
| 2 | certificates_directory = "/var/sota/" | ||
| 3 | ca_file = "root.crt" | ||
| 4 | client_certificate = "client.pem" | ||
| 5 | pkey_file = "pkey.pem" | ||
| 6 | |||
| 7 | [uptane] | ||
| 8 | metadata_path = "/var/sota/metadata" | ||
| 9 | private_key_path = "ecukey.der" | ||
| 10 | public_key_path = "ecukey.pub" | ||
| 11 | |||
| 12 | [provision] | ||
| 13 | provision_path = "/var/sota/sota_provisioning_credentials.zip" | ||
| 14 | |||
diff --git a/recipes-sota/aktualizr/files/sota_hsm_test.toml b/recipes-sota/aktualizr/files/sota_hsm_test.toml deleted file mode 100644 index 28aefc2..0000000 --- a/recipes-sota/aktualizr/files/sota_hsm_test.toml +++ /dev/null | |||
| @@ -1,18 +0,0 @@ | |||
| 1 | [tls] | ||
| 2 | certificates_directory = "/var/sota/" | ||
| 3 | ca_file = "/var/sota/token/root.crt" | ||
| 4 | client_certificate = "01" | ||
| 5 | cert_source = "pkcs11" | ||
| 6 | pkey_file = "02" | ||
| 7 | pkey_source = "pkcs11" | ||
| 8 | |||
| 9 | [p11] | ||
| 10 | module = "/usr/lib/softhsm/libsofthsm2.so" | ||
| 11 | pass = "1234" | ||
| 12 | |||
| 13 | [uptane] | ||
| 14 | metadata_path = "/var/sota/metadata" | ||
| 15 | key_source = "pkcs11" | ||
| 16 | private_key_path = "03" | ||
| 17 | public_key_path = "03" | ||
| 18 | |||
diff --git a/recipes-sota/aktualizr/files/sota_implicit_prov.toml b/recipes-sota/aktualizr/files/sota_implicit_prov.toml deleted file mode 100644 index 756c868..0000000 --- a/recipes-sota/aktualizr/files/sota_implicit_prov.toml +++ /dev/null | |||
| @@ -1,11 +0,0 @@ | |||
| 1 | [tls] | ||
| 2 | certificates_directory = "/var/sota/" | ||
| 3 | ca_file = "/usr/lib/sota/root.crt" | ||
| 4 | client_certificate = "client.pem" | ||
| 5 | pkey_file = "pkey.pem" | ||
| 6 | |||
| 7 | [uptane] | ||
| 8 | metadata_path = "/var/sota/metadata" | ||
| 9 | private_key_path = "ecukey.der" | ||
| 10 | public_key_path = "ecukey.pub" | ||
| 11 | |||
diff --git a/recipes-sota/garage-sign/garage-sign.bb b/recipes-sota/garage-sign/garage-sign.bb deleted file mode 100644 index d5388bc..0000000 --- a/recipes-sota/garage-sign/garage-sign.bb +++ /dev/null | |||
| @@ -1,34 +0,0 @@ | |||
| 1 | SUMMARY = "garage-sign" | ||
| 2 | DESCRIPTION = "Metadata signing tool for ATS Garage" | ||
| 3 | HOMEPAGE = "https://ats-tuf-cli-releases.s3-eu-central-1.amazonaws.com/index.html" | ||
| 4 | SECTION = "base" | ||
| 5 | LICENSE = "CLOSED" | ||
| 6 | LIC_FILES_CHKSUM = "file://${S}/docs/LICENSE;md5=3025e77db7bd3f1d616b3ffd11d54c94" | ||
| 7 | DEPENDS = "" | ||
| 8 | |||
| 9 | PV = "0.2.0-35-g0544c33" | ||
| 10 | |||
| 11 | SRC_URI = " \ | ||
| 12 | https://ats-tuf-cli-releases.s3-eu-central-1.amazonaws.com/cli-${PV}.tgz \ | ||
| 13 | " | ||
| 14 | |||
| 15 | SRC_URI[md5sum] = "1546e06d1e747f67aee5ed7096bf1c74" | ||
| 16 | SRC_URI[sha256sum] = "1432348bca8ca5ad75df1218f348f480d429d7509d6454deb6e16ff31c5e08fc" | ||
| 17 | |||
| 18 | S = "${WORKDIR}/${BPN}" | ||
| 19 | |||
| 20 | BBCLASSEXTEND =+ "native" | ||
| 21 | |||
| 22 | do_install() { | ||
| 23 | install -d ${D}${bindir} | ||
| 24 | install -m "0755" -t ${D}${bindir} ${S}/bin/* | ||
| 25 | install -d ${D}${libdir} | ||
| 26 | install -m "0644" -t ${D}${libdir} ${S}/lib/* | ||
| 27 | } | ||
| 28 | |||
| 29 | FILES_${PN} = " \ | ||
| 30 | /usr/bin \ | ||
| 31 | /usr/bin/garage-sign.bat \ | ||
| 32 | /usr/bin/garage-sign \ | ||
| 33 | /usr/lib/* \ | ||
| 34 | " | ||
diff --git a/recipes-sota/ostree/ostree_git.bb b/recipes-sota/ostree/ostree_git.bb index 724976a..00559b6 100644 --- a/recipes-sota/ostree/ostree_git.bb +++ b/recipes-sota/ostree/ostree_git.bb | |||
| @@ -8,7 +8,7 @@ INHERIT_remove_class-native = "systemd" | |||
| 8 | 8 | ||
| 9 | SRC_URI = "gitsm://github.com/ostreedev/ostree.git;branch=master" | 9 | SRC_URI = "gitsm://github.com/ostreedev/ostree.git;branch=master" |
| 10 | 10 | ||
| 11 | SRCREV="ae61321046ad7f4148a5884c8c6c8b2594ff840e" | 11 | SRCREV="854a823e05d6fe8b610c02c2a71eaeb2bf1e98a6" |
| 12 | 12 | ||
| 13 | PV = "v2017.13" | 13 | PV = "v2017.13" |
| 14 | 14 | ||
| @@ -16,14 +16,14 @@ S = "${WORKDIR}/git" | |||
| 16 | 16 | ||
| 17 | BBCLASSEXTEND = "native" | 17 | BBCLASSEXTEND = "native" |
| 18 | 18 | ||
| 19 | DEPENDS += "attr libarchive glib-2.0 pkgconfig gpgme libgsystem fuse libsoup-2.4 e2fsprogs gtk-doc-native curl xz" | 19 | DEPENDS += "attr libarchive glib-2.0 pkgconfig gpgme libgsystem fuse e2fsprogs gtk-doc-native curl xz" |
| 20 | DEPENDS_append = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', ' systemd', '', d)}" | 20 | DEPENDS_append = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', ' systemd', '', d)}" |
| 21 | DEPENDS_remove_class-native = "systemd-native" | 21 | DEPENDS_remove_class-native = "systemd-native" |
| 22 | 22 | ||
| 23 | RDEPENDS_${PN} = "python util-linux-libuuid util-linux-libblkid util-linux-libmount libcap bash" | 23 | RDEPENDS_${PN} = "python util-linux-libuuid util-linux-libblkid util-linux-libmount libcap bash" |
| 24 | RDEPENDS_${PN}_remove_class-native = "python-native" | 24 | RDEPENDS_${PN}_remove_class-native = "python-native" |
| 25 | 25 | ||
| 26 | EXTRA_OECONF = "--with-libarchive --disable-gtk-doc --disable-gtk-doc-html --disable-gtk-doc-pdf --disable-man --with-smack --with-builtin-grub2-mkconfig --with-curl" | 26 | EXTRA_OECONF = "CFLAGS='-Wno-error=missing-prototypes' --with-libarchive --disable-gtk-doc --disable-gtk-doc-html --disable-gtk-doc-pdf --disable-man --with-smack --with-builtin-grub2-mkconfig --with-curl --without-soup" |
| 27 | EXTRA_OECONF_append_class-native = " --enable-wrpseudo-compat" | 27 | EXTRA_OECONF_append_class-native = " --enable-wrpseudo-compat" |
| 28 | 28 | ||
| 29 | # Path to ${prefix}/lib/ostree/ostree-grub-generator is hardcoded on the | 29 | # Path to ${prefix}/lib/ostree/ostree-grub-generator is hardcoded on the |
diff --git a/recipes-support/ca-certificates/ca-certificates_%.bbappend b/recipes-support/ca-certificates/ca-certificates_%.bbappend index afaadfd..cc95a68 100644 --- a/recipes-support/ca-certificates/ca-certificates_%.bbappend +++ b/recipes-support/ca-certificates/ca-certificates_%.bbappend | |||
| @@ -1 +1 @@ | |||
| SYSROOT_DIRS += "/etc" | SYSROOT_DIRS += "${sysconfdir}" | ||
diff --git a/recipes-support/glib-networking/glib-networking_%.bbappend b/recipes-support/glib-networking/glib-networking_%.bbappend deleted file mode 100644 index 22e6f05..0000000 --- a/recipes-support/glib-networking/glib-networking_%.bbappend +++ /dev/null | |||
| @@ -1,8 +0,0 @@ | |||
| 1 | BBCLASSEXTEND_append_sota = " native nativesdk" | ||
| 2 | |||
| 3 | # Hackery to prevent relocatable_native_pcfiles from crashing | ||
| 4 | do_install_append_class-native () { | ||
| 5 | if [ -d ${D}${libdir}/pkgconfig ]; then | ||
| 6 | rmdir ${D}${libdir}/pkgconfig | ||
| 7 | fi | ||
| 8 | } | ||
diff --git a/recipes-support/libsoup/libsoup-2.4_%.bbappend b/recipes-support/libsoup/libsoup-2.4_%.bbappend deleted file mode 100644 index 18383f1..0000000 --- a/recipes-support/libsoup/libsoup-2.4_%.bbappend +++ /dev/null | |||
| @@ -1,3 +0,0 @@ | |||
| 1 | BBCLASSEXTEND_append_sota = " native nativesdk" | ||
| 2 | |||
| 3 | DEPENDS_append_class-native = "${@bb.utils.contains('DISTRO_FEATURES', 'sota', ' glib-networking-native', ' ', d)}" | ||
diff --git a/recipes-support/slcand-start/files/slcand@.service b/recipes-support/slcand-start/files/slcand@.service new file mode 100644 index 0000000..c539568 --- /dev/null +++ b/recipes-support/slcand-start/files/slcand@.service | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | [Unit] | ||
| 2 | Description=Serial CAN daemon (can-utils) | ||
| 3 | |||
| 4 | [Service] | ||
| 5 | Type=forking | ||
| 6 | ExecStart=/usr/bin/slcand -o -c -s4 %I can0 | ||
| 7 | ExecStartPost=/bin/sh -c '/bin/sleep 3; /sbin/ip link set can0 up' | ||
| 8 | |||
diff --git a/recipes-support/slcand-start/slcand-start.bb b/recipes-support/slcand-start/slcand-start.bb new file mode 100644 index 0000000..dfefaea --- /dev/null +++ b/recipes-support/slcand-start/slcand-start.bb | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | SUMMARY = "Mock smartcard for aktualizr" | ||
| 2 | LICENSE = "MIT" | ||
| 3 | LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ | ||
| 4 | file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" | ||
| 5 | |||
| 6 | |||
| 7 | inherit systemd | ||
| 8 | |||
| 9 | RDEPENDS_${PN} = "can-utils" | ||
| 10 | |||
| 11 | SRC_URI = "file://slcand@.service" | ||
| 12 | |||
| 13 | SYSTEMD_SERVICE_${PN} = "slcand@.service" | ||
| 14 | |||
| 15 | do_install() { | ||
| 16 | install -d ${D}${systemd_unitdir}/system | ||
| 17 | install -m 0644 ${WORKDIR}/slcand@.service ${D}${systemd_unitdir}/system/slcand@.service | ||
| 18 | } | ||
| 19 | |||
| 20 | FILES_${PN} = "${systemd_unitdir}/system/createtoken.service" | ||
| 21 | |||
diff --git a/scripts/qemucommand.py b/scripts/qemucommand.py index 82a9540..9a893d8 100644 --- a/scripts/qemucommand.py +++ b/scripts/qemucommand.py | |||
| @@ -46,7 +46,7 @@ class QemuCommand(object): | |||
| 46 | if len(machines) == 1: | 46 | if len(machines) == 1: |
| 47 | self.machine = machines[0] | 47 | self.machine = machines[0] |
| 48 | else: | 48 | else: |
| 49 | raise ValueError("Could not autodetect machine type from %s" % args.dir) | 49 | raise ValueError("Could not autodetect machine type. More than one entry in %s. Maybe --machine qemux86-64?" % args.dir) |
| 50 | if args.efi: | 50 | if args.efi: |
| 51 | self.bios = 'OVMF.fd' | 51 | self.bios = 'OVMF.fd' |
| 52 | else: | 52 | else: |
| @@ -118,10 +118,9 @@ class QemuCommand(object): | |||
| 118 | 118 | ||
| 119 | def img_command_line(self): | 119 | def img_command_line(self): |
| 120 | cmdline = [ | 120 | cmdline = [ |
| 121 | "qemu-img", "create", | 121 | "qemu-img", "create", |
| 122 | "-o", "backing_file=%s" % self.image, | 122 | "-o", "backing_file=%s" % self.image, |
| 123 | "-f", "qcow2", | 123 | "-f", "qcow2", |
| 124 | self.overlay] | 124 | self.overlay] |
| 125 | return cmdline | 125 | return cmdline |
| 126 | 126 | ||
| 127 | |||
