From 3c916f9a8b6fdd1aa8403df812c5128afaf089c2 Mon Sep 17 00:00:00 2001 From: Mirza Krak Date: Wed, 18 Sep 2019 18:31:54 +0000 Subject: [PATCH 1/2] remove mender-convert (version 1) See https://hub.mender.io/t/new-iteration-of-the-mender-convert-tool/824 for more details. Will be replaced by mender-convert (version 2) Changelog: Title Signed-off-by: Mirza Krak --- Dockerfile | 105 --- LICENSE | 181 ---- LIC_FILES_CHKSUM.sha256 | 2 - README.md | 138 --- bbb-convert-stage-2.sh | 44 - convert-stage-3.sh | 22 - convert-stage-4.sh | 366 -------- convert-stage-5.sh | 389 -------- device-image-shell/.dockerignore | 1 - device-image-shell/Dockerfile | 13 - device-image-shell/README.md | 64 -- device-image-shell/docker-build | 7 - device-image-shell/docker-device-image-shell | 58 -- device-image-shell/docker-entrypoint.sh | 38 - docker-build | 21 - docker-entrypoint.sh | 11 - docker-mender-convert | 16 - files/init_resize.sh | 112 --- files/resizefs.service | 13 - files/resizefs.sh | 42 - files/uboot_debian_9.4/MLO | Bin 91876 -> 0 bytes files/uboot_debian_9.4/u-boot.img | Bin 432064 -> 0 bytes files/variables.template | 31 - mender-convert | 870 ------------------ mender-convert-functions.sh | 888 ------------------- qemux86_64-convert-stage-2.sh | 21 - rockpro64-convert-stage-2.sh | 22 - rpi-convert-stage-2.sh | 14 - rpi-convert-stage-5.sh | 258 ------ 29 files changed, 3747 deletions(-) delete mode 100644 Dockerfile delete mode 100644 LICENSE delete mode 100644 LIC_FILES_CHKSUM.sha256 delete mode 100644 README.md delete mode 100755 bbb-convert-stage-2.sh delete mode 100755 convert-stage-3.sh delete mode 100755 convert-stage-4.sh delete mode 100755 convert-stage-5.sh delete mode 100644 device-image-shell/.dockerignore delete mode 100644 device-image-shell/Dockerfile delete mode 100644 device-image-shell/README.md delete mode 100755 device-image-shell/docker-build delete mode 100755 device-image-shell/docker-device-image-shell delete mode 100755 device-image-shell/docker-entrypoint.sh delete mode 100755 docker-build delete mode 100755 docker-entrypoint.sh delete mode 100755 docker-mender-convert delete mode 100644 files/init_resize.sh delete mode 100644 files/resizefs.service delete mode 100644 files/resizefs.sh delete mode 100644 files/uboot_debian_9.4/MLO delete mode 100644 files/uboot_debian_9.4/u-boot.img delete mode 100644 files/variables.template delete mode 100755 mender-convert delete mode 100755 mender-convert-functions.sh delete mode 100755 qemux86_64-convert-stage-2.sh delete mode 100755 rockpro64-convert-stage-2.sh delete mode 100755 rpi-convert-stage-2.sh delete mode 100755 rpi-convert-stage-5.sh diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 9fa889c..0000000 --- a/Dockerfile +++ /dev/null @@ -1,105 +0,0 @@ -FROM ubuntu:18.04 - -ARG MENDER_ARTIFACT_VERSION=3.0.1 -ARG GOLANG_VERSION=1.11.2 - -RUN apt-get update && apt-get install -y \ - kpartx \ - bison \ - flex \ - mtools \ - parted \ - mtd-utils \ - e2fsprogs \ - u-boot-tools \ - pigz \ - device-tree-compiler \ - autoconf \ - autotools-dev \ - libtool \ - pkg-config \ - python \ - jq \ -# for mender-convert to run (mkfs.vfat is required for boot partition) - sudo \ - dosfstools \ -# to compile U-Boot - bc \ -# to download mender-artifact - wget \ -# to download mender-convert and U-Boot sources - git \ -# for arm64 support - gcc-aarch64-linux-gnu - -# Disable sanity checks made by mtools. These checks reject copy/paste operations on converted disk images. -RUN echo "mtools_skip_check=1" >> $HOME/.mtoolsrc - -# To provide support for Raspberry Pi Zero W a toolchain tuned for ARMv6 architecture must be used. -# https://tracker.mender.io/browse/MEN-2399 -# Assumes $(pwd) is / -RUN wget -nc -q https://toolchains.bootlin.com/downloads/releases/toolchains/armv6-eabihf/tarballs/armv6-eabihf--glibc--stable-2018.11-1.tar.bz2 \ - && tar -xjf armv6-eabihf--glibc--stable-2018.11-1.tar.bz2 \ - && rm armv6-eabihf--glibc--stable-2018.11-1.tar.bz2 \ - && echo 'export PATH=$PATH:/armv6-eabihf--glibc--stable-2018.11-1/bin' >> /root/.bashrc - -RUN wget -q -O /usr/bin/mender-artifact https://d1b0l86ne08fsf.cloudfront.net/mender-artifact/$MENDER_ARTIFACT_VERSION/linux/mender-artifact \ - && chmod +x /usr/bin/mender-artifact - -# Golang environment, for cross-compiling the Mender client -RUN wget https://dl.google.com/go/go$GOLANG_VERSION.linux-amd64.tar.gz \ - && tar -C /usr/local -xzf go$GOLANG_VERSION.linux-amd64.tar.gz \ - && echo 'export PATH=$PATH:/usr/local/go/bin' >> /root/.bashrc - -ENV PATH "$PATH:/usr/local/go/bin:/armv6-eabihf--glibc--stable-2018.11-1/bin" -ENV GOPATH "/root/go" - -# Download Mender client -ARG mender_client_version -RUN test -n "$mender_client_version" || (echo "Argument 'mender_client_version' is mandatory." && exit 1) -ENV MENDER_CLIENT_VERSION=$mender_client_version - -RUN go get -d github.com/mendersoftware/mender -WORKDIR $GOPATH/src/github.com/mendersoftware/mender -RUN git checkout $MENDER_CLIENT_VERSION - -# Toolchain configuration -ARG toolchain_host -RUN test -n "$toolchain_host" || (echo "Argument 'toolchain_host' is mandatory." && exit 1) -ENV TOOLCHAIN_HOST=${toolchain_host} - -ARG go_flags -RUN test -n "$go_flags" || (echo "Argument 'go_flags' is mandatory." && exit 1) -ENV GO_FLAGS=$go_flags - -RUN test -n "$mender_client_version" || (echo "Argument 'mender_client_version' is mandatory." && exit 1) -ENV MENDER_CLIENT_VERSION=$mender_client_version - -ENV CC "${TOOLCHAIN_HOST}-gcc" - -# Build liblzma from source -RUN wget -q https://tukaani.org/xz/xz-5.2.4.tar.gz \ - && tar -C /root -xzf xz-5.2.4.tar.gz \ - && cd /root/xz-5.2.4 \ - && ./configure --host=${TOOLCHAIN_HOST} --prefix=/root/xz-5.2.4/install \ - && make \ - && make install - -ENV LIBLZMA_INSTALL_PATH "/root/xz-5.2.4/install" - -# NOTE: we are assuming generic ARM board here, needs to be extended later -RUN env CGO_ENABLED=1 \ - CGO_CFLAGS="-I${LIBLZMA_INSTALL_PATH}/include" \ - CGO_LDFLAGS="-L${LIBLZMA_INSTALL_PATH}/lib" \ - CC=$CC \ - GOOS=linux \ - ${GO_FLAGS} make build - -# allow us to keep original PATH variables when sudoing -RUN echo "Defaults secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:$PATH\"" > /etc/sudoers.d/secure_path_override -RUN chmod 0440 /etc/sudoers.d/secure_path_override - -WORKDIR / - -COPY docker-entrypoint.sh /usr/local/bin/ -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] diff --git a/LICENSE b/LICENSE deleted file mode 100644 index a819abc..0000000 --- a/LICENSE +++ /dev/null @@ -1,181 +0,0 @@ -Copyright 2019 Northern.tech AS - -All content in this project is licensed under the Apache License v2, unless -indicated otherwise. - -------------------------------------------------------------------------------- - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/LIC_FILES_CHKSUM.sha256 b/LIC_FILES_CHKSUM.sha256 deleted file mode 100644 index 2534c88..0000000 --- a/LIC_FILES_CHKSUM.sha256 +++ /dev/null @@ -1,2 +0,0 @@ -beb140be4cd64599bedc691a55b2729c9cc611a4b9d6ec44e01270105daf18a2 LICENSE -beb140be4cd64599bedc691a55b2729c9cc611a4b9d6ec44e01270105daf18a2 mendertesting/LICENSE diff --git a/README.md b/README.md deleted file mode 100644 index 93d6beb..0000000 --- a/README.md +++ /dev/null @@ -1,138 +0,0 @@ -[![Build Status](https://travis-ci.com/mendersoftware/mender-convert.svg?branch=master)](https://travis-ci.com/mendersoftware/mender-convert) - -mender-convert -============== - -Mender is an open source over-the-air (OTA) software updater for embedded Linux devices. Mender comprises a client running at the embedded device, as well as a server that manages deployments across many devices. - -This repository contains mender-convert, which is used to convert pre-built disk images (Debian, Ubuntu, Raspbian, etc) to a Mender compatible -image by restructuring partition table and injecting the necessary files. - -Currently official Raspberry Pi 3 and BeagleBone Black images are supported and this will be extended. - -![Mender logo](https://mender.io/user/pages/resources/06.digital-assets/mender.io.png) - -## Getting started - -To start using Mender, we recommend that you begin with the Getting started -section in [the Mender documentation](https://docs.mender.io/). - - -## Docker environment for mender-convert - -In order to correctly set up partitions and bootloaders, mender-convert has many dependencies, -and their version and name vary between Linux distributions. - -To make using mender-convert easier, a reference setup using a Ubuntu 18.04 Docker container -is provided. - -You need to [install Docker Engine](https://docs.docker.com/install) to use this environment. - - -### Build the mender-convert container image - -To build a container based on Ubuntu 18.04 with all required dependencies for mender-convert, -copy this directory to your workstation and change the current directory to it. - -Then run - -```bash -./docker-build -``` - -This will create a container image you can use to run mender-convert. - - -### Use the mender-convert container image - -Create a directory `input` under the directory where you copied these files (`docker-build`, `docker-mender-convert`, etc.): - -```bash -mkdir input -``` - -Then put your raw disk image into `input/`, e.g. - -```bash -mv ~/Downloads/2018-11-13-raspbian-stretch.img input/2018-11-13-raspbian-stretch.img -``` - -You can run mender-convert from inside the container with your desired options, e.g. - - -```bash -DEVICE_TYPE="raspberrypi3" -RAW_DISK_IMAGE="input/2018-11-13-raspbian-stretch.img" - -ARTIFACT_NAME="2018-11-13-raspbian-stretch" -MENDER_DISK_IMAGE="2018-11-13-raspbian-stretch.sdimg" -TENANT_TOKEN="" - -./docker-mender-convert from-raw-disk-image \ - --raw-disk-image $RAW_DISK_IMAGE \ - --mender-disk-image $MENDER_DISK_IMAGE \ - --device-type $DEVICE_TYPE \ - --artifact-name $ARTIFACT_NAME \ - --bootloader-toolchain arm-buildroot-linux-gnueabihf \ - --server-url "https://hosted.mender.io" \ - --tenant-token $TENANT_TOKEN -``` - -By default conversion in containter uses GCC 7.3.0 bootlin toolchain tuned for -ARMv6 architecture (especially for ARM1176(F)-S single-core processor). -The aim of that is to provide a support for the Raspberry Pi Zero W development board. - -ARMv7 is backward compatible with ARMv6, so binaries compiled for ARMv6 should also work on ARMv7. - -Note that the default Mender client is the latest stable and cross-compiled for generic ARM boards, -which should work well in most cases. If you would like to use a different Mender client, -place it in `input/` and adjust the `--mender-client` argument. - -Conversion will take 10-15 minutes, depending on your storage and resources available. -You can watch `output/build.log` for progress and diagnostics information. - -After it finishes, you can find your images in the `output` directory on your host machine! - - -### Known issues -* An issue for `Raspberry Pi Zero W` has been spotted with the `mender-convert` tool version 1.1.0. - After an initial boot, having last partition resized to the end of the SD card, the correct device - tree cannot be found. As a result the boot cannot succeed. - For more information and current status, see [issue tracker](https://tracker.mender.io/browse/MEN-2436). -* If building U-boot fails with: -``` - D scripts/Kconfig - input in flex scanner failed - .... - include/linux/kconfig.h:4:32: fatal error: generated/autoconf.h: No such file or directory - #include -``` -you might be using a case-sensitive filesystem which is not supported. Case-sensitive filesystems are typically used on OSX (Mac) and Windows but you can also run in to this on Linux if running on a NTFS formatted partition. - -For details see this [discussion](https://hub.mender.io/t/raspberry-pi-3-model-b-b-raspbian/140/10) - - -## Contributing - -We welcome and ask for your contribution. If you would like to contribute to Mender, please read our guide on how to best get started [contributing code or documentation](https://github.com/mendersoftware/mender/blob/master/CONTRIBUTING.md). - -## License - -Mender is licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/mendersoftware/mender-crossbuild/blob/master/LICENSE) for the full license text. - -## Security disclosure - -We take security very seriously. If you come across any issue regarding -security, please disclose the information by sending an email to -[security@mender.io](security@mender.io). Please do not create a new public -issue. We thank you in advance for your cooperation. - -## Connect with us - -* Join the [Mender Hub discussion forum](https://hub.mender.io) -* Follow us on [Twitter](https://twitter.com/mender_io). Please - feel free to tweet us questions. -* Fork us on [Github](https://github.com/mendersoftware) -* Create an issue in the [bugtracker](https://tracker.mender.io/projects/MEN) -* Email us at [contact@mender.io](mailto:contact@mender.io) -* Connect to the [#mender IRC channel on Freenode](http://webchat.freenode.net/?channels=mender) diff --git a/bbb-convert-stage-2.sh b/bbb-convert-stage-2.sh deleted file mode 100755 index 87f74c5..0000000 --- a/bbb-convert-stage-2.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -output_dir=$1 -boot_mapping=$2 -embedded_rootfs_dir=$3 -uboot_backup_dir=${embedded_rootfs_dir}/opt/backup/uboot -build_log=$output_dir/build.log - -[ ! -f $output_dir/boot.vfat ] && \ - { log "Error: extracted boot partition not found. Aborting."; exit 1; } -[ ! -d "${embedded_rootfs_dir}" ] && \ - { log "Error: embedded content not mounted."; exit 1; } -[[ ! -f $uboot_backup_dir/MLO || ! -f $uboot_backup_dir/u-boot.img ]] && \ - { log "Error: cannot find U-Boot related files."; exit 1; } - -cat <<- 'EOF' | sudo tee --append ${output_dir}/uEnv.txt 2>&1 >/dev/null -loadaddr=0x82000000 -fdtaddr=0x88000000 -rdaddr=0x88080000 - -initrd_high=0xffffffff -fdt_high=0xffffffff - -loadximage=echo debug: [/boot/vmlinuz-${uname_r}] ... ; load mmc 0:2 ${loadaddr} /boot/vmlinuz-${uname_r} -loadxfdt=echo debug: [/boot/dtbs/${uname_r}/${fdtfile}] ... ;load mmc 0:2 ${fdtaddr} /boot/dtbs/${uname_r}/${fdtfile} -loadxrd=echo debug: [/boot/initrd.img-${uname_r}] ... ; load mmc 0:2 ${rdaddr} /boot/initrd.img-${uname_r}; setenv rdsize ${filesize} -loaduEnvtxt=load mmc 0:2 ${loadaddr} /boot/uEnv.txt ; env import -t ${loadaddr} ${filesize}; -check_dtb=if test -n ${dtb}; then setenv fdtfile ${dtb};fi; -loadall=run loaduEnvtxt; run check_dtb; run loadximage; run loadxrd; run loadxfdt; - -mmcargs=setenv bootargs console=tty0 console=${console} ${optargs} ${cape_disable} ${cape_enable} root=/dev/mmcblk0p2 rootfstype=${mmcrootfstype} ${cmdline} - -uenvcmd=run loadall; run mmcargs; echo debug: [${bootargs}] ... ; echo debug: [bootz ${loadaddr} ${rdaddr}:${rdsize} ${fdtaddr}] ... ; bootz ${loadaddr} ${rdaddr}:${rdsize} ${fdtaddr}; -EOF - -mcopy -o -i ${output_dir}/boot.vfat -s ${output_dir}/uEnv.txt ::uEnv.txt -mcopy -o -i ${output_dir}/boot.vfat -s ${uboot_backup_dir}/MLO ::MLO -mcopy -o -i ${output_dir}/boot.vfat -s ${uboot_backup_dir}/u-boot.img ::u-boot.img - -sudo dd if=${output_dir}/boot.vfat of=/dev/mapper/${boot_mapping} bs=1M conv=sparse >> "$build_log" 2>&1 - -log "\tDone." - -exit 0 diff --git a/convert-stage-3.sh b/convert-stage-3.sh deleted file mode 100755 index ec6463e..0000000 --- a/convert-stage-3.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -output_dir=$1 -rootfs_mapping=$2 -build_log=$output_dir/build.log - -[ ! -f ${output_dir}/rootfs.img ] && \ - { log "Error: extracted rootfs partition not found. Aborting."; exit 1; } - -sudo dd if=${output_dir}/rootfs.img of=/dev/mapper/${rootfs_mapping} bs=8M conv=sparse >> "$build_log" 2>&1 -sync - -sudo e2fsck -y -f /dev/mapper/${rootfs_mapping} >> "$build_log" 2>&1 -sudo resize2fs /dev/mapper/${rootfs_mapping} >> "$build_log" 2>&1 -# Check Linux ext4 file system just in case. -sudo fsck.ext4 -fp /dev/mapper/${rootfs_mapping} >> "$build_log" 2>&1 -# Make sure the rootfs partition's label follows Mender naming convention. -sudo tune2fs -L "primary" /dev/mapper/${rootfs_mapping} >> "$build_log" 2>&1 - -log "\tDone." - -exit 0 diff --git a/convert-stage-4.sh b/convert-stage-4.sh deleted file mode 100755 index 5b39f3d..0000000 --- a/convert-stage-4.sh +++ /dev/null @@ -1,366 +0,0 @@ -#!/bin/bash - -set -e - -show_help() { - cat << EOF - -Mender executables, service and configuration files installer. - -Usage: $0 [options] - - Options: [-m|--mender-disk-image | -g|--mender-client | -a|--artifact-name | - -d|--device-type | -n|--demo | -p|--demo-host-ip | -u| --server-url | - -c|--server-cert -t| --tenant-token -k|--keep -h|--help] - - --mender-disk-image - Mender raw disk image - --mender-client - Mender client binary file - --artifact-name - artifact info - --device-type - target device type identification - --demo - Configure image using demo parameters - --demo-host-ip - Mender demo server IP address - --server-url - Mender production server url - --server-cert - Mender server certificate - --tenant-token - Mender tenant token - --keep - Keep intermediate files in output directory - --help - Show help and exit - - For examples, see: ./mender-convert --help - -EOF - exit 1 -} - -jq_inplace() { - jq_args="$1" - dest_file="$2" - sudo sh -c -e "jq \"${jq_args}\" ${dest_file} > ${dest_file}.tmp && mv ${dest_file}.tmp ${dest_file}" -} - -tool_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -output_dir=${tool_dir}/output - -meta_mender_repo="https://raw.githubusercontent.com/mendersoftware/meta-mender" -meta_mender_revision="thud" - -mender_dir=$output_dir/mender -device_type= -artifact_name= -# Mender demo server IP address. -demo_host_ip= -# Mender production server url passed as CLI option. -server_url= -# Mender production certificate. -server_cert= -# Mender tenant token passed as CLI option. -tenant_token= -# Mender tenant token. -mender_tenant_token="dummy" -# Mender state-script format version -mender_state_scripts_version="3" - -declare -a mender_disk_mappings - -append_rootfs_configuration() { - local conffile=$1 - - local rootfsparta="/dev/mmcblk0p2" - local rootfspartb="/dev/mmcblk0p3" - - if [ "$device_type" == "qemux86_64" ]; then - rootfsparta="/dev/hda2" - rootfspartb="/dev/hda3" - elif [ "$device_type" == "rockpro64" ]; then - rootfsparta="/dev/mmcblk1p2" - rootfspartb="/dev/mmcblk1p3" - fi - - jq_inplace '.RootfsPartA = \"'$rootfsparta'\" | .RootfsPartB = \"'$rootfspartb'\"' ${conffile} -} - -create_client_files() { - cat <<- EOF > $mender_dir/device_type -device_type=${device_type} -EOF - - case "$device_type" in - "beaglebone" | "qemux86_64") - cat <<- EOF > $mender_dir/fw_env.config -/dev/mmcblk0 0x800000 0x20000 -/dev/mmcblk0 0x1000000 0x20000 -EOF - ;; - "raspberrypi3"|"raspberrypi0w") - cat <<- EOF > $mender_dir/fw_env.config -/dev/mmcblk0 0x400000 0x4000 -/dev/mmcblk0 0x800000 0x4000 -EOF - ;; - "rockpro64") - cat <<- EOF > $mender_dir/fw_env.config -/dev/mmcblk1 0x400000 0x8000 -/dev/mmcblk1 0x800000 0x8000 -EOF - ;; - - esac -} - -get_mender_files_from_upstream() { - - mkdir -p $mender_dir - - log "\tDownloading demo server certificate." - - wget -q -O $mender_dir/server.demo.crt \ - $meta_mender_repo/$meta_mender_revision/meta-mender-demo/recipes-mender/mender/files/server.crt -} - -install_files() { - local primary_dir=$1 - local data_dir=$2 - - sysconfdir="etc/mender" - bindir="usr/bin" - localstatedir="var/lib/mender" - dataconfdir="mender" - databootdir="u-boot" - - log "\tInstalling files." - - # Prepare 'data' partition - sudo install -d -m 755 ${data_dir}/${dataconfdir} - sudo install -d -m 755 ${data_dir}/${databootdir} - - sudo install -d -m 755 ${primary_dir}/${sysconfdir}/scripts/ - echo -n "${mender_state_scripts_version}" | sudo tee ${primary_dir}/${sysconfdir}/scripts/version - - sudo install -m 0444 ${mender_dir}/device_type ${data_dir}/${dataconfdir} - sudo install -m 0644 ${mender_dir}/fw_env.config ${data_dir}/${databootdir} - - sudo ln -sf /data/${databootdir}/fw_env.config ${primary_dir}/etc/fw_env.config - - # Create mount-points - # - # Note that only one of /boot/efi or /uboot will be used depending on what - # type of Mender integration is used (GRUB or U-boot). I do not see any - # problems with keeping an empty directory to reduce complexity of creating - # this directory structure. - sudo install -d -m 755 ${primary_dir}/data - sudo install -d -m 755 ${primary_dir}/boot/efi - sudo install -d -m 755 ${primary_dir}/uboot - - case "$device_type" in - "qemux86_64") - sudo install -d ${primary_dir}/lib64 - sudo ln -sf /lib/ld-linux-x86-64.so.2 ${primary_dir}/lib64/ld-linux-x86-64.so.2 - ;; - esac - - sudo ln -sf /data/${dataconfdir} ${primary_dir}/${localstatedir} - - # Call mender make install target - ( cd $GOPATH/src/github.com/mendersoftware/mender && \ - sudo make install prefix=$primary_dir ) - - # If specified, replace Mender client binary - if [ -n "${mender_client}" ]; then - sudo install -m 0755 ${mender_client} ${primary_dir}/${bindir}/mender - fi - - # Enable menderd service starting on boot. - if [ -z "${standalone_operation}" ]; then - # Enable menderd service starting on boot. - sudo ln -sf /lib/systemd/system/mender.service \ - ${primary_dir}/etc/systemd/system/multi-user.target.wants/mender.service - fi - - # By default production settings configuration is installed - if [ -n "${demo}" ] && [ ${demo} -eq 1 ]; then - sudo install -m 0644 ${primary_dir}/${sysconfdir}/mender.conf.demo ${primary_dir}/${sysconfdir}/mender.conf - fi - - # If specified, replace server URL - if [ -n "${server_url}" ]; then - jq_inplace '.ServerURL = \"'${server_url}'\"' ${primary_dir}/${sysconfdir}/mender.conf - fi - - # Set tenant token - if [ -n "${tenant_token}" ]; then - jq_inplace '.TenantToken = \"'${tenant_token}'\"' ${primary_dir}/${sysconfdir}/mender.conf - fi - - # Append RootfsPartA/B to mender.conf - append_rootfs_configuration ${primary_dir}/${sysconfdir}/mender.conf - - # Set artifact name - if [ -n "${artifact_name}" ]; then - sudo sh -c -e "echo artifact_name=${artifact_name} > ${primary_dir}/${sysconfdir}/artifact_info"; - fi - - # Set demo server and install demo certificate - if [ -n "${demo_host_ip}" ]; then - sudo sh -c -e "echo '$demo_host_ip docker.mender.io s3.docker.mender.io' >> $primary_dir/etc/hosts"; - jq_inplace '.ServerURL = \"https://docker.mender.io\"' ${primary_dir}/${sysconfdir}/mender.conf - sudo install -m 0444 ${mender_dir}/server.demo.crt ${primary_dir}/${sysconfdir}/server.crt - fi - - # Install provided - if [ -n "${server_cert}" ]; then - sudo install -m 0444 ${server_cert} ${primary_dir}/${sysconfdir}/server.crt - fi - - if [ -e "${primary_dir}/${sysconfdir}/server.crt" ]; then - jq_inplace '.ServerCertificate = \"/'${sysconfdir}'/server.crt\"' ${primary_dir}/${sysconfdir}/mender.conf - fi -} - -do_install_mender() { - if [ -z "${mender_disk_image}" ]; then - log "Mender raw disk image not set. Aborting." - show_help - fi - - if [ -z "${device_type}" ]; then - log "Target device type name not set. Aborting." - show_help - fi - - if [ -z "${artifact_name}" ]; then - log "Artifact info not set. Aborting." - show_help - fi - - if [ -z "${server_url}" ] && [ -z "${demo_host_ip}" ] && \ - [ -z "${tenant_token}" ]; then - log "No Mender server configuration was provided, it will only be possible to update using standalone mode." - standalone_operation="true" - fi - - if [ -n "${server_url}" ] && [ -n "${demo_host_ip}" ]; then - log "Incompatible server type choice. Aborting." - show_help - fi - - [ ! -f $mender_disk_image ] && \ - { log "$mender_disk_image - file not found. Aborting."; exit 1; } - - test -n "$(go version)" || \ - { log "go binary not found in PATH. Aborting."; exit 1; } - - test -n "$GOPATH" || \ - { log "GOPATH not set. Aborting."; exit 1; } - - test -d $GOPATH/src/github.com/mendersoftware/mender || \ - { log "mender source not found in \$GOPATH/src/github.com/mendersoftware/mender. Aborting."; exit 1; } - - # Mount rootfs partition A. - create_device_maps $mender_disk_image mender_disk_mappings - - # Change current directory to 'output' directory. - cd $output_dir - - primary=${mender_disk_mappings[1]} - data=${mender_disk_mappings[3]} - - if [ "$device_type" == "qemux86_64" ]; then - data=${mender_disk_mappings[4]} - fi - - map_primary=/dev/mapper/"$primary" - map_data=/dev/mapper/"$data" - path_primary=$output_dir/sdimg/primary - path_data=$output_dir/sdimg/data - mkdir -p ${path_primary} ${path_data} - - sudo mount ${map_primary} ${path_primary} - sudo mount ${map_data} ${path_data} - - # Get Mender client related files. - get_mender_files_from_upstream - - # Create all necessary client's files. - create_client_files - - # Create all required paths and install files. - install_files ${path_primary} ${path_data} - - # Back to working directory. - cd $tool_dir && sync - - # Clean stuff. - detach_device_maps ${mender_disk_mappings[@]} - rm -rf $output_dir/sdimg - [[ $keep -eq 0 ]] && { rm -rf $mender_dir; } - - log "\tDone." -} - -PARAMS="" - -while (( "$#" )); do - case "$1" in - -m | --mender-disk-image) - mender_disk_image=$2 - shift 2 - ;; - -g | --mender-client) - mender_client=$2 - shift 2 - ;; - -d | --device-type) - device_type=$2 - shift 2 - ;; - -a | --artifact-name) - artifact_name=$2 - shift 2 - ;; - -n | --demo) - demo="1" - shift 1 - ;; - -i | --demo-host-ip) - demo_host_ip=$2 - shift 2 - ;; - -c | --server-cert) - server_cert=$2 - shift 2 - ;; - -u | --server-url) - server_url=$2 - shift 2 - ;; - -t | --tenant-token) - tenant_token=$2 - shift 2 - ;; - -k | --keep) - keep="1" - shift 1 - ;; - -h | --help) - show_help - ;; - --) - shift - break - ;; - -*) - log "Error: unsupported option $1" - exit 1 - ;; - *) - PARAMS="$PARAMS $1" - shift - ;; - esac -done - -eval set -- "$PARAMS" - -# Some commands expect elevated privileges. -sudo true - -do_install_mender diff --git a/convert-stage-5.sh b/convert-stage-5.sh deleted file mode 100755 index 6e97896..0000000 --- a/convert-stage-5.sh +++ /dev/null @@ -1,389 +0,0 @@ -#!/bin/bash - -show_help() { -cat << EOF - -Tool adding GRUB specific files to Mender compliant image file. - -Usage: $0 [options] - - Options: [-m|--mender-disk-image | -b|--bootloader-toolchain | - -k|--keep | -d|--device-type] - - --mender-disk-image - Mender raw disk image - --bootloader-toolchain - GNU Arm Embedded Toolchain - --device-type - target device type identification - --keep - prevent deleting GRUB workspace - - Note: supported device types are: beaglebone, raspberrypi3 - - Examples: - - ./mender-convert install-bootloader-to-mender-disk-image - --mender-disk-image - --device-type - --bootloader-toolchain arm-linux-gnueabihf - - Note: toolchain naming convention is arch-vendor-(os-)abi - - arch is for architecture: arm, mips, x86, i686... - vendor is tool chain supplier: apple, Codesourcery, Linux, - os is for operating system: linux, none (bare metal) - abi is for application binary interface convention: eabi, gnueabi, gnueabihf - -EOF -} - -tool_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -output_dir=${tool_dir}/output -integration_dir=${tool_dir}/integration -grub_dir=$output_dir/grub -grubenv_dir=$output_dir/grubenv -mender_disk_image= -bootloader_toolchain= -device_type= -keep=0 -efi_boot=EFI/BOOT -EFI_STUB_VER="4.12.0" -build_log=$output_dir/build.log - -declare -a mender_disk_mappings - -version() { - echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }' -} - -get_kernel_version() { - local search_path=$1/boot - local resultvar=$2 - - [ ! -d "$search_path" ] && { return 1; } - - kernel_image=$(ls -1 $search_path | grep -E "^vmlinuz") - - local myresult=${kernel_image#*-} - eval $resultvar="'$myresult'" - return 0 -} - -build_env_lock_boot_files() { - log "\tBuilding boot scripts and tools." - local grubenv_repo_vc_dir=$grubenv_dir/.git - local grubenv_build_dir=$grubenv_dir/build - - mkdir -p $grubenv_dir - - if [ ! -d $grubenv_repo_vc_dir ]; then - git clone https://github.com/mendersoftware/grub-mender-grubenv.git $grubenv_dir >> "$build_log" 2>&1 - fi - cd $grubenv_dir - - mkdir -p $grubenv_build_dir - - # Remove old defines & settings. - make --quiet distclean >> "$build_log" 2>&1 - - # Prepare configuration file. - cp mender_grubenv_defines.example mender_grubenv_defines - - local kernel_imagetype=kernel - local kernel_devicetree=dtb - - sed -i '/^kernel_imagetype/s/=.*$/='${kernel_imagetype}'/' mender_grubenv_defines - sed -i '/^kernel_devicetree/s/=.*$/='${kernel_devicetree//\//\\/}'/' mender_grubenv_defines - if [ "$device_type" == "qemux86_64" ]; then - local root_base=/dev/hda - sed -i '/^mender_kernel_root_base/s/=.*$/='${root_base//\//\\/}'/' mender_grubenv_defines - fi - - make --quiet >> "$build_log" 2>&1 - rc=$? - [[ $rc -eq 0 ]] && { make --quiet DESTDIR=$grubenv_build_dir install >> "$build_log" 2>&1; } - rc=$? - [[ $rc -ne 0 ]] && { log "\tError: building process failed. Aborting."; } - - cd ${output_dir} - return $rc -} - -# Takes following arguments: -# -# $1 - linux kernel version -build_grub_efi() { - if [ "$device_type" == "rockpro64" ]; then - return 0 - fi - - log "\tBuilding GRUB efi file." - - local grub_build_dir=$grub_dir/build - local grub_arm_dir=$grub_build_dir/arm - local host=$(uname -m) - local grub_host_dir=$grub_build_dir/$host - local grub_repo_vc_dir=$grub_dir/.git - - local version=$(echo $1 | sed 's/[^0-9.]*\([0-9.]*\).*/\1/') - - # Build grub modules for arm platform and executables for the host. - if [ ! -d $grub_repo_vc_dir ]; then - git clone git://git.savannah.gnu.org/grub.git $grub_dir >> "$build_log" 2>&1 - fi - - cd $grub_dir - make --quiet distclean >> "$build_log" 2>&1 - - if [ $(version $version) -lt $(version $EFI_STUB_VER) ]; then - # To avoid error message: "plain image kernel not supported - rebuild - # with CONFIG_(U)EFI_STUB enabled" - use a specific commit. - git checkout 9b37229f0 >> "$build_log" 2>&1 - else - git checkout 72e80c025 >> "$build_log" 2>&1 - fi - - mkdir -p $grub_arm_dir - mkdir -p $grub_host_dir - - local cores=$(nproc) - - # First build host tools. - ./autogen.sh >> "$build_log" 2>&1 - ./configure --quiet CC=gcc --target=${host} --with-platform=efi --prefix=$grub_host_dir >> "$build_log" 2>&1 - make --quiet -j$cores >> "$build_log" 2>&1 - make --quiet install >> "$build_log" 2>&1 - - local format=${host}-efi - grub_name=bootx64.efi - local modules_path=$grub_host_dir/lib/grub/$format/ - - if [ "$device_type" == "beaglebone" ]; then - # Clean workspace. - make --quiet clean >> "$build_log" 2>&1 - make --quiet distclean >> "$build_log" 2>&1 - - # Now build ARM modules. - ./configure --quiet --host=$bootloader_toolchain --with-platform=efi \ - --prefix=$grub_arm_dir CFLAGS="-Os -march=armv7-a" \ - CCASFLAGS="-march=armv7-a" --disable-werror >> "$build_log" 2>&1 - make --quiet -j$cores >> "$build_log" 2>&1 - make --quiet install >> "$build_log" 2>&1 - - format=arm-efi - grub_name=grub-arm.efi - modules_path=$grub_arm_dir/lib/grub/$format/ - fi - - # Build GRUB EFI image. - ${grub_host_dir}/bin/grub-mkimage -v -p /$efi_boot -o $grub_name --format=$format \ - -d $modules_path boot linux ext2 fat serial part_msdos part_gpt normal \ - efi_gop iso9660 configfile search loadenv test cat echo gcry_sha256 halt \ - hashsum loadenv reboot >> "$build_log" 2>&1 - - rc=$? - [[ $rc -ne 0 ]] && { log "\tBuilding grub.efi failed. Aborting."; } \ - || { log "\tBuilding grub.efi succeeded."; } - - cd ${output_dir} - return $rc -} - -# Takes following arguments: -# -# $1 - boot partition mountpoint -set_uenv() { - local boot_dir=$1 - # Erase/create uEnv.txt file. - sudo install -b -m 644 /dev/null $boot_dir/uEnv.txt - - # Fill uEnv.txt file. - cat <<- 'EOF' | sudo tee $boot_dir/uEnv.txt 2>&1 >/dev/null - bootdir= - grubfile=EFI/BOOT/grub-arm.efi - grubaddr=0x80007fc0 - loadgrub=fatload mmc 0:1 ${grubaddr} ${grubfile} - grubstart=bootefi ${grubaddr} - uenvcmd=mmc rescan; run loadgrub; run grubstart; - EOF -} - -# Takes following arguments: -# -# $1 - boot partition mountpoint -# $2 - primary partition mountpoint -# $3 - linux kernel version -install_files() { - log "\tInstalling GRUB files." - local boot_dir=$1 - local rootfs_dir=$2 - local linux_version=$3 - - if [ "$device_type" == "rockpro64" ]; then - cp $integration_dir/rockpro64/boot.scr ${boot_dir}/ - - # It is not possible to resize rootfs part when using Mender. so disable - # the service - touch ${rootfs_dir}/root/.no_rootfs_resize - return 0 - fi - - local grub_build_dir=$grub_dir/build - local grub_arm_dir=$grub_build_dir/arm - local grub_host_dir=$grub_build_dir/$(uname -m) - - local grubenv_build_dir=$grubenv_dir/build - local grubenv_efi_boot_dir=$grubenv_build_dir/boot/efi/EFI/BOOT/ - - local efi_boot_dir=$boot_dir/$efi_boot - - # Make sure env, lock, lock.sha256sum files exists in working directory. - [[ ! -d $grubenv_efi_boot_dir/mender_grubenv1 || \ - ! -d $grubenv_efi_boot_dir/mender_grubenv2 ]] && \ - { log "Error: cannot find mender grub related files."; return 1; } - - sudo install -d -m 755 $efi_boot_dir - - cd $grubenv_efi_boot_dir && find . -type f -exec sudo install -Dm 644 "{}" "$efi_boot_dir/{}" \; - cd ${output_dir} - - if [ "$device_type" == "qemux86_64" ]; then - sudo install -m 0755 ${grub_host_dir}/bin/grub-editenv $rootfs_dir/usr/bin - else - sudo install -m 0755 ${grub_arm_dir}/bin/grub-editenv $rootfs_dir/usr/bin - fi - - sudo install -m 0644 ${grub_dir}/${grub_name} $efi_boot_dir - - sudo install -m 0755 $grubenv_build_dir/usr/bin/fw_printenv $rootfs_dir/sbin/fw_printenv - sudo install -m 0755 $grubenv_build_dir/usr/bin/fw_setenv $rootfs_dir/sbin/fw_setenv - - # Replace U-Boot default printenv/setenv commands. - sudo ln -fs /sbin/fw_printenv $rootfs_dir/usr/bin/fw_printenv - sudo ln -fs /sbin/fw_setenv $rootfs_dir/usr/bin/fw_setenv - - #Create links for grub - if [ "$device_type" == "qemux86_64" ]; then - # Copy kernel image to fit the grubenv defines. - sudo cp $boot_dir/bzImage $rootfs_dir/boot/kernel - elif [ "$device_type" == "beaglebone" ]; then - #Replace U-Boot default images for Debian 9.5 - if [ `grep -s '9.5' $rootfs_dir/etc/debian_version | wc -l` -eq 1 ]; then - sudo cp ${tool_dir}/files/uboot_debian_9.4/MLO ${boot_dir}/MLO - sudo cp ${tool_dir}/files/uboot_debian_9.4/u-boot.img ${boot_dir}/u-boot.img - fi - # Make links to kernel and device tree files. - sudo ln -sf /boot/dtbs/$linux_version/am335x-boneblack.dtb $rootfs_dir/boot/dtb - sudo ln -sf /boot/vmlinuz-$linux_version $rootfs_dir/boot/kernel - set_uenv $boot_dir - fi -} - -do_install_bootloader() { - if [ -z "${mender_disk_image}" ]; then - log "Mender raw disk image not set. Aborting." - exit 1 - fi - - if [ -z "${bootloader_toolchain}" ]; then - log "ARM GCC toolchain not set. Aborting." - exit 1 - fi - - if [ -z "${device_type}" ]; then - log "Target device type name not set. Aborting." - exit 1 - fi - - if ! [ -x "$(command -v ${bootloader_toolchain}-gcc)" ]; then - log "Error: ARM GCC not found in PATH. Aborting." - exit 1 - fi - - [ ! -f $mender_disk_image ] && \ - { log "$mender_disk_image - file not found. Aborting."; exit 1; } - - # Map & mount Mender compliant image. - create_device_maps $mender_disk_image mender_disk_mappings - - # Change current directory to 'output' directory. - cd $output_dir - - boot=${mender_disk_mappings[0]} - primary=${mender_disk_mappings[1]} - map_boot=/dev/mapper/"$boot" - map_primary=/dev/mapper/"$primary" - path_boot=$output_dir/sdimg/boot - path_primary=$output_dir/sdimg/primary - mkdir -p ${path_boot} ${path_primary} - - sudo mount ${map_boot} ${path_boot} - sudo mount ${map_primary} ${path_primary} - - get_kernel_version ${path_primary} kernel_version - log "\tFound kernel version: $kernel_version" - - build_env_lock_boot_files - rc=$? - if [ "$device_type" == "qemux86_64" ]; then - [[ $rc -eq 0 ]] && { build_grub_efi ${EFI_STUB_VER}; } - else - [[ $rc -eq 0 ]] && { build_grub_efi ${kernel_version}; } - fi - rc=$? - [[ $rc -eq 0 ]] && { install_files ${path_boot} ${path_primary} ${kernel_version}; } - rc=$? - - # Back to working directory. - cd $tool_dir && sync - - detach_device_maps ${mender_disk_mappings[@]} - # Clean files. - rm -rf $output_dir/sdimg - - [[ $keep -eq 0 ]] && { rm -rf $grubenv_dir $grub_dir; } - [[ $rc -ne 0 ]] && { exit 1; } || { log "\tDone."; } -} - -PARAMS="" - -while (( "$#" )); do - case "$1" in - -m | --mender-disk-image) - mender_disk_image=$2 - shift 2 - ;; - -b | --bootloader-toolchain) - bootloader_toolchain=$2 - shift 2 - ;; - -d | --device-type) - device_type=$2 - shift 2 - ;; - -k | --keep) - keep=1 - shift 1 - ;; - -h | --help) - show_help - exit 0 - ;; - --) - shift - break - ;; - -*) - log "Error: unsupported option $1" - exit 1 - ;; - *) - PARAMS="$PARAMS $1" - shift - ;; - esac -done - -eval set -- "$PARAMS" - -# Some commands expect elevated privileges. -sudo true - -do_install_bootloader diff --git a/device-image-shell/.dockerignore b/device-image-shell/.dockerignore deleted file mode 100644 index ea1472e..0000000 --- a/device-image-shell/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -output/ diff --git a/device-image-shell/Dockerfile b/device-image-shell/Dockerfile deleted file mode 100644 index 7acfbbb..0000000 --- a/device-image-shell/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM ubuntu:18.04 - -ARG MENDER_ARTIFACT_VERSION=3.0.1 - -RUN apt-get update && apt-get install -y \ - wget \ - qemu-user-static - -RUN wget -q -O /usr/bin/mender-artifact https://d1b0l86ne08fsf.cloudfront.net/mender-artifact/$MENDER_ARTIFACT_VERSION/mender-artifact \ - && chmod +x /usr/bin/mender-artifact - -COPY docker-entrypoint.sh /usr/local/bin/ -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] diff --git a/device-image-shell/README.md b/device-image-shell/README.md deleted file mode 100644 index b7eb1eb..0000000 --- a/device-image-shell/README.md +++ /dev/null @@ -1,64 +0,0 @@ -Device Image Shell -================== - -This directory contains a tool that takes the root file system of your device as input and emulates a shell session on your device. -Any commands you run (e.g. apt update, apt upgrade) will behave as if you were logged into your actual device! - -The purpose of the tool is to create a new root file system image and Mender Artifact that can be deployed to a fleet of devices in the field. - - -## Docker environment - -To ensure dependencies are correctly set up and it is portable, a docker environment is used. - -You need to [install Docker Engine](https://docs.docker.com/install) to use this tool. - - -### Build the device-image-shell container image - -To build a container based on Ubuntu 18.04 with the required dependencies, copy this directory to your workstation and change the current directory to it. - -Then run - -```bash -./docker-build -``` - -This will create a container image `device-image-shell`. - - -### Use the device-image-shell container image - -The also assumes your device is based on the ARM architecture, which is the most common (e.g. Raspberry Pi, BeagleBoard, etc.). - -You need a root file system image (usually with .ext4 extension) for your device as a starting point, such as one output by [mender-convert](https://github.com/mendersoftware/mender-convert). Make sure to have `qemu-user-static` installed on a host machine. - -You can now enter a shell in your device root file system image by running `docker-device-image-shell` with the desired arguments: - -1. path to your existing root file system image -2. desired name for the generated Mender Artifact -3. device type, which Mender uses to ensure compatibility between devices and software - -For example, if you are using a Raspberry Pi 3, you can run: - -```bash -./docker-device-image-shell ../output/2018-11-13-raspbian-stretch-lite.ext4 2018-11-13-raspbian-stretch-lite-aptupgrade raspberrypi3 -``` - -You should now see a shell prompt. You are in an emulated environment, so any commands run here will behave as if you ran them on your device! In addition, any changes you make will be preserved in the output root file system image and Mender Artifact. - -For example, to update to the latest packages run: - -```bash -apt update -apt upgrade -``` - -When you are done, press `Ctrl+D` or run the `exit` command. Generating the Mender Artifact will take a few more minutes, depending on the size of the input image and resources available on your workstation. - -After it finishes you can find your new `.ext4` and `.mender` files in the `output/` directory. For devices where Mender is installed, you can use the Mender Artifact (`.mender` file) to deploy the changes you made in the shell to all your devices! - - -### Use caution - -Please note that since this tool is using an emulated environment (based on `qemu`) and you are not properly logged in to your device, some things may not work as expected. Look for any relevant errors in commands you run and make sure to test your changes before deploying to production devices! diff --git a/device-image-shell/docker-build b/device-image-shell/docker-build deleted file mode 100755 index 752bb63..0000000 --- a/device-image-shell/docker-build +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -set -e - -DOCKER_IMAGE_NAME=device-image-shell - -docker build . -t ${DOCKER_IMAGE_NAME} diff --git a/device-image-shell/docker-device-image-shell b/device-image-shell/docker-device-image-shell deleted file mode 100755 index e697568..0000000 --- a/device-image-shell/docker-device-image-shell +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/sh - -set -e - -DOCKER_IMAGE_NAME=device-image-shell -OUTPUT_DIR="$(pwd)/output" - -show_usage() { - echo "Usage:" - echo "$0 " -} - -if [ "$#" -ne 3 ]; then - echo "ERROR: 3 parameters required." - show_usage - exit 1 -fi - -ROOTFS_INPUT_FILE=$1 -ARTIFACT_NAME=$2 -DEVICE_TYPE=$3 - -if [ ! -f "$ROOTFS_INPUT_FILE" ]; then - echo "ERROR: File passed as first argument is not accessible." - echo "Got ROOTFS_INPUT_FILE=\"$ROOTFS_INPUT_FILE\"" - show_usage - exit 1 -fi - - -mkdir -p $OUTPUT_DIR - -ROOTFS_INPUT_FILE_NAME="$(basename -- $ROOTFS_INPUT_FILE)" -ROOTFS_INPUT_FILE_EXTENSION="${ROOTFS_INPUT_FILE_NAME##*.}" - -ROOTFS_OUTPUT_FILE_NAME="$ARTIFACT_NAME.$ROOTFS_INPUT_FILE_EXTENSION" - -echo "Copying rootfs input file..." -rsync -h --progress $ROOTFS_INPUT_FILE $OUTPUT_DIR/$ROOTFS_OUTPUT_FILE_NAME - -docker run \ - -ti \ - --privileged=true \ - --mount type=bind,source=$OUTPUT_DIR,target=/root_images \ - $DOCKER_IMAGE_NAME $ROOTFS_OUTPUT_FILE_NAME $ARTIFACT_NAME $DEVICE_TYPE - - -# Output Artifact gets root owner and group, change to current logged in -CURRENT_USER=$(id -u -n) -CURRENT_GROUP=$(id -g -n) - -echo "Changing ownership of Mender Artifact (may ask you to authenticate)" -sudo chown $CURRENT_USER:$CURRENT_GROUP $OUTPUT_DIR/$ARTIFACT_NAME.mender - -echo "Image generation complete!" -/bin/echo -e "The new root file system is at:\n\t$OUTPUT_DIR/$ROOTFS_OUTPUT_FILE_NAME" -/bin/echo -e "The new Mender Artifact you can upload to your Mender server to deploy to your devices is at:\ - \n\t$OUTPUT_DIR/$ARTIFACT_NAME.mender" diff --git a/device-image-shell/docker-entrypoint.sh b/device-image-shell/docker-entrypoint.sh deleted file mode 100755 index 41b794f..0000000 --- a/device-image-shell/docker-entrypoint.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -set -e - -ROOTFS_OUTPUT_FILE_NAME=$1 -ARTIFACT_NAME=$2 -DEVICE_TYPE=$3 - -mkdir /root_system - -mount /root_images/$ROOTFS_OUTPUT_FILE_NAME /root_system - -if [ -f /root_system/usr/bin/qemu-arm-static ]; then - echo "WARNING: /usr/bin/qemu-arm-static already exists in image. Using this but may be of incompatible version." - QEMU_STATIC_COPIED=false -else - # trick to make chroot into ARM image work - cp /usr/bin/qemu-arm-static /root_system/usr/bin - QEMU_STATIC_COPIED=true -fi - -echo "Entering emulated shell in device image. All commands are run as the root user of the device image." -echo "Make changes (e.g. apt update, apt upgrade, wget ...) and press Ctrl-D when done." - -# Using bash for command completion support and other conveniences -chroot /root_system /bin/bash - -# Mender Artifact name must also be present inside -echo artifact_name=$ARTIFACT_NAME > /root_system/etc/mender/artifact_info - -if [ "$QEMU_STATIC_COPIED" = true ]; then - rm /root_system/usr/bin/qemu-arm-static -fi - -umount /root_system - -echo "Creating Mender Artifact. This may take 10-20 minutes (using LZMA)..." -mender-artifact --compression lzma write rootfs-image -t $DEVICE_TYPE -n $ARTIFACT_NAME -f /root_images/$ROOTFS_OUTPUT_FILE_NAME -o /root_images/$ARTIFACT_NAME.mender -sync diff --git a/docker-build b/docker-build deleted file mode 100755 index 3436a2d..0000000 --- a/docker-build +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -set -e - -if [ -z "$IMAGE_NAME" ]; then - IMAGE_NAME=mender-convert -fi - -MENDER_CLIENT_VERSION="2.0.1" - -DOCKER_ARGS="--build-arg mender_client_version=${MENDER_CLIENT_VERSION}" - -if [ "$1" = "arm64" ]; then - DOCKER_ARGS="${DOCKER_ARGS} --build-arg toolchain_host=aarch64-linux-gnu" - DOCKER_ARGS="${DOCKER_ARGS} --build-arg go_flags=GOARCH=arm64" -else - DOCKER_ARGS="${DOCKER_ARGS} --build-arg toolchain_host=arm-buildroot-linux-gnueabihf" - DOCKER_ARGS="${DOCKER_ARGS} --build-arg go_flags=\"GOARM=6 GOARCH=arm\"" -fi - -eval docker build . -t ${IMAGE_NAME} ${DOCKER_ARGS} diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100755 index b18eb05..0000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -set -e - -# run conversion, args provided to container (end of docker run ...) - -cd /mender-convert - -echo "Running mender-convert "$@"" - -./mender-convert "$@" diff --git a/docker-mender-convert b/docker-mender-convert deleted file mode 100755 index c28afc8..0000000 --- a/docker-mender-convert +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -set -e - -IMAGE_NAME=mender-convert - -MENDER_CONVERT_DIR="$(pwd)" -mkdir -p output - -docker run \ - --mount type=bind,source="$MENDER_CONVERT_DIR,target=/mender-convert" \ - --privileged=true \ - --cap-add=SYS_MODULE \ - -v /dev:/dev \ - -v /lib/modules:/lib/modules:ro \ - $IMAGE_NAME "$@" diff --git a/files/init_resize.sh b/files/init_resize.sh deleted file mode 100644 index fb83634..0000000 --- a/files/init_resize.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/sh - -reboot_pi () { - umount /uboot - sync - echo b > /proc/sysrq-trigger - sleep 5 - exit 0 -} - -check_commands () { - if ! command -v whiptail > /dev/null; then - FAIL_REASON="whiptail not found" - sleep 5 - return 1 - fi - for COMMAND in grep cut sed parted fdisk; do - if ! command -v $COMMAND > /dev/null; then - FAIL_REASON="$COMMAND not found" - return 1 - fi - done - return 0 -} - -get_variables () { - # /sys/block/mmcblk0/mmcblk0p4/ - ROOT_PART_NAME="mmcblk0p4" - ROOT_DEV_NAME="mmcblk0" - ROOT_DEV="/dev/${ROOT_DEV_NAME}" - ROOT_PART_NUM=`cat /sys/block/${ROOT_DEV_NAME}/${ROOT_PART_NAME}/partition` - - BOOT_PART_DEV=`cat /proc/mounts | grep " /uboot " | cut -d " " -f 1` - BOOT_PART_NAME=`echo $BOOT_PART_DEV | cut -d "/" -f 3` - BOOT_DEV_NAME=`echo /sys/block/*/${BOOT_PART_NAME} | cut -d "/" -f 4` - BOOT_PART_NUM=`cat /sys/block/${BOOT_DEV_NAME}/${BOOT_PART_NAME}/partition` - - ROOT_DEV_SIZE=`cat /sys/block/${ROOT_DEV_NAME}/size` - TARGET_END=`expr $ROOT_DEV_SIZE - 1` - - PARTITION_TABLE=`parted -m $ROOT_DEV unit s print | tr -d 's'` - - LAST_PART_NUM=`echo "$PARTITION_TABLE" | tail -n 1 | cut -d ":" -f 1` - - ROOT_PART_LINE=`echo "$PARTITION_TABLE" | grep -e "^${ROOT_PART_NUM}:"` - ROOT_PART_START=`echo $ROOT_PART_LINE | cut -d ":" -f 2` - ROOT_PART_END=`echo $ROOT_PART_LINE | cut -d ":" -f 3` -} - -check_variables () { - if [ $ROOT_PART_NUM -ne $LAST_PART_NUM ]; then - FAIL_REASON="Data partition should be last partition" - return 1 - fi - - if [ $ROOT_PART_END -gt $TARGET_END ]; then - FAIL_REASON="Data partition runs past the end of device" - return 1 - fi - - if [ ! -b $ROOT_DEV ] || [ ! -b $ROOT_PART_DEV ] || [ ! -b $BOOT_PART_DEV ] ; then - FAIL_REASON="Could not determine partitions" - return 1 - fi -} - -main () { - get_variables - - if ! check_variables; then - return 1 - fi - - if [ $ROOT_PART_END -eq $TARGET_END ]; then - reboot_pi - fi - - if ! parted -m $ROOT_DEV u s resizepart $ROOT_PART_NUM $TARGET_END; then - FAIL_REASON="Data partition resize failed" - return 1 - fi - - return 0 -} - -mount -t proc proc /proc -mount -t sysfs sys /sys - -mount /uboot -sed -i 's| init=/usr/lib/raspi-config/init_resize.sh||' /uboot/cmdline.txt -sed -i 's| sdhci\.debug_quirks2=4||' ${output_dir}/cmdline.txt -if ! grep -q splash /uboot/cmdline.txt; then - sed -i "s/ quiet//g" /uboot/cmdline.txt -fi -mount /uboot -o remount,ro -sync - -echo 1 > /proc/sys/kernel/sysrq - -if ! check_commands; then - reboot_pi -fi - -if main; then - whiptail --infobox "Resized data partition. Rebooting in 5 seconds..." 20 60 - sleep 5 -else - sleep 5 - whiptail --msgbox "Could not expand filesystem, please try raspi-config.\n${FAIL_REASON}" 20 60 -fi - -reboot_pi diff --git a/files/resizefs.service b/files/resizefs.service deleted file mode 100644 index b1950c1..0000000 --- a/files/resizefs.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Expand data partition file system -After=mender.service - -[Service] -Type=simple -User=root -Group=root -ExecStart=/bin/sh -c 'sleep 1 ; /usr/sbin/resizefs.sh start' -RemainAfterExit=true - -[Install] -WantedBy=multi-user.target diff --git a/files/resizefs.sh b/files/resizefs.sh deleted file mode 100644 index 88e546b..0000000 --- a/files/resizefs.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: resizefs -# Required-Start: -# Required-Stop: -# Default-Start: 3 -# Default-Stop: -# Short-Description: Resize the data filesystem to fill partition -# Description: -### END INIT INFO - -. /lib/lsb/init-functions - -case "$1" in - start) - log_daemon_msg "Starting resizefs service (once)" - DISK=$(lsblk -f | sed -n '2{p;q}') - DISK_DEV="/dev/$DISK" - DISK_SIZE=$(blockdev --getsize $DISK_DEV) - DATA_PART_DEV=$(findmnt /data -o source -n) - DATA_PART=$(basename $DATA_PART_DEV) - DATA_PART_START=$(parted -m $DISK_DEV unit s print | tr -d 's' | tail -n 1 | cut -d ":" -f 2) - DATA_PART_SIZE=$(blockdev --getsize $DATA_PART_DEV) - FREE_SPACE=`expr $DISK_SIZE - $DATA_PART_START - $DATA_PART_SIZE` - - if [ $FREE_SPACE -eq 0 ]; then - log_daemon_msg "Data partition already resized, aborting" - else - resize2fs $DATA_PART_DEV - FSSIZEMEG=`expr $FREE_SPACE + $DATA_PART_SIZE` - FSSIZEMEG=`expr $FSSIZEMEG / 2 / 1024`"M" - log_daemon_msg "Resizing $DATA_PART finished, new size is $FSSIZEMEG" - fi - - systemctl --no-reload disable resizefs.service - log_end_msg $? - ;; - *) - echo "Usage: $0 start" >&2 - exit 3 - ;; -esac diff --git a/files/uboot_debian_9.4/MLO b/files/uboot_debian_9.4/MLO deleted file mode 100644 index 5ef1144360dffa3117e57f485038eb5c9126bca6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91876 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 B-?`9%YtuOeItqQuw}g92%< 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 SD*D+Ev-ul*R;#oVKK}zUNUyp8 diff --git a/files/uboot_debian_9.4/u-boot.img b/files/uboot_debian_9.4/u-boot.img deleted file mode 100644 index 33e39aa63db818c2eef4839e4ba146cbc082f8e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 432064 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

t?xI@05Ylu!t>k5++EHU%qP@Y5UE9JSm-DVqy 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ÐPm0Nv`7o(=E!n=d^JEMACH~nu;d>su-V;tC~a=I z5Sp?qpzZCS;Mh@*S4`6v->dtu3j!W=_QrrOfO>o;TFjSD`w;rfWd z`jT<#HT(W-d{Y_@OY8f2{W(8# zLk8DHY3+@8CmbZ&dn0h|k1UwPeVv(?j$M|0r$=uMwr*8Z~Q zfA4~W(!|J|+C*@mLej!WuK0_Z^|0VM2u;7Rw6>oU??C<~k=fQeYU}Ih-58l&8*g9a zo{c`Ry6OH7YC>K=2hxMOmz87((O)`{iqF6bmvKYS5hA6(t?TfZ55_KP8xzQ6{{j~vDLprwpB zlLKpBH}HqnwIA@Lu@2!`{9FtNr{PI^I<0fGCQb%El;Zg?!fBtQ{h=A}y8tBLBw3~p z@3hwk@QeUx&nMhX$I}QPJen9-AH`+DE5f%YuL0K)PWVUj<@%aRbA;##vMR+Dkrf8A zTtD(GufN+KUwaaxv}2SUzW)UAZud0%vli8v67eJZ?&&0zCR*}SDG;?BO?2Ki)=$pzwZ3!gI+f&C@ig&9|GTG*9C-Yo=*r&E2CSH+FNn+t1<2Eo5vm z$7XhCGPYgDlDo4QQzuVd)~&g5S+`7A*~OWf&m)iS)Y9f|rfWV=X*p)r@w&CSujBo7 zyzj(&E;q9~mow`Oxd_Mm>v-RZcUV_EZzyd^&P{1f{vi^{l(FIRSu@XAb1Ky(8D)*u zEj(u$t{Y>wpXUzhx++i?rdeR2x{juIQ%g59*(@BJ-92i!zB;NezE2&oteY`Q7l%3~ zYnr=Lbf_<*`p)j=OqDtrbD_SoyI;rq4!q}bv%7OkDsgZ`INo2!`wqM_Hv7C@|5JS# zn|Gcun}zDh*c8C^_vW%sMl^FAbMZfK1EnuRJFchWXBJ=F8Hw~NW_DcIDC4_$&9p8` zPvJ-ZFX5`L;;)x5Hb8Y(1z!E?`Z%I*rj_u`wcj0xovm{xp|Ke)O3ZuA3Z zo^_7RJaSIP(z@j=m79bx{@|wW@zJ>E^K2%-25_KXWV5MnN*J5PDHto_F~0g+*LBPE z&E4`@&E0vwZ0r^+&D~cbkscZM-)YyGn!9&QUDv%9ecU*+x%-V@HFmEz$I|lb_HG%Q z$zgCOJn^Eb;})3cQe!lWvO?~Z0Ww&+|n%^+={eJy%XcQ5P1PVdVpgXuV$oc z?p9(P18X`i$nbm{eTA{b_@n-s=JOOTm|2&6Cf7x6lIb=BFPk~U@w~2?la;r0Yiv)+ z^aagagr%HU(R*GqHv;ddk4&#`Mjcbm%ji9q#xdnQhj*Rh{&OZpb9eF$s0VX(m!vm$ z3n*8PIz`JI9vi9y>Uy5)L*XImiT4@)E=y-T5&VHFpr7<7#2$>9ufO~h6b;e-7|z(8 z->!8{1f&8k_pWsv1GoV%1781rtt+{2t*h;awXRj)t#!>nSS{X%2G_c7#(Q6At?Pw> zwJypoAHTV)YhBZ>taW`FUhBGrt#i41*1EPL-~U0ni+DbR-^&4W0I%b_7bJXhZLMqH zrM0d?KqJ0Cc6qJKhcXWhAum7$(&hr>fW@fK^>*fG!^bG#S2wJ4Wn`>#wQ1M6s_}k1 zo{e~x0CE9u+|uZJ8}KgR0N@bdAAo-YJ_DQudgo$(5;KY*hwNm>m04)ck+!y$4`i#kD^?GOoe~Lx2zn$#oHyjU=nM zAtTVL*}`g3!3IN?)$U4Kyp1iEWN;!;5>hA$kA!p*LV8FDp@jf;I%$NKKnNj_%1a@I zygX7K|KIP-%-y@Il`NYi-~WBzxAy4XnLFjonKNh3In(T0;S*^Zi>8@4X-b+#^>j;N z`v2emzZ3(>pGaGl5d3{}rLDow@qU85V+>I0C;DAo^OF|&7X6Vt7Vw*cn-lo-hBX!m zJO6~K@g|Cd-B2Wq`Q!KC6B85ifMT=MA&_AKz}>p zl8LY3dD7xbCcca3gQeh&=xev(`564~!t-f7V|YSt!PW$&mcv!RIdE&>R>EPNR*-XW zJOd_X;40yk!JPtE2DcWDzjstG7_A5#@w+d)X3@J|@s-$utDnChx&Ef$vo~HBdVlQ| zPaN^#JAX9(s%Ibl$rX=3^v+W{ZeMiI#kag}LFJvleA`L)T@zY*$4P&5K6}B|3-9{V zkA3%Ew)c@Ap786RJsEq=ZI3+v^~)c=^sMWnFWdLAU71+__M=K+w#cVZU4A@$wRwtE4}HjAG>XR z^!m>=egFQupJ;sHi=X;w^s(CPxlgq|u;lwcI=kV)PkyTU@ssP-k6(kuy5Bf1@V)zP zd;aswR($2wv)*;x7alnBrhD#u|DAKn7hW;X|GCE(e{JQnhu`wXixX>)>KNJa$&&*6 z8!CrxzsC2Y-SaPeqU4LtL)Wia`sj0Sy8M<4Uwzx{^KbgueIKZM7#`>t0Yt zUiGm>?>PSYBc8r{$px>kY=|vNXoJb`1uiuY9aJe0i4|{Nr!0n;*UC zrjir)Kfmyj?O!?a&tH4|v*Dg+?>PED@4WXd7hiGL-=8|^$-(x@A0GRsiywY#xZ{z( z?Ff9X^SiIPtv;i^c;hqGcR%90>8Ue+aNT1Kv9CP%;lDlq{f94jHq!j}$K&hTt{DFG z_wGFZhv~|>Ek8f$usVN7=_l^Lc*&EeT{y4j6TUgCmM%T~-Zwal?=QP;Wc#g`C!9r( z4BhpCp9Q{q#0x)u?e+IRzIyrf-}~(6KlX#Kzr5krvnQ8)zH0Ni_uTR6=oj`mm)`l? z+i$(^-HV^O{jhgGbW7&cEsy@^XGR}--?1k@G56Brew04?@Ze7`+Z_6j(=UiE`PexZ z>^b~_BYyV27Z+W->Sk4X%ljAXZMpWy-#>KY!Z(imvE)_%^QHNb^R^HEMG zU-8TNyW+b~eB^(Aa>~PRI%m%hmwx-qCx;VH-Sxr?&)s`f^SyVx{L!mEd;YI({Qmb} zckP28{K}Ue+tmBVr@H?zeD{OH+rRjcC+FXG#&(M8oWEzT z@5|4f|J1-!!ykL@s(8)#y^*%J-WvGU36~Ci@rH*IWgDIu>Ah}r@wX4#a`@eM9XDtB z+LPxE+`IV;UoAiUp3lAgoX?*!_kvr`{pgE7_)^US-@ENC?|;1Fq?>=d^Rr(Hz31dV z27mM38!yO~UK^Y9@%fA1d&Y(%etr4yg4D~lt9h54dEa%%?78!qn@_prqD?2>zW6;? zJ@ob^_dfdbJD&T|#mk<0;_ycvdiV`Z&ph&n|GxFfk@%%QeD!yZyLWQu$#?zN)1#kF zjBdH(_+Ol}@QUOGN51&Y&GU!OJ-pz3@{jl2^X4yo;hWXh-rDz(8$Z8t-iGge;oA8>_|EF>KkmP8 z`0*80dxmbk^UT0k=A1Zk-hZ5uShMlo!$1GQs}_Ix#HZ$+bLDe$DxY6^*+eOLK=dfg zU*lPE^koy|znkzRzdaYv#d!Y4JgBKH6*Q$cl&Hq0BNflj z~mN)F>z1tB@-{;+vCqp zPF#81_GPx;1pK7M zEAU)`=hb+!jVVWS{C_W=3-SCAo`>W4OFS{htv-b(Y5Z0^kHGV8JdebaayFk|gP#QO zhw^2` zic2PLEx%;q+LNIN!kuvnbV2y9Tyx0;qN>-IT{3YK+@lqjOzeWQ@e-BL_23_cV?6u& z3*yd0K8xTO_G&yYT$LZ^YUl^=hWjww-Ea@W{R-}{aEn3buY#+AYlhnncj>PuCyxEi z@BmO#Uv19uqQT)6pg3*buO4u@L|w*>AuxFg_>f;$Fo&YTjY#ff5Yhr!K- zn+J#dN|0X(^232uB_+rcKg7a6#4EW2aIoC3n&-pj$uRy_e{gc*mJd%(JpGZ$i6wad z#|@JcK(D&8SJNoznf|xJPg=G9i{K~CTK_fhlV+`d5`NOI^o|J&gw&C}1{scSD2I0+knzk@DFy0-p5z;Dy?`}6RV{tfM`zrfFaVf}xF zpM8mO2phv$M?MJ)^I{$OWZm#kmzyW+W^u&l)y7YlS;jlelXYbN?=w%ls;hVEv>(Qk zW!;G<%lIaqjQb-zna5%0vi?U({l1Cu>j-s(yl=qwB^WU#5$6oNFII~syc_R_tHb5} z9K2(psJw^qzDO;S_ZZ$6s)h32@p88B0(l=tILkZ(?sq$KUh2zg2!@lKpG-U8%l@%%NEW${ed zY<&rXtuMoEeJ@5nw!T+N{u2{=JGiI|be9N3{8xJJ11 z;U?hr!I_A}Ieuj6@;tls(urr`{?T&j#HZl`ZI@20#`7P|aF<~Y!#M`=mc% zZ!CoK1+`Ja3-f1HwZL@0kiu zjN#``g=e>fPlf085JVeKIzw2+u`Z_rKJqdZ{O4tcV2k*x71~`JhXauq< z-dWSn;`s?UlGf+(ybF%w$Gv!d8IEJcH}HHIj=bx~c>WY_KHh(Y=W}rE-+#li1hzqr zWsC4U%DlhAyptYI!uxVKj%UwcTsQ^q9Ls9)+yuvQ>~uWa;7Eskc%BPK*(;3aE;wTR zLOe&|h~>R_UIItTy9Uqe;fUoM@calIF}n`WdN^Y9b9mki#}>T{&wX&Tr*poI4#8^9 zUep7QxH<;U6X1x$Q}C>YBib} zm3U`ab$Hgp5q=+@t#E|D3(tNy%APy%48Rd5!+6Hw*hX1A_reixm*e>+I4=y80WJbu zm%*`(-m~TMiFe?gFdT`vE8*BiA4S+_;F$kDJih@)*eFx~81F3W*Lc1F$96pab(c>p zgJV0c$MbYJyeigr2i}RFAv~jSq^rGnz7dWz^L{)(3P*g>?!6E1q^obWU_A)l*`|-; z`3xNK|2KYz&6;%b3Otv?vA*l@Y=9$v&cZVQM>^S!=L8(-InVoj@7#wBoF+4AZo*!^Ea*PZqGww-tE`RFU&x#^8h z{pEjt`Mw`~@#|mN`tu!c82RW}^y^ABn#4;-7VV_1xtZhn;r* zV&5xo{_WNO_|12|^W>UOAAZlsmF@3)=j(2dKl<9|yIyvBZPjaDl|14DFW&pylTZEq zffMhm|IFDR7`yt4w|#u_o45S>gNq-m+~4(w#M2W?Kd8P`{ZnUdPg!GIa`^naF1`NR zzuox5TN}Ro%7&*=M|4G z`RX(4zP$2=VysaE*%974e{9vrzT=->c*&+4%lCfk+$YZX z^{f8&!do7D&)uJV_ubhu`_I{U!Et;3Q2MC`l^2%`P=A|o!|MyJ#YE+uikh6 zl_y`kAR0Qiwc|slU0U&zSMFc@>gP^>@w^8ve(F7+`NDmVU;W=7czJxo>jt_quf4YF zbEiLe#P2~i`}a-mZ!9VK^1j0+=J>u;^0j^QCl>g=uIBCk>f~1%=azhX-{OfSzVE0b z_dhWC-NqwS>Hcp{eyj2DlKb~9npo)jM#*FQj-Pmi?{RhF{wF4X*m#0^)&3t(KGpc@ zk|+0_H1SH`kJK^yADMi#@z|0d?0fmdalY@DJhboViI@2vR!8lBaPoVNOG|#guX>`! z_XkzC|4);DY^+rq_W#%9Um7=-{CVH{iFLl`)oJ_xKKYNvhLRWeoiTB`?|(}Ey03m> zv+r-})cr3^{&(XhRlfgMlg~D;F8TGoQzq8<{H0^`kqsj`+qz6o5qTgpY2;Y zQRe%(TDAX|lfP&@SuNlH%;ZlSSCl-xZ`p+7`$@?S`_7*T_&%tD`){25P~)H)+W(Qs zk2VgM+_Wz|5%PUlMfZPd^3#p6lF#f*OvHURmwaO11rxh`pHz|kAD{eK~ zjpHSE@4IMXkM9d5_wIY$#OrxQ zjp>qG_FXuU^nF(K?7wF6ZH=!fxprUQM6d7dCGXgG*2H$-JJrDc>n8uBvA^WK`_7#> z&-Xs%-~WNh_cy*)owNVllkaKVS@N!ZXHV?#U0-s=zO57OzBj3D``(8`6UZW7MCn7Iljcf%HGD3^T|Dyntw+j z<68<&f-_m&{>g7;wUpDV3b>h5| zrAN)fjpFl4<{mrGr%swz(ztZqVd{7&!^g~9rd~O(#5sE2B6Y&Nl7+|3n^cV$IF`7^zitYMolIHmHrT?41e>HK}IRqFPlOVrU%B2No9skEQBx z;POb||2=io z0*s{#N8rlg|16%!VBr;TTjBpb(qoKV*bj%6TliC?KLzg@xOMpc4W!4|y)Xo~68?|j z$@rJSwZQ)?q-TET!eLBWbiF!eK_A{PhC2=Z$50=Pc?+X(74YAQ=VG|G!gaupgGm-( z{9V`!cQnes5#_JIJKADlExvyRMD{!;|p739cRfKO#Nba{%sGwR9oQJD2v)!oMEhziHY( z41XE?pTLv&x*V<*{{KXJw*Pr>kXshL+qC~)_#5E=p=tjZ{FU&30Z-D?m2jQ#{}t)k z{-l|gq5fYs?VpAp?Xc);ru~W274UxqPsYC#t{MJcAU)fECmis+=pCm0FM@wF{NFe2 zzYBiQ^`hJHBt5+aZX5jnh4ie?cDR>&+J6-Ojrjgu)BeNouY&((JXziw;kLm4JESK* z{cz~Fi{5YA|Ml>n0soIp`zPRE3;(@%lAf-H>xTb-4$%MiBY(F4`EU;6e-KXvHv!iO z|I_%+_TK?_Jp6An?LP+pCiovT?LPv4IsCWa$@aPeZY%tMKzg?Sbp8K+)BYjES&8@` z$CL3dgKL5RS)^xv=fb@b{&$)7zZm}0;D6k-e-!=-`0v7VG2C0>I^cf+>Divs_5ZJ$ z_8&x?<%oY1o^#+Xfop>Q=Sa`?I0x@H-y%KR|Fv+hg8zM{{a*+F>F_^k+CL6|75w+$ zc?8^5a9!~K;{g5t%gCSb2H=(<{*8E+z)iyW;KyRIy#9Y}LH~!aCHy~v_^T2BRy+ys zo8a2v{}a-)J*Vsc-!knVMw~Ll|0JHo*X3}n@c$a=+5YFjodo}TO#APJzXARyO#8>+ zuY~_@JeR;-3D*h#-;kc|KVAR-x@rF);;caYkK)Prm%=r}|4XE2`|pH15&n0Y_P+@J z&G7%gwEr&nPl5jqJP(I^3*0vN|AO?a&vgC&0n`4&h_eduKZ7UBdn4Qy_@6_1;?ws3 z51971{r@S`{t3ici}?59c_iG`aNY2~=t@yuY064eR;sd+m6fh2VJ%hntFPcMWiMnV zGTeMfAM+r8%vFmal`MgLM{Dwt>NM4*25^gNhXPHiN0;4x%X|NDlkd{QA3wGt@`<0E zTm7LMzW3{&-&NQ0#(g8V-*NK0zK%$$1PAfYo4;V;qSC_`FFE2!TylhYqXqM=pHc8D zp<*e&x%%-xc+7eIi?Hg>Jx1M?KIs>i-T3V@Z~o*ZzbgOJ;9G`58UIjZESvPl!m&hZ z+&>tI?@Fsscy}Zi_9s(`!7x4k;c&*Ej0Q5HKqin2NJVzLo@_80NT-nmVTo8ES-Z|3 zsSWzm;Y>Oi4nvw7iukkeXA()3O%L(|N)3h6!BixfNu*RP7W7Brkqn}w!hx7%;vY%p zf|)>KrNT(;4<_Q7R3aJ;r~E_dyy)q0Jme3?LMk+r703s(L-IbFie$nji$KUPl}W`z zku)-k#R5!~h$W+8L}F5aq4OAuM5F$2JQK-`OKQnSCuda+lmb*V5!|K1nGyeBBp#B; zNF4T~(#%mOjD28g=gnuxR$m|~TgUVEREVB+Dqlsbv1&M4b z9*C+?0%_bY$!rF-%>;C-u7JMeWHOK$F<;Z+Kq@%mN58RX5TcV-5Hv;7yZpo1NJu3EDRksiB%bl3LuxN$ zMB+mU31LH`uuM3ZiR=a~4yKgm5oqK@%1?Zt_Qa1VI}|3Jpi8DTMfyXD>>wx}i?@xsl-%X2-pt|8yTA>R{Xdnt8g|ZPFB)~v)yi_DCagrd$-4ciFL~{YO z6e*Bo7PQBA!+w8CpMUd4VG^#TcNu@JRawL!r zJ3-Pz>GW~U_l5RX&Y$(s~T2C;?C|sDiQ!GIP9Lz^0M^u zQXG8eGza3VGEPhy*(nP-gX5WSTE6J!0Xqw)GHewladW9~!l_g|(NGpDRb`cH(v?mb zQVqm+#S^1($MA1wRattKQ|V+<c31R7vRbP_`j zpm6eXNSBtXxhv0q4Ob$}wv(k3AR zsdwa8HpZHoZ~}|2&QCfV@4&#Z81IC5vVqb5M z(;FtK1{2wM#tDxFCE8{O5|JbS%`+O+f%zaZfsaB#W;% z(S;R|^*Sriy|NVsDR?E6jw*`+fBbHfu_c&^$W(`r3)5x7AQNV^W{uN?*3^(YkXVC} zAq?Od&=Kp6|7+H`v9@k^IF4fcz}ExBH96+;(9J{fnuT^H3d#hPup~CF1?phS5+*|S z=m8t$KS1yRr9+!dD6Af)z&T_cBiwurL|P`Z5vooU8_24s(ogh z2CP;t<;c<8)3@D8gY^eTz>n+d*6;B5ZIhRp^-WF1(+u=A`CI$9w)U1%en)w|TXH4p z5H#BE+WZd?x#L<8CF|1N%jtuF8w5jX4~BapplEd8aK?dj;Ut36NkZs$(i7dNTcQc9 z5(f{!_zBtA84aXjvq?7^KpjJg;n~DBWk}Y*&n%$oNsNY5m7wzCar>K{y4r2c9oyV$ zv>NzXzo}o_NZRu(6_V@JG_|ba)=KkIe9nv|lqadWMwcp>jy}iGAt0!8|*0cS+t$nTi zs;OzqcGZ*!q(G5P;lOY-+?0riou(+H@>12b-KRPs1!EZL3&a6dHsp=f8Xuub25?NI z?qDXcJK^+=Lv@O!o$kICAYfBvUuR`+Yl|DpmV-j85~*RQ2mCIa(V-e=O&wdBZJs*3 zgKCFn`%vYfPGv@f6i+iRr`sW?$~lXoGnkqy@wQeDWg+r*`kIC4Ya}5?IW~7{x5NuU zRuj_z0*7T-Wuyj3Kw4apHyQWZU>^WO1qU;IxgYw7Gn7iioDK+x!EvWu#GpXNfv^*W zSOLw#(Ha0`CunHtYz(8B7V!CPN?=y!Ama^26NidrF3c(-ur`=LDg}CUvay*hRDqP? z{uD@y!;P_K(8+-+Lt(ws643+M5Y!u#Z{&mGS(GYZlKhT%%%=GlR7;pSkm<}ecYq-+R05K2lFTO|k~Ndyfe%VQXc52FagQEPS2Bx(1^ zDWgr(h^BfQN+BYP4gfrPIE2!pJWvO2F%3)_jh;jx5eN3jU|70n(!d5vN0+k|@J44P z+*lfX_Cs0)3|)(;EP}YaMI$lrQdgE%u29boEgzlovg~SCXs>cKjDcu|iNF{z$mKk0 zM|+PlfDuM5oQYry-$2~5E>b_f$p_udGYROIP+lQUMB*d{@ayL8uD13q{=T#O{7v26 z{hj`f)-J7%X5E~0i^_=DnT4_|gPJqQ@r*hIOfzJI7^Y1(b6eANNe8WDcyXy}PGli| zQ-U{)Pm6<|mMfLovGfB}ONk^xiWTp122)@e!2s&Vp}$nCQ<(_t4by8=RNGC>9Oy-kh^l4K=WD8J ztLhX#4|p|yW8R{$52~Yt7SBLyh-i#!qXjh?ww?Z}zYJq6ghIu1V7ob=e|If2qKVQG z>!t<>!i2VzNQ;AUQ9;!?boHqReQ0hkS?v|RKsb88idP`pp7s{Uig*hHzpdgk;2bHw4v}& z00XI`jkl;i1ghc{u#KrrJ*d5IAWid4{k?5{FkbJJ>tRu1+D(3c1qmTc`OT8oQ*h=v10=0k;(hMA5!J`G?R<+=KZ;tzWq z7+TlHz;nUbKs)%ev`LJK@K7z}R=Zon+E0Z<^&_HRhdW0f|%(gp1-5gXZ}Q1+pIq(#K4 z(vawR1Q~~NpUTq86^N}d$yPvPjkP$-ouEM05l;M49*6eGk1Vb*%x0Ac$Ec2R##p7o z6iq7mhv*KcB(-TnntgNxhum5<`)f~lS)Yjf_5`hn4yr8_qc|_?rtIk^mF%@hS zwCf4BK?8Bv{lr#eW2M!_Rj*yS=9DwaSHobhS!jAK42^4t10hV-t|hCIiTSFaY8u$W z_5^*Dh1Qm(%gJRBwhU9vn6Coo24#`$qV5=Cxe`O(h|nwu9<47C+37q{VGYs}4CWQG zgV2OTpi7OR71FRZjRvqx16AcHh&f^OXiQJ^L+ZvvTd4{r)1&wkiUl~6EZ-=R%eTI4 zyfYE+&xW^$L;WM!wp64qU=^l@$dH4nz>KrJ6~OqB>bVcW*>=XiyD-7|eHL+9T@#YzS-~p+u@76H)0zPy)xs z#E2qRv+A);$d*5)ReesVr~Ih~&j(b)#@%G%Qi0Azw4td`E}n#0%|0)#{-Rge*!Viz zYLy(rG&<($b9qv4ED%Xk1$F)5c%C=QEcOa?4L!czehPZXgkwDE^YO%2K`@w_ADqww3UAY z;@z_TX{g5(lC0v2MyG(k@}k^F;aThgB$$^#J8RJc*TM|wq()~$*P3}Wu=7;mU1>i# z2Re`T>=hoz7$&lap3`*ol^5|VnGWlb%Wdyw;V>qLaBw8y^k(CnOP9W{!?pbsol}nz znt5Q1#;m!_x*Pzy>z}Vjf0F0?%M6w_Sq7qLZ`K>Y_cB zl46mDf+EM*N{(G_>3Cg?*e$K5IkX9a#GETW@5|oV6rHPoep<*JFdP#qT`Pf42SOG%*uZ#=HK#-2)Ls)k znS=(s@*@Qn?ps&w1%D|}cf$XbLN zATa*xs!9zf8%wiS2-Tr1aw_VKeZDqmcSiFa=}=L19m@QOj)e`Lq)18mi|xtGHQ)7+lqXQoTo4~Hd5h~nHqbiA zCPkOiJse)mN?1}J113GW6d!k1aH=3 zhOLs=bz^!INFp}s(8xohi4zXPOtd}_*zDv&*Ex0T>+o9#DJ2)W$ypa%w{czVdJqei zUSWqNZs-f+n+??X9v}u*}HSc%Bc;Z1UM|Pv- z@grF@?9>q5TDnhzk)Uw^OCVYi2mj86b47j853n10KiJs-Ox+9i+1hz<>$T1vK$Sry z=zyD;TuE|e5!QuqZg6lAJ4~=?&5Q^vz~m6h#*)VTr(4Iw^F(24%?0x!nv`6%sRu-N zjGY#U=szC{02hUo6KwwPljA|I%9@9E5XyO^6TzuojE@!d9%u>s{?YYD7!MoXpE&`m$nGQdvSc>1JJc) zYqgzTD2^(sn_wKlT^gKlv;gfo8!Q$+a5lqOpAnxqo1SX0U#U)UXiUSo*qH{LE!%5+ zGv>ou2{@IbSQ!K(ReDCaeC@uO;R=9RMP|&R^*~w74$*zB)ic*Djkz?g#;zP3G!!%q zjyhYbH_Q%4GuDfn5N6C~cRILfeO(O@G-E#9eFtdzL^>o(#?!INR5)bwfNP`c9$6&HoQBgNonSMxPRtA`J@etoH-|M`j{~%*<@1$COd>RU>%rI zSo8DAjg~S9Hp$RnI)^(hIIXaKxst5S(+rC_Di1@ssWjHq94yK^vs@^ddWOrXbu?1C zLp{3A)uUmME#7(9bW_J%Zzk)!ndF#&H%d-lr=3G-)xe*xS3pf29xVt{&?;g9DD<`K z*H>9rtwykPmvwAV+F;ngJyEhz4TTOhB!-3*6;^K2Z&*8$h=s9a0jfi2EmhrcrmL+_ zWri|1@&Vsf99#9F=VIMUx}kzfLPH(Hn1Ru7^X8FZl^RQBf{bzqTJFJ54vW12g>iz+ z0~6-ryfE%{j2EU4^S0Lkepg-;Nm3&O8>}hmQ=((cpp$W{agdtdyAGKUJ0?ma6 z!+WJfi^7~;iOStY!Ds~Qn3yF}yKY&&aj7=jHJ3F*MDLF$-2S68 zmqK&pxL>u-ngn@Kv1XBrBm39chZb|zuk$V)q0KUvLp{WG%X_Dvq*@F6%33g_05l}8R1PpCyBcy< zJ^$k_!^OI&dS|VjTo(G7ML{;cDF-P?)9fWgL~cqYSGo0@g>pL(MNhBT4Mp0(=0dQU z8BLjCk+d$%D9+BMVAU>h#~CLVY?;;2(=h04f`}X(5TYfsUNcp1Ghz-b+A}FLrBIhs zaVd4tV%-?F;5?wf2yD3NqIN_FaqydzsCOad_=Qvs4VPDkynHS7n#$(Y&oFb#KO{5O zvml(5Q7m0ye8!uOh`@;CbR<1AxDZY|4UEoa5=?2O^|mYM2;{No3^q35x3s3i@`y_Z z+3CAn4tw)a$XrORCWq;2#V9#Q^C@lms^zDeRsCcNBv+D9jD_+36gby-oZ?2CX0CN_SB8VeOyv$UO!je6L z`Be|V8l7%N;0Fg@_mW3ONKwF}q*2`*T>>Y+@pNtJMxpRv7F$_%A{+u1zlvGMv1lsR z@nuUMj)ssVR$9<)VLE3X2h;+AWkqPH{2EVXi8_JhKzZ!Mup_fZ&k=zVtveXqmA+>l)&*@&khPBC{Oa(zUbc)Y@od5DpvlE2a16=@b9b z!dWm5c#GlOldy-ikR`*`RLNb2v(W`ael-2)Agj;jA!qyd)!CMaIrV=jZf!aLhGPEN zMa&W})*4|qpm3OT$(-!as6V-(K(C-gb7KIogmNBsLx-I4L{{&)#wH`~kH-e8==d4A zq0zIn&CWDg9td=|(n5T5n7Vx>3K z$YNd*OAO)UJAA(g!zyWw9X=E);*djrYY_K z-Ff{%m&Fu^R@R1tE{iD+t*ng)T^3W!zAR2P+9L8$T%1{ZqaP$0OVUH(e@r-Q;xzyg z0mX;q;v@6!NGO~*2t4G)KS)IAw1<-@P&iv7C7DNAh6SZ5yVe#q0Eb%XOq^JNEn;*ESh=obH++bX+?>M(O_RTIk`#; zPCB$l1WOFFosg&XSyXbKLfCa)vAPZN;qzlrq6H!^@_|Kh^5wISOTtQ&k3gx@9-fK??E+g5i}o6`hsS9i4`6_#2U|{`*?(ugX}@Wqv*2U z9x%PIShNQ*{dRA9AZfPU=Osbi`VygTErfdd*0ohC%Ih(|?(Cdl9D#(zt@-)0j||ai z$ncT>K^9>IlJx8{HzcnQfRNKTaYQ+`JRbCv24@V+EQ))YgwUH{rsyQHiI=mJGgc~; zZ{PKtlA^ItQ$|@!)mEgRxY#e)Zn2M3D>hl&S>iw6%C4X$DPOhs%>aeUVl$9GL}eAg7mcTI78*A&Nh zO>unVXw;%`7sq!^aeUVl$9GL}eAg7mcTI78*I0bJgzs*cJ^=M|&%1P@eCl7neo8P~ zqpogBFk3?wX0RvbGGS|Q=X^olY>gtBur-PVvo-3bLc-QqS34zdw#GUx5y^*yt+9@W zn&bzwHL&nJ$0~BWxN-MJeq1(DkpkI7MRH~n6{$L#s18tjn#gX?;nj^r znbW&kmj2nC#o}%Y1L%Yf81UBH)?jai?9O84aHPs8w}gd8f=R+hV2kWH!k5uRYM0h< zjH;El--_wA*5XA+UI;4a`dOhOhoImfW?7OXIFY-DaYKo@`;}9CslX^_?;JdF(pcTb z^);u~ZP-kh<;-O)T(8-zTgCcoH+Ob)<6P;Ce8YPc(@J_C8w-I5e>Z34cxt+PQ5RL2e^k;JnF+Q8LJeN$be2009bgTD>;V;f2 zvkH&tO$f}LLq_d`r{c-|(LBeRZRqEY2P!9WXcnynINloflwU`?Z%M21FZKt$X?s0SQd`Tu0nudW>&DT zyr>{M;Ztr!^D0q1Zb5AnYr`9@x%|J#QKvIj4Ita1fd!mhgzd+e?_zHFq=ylcHI6vv z*KoRFEjD>%2F+i&RnyQbIfF0*;#9{p z>wB41N4Kv<4*G0u!8JPQK3L9P91Rt80bA}Nw7J_AZT|TMd1uCT z^B*uluDK0Zrm_2)d)s^Zr*CSF!+>9-;b7TIQRG>iqVu^2S$iVpV^M!dH?Sw`ciodc zB*Se{FS!@%yzNjbmT-+(bH=SH+r_h|5-w^jmS%}sLLCq1SC`e&Qga{JsT>GC%W+C~ z%>sTWSh9UmqiKpnU`edVXl;S)eo? z6X5U*;Y4=8(=5e-8c$q@2xmmr#6j zSjh={CJZG41eR|C2&A+}b$tys;aYliAtDDY03Jv_0Pr>cQs7a3A@DWDfd{vjBV>j2 z@}{AzZ?>9GK*EsZHcnPNUNz&x=q`c0p=Dm z-rI${fI~R&-oPdCkpXTd#ig?DuV3!O!hQ2r4pv)v32X~gYt`K1^mccuZXCrF#5G(k zQa{y?wP$Jt?)t6W;jB<@MtErsByquUW*ntNvsG|TXA@3Qw4Ns!U}t}mpbfe@E;=@?i5 zq0@@yy{as|iix}td2O1mllOKquAC69AUw^*gcA=v2a+=?fZ0`&RE1@#CGW&I<8^oTzY9Zsm0wgKD%ogOg=Bgx2JaOQ?Z zxtMS(zcY3!k{O9jiBYQJyu7Z<*VSS#W|S=4X2CULeQncz^5E5!T|OSpthVt5f_8Jm zVD5@Y81ZoJYCMz1g=%u6aD0`yP?+}-goO40MHOx+^Tv>?Uvn|=3HC+WemHs;WF!On ziZY=d#ITtnq*Qh4YwU4b2v09AFT*{>a;Koamr`KP-E)kawdIOFSewem^qrp|R2Rc0 zW8GUz*&w`>P4=u4H~KomQnhH=kzgN7mzJ;raU%#02p7UBUJfn?m&--b-4WfIX4P`9 zZ@CDB_AW!IfH@2gEk-ziU!2Sy7JK$kWH@VXAl99VaWtCAk+>n+8A#%oNhUJuA5~p29d9CeNW>yd)(BC z^m0Y%GMy{4#szs&F}ZDHD4G~u=9HtslFli*u}|kC3GPL7Y8W*3bjVONi>_txnMV`e z8l_k~?y}R@P^aap^-*v&pgaK1UD<@erpn$Z2SHRM3T68YWHBy>(a6z5B*rz>vbDJf z_X_fKH;8ID29Zrbsf+jTl_lHPY3>_K6L`d}$Ni^g`8sf$ZC}5yzqM3t1q+i46V)1A zUC4_dVY&BjpkN|_Y77v}Mm!d}xxUl4q8-WBg4kO@P zFe-JowYB!H^)+u}7Nx4XrnYX~`VAX5o$709ZfR}1ARNb)wdu-XFsJOGpU9wP2-k-; zWx;CkT(?nGIN~7^l+zsLEh_TENIM8jIxYHgSqbX`RbeCvN-PY{NK=YSCd-0&aT@il z^~exJ0eC8$ax@R?rXc?M)VvJvtsR-V*LxxH>^$ zq$~@uE3x(%e^FZoMMw;)tg@yytpjPv#AOD9jDuUVjakw`T$4)A;Nf_Akt79|I;Fh| z(G-w%29qeHzoSVAPT|ntgj|83-*C(9kcy-(^rw?J^j`z(sMbIV*B$zaF74~X!NBfuIlAHMYxS%UWsM3P8H277!#&NkW$~1kG#fP;7$?E< zuJzX5-tOLdC&xR{8+l|SZZ!yi{ZK1!Yw0f%4uUz||#F+u; z`{;z|`eZ_G#@!gyurFNKq*URk$O^{WTh8`ht!GPHvK@9z= zaeaUc>WDjL!S@3kQhCL$!{Hh=OQgUUq>cM=QEnPTQ;JE9?m>KXg)>ck5NI->w8~o9 zEsy(M%guea!X!xnt2GIb>o5bY&~OYBSQHyt`Vl~%uB0AZIpCZ+ZPqiS?Co#m#Zc40 zgoOEE=|k5##IozOa}Hdtd(9EDCxtJL3n6jLgc~idA@s1QzqQFVwL+WVj|R^!CBb$D z!3?a?pa#c$pyGU)jir<91hVzhdqLCYFt6BE)MFB0qA~kaEQ}<%vuz5@c?rio$U!q-QCu2TG|$6*&NDJdxH45Qg^E9P4H5v3{+t31BFp-R4kY}ep%fUFPhYQ;+ZT_qtrZLbbj1VNygGWY&kXok!10}Qa zCb4Qkk=UGulcSF7(J}PPZc`Z*Zh#~LV0k#Qs^{(KSPf$?Yf&Tk=qPvTiy9WcJzQ61 z;^I$aMhG*PGY}{_piZzRwJ2}Y>~OV~Ul5@Sj2@h(wWCervciEFl*Pb@c_Nt|&L8tE zs35^YOxsVnakEsd#ql-iaGa2su7x_dWxIp2O`6NK!eWqv78z1rX>xisPTy8IR=$IO zw&Ty18pXrX6%RRA5(9TYs3uv;)r4N+H1U!JC=5*U-sD)*T>;sdQf;-pmUOys=wp=?R8ItZ{3#&A79*tG~OqwZj`T3z@V1 zHHg>cYq9aV!dYDR72Xx_M)XBeh=ta$vATnq!0v?8H=fRfanoRTUyEEf(AQbni|NiO zsE!l;xdy>}C^szXt9RXFLPGoVdtv#?vaT1K?AQJiz6dg#q z@eJh1aVTU|QJ`foa(itvv{c#?@;4SK$avnLGW$1-$fXaSqpiS*-Ss=m($EV{EKH1N zld{n=6>zGk&gg2vFdmMAs~j*h#XjWhM5l<3A=|u7k0NJRn=rd&Q(q>X_sML}k+7QS zquWp3=(W>Fx1YSx>!y!h{8L_gifRrV>2Y=jBJiBCUnv-=9aM_+6%yxSq#nk{fb5v)^;Q|F@Fne#LYLSmxF<|3R zc7#IM#56~6BploYG0IBbB4sCOVB!sqlB7L8griI&@g#Il!4to*@I6_rwC>sA&3X`e zN^@^>1*9~&uveQ0AqM2CnExriI;aX!oQPw9qb!65TwXc2yaIoN%el9Id1Yp~wINEm zZq3_sAX-}^%y(i(&bQo^dSPL0Fi3^gvf+%;nNpxe)bg_Qa*@J~X&DAf++!?ucwI3j zbxCF@kd}4LY6)WnW&Hx%&<<`@rOif>hg~d#vD#RIuxdC0EIX$`?+T}eU@SS^*?Aho z^_}$`n$J5OLuV<>lmmH(>|$V*$v3tg7v)M8Yu3yrsJ#CA)#>8N+c*Mq#yF zslth@%z(y8XxnkDK+hz~jndPFtF&ACjTy@=mNpqqX5iv0$FLYTsFVOPjfHVH?$ut- z0vO<&W`a*&ZVeq(r9Lt}zyb|EmheIkcDJJl{0xTbWm2IAv0dIu&{F6JPXv#{G-e96 z2I#aQvC4X?3OM{wwBtB}(pHw%2AbPfV_qek*3)4?ELSIE-X=JL?G*sA4@ZTLS2*qD zwdk(wTc|vUDC3Z5IT5T4gD5jN0^4y=GvDBf(6GS9fzi81SG$Jh)(7vO> z{&a|-zf__1uu>RylvFmDL2Mm47YbrY=LN&g>QAM2#{x+=7%f7Z7yKNeFcp#U(*)#q z!x>EV-ycl!*5u^KIP%mb5h4SCE^11!7cMiWYG7~yK;9~qR^TS#u|vWuse;aZ$xBGeFHD%~a9iV~923lJx1xt&Jk*)!wsC{~ewgO|+n|4~k+NVK$TYB2N>$MGy{m*n3 zE*IefG{ryl7D_argX?&mvaFdVEH&RHFzuAfnzgdXYTc#CNHLG72_7?3nFcTfSv%nl z@{oH1L76N-#R&>+;uK9xpF|_LaV3Zn1WQBKV8ocqCF#iu31j>Vn0ZllL(x_-?vi(R zb%T%Q)@E!sL(G<*eh6pa%^aEK=5L3~6N!B)70A3Z0)sCqj-@xdoMDi6sp`p(8;P?w zaE=_@VcMJ^w1^l4Z4d@Uk<>8ThKt08#!+)Z!OUT?6nxN3o5exO5J6!FkRb^L+qn}4 zvEqG3_M{&OWKbKXPH4sizl;wPZhkY}iVQhF-*gg2A~Z{WRuZZ+bhhr9CQlv7WZBzX zhYi0NRnb@U1c`ZTXgJ-$Oq$3OT2=r(%Sa28Ym(v?8mfBTSiM4m+A(#OShe}hj(Xv= z{B#cEbU^u<>Da?v1gv3lU8X| z3})7GnPss+6vT9JF~A5%U6~HRXdtD*Yy@dpXHOE5zG`6<8pSB7;SxyO+WU3Ff|-w; z@kmbGHfxdHw6<8zNOLu4jx2QEvO<(?5s8guIA%(h>%feI^k0K3QEJe=284KJR)f9U z`*q7e*E#Jy+JXw|)wz>N$doo3ZXgb=KpO#pgF?8ZZE1FA?i2{BVoW0gg6N8QWT#wq!=(LOz^%10&SkUieU-gooJ5WlWEgE_ zwgnZ|%yY^Y8NkD+4_KzKR>w#AN`5kr2b$(E4GcmL{=CgS)`B!w3uXCU}q*{#WNY3btZtl zS0?<4Bnty(fMOA>ayl>!NZusod8d3zqC7Ot20wkx8aq8(&lWLJq_vR%W|*naVys7x z#`+AoOc4t-j8Y<9M;IUmLneilp3Ne&pkuHGv{JkWR|!?Yfo`?H(M0W??TUD29TNro zP$Eka5Svs(ipr202}Fm)2R7xg|Cd7}Si>3CWn4v2>f-qV8FiF2_17SsOty zJ}v7w&IzXyR&_Yzj5EMlTXv|eaM%I}r`lUvTOI5rtg6esp6aysb@;j}Yc}*Nq(MhA zC+s^?d0nF_rx)xV#f*p~J&0+n%DNhjA5v58j(Vqipj~VD)$1Vhi&5VAYvIRQO^>gv zE<~#(KBUnuSOUuu>L)2C{B^#?%mAN)?+UKTJ#w4dnFbNIEyGr-9yQ%4_@9E(P5+$thU>J;wsz3;U)LQ{Ot_R;J z%T@_HC`S!OKm~=rN-W7qJC&8CY6#0|g@}{`37oMpp|%c5kcBF%%~rqx(T+1%mW3RJ zpB_llxEMxA9UqZZCwe`jGXetE%S$K=ZaXFs_^ncBWj^W*(5so=^O-rAf}{vf41BQ> zRjw4IUcqsIQwWBjsK9}yqL|);{+xkmAIffWgviV?!R8|$1g&IyrlrUvbY0!dm}%96s$ zZfK0uGy#aDPU~FFIx4W}t+d*NQz{%EQKOKzqL64k@}1SiWzi0J%c229cI>Q`9xWib z6$XnDN-e^WhJ0m$%V8~I<)xpG=sdKFvStP<59I|K17taF_8PdV)^2n6ryZtc`BTzQ8#7?kxt2jU$B&^}7c z2#2^p7HVddh4Nta)@=uKl+3Vm>M$45ieYT!RJM7RaB(NB<6k@C6(=|vZhBBk* z@i~=W#LQM%3no2MF2WR1Pn#UKg2SUSmN2Blaay=6m=p9t1~5Ph5n2>!=8B+tlBOOt z(d$B4SxeT}(~iZiSX>5jM>By3%i2W|s-PB0k1;)-ynq&QO!tGb9HtzC$p>wMCd}5C zWkt!&1?zFgW549Cs`JxO(>YBJOP#i7*o8X*bWT`Z91{GEF z9?g}K4$Vojivy+>7^6jCV^Zq*6hial}TeXtxc;OV4C=(p=c}!qh&bBk!SLj z)FvpsE0RoxLrPLa(I2BBjQ@IcrbLI_p(eM1_}p9?VJOC=69h_KJ!z3*QKZ9~QOAr+ zN^DqIz(otY+cV6vF0HUb=RhmlPE+tH3$+HP%Y+iL-!NtXKo7zy)!eEljRY`kpV^~e z)Hul$C%DA921(>$pa-U9F5qD=v+n>v)`DRjC=AikMyET?oh|;po(})^-uC`he_#7K ztuyBj(y>MK6@ms{l2nlQYZc}^6gFYInj(8VHgSVoy#3t@p?UqiG!p@{h6#asA@;6g zS6zkps>-VC5C$YC;vqC2R$PFS(1y(uGief)-XKjulEg%hbogBVw;}0F0xN*=M;M!g zLILLN5s3@Io*n>;Q8w(Xau3p21(uUabB2fsOi$$sBS;js9-slY3sWB!h1i6+b}KLz z%-po-oeu2XFs=(nm3ax|Z$3%uI#_`&$7kC}qFNypC-S(o#9EK~VbS)V=}?Ev58GBG ztgp4&-{mXzr3dSgC@M_Jrj3KVzf~JJD*4hU}i>+9O-}tTA2rjo z9J96G-`48uALwmGI-*Db@<>onATUT&VXa$!TZ4bp~~T4&?)briVb^cbF;IdYF%Y*HICVI!hJ7r`hS$)H)cg|TyBH;j}s#RY|@6Ob{di%7B0 z#$i9^1fee2UHNVJey2P;Vf7A&xU*%f0)L`W`&bQgYJBTxd0BEGx>^l%ZR_gZ-bEd3 ztU^>U!+gCw$=vML0JY(1iYdq8BD6ANel2OdcFU6Tw8(*)o7VKrv&XhcaQewb0s{pTtN5 zwp6{vhGHaFIEZk`$xaNEZ;x+ZbVe-KB`{w2ad5x@DBC_MxLbu|)mk`om6n>m{RWpRX!8y5n7EwZG6j_bjJU9;+p{hiY@AgorFgXLyo zDmIQ`Du?~zD~FYPGB-zk2wiz#qL`cHsBU&=Kx&3z4ZD9Sn0A3@asvuvT<<0nwbxR2 zTaLQTncQNBAhDwBfIw-*#h@ohE>+75_%Df#z2A?K9HUf1rZ=2{<_=$9pC6DKnr^r9 zxyUS@ub6yX%RE9t-}0*Wj#UNGj$}jVlx{aNYm$bz);XC-9QbF!^o0OrzDr~u}L@=k&^}f6yHEFwgWVNcomhI>uM)~wK>tu4M zBm!tYD7$Wj75HAKz?wk8pAIL3^br(uV-nVR$IIXzK@u!3~j?&4i#lPjeP zx{Y2D?@nXdZh(yJA~8tzSY1s!w3!Sw8^%|aais%n?z2lQ6F+Vmk!I?tTw%|ue3Cgw z;os!HBt`-HvChM^$Yd!&%#Vdc<_&8RsCgKlyaIdNcg)SNnhSAbZNf=Yua&By zRLJ05Zzd~AmYIcY%Fw)7&gN-^{Do`F^47bl4)j`*TC1ng#0*}>G0(9ItDX(b;fF&c z2EeI{{xEz7b{A%d?q;$>Ujk%mp|emS3*et;W@=4=O=s*Z`V-adUL3yBr-NZ*uia71 znVe*?o5Y9i%e8KVf_DDyfqu4Fdl&xlAB1IYt{v!eDE)vZVynv5?!JE6(LyN%cJ1PS z(7y#9Gw!=G1C(hTu?l+@EYu+#XKh&;vh`R1<%&KgyXdJC@c_Rlh7XxG)k1_-7`P!6 zW(+u zpSBpt7F8@KiiMT4v!}Pcv-Lbx>ULQGVKqD1*NOuUuzO4PP(s?k*RoJ75Tx;e9{Va7 z#3>fd?oJ}q(ikH&A<)o{J{EFfKHA$WV42fR2?LZ{IMR4FAcb+%Qi9}!Sq~iC0;OHg z9?=ZY2LX~y+5V)xJ>NY&MWV^~Qo|%r4Drt?IJOnlq5>##;upsW4@`(RH4|j+U~vaF z2S)8m5GcfLoEc{RV!K0~g^}Zf>C@&A14M~e?%_HX0t1?Wb5U3!zEuTw3MOLXc6eWl#wlJ9vItn=mhwQ@# zqPL_FofOVF<3vqLgi)y?cOzk037Qq-zARcqLzxOh6T|-D5Tct^gRDF>Qr{qSE$%X< zG@COR8lS9f3^*-zU8g5oXoF&u<6x?>F)Zfg5Nz|QNRl=xSuN)^&S92CX1_TAcovJ2 zcbwMJ-iwtVr}drP$%k`>gGX6Sbr#K*14}PMhRsPIpCR9Ld+K)PPDghUYLzrrPBe+h z0&SX(M1I$%B2nb^a#AOm5xW}KewHdfDk$sc>OuXoZ(Eb3wNE-1B(S&<^ak@#Bt615 z($;!T=wY|C-o^{_+U`gqiz@hdjs&R&vIt_-I|#tWabO-hA7O~GD5k+2vre4Q=33NT zxLwp7jbQFwh%h2c77K|`D2+Wdk7U5YU_hr?R(7hnND`v8cG516J@G^qlL~szHUE9^@YVUxU9$Z+LFYRK;{f!3T`_zetP~vKbUnjY20q~$!%|^ZisG=vhlo{r^+G6N z1Jw${1S^B#C^T>`1J)Z6DGPb_)aI7Ek{L2@nq3hGT+^sL3JVtwutye=Da&hzRnD;2 z2S95aMa0IV#}1fI8VDsN=XZGu16NgnLW7vtN;_C)3sV7A6d_D}!rB7x zuUL}YSJpj^V3rCUzO%KnyZ3B=ldo%ApTG0}u=noKeO*_%=yo1$B+_EQKuQDINo*uH zdRulBRWXt!IZ`9piY2E?WmlFZ*%FZ@MGspFZqIfix8`8L1^3`yOs{*6dvFg9n0r$& z7x&=OlMpB_$9I_|iC+@HPl?Z!y9hxQXdH&O=ycbL-N~+g3%1!q6@=1E#8;-v8=OlVCjMCd%PG6I=dv;=qhgWLh zXql!4E??BtoDCYvRIT7!m){Ox*@&Z>iD&!bY-D&ofVOQ*vyd^M|BwDj56Ue zsCeqW3nNJ22J*G)gM^`&BzZO3Z$?+vCMUfvH1Kj_7a&iM=>!&vQCeuFb@&sWgU+VU z*Yo+Nu?4CItzicSw0gr*CD!L+4dvvZqC$l8ZzS>9#knPx34Dmotv_fU;gpBOg3Q+Z z9Sz_-;w>qj;$Pxs0{zhBCfoqx${xbvjZjvoSSI`n(%;& zXQm%&qlQsrntrlrRwMTTF>a0!#e+~p;%txlhOMUjNEt^^)U@R^TGdMZxgY3^Fg_Ge zxig%yxHJj&d=L1EVa!(}^yc_cQX33_{&9K2p+=*t^^YGh*AX*i#_A0;G7*R1PYCijTy8Fo5G;xfq^{eBy*M< zCU)?i>SQifMjIeVVEMtHl|Bm;0}DpboM_DICatSJ$eDGlP_PFT}v!+>tnAuDX?nbkk< zT*k_!V)RF7OWp*TNVZUO?R;~mQq4<;-;z^6v<&4x%KM^bv&PXu(;bM+I6YW5oE(Zc zGcj>)M8U2_gPioiAf9JSG`2ir)2%Ria&Weklh0D@JD-ZeECl+q;gX9KEE1n>F(!19 zzOWSMh1?bTnJ1L1+Fa$An{1{L+j_9K0W1V34Z*~gF{-8^O`_xp&AX*)WL~2+pZqqo ziJ?82)|88a;#D(jGXE`uB2 ze1Of1lpsTbKqFU8<~KMs8tX$;zjM-zWSX=`v{4(sOa|c_FszvKp65c^*jh_1F&byj zZp|~2W`YD*BP*p$X30NMSSiU)=7a3f+b?+Huz29pAB{z!hoO*s^tQ|z(+n1V5?duQ zGYhcS=)Q;w-)mkh_cnc7__WlgQDDdCc`t>&Ay!>EVKHK0y@`LYp$ZRH)r?^6)BABD zSOfCzP`Ra4i*rU?7K+8stToeb0qegpK7DI|+lRS&Q({SUsh3es!b z+Mjr97tE(3k6emni(vaTgbQ<`8 zsxo$MSo0`OcloUvE`c>sj26R4!+5RSiWRvtYwS|r#(L4J=^%MUMr?}62{=nZIbxxp zu2?lt0yBoctbf<;@`wTvc1mzK#$<9G0`f`H1r+8y->W7~^vuQs6Ltugikiz1$J54^ zKFzH)revP_kj+7+K^YJ%s6cqYnnFC@+t5z2M-=;=B3_{*@p1#EWXv>c*F=1iG`oR= zbXWCnXNEKCsXhn6EV(1B(84^Wn*rr~4%0c?wd4#?>IdU<86xB^aOZou@yIjO4)U1m z$kdF6sxJ!`CLYm3GEum8Bn66Ss~qrsn!Spa<8t26KAAWo=WgTqe(`L9Zy$1R;$5wR z4B76dO=HXWkhHn%o*u>HuzKe#$*5K%;mHimp;cqk*2uI`EmN&5dlwi@W97)OK!1ak zg+)$0MOW|*U{1Ncpzf!TpIQnruOx$;Z_f&^awH*tEVF?H0`-Q@7S5e}n_3@f?(8yM zDow>HfkN?F3l6-xxOUrAb^FR_`Ldk-$-bR11HUU{kWvq@Vu1)v2Syz^ZM>`%2t;Vk zcNBAf-a)413m?58X#K{#VHr~!alK(Bel^LT9h~a01UYZ z1-6-)Kr$G7Q0w!8p#jbFlM{Z%!{oEA-b*k7(o7D|8^nYFOa}TlMBshU!lPmnY6@ft zGG$asItlVYc)^@Uws*PIXI2^&^Bx7Nm+%)qLRJ$%^W3)&VfY%JLG9RD32JLj!< zjAexR1S&h5{~#!vpJ;9?m@*RP8^NO{8+>dH35Au0LE(gPXP);}ldU%2b6sYPAlA(1 z^D1a&?kzCLYMU%n`CMyw3YNyCpGMJ8GM<>ty^#ujn@zTW5iezd zTN*aR#(&s+&mO}h2j0`rqg{C9l9uu8Hk)g4=>a;?J~X4vxE_(rfw>Q@I?nUb2NQ6m z+K|?7(gu_Jq%pk_aU6}-g}ph_e(2{!Jj^$380I1grW!JFjSxC^lip$_ma?AwcAXUir#kY;gy6ic#*`X9v`HgE1~-T1Jve2~khdMVKR z9(W+QN~~w$8hhQKj5sRpi2`4;$=Gs$OR{+p4lRTDHeGLuiz#{G8&1bj*JS9zzvvBo zF5-1zFVkTY!ft5FQEj3$iM<)<8n%PIcM_v57C718jS*!fV|&kVKdfx`Lmdx_bH-(j zyA;u`ZGoDxQdYAU3yH7@Y|lb0%y4boMH(`VZ5o(aO`B<|kKv>OvnBS98X z@6I7IAFiGx9!Sk|k#+>S4`GkD(Vfs5LgQtlassq(&g!?Dk-nTh=Tj38;qTJX9gU>;L z5-rqm2t*!z0&@r$N+ExO_Jq8vKr#{>6`iXE`SgeTEMdT(`wpYHt`vr}*$~iAQu&+P zT?nf|SVe#(NF4Lv`dqab4511=It*$S$ez_Sxi}1*oEE}{z!**iG3kb}_~K1$eq~z` zBVIOa!Y&hTObmB@1AD_0pWiv1%$WG(CR=$y%b;x@QC?;N?2K*KG%a_uw#XRE)Et8Q z3=$KRH1@Ow4GZVZnJL@05i*o_!`%6UB{El8v7w=}xwH$dtgsP^HyEw&ji12kuri6A z-M0P8*T+%ZXgo88T=l@nhlL$i7~B^&;+i1_n<-o4{hPbYIz9SuAIfcWP&2o%sqhyCia1jpbd6hlSS#+pSBSiO zrAvX}s;N?JijT}K^GWgo%c?Luj6DxA8n1td#3nWrV9bP$g%OIjc}G$#JWPYM&xT&G zgIwAH8JgiK5w-Ca>h57Uwe5!X#LYLbw;7*=@1+sJc>Tk1by+nk({(Fs*jaMhWh1wU zrt?shP;SO+bN_rlzF{Qx{dHdF?CjvVDL*mZB~6XhU`0RQH@Cb|n8Gm=`#C{#Wo(2q z=cPU8=OpAdm)sP_YfRse87EZf8|E-ukHdSg)(iDdj#^y$UOZykkcZ_7SH8l0D$S$)38QIXP8-KPrzS$r5j?@H$LsY{STsej&{3 zpBe$D#)fHj!LT0TT4oXypasM36G{jf$>yVhro;&O9g#s4bOw4N{8$`T4EdIqC)1&X19%-1~ z-8nc8!?&Bp_BIXnw|8PE38`Wyb|dy~;oe5jF!U_y!t}?(<-2?c#E`OQYJgS9#hP&w z8c1Y}F;}y+peP`UE%g-}Ov9_R5!m)4->oEn3I+NW?Hl5*5Sn^1D^<)CsSUPsSohXV zVH6eK`L^#~@s1z4zqqvO!McqdSt%?CWo_KaIbSpCrXQmR7(x`kO9=+YD=@P`O=)N} z&&^$1JJ7OiuM*fWl3LhwsEMJzz*YtdIy?>u1~h@#4j`78cnS>EB%f8__9ygpyHwr<%VGBpraq%U@k?S^tB;-H=+ za}9ElSzR=1dDca{x{>K!!!+dBKS{|mno%0d79M_!(c8>RnZ5=RG&+j)HSU+?mm@b@ zyI@eYa-Cz%O}-7&v_X6o%@&6FJ{P8H1EX(x zEM}9|_*CjbnWh!?r;%mhdJo7}H{!n4w7lFO6~(r%?iH16D~pC&r#cKzB93O0=ls7HhfuRSACBx%IKF|+>T4iF`;fJ3r{&EvqgEWMkD4}a-!{Q|qUp(** zymejM%zL*w2zTNl)j6$U1lwc0+qx^DI>qcVv!x#k`#*O2pMuAc>mO6uRV3cynNI1n- zCY{gNCWn1R^mZKij1I$n*jTJ_1r+oI*_(`uy+b_=qRYx*Z0rOwh)dE~N8*%wZoJMS z&-09H(%LM0VJ;Y36QxCL3wfnF-xJk`IYL8e$arYT(_n3#dBU+GjAR_5&p~LUd>daE zVlpj%kijfBVsYb0r}-rk!o#m+c4XWQD_@Bt-`uy7OSr%6S6{FqLP

Q$r-Qls|M^3I&EohlVL<&GEHM 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 diff --git a/files/variables.template b/files/variables.template deleted file mode 100644 index bbcd898..0000000 --- a/files/variables.template +++ /dev/null @@ -1,31 +0,0 @@ -MENDER_BOOT_PART="/dev/mmcblk0p1" -MENDER_BOOT_PART_DEFAULT="/dev/mmcblk0p1" -MENDER_BOOT_PART_FSTYPE="auto" -MENDER_BOOT_PART_FSTYPE_DEFAULT="auto" -MENDER_BOOT_PART_MOUNT_LOCATION="" -MENDER_BOOT_PART_SIZE_MB="16" -MENDER_BOOT_PART_SIZE_MB_DEFAULT="16" -MENDER_DATA_PART_DEFAULT="/dev/mmcblk0p4" -MENDER_DATA_PART_FSTYPE="auto" -MENDER_DATA_PART_FSTYPE_DEFAULT="auto" -MENDER_DATA_PART_SIZE_MB="128" -MENDER_DATA_PART_SIZE_MB_DEFAULT="128" -MENDER_DEVICE_TYPE="vexpress-qemu" -MENDER_DEVICE_TYPES_COMPATIBLE="vexpress-qemu" -MENDER_DEVICE_TYPES_COMPATIBLE_DEFAULT="vexpress-qemu" -MENDER_DEVICE_TYPE_DEFAULT="vexpress-qemu" -MENDER_PARTITIONING_OVERHEAD_KB="32768" -MENDER_PARTITION_ALIGNMENT="" -MENDER_ROOTFS_PART_A="/dev/mmcblk0p2" -MENDER_ROOTFS_PART_B="/dev/mmcblk0p3" -MENDER_STORAGE_DEVICE="/dev/mmcblk0" -MENDER_STORAGE_TOTAL_SIZE_MB="" -MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET="" -MENDER_CALC_ROOTFS_SIZE="" -MENDER_ARTIFACT_NAME="release-1" -MENDER_MACHINE="vexpress-qemu" -HOST_ARCH="arm" -IMAGE_FSTYPES=" tar.bz2 ext4 mender mender.bmap sdimg sdimg.bmap" -ARTIFACTIMG_FSTYPE="ext4" -DISTRO_FEATURES="" -DEPLOY_DIR_IMAGE="" diff --git a/mender-convert b/mender-convert deleted file mode 100755 index 45c2001..0000000 --- a/mender-convert +++ /dev/null @@ -1,870 +0,0 @@ -#!/bin/bash - -show_help() { -cat << EOF - -Mender conversion tool - -A tool that takes an existing embedded image (Debian, Ubuntu, Raspbian, etc) -and converts it to a Mender image by restructuring partition table and adding -necessary files. - -Usage: $0 COMMAND [options] - -General commands: - - from-raw-disk-image - composes fully functional Mender - image compliant with Mender - partition layout, having all - necessary files installed - mender-disk-image-to-artifact - creates Mender artifact file - from Mender image - -Options: [-r|--raw-disk-image | -m|--mender-disk-image | -s|--data-part-size-mb | - -d|--device-type | -p|--rootfs-partition-id | -n|--demo | -i|--demo-host-ip | - -c|--server-cert | -u|--server-url | -t|--tenant-token | - -g|--mender-client | -b|--bootloader-toolchain | -a|--artifact-name | - -e|--storage-total-size-mb | -k|--keep | -v|--version -h|--help] - - raw-disk-image - raw disk embedded Linux (Debian, Raspbian, - Ubuntu, etc.) image path - mender-disk-image - Mender disk image name where the script writes to - should have "sdimg" suffix - data-part-size-mb - data partition size in MB; default value 128MB - device-type - target device identification used to build - Mender image - rootfs-partition-id - selects root filesystem (primary|secondary) - as the source filesystem for an artifact - demo - Configure image using demo parameters - demo-host-ip - server demo ip used for testing purposes - server-cert - server certificate file - server-url - production server url - tenant-token - Mender tenant token - mender-client - Mender client binary - bootloader-toolchain - GNU Arm Embedded Toolchain - artifact-name - Mender artifact name - storage-total-size-mb - total storage size in MB; default value 8000MB; - it is used to calculate the rootfs final size - keep - keep intermediate files in output directory - version - print the version - help - show help and exit - - Note: root filesystem size used in Mender image creation can be found as - an output from 'raw-disk-image-shrink-rootfs' command or, in case - of using unmodified embedded raw disk image, can be checked with - any partition manipulation program (e.g. parted, fdisk, etc.). - -Examples: - - To create fully functional Mender image from raw disk image in a single step: - - ./mender-convert from-raw-disk-image - --raw-disk-image - [--mender-disk-image ] - --device-type - [--mender-client ] - --artifact-name release-1_1.5.0 - --bootloader-toolchain arm-linux-gnueabihf - --demo-host-ip 192.168.10.2 - --keep - - Output: - - Mender image: ready to use image with client and bootloader installed - - Mender artifact: update file based on the already built Mender image - - Mender root filesystem: EXT4 image used to produce the Mender artifact - - To create Mender artifact file from Mender image: - - ./mender-convert mender-disk-image-to-artifact - --mender-disk-image - --device-type - --artifact-name release-1_1.5.0 - --rootfs-partition-id - - Note: artifact name format is: release-_ - -EOF -} - -show_version() { - local version=$(cd "$tool_dir" && (git describe --tags --dirty --exact-match 2>/dev/null || git rev-parse --short HEAD)) - echo "mender-convert version: $version" -} - -if [ $# -eq 0 ]; then - show_help - exit 1 -fi - -tool_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -mender_disk_image= -raw_disk_image= -device_type= -mender_disk_counts= -artifact_name= -rootfs_partition_id= -raw_disk_counts= -mender_client= -# Mender production certificate. -server_cert= -# Mender production server url. -server_url= -# Mender demo server IP address. -demo_host_ip= -# Mender hosted token. -tenant_token= - -# Conversion progress. -declare -i step=1 -declare -i total= - -declare -a rootfs_partition_ids=("primary" "secondary") -declare -a mender_disk_mappings -declare -a raw_disk_mappings -#Supported devices -declare -a supported_devices=("beaglebone" "raspberrypi3" "qemux86_64" "raspberrypi0w" "rockpro64") - -do_raw_disk_image_shrink_rootfs() { - log "$step/$total Shrinking raw disk image root filesystem..." - ((step++)) - if [ -z "${raw_disk_image}" ]; then - log "Raw disk image not set. Aborting." - return 1 - fi - - # For root filesystem partition set 8MB alignment for shrinking purpose. - partition_alignment=$PART_ALIGN_8MB - - # Gather information about raw disk image. - get_raw_disk_sizes ${raw_disk_image} raw_disk_counts raw_disk_sizes - local sector_size=${raw_disk_sizes[sector_size]} - - if [[ $raw_disk_counts -eq 1 ]]; then - offset=${raw_disk_sizes[pboot_start]} - elif [[ $raw_disk_counts -eq 2 ]]; then - offset=${raw_disk_sizes[prootfs_start]} - else - log "Warning: invalid/unsupported embedded raw disk image. Skipping resize..." - return 0 - fi - - # Find first available loopback device and mount appropriate partition. - loopdevice=$(sudo losetup --show -f -o $((${offset} * $sector_size)) $raw_disk_image) - [ $? -ne 0 ] && { log "Error: inaccesible loopback device"; return 1; } - - block_size=($(sudo dumpe2fs -h $loopdevice | grep 'Block size' | tr -s ' ' | cut -d ' ' -f3)) - min_size_blocks=($(sudo resize2fs -P $loopdevice | awk '{print $NF}')) - - new_size_sectors=$(( $min_size_blocks * $block_size / $sector_size )) - align_partition_size new_size_sectors $sector_size - - log "\tRoot filesystem size:\ - \n\tminimal: $(( $min_size_blocks * $block_size )) \ - \n\taligned: $(( $new_size_sectors * $sector_size ))\ - \n\tsectors: $new_size_sectors" - - sudo e2fsck -y -f $loopdevice >> "$build_log" 2>&1 - sudo resize2fs -p $loopdevice ${new_size_sectors}s >> "$build_log" 2>&1 - sudo e2fsck -y -f $loopdevice >> "$build_log" 2>&1 - - sudo losetup -d $loopdevice - loopdevice=$(sudo losetup --show -f $raw_disk_image) - - if [[ $raw_disk_counts -eq 1 ]]; then - create_single_disk_partition_table $loopdevice \ - ${raw_disk_sizes[pboot_start]} $new_size_sectors - elif [[ $raw_disk_counts -eq 2 ]]; then - create_double_disk_partition_table $loopdevice \ - ${raw_disk_sizes[prootfs_start]} $new_size_sectors - fi - - sudo partprobe - endsector=($(sudo parted $loopdevice -ms unit s print | grep "^$raw_disk_counts" | cut -f3 -d: | sed 's/[^0-9]*//g')) - - sudo losetup -d $loopdevice - log "\tRaw disk image new endsector: $endsector" - sudo truncate -s $((($endsector+1) * $sector_size)) $raw_disk_image - log "\tNew root filesystem size (sectors): $new_size_sectors" - - return 0 -} - -do_raw_disk_image_create_partitions() { - log "$step/$total Repartitioning raw disk image..." - ((step++)) - - if [ -z "$raw_disk_image" ] || [ -z "$device_type" ] || \ - [ -z "$artifact_name" ]; then - show_help - return 1 - fi - - if [[ ! -f ${raw_disk_image} ]]; then - log "Raw disk image not found. Aborting." - return 1 - fi - - local supported=$(echo ${supported_devices[@]} | grep -o $device_type | wc -w) - - [[ $supported -eq 0 ]] && \ - { log "Error: incorrect device type. Aborting."; return 1; } - - # Change current directory to 'output' directory. - cd $output_dir - - set_mender_disk_alignment $device_type partition_alignment vfat_storage_offset - - get_raw_disk_sizes ${raw_disk_image} raw_disk_counts raw_disk_sizes - rc=$? - [ $rc -eq 0 ] || { return 1; } - - log "\tDetected raw disk image with $raw_disk_counts partition(s)." - - log "\tCalculating partitions' sizes of the Mender image." - set_mender_disk_sizes ${raw_disk_counts} ${partition_alignment} \ - ${vfat_storage_offset} ${data_part_size_mb} \ - raw_disk_sizes mender_disk_sizes - - local mender_disk_image_size= - calculate_mender_disk_size ${partition_alignment} mender_disk_sizes \ - mender_disk_counts mender_disk_image_size - - mender_image_size_to_total_storage_size ${mender_disk_counts} \ - mender_disk_image_size ${storage_total_size_mb} \ - mender_disk_sizes - rc=$? - [ $rc -eq 0 ] || { return 1; } - - if [[ ${raw_disk_counts} -gt 1 ]]; then - log "\tExtracting boot partition from raw disk image." - - extract_file_from_image ${raw_disk_image} ${raw_disk_sizes[pboot_start]} \ - ${raw_disk_sizes[pboot_size]} "boot.vfat" - - log "\tExtracting root filesystem partition from raw disk image." - extract_file_from_image ${raw_disk_image} ${raw_disk_sizes[prootfs_start]} \ - ${raw_disk_sizes[prootfs_size]} "rootfs.img" - else - log "\tGenerating boot partition (required, does not exist in original image)" - - dd if=/dev/zero of=${output_dir}/boot.vfat count=${mender_disk_sizes[pboot_size]} bs=512 >> "$build_log" 2>&1 - mkfs.vfat ${output_dir}/boot.vfat >> "$build_log" 2>&1 - - log "\tExtracting root filesystem partition from raw disk image." - extract_file_from_image ${raw_disk_image} ${raw_disk_sizes[pboot_start]} \ - ${raw_disk_sizes[pboot_size]} "rootfs.img" - fi - - local sector_size=${mender_disk_sizes[sector_size]} - log "\tCreating blank Mender disk image:\ - \n\t\timage size: ${mender_disk_image_size} bytes\ - \n\t\tboot partition size: $((${mender_disk_sizes[pboot_size]} * $sector_size)) bytes\ - \n\t\troot filesystem size: $((${mender_disk_sizes[prootfs_size]} * $sector_size)) bytes\ - \n\t\tdata partition size: $((${mender_disk_sizes[pdata_size]} * $sector_size)) bytes" - - if [ -v mender_disk_sizes[pswap_size] ]; then - log "\t\tswap partition size: $((${mender_disk_sizes[pswap_size]} * $sector_size)) bytes" - fi - - create_test_config_file $device_type $partition_alignment $mender_disk_image_size \ - mender_disk_sizes - - create_mender_disk $mender_disk_image $mender_disk_image_size - format_mender_disk $mender_disk_image $mender_disk_image_size \ - $partition_alignment mender_disk_sizes - rc=$? - [ $rc -eq 0 ] || { return 1; } - - verify_mender_disk $mender_disk_image $mender_disk_counts - rc=$? - [ $rc -eq 0 ] || { return 1; } - - create_device_maps $mender_disk_image mender_disk_mappings - - log "$step/$total Formatting repartitioned raw disk image..." - ((step++)) - make_mender_disk_filesystem ${mender_disk_mappings[@]} - - case "$device_type" in - "beaglebone") - do_make_sdimg_beaglebone - ;; - "raspberrypi3" | "raspberrypi0w") - do_make_sdimg_raspberrypi3 - ;; - "qemux86_64") - do_make_sdimg_qemux86_64 - ;; - "rockpro64") - do_make_sdimg_rockpro64 - ;; - *) - log "Error: unsupported device type $device_type" - exit 1 - ;; - esac - - rc=$? - - log "$step/$total Cleaning intermediate files..." - ((step++)) - # Clean and detach. - detach_device_maps ${mender_disk_mappings[@]} - detach_device_maps ${raw_disk_mappings[@]} - sync - rm -rf $embedded_base_dir - rm -rf $sdimg_base_dir - - [ $rc -eq 0 ] || { log "\nRepartitioning of $raw_disk_image image failed."; } - - return $rc -} - -do_make_sdimg_rockpro64() { - local ret=0 - - create_device_maps $raw_disk_image raw_disk_mappings - mount_raw_disk ${raw_disk_mappings[@]} - - log "$step/$total Setting boot partition..." - ((step++)) - - stage_2_args="$output_dir ${mender_disk_mappings[0]} ${embedded_rootfs_dir}" - ${tool_dir}/rockpro64-convert-stage-2.sh ${stage_2_args} || ret=$? - [[ $ret -ne 0 ]] && { log "Aborting."; return $ret; } - - log "$step/$total Setting root filesystem partition..." - ((step++)) - - stage_3_args="$output_dir ${mender_disk_mappings[1]}" - ${tool_dir}/convert-stage-3.sh ${stage_3_args} || ret=$? - [[ $ret -ne 0 ]] && { return $ret; } - - mount_mender_disk ${mender_disk_mappings[@]} - - log "$step/$total Setting file system table..." - ((step++)) - set_fstab $device_type - - log "Write bootloader" - dd if=$integration_dir/rockpro64/rksd_loader.img of=$mender_disk_image \ - seek=64 conv=notrunc status=none - - return $ret -} - -do_make_sdimg_beaglebone() { - local ret=0 - - create_device_maps $raw_disk_image raw_disk_mappings - mount_raw_disk ${raw_disk_mappings[@]} - - log "$step/$total Setting boot partition..." - ((step++)) - - stage_2_args="$output_dir ${mender_disk_mappings[0]} ${embedded_rootfs_dir}" - ${tool_dir}/bbb-convert-stage-2.sh ${stage_2_args} || ret=$? - [[ $ret -ne 0 ]] && { log "Aborting."; return $ret; } - - log "$step/$total Setting root filesystem partition..." - ((step++)) - - stage_3_args="$output_dir ${mender_disk_mappings[1]}" - ${tool_dir}/convert-stage-3.sh ${stage_3_args} || ret=$? - [[ $ret -ne 0 ]] && { return $ret; } - - mount_mender_disk ${mender_disk_mappings[@]} - - log "$step/$total Setting file system table..." - ((step++)) - set_fstab $device_type - - return $ret -} - -do_make_sdimg_raspberrypi3() { - log "$step/$total Setting boot partition..." - ((step++)) - - stage_2_args="$output_dir ${mender_disk_mappings[0]}" - ${tool_dir}/rpi-convert-stage-2.sh ${stage_2_args} || ret=$? - [[ $ret -ne 0 ]] && { return $ret; } - - log "$step/$total Setting root filesystem partition..." - ((step++)) - - stage_3_args="$output_dir ${mender_disk_mappings[1]}" - ${tool_dir}/convert-stage-3.sh ${stage_3_args} || ret=$? - [[ $ret -ne 0 ]] && { return $ret; } - - mount_mender_disk ${mender_disk_mappings[@]} - - log "$step/$total Setting file system table..." - ((step++)) - set_fstab $device_type - - return 0 -} - -do_make_sdimg_qemux86_64() { - log "$step/$total Setting boot partition..." - ((step++)) - - stage_2_args="$output_dir ${mender_disk_mappings[0]}" - ${tool_dir}/qemux86_64-convert-stage-2.sh ${stage_2_args} || ret=$? - [[ $ret -ne 0 ]] && { return $ret; } - - log "$step/$total Setting root filesystem partition..." - ((step++)) - - stage_3_args="$output_dir ${mender_disk_mappings[1]}" - ${tool_dir}/convert-stage-3.sh ${stage_3_args} || ret=$? - [[ $ret -ne 0 ]] && { return $ret; } - - mount_mender_disk ${mender_disk_mappings[@]} - - log "$step/$total Setting file system table..." - ((step++)) - set_fstab $device_type - - return 0 -} - -do_install_mender_to_mender_disk_image() { - log "$step/$total Installing Mender to Mender disk image..." - ((step++)) - - if [ -z "$mender_disk_image" ] || [ -z "$device_type" ] || \ - [ -z "$artifact_name" ]; then - show_help - return 1 - fi - - local supported=$(echo ${supported_devices[@]} | grep -o $device_type | wc -w) - - [[ $supported -eq 0 ]] && \ - { log "Error: incorrect device type. Aborting."; return 1; } - - # mender-image-1.5.0 - stage_4_args="-m $mender_disk_image -d $device_type -a ${artifact_name}" - - if [ -n "$mender_client" ]; then - stage_4_args="${stage_4_args} --mender-client ${mender_client}" - fi - - if [ -n "$demo" ] && [ ${demo} -eq 1 ]; then - stage_4_args="${stage_4_args} --demo" - fi - - if [ -n "$demo_host_ip" ]; then - stage_4_args="${stage_4_args} -i ${demo_host_ip}" - fi - - if [ -n "$server_cert" ]; then - stage_4_args="${stage_4_args} -c ${server_cert}" - fi - - if [ -n "$server_url" ]; then - stage_4_args="${stage_4_args} -u ${server_url}" - fi - - if [ -n "${tenant_token}" ]; then - stage_4_args="${stage_4_args} -t ${tenant_token}" - fi - - if [ -n "${keep}" ]; then - stage_4_args="${stage_4_args} -k" - fi - - eval set -- " ${stage_4_args}" - - ${tool_dir}/convert-stage-4.sh ${stage_4_args} || ret=$? - [[ $ret -ne 0 ]] && { log "\nInstalling Mender to Mender disk image failed."; return $ret; } - - # Update test configuration file - update_test_config_file $device_type artifact-name $artifact_name - - return 0 -} - -do_install_bootloader_to_mender_disk_image() { - log "$step/$total Installing Bootloader to Mender disk image..." - ((step++)) - - if [ -z "$mender_disk_image" ] || [ -z "$device_type" ] || \ - [ -z "$bootloader_toolchain" ]; then - show_help - return 1 - fi - - local supported=$(echo ${supported_devices[@]} | grep -o $device_type | wc -w) - - [[ $supported -eq 0 ]] && \ - { log "Error: incorrect device type. Aborting."; return 1; } - - case "$device_type" in - "beaglebone" | "qemux86_64" | "rockpro64") - stage_5_args="-m $mender_disk_image -d $device_type -b ${bootloader_toolchain} $keep" - eval set -- " ${stage_5_args}" - ${tool_dir}/convert-stage-5.sh ${stage_5_args}|| ret=$? - [[ $ret -ne 0 ]] && { log "\nInstalling Bootloader failed."; return $ret; } - - # Update test configuration file - update_test_config_file $device_type distro-feature "mender-grub" \ - mount-location "\/boot\/efi" - ;; - "raspberrypi3"|"raspberrypi0w") - stage_5_args="-m $mender_disk_image -d $device_type -b ${bootloader_toolchain} $keep" - eval set -- " ${stage_5_args}" - ${tool_dir}/rpi-convert-stage-5.sh ${stage_5_args}|| ret=$? - [[ $ret -ne 0 ]] && { log "\nInstalling Bootloader failed."; return $ret; } - - # Update test configuration file - update_test_config_file $device_type distro-feature "mender-uboot" \ - mount-location "\/uboot" - ;; - *) - log "Error: unsupported device type $device_type" - exit 1 - ;; - esac - - return 0 -} - -do_mender_disk_image_to_artifact() { - log "$step/$total Creating Mender Artifact..." - ((step++)) - - if [ -z "${mender_disk_image}" ]; then - log "Mender disk image not set. Aborting." - return 1 - fi - - if [ -z "${device_type}" ]; then - log "Target device_type name not set. Aborting." - return 1 - fi - - if [ -z "${artifact_name}" ]; then - log "Artifact name not set. Aborting." - return 1 - fi - - if [ -z "${rootfs_partition_id}" ]; then - log "\tRootfs partition id not set - 'primary' will be used by default." - rootfs_partition_id="primary" - fi - - local supported=$(echo ${supported_devices[@]} | grep -o $device_type | wc -w) - - [[ $supported -eq 0 ]] && \ - { log "Error: incorrect device type. Aborting."; return 1; } - - inarray=$(echo ${rootfs_partition_ids[@]} | grep -o $rootfs_partition_id | wc -w) - - [[ $inarray -eq 0 ]] && \ - { log "Error: invalid rootfs partition id provided. Aborting."; return 1; } - - local count=0 - local sector_size=0 - local prootfs_start=0 - local prootfs_size=0 - local rootfs_a_start=0 - local rootfs_a_size=0 - local rootfs_b_start=0 - local rootfs_b_size=0 - local rootfs_path= - local mender_device_type= - - get_mender_disk_sizes $mender_disk_image count sector_size rootfs_a_start \ - rootfs_a_size rootfs_b_start rootfs_b_size - ret=$? - [[ $ret -ne 0 ]] && \ - { log "Error: cannot validate Mender disk image. Aborting."; return 1; } - - # Check if device type matches. - create_device_maps $mender_disk_image mender_disk_mappings - mount_mender_disk ${mender_disk_mappings[@]} - - # Find .sdimg file's dedicated device type. - mender_device_type=$( cat $sdimg_data_dir/mender/device_type | sed 's/[^=].*=//' ) - - if [ "$mender_device_type" != "$device_type" ]; then - log "Error: device types of Mender artifact & Mender not matching. Aborting." - ret=1 - fi - - if ! [ -x "$(command -v mender-artifact)" ]; then - log "Error: mender-artifact not found in PATH. Aborting." - ret=1 - fi - - if [ $ret -eq 0 ]; then - if [[ $rootfs_partition_id == "primary" ]]; then - prootfs_start=$rootfs_a_start - prootfs_size=$rootfs_a_size - rootfs_path=$sdimg_primary_dir - elif [[ $rootfs_partition_id == "secondary" ]]; then - prootfs_start=$rootfs_b_start - prootfs_size=$rootfs_b_size - rootfs_path=$sdimg_secondary_dir - fi - - # Extract root filesystem ext4 image to use it to generate Mender artifact. - # Ext4 disk image will be also verified in acceptance tests. - extract_file_from_image $mender_disk_image $prootfs_start \ - $prootfs_size $mender_rootfs_basename - - fsck.ext4 -fp $mender_rootfs_image &> /dev/null || ret=$? - [[ $ret -ne 0 ]] && \ - { log "Error: checking $mender_rootfs_basename file system failed. Aborting."; } - - # Find first available loopback device and use it. - loopdevice=($(sudo losetup --show -f ${mender_rootfs_image} || ret=$?)) - [[ $ret -ne 0 ]] && \ - { log "Error: cannot find an unused loop device. Aborting."; } - - if [ $ret -eq 0 ]; then - # Mount extracted ext4 partition to verify 'artifact_info' file content. - rootfs_mountpoint=${output_dir}/mnt/${rootfs_partition_id} - mkdir -p ${rootfs_mountpoint} - sudo mount $loopdevice ${rootfs_mountpoint} - - # Set 'artifact name' as passed in the command line. - sudo sed -i '/^artifact/s/=.*$/='${artifact_name}'/' "${rootfs_mountpoint}/etc/mender/artifact_info" - - sudo umount -l ${rootfs_mountpoint} - sudo losetup -d $loopdevice - rm -rf ${output_dir}/mnt - - log "\tWriting Mender artifact to: ${mender_artifact}" - log "\tThis may take 10-20 minutes (using LZMA)..." - - #Create Mender artifact - mender-artifact \ - --compression lzma \ - write rootfs-image \ - --file ${mender_rootfs_image} \ - --output-path ${mender_artifact} \ - --artifact-name ${artifact_name} \ - --device-type ${device_type} - - ret=$? - [[ $ret -eq 0 ]] && \ - { log "\tCreating Mender Artifact succeeded."; } || \ - { log "\tCreating Mender Artifact failed."; } - fi - fi - - # Clean and detach. - detach_device_maps ${mender_disk_mappings[@]} - - rm -rf $sdimg_base_dir - return $ret -} - -do_from_raw_disk_image() { - if [ -z "$raw_disk_image" ] || [ -z "$device_type" ] || \ - [ -z "$artifact_name" ] || \ - [ -z "$bootloader_toolchain" ]; then - show_help - return 1 - fi - - do_raw_disk_image_shrink_rootfs || rc=$? - [[ $rc -ne 0 ]] && { return 1; } - - do_raw_disk_image_create_partitions || rc=$? - [[ $rc -ne 0 ]] && { return 1; } - - do_install_mender_to_mender_disk_image || rc=$? - [[ $rc -ne 0 ]] && { return 1; } - - do_install_bootloader_to_mender_disk_image || rc=$? - [[ $rc -ne 0 ]] && { return 1; } - - do_mender_disk_image_to_artifact || rc=$? - [[ $rc -ne 0 ]] && { return 1; } - - return 0 -} - -PARAMS="" - -# Load necessary functions. -source ${tool_dir}/mender-convert-functions.sh - -export -f create_device_maps -export -f detach_device_maps -export -f mount_mender_disk -export -f log -export -f logsetup - -while (( "$#" )); do - case "$1" in - -p | --rootfs-partition-id) - rootfs_partition_id=$2 - shift 2 - ;; - -m | --mender-disk-image) - mender_disk_image=$2 - shift 2 - ;; - -r | --raw-disk-image) - raw_disk_image=$(get_path $2) - shift 2 - ;; - -s | --data-part-size-mb) - data_part_size_mb=$2 - shift 2 - ;; - -d | --device-type) - device_type=$2 - shift 2 - ;; - -a | --artifact-name) - artifact_name=$2 - shift 2 - ;; - -g | --mender-client) - mender_client=$(get_path $2) - shift 2 - ;; - -b | --bootloader-toolchain) - bootloader_toolchain=$2 - shift 2 - ;; - -n | --demo) - demo="1" - shift 1 - ;; - -i | --demo-host-ip) - demo_host_ip=$2 - shift 2 - ;; - -c | --server-cert) - server_cert=$(get_path $2) - shift 2 - ;; - -u | --server-url) - server_url=$2 - shift 2 - ;; - -t | --tenant-token) - tenant_token=$2 - shift 2 - ;; - -e | --storage-total-size-mb) - storage_total_size_mb=$2 - shift 2 - ;; - -k | --keep) - keep="-k" - shift 1 - ;; - -v | --version) - show_version - exit 0 - ;; - -h | --help) - show_help - exit 0 - ;; - --) - shift - break - ;; - -*) - log "Error: unsupported option $1" - exit 1 - ;; - *) - PARAMS="$PARAMS $1" - shift - ;; - esac -done - -[ -z "${data_part_size_mb}" ] && \ - { log "*** Data partition size set to default value: 128MB ***"; \ - data_part_size_mb=$DATA_PART_SIZE_MB; } -[ -z "${storage_total_size_mb}" ] && \ - { log "*** Total storage size set to default value: 8GB ***"; \ - storage_total_size_mb=$STORAGE_TOTAL_SIZE_MB; } - -eval set -- "$PARAMS" - -# Before running any command first create output directory -# and configure where logs should be redirected. -mkdir -p $output_dir -logsetup - -# Fetch integration binaries - -MENDER_INTEGRATION_URL="https://d1b0l86ne08fsf.cloudfront.net/mender-convert" -if [ "$device_type" == "rockpro64" ]; then - if [ ! -f $integration_dir/rockpro64/emmc-boot-integration.tar.gz ]; then - rockpro64_integration_dir=$integration_dir/rockpro64 - - mkdir -p $rockpro64_integration_dir - wget -P $rockpro64_integration_dir \ - ${MENDER_INTEGRATION_URL}/armbian/rockpro64/emmc-boot-integration.tar.gz - - tar xvf $rockpro64_integration_dir/emmc-boot-integration.tar.gz -C $rockpro64_integration_dir - fi -fi - -# Some commands expect elevated privileges. -sudo true - -# Make sure the user's given Mender image name has a correct extension. -# If Mender image name is not provided, then use following syntax: -# mender--.sdimg -if [ -n "${mender_disk_image}" ]; then - mender_disk_filename=$(basename -- "$mender_disk_image") - if [[ $mender_disk_filename =~ \.sdimg$ ]]; then - mender_disk_image=$output_dir/${mender_disk_filename} - else - mender_disk_image=$output_dir/${mender_disk_filename}.sdimg - fi -else - mender_disk_filename="mender-${device_type}-${artifact_name}" - mender_disk_image=$output_dir/${mender_disk_filename}.sdimg -fi - -mender_disk_basename="${mender_disk_filename%.*}" -mender_rootfs_basename=${mender_disk_basename}.ext4 -mender_rootfs_image=${output_dir}/${mender_rootfs_basename} -mender_artifact=${output_dir}/${mender_disk_basename}.mender - -case "$1" in - mender-disk-image-to-artifact) - total=1 - do_mender_disk_image_to_artifact || rc=$? - [[ $rc -ne 0 ]] && { log "Check $build_log for details."; exit 1; } - log "A Mender Artifact has been successfully extracted from your Mender disk image!" - log "You can find the Mender Artifact at:\n\t$mender_artifact\nand use it to deploy updates." - ;; - from-raw-disk-image) - total=10 - do_from_raw_disk_image || rc=$? - [[ $rc -ne 0 ]] && { log "Check $build_log for details."; exit 1; } - log "Conversion complete!" - log "The Mender disk image you can provision your device storage with is at:\ - \n\t${mender_disk_image}" - log "The Mender root file system partition is at:\n\t${mender_rootfs_image}" - log "The Mender Artifact you can upload to your Mender server to deploy to your devices is at:\ - \n\t${mender_artifact}" - ;; - *) - show_help - ;; -esac - -[[ $keep != "-k" ]] && { rm -f $output_dir/boot.vfat \ - $output_dir/cmdline.txt $output_dir/config.txt \ - $output_dir/syslinux.cfg $output_dir/rootfs.img; } - -exit 0 diff --git a/mender-convert-functions.sh b/mender-convert-functions.sh deleted file mode 100755 index 93b4b90..0000000 --- a/mender-convert-functions.sh +++ /dev/null @@ -1,888 +0,0 @@ -#!/bin/bash - -# Partition alignment value in bytes. -declare -i partition_alignment -# Boot partition storage offset in bytes. -declare -i vfat_storage_offset - -PART_ALIGN_4MB=4194304 -PART_ALIGN_8MB=8388608 - -# Default 'data' partition size in MiB. -declare -i data_part_size_mb -# Default total storage size in MiB. -declare -i storage_total_size_mb - -DATA_PART_SIZE_MB=128 -STORAGE_TOTAL_SIZE_MB=8000 - -# Number of required heads in a final image. -declare -i -r heads=255 -# Number of required sectors in a final image. -declare -i -r sectors=63 - -declare -a mender_partitions_regular=('boot' 'primary' 'secondary' 'data') -declare -a mender_partitions_extended=('boot' 'primary' 'secondary' 'n/a' 'data' 'swap') -declare -a raw_disk_partitions=('boot' 'rootfs') - -declare -A raw_disk_sizes -declare -A mender_disk_sizes - -tool_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -files_dir=${tool_dir}/files -output_dir=${tool_dir}/output -integration_dir=${tool_dir}/integration -build_log=${output_dir}/build.log - -embedded_base_dir=$output_dir/embedded -sdimg_base_dir=$output_dir/sdimg - -embedded_boot_dir=$embedded_base_dir/boot -embedded_rootfs_dir=$embedded_base_dir/rootfs -sdimg_boot_dir=$sdimg_base_dir/boot -sdimg_primary_dir=$sdimg_base_dir/primary -sdimg_secondary_dir=$sdimg_base_dir/secondary -sdimg_data_dir=$sdimg_base_dir/data - -logsetup() { - [ ! -f $build_log ] && { touch $build_log; } - echo -n "" > $build_log - exec > >(tee -a $build_log) - exec 2>&1 -} - -log() { - echo -e "$*" -} - -# Takes following arguments: -# -# $1 -relative file path -get_path() { - echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")" -} - -get_part_number_from_device() { - case "$1" in - /dev/*[0-9]p[1-9]) - echo ${1##*[0-9]p} - ;; - /dev/[sh]d[a-z][1-9]) - echo ${1##*d[a-z]} - ;; - ubi[0-9]_[0-9]) - echo ${1##*[0-9]_} - ;; - [a-z]*\.sdimg[1-9]) - echo ${1##*\.sdimg} - ;; - /dev/mapper/*[0-9]p[1-9]) - echo ${1##*[0-9]p} - ;; - *) - log "Could not determine partition number from $1" - exit 1 - ;; - esac -} - -# Takes following arguments: -# -# $1 - raw disk image -# $2 - boot partition start offset (in sectors) -# $3 - boot partition size (in sectors) -create_single_disk_partition_table() { - local device=$1 - local bootstart=$2 - local stopsector=$(( $3 - 1 )) - - sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | sudo fdisk $device &> /dev/null - d # delete partition - n # new partition - p # primary partition - 1 # partion number 1 - ${bootstart} - +${stopsector} - a # set boot flag - w # write the partition table - q # and we're done -EOF -} - -# Takes following arguments: -# -# $1 - raw disk image -# $2 - root filesystem partition start offset (in sectors) -# $3 - root filesystem partition size (in sectors) -create_double_disk_partition_table() { - local device=$1 - local rootfsstart=$2 - local rootfsstop=$(( $3 - 1 )) - - sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | sudo fdisk $device &> /dev/null - d # delete partition - 2 - n - p - 2 - ${rootfsstart} - +${rootfsstop} - w # write the partition table - q # and we're done -EOF -} - -# Takes following arguments: -# -# $1 - raw_disk image path -# -# Calculates following values: -# -# $2 - number of partitions -# $3 - array of partitions' sizes for raw disk -# -get_raw_disk_sizes() { - local limage=$1 - local rvar_count=$2 - shift 2 - local rvar_array=($@) - - local lsubname=${limage:0:10} - local lfdisk="$(fdisk -u -l ${limage})" - local lparts=($(echo "${lfdisk}" | grep "^${lsubname}" | cut -d' ' -f1)) - local lcount=${#lparts[@]} - - if [[ $lcount -gt 3 ]]; then - log "\tError: invalid/unsupported raw disk image. Aborting." - return 1 - fi - - local lsectorsize=($(echo "${lfdisk}" | grep '^Sector' | cut -d' ' -f4)) - - local idx_start=2 - local idx_size=4 - - local lfirstpartinfo="$(echo "${lfdisk}" | grep "^${lparts[0]}")" - - if [[ $lcount -gt 1 ]]; then - local lsecondpartinfo="$(echo "${lfdisk}" | grep "^${lparts[1]}")" - eval $rvar_array[prootfs_start]="'$(echo "${lsecondpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})'" - eval $rvar_array[prootfs_size]="'$(echo "${lsecondpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})'" - fi - - if [[ $lcount -gt 2 ]]; then - local lthirdpartinfo="$(echo "${lfdisk}" | grep "^${lparts[2]}")" - eval $rvar_array[pswap_start]="'$(echo "${lthirdpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})'" - eval $rvar_array[pswap_size]="'$(echo "${lthirdpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})'" - fi - - # Check is first partition is marked as bootable. - if [[ "$lfirstpartinfo" =~ .*\*.* ]]; then - ((idx_start+=1)) - ((idx_size+=1)) - fi - - eval $rvar_array[pboot_start]="'$(echo "${lfirstpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_start})'" - eval $rvar_array[pboot_size]="'$(echo "${lfirstpartinfo}" | tr -s ' ' | cut -d' ' -f${idx_size})'" - eval $rvar_array[sector_size]="'$lsectorsize'" - - eval $rvar_count="'$lcount'" - - return 0 -} - -# Takes the following argument -# $1 - device type -# -# Calculates the following arguments: -# $2 - partition alignment -# $3 - vfat storage offset - -set_mender_disk_alignment() { - local rvar_partition_alignment=$2 - local rvar_vfat_storage_offset=$3 - - case "$1" in - "beaglebone" | "qemux86_64") - local lvar_partition_alignment=${PART_ALIGN_8MB} - local lvar_vfat_storage_offset=$lvar_partition_alignment - ;; - "raspberrypi3" | "raspberrypi0w" | "rockpro64") - local lvar_partition_alignment=${PART_ALIGN_4MB} - local lvar_uboot_env_size=$(( $lvar_partition_alignment * 2 )) - local lvar_vfat_storage_offset=$(( $lvar_partition_alignment + $lvar_uboot_env_size )) - ;; - *) - log "Error: unsupported device type $1" - exit 1 - ;; - esac - - eval $rvar_partition_alignment="'$lvar_partition_alignment'" - eval $rvar_vfat_storage_offset="'$lvar_vfat_storage_offset'" -} - -# Takes following arguments: -# -# $1 - Mender disk image path -# -# Calculates following values: -# -# $2 - number of partitions -# $3 - size of the sector (in bytes) -# $4 - rootfs A partition start offset (in sectors) -# $5 - rootfs A partition size (in sectors) -# $6 - rootfs B partition start offset (in sectors) -# $7 - rootfs B partition size (in sectors) -get_mender_disk_sizes() { - local limage=$1 - local rvar_count=$2 - local rvar_sectorsize=$3 - local rvar_rootfs_a_start=$4 - local rvar_rootfs_a_size=$5 - local rvar_rootfs_b_start=$6 - local rvar_rootfs_b_size=$7 - - local lsubname=${limage:0:10} - local lfdisk="$(fdisk -u -l ${limage})" - - local lparts=($(echo "${lfdisk}" | grep "^${lsubname}" | cut -d' ' -f1)) - local lcount=${#lparts[@]} - - if [[ $lcount -ne 4 ]] && [[ $lcount -ne 6 ]]; then - log "Error: invalid Mender disk image. Aborting." - return 1 - else - local lsectorsize=($(echo "${lfdisk}" | grep '^Sector' | cut -d' ' -f4)) - - local lrootfs_a_info="$(echo "${lfdisk}" | grep "^${lparts[1]}")" - local lrootfs_b_info="$(echo "${lfdisk}" | grep "^${lparts[2]}")" - - idx_start=2 - idx_size=4 - - local lrootfs_a_start=($(echo "${lrootfs_a_info}" | tr -s ' ' | cut -d' ' -f${idx_start})) - local lrootfs_a_size=($(echo "${lrootfs_a_info}" | tr -s ' ' | cut -d' ' -f${idx_size})) - local lrootfs_b_start=($(echo "${lrootfs_b_info}" | tr -s ' ' | cut -d' ' -f${idx_start})) - local lrootfs_b_size=($(echo "${lrootfs_b_info}" | tr -s ' ' | cut -d' ' -f${idx_size})) - - eval $rvar_count="'$lcount'" - eval $rvar_sectorsize="'$lsectorsize'" - eval $rvar_rootfs_a_start="'$lrootfs_a_start'" - eval $rvar_rootfs_a_size="'$lrootfs_a_size'" - eval $rvar_rootfs_b_start="'$lrootfs_b_start'" - eval $rvar_rootfs_b_size="'$lrootfs_b_size'" - - return 0 - fi -} - -# Takes following arguments: -# -# $1 - size variable to be aligned in sectors -# $2 - size of the sector -# -align_partition_size() { - # Final size is aligned with reference to 'partition_alignment' variable. - local rvar_size=$1 - local -n ref=$1 - - local size_in_bytes=$(( $ref * $2 )) - local reminder=$(( ${size_in_bytes} % ${partition_alignment} )) - - if [ $reminder -ne 0 ]; then - size_in_bytes=$(( $size_in_bytes - $reminder + ${partition_alignment} )) - fi - - local lsize=$(( $size_in_bytes / $2 )) - - eval $rvar_size="'$lsize'" -} - -# Takes following arguments: -# -# $1 - number of partition of the raw disk image -# $2 - mender image partition alignment -# $3 - mender image's boot partition offset -# $4 - data partition size (in MB) -# $5 - array of partitions' sizes for raw image -# -# Returns: -# -# $6 - array of partitions' sizes for Mender image -# -set_mender_disk_sizes() { - local count=$1 - local alignment=$2 - local offset=$3 - local datasize_mb=$4 - local _raw_sizes=$(declare -p $5) - eval "declare -A raw_sizes="${_raw_sizes#*=} - shift 5 - local rvar_array=($@) - - local sector_size=${raw_sizes[sector_size]} - local datasize=$(( ($datasize_mb * 1024 * 1024) / $sector_size )) - - local bootstart= - local bootsize= - local rootfsstart= - local rootfssize= - local bootflag= - - if [[ $count -eq 1 ]]; then - # Default size of the boot partition: 16MiB. - bootsize=$(( (${alignment} * 2) / ${sector_size} )) - # Root filesystem size is determined by the size of the single partition. - rootfssize=${raw_sizes[pboot_size]} - else - bootsize=${raw_sizes[pboot_size]} - rootfssize=${raw_sizes[prootfs_size]} - fi - - # Boot partition storage offset is defined from the top down. - bootstart=$(( ${offset} / ${sector_size} )) - - align_partition_size bootsize $sector_size - align_partition_size rootfssize $sector_size - align_partition_size datasize $sector_size - - eval $rvar_array[pboot_start]="'$bootstart'" - eval $rvar_array[pboot_size]="'$bootsize'" - eval $rvar_array[prootfs_size]="'$rootfssize'" - eval $rvar_array[pdata_size]="'$datasize'" - - if [[ $count -eq 3 ]]; then - # Add space for Swap partition. - local swapsize=${raw_sizes[pswap_size]} - align_partition_size swapsize $sector_size - eval $rvar_array[pswap_size]="'$swapsize'" - fi - - eval $rvar_array[sector_size]="'$sector_size'" -} - -# Takes following arguments: -# -# $1 - partition alignment -# $2 - array of partitions' sizes for Mender image -# -# Returns: -# -# #3 - number of partitions of the Mender disk image -# $4 - final Mender disk image size (in bytes) -# -calculate_mender_disk_size() { - local _mender_sizes=$(declare -p $2) - eval "declare -A mender_sizes="${_mender_sizes#*=} - local sector_size=${mender_sizes[sector_size]} - local rvar_counts=$3 - local rvar_sdimgsize=$4 - - local sdimgsize=$(( (${mender_sizes[pboot_start]} + ${mender_sizes[pboot_size]} + \ - 2 * ${mender_sizes[prootfs_size]} + \ - ${mender_sizes[pdata_size]}) * $sector_size )) - - eval $rvar_counts="'4'" - - if [ -v mender_sizes[pswap_size] ]; then - log "\tSwap partition found." - # Add size of the swap partition to the total size. - sdimgsize=$(( $sdimgsize + (${mender_sizes[pswap_size]} * $sector_size) )) - # Add alignment used as swap partition offset. - sdimgsize=$(( $sdimgsize + 2 * ${1} )) - eval $rvar_counts="'6'" - fi - - eval $rvar_sdimgsize="'$sdimgsize'" -} - -# Takes following arguments: -# -# $1 - number of partition of the Mender image -# $2 - calculated total size of the Mender image in bytes -# $3 - expected total size of the Mender image in mb -# $4 - array of partitions' sizes for Mender image -# -# Returns: -# -# Size of the rootfs partition updated and adjusted to total storage size -# -mender_image_size_to_total_storage_size() { - local count=$1 - local rvar_image_size=$2 - local -n image_size_bytes=$2 - local storage_size_mb=$3 - - local _mender_sizes=$(declare -p $4) - eval "declare -A mender_sizes="${_mender_sizes#*=} - - shift 3 - local rvar_array=($@) - - local image_size_mb=$(( (($image_size_bytes / 1024) / 1024) )) - - log "\tAdjust Mender disk image size to the total storage size (${storage_size_mb}MB)." - - if [ $image_size_mb -gt $storage_size_mb ]; then - log "\tDefined total storage size of ${3}MB is too small." - log "\tMinimal required storage is ${image_size_mb}MB. Aborting." - return 1 - elif [ $image_size_mb -eq $storage_size_mb ]; then - # Simply continue. - log "\tCalculated Mender image size exactly fits the defined total storage." - return 0 - fi - - # Get spare space for rootfs a/b partitions (in sectors). - local sector_size=${mender_sizes[sector_size]} - local image_size_s=$(( $image_size_bytes / $sector_size )) - local storage_size_bytes=$(( ($storage_size_mb * 1024 * 1024) )) - local storage_size_s=$(( $storage_size_bytes / $sector_size )) - local rootfs_overplus_bytes=0 - - local spare_storage_bytes=$(( $storage_size_bytes - $image_size_bytes )) - - if [ $(($spare_storage_bytes % 2)) -ne 0 ]; then - log "\tAdditional space for rootfs partitions not divisible by 2.\ - \n\tFinal image will be smaller than ${storage_size_mb}MB" - fi - rootfs_overplus_bytes=$(( $spare_storage_bytes / 2 )) - - local reminder=$(( ${rootfs_overplus_bytes} % ${partition_alignment} )) - if [ $reminder -ne 0 ]; then - log "\tAdditional space for rootfs partitions not aligned.\ - \n\tFinal image will be smaller than ${storage_size_mb}MB" - fi - rootfs_overplus_bytes=$(($rootfs_overplus_bytes - $reminder)) - rootfs_overplus_s=$(( $rootfs_overplus_bytes / $sector_size )) - - local prootfs_size=${mender_sizes[prootfs_size]} - prootfs_size=$(( $prootfs_size + $rootfs_overplus_s )) - - image_size_bytes=$(( $image_size_bytes + 2 * $rootfs_overplus_bytes )) - - eval $rvar_array[prootfs_size]="'$prootfs_size'" - eval $rvar_image_size="'$image_size_bytes'" - - return 0 -} - -# Takes following arguments: -# -# $1 - raw disk image path -# $2 - raw disk image size -create_mender_disk() { - local lfile=$1 - local lsize=$2 - - # Generates a sparse image - dd if=/dev/zero of=${lfile} seek=${lsize} bs=1 count=0 >> "$build_log" 2>&1 -} - -# Takes following arguments: -# -# $1 - Mender disk image path -# $2 - Mender disk image size -# $3 - partition alignment -# $4 - array of partitions' sizes for Mender image -# -format_mender_disk() { - local lfile=$1 - local lsize=$2 - local rc=0 - - local _mender_sizes=$(declare -p $4) - eval "declare -A mender_sizes="${_mender_sizes#*=} - - local sector_size=${mender_sizes[sector_size]} - local alignment=$(($3 / ${sector_size})) - - cylinders=$(( ${lsize} / ${heads} / ${sectors} / ${sector_size} )) - - pboot_start=${mender_sizes[pboot_start]} - pboot_size=${mender_sizes[pboot_size]} - pboot_end=$((${pboot_start} + ${pboot_size} - 1)) - - prootfs_size=${mender_sizes[prootfs_size]} - - prootfsa_start=$((${pboot_end} + 1)) - prootfsa_end=$((${prootfsa_start} + ${prootfs_size} - 1)) - - prootfsb_start=$((${prootfsa_end} + 1)) - prootfsb_end=$((${prootfsb_start} + ${prootfs_size} - 1)) - - pdata_start=$((${prootfsb_end} + 1)) - pdata_size=${mender_sizes[pdata_size]} - pdata_end=$((${pdata_start} + ${pdata_size} - 1)) - - if [ -v mender_sizes[pswap_size] ]; then - local pextended_start=$((${prootfsb_end} + 1)) - - pdata_start=$(($pextended_start + ${alignment})) - pdata_end=$((${pdata_start} + ${pdata_size} - 1)) - - local pswap_start=$((${pdata_end} + ${alignment} + 1)) - local pswap_size=${mender_sizes[pswap_size]} - local pswap_end=$((${pswap_start} + ${pswap_size} - 1)) - fi - - sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | sudo fdisk ${lfile} &> /dev/null - o # clear the in memory partition table - x - h - ${heads} - s - ${sectors} - c - ${cylinders} - r - w # write the partition table - q # and we're done -EOF - - # Create partition table - sudo parted -s ${lfile} mklabel msdos || rc=$? - sudo parted -s ${lfile} unit s mkpart primary fat32 ${pboot_start} ${pboot_end} || rc=$? - sudo parted -s ${lfile} set 1 boot on || rc=$? - sudo parted -s ${lfile} -- unit s mkpart primary ext4 ${prootfsa_start} ${prootfsa_end} || rc=$? - sudo parted -s ${lfile} -- unit s mkpart primary ext4 ${prootfsb_start} ${prootfsb_end} || rc=$? - - if [ -v mender_sizes[pswap_size] ]; then - log "\tAdding swap partition." - sudo parted -s ${lfile} -- unit s mkpart extended ${pextended_start} 100% || rc=$? - sudo parted -s ${lfile} -- unit s mkpart logical ext4 ${pdata_start} ${pdata_end} || rc=$? - sudo parted -s ${lfile} -- unit s mkpart logical linux-swap ${pswap_start} ${pswap_end} || rc=$? - else - sudo parted -s ${lfile} -- unit s mkpart primary ext4 ${pdata_start} ${pdata_end} || rc=$? - fi - - [[ $rc -eq 0 ]] && { log "\tChanges in partition table applied."; } - - return $rc -} - -# Takes following arguments: -# -# $1 - raw disk file -# -verify_mender_disk() { - local lfile=$1 - local lcounts=$2 - - local limage=$(basename $lfile) - local partitions=($(fdisk -l -u ${limage} | cut -d' ' -f1 | grep 'sdimg[1-9]\{1\}$')) - - local no_of_parts=${#partitions[@]} - - [[ $no_of_parts -eq $lcounts ]] || \ - { log "Error: incorrect number of partitions: $no_of_parts. Aborting."; return 1; } - - return 0 -} - -# Takes following arguments: -# -# $1 - raw disk image -# $2 - partition mappings holder -create_device_maps() { - local -n mappings=$2 - - if [[ -n "$1" ]]; then - loopdevice=$(sudo losetup --show -f $1) - mapfile -t mappings < <( sudo kpartx -s -v -a $loopdevice | grep 'loop' | cut -d' ' -f3 ) - [[ ${#mappings[@]} -eq 0 ]] \ - && { log "Error: partition mappings failed. Aborting."; exit 1; } - else - log "Error: no device passed. Aborting." - exit 1 - fi - - sudo partprobe /dev/${mappings[0]%p*} -} - -# Takes following arguments: -# -# $1 - partition mappings holder -detach_device_maps() { - local mappings=($@) - - [ ${#mappings[@]} -eq 0 ] && { log "\tPartition mappings cleaned."; return; } - - local mapper=${mappings[0]%p*} - - for mapping in ${mappings[@]} - do - map_dev=/dev/mapper/"$mapping" - is_mounted=`grep ${map_dev} /proc/self/mounts | wc -l` - if [ ${is_mounted} -ne 0 ]; then - sudo umount -l $map_dev - fi - done - - sudo kpartx -d /dev/$mapper & - sudo losetup -d /dev/$mapper & - wait && sync -} - -# Takes following arguments: -# -# $1 - partition mappings holder -# -make_mender_disk_filesystem() { - local mappings=($@) - local counts=${#mappings[@]} - - if [ $counts -eq 4 ]; then - local labels=(${mender_partitions_regular[@]}) - elif [ $counts -eq 6 ]; then - local labels=(${mender_partitions_extended[@]}) - fi - - for mapping in ${mappings[@]} - do - map_dev=/dev/mapper/"$mapping" - part_no=$(get_part_number_from_device $map_dev) - label=${labels[${part_no} - 1]} - - case ${part_no} in - 1) - log "\tCreating MS-DOS filesystem for '$label' partition." - sudo mkfs.vfat -n ${label} $map_dev >> "$build_log" 2>&1 - ;; - 2|3) - log "\tCreating ext4 filesystem for '$label' partition." - sudo mkfs.ext4 -L ${label} $map_dev >> "$build_log" 2>&1 - ;; - 4) - if [ $counts -eq 4 ]; then - log "\tCreating ext4 filesystem for '$label' partition." - sudo mkfs.ext4 -L ${label} $map_dev >> "$build_log" 2>&1 - else - continue - fi - ;; - 5) - log "\tCreating ext4 filesystem for '$label' partition." - sudo mkfs.ext4 -L ${label} $map_dev >> "$build_log" 2>&1 - ;; - 6) - log "\tCreating swap area for '$label' partition." - sudo mkswap -L ${label} $map_dev >> "$build_log" 2>&1 - ;; - *) - break - ;; - esac - done -} - -# Takes following arguments: -# -# $1 - partition mappings holder -mount_raw_disk() { - local mappings=($@) - - if [ ${#mappings[@]} -eq 1 ]; then - local path=$embedded_rootfs_dir - mkdir -p $path - sudo mount /dev/mapper/"${mappings[0]}" $path - return - fi - - for mapping in ${mappings[@]} - do - local part_no=${mapping#*p*p} - local path=$embedded_base_dir/${raw_disk_partitions[${part_no} - 1]} - mkdir -p $path - sudo mount /dev/mapper/"${mapping}" $path 2>&1 >/dev/null - done -} - -# Takes following arguments: -# -# $1 - partition mappings holder -mount_mender_disk() { - local mappings=($@) - local counts=${#mappings[@]} - - if [ $counts -eq 4 ]; then - local labels=(${mender_partitions_regular[@]}) - elif [ $counts -eq 6 ]; then - local labels=(${mender_partitions_extended[@]}) - fi - - for mapping in ${mappings[@]} - do - local part_no=${mapping#*p*p} - local path=$sdimg_base_dir/${labels[${part_no} - 1]} - mkdir -p $path - - case ${part_no} in - 1|2|3) - sudo mount /dev/mapper/"${mapping}" $path 2>&1 >/dev/null - ;; - 4) - if [ $counts -eq 4 ]; then - sudo mount /dev/mapper/"${mapping}" $path 2>&1 >/dev/null - else - # Skip extended partition. - continue - fi - ;; - 5) - sudo mount /dev/mapper/"${mapping}" $path 2>&1 >/dev/null - ;; - 6) - # Skip swap partition. - continue - ;; - *) - break - ;; - esac - - done -} - -# Takes following arguments -# -# $1 - device type -set_fstab() { - local mountpoint= - local blk_device= - local data_id=4 - local device_type=$1 - local sysconfdir="$sdimg_primary_dir/etc" - - [ ! -d "${sysconfdir}" ] && { log "Error: cannot find rootfs config dir."; exit 1; } - - # Erase/create the fstab file. - sudo install -b -m 644 /dev/null ${sysconfdir}/fstab - - case "$device_type" in - "beaglebone") - mountpoint="/boot/efi" - blk_device=mmcblk0p - ;; - "raspberrypi3"|"raspberrypi0w") - mountpoint="/uboot" - blk_device=mmcblk0p - ;; - "rockpro64") - mountpoint="/uboot" - blk_device=mmcblk1p - ;; - "qemux86_64") - mountpoint="/boot/efi" - blk_device=hda - data_id=5 - ;; - *) - log "Error: unsupported device type $device_type" - exit 1 - ;; - esac - - # Add Mender specific entries to fstab. - sudo bash -c "cat <<- EOF > ${sysconfdir}/fstab - # stock fstab - you probably want to override this with a machine specific one - - /dev/root / auto defaults 1 1 - proc /proc proc defaults 0 0 - devpts /dev/pts devpts mode=0620,gid=5 0 0 - tmpfs /run tmpfs mode=0755,nodev,nosuid,strictatime 0 0 - tmpfs /var/volatile tmpfs defaults 0 0 - - # uncomment this if your device has a SD/MMC/Transflash slot - #/dev/mmcblk0p1 /media/card auto defaults,sync,noauto 0 0 - - # Where the U-Boot environment resides; for devices with SD card support ONLY! - /dev/${blk_device}1 $mountpoint auto defaults,sync 0 0 - /dev/${blk_device}${data_id} /data auto defaults 0 0 - EOF" - - if [ "$device_type" == "qemux86_64" ]; then - # Add entry referring to swap partition. - sudo tee -a ${sysconfdir}/fstab <<< "/dev/hda6 swap swap defaults 0 0" 2>&1 >/dev/null - fi - - log "\tDone." -} - -# Takes following arguments -# -# $1 - path to source raw disk image -# $2 - sector start (in 512 blocks) -# $3 - size (in 512 blocks) - -extract_file_from_image() { - log "\tStoring data in $4." - local cmd="dd if=$1 of=${output_dir}/$4 skip=$2 bs=512 count=$3 conv=sparse" - $(${cmd}>> "$build_log" 2>&1) -} - -# Takes following arguments -# -# $1 - device type -# $2 - partition alignment in bytes -# $3 - total size in bytes -# $4 - array of partitions' sizes for Mender image -# -create_test_config_file() { - local device_type=$1 - local alignment=$2 - local mender_image_size_mb=$(( (($3 / 1024) / 1024) )) - local _mender_sizes=$(declare -p $4) - eval "declare -A mender_sizes="${_mender_sizes#*=} - local sector_size=${mender_sizes[sector_size]} - - local boot_offset=$(( (${mender_sizes[pboot_start]} * $sector_size) )) - local boot_size_mb=$(( (((${mender_sizes[pboot_size]} * $sector_size) / 1024) / 1024) )) - local rootfs_size_mb=$(( (((${mender_sizes[prootfs_size]} * $sector_size) / 1024) / 1024) )) - local data_size_mb=$(( (((${mender_sizes[pdata_size]} * $sector_size) / 1024) / 1024) )) - - cp ${files_dir}/variables.template ${output_dir}/${device_type}_variables.cfg - - sed -i '/^MENDER_BOOT_PART_SIZE_MB/s/=.*$/="'${boot_size_mb}'"/' ${output_dir}/${device_type}_variables.cfg - sed -i '/^MENDER_DATA_PART_SIZE_MB/s/=.*$/="'${data_size_mb}'"/' ${output_dir}/${device_type}_variables.cfg - sed -i '/^MENDER_DEVICE_TYPE/s/=.*$/="'${device_type}'"/' ${output_dir}/${device_type}_variables.cfg - sed -i '/^MENDER_PARTITION_ALIGNMENT/s/=.*$/="'${alignment}'"/' ${output_dir}/${device_type}_variables.cfg - sed -i '/^MENDER_STORAGE_TOTAL_SIZE_MB/s/=.*$/="'${mender_image_size_mb}'"/' ${output_dir}/${device_type}_variables.cfg - sed -i '/^MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET/s/=.*$/="'${boot_offset}'"/' ${output_dir}/${device_type}_variables.cfg - sed -i '/^MENDER_CALC_ROOTFS_SIZE/s/=.*$/="'${rootfs_size_mb}'"/' ${output_dir}/${device_type}_variables.cfg - sed -i '/^MENDER_MACHINE/s/=.*$/="'${device_type}'"/' ${output_dir}/${device_type}_variables.cfg - sed -i '/^DEPLOY_DIR_IMAGE/s/=.*$/="'${output_dir//\//\\/}'"/' ${output_dir}/${device_type}_variables.cfg -} - -# Takes following arguments -# -# $1 - device type -# $2 - parameter name to change -# $3 - parameter value -update_test_config_file() { - local device_type=$1 - - [ ! -f "${output_dir}/${device_type}_variables.cfg" ] && \ - { log "Error: test configuration file '${device_type}_variables.cfg' not found. Aborting."; return 1; } - - shift - - while test ${#} -gt 0 - do - case "$1" in - "artifact-name") - sed -i '/^MENDER_ARTIFACT_NAME/s/=.*$/="'${2}'"/' ${output_dir}/${device_type}_variables.cfg - ;; - "distro-feature") - sed -i '/^DISTRO_FEATURES/s/=.*$/="'${2}'"/' ${output_dir}/${device_type}_variables.cfg - ;; - "mount-location") - sed -i '/^MENDER_BOOT_PART_MOUNT_LOCATION/s/=.*$/="'${2}'"/' ${output_dir}/${device_type}_variables.cfg - ;; - esac - shift 2 - done - - return 0 -} diff --git a/qemux86_64-convert-stage-2.sh b/qemux86_64-convert-stage-2.sh deleted file mode 100755 index 8f94d0e..0000000 --- a/qemux86_64-convert-stage-2.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -output_dir=$1 -boot_mapping=$2 -build_log=$output_dir/build.log - -[ ! -f $output_dir/boot.vfat ] && \ - { log "Error: extracted boot partition not found. Aborting."; exit 1; } - -# Make a copy of Linux kernel arguments and modify. -mcopy -on -i ${output_dir}/boot.vfat -s ::EFI/BOOT/grub.cfg ${output_dir}/grub.cfg -sed -i 's/\b[ ]root=[^ ]*/ root=\/dev\/hda2/' ${output_dir}/grub.cfg - -# Update Linux kernel command arguments with our custom configuration -mcopy -o -i ${output_dir}/boot.vfat -s ${output_dir}/grub.cfg ::EFI/BOOT/grub.cfg - -sudo dd if=${output_dir}/boot.vfat of=/dev/mapper/${boot_mapping} bs=1M conv=sparse >> "$build_log" 2>&1 - -log "\tDone." - -exit 0 diff --git a/rockpro64-convert-stage-2.sh b/rockpro64-convert-stage-2.sh deleted file mode 100755 index 464bd30..0000000 --- a/rockpro64-convert-stage-2.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -output_dir=$1 -boot_mapping=$2 -embedded_rootfs_dir=$3 -uboot_backup_dir=${embedded_rootfs_dir}/opt/backup/uboot -build_log=$output_dir/build.log - -boot_part_dev="/dev/mapper/${boot_mapping}" - -[ ! -f $output_dir/boot.vfat ] && \ - { log "Error: extracted boot partition not found. Aborting."; exit 1; } -[ ! -d "${embedded_rootfs_dir}" ] && \ - { log "Error: embedded content not mounted."; exit 1; } -[ ! -e ${boot_part_dev} ] && \ - { log "Error: boot part does not exist: ${boot_part_dev}."; exit 1; } - -sudo dd if=${output_dir}/boot.vfat of=${boot_part_dev} bs=1M conv=sparse >> "$build_log" 2>&1 - -log "\tDone." - -exit 0 diff --git a/rpi-convert-stage-2.sh b/rpi-convert-stage-2.sh deleted file mode 100755 index f3e9dd6..0000000 --- a/rpi-convert-stage-2.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -output_dir=$1 -boot_mapping=$2 -build_log=$output_dir/build.log - -[ ! -f $output_dir/boot.vfat ] && \ - { log "Error: extracted boot partition not found. Aborting."; exit 1; } - -sudo dd if=${output_dir}/boot.vfat of=/dev/mapper/${boot_mapping} bs=1M conv=sparse >> "$build_log" 2>&1 - -log "\tDone." - -exit 0 diff --git a/rpi-convert-stage-5.sh b/rpi-convert-stage-5.sh deleted file mode 100755 index 7eda331..0000000 --- a/rpi-convert-stage-5.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/bin/bash - -# Copyright 2018 Northern.tech AS -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -application_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -files_dir=${application_dir}/files -output_dir=${application_dir}/output -uboot_dir=${output_dir}/uboot-mender -bin_base_dir=${output_dir}/bin -bin_dir_pi=${bin_base_dir}/raspberrypi -sdimg_base_dir=$output_dir/sdimg -build_log=${output_dir}/build.log - -declare -a mender_disk_mappings -declare -a mender_partitions_regular=("boot" "primary" "secondary" "data") - -# Takes following arguments: -# -# $1 - ARM toolchain -# $2 - RPI machine (raspberrypi3 or raspberrypi0w) -build_uboot_files() { - local CROSS_COMPILE=${1}- - local ARCH=arm - local branch="mender-rpi-2018.07" - local commit="884893e54a" - local uboot_repo_vc_dir=$uboot_dir/.git - local defconfig="rpi_3_32b_defconfig" - - if [ "$2" == "raspberrypi0w" ]; then - defconfig="rpi_0_w_defconfig" - fi - - export CROSS_COMPILE=$CROSS_COMPILE - export ARCH=$ARCH - - mkdir -p $bin_dir_pi - - log "\tBuilding U-Boot related files." - - if [ ! -d $uboot_repo_vc_dir ]; then - git clone https://github.com/mendersoftware/uboot-mender.git -b $branch >> "$build_log" 2>&1 - fi - - cd $uboot_dir - - git checkout $commit >> "$build_log" 2>&1 - - make --quiet distclean >> "$build_log" - make --quiet $defconfig >> "$build_log" 2>&1 - make --quiet >> "$build_log" 2>&1 - make --quiet envtools >> "$build_log" 2>&1 - - cat<<-'EOF' >boot.cmd - fdt addr ${fdt_addr} && fdt get value bootargs /chosen bootargs - run mender_setup - mmc dev ${mender_uboot_dev} - if load ${mender_uboot_root} ${kernel_addr_r} /boot/zImage; then - bootz ${kernel_addr_r} - ${fdt_addr} - elif load ${mender_uboot_root} ${kernel_addr_r} /boot/uImage; then - bootm ${kernel_addr_r} - ${fdt_addr} - else - echo "No bootable Kernel found." - fi - run mender_try_to_recover - EOF - - if [ ! -e $uboot_dir/tools/mkimage ]; then - log "Error: cannot build U-Boot. Aborting" - return 1 - fi - - $uboot_dir/tools/mkimage -A arm -T script -C none -n "Boot script" -d "boot.cmd" boot.scr >> "$build_log" 2>&1 - cp -t $bin_dir_pi $uboot_dir/boot.scr $uboot_dir/tools/env/fw_printenv $uboot_dir/u-boot.bin - - return 0 -} - -# Takes following arguments: -# -# $1 - boot partition mountpoint -# $2 - primary partition mountpoint -install_files() { - local boot_dir=$1 - local rootfs_dir=$2 - local kernel_img="kernel7.img" - - if [ "${device_type}" == "raspberrypi0w" ]; then - kernel_img="kernel.img" - fi - - log "\tInstalling U-Boot related files." - - # Make a copy of Linux kernel arguments and modify. - sudo cp ${boot_dir}/cmdline.txt ${output_dir}/cmdline.txt - - sed -i 's/\b[ ]root=[^ ]*/ root=\${mender_kernel_root}/' ${output_dir}/cmdline.txt - - # Original Raspberry Pi image run once will have init_resize.sh script removed - # from the init argument from the cmdline. - # - # On the other hand in Mender image we want to retain a mechanism of last - # partition resizing. Check the cmdline.txt file and add it back if necessary. - if ! grep -q "init=/usr/lib/raspi-config/init_resize.sh" ${output_dir}/cmdline.txt; then - cmdline=$(cat ${output_dir}/cmdline.txt) - sh -c -e "echo '${cmdline} init=/usr/lib/raspi-config/init_resize.sh' > ${output_dir}/cmdline.txt"; - fi - - # Update Linux kernel command arguments with our custom configuration - sudo cp ${output_dir}/cmdline.txt ${boot_dir} - - # Mask udisks2.service, otherwise it will mount the inactive part and we - # might write an update while it is mounted which often result in - # corruptions. - # - # TODO: Find a way to only blacklist mmcblk0pX devices instead of masking - # the service. - sudo ln -sf /dev/null ${rootfs_dir}/etc/systemd/system/udisks2.service - - # Extract Linux kernel and install to /boot directory on rootfs - sudo cp ${boot_dir}/${kernel_img} ${rootfs_dir}/boot/zImage - - # Replace kernel with U-boot and add boot script - sudo mkdir -p ${rootfs_dir}/uboot - - sudo cp ${bin_dir_pi}/u-boot.bin ${boot_dir}/${kernel_img} - - sudo cp ${bin_dir_pi}/boot.scr ${boot_dir} - - # Raspberry Pi configuration files, applications expect to find this on - # the device and in some cases parse the options to determinate - # functionality. - sudo ln -fs /uboot/config.txt ${rootfs_dir}/boot/config.txt - - sudo install -m 755 ${bin_dir_pi}/fw_printenv ${rootfs_dir}/sbin/fw_printenv - sudo ln -fs /sbin/fw_printenv ${rootfs_dir}/sbin/fw_setenv - - # Override init script to expand the data partition instead of rootfs, which it - # normally expands in standard Raspberry Pi distributions. - sudo install -m 755 ${files_dir}/init_resize.sh \ - ${rootfs_dir}/usr/lib/raspi-config/init_resize.sh - - # As the whole process must be conducted in two steps, i.e. resize partition - # during first boot and resize the partition's file system on system's first - # start-up add systemd service file and script. - sudo install -m 644 ${files_dir}/resizefs.service \ - ${rootfs_dir}/lib/systemd/system/resizefs.service - sudo ln -sf /lib/systemd/system/resizefs.service \ - ${rootfs_dir}/etc/systemd/system/multi-user.target.wants/resizefs.service - sudo install -m 755 ${files_dir}/resizefs.sh \ - ${rootfs_dir}/usr/sbin/resizefs.sh - - # Remove original 'resize2fs_once' script and its symbolic link. - sudo unlink ${rootfs_dir}/etc/rc3.d/S01resize2fs_once - sudo rm ${rootfs_dir}/etc/init.d/resize2fs_once -} - -do_install_bootloader() { - if [ -z "${mender_disk_image}" ]; then - log "Mender raw disk image file not set. Aborting." - exit 1 - fi - - if [ -z "${bootloader_toolchain}" ]; then - log "ARM GCC toolchain not set. Aborting." - exit 1 - fi - - if ! [ -x "$(command -v ${bootloader_toolchain}-gcc)" ]; then - log "Error: ARM GCC not found in PATH. Aborting." - exit 1 - fi - - [ ! -f $mender_disk_image ] && \ - { log "$mender_disk_image - file not found. Aborting."; exit 1; } - - # Map & mount Mender compliant image. - create_device_maps $mender_disk_image mender_disk_mappings - - # Change current directory to 'output' directory. - cd $output_dir - - # Build patched U-Boot files. - build_uboot_files $bootloader_toolchain $device_type - rc=$? - cd $output_dir - - if [ $rc -eq 0 ]; then - mount_mender_disk ${mender_disk_mappings[@]} - install_files ${output_dir}/sdimg/boot ${output_dir}/sdimg/primary - fi - - detach_device_maps ${mender_disk_mappings[@]} - rm -rf $sdimg_base_dir - - [[ $keep -eq 0 ]] && { rm -f ${output_dir}/config.txt ${output_dir}/cmdline.txt; - rm -rf $uboot_dir $bin_base_dir; } - - [[ "$rc" -ne 0 ]] && { exit 1; } || { log "\tDone."; } -} - -# Conditional once we support other boards -PARAMS="" - -while (( "$#" )); do - case "$1" in - -m | --mender-disk-image) - mender_disk_image=$2 - shift 2 - ;; - -b | --bootloader-toolchain) - bootloader_toolchain=$2 - shift 2 - ;; - -d | --device-type) - device_type=$2 - shift 2 - ;; - -k | --keep) - keep=1 - shift 1 - ;; - -h | --help) - show_help - exit 0 - ;; - --) - shift - break - ;; - -*) - log "Error: unsupported option $1" - exit 1 - ;; - *) - PARAMS="$PARAMS $1" - shift - ;; - esac -done - -eval set -- "$PARAMS" - -# Some commands expect elevated privileges. -sudo true - -do_install_bootloader From fac622517c91cb2883696b18ea04a17d06ec41cb Mon Sep 17 00:00:00 2001 From: Mirza Krak Date: Wed, 3 Jul 2019 13:12:57 +0000 Subject: [PATCH 2/2] MEN-2608: add mender-convert (version 2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The goals of the re-write was to achieve the following: 1. It should be easy to extend the tool to support other boards or distributions 2. We should not compile code in the tool (rely on binaries built elsewhere) compiling code increases complexity, due to requirement of toolchains etc. 3. The tool shall not be designed around specific hardware/platform types - This is the case today with the usage of --device-type flag 4 The tool should be to convert images without knowing anything about the hardware/platform relates to above 3. 5. Configuration interface should be simplified - command line flags -> configuration files 6. Platform specific code shall be provided trough “hooks”, and are not part of the “core” mender-convert code 7. It shall be easy to extend functionality - support for rootfs overlay to inject user applications/configurations - ability to override how the Mender Artifact is generated (to be able to sign and include state-scripts) 8. Code structure should be modular - Eases Maintenance and possibility of making isolated changes Changelog: Title Signed-off-by: Mirza Krak --- .dockerignore | 6 +- .gitignore | 10 +- Dockerfile | 45 +++ LICENSE | 181 ++++++++++++ LIC_FILES_CHKSUM.sha256 | 2 + README.md | 153 +++++++++++ configs/beaglebone_black_base_config | 37 +++ configs/beaglebone_black_debian_sdcard_config | 6 + configs/mender_convert_config | 147 ++++++++++ configs/mender_grub_config | 35 +++ configs/qemux86-64_config | 16 ++ configs/raspberrypi3_config | 8 + configs/raspberrypi_config | 82 ++++++ configs/rockpro64_config | 25 ++ configs/rockpro64_emmc_config | 8 + configs/rockpro64_sd_config | 6 + docker-build | 21 ++ docker-entrypoint.sh | 25 ++ docker-mender-convert | 31 +++ mender-convert | 99 +++++++ mender-convert-extract | 99 +++++++ mender-convert-modify | 215 +++++++++++++++ mender-convert-package | 259 ++++++++++++++++++ modules/bootstrap.sh | 52 ++++ modules/config.sh | 20 ++ modules/disk.sh | 176 ++++++++++++ modules/log.sh | 67 +++++ modules/probe.sh | 237 ++++++++++++++++ modules/run.sh | 28 ++ requirements-deb.txt | 1 + rootfs_overlay_demo/.gitkeep | 0 scripts/README-run-tests.md | 13 + scripts/bootstrap-rootfs-overlay-demo.sh | 64 +++++ scripts/run-tests.sh | 143 ++++++++++ 34 files changed, 2309 insertions(+), 8 deletions(-) create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 LIC_FILES_CHKSUM.sha256 create mode 100644 README.md create mode 100644 configs/beaglebone_black_base_config create mode 100644 configs/beaglebone_black_debian_sdcard_config create mode 100644 configs/mender_convert_config create mode 100644 configs/mender_grub_config create mode 100644 configs/qemux86-64_config create mode 100644 configs/raspberrypi3_config create mode 100644 configs/raspberrypi_config create mode 100644 configs/rockpro64_config create mode 100644 configs/rockpro64_emmc_config create mode 100644 configs/rockpro64_sd_config create mode 100755 docker-build create mode 100755 docker-entrypoint.sh create mode 100755 docker-mender-convert create mode 100755 mender-convert create mode 100755 mender-convert-extract create mode 100755 mender-convert-modify create mode 100755 mender-convert-package create mode 100644 modules/bootstrap.sh create mode 100644 modules/config.sh create mode 100644 modules/disk.sh create mode 100644 modules/log.sh create mode 100644 modules/probe.sh create mode 100644 modules/run.sh create mode 100644 requirements-deb.txt create mode 100644 rootfs_overlay_demo/.gitkeep create mode 100644 scripts/README-run-tests.md create mode 100755 scripts/bootstrap-rootfs-overlay-demo.sh create mode 100755 scripts/run-tests.sh diff --git a/.dockerignore b/.dockerignore index 24ae780..94e5f31 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,3 @@ -input/ -output/ -device-image-shell/output +deploy +input +work diff --git a/.gitignore b/.gitignore index 3ecb6c2..be018dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -input/ -output/ -device-image-shell/output -mendertesting/ -integration/ +deploy +input +work +rootfs_overlay_demo/* +tests diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b19e133 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +FROM ubuntu:19.04 + +ARG MENDER_ARTIFACT_VERSION=3.1.0 + +RUN apt-get update && apt-get install -y \ +# For 'ar' command to unpack .deb + binutils \ + xz-utils \ +# to be able to detect file system types of extracted images + file \ +# to copy files between rootfs directories + rsync \ +# to generate partition table + parted \ +# mkfs.ext4 and family + e2fsprogs \ +# mkfs.xfs and family + xfsprogs \ +# Parallel gzip compression + pigz \ + sudo \ +# mkfs.vfat (required for boot partition) + dosfstools \ +# to download mender-artifact + wget \ +# to download mender-grub-env + git \ +# to compile mender-grub-env + make \ +# to get rid of 'sh: 1: udevadm: not found' errors triggered by parted + udev \ +# to create bmap index file (MENDER_USE_BMAP) + bmap-tools + +RUN wget -q -O /usr/bin/mender-artifact https://d1b0l86ne08fsf.cloudfront.net/mender-artifact/$MENDER_ARTIFACT_VERSION/linux/mender-artifact \ + && chmod +x /usr/bin/mender-artifact + +# allow us to keep original PATH variables when sudoing +RUN echo "Defaults secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:$PATH\"" > /etc/sudoers.d/secure_path_override +RUN chmod 0440 /etc/sudoers.d/secure_path_override + +WORKDIR / + +COPY docker-entrypoint.sh /usr/local/bin/ +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a819abc --- /dev/null +++ b/LICENSE @@ -0,0 +1,181 @@ +Copyright 2019 Northern.tech AS + +All content in this project is licensed under the Apache License v2, unless +indicated otherwise. + +------------------------------------------------------------------------------- + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/LIC_FILES_CHKSUM.sha256 b/LIC_FILES_CHKSUM.sha256 new file mode 100644 index 0000000..2534c88 --- /dev/null +++ b/LIC_FILES_CHKSUM.sha256 @@ -0,0 +1,2 @@ +beb140be4cd64599bedc691a55b2729c9cc611a4b9d6ec44e01270105daf18a2 LICENSE +beb140be4cd64599bedc691a55b2729c9cc611a4b9d6ec44e01270105daf18a2 mendertesting/LICENSE diff --git a/README.md b/README.md new file mode 100644 index 0000000..0581708 --- /dev/null +++ b/README.md @@ -0,0 +1,153 @@ +# mender-convert + +Mender is an open source over-the-air (OTA) software updater for embedded Linux devices. Mender comprises a client running at the embedded device, as well as a server that manages deployments across many devices. + +This repository contains mender-convert, which is used to convert pre-built disk images (Debian, Ubuntu, Raspbian, etc) to a Mender compatible image by restructuring partition table and injecting the necessary files. + +For a full list of tested devices and images please visit [Mender Hub](https://hub.mender.io/c/board-integrations/debian-family). If your device and image combination is not listed as supported, this does not necessarily mean that it will not work, it probably just means that no one has tested and reported it back and usually only small tweaks are necessary to get this running on your device. + +![Mender logo](https://mender.io/user/pages/resources/06.digital-assets/mender.io.png) + + +## Getting started + +To start using Mender, we recommend that you begin with the Getting started +section in [the Mender documentation](https://docs.mender.io/). + +For more detailed information about `mender-convert` please visit the +[Debian family](https://docs.mender.io/artifacts/debian-family) section in +[the Mender documentation](https://docs.mender.io/). + + +### Prepare image and configuration + +Download the raw Raspberry Pi disk image into a subdirectory input: + +```bash +mkdir -p input +cd input +wget https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-06-24/2019-06-20-raspbian-buster-lite.zip +``` + +Extract the raw Raspberry Pi disk image: + +```bash +unzip 2019-06-20-raspbian-buster-lite.zip && cd .. +``` + +Bootstrap the demo rootfs overlay that is configured to connect to +https://hosted.mender.io with polling intervals set appropriately for +demonstration purposes: + +``` +./scripts/bootstrap-rootfs-overlay-demo.sh \ + --output-dir ${PWD}/rootfs_overlay_demo \ + --tenant-token "Paste token from Hosted Mender" +``` + + +### Docker environment for mender-convert + +To make using mender-convert easier, a reference setup using a Docker +container is provided. + +You need to [install Docker Engine](https://docs.docker.com/install) to use +this environment. + + +#### Build the mender-convert container image + +Build a container with all required dependencies for `mender-convert`: + +```bash +./docker-build +``` + +This will create a container image which you can use to run `mender-convert` +without polluting your host environment with the necessary dependencies. + + +#### Use the mender-convert container image + +Run mender-convert from inside the container with your desired options, e.g. + +```bash +MENDER_ARTIFACT_NAME=release-1 ./docker-mender-convert \ + --disk-image input/2019-04-08-raspbian-stretch-lite.img \ + --config configs/raspberrypi3_config \ + --overlay rootfs_overlay_demo/ +``` + +Conversion will take 10-30 minutes, depending on image size and resources +available. You can watch `work/convert.log` for progress and diagnostics +information. + +After it finishes, you can find your images in the `deploy` directory on your +host machine! + +## Using mender-convert without Docker + +In order to be able to manipulate and create filesystem and disk images, +mender-convert has a few dependencies, and their version and name vary between +Linux distributions. Here is an example of how to install the dependencies on a +Debian based distribution: + +``` +sudo apt install $(cat requirements-deb.txt) +``` + +Start the conversion process with: + +```bash +MENDER_ARTIFACT_NAME=release-1 ./mender-convert \ + --disk-image input/2019-04-08-raspbian-stretch-lite.img \ + --config configs/raspberrypi3_config \ + --overlay rootfs_overlay_demo/ +``` + +**NOTE!** You will be prompted to enter `sudo` password during the conversion +process. This is required to be able to loopback mount images and for modifying +them. Our recommendation is to use the provided Docker container, to run the +tool in a isolated environment (at least to some degree). + + +## Contributing + +We welcome and ask for your contribution. If you would like to contribute to +Mender, please read our guide on how to best get started +[contributing code or documentation](https://github.com/mendersoftware/mender/blob/master/CONTRIBUTING.md). + + +## License + +Mender is licensed under the Apache License, Version 2.0. See +[LICENSE](https://github.com/mendersoftware/mender-convert/blob/master/LICENSE) +for the full license text. + + +## Security disclosure + +We take security very seriously. If you come across any issue regarding +security, please disclose the information by sending an email to +[security@mender.io](security@mender.io). Please do not create a new public +issue. We thank you in advance for your cooperation. + + +## Connect with us + +* Join the [Mender Hub discussion forum](https://hub.mender.io) +* Follow us on [Twitter](https://twitter.com/mender_io). Please + feel free to tweet us questions. +* Fork us on [Github](https://github.com/mendersoftware) +* Create an issue in the [bugtracker](https://tracker.mender.io/projects/MEN) +* Email us at [contact@mender.io](mailto:contact@mender.io) +* Connect to the [#mender IRC channel on Freenode](http://webchat.freenode.net/?channels=mender) + + +## Authors + +Mender was created by the team at [Northern.tech AS](https://northern.tech), +with many contributions from the community. Thanks +[everyone](https://github.com/mendersoftware/mender/graphs/contributors)! + +[Mender](https://mender.io) is sponsored by [Northern.tech AS](https://northern.tech). diff --git a/configs/beaglebone_black_base_config b/configs/beaglebone_black_base_config new file mode 100644 index 0000000..84fb04b --- /dev/null +++ b/configs/beaglebone_black_base_config @@ -0,0 +1,37 @@ +# Binaries generated with the following script: +# +# https://github.com/drewmoseley/mender-convert-integration-scripts/blob/master/build-uboot-bbb.sh +# + +# There are reported issues with GRUB bootloader integration, fallback to U-boot. +MENDER_GRUB_EFI_INTEGRATION=n + +# 4MB alignment +MENDER_PARTITION_ALIGNMENT="4194304" + +BEAGLEBONE_BLACK_BINARIES_URL="${MENDER_STORAGE_URL}/mender-convert/beaglebone/${BEAGLEBONE_BLACK_BINARIES}" + +function platform_modify() { + mkdir -p work/bbb/binaries + + run_and_log_cmd "wget -q ${BEAGLEBONE_BLACK_BINARIES_URL} -P work/bbb/binaries" + run_and_log_cmd "tar xvf work/bbb/binaries/${BEAGLEBONE_BLACK_BINARIES} -C work/bbb/binaries" + + # Mask udisks2.service, otherwise it will mount the inactive part and we + # might write an update while it is mounted which often result in + # corruptions. + # + # TODO: Find a way to only blacklist mmcblk0pX devices instead of masking + # the service. + run_and_log_cmd "sudo ln -sf /dev/null work/rootfs/etc/systemd/system/udisks2.service" + + # Place u-boot and MLO into rootfs/boot + run_and_log_cmd "sudo mkdir -p work/rootfs/boot" + run_and_log_cmd "sudo cp work/bbb/binaries/MLO work/boot/" + run_and_log_cmd "sudo cp work/bbb/binaries/u-boot.img work/boot/" + run_and_log_cmd "sudo cp work/bbb/binaries/fw_env.config work/rootfs/etc/" + run_and_log_cmd "sudo cp work/bbb/binaries/uboot-git-log.txt work/boot" + + run_and_log_cmd "sudo install -m 755 work/bbb/binaries/fw_printenv work/rootfs/sbin/fw_printenv" + run_and_log_cmd "sudo ln -fs /sbin/fw_printenv work/rootfs/sbin/fw_setenv" +} diff --git a/configs/beaglebone_black_debian_sdcard_config b/configs/beaglebone_black_debian_sdcard_config new file mode 100644 index 0000000..67a0b0d --- /dev/null +++ b/configs/beaglebone_black_debian_sdcard_config @@ -0,0 +1,6 @@ +# Binaries generated with the following script: +# +# https://github.com/drewmoseley/mender-convert-integration-scripts/blob/master/build-uboot-bbb.sh +# +BEAGLEBONE_BLACK_BINARIES="beaglebone-black-integration-debian-2018.07.002.tar" +source configs/beaglebone_black_base_config diff --git a/configs/mender_convert_config b/configs/mender_convert_config new file mode 100644 index 0000000..c865ded --- /dev/null +++ b/configs/mender_convert_config @@ -0,0 +1,147 @@ +# This is the default configuration used by mender-convert. You can override +# any option specified here by providing your own configuration file using the +# '--config' argument. +# +# NOTE! This file will always be sourced. + +# Compress generated disk image using gzip +# +# This is useful when you have large disk images, compressing them +# makes it easier to transfer them between e.g an build server and a local +# machine, and obviously saves space. +MENDER_COMPRESS_DISK_IMAGE=y + +# Compression algorithm for Mender Artifact +# +# Supported values are: lzma, gzip (default), none +# +# LZMA will produce a smaller Mender Artifact (2-3x) but will significantly +# increase time spent generating the Mender Artifact (10x) +MENDER_ARTIFACT_COMPRESSION="gzip" + +# Enable Mender systemd server +# +# You want this enabled if you want the Mender client to operate in managed mode +# and connect to a server. If you are not interested connecting to a server +# and will only be running standalone mode updates, then you can safely disable +# this. +MENDER_ENABLE_SYSTEMD=y + +# Set the fstab options for mounting the data partition +MENDER_DATA_PART_FSTAB_OPTS="defaults" + +# The file system will be grown to occupy the full block device. If the file +# system is already at maximum size, no action will be performed. +# +# This feature is utilizing x−systemd.growfs and will only work on systemd 242 +# and newer and nothing will be done if an older systemd version is used. +MENDER_DATA_PART_GROWFS=y + +# The name of the image or update that will be built. This is what the device +# will report that it is running, and different updates must have different +# names. +# +# This variable must be defined or the build will fail, but you should not +# set it in a configuration file and instead it should be an input to the +# mender-convert tool, e.g +# +# MENDER_ARTIFACT_NAME="release-1" ./mender-convert +# +#MENDER_ARTIFACT_NAME="" + +# A string that defines the type of device this image will be installed on and +# this value is used for compatibility checks between Mender Artifact and +# what the device is reporting. +# +# You can define multiple types by providing a space separated string of device +# types. +# +# It defaults to the content of '/etc/hostname', which is extracted from the +# input disk image +MENDER_DEVICE_TYPE="" + +# Total size of the physical storage medium that mender partitioned images +# will be written to, expressed in MiB. The size of rootfs partition will be +# calculated automatically by subtracting the sizes of boot +# (see MENDER_BOOT_PART_SIZE_MB) and data partitions +# (see MENDER_DATA_PART_SIZE_MB). +# +MENDER_STORAGE_TOTAL_SIZE_MB="8192" + +# The size of the boot partition in the generated .biosimg, .sdimg or .uefiimg +# file. +MENDER_BOOT_PART_SIZE_MB="40" + +# The size of the persistent data partition in the generated .biosimg, .sdimg +# or .uefiimg file. +# +# You rarely need to increase this number as this partition will be expanded +# on first boot to occupy the renaming free blocks on the physical storage. +MENDER_DATA_PART_SIZE_MB="128" + +# Alignment of partitions used when building partitioned images, expressed in +# bytes +# +# Default is 8MB +MENDER_PARTITION_ALIGNMENT="8388608" + +# Mender client version +# +# This is used to fetch the correct binaries +MENDER_CLIENT_VERSION="2.0.1" + +# File storage, containing binary files, do not modify this unless you know +# what you are doing. +MENDER_STORAGE_URL="https://d1b0l86ne08fsf.cloudfront.net" + +# Mender GitHub organization URL prefix +MENDER_GITHUB_ORG="https://github.com/mendersoftware" + +# Device file corresponding to the root filesystem partitions, without index. +MENDER_STORAGE_DEVICE=/dev/mmcblk0p + +# Partition index of boot partition +MENDER_BOOT_PART_INDEX="1" + +# Partition index of root filesystem A +MENDER_ROOTFS_PART_A_INDEX="2" + +# Partition index of root filesystem B +MENDER_ROOTFS_PART_B_INDEX="3" + +# Partition index of persistent data partition +MENDER_DATA_PART_INDEX="4" + +# Basename of DTB that should be loaded by the bootloader. +MENDER_KERNEL_DEVICETREE=kernel.dtb + +# Generate bmap index files +# +# https://github.com/intel/bmap-tools +MENDER_USE_BMAP="n" + +source configs/mender_grub_config + +# Function to create Mender Artifact +# +# This function is defined here, to allow it to be overridden which can be +# achieved by providing this function in a custom configuration file which will +# take precedence of this one. +# +# You might want to override this to e.g provide state-scripts or providing +# a private key to sign your artifact. +mender_create_artifact() { + local -r device_type="${1}" + local -r artifact_name="${2}" + + mender_artifact=deploy/${device_type}-${artifact_name}.mender + log_info "Writing Mender artifact to: ${mender_artifact}" + log_info "This can take up to 20 minutes depending on which compression method is used" + + run_and_log_cmd "mender-artifact --compression ${MENDER_ARTIFACT_COMPRESSION} \ + write rootfs-image \ + --file work/rootfs.img \ + --output-path ${mender_artifact} \ + --artifact-name ${artifact_name} \ + --device-type ${device_type}" +} diff --git a/configs/mender_grub_config b/configs/mender_grub_config new file mode 100644 index 0000000..30efd47 --- /dev/null +++ b/configs/mender_grub_config @@ -0,0 +1,35 @@ +# Use U-boot -> GRUB -> EFI boot-loader integration +# +# Only disable this if you know what you are doing +MENDER_GRUB_EFI_INTEGRATION=y + +# Specific Linux kernel boot arguments +# +# Typically you would read the content of /proc/cmdline on a "golden image" +# add the appropriate arguments here. +# +# This will override the defaults set by by grub-mender-grubenv, if not an +# empty string +MENDER_GRUB_KERNEL_BOOT_ARGS="" + +# grub-mender-grubenv is the Mender integration for the GRUB bootloader +MENDER_GRUBENV_VERSION="1.3.0" +MENDER_GRUBENV_URL="${MENDER_GITHUB_ORG}/grub-mender-grubenv/archive/${MENDER_GRUBENV_VERSION}.tar.gz" + +# Name of the storage device containing root filesystem partitions in GRUB +# format. +MENDER_GRUB_STORAGE_DEVICE=hd0 + +# Type of kernel (bzImage or zImage) +# +# mender-convert will try to determinate this value on its own, only set this +# if was not possible to auto-detect +MENDER_GRUB_KERNEL_IMAGETYPE="" + +# Type of initrd image +# +# mender-convert will try to determinate this value on its own, only set this +# if was not possible to auto-detect +MENDER_GRUB_INITRD_IMAGETYPE="" + +MENDER_GRUB_BINARY_STORAGE_URL="${MENDER_STORAGE_URL}/mender-convert/grub-efi" diff --git a/configs/qemux86-64_config b/configs/qemux86-64_config new file mode 100644 index 0000000..aa46612 --- /dev/null +++ b/configs/qemux86-64_config @@ -0,0 +1,16 @@ +# This configuration can be used to run on a qemux86-64 machine. +# +# This has been tested on images generated with the following command: +# +# mkosi -d ubuntu -r bionic -t gpt_ext4 -b --checksum --password password -o image.raw +# +# Converted with the following command: +# +# MENDER_ARTIFACT_NAME=release-1 ./mender-convert --disk-image input/image.raw --overlay rootfs_overlay_demo --config configs/qemux86-64_config +# +# and qemu is executed with the following command: +# +# qemu-system-x86_64 -enable-kvm -m 512 -smp 2 -bios /usr/share/ovmf/x64/OVMF_CODE.fd -drive format=raw,file=qemux86_64-release-1.sdimg + +MENDER_STORAGE_DEVICE=/dev/sda +MENDER_DEVICE_TYPE="qemux86_64" diff --git a/configs/raspberrypi3_config b/configs/raspberrypi3_config new file mode 100644 index 0000000..6315fd7 --- /dev/null +++ b/configs/raspberrypi3_config @@ -0,0 +1,8 @@ +# Binaries generated with the following script: +# +# https://d1b0l86ne08fsf.cloudfront.net/mender-convert/raspberrypi/raspberrypi-integration-scripts.tar.gz +RASPBERRYPI_BINARIES="raspberrypi3-integration-2018.07.tar.gz" +RASPBERRYPI_KERNEL_IMAGE="kernel7.img" +MENDER_KERNEL_IMAGETYPE=zImage + +source configs/raspberrypi_config diff --git a/configs/raspberrypi_config b/configs/raspberrypi_config new file mode 100644 index 0000000..f65ed2b --- /dev/null +++ b/configs/raspberrypi_config @@ -0,0 +1,82 @@ +# Raspberry Pi does not support GRUB bootloader integration, fallback to U-boot. +MENDER_GRUB_EFI_INTEGRATION=n + +# 4MB alignment +MENDER_PARTITION_ALIGNMENT="4194304" + +RASPBERRYPI_BINARIES_URL="${MENDER_STORAGE_URL}/mender-convert/raspberrypi/${RASPBERRYPI_BINARIES}" + +function platform_modify() { + mkdir -p work/rpi/binaries + + run_and_log_cmd "wget -q ${RASPBERRYPI_BINARIES_URL} -P work/rpi/binaries" + run_and_log_cmd "tar xvf work/rpi/binaries/${RASPBERRYPI_BINARIES} -C work/rpi/binaries" + + # Make a copy of Linux kernel arguments and modify. + run_and_log_cmd "cp work/boot/cmdline.txt work/rpi/cmdline.txt" + + # Set a dynamic rootfs part (required for Mender A/B update strategy) + run_and_log_cmd "sed -i 's/\b[ ]root=[^ ]*/ root=\${mender_kernel_root}/' work/rpi/cmdline.txt" + + # Root filesystem can not be resized when the disk is partition according + # to Mender layout, where the rootfs partition is the not last one which + # is a requirement to be able to do an "online" resize. + # + # This disables resize of rootfs on boot but applies the changes to + # cmdline.txt that are performed in the init_resize.sh script. + # + # Extracted from /usr/lib/raspi-config/init_resize.sh + run_and_log_cmd "sed -i 's| init=/usr/lib/raspi-config/init_resize\.sh||' work/rpi/cmdline.txt" + run_and_log_cmd "sed -i 's| sdhci\.debug_quirks2=4||' work/rpi/cmdline.txt" + if ! grep -q splash work/rpi/cmdline.txt; then + run_and_log_cmd "sed -i 's/ quiet//g' work/rpi/cmdline.txt" + fi + + # Update Linux kernel command arguments with our custom configuration + run_and_log_cmd "sudo cp work/rpi/cmdline.txt work/boot/" + + # Enable Full KMS (Kernel Mode Setting) graphics driver. This is the + # the open-source GPU driver that is part of mesa, also known as VC4. + # + # This is done because it seems that the firmware GPU driver does currently + # not play well when U-boot is enabled and HDMI output is "scrambled" + # + # Fixes: https://tracker.mender.io/browse/MEN-2685 + # + # Will need to revisit this later when there are new firware releases. + # + # Should be noted that RPi4 only works with this enabled and the + # configuration in the Yocto BSP (meta-raspberrypi) is also nowdays using + # this driver by default. + run_and_log_cmd "echo 'dtoverlay=vc4-kms-v3d' | sudo tee -a work/boot/config.txt" + + # Mask udisks2.service, otherwise it will mount the inactive part and we + # might write an update while it is mounted which often result in + # corruptions. + # + # TODO: Find a way to only blacklist mmcblk0pX devices instead of masking + # the service. + run_and_log_cmd "sudo ln -sf /dev/null work/rootfs/etc/systemd/system/udisks2.service" + + # Extract Linux kernel and install to /boot directory on rootfs + run_and_log_cmd "sudo cp work/boot/${RASPBERRYPI_KERNEL_IMAGE} work/rootfs/boot/${MENDER_KERNEL_IMAGETYPE}" + + # Replace kernel with U-boot and add boot script + run_and_log_cmd "sudo mkdir -p work/rootfs/uboot" + run_and_log_cmd "sudo cp work/rpi/binaries/u-boot.bin work/boot/${RASPBERRYPI_KERNEL_IMAGE}" + run_and_log_cmd "sudo cp work/rpi/binaries/boot.scr work/boot" + run_and_log_cmd "sudo cp work/rpi/binaries/fw_env.config work/rootfs/etc/" + + # Raspberry Pi applications expect to find this on the device and in some + # cases parse the options to determinate functionality. + run_and_log_cmd "sudo ln -fs /uboot/config.txt work/rootfs/boot/config.txt" + run_and_log_cmd "sudo ln -fs /uboot/overlays work/rootfs/boot/overlays" + run_and_log_cmd "sudo ln -fs /uboot/cmdline.txt work/rootfs/boot/cmdline.txt" + + run_and_log_cmd "sudo install -m 755 work/rpi/binaries/fw_printenv work/rootfs/sbin/fw_printenv" + run_and_log_cmd "sudo ln -fs /sbin/fw_printenv work/rootfs/sbin/fw_setenv" + + # Remove original 'resize2fs_once' script and its symbolic link. + run_and_log_cmd "sudo unlink work/rootfs/etc/rc3.d/S01resize2fs_once" + run_and_log_cmd "sudo rm work/rootfs/etc/init.d/resize2fs_once" +} diff --git a/configs/rockpro64_config b/configs/rockpro64_config new file mode 100644 index 0000000..9e9e631 --- /dev/null +++ b/configs/rockpro64_config @@ -0,0 +1,25 @@ +# ROCKPro64 do not support GRUB bootloader integration, fallback to U-boot. +MENDER_GRUB_EFI_INTEGRATION=n + +ROCKPRO64_BINARIES_URL="${MENDER_STORAGE_URL}/mender-convert/armbian/rockpro64/${ROCKPRO64_BINARIES}" + +function platform_modify() { + mkdir -p work/rockpro64 + + run_and_log_cmd "wget -Nq ${ROCKPRO64_BINARIES_URL} -P work/rockpro64" + run_and_log_cmd "tar xvf work/rockpro64/${ROCKPRO64_BINARIES} -C work/rockpro64" + + run_and_log_cmd "sudo cp work/rockpro64/boot.scr work/boot" + + run_and_log_cmd "sudo cp work/rockpro64/fw_env.config work/rootfs/etc/" + + # It is not possible to resize rootfs part when using Mender. so disable + # the service + run_and_log_cmd "sudo touch work/rootfs/root/.no_rootfs_resize" +} + +function platform_package() { + log_info "Embedding bootloader in disk image" + run_and_log_cmd "dd if=work/rockpro64/rksd_loader.img of=${sdimg_path} \ + seek=64 conv=notrunc status=none" +} diff --git a/configs/rockpro64_emmc_config b/configs/rockpro64_emmc_config new file mode 100644 index 0000000..3ae58f2 --- /dev/null +++ b/configs/rockpro64_emmc_config @@ -0,0 +1,8 @@ +MENDER_STORAGE_DEVICE=/dev/mmcblk1p + +# Binaries generated with the following script: +# +# https://d1b0l86ne08fsf.cloudfront.net/mender-convert/armbian/rockpro64/integration-scripts.tar.gz +ROCKPRO64_BINARIES="emmc-boot-integration-2017.09.tar.gz" + +source configs/rockpro64_config diff --git a/configs/rockpro64_sd_config b/configs/rockpro64_sd_config new file mode 100644 index 0000000..514f8c3 --- /dev/null +++ b/configs/rockpro64_sd_config @@ -0,0 +1,6 @@ +# Binaries generated with the following script: +# +# https://d1b0l86ne08fsf.cloudfront.net/mender-convert/armbian/rockpro64/integration-scripts.tar.gz +ROCKPRO64_BINARIES="sd-boot-integration-2017.09.tar.gz" + +source configs/rockpro64_config diff --git a/docker-build b/docker-build new file mode 100755 index 0000000..d758b0f --- /dev/null +++ b/docker-build @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +IMAGE_NAME=mender-convert + +eval docker build . -t ${IMAGE_NAME} diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 0000000..bfc703d --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +# run conversion, args provided to container (end of docker run ...) + +cd /mender-convert + +echo "Running mender-convert "$@"" + +./mender-convert "$@" diff --git a/docker-mender-convert b/docker-mender-convert new file mode 100755 index 0000000..ab9c36f --- /dev/null +++ b/docker-mender-convert @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +IMAGE_NAME=mender-convert + +MENDER_CONVERT_DIR="$(pwd)" +mkdir -p output + +docker run \ + --mount type=bind,source="$MENDER_CONVERT_DIR,target=/mender-convert" \ + --privileged=true \ + --cap-add=SYS_MODULE \ + -v /dev:/dev \ + -v /lib/modules:/lib/modules:ro \ + --env MENDER_ARTIFACT_NAME=${MENDER_ARTIFACT_NAME} \ + $IMAGE_NAME "$@" diff --git a/mender-convert b/mender-convert new file mode 100755 index 0000000..70f32a3 --- /dev/null +++ b/mender-convert @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +MENDER_CONVERT_VERSION=$(git describe --tags --dirty --exact-match 2>/dev/null || git rev-parse --short HEAD) + +function show_help() { + cat << EOF +mender-convert + +A tool that takes an existing embedded image (Debian, Ubuntu, Raspbian, etc) +and converts it to a Mender image by restructuring partition table and adding +necessary files. + +Usage: $0 COMMAND [options] + +Options: + -d, --disk-image - Path to disk image to convert (Debian, Raspbian, + Ubuntu, etc) + -o, --overlay - Path to root filesystem overlay directory, you + are able to provide this option multiple times + -c, --config - Path to configuration file, you are able to + provide this option multiple times + -v, --version - output version information and exit + -h, --help - display this help and exit + +EOF +} + +function show_version() { + echo "Version: ${MENDER_CONVERT_VERSION}" +} + +function trap_exit() { + sudo rm -rf work +} + +function trap_term() { + echo "Program interrupted by user" +} + +trap trap_term INT TERM +trap trap_exit EXIT + +mender_convert_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +if [ "${mender_convert_dir}" != "${PWD}" ]; then + echo "You must execute mender-convert from the root directory: ${mender_convert_dir}" + exit 1 +fi + +if [ -z "${MENDER_ARTIFACT_NAME}" ]; then + echo "Sorry, it seems that you have not defined MENDER_ARTIFACT_NAME" + echo "You can do this with the following command:" + echo "" + echo -e "\tMENDER_ARTIFACT_NAME="release-1" ./mender-convert" + exit 1 +fi + +source modules/bootstrap.sh + +# We only handle a selection of the arguments here, the rest are passed on +# to the sub-scripts. +while (( "$#" )); do + case "$1" in + -h | --help) + show_help + exit 0 + ;; + -v | --version) + show_version + exit 0 + ;; + *) + break; + ;; + esac +done + +mkdir -p work +touch work/convert.log + +./mender-convert-extract "$@" +./mender-convert-modify "$@" +./mender-convert-package "$@" + +echo "Output Artifacts and images can be found in deploy directory:" +ls -1 deploy/* diff --git a/mender-convert-extract b/mender-convert-extract new file mode 100755 index 0000000..708d745 --- /dev/null +++ b/mender-convert-extract @@ -0,0 +1,99 @@ +#!/bin/bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +echo "Running $(basename $0): $@" + +source modules/bootstrap.sh +source modules/disk.sh + +disk_image="" +while (( "$#" )); do + case "$1" in + -o | --overlay) + overlays+="${2}" + shift 2 + ;; + -c | --config) + configs+="${2}" + shift 2 + ;; + -d | --disk-image) + disk_image="${2}" + shift 2 + ;; + *) + log_fatal "Sorry but the provided option is not supported: $1" + ;; + esac +done + +if [ -z "${disk_image}" ]; then + log_warn "Sorry, but '--disk-image' is a mandatory option" + log_warn "See ./mender-convert --help for more information" + exit 1 +fi + +if [ ! -e ${disk_image} ]; then + log_fatal "File not found: ${disk_image}" +fi + +source modules/config.sh "${configs[@]}" + +MKFS_VFAT="/usr/bin/mkfs.vfat" +if [ ! -f ${MKFS_VFAT} ]; then + MKFS_VFAT="/sbin/mkfs.vfat" +fi + +declare -i nr_of_parts=$(disk_get_nr_of_parts ${disk_image}) + +log_info "Validating disk image" + +if [ ${nr_of_parts} -eq 0 ]; then + log_fatal "Sorry, but could not find any valid partitions for: ${disk_image}" +fi + +log_info "Disk parsed succesfully" +log_info "NUMBER OF PARTS: ${nr_of_parts} TYPE: $(disk_get_part_value ${disk_image} 1 SCHEME)" + +for ((n=1;n<=${nr_of_parts};n++)); do + part_dst_file="work/part-${n}.fs" + + if [ "$(disk_get_part_value ${disk_image} ${n} TYPE)" == "0x8e" ]; then + log_fatal "Detected an LVM volume group on disk. Unfortunatly this is not yet supported" + fi + + log_info "PART ${n}: SIZE: $(disk_get_part_value ${disk_image} ${n} SIZE) TYPE: $(disk_get_part_value ${disk_image} ${n} TYPE)" + log_info "PART ${n}: extracting to ${part_dst_file}" + + disk_extract_part "${disk_image}" $(disk_get_part_value ${disk_image} ${n} START) \ + $(disk_get_part_value ${disk_image} ${n} SECTORS) ${part_dst_file} +done + +# Some disk images will not have an boot partition for us to extract, +# but we do require it be present and hence we might need to generate +# a filesystem image here. +if [ ${nr_of_parts} -eq 1 ]; then + log_info "Generating boot partition (required, does not exist in original image)" + run_and_log_cmd "dd if=/dev/zero of=work/boot-generated.vfat count=${MENDER_BOOT_PART_SIZE_MB} bs=1M status=none" + run_and_log_cmd "${MKFS_VFAT} work/boot-generated.vfat" +fi + +# Extract boot gap, that is the area from sector 1 until first part, and +# this is done because some images might contain the bootloader embedded here +# and we might need to keep this area intact when we generate our custom +# image. +disk_extract_part "${disk_image}" \ + 1 $(( $(disk_get_part_value ${disk_image} 1 START) - 1)) work/boot-gap.bin diff --git a/mender-convert-modify b/mender-convert-modify new file mode 100755 index 0000000..0ca16e7 --- /dev/null +++ b/mender-convert-modify @@ -0,0 +1,215 @@ +#!/bin/bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Default that can be overridden by providing this method in a +# configuration file passed with '--config' +function platform_modify() { + true +} + +function trap_exit() { + echo "mender-convert-modify has finished. Cleaning..." + sudo umount -f work/boot + sudo umount -f work/rootfs +} + +function trap_term() { + true +} + +trap trap_term INT TERM +trap trap_exit EXIT + +echo "Running $(basename $0): $@" + +source modules/bootstrap.sh +source modules/disk.sh +source modules/probe.sh + +while (( "$#" )); do + case "$1" in + -o | --overlay) + overlays+="${2}" + shift 2 + ;; + -c | --config) + configs+="${2}" + shift 2 + ;; + -d | --disk-image) + disk_image="${2}" + shift 2 + ;; + *) + log_fatal "Sorry, but the provided option is not supported: $1" + ;; + esac +done + +source modules/config.sh "${configs[@]}" + +boot_part=$(disk_boot_part) +root_part=$(disk_root_part) + +# Create mount points +mkdir -p work/boot +mkdir -p work/rootfs + +sudo mount ${boot_part} work/boot +sudo mount ${root_part} work/rootfs + +mkdir -p work/mender-deb/files + +log_info "Installing Mender client and related files" + +deb_arch=$(probe_debian_arch_name) +deb_name="mender-client_${MENDER_CLIENT_VERSION}-1_${deb_arch}.deb" +run_and_log_cmd "wget -Nq ${MENDER_STORAGE_URL}/mender-convert/deb/${deb_name} -P work/mender-deb" + +cd work/mender-deb +run_and_log_cmd "ar -xv ${deb_name}" +run_and_log_cmd "tar -xf data.tar.xz -C files" +cd - > /dev/null 2>&1 + +run_and_log_cmd "sudo rsync --archive --keep-dirlinks --verbose work/mender-deb/files/ work/rootfs/" + +if [ "${MENDER_ENABLE_SYSTEMD}" == "y" ]; then + run_and_log_cmd "sudo ln -sf /lib/systemd/system/mender.service \ + work/rootfs/etc/systemd/system/multi-user.target.wants/mender.service" +fi + +if [ "${MENDER_GRUB_EFI_INTEGRATION}" == "y" ]; then + run_and_log_cmd "wget -Nq '${MENDER_GRUBENV_URL}' -P work/" + run_and_log_cmd "tar xvf work/${MENDER_GRUBENV_VERSION}.tar.gz -C work/" + + if [ -z "${MENDER_GRUB_KERNEL_IMAGETYPE}" ]; then + kernel_imagetype=$(probe_kernel_in_boot_and_root) + else + kernel_imagetype="${MENDER_GRUB_KERNEL_IMAGETYPE}" + fi + + if [ -z "${MENDER_GRUB_INITRD_IMAGETYPE}" ]; then + initrd_imagetype=$(probe_initrd_in_boot_and_root) + else + kernel_imagetype="${MENDER_GRUB_INITRD_IMAGETYPE}" + fi + + cat <<- EOF > work/grub-mender-grubenv-${MENDER_GRUBENV_VERSION}/mender_grubenv_defines +mender_rootfsa_part=${MENDER_ROOTFS_PART_A_INDEX} +mender_rootfsb_part=${MENDER_ROOTFS_PART_B_INDEX} +mender_kernel_root_base=${MENDER_STORAGE_DEVICE} +mender_grub_storage_device=${MENDER_GRUB_STORAGE_DEVICE} +kernel_imagetype=${kernel_imagetype} +initrd_imagetype=${initrd_imagetype} +kernel_devicetree=${MENDER_KERNEL_DEVICETREE} +EOF + + if [ -n "${MENDER_GRUB_KERNEL_BOOT_ARGS}" ]; then + cat <<- EOF > work/grub-mender-grubenv-${MENDER_GRUBENV_VERSION}/11_bootargs_grub.cfg +set bootargs="${MENDER_GRUB_KERNEL_BOOT_ARGS}" +EOF + fi + + cd work/grub-mender-grubenv-${MENDER_GRUBENV_VERSION} + run_and_log_cmd "make 2>&1" + run_and_log_cmd "sudo make DESTDIR=../ BOOT_DIR=boot install-boot-files" + run_and_log_cmd "sudo make DESTDIR=../rootfs install-tools" + cd - > /dev/null 2>&1 + + # Remove conflicting boot files. These files do not necessarily effect the + # functionality, but lets get rid of them to avoid confusion. + # + # There is no Mender integration for EFI boot or systemd-boot. + sudo rm -rf work/boot/loader + sudo rm -rf work/boot/EFI/Linux + sudo rm -rf work/boot/EFI/systemd + sudo rm -rf work/boot/NvVars + + log_info "Installing GRUB" + + arch=$(probe_arch) + efi_name=$(probe_grub_efi_name) + efi_target_name=$(probe_grub_efi_target_name) + + log_info "GRUB EFI: ${efi_target_name}" + + run_and_log_cmd "wget -Nq ${MENDER_GRUB_BINARY_STORAGE_URL}/${arch}/${efi_name} -P work/" + run_and_log_cmd "wget -Nq ${MENDER_GRUB_BINARY_STORAGE_URL}/${arch}/grub-editenv -P work/" + + run_and_log_cmd "sudo install -m 751 work/grub-editenv work/rootfs/usr/bin/" + + run_and_log_cmd "sudo mkdir -p work/boot/EFI/BOOT" + run_and_log_cmd "sudo cp work/${efi_name} -P work/boot/EFI/BOOT/${efi_target_name}" +fi + +run_and_log_cmd "sudo mkdir -p work/rootfs/data/mender" +run_and_log_cmd "sudo ln -sf /data/mender work/rootfs/var/lib/mender" + +cat <<- EOF > work/mender.conf.data +{ + "RootfsPartA": "${MENDER_STORAGE_DEVICE}${MENDER_ROOTFS_PART_A_INDEX}", + "RootfsPartB": "${MENDER_STORAGE_DEVICE}${MENDER_ROOTFS_PART_B_INDEX}" +} +EOF + +run_and_log_cmd "sudo cp work/mender.conf.data work/rootfs/data/mender/mender.conf" + +if [ -z "${MENDER_DEVICE_TYPE}" ]; then + # Observed systems who do not have this file, e.g images generated with mkosi + if [ -f work/rootfs/etc/hostname ]; then + device_type=$(cat work/rootfs/etc/hostname) + else + device_type="default" + fi +else + device_type="${MENDER_DEVICE_TYPE}" +fi + +run_and_log_cmd "echo 'device_type=${device_type}' > work/device_type" +run_and_log_cmd "sudo install -m 0444 work/device_type work/rootfs/data/mender/" +run_and_log_cmd "sudo echo 'artifact_name=${MENDER_ARTIFACT_NAME}' \ + > work/rootfs/etc/mender/artifact_info" + +log_info "Installing a custom /etc/fstab (see work/convert.log for more info)" + +if [ "${MENDER_GRUB_EFI_INTEGRATION}" == "y" ]; then + boot_part_mountpoint="/boot/efi" +else + boot_part_mountpoint="/uboot" +fi + +run_and_log_cmd "sudo mkdir -p work/rootfs/${boot_part_mountpoint}" + +if [ "${MENDER_DATA_PART_GROWFS}" == "y" ]; then + MENDER_DATA_PART_FSTAB_OPTS="${MENDER_DATA_PART_FSTAB_OPTS},x-systemd.growfs" +fi + +sudo bash -c "cat <<- EOF > work/rootfs/etc/fstab +# stock fstab - you probably want to override this with a machine specific one +/dev/root / auto defaults 1 1 +proc /proc proc defaults 0 0 + +${MENDER_STORAGE_DEVICE}${MENDER_BOOT_PART_INDEX} ${boot_part_mountpoint} auto defaults,sync 0 0 +${MENDER_STORAGE_DEVICE}${MENDER_DATA_PART_INDEX} /data auto ${MENDER_DATA_PART_FSTAB_OPTS} 0 0 +EOF" + +log_info "Performing platform specific modifications (if any)" +platform_modify + +for overlay in "${overlays[@]}"; do + log_info "Applying rootfs overlay: ${overlay}" + run_and_log_cmd "sudo rsync --archive --keep-dirlinks --verbose ${overlay}/ work/rootfs/" +done diff --git a/mender-convert-package b/mender-convert-package new file mode 100755 index 0000000..f8e968e --- /dev/null +++ b/mender-convert-package @@ -0,0 +1,259 @@ +#!/bin/bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Default that can be overridden by providing this method in a +# configuration file passed with '--config' +function platform_package() { + true +} + +function trap_exit() { + echo "mender-convert-package has finished. Cleaning..." + sudo umount -f work/boot > /dev/null + sudo umount -f work/rootfs > /dev/null +} + +function trap_term() { + true +} + +trap trap_term INT TERM +trap trap_exit EXIT + +echo "Running $(basename $0): $@" + +source modules/bootstrap.sh +source modules/disk.sh + +while (( "$#" )); do + case "$1" in + -o | --overlay) + overlays+="${2}" + shift 2 + ;; + -c | --config) + configs+="${2}" + shift 2 + ;; + -d | --disk-image) + disk_image="${2}" + shift 2 + ;; + *) + log_fatal "Sorry but the provided option is not supported: $1" + ;; + esac +done + +source modules/config.sh "${configs[@]}" + +PARTED="/usr/bin/parted" +if [ ! -f ${PARTED} ]; then + PARTED="/sbin/parted" +fi + +output_dir=work + +boot_part=$(disk_boot_part) +root_part=$(disk_root_part) + +# Final output +mkdir -p deploy + +# Create mount points +mkdir -p work/boot +mkdir -p work/rootfs + +sudo mount ${boot_part} work/boot +sudo mount ${root_part} work/rootfs + +# Convert to 512 blocks +disk_image_total_sectors=$(disk_mb_to_sectors ${MENDER_STORAGE_TOTAL_SIZE_MB}) +boot_part_sectors=$(disk_mb_to_sectors ${MENDER_BOOT_PART_SIZE_MB}) +data_part_sectors=$(disk_mb_to_sectors ${MENDER_DATA_PART_SIZE_MB}) +alignment_sectors=$((${MENDER_PARTITION_ALIGNMENT} / 512)) + +if [ "${MENDER_GRUB_EFI_INTEGRATION}" == "y" ]; then + boot_part_start=${alignment_sectors} + overhead_sectors=$(( ${alignment_sectors} * 4 )) +else + # The two first blocks are typically reserved for U-boot environment. + boot_part_start=$(( ${alignment_sectors} * 3)) + overhead_sectors=$(( ${alignment_sectors} * 6 )) +fi + +# Validate boot part size +actual_boot_size=$(du --apparent-size -s --block-size=512 ${boot_part} | cut -f 1) +if [ ${actual_boot_size} -gt ${boot_part_sectors} ]; then + log_warn "The allocated boot part size $(disk_sectors_to_mb ${boot_part_sectors}) MiB is too small." + log_warn "The actual boot part size is $(disk_sectors_to_mb ${actual_boot_size}) MiB" + log_warn "Will adjust MENDER_BOOT_PART_SIZE_MB automatically" + log_warn "Considered adjusting the configuration file to avoid this message" + boot_part_sectors=${actual_boot_size} +fi + +# Make sure that the boot part sector size is aligned to +# MENDER_PARTITION_ALIGNMENT, it is possible that the boot part is extracted +# as-is from the input image, and the input image might not have used the same +# alignment as our configuration +boot_part_sectors=$(disk_align_sectors ${boot_part_sectors} ${MENDER_PARTITION_ALIGNMENT} ) + +# Calculate rootfs size +rootfs_part_sectors=$(( (${disk_image_total_sectors} - ${data_part_sectors} \ + - ${boot_part_sectors} - ${overhead_sectors}) / 2 )) + +# Make sure rootfs size is aligned to MENDER_PARTITION_ALIGNMENT +rootfs_part_sectors=$(disk_align_sectors ${rootfs_part_sectors} ${MENDER_PARTITION_ALIGNMENT} ) + +device_type=$(cat work/rootfs/data/mender/device_type | sed 's/[^=]*=//') +artifact_name=$(cat work/rootfs/etc/mender/artifact_info | sed 's/[^=]*=//') + +image_name="${device_type}-${artifact_name}" + +actual_rootfs_size=$(sudo du --apparent-size -s --block-size=512 work/rootfs | cut -f 1) + +# 50 % free space, not to be confused with rootfs_part_sectors +rootfs_image_sectors=$(awk -v r1="$actual_rootfs_size" 'BEGIN{printf "%.0f", r1 * 1.50}') + +if [ ${rootfs_image_sectors} -gt ${rootfs_part_sectors} ]; then + log_warn "The calculated rootfs partition size $(disk_sectors_to_mb ${rootfs_part_sectors}) MiB is too small." + log_warn "The actual rootfs image size is $(disk_sectors_to_mb ${rootfs_image_sectors}) MiB" + log_fatal "You can try adjusting the MENDER_STORAGE_TOTAL_SIZE_MB variable to increase available space" +fi + +# Extract file-system type from rootfs +if file ${root_part} | grep -q ext4; then + image_fs_type="ext4" +elif file ${root_part} | grep -q XFS; then + image_fs_type="xfs" +else + log_warn "$(file work/${root_part})" + log_fatal "Could not determinate root file-system type. Aborting..." +fi + +disk_create_file_system_from_folder "work/rootfs/data/" "work/data.img" \ + "${data_part_sectors}" "${image_fs_type}" + +# Clear this area as it will be contained in the data.img +sudo rm -rf work/rootfs/data/* + +disk_create_file_system_from_folder "work/rootfs/" "work/rootfs.img" \ + "${rootfs_image_sectors}" "${image_fs_type}" + +log_info "Copying root filesystem image to deploy directory" +run_and_log_cmd "cp --sparse=always work/rootfs.img deploy/${image_name}.${image_fs_type}" + +mender_create_artifact "${device_type}" "${artifact_name}" + +log_info "Creating Mender compatible disk-image" + +sdimg_path=deploy/${image_name}.sdimg + +log_info "Total disk size: $(disk_sectors_to_mb ${disk_image_total_sectors}) MiB" +log_info " Boot partition $(disk_sectors_to_mb ${boot_part_sectors}) MiB" +log_info " RootFS $(disk_sectors_to_mb ${rootfs_part_sectors}) x 2 MiB" +log_info " Data $(disk_sectors_to_mb ${data_part_sectors}) MiB" + +# Initialize sdcard image file +run_and_log_cmd \ + "dd if=/dev/zero of=${sdimg_path} bs=512 count=0 seek=${disk_image_total_sectors} status=none" + +# boot_part_start, is defined at the beginning of this file +boot_part_end=$(( ${boot_part_start} + ${boot_part_sectors} - 1 )) + +rootfsa_start=$(disk_align_sectors ${boot_part_end} ${MENDER_PARTITION_ALIGNMENT} ) +rootfsa_end=$(( ${rootfsa_start} + ${rootfs_part_sectors} - 1 )) + +rootfsb_start=$(disk_align_sectors ${rootfsa_end} ${MENDER_PARTITION_ALIGNMENT} ) +rootfsb_end=$(( ${rootfsb_start} + ${rootfs_part_sectors} - 1 )) + +data_start=$(disk_align_sectors ${rootfsb_end} ${MENDER_PARTITION_ALIGNMENT} ) +data_end=$(( ${data_start} + ${data_part_sectors} - 1 )) + +# Create partition table. TODO: GPT support +run_and_log_cmd "${PARTED} -s ${sdimg_path} mklabel msdos" +run_and_log_cmd "${PARTED} -s ${sdimg_path} unit s mkpart primary fat32 ${boot_part_start} ${boot_part_end}" +run_and_log_cmd "${PARTED} -s ${sdimg_path} set 1 boot on" +run_and_log_cmd "${PARTED} -s ${sdimg_path} -- unit s mkpart primary ext2 ${rootfsa_start} ${rootfsa_end}" +run_and_log_cmd "${PARTED} -s ${sdimg_path} -- unit s mkpart primary ext2 ${rootfsb_start} ${rootfsb_end}" +run_and_log_cmd "${PARTED} -s ${sdimg_path} -- unit s mkpart primary ext2 ${data_start} ${data_end}" +run_and_log_cmd "${PARTED} -s ${sdimg_path} print" + +# Burn Partitions +disk_write_at_offset "${boot_part}" "${sdimg_path}" "${boot_part_start}" +disk_write_at_offset "${output_dir}/rootfs.img" "${sdimg_path}" "${rootfsa_start}" +disk_write_at_offset "${output_dir}/rootfs.img" "${sdimg_path}" "${rootfsb_start}" +disk_write_at_offset "${output_dir}/data.img" "${sdimg_path}" "${data_start}" + +log_info "Performing platform specific package operations (if any)" +platform_package + +# Create bmap index +if [ "${MENDER_USE_BMAP}" == "y" ]; then + BMAP_TOOL="/usr/bin/bmaptool" + if [ ! -e "${BMAP_TOOL}" ]; then + log_error "You have enabled the MENDER_USE_BMAP option, but we could not find the required 'bmaptool'" + log_fatal "You can install 'bmaptool' with: apt-get install bmap-tools (on Debian based distributions)" + fi + run_and_log_cmd "${BMAP_TOOL} create ${sdimg_path} > ${sdimg_path}.bmap" +fi + +if [ "${MENDER_COMPRESS_DISK_IMAGE}" == "y" ]; then + log_info "Compressing ${sdimg_path}.gz" + run_and_log_cmd "pigz --best --force ${sdimg_path}" +fi + +log_info "Conversion has completed! \o/" + +##################### Create configuration file for tests ###################### + +if [ "${MENDER_GRUB_EFI_INTEGRATION}" == "y" ]; then + boot_part_mountpoint="/boot/efi" + + # This is the name of the DISTRO_FEATURES in Yocto + distro_feature="mender-grub" +else + boot_part_mountpoint="/uboot" + + # This is the name of the DISTRO_FEATURES in Yocto + distro_feature="mender-uboot" +fi + +cat <<- EOF > deploy/${image_name}.cfg +MENDER_BOOT_PART="${MENDER_STORAGE_DEVICE}${MENDER_BOOT_PART_INDEX}" +MENDER_ROOTFS_PART_A="${MENDER_STORAGE_DEVICE}${MENDER_ROOTFS_PART_A_INDEX}" +MENDER_ROOTFS_PART_B="${MENDER_STORAGE_DEVICE}${MENDER_ROOTFS_PART_B_INDEX}" +MENDER_BOOT_PART_MOUNT_LOCATION="${boot_part_mountpoint}" +MENDER_BOOT_PART_SIZE_MB="$(disk_sectors_to_mb ${boot_part_sectors})" +MENDER_DATA_PART_SIZE_MB="${MENDER_DATA_PART_SIZE_MB}" +MENDER_DEVICE_TYPE="${device_type}" +MENDER_PARTITIONING_OVERHEAD_KB="$(( (${overhead_sectors} * 512) / 1024 ))" +MENDER_PARTITION_ALIGNMENT="${MENDER_PARTITION_ALIGNMENT}" +MENDER_STORAGE_DEVICE="${MENDER_STORAGE_DEVICE}" +MENDER_STORAGE_TOTAL_SIZE_MB="${MENDER_STORAGE_TOTAL_SIZE_MB}" +MENDER_UBOOT_ENV_STORAGE_DEVICE_OFFSET="12582912" +MENDER_ARTIFACT_NAME="${artifact_name}" +DISTRO_FEATURES="${distro_feature}" +DEPLOY_DIR_IMAGE="${PWD}/deploy" +MENDER_MACHINE="${device_type}" +EOF + +# Something that the tests expect to be defined (originally from Yocto) +cat <<- EOF >> deploy/${image_name}.cfg +IMAGE_FSTYPES="${image_fs_type} mender sdimg" +ARTIFACTIMG_FSTYPE="${image_fs_type}" +LAYER_CONF_VERSION="2" +EOF diff --git a/modules/bootstrap.sh b/modules/bootstrap.sh new file mode 100644 index 0000000..33644e6 --- /dev/null +++ b/modules/bootstrap.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Credit to: +# https://github.com/gruntwork-io/bash-commons/blob/master/modules/bash-commons/src/bootstrap.sh + +# Sets some Bash options to encourage well formed code. +# For example, some of the options here will cause the script to terminate as +# soon as a command fails. Another option will cause an error if an undefined +# variable is used. +# See: https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html + +# Any trap on ERR is inherited by shell functions, command substitutions, and +# commands executed in a subshell environment. The ERR trap is normally not +# inherited in such cases. +set -o errtrace + +# Any trap on DEBUG and RETURN are inherited by shell functions, command +# substitutions, and commands executed in a subshell environment. The DEBUG and +# RETURN traps are normally not inherited in such cases. +set -o functrace + +# Exit if any command exits with a non-zero exit status. +set -o errexit + +# Exit if script uses undefined variables. +set -o nounset + +# Prevent masking an error in a pipeline. +# Look at the end of the 'Use set -e' section for an excellent explanation. +# see: https://www.davidpashley.com/articles/writing-robust-shell-scripts/ +set -o pipefail + +# Make debugging easier when you use `set -x` +# See: http://wiki.bash-hackers.org/scripting/debuggingtips#making_xtrace_more_useful +export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' + +source modules/log.sh +source modules/run.sh diff --git a/modules/config.sh b/modules/config.sh new file mode 100644 index 0000000..82e6c5e --- /dev/null +++ b/modules/config.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +for config in configs/mender_convert_config "$@"; do + log_info "Using configuration file: ${config}" + source ${config} +done diff --git a/modules/disk.sh b/modules/disk.sh new file mode 100644 index 0000000..b29b97d --- /dev/null +++ b/modules/disk.sh @@ -0,0 +1,176 @@ +#!/usr/bin/env bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Print desired information about a partition +# +# Example usage: +# +# part_one_start=$(disk_get_part_value ${disk_image_path} 1 START) +# +# $1 - path to disk image +# $2 - part number +# $3 - information to be printed +# +# We use 'partx' to parse input disk image and it supports the following fields: +# +# NR partition number +# START start of the partition in sectors +# END end of the partition in sectors +# SECTORS number of sectors +# SIZE human readable size +# NAME partition name +# UUID partition UUID +# TYPE partition type (a string, a UUID, or hex) +# FLAGS partition flags +# SCHEME partition table type (dos, gpt, ...) +disk_get_part_value() { + echo "$(partx -o ${3} -g -r --nr ${2} ${1})" +} + +# Prints number of partitions found in disk image +# +# Example usage: +# +# nr_of_parts=$(disk_get_nr_of_parts ${disk_image_path}) +# +# $1 - path to disk image +disk_get_nr_of_parts() { + echo "$(partx -l ${1} | wc -l)" +} + +# Extract a file system image from a disk image +# +# $1 - path to disk image +# $2 - sector start (in 512 blocks) +# $3 - size (in 512 blocks) +# $4 - path to output file +disk_extract_part() { + run_and_log_cmd "dd if=$1 of=$4 skip=$2 bs=512 count=$3 conv=sparse status=none" +} + +# Convert MiB to number of 512 sectors +# +# $1 - MiB value +disk_mb_to_sectors() { + echo "$(( (${1} * 1024 * 1024) / 512 ))" +} + +# Convert 512 sectors to MiB +# +# $1 - number of 512 sectors +disk_sectors_to_mb() { + echo "$(( (${1} * 512) / 1024 / 1024 ))" +} + + +# Align value (result is number of 512 sectors) +# +# $1 - value to align (number of 512 sectors) +# $2 - alignment in bytes +disk_align_sectors() { + local size_in_bytes=$(( ${1} * 512)) + local reminder=$(( ${size_in_bytes} % ${2} )) + + if [ $reminder -ne 0 ]; then + size_in_bytes=$(( $size_in_bytes - $reminder + ${2} )) + fi + + echo "$(( $size_in_bytes / 512 ))" +} + +# Write file at offset of another file +# +# $1 - file to write +# $2 - destination file +# $3 - offset in number of 512 sectors +disk_write_at_offset() { + run_and_log_cmd "dd if=${1} of=${2} seek=${3} conv=sparse status=none" +} + +# Create file system image from directory content +# +# $1 - base folder +# $2 - destination file +# $3 - image size in sectors +# $4 - file system type, e.g ext4, xfs, ... +disk_create_file_system_from_folder() { + log_info "Creating a file-system image from: ${1}" + + run_and_log_cmd "dd if=/dev/zero of=${2} seek=${3} count=0 bs=512 status=none" + + case "$4" in + "ext4") + MKFS_EXT4="/usr/bin/mkfs.ext4" + if [ ! -f ${MKFS_EXT4} ]; then + MKFS_EXT4="/sbin/mkfs.ext4" + fi + run_and_log_cmd "${MKFS_EXT4} -q -F ${2}" + ;; + + "xfs") + MKFS_XFS="/usr/bin/mkfs.xfs" + if [ ! -f ${MKFS_XFS} ]; then + MKFS_XFS="/sbin/mkfs.xfs" + fi + run_and_log_cmd "${MKFS_XFS} -q -f ${2}" + ;; + *) + log_fatal "Unknown file system type specified: ${4}" + esac + + run_and_log_cmd "mkdir -p work/output" + run_and_log_cmd "sudo mount ${2} work/output" + run_and_log_cmd "sudo rsync --archive --delete ${1} work/output/" + run_and_log_cmd "sudo umount work/output" +} + +# Print path to the boot partition filesystem image +# +disk_boot_part() { + # Why this little dance you might wonder. + # + # Some disk images do not have a boot partition, but our integration does + # require one and this is why there is a difference here. + # + # If input image did not have a boot part it will be generated and be called: + # + # work/boot-generated.vfat + # + # This is mostly done to make it obvious that we have created an empty vfat file. + # + # But if the disk image already had a boot part, we assume that it is the first + # partition that was extracted. + # + # We also need to adjust the part number of the rootfs part depending on if + # boot part was extracted or generated. + boot_part="work/boot-generated.vfat" + if [ ! -f ${boot_part} ]; then + boot_part="work/part-1.fs" + fi + echo "${boot_part}" +} + +# Print path to the root partition filesystem image +# +disk_root_part() { + boot_part="work/boot-generated.vfat" + if [ ! -f ${boot_part} ]; then + root_part="work/part-2.fs" + else + root_part="work/part-1.fs" + fi + echo "${root_part}" +} diff --git a/modules/log.sh b/modules/log.sh new file mode 100644 index 0000000..b13261b --- /dev/null +++ b/modules/log.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This must be an absolute path, as users might call the log functions +# from sub-directories +log_file="${PWD}/work/convert.log" + +# Log the given message at the given level. +function log { + local -r level="$1" + local -r message="$2" + local -r timestamp=$(date +"%Y-%m-%d %H:%M:%S") + local -r script_name="$(basename "$0")" + >&2 echo -e "${timestamp} [${level}] [$script_name] ${message}" | tee -a ${log_file} +} + +function local_log_debug { + local -r level="DEBUG" + local -r message="$1" + local -r timestamp=$(date +"%Y-%m-%d %H:%M:%S") + local -r script_name="$(basename "$0")" + echo -e "${timestamp} [${level}] [$script_name] ${message}" >> ${log_file} +} + +# Log the given message at DEBUG level. +function log_debug { + local -r message="$1" + local_log_debug "$message" +} + +# Log the given message at INFO level. +function log_info { + local -r message="$1" + log "INFO" "$message" +} + +# Log the given message at WARN level. +function log_warn { + local -r message="$1" + log "WARN" "$message" +} + +# Log the given message at ERROR level. +function log_error { + local -r message="$1" + log "ERROR" "$message" +} + +# Log the given message at FATAL level. +function log_fatal { + local -r message="$1" + log "FATAL" "$message" + exit 1 +} diff --git a/modules/probe.sh b/modules/probe.sh new file mode 100644 index 0000000..736c4fc --- /dev/null +++ b/modules/probe.sh @@ -0,0 +1,237 @@ +#!/usr/bin/env bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Prints target architecture +# +# No input parameters and these work on the assumption that boot and root parts +# are mounted at work/boot and work/rootfs +probe_arch() { + # --dereference, means to follow symlinks because 'ls' could be a symlink + # to busybox + file_info="" + for location in bin/ls usr/bin/ls; do + if [ -e work/rootfs/${location} ]; then + file_info=$(file -b --dereference work/rootfs/${location}) + break + fi + done + + if [ -z "${file_info}" ]; then + log_fatal "Sorry, where not able to determinate target architecture" + fi + + target_arch="unknown" + if grep -q x86-64 <<< "${file_info}"; then + target_arch="x86-64" + elif grep -Eq "ELF 32-bit.*ARM" <<< "${file_info}"; then + target_arch="arm" + elif grep -Eq "ELF 64-bit.*aarch64" <<< "${file_info}"; then + target_arch="aarch64" + else + log_fatal "Unsupported architecture: ${file_info}" + fi + echo "${target_arch}" +} + +# Prints GRUB EFI name depending on target architecture +# +# No input parameters and these work on the assumption that boot and root parts +# are mounted at work/boot and work/rootfs +probe_grub_efi_name() { + efi_name="" + arch=$(probe_arch) + case "${arch}" in + "x86-64") + efi_name="grub-efi-bootx64.efi" + ;; + "arm") + efi_name="grub-efi-bootarm.efi" + ;; + "aarch64") + efi_name="grub-efi-bootaa64.efi" + ;; + *) + log_fatal "Unknown arch: ${arch}" + esac + echo "$efi_name" +} + +# Prints Debian arch name depending on target architecture +# +# No input parameters and these work on the assumption that boot and root parts +# are mounted at work/boot and work/rootfs +probe_debian_arch_name() { + deb_arch="" + arch=$(probe_arch) + case "${arch}" in + "x86-64") + deb_arch="amd64" + ;; + "arm") + deb_arch="armhf" + ;; + "aarch64") + deb_arch="arm64" + ;; + *) + log_fatal "Unknown arch: ${arch}" + esac + echo "${deb_arch}" +} + +# Prints GRUB EFI target name depending on target architecture +# +# This is what the file name should be when put on target boot part. +# +# No input parameters and these work on the assumption that boot and root parts +# are mounted at work/boot and work/rootfs +probe_grub_efi_target_name() { + efi_target_name="" + arch=$(probe_arch) + case "$arch" in + "x86-64") + efi_target_name="bootx64.efi" + ;; + "arm") + efi_target_name="bootarm.efi" + ;; + "aarch64") + efi_target_name="bootaa64.efi" + ;; + *) + log_fatal "Unknown arch: ${arch}" + esac + echo "$efi_target_name" +} + +# Prints path to the Linux kernel image +# +# $1 - directory in which the search is performed +# +probe_kernel_image() { + kernel_image_path="" + for image in vmlinuz zImage bzImage; do + # Linux kernel image type and naming varies between different platforms. + # + # The wildcard at the end is important, because it is common to suffix the + # Linux kernel version to the image type/name, e.g: + # + # vmlinuz-4.14-x86_64 + # vmlinuz-3.10.0-862.el7.x86_64 + # vmlinuz-4.15.0-20-generic + # + kernel_image_path=$(sudo find ${1} -name ${image}* ! -name '*-rescue-*') + if [ -n "${kernel_image_path}" ]; then + break + fi + done + echo "${kernel_image_path}" +} + +# Prints path to the initrd/initramfs image +# +# $1 - directory in which the search is performed +# +probe_initrd_image() { + initrd_image_path="" + for image in initramfs initrd; do + # initrd/initramfs naming varies between different platforms. + # + # The wildcard at the end is important, because it is common to suffix the + # Linux kernel version to the image name, e.g: + # + # initrd.img-4.15.0-20-generic + # + initrd_image_path=$(sudo find ${1} -name ${image}* ! -name '*-rescue-*') + if [ -n "${initrd_image_path}" ]; then + break + fi + done + echo "${initrd_image_path}" +} + + +# Prints Linux kernel image name +# +# It will look for it in both boot and rootfs parts. If image is only present +# in boot part, it will move it to rootfs/boot +# +# No input parameters and these work on the assumption that boot and root parts +# are mounted at work/boot and work/rootfs +probe_kernel_in_boot_and_root() { + kernel_imagetype_path="" + + # Important to check rootfs/boot first, because it might be possible that + # they are stored in both partitions, and in this case we want to find the + # image in the rootfs first and use that, to avoid copying it over from + # boot part when it is already there. + for boot in work/rootfs/boot work/boot; do + kernel_imagetype_path=$(probe_kernel_image ${boot}) + if [ -n "${kernel_imagetype_path}" ] && [ "${boot}" == "work/boot" ]; then + log_info "Found Linux kernel image in boot part, moving to rootfs/boot" + sudo cp ${kernel_imagetype_path} work/rootfs/boot + break; + elif [ -n "${kernel_imagetype_path}" ]; then + break; + fi + done + + if [ -n "${kernel_imagetype_path}" ]; then + log_info "Found Linux kernel image: \n\n\t${kernel_imagetype_path}\n" + kernel_imagetype=$(basename ${kernel_imagetype_path}) + else + log_warn "Unfortunatly we where not able to find the Linux kernel image." + log_fatal "Please specifc the image name using MENDER_GRUB_KERNEL_IMAGETYPE" + fi + echo "${kernel_imagetype}" +} + +# Prints initrd/initramfs image name +# +# It will look for it in both boot and rootfs parts. If image is only present +# in boot part, it will move it to rootfs/boot +# +# No input parameters and these work on the assumption that boot and root parts +# are mounted at work/boot and work/rootfs +probe_initrd_in_boot_and_root() { + initrd_image_path="" + + # Important to check rootfs/boot first, because it might be possible that + # they are stored in both partitions, and in this case we want to find the + # image in the rootfs first and use that, to avoid copying it over from + # boot part when it is already there. + for boot in work/rootfs/boot work/boot; do + initrd_image_path=$(probe_initrd_image ${boot}) + if [ -n "${initrd_image_path}" ] && [ "${boot}" == "work/boot" ]; then + sudo cp ${initrd_image_path} ${target_rootfs_dir}/boot + break; + elif [ -n "${initrd_image_path}" ]; then + break; + fi + done + + if [ -n "${initrd_image_path}" ]; then + log_info "Found initramfs image: \n\n\t${initrd_image_path}\n" + initrd_imagetype=$(basename ${initrd_image_path}) + else + log_info "Unfortunatly we where not able to find the initrd image." + log_info "Please specifc the image name using MENDER_GRUB_INITRD_IMAGETYPE \ +(only required if your board is using this)" + initrd_imagetype="" + fi + + echo "${initrd_imagetype}" +} diff --git a/modules/run.sh b/modules/run.sh new file mode 100644 index 0000000..6a1a618 --- /dev/null +++ b/modules/run.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Run a command, capture output and log it +# +# $1 - command to run +function run_and_log_cmd() { + local -r cmd="${1}" + + log_debug "Running: \n\r\n\r\t ${cmd}" + log_debug "Run result: \n\r" + + result=$(eval ${cmd}) + log_debug "${result}" +} diff --git a/requirements-deb.txt b/requirements-deb.txt new file mode 100644 index 0000000..4d91f68 --- /dev/null +++ b/requirements-deb.txt @@ -0,0 +1 @@ +binutils xz-utils file rsync parted e2fsprogs xfsprogs pigz dosfstools wget git make bmap-tools diff --git a/rootfs_overlay_demo/.gitkeep b/rootfs_overlay_demo/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/scripts/README-run-tests.md b/scripts/README-run-tests.md new file mode 100644 index 0000000..f6b5219 --- /dev/null +++ b/scripts/README-run-tests.md @@ -0,0 +1,13 @@ +# Run tests + +Run the following commands to install test dependencies (assumes that all mender-convert dependencies are already installed): + + sudo apt-get update e2fsprogs=1.44.1-1 + sudo apt-get -qy --force-yes install python-pip + sudo pip2 install pytest --upgrade + sudo pip2 install pytest-xdist --upgrade + sudo pip2 install pytest-html --upgrade + +Run tests: + + ./scripts/run-tests.sh diff --git a/scripts/bootstrap-rootfs-overlay-demo.sh b/scripts/bootstrap-rootfs-overlay-demo.sh new file mode 100755 index 0000000..57bac6f --- /dev/null +++ b/scripts/bootstrap-rootfs-overlay-demo.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# +# Copyright 2019 Northern.tech AS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Exit if any command exits with a non-zero exit status. +set -o errexit + +root_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" && pwd ) +if [ "${root_dir}" != "${PWD}" ]; then + echo "You must execute $(basename $0) from the root directory: ${root_dir}" + exit 1 +fi + +# Do not actually paste it here, this is just the default value that will +# end up in mender.conf if no token is specified using '--tenant-token' +tenant_token="Paste your Hosted Mender token here" +output_dir="" +while (( "$#" )); do + case "$1" in + -t | --tenant-token) + tenant_token="${2}" + shift 2 + ;; + -o | --output-dir) + output_dir="${2}" + shift 2 + ;; + *) + echo "Sorry but the provided option is not supported: $1" + echo "Usage: $(basename $0) --tenant-token" + exit 1 + ;; + esac +done + +if [ -z "${output_dir}" ]; then + echo "Sorry, but you need to provide an output directory using the '-o/--output-dir' option" + exit 1 +fi + +mkdir -p ${output_dir}/etc/mender +cat <<- EOF > ${output_dir}/etc/mender/mender.conf +{ + "InventoryPollIntervalSeconds": 5, + "RetryPollIntervalSeconds": 30, + "ServerURL": "https://hosted.mender.io/", + "TenantToken": "${tenant_token}", + "UpdatePollIntervalSeconds": 5 +} +EOF + +echo "Configuration file written to: ${output_dir}/etc/mender" diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh new file mode 100755 index 0000000..d431344 --- /dev/null +++ b/scripts/run-tests.sh @@ -0,0 +1,143 @@ +#!/bin/bash + +set -e + +root_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" && pwd ) +if [ "${root_dir}" != "${PWD}" ]; then + echo "You must execute $(basename $0) from the root directory: ${root_dir}" + exit 1 +fi + +WORKSPACE=./tests + +# Relative to where scripts are executed (${WORKSPACE}/mender-image-tests) +MENDER_CONVERT_DIR=../../ + +BBB_DEBIAN_IMAGE="bone-debian-9.5-iot-armhf-2018-10-07-4gb.img" +BBB_DEBIAN_IMAGE_URL="http://debian.beagleboard.org/images/${BBB_DEBIAN_IMAGE}.xz" + +RASPBIAN_IMAGE="2019-04-08-raspbian-stretch-lite" +RASPBIAN_IMAGE_URL="https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-04-09/${RASPBIAN_IMAGE}.zip" + +TINKER_IMAGE="20170417-tinker-board-linaro-stretch-alip-v1.8" +TINKER_IMAGE_URL="http://dlcdnet.asus.com/pub/ASUS/mb/Linux/Tinker_Board_2GB/${TINKER_IMAGE}.zip" + +UBUNTU_IMAGE="Ubuntu-Bionic-x86-64.img" +UBUNTU_IMAGE_URL="https://d1b0l86ne08fsf.cloudfront.net/mender-convert/images/${UBUNTU_IMAGE}.gz" + +MENDER_ACCEPTANCE_URL="https://raw.githubusercontent.com/mendersoftware/meta-mender/master/tests/acceptance" + +# Some distros do not have /sbin in path for "normal users" +export PATH="${PATH}:/sbin" + +convert_and_test() { + device_type=$1 + artifact_name=$2 + image_url=$3 + image_name=$4 + image_name_compressed=$5 + config=$6 # Optional + + wget -N ${image_url} -P input/ + + echo "Extracting: ${image_name_compressed}" + case "${image_name_compressed}" in + *.gz) + gunzip -f input/${image_name_compressed} + ;; + *.zip) + cd input + unzip -o ${image_name_compressed} + cd - + ;; + *.xz) + xz -d -f input/${image_name_compressed} + ;; + *) + echo "Unknown image type: ${image_name_compressed}" + exit 1 + esac + + rm -f ${WORKSPACE}/test_config + + if [ -n "${config}" ]; then + cp ${config} ${WORKSPACE}/test_config + fi + + # Disable compression of disk image when testing, otherwise we need to + # unpack each image we test which is time consuming + echo "MENDER_COMPRESS_DISK_IMAGE=n" >> ${WORKSPACE}/test_config + + echo "Configuration used:" + cat ${WORKSPACE}/test_config + + MENDER_ARTIFACT_NAME=${artifact_name} ./docker-mender-convert \ + --disk-image input/${image_name} \ + --config ${WORKSPACE}/test_config + + cd ${WORKSPACE}/mender-image-tests + + py.test --verbose \ + --junit-xml="${WORKSPACE}/results.xml" \ + --test-conversion \ + --test-variables="${MENDER_CONVERT_DIR}/deploy/${device_type}-${artifact_name}.cfg" \ + --board-type="${device_type}" \ + --mender-image=${device_type}-${artifact_name}.sdimg \ + --sdimg-location="${MENDER_CONVERT_DIR}/deploy" + + cd - +} + +get_pytest_files() { + wget -N ${MENDER_ACCEPTANCE_URL}/pytest.ini -P $WORKSPACE/mender-image-tests + wget -N ${MENDER_ACCEPTANCE_URL}/common.py -P $WORKSPACE/mender-image-tests + wget -N ${MENDER_ACCEPTANCE_URL}/conftest.py -P $WORKSPACE/mender-image-tests + wget -N ${MENDER_ACCEPTANCE_URL}/fixtures.py -P $WORKSPACE/mender-image-tests +} + +if [ ! -d ${WORKSPACE}/mender-image-tests ]; then + git clone https://github.com/mendersoftware/mender-image-tests ${WORKSPACE}/mender-image-tests +else + cd ${WORKSPACE}/mender-image-tests + git pull + cd - +fi + +if ! [ -x "$(command -v mender-artifact)" ]; then + echo "mender-artifact: not found in PATH." + github_PR_status "failure" "mender-artifact: not found in PATH." + exit 1 +fi + +mkdir -p ${WORKSPACE} + +get_pytest_files + +./docker-build + +convert_and_test "qemux86_64" \ + "release-1" \ + "${UBUNTU_IMAGE_URL}" \ + "${UBUNTU_IMAGE}" \ + "${UBUNTU_IMAGE}.gz" \ + "configs/qemux86-64_config" + + +convert_and_test "raspberrypi" \ + "release-1" \ + "${RASPBIAN_IMAGE_URL}" \ + "${RASPBIAN_IMAGE}.img" \ + "${RASPBIAN_IMAGE}.zip" \ + "configs/raspberrypi3_config" + +convert_and_test "linaro-alip" \ + "release-1" \ + "${TINKER_IMAGE_URL}" \ + "${TINKER_IMAGE}.img" \ + "${TINKER_IMAGE}.zip" + +convert_and_test "beaglebone" \ + "release-1" \ + "${BBB_DEBIAN_IMAGE_URL}" \ + "${BBB_DEBIAN_IMAGE}" \ + "${BBB_DEBIAN_IMAGE}.xz"