├── .gitignore
├── .gitmodules
├── LICENSE
├── README.md
├── configuration
├── base
│ └── common.yml
├── documentation
│ └── packages-baseline.yml
├── mender
│ ├── identity
│ │ └── mender-device-identity
│ ├── inventory
│ │ └── mender-inventory-bootloader-integration
│ └── mender.yml
└── overlay
│ ├── pi-cross-dev.global.yml
│ ├── pi2-gitops.global.yml
│ ├── pi2.global.yml
│ ├── pi3-gitops.global.yml
│ ├── pi3.global.yml
│ ├── pi4-gitops.global.yml
│ ├── pi4.global.yml
│ ├── pi5-gitops.global.yml
│ └── pi5.global.yml
├── docs
├── kernel_build.md
└── wifi_setup.md
├── pi-cross-dev.yml
├── pi2-gitops.yml
├── pi2.yml
├── pi3-gitops.yml
├── pi3.yml
├── pi4-gitops.yml
├── pi4.yml
├── pi5-gitops.yml
├── pi5.yml
├── plugins
├── playbooks
│ └── os_setup
│ │ ├── collections
│ │ └── ansible_collections
│ │ ├── main.yml
│ │ └── roles
│ │ ├── bootloader
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── files
│ │ │ ├── boot.scr.txt
│ │ │ ├── cmdline.txt.u-boot
│ │ │ ├── config.txt.u-boot.arm64
│ │ │ ├── config.txt.u-boot.armhf
│ │ │ ├── generate-archives
│ │ │ ├── raspberrypi-bootloader.tar.gz
│ │ │ ├── u-boot-bootloader.arm64.pi3.tar.gz
│ │ │ ├── u-boot-bootloader.arm64.pi4-v2.tar.gz
│ │ │ ├── u-boot-bootloader.arm64.pi4.tar.gz
│ │ │ ├── u-boot-bootloader.armhf.pi2.tar.gz
│ │ │ └── u-boot-bootloader.armhf.pi3.tar.gz
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ ├── cmdline.txt.raspberry-pi
│ │ │ ├── config.txt.raspberry-pi.arm64
│ │ │ ├── fw_env.config
│ │ │ └── multiboot.cfg
│ │ ├── essential_bare_metal_packages
│ │ ├── files
│ │ │ ├── 85-systemd_networkd.preset
│ │ │ ├── 95-wpa_supplicant.preset
│ │ │ └── brcmfmac.conf
│ │ ├── tasks
│ │ │ └── main.yml
│ │ ├── templates
│ │ │ └── edi-set-hostname.override.conf
│ │ └── vars
│ │ │ └── main.yml
│ │ ├── mender
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── files
│ │ │ ├── 05_mender_update
│ │ │ ├── empty.json
│ │ │ ├── mender-io-archive-keyring.gpg
│ │ │ ├── override.conf
│ │ │ └── pi-uboot
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ ├── device_type
│ │ │ ├── mender-connect.conf
│ │ │ ├── mender-io.list
│ │ │ └── mender.conf
│ │ └── repositories
│ │ ├── files
│ │ ├── 50-get-edi-io
│ │ └── get-edi-io-archive-keyring.gpg
│ │ ├── tasks
│ │ └── main.yml
│ │ └── templates
│ │ └── get-edi-io.list
├── postprocessing_commands
│ ├── container_image
│ │ └── buildah2image.edi
│ ├── documentation
│ │ ├── write_doc
│ │ └── write_doc.edi
│ ├── fully_named_artifacts
│ │ └── create_full_names.edi
│ ├── genimage
│ │ ├── exclude-patterns
│ │ ├── fstab
│ │ ├── genimage.cfg
│ │ ├── hostname
│ │ ├── hosts
│ │ └── rootfs2image.edi
│ ├── mender
│ │ ├── ArtifactInstall_Enter_50_BootpartitionSetup
│ │ ├── ArtifactInstall_Leave_50_ConfigurationBackup
│ │ ├── ArtifactReboot_Leave_50_ConfigurationRestore
│ │ ├── image2mender
│ │ └── image2mender.edi
│ ├── rootfs
│ │ └── buildah2rootfs.edi
│ └── timestamp
│ │ └── timestamp.edi
└── preprocessing_commands
│ ├── bootstrap
│ └── mmdebstrap.edi
│ └── prerequisites
│ ├── check_prerequisites
│ └── check_prerequisites.edi
└── ssh_pub_keys
└── README.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | # edi build artifacts
2 |
3 | artifacts/*
4 | main.retry
5 |
6 | # pycharm files
7 | .idea/*
8 | /configuration/mender/mender_custom.yml
9 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "submodules/ansible_collections/get_edi_io/debian_setup"]
2 | path = submodules/ansible_collections/get_edi_io/debian_setup
3 | url = https://github.com/lueschem/debian_setup.git
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Matthias Lüscher
4 |
5 | -----------------------------------------------------------------------------
6 | Please note that some bash scripts within the plugins/postprocessing_commands
7 | folder are licensed under the GNU Lesser General Public License.
8 | -----------------------------------------------------------------------------
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in all
18 | copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | SOFTWARE.
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # edi Project Configuration for Raspberry Pi Devices
2 |
3 | Debian tool chain and image generation for the Raspberry Pi 2, 3, 4 and 5.
4 |
5 |
6 |
7 | > [!NOTE]
8 | > The *master* branch is **experimental** and currently based on Debian *trixie*.
9 | > To get the stable Debian *bookworm* configuration please check out the *debian_bookworm* branch.
10 |
11 | ## Introduction
12 |
13 | The edi configuration contained in this repository can be used to
14 | generate the following artifacts:
15 |
16 | * A Debian trixie arm64 (64bit) image suitable for the Raspberry Pi 3, 4 or 5.
17 | * A Debian trixie armhf (32bit) image suitable for the Raspberry Pi 2.
18 | * Matching Mender update artifacts for the above configurations.
19 | * A Podman/Docker image with a pre-installed cross development toolchains (armhf/arm64) for C and C++.
20 |
21 | > [!NOTE]
22 | > The Raspberry Pi 3 images are now making use of the tryboot feature too and do no longer
23 | > rely on u-boot to switch the boot partitions. A bookworm or older image is therefore incompatible
24 | > with a trixie or newer image. A migration to the new approach during the upgrade might be possible
25 | > but is currently not implemented. Feel free to write a feature request in case your existing project
26 | > would benefit from such a feature.
27 |
28 | ## Basic Usage
29 |
30 | ### Preparation
31 |
32 | Prior to using this edi project configuration you have to install
33 | [edi](https://www.get-edi.io) according to
34 | [this instructions](https://docs.get-edi.io/en/stable/getting_started_v2.html).
35 | Please take a careful look at the "Setting up ssh Keys" section since you
36 | will need a proper ssh key setup in order to access the
37 | the target device using ssh.
38 |
39 | The artifact generation requires some additional tools. On
40 | Ubuntu 24.04 and newer those tools can be installed as follows:
41 |
42 | ``` bash
43 | sudo apt install buildah containers-storage crun curl distrobox dosfstools e2fsprogs fakeroot genimage git mender-artifact mmdebstrap mtools parted python3-sphinx python3-testinfra podman rsync zerofree
44 | ```
45 |
46 | ### Cloning this Repository
47 |
48 | The edi-pi project configuration contained in this git repository can be cloned as follows:
49 |
50 | ``` bash
51 | mkdir -p ~/edi-workspace/ && cd ~/edi-workspace/
52 | git clone --recursive https://github.com/lueschem/edi-pi.git
53 | ```
54 |
55 | The following steps assume that you are located within the project configuration directory:
56 |
57 | ``` bash
58 | cd ~/edi-workspace/edi-pi/
59 | ```
60 |
61 | If the repository has already been cloned earlier, do not forget to update the submodules:
62 |
63 | ``` bash
64 | git submodule update --init
65 | ```
66 |
67 | ### Optional: Connecting to Mender
68 |
69 | To enable over the air (OTA) updates, the generated images are configured
70 | to connect to [https://hosted.mender.io/](https://hosted.mender.io/).
71 | In order to connect to your Mender tenant you have to provide your tenant token prior to building the images.
72 | The tenant token can be added to `configuration/mender/mender.yml`. If you do not want to
73 | add the tenant token to the version control system you can also copy `configuration/mender/mender.yml` to
74 | `configuration/mender/mender_custom.yml` and add the tenant token there.
75 |
76 | ### Creating a Raspberry Pi Image
77 |
78 | A Raspberry Pi image can be created using the following command:
79 |
80 | For Raspberry Pi 5, arm64:
81 |
82 | ``` bash
83 | edi -v project make pi5.yml
84 | ```
85 |
86 | For Raspberry Pi 5, arm64, prepared for GitOps (git and Ansible preinstalled):
87 |
88 | ``` bash
89 | edi -v project make pi5-gitops.yml
90 | ```
91 |
92 | For Raspberry Pi 4, arm64:
93 |
94 | ``` bash
95 | edi -v project make pi4.yml
96 | ```
97 |
98 | For Raspberry Pi 4, arm64, prepared for GitOps (git and Ansible preinstalled):
99 |
100 | ``` bash
101 | edi -v project make pi4-gitops.yml
102 | ```
103 |
104 | For Raspberry Pi 3, arm64:
105 |
106 | ``` bash
107 | edi -v project make pi3.yml
108 | ```
109 |
110 | For Raspberry Pi 2, armhf:
111 |
112 | ``` bash
113 | edi -v project make pi2.yml
114 | ```
115 |
116 | The resulting image can be copied to a SD card (here /dev/mmcblk0)
117 | using the following command
118 | (**Please note that everything on the SD card will be erased!**):
119 |
120 | Example for Raspberry Pi 5, arm64:
121 |
122 | ``` bash
123 | sudo umount /dev/mmcblk0p?
124 | sudo dd if=artifacts/pi5.img of=/dev/mmcblk0 bs=4M conv=fsync status=progress
125 | ```
126 |
127 | Once you have booted the Raspberry Pi using this SD card you can
128 | access it using ssh (the access should be granted thanks to your
129 | ssh keys):
130 |
131 | ``` bash
132 | ssh pi@IP_ADDRESS
133 | ```
134 |
135 | The password for the user _pi_ is _raspberry_ (just in case you want to
136 | execute a command using `sudo` or login via a local terminal).
137 |
138 | ### Creating a Cross Development Container
139 |
140 | A Podman image of a cross development container can be created using the
141 | following command:
142 |
143 | ``` bash
144 | edi -v project make pi-cross-dev.yml
145 | ```
146 |
147 | distrobox can be used to transform the image into a convenient development container:
148 |
149 | ``` bash
150 | source artifacts/pi-cross-dev_manifest
151 | distrobox create --image ${podman_image} --name SOME_CONTAINER_NAME --init --unshare-all --additional-packages "systemd libpam-systemd"
152 | ```
153 |
154 | For all the development work the container can be entered as follows:
155 |
156 | ``` bash
157 | distrobox enter SOME_CONTAINER_NAME
158 | ```
159 |
160 | You can directly start to cross compile applications:
161 |
162 | For the Raspberry Pi 3, 4 or 5, arm64:
163 |
164 | ``` bash
165 | aarch64-linux-gnu-g++ ...
166 | ```
167 |
168 | For the Raspberry Pi 2, armhf:
169 |
170 | ``` bash
171 | arm-linux-gnueabihf-g++
172 | ```
173 |
174 | ## Documenting an Artifact
175 |
176 | During the image build the documentation gets rendered to artifacts/CONFIGNAME_documentation
177 | as reStructuredText. The text files can be transformed into a nice pdf file with some
178 | additional tools that need to be installed first:
179 |
180 | ``` bash
181 | sudo apt install texlive-latex-recommended texlive-pictures texlive-latex-extra texlive-xetex latexmk
182 | ```
183 |
184 | Then the pdf can be generated using the following commands:
185 |
186 | ``` bash
187 | cd artifacts/CONFIGNAME_documentation
188 | make PDFLATEX=xelatex latexpdf
189 | make PDFLATEX=xelatex latexpdf
190 | ```
191 |
192 | ### More Information
193 |
194 | For more information about this setup please read the [edi documentation](https://docs.get-edi.io) and
195 | [this blog post](https://www.get-edi.io/Rootless-Creation-of-Debian-OS-and-OCI-Images/).
196 |
197 | For details about the Mender based robust update integration please refer to this
198 | [blog post](https://www.get-edi.io/Updating-a-Debian-Based-IoT-Fleet/).
199 |
200 | If you are curious about the U-Boot bootloader setup please take a look at this
201 | [blog post](https://www.get-edi.io/Booting-Debian-with-U-Boot/).
202 |
203 | For the kernel build instructions related to the Raspberry Pi 4 and 5 please check
204 | [this blog post](https://www.get-edi.io/Getting-Started-with-a-new-Embedded-System/).
205 |
206 | The WiFi setup is [documented here](docs/wifi_setup.md).
207 |
208 | A GitOps example can be found [here](https://www.get-edi.io/Surprisingly-Easy-IoT-Device-Management/).
209 |
--------------------------------------------------------------------------------
/configuration/base/common.yml:
--------------------------------------------------------------------------------
1 | general:
2 | edi_required_minimal_edi_version: 1.19.0
3 | parameters:
4 | mender_device_type: generic
5 | ansible_pipelining: true
6 | ebs_bootloader_type: "u-boot"
7 | default_user_name: pi
8 | default_user_group_name: pi
9 | debian_distribution_release: trixie
10 | ansible_python_interpreter: /usr/bin/python3
11 |
12 | preprocessing_commands:
13 | 100_prerequisites:
14 | path: preprocessing_commands/prerequisites/check_prerequisites.edi
15 | output:
16 | edi_prerequisites_log:
17 | location: {{ edi_configuration_name }}_prerequisites.log
18 | type: path
19 | 200_mmdebstrap:
20 | path: preprocessing_commands/bootstrap/mmdebstrap.edi
21 | output:
22 | edi_bootstrapped_rootfs:
23 | location: {{ edi_configuration_name }}_bootstrapped-rootfs.tar
24 | type: path
25 |
26 | playbooks:
27 | 100_os_setup:
28 | path: playbooks/os_setup/main.yml
29 | parameters:
30 | create_default_user: True
31 | # password is raspberry
32 | default_user_password: "$6$UFxTVMw7t4D3xPRl$GikrlPLW3hr34zssKC1w9rP9kUoSoa1UPoGMIylT8qb3fYM2lDAe9Mvr7hl1VRjz8wR84tfEkZ6.uot.K2B/F0"
33 | install_openssh_server: True
34 | disable_ssh_password_authentication: True
35 | install_documentation: changelog
36 | translations_filter: en_translations_only
37 | base_system_sources_list_template: debian.list
38 | document_build_setup: true
39 | document_installed_packages: true
40 | ssh_host_key_backup_folder: /data/backup/ssh
41 |
42 | postprocessing_commands:
43 | 100_timestamp:
44 | path: postprocessing_commands/timestamp/timestamp.edi
45 | output:
46 | pp_timestamp:
47 | location: {{ edi_configuration_name }}_timestamp
48 | type: path
49 | 200_buildah2rootfs:
50 | path: postprocessing_commands/rootfs/buildah2rootfs.edi
51 | output:
52 | pp_rootfs_archive:
53 | location: {{ edi_configuration_name }}_configured-rootfs.tar
54 | type: path
55 | 300_rootfs2image:
56 | path: postprocessing_commands/genimage/rootfs2image.edi
57 | require_root: "fakeroot"
58 | output:
59 | pp_image:
60 | location: {{ edi_configuration_name }}.img
61 | type: path
62 | pp_partition_image:
63 | location: {{ edi_configuration_name }}_rootfs.ext4
64 | type: path
65 | parameters:
66 | hostname: raspberry
67 | 400_mender:
68 | path: postprocessing_commands/mender/image2mender.edi
69 | output:
70 | pp_mender_artifact:
71 | location: {{ edi_configuration_name }}.mender
72 | type: path
73 | 500_documentation:
74 | path: postprocessing_commands/documentation/write_doc.edi
75 | output:
76 | pp_documentation:
77 | location: {{ edi_configuration_name }}_documentation
78 | type: path
79 | parameters:
80 | author: The edi-pi Project Team
81 | 600_fully_named_artifacts:
82 | path: postprocessing_commands/fully_named_artifacts/create_full_names.edi
83 | output:
84 | pp_fully_named_artifacts:
85 | location: {{ edi_configuration_name }}_fully_named_artifacts
86 | type: path
87 |
88 | documentation_steps:
89 | 100_index:
90 | path: documentation_steps/rst/templates/index.rst.j2
91 | output:
92 | file: index.rst
93 | parameters:
94 | edi_doc_include_packages: []
95 | toctree_items: ['setup', 'versions', 'changelog']
96 | 200_setup:
97 | path: documentation_steps/rst/templates/setup.rst.j2
98 | output:
99 | file: setup.rst
100 | parameters:
101 | edi_doc_include_packages: []
102 | 300_versions:
103 | output:
104 | file: versions.rst
105 | path: documentation_steps/rst/templates/versions.rst.j2
106 | 400_changelog:
107 | path: documentation_steps/rst/templates/changelog.rst.j2
108 | output:
109 | file: changelog.rst
110 | parameters:
111 | edi_doc_include_changelog: True
112 | edi_doc_changelog_baseline: 2023-06-10 00:00:00 GMT
113 | edi_doc_replacements:
114 | - pattern: '(CVE-[0-9]{4}-[0-9]{4,6})'
115 | replacement: '`\1 `_'
116 | - pattern: '(?i)[#]*(Closes:\s[#])([0-9]{6,10})'
117 | replacement: '`\1\2 `_'
118 | - pattern: '(?i)[#]*(LP:\s[#])([0-9]{6,10})'
119 | replacement: '`\1\2 `_'
120 |
121 |
122 |
--------------------------------------------------------------------------------
/configuration/documentation/packages-baseline.yml:
--------------------------------------------------------------------------------
1 | - package: adduser
2 | architecture: all
3 | version: "3.118"
4 | source_package: adduser
5 | status: ii
6 | - package: apt
7 | architecture: arm64
8 | version: "1.8.2"
9 | source_package: apt
10 | status: ii
11 | - package: base-files
12 | architecture: arm64
13 | version: "10.3+deb10u2"
14 | source_package: base-files
15 | status: ii
16 | - package: base-passwd
17 | architecture: arm64
18 | version: "3.5.46"
19 | source_package: base-passwd
20 | status: ii
21 | - package: bash
22 | architecture: arm64
23 | version: "5.0-4"
24 | source_package: bash
25 | status: ii
26 | - package: bsdutils
27 | architecture: arm64
28 | version: "1:2.33.1-0.1"
29 | source_package: util-linux
30 | status: ii
31 | - package: ca-certificates
32 | architecture: all
33 | version: "20190110"
34 | source_package: ca-certificates
35 | status: ii
36 | - package: coreutils
37 | architecture: arm64
38 | version: "8.30-3"
39 | source_package: coreutils
40 | status: ii
41 | - package: cpio
42 | architecture: arm64
43 | version: "2.12+dfsg-9"
44 | source_package: cpio
45 | status: ii
46 | - package: dash
47 | architecture: arm64
48 | version: "0.5.10.2-5"
49 | source_package: dash
50 | status: ii
51 | - package: dbus
52 | architecture: arm64
53 | version: "1.12.16-1"
54 | source_package: dbus
55 | status: ii
56 | - package: debconf
57 | architecture: all
58 | version: "1.5.71"
59 | source_package: debconf
60 | status: ii
61 | - package: debian-archive-keyring
62 | architecture: all
63 | version: "2019.1"
64 | source_package: debian-archive-keyring
65 | status: ii
66 | - package: debianutils
67 | architecture: arm64
68 | version: "4.8.6.1"
69 | source_package: debianutils
70 | status: ii
71 | - package: diffutils
72 | architecture: arm64
73 | version: "1:3.7-3"
74 | source_package: diffutils
75 | status: ii
76 | - package: dirmngr
77 | architecture: arm64
78 | version: "2.2.12-1+deb10u1"
79 | source_package: gnupg2
80 | status: ii
81 | - package: distro-info-data
82 | architecture: all
83 | version: "0.41+deb10u1"
84 | source_package: distro-info-data
85 | status: ii
86 | - package: dmsetup
87 | architecture: arm64
88 | version: "2:1.02.155-3"
89 | source_package: lvm2
90 | status: ii
91 | - package: dosfstools
92 | architecture: arm64
93 | version: "4.1-2"
94 | source_package: dosfstools
95 | status: ii
96 | - package: dpkg
97 | architecture: arm64
98 | version: "1.19.7"
99 | source_package: dpkg
100 | status: ii
101 | - package: dumb-init
102 | architecture: arm64
103 | version: "1.2.2-1.1"
104 | source_package: dumb-init
105 | status: ii
106 | - package: e2fsprogs
107 | architecture: arm64
108 | version: "1.44.5-1+deb10u2"
109 | source_package: e2fsprogs
110 | status: ii
111 | - package: edi-boot-shim
112 | architecture: all
113 | version: "0.8.0+deb10"
114 | source_package: edi-boot-shim
115 | status: ii
116 | - package: fdisk
117 | architecture: arm64
118 | version: "2.33.1-0.1"
119 | source_package: util-linux
120 | status: ii
121 | - package: findutils
122 | architecture: arm64
123 | version: "4.6.0+git+20190209-2"
124 | source_package: findutils
125 | status: ii
126 | - package: firmware-brcm80211
127 | architecture: all
128 | version: "1:20190114-1+rpt4"
129 | source_package: firmware-nonfree
130 | status: ii
131 | - package: gcc-8-base
132 | architecture: arm64
133 | version: "8.3.0-6"
134 | source_package: gcc-8
135 | status: ii
136 | - package: gnupg
137 | architecture: all
138 | version: "2.2.12-1+deb10u1"
139 | source_package: gnupg2
140 | status: ii
141 | - package: gnupg-l10n
142 | architecture: all
143 | version: "2.2.12-1+deb10u1"
144 | source_package: gnupg2
145 | status: ii
146 | - package: gnupg-utils
147 | architecture: arm64
148 | version: "2.2.12-1+deb10u1"
149 | source_package: gnupg2
150 | status: ii
151 | - package: gpg
152 | architecture: arm64
153 | version: "2.2.12-1+deb10u1"
154 | source_package: gnupg2
155 | status: ii
156 | - package: gpg-agent
157 | architecture: arm64
158 | version: "2.2.12-1+deb10u1"
159 | source_package: gnupg2
160 | status: ii
161 | - package: gpg-wks-client
162 | architecture: arm64
163 | version: "2.2.12-1+deb10u1"
164 | source_package: gnupg2
165 | status: ii
166 | - package: gpg-wks-server
167 | architecture: arm64
168 | version: "2.2.12-1+deb10u1"
169 | source_package: gnupg2
170 | status: ii
171 | - package: gpgconf
172 | architecture: arm64
173 | version: "2.2.12-1+deb10u1"
174 | source_package: gnupg2
175 | status: ii
176 | - package: gpgsm
177 | architecture: arm64
178 | version: "2.2.12-1+deb10u1"
179 | source_package: gnupg2
180 | status: ii
181 | - package: gpgv
182 | architecture: arm64
183 | version: "2.2.12-1+deb10u1"
184 | source_package: gnupg2
185 | status: ii
186 | - package: grep
187 | architecture: arm64
188 | version: "3.3-1"
189 | source_package: grep
190 | status: ii
191 | - package: gzip
192 | architecture: arm64
193 | version: "1.9-3"
194 | source_package: gzip
195 | status: ii
196 | - package: haveged
197 | architecture: arm64
198 | version: "1.9.1-7"
199 | source_package: haveged
200 | status: ii
201 | - package: hostname
202 | architecture: arm64
203 | version: "3.21"
204 | source_package: hostname
205 | status: ii
206 | - package: ifupdown
207 | architecture: arm64
208 | version: "0.8.35"
209 | source_package: ifupdown
210 | status: ii
211 | - package: init-system-helpers
212 | architecture: all
213 | version: "1.56+nmu1"
214 | source_package: init-system-helpers
215 | status: ii
216 | - package: initramfs-tools
217 | architecture: all
218 | version: "0.133+deb10u1"
219 | source_package: initramfs-tools
220 | status: ii
221 | - package: initramfs-tools-core
222 | architecture: all
223 | version: "0.133+deb10u1"
224 | source_package: initramfs-tools
225 | status: ii
226 | - package: iproute2
227 | architecture: arm64
228 | version: "4.20.0-2"
229 | source_package: iproute2
230 | status: ii
231 | - package: iputils-ping
232 | architecture: arm64
233 | version: "3:20180629-2"
234 | source_package: iputils
235 | status: ii
236 | - package: isc-dhcp-client
237 | architecture: arm64
238 | version: "4.4.1-2"
239 | source_package: isc-dhcp
240 | status: ii
241 | - package: iso-codes
242 | architecture: all
243 | version: "4.2-1"
244 | source_package: iso-codes
245 | status: ii
246 | - package: klibc-utils
247 | architecture: arm64
248 | version: "2.0.6-1"
249 | source_package: klibc
250 | status: ii
251 | - package: kmod
252 | architecture: arm64
253 | version: "26-1"
254 | source_package: kmod
255 | status: ii
256 | - package: libacl1
257 | architecture: arm64
258 | version: "2.2.53-4"
259 | source_package: acl
260 | status: ii
261 | - package: libapparmor1
262 | architecture: arm64
263 | version: "2.13.2-10"
264 | source_package: apparmor
265 | status: ii
266 | - package: libapt-inst2.0
267 | architecture: arm64
268 | version: "1.8.2"
269 | source_package: apt
270 | status: ii
271 | - package: libapt-pkg5.0
272 | architecture: arm64
273 | version: "1.8.2"
274 | source_package: apt
275 | status: ii
276 | - package: libargon2-1
277 | architecture: arm64
278 | version: "0~20171227-0.2"
279 | source_package: argon2
280 | status: ii
281 | - package: libassuan0
282 | architecture: arm64
283 | version: "2.5.2-1"
284 | source_package: libassuan
285 | status: ii
286 | - package: libattr1
287 | architecture: arm64
288 | version: "1:2.4.48-4"
289 | source_package: attr
290 | status: ii
291 | - package: libaudit-common
292 | architecture: all
293 | version: "1:2.8.4-3"
294 | source_package: audit
295 | status: ii
296 | - package: libaudit1
297 | architecture: arm64
298 | version: "1:2.8.4-3"
299 | source_package: audit
300 | status: ii
301 | - package: libblkid1
302 | architecture: arm64
303 | version: "2.33.1-0.1"
304 | source_package: util-linux
305 | status: ii
306 | - package: libbsd0
307 | architecture: arm64
308 | version: "0.9.1-2"
309 | source_package: libbsd
310 | status: ii
311 | - package: libbz2-1.0
312 | architecture: arm64
313 | version: "1.0.6-9.2~deb10u1"
314 | source_package: bzip2
315 | status: ii
316 | - package: libc-bin
317 | architecture: arm64
318 | version: "2.28-10"
319 | source_package: glibc
320 | status: ii
321 | - package: libc6
322 | architecture: arm64
323 | version: "2.28-10"
324 | source_package: glibc
325 | status: ii
326 | - package: libcap-ng0
327 | architecture: arm64
328 | version: "0.7.9-2"
329 | source_package: libcap-ng
330 | status: ii
331 | - package: libcap2
332 | architecture: arm64
333 | version: "1:2.25-2"
334 | source_package: libcap2
335 | status: ii
336 | - package: libcap2-bin
337 | architecture: arm64
338 | version: "1:2.25-2"
339 | source_package: libcap2
340 | status: ii
341 | - package: libcom-err2
342 | architecture: arm64
343 | version: "1.44.5-1+deb10u2"
344 | source_package: e2fsprogs
345 | status: ii
346 | - package: libcryptsetup12
347 | architecture: arm64
348 | version: "2:2.1.0-5+deb10u2"
349 | source_package: cryptsetup
350 | status: ii
351 | - package: libdb5.3
352 | architecture: arm64
353 | version: "5.3.28+dfsg1-0.5"
354 | source_package: db5.3
355 | status: ii
356 | - package: libdbus-1-3
357 | architecture: arm64
358 | version: "1.12.16-1"
359 | source_package: dbus
360 | status: ii
361 | - package: libdebconfclient0
362 | architecture: arm64
363 | version: "0.249"
364 | source_package: cdebconf
365 | status: ii
366 | - package: libdevmapper1.02.1
367 | architecture: arm64
368 | version: "2:1.02.155-3"
369 | source_package: lvm2
370 | status: ii
371 | - package: libdns-export1104
372 | architecture: arm64
373 | version: "1:9.11.5.P4+dfsg-5.1"
374 | source_package: bind9
375 | status: ii
376 | - package: libedit2
377 | architecture: arm64
378 | version: "3.1-20181209-1"
379 | source_package: libedit
380 | status: ii
381 | - package: libelf1
382 | architecture: arm64
383 | version: "0.176-1.1"
384 | source_package: elfutils
385 | status: ii
386 | - package: libexpat1
387 | architecture: arm64
388 | version: "2.2.6-2+deb10u1"
389 | source_package: expat
390 | status: ii
391 | - package: libext2fs2
392 | architecture: arm64
393 | version: "1.44.5-1+deb10u2"
394 | source_package: e2fsprogs
395 | status: ii
396 | - package: libfdisk1
397 | architecture: arm64
398 | version: "2.33.1-0.1"
399 | source_package: util-linux
400 | status: ii
401 | - package: libffi6
402 | architecture: arm64
403 | version: "3.2.1-9"
404 | source_package: libffi
405 | status: ii
406 | - package: libgcc1
407 | architecture: arm64
408 | version: "1:8.3.0-6"
409 | source_package: gcc-8
410 | status: ii
411 | - package: libgcrypt20
412 | architecture: arm64
413 | version: "1.8.4-5"
414 | source_package: libgcrypt20
415 | status: ii
416 | - package: libgmp10
417 | architecture: arm64
418 | version: "2:6.1.2+dfsg-4"
419 | source_package: gmp
420 | status: ii
421 | - package: libgnutls30
422 | architecture: arm64
423 | version: "3.6.7-4"
424 | source_package: gnutls28
425 | status: ii
426 | - package: libgpg-error0
427 | architecture: arm64
428 | version: "1.35-1"
429 | source_package: libgpg-error
430 | status: ii
431 | - package: libgssapi-krb5-2
432 | architecture: arm64
433 | version: "1.17-3"
434 | source_package: krb5
435 | status: ii
436 | - package: libhavege1
437 | architecture: arm64
438 | version: "1.9.1-7"
439 | source_package: haveged
440 | status: ii
441 | - package: libhogweed4
442 | architecture: arm64
443 | version: "3.4.1-1"
444 | source_package: nettle
445 | status: ii
446 | - package: libidn11
447 | architecture: arm64
448 | version: "1.33-2.2"
449 | source_package: libidn
450 | status: ii
451 | - package: libidn2-0
452 | architecture: arm64
453 | version: "2.0.5-1"
454 | source_package: libidn2
455 | status: ii
456 | - package: libip4tc0
457 | architecture: arm64
458 | version: "1.8.2-4"
459 | source_package: iptables
460 | status: ii
461 | - package: libisc-export1100
462 | architecture: arm64
463 | version: "1:9.11.5.P4+dfsg-5.1"
464 | source_package: bind9
465 | status: ii
466 | - package: libiw30
467 | architecture: arm64
468 | version: "30~pre9-13"
469 | source_package: wireless-tools
470 | status: ii
471 | - package: libjson-c3
472 | architecture: arm64
473 | version: "0.12.1+ds-2"
474 | source_package: json-c
475 | status: ii
476 | - package: libk5crypto3
477 | architecture: arm64
478 | version: "1.17-3"
479 | source_package: krb5
480 | status: ii
481 | - package: libkeyutils1
482 | architecture: arm64
483 | version: "1.6-6"
484 | source_package: keyutils
485 | status: ii
486 | - package: libklibc
487 | architecture: arm64
488 | version: "2.0.6-1"
489 | source_package: klibc
490 | status: ii
491 | - package: libkmod2
492 | architecture: arm64
493 | version: "26-1"
494 | source_package: kmod
495 | status: ii
496 | - package: libkrb5-3
497 | architecture: arm64
498 | version: "1.17-3"
499 | source_package: krb5
500 | status: ii
501 | - package: libkrb5support0
502 | architecture: arm64
503 | version: "1.17-3"
504 | source_package: krb5
505 | status: ii
506 | - package: libksba8
507 | architecture: arm64
508 | version: "1.3.5-2"
509 | source_package: libksba
510 | status: ii
511 | - package: libldap-2.4-2
512 | architecture: arm64
513 | version: "2.4.47+dfsg-3+deb10u1"
514 | source_package: openldap
515 | status: ii
516 | - package: libldap-common
517 | architecture: all
518 | version: "2.4.47+dfsg-3+deb10u1"
519 | source_package: openldap
520 | status: ii
521 | - package: liblz4-1
522 | architecture: arm64
523 | version: "1.8.3-1"
524 | source_package: lz4
525 | status: ii
526 | - package: liblzma5
527 | architecture: arm64
528 | version: "5.2.4-1"
529 | source_package: xz-utils
530 | status: ii
531 | - package: libmnl0
532 | architecture: arm64
533 | version: "1.0.4-2"
534 | source_package: libmnl
535 | status: ii
536 | - package: libmount1
537 | architecture: arm64
538 | version: "2.33.1-0.1"
539 | source_package: util-linux
540 | status: ii
541 | - package: libmpdec2
542 | architecture: arm64
543 | version: "2.4.2-2"
544 | source_package: mpdecimal
545 | status: ii
546 | - package: libncurses6
547 | architecture: arm64
548 | version: "6.1+20181013-2+deb10u2"
549 | source_package: ncurses
550 | status: ii
551 | - package: libncursesw6
552 | architecture: arm64
553 | version: "6.1+20181013-2+deb10u2"
554 | source_package: ncurses
555 | status: ii
556 | - package: libnettle6
557 | architecture: arm64
558 | version: "3.4.1-1"
559 | source_package: nettle
560 | status: ii
561 | - package: libnl-3-200
562 | architecture: arm64
563 | version: "3.4.0-1"
564 | source_package: libnl3
565 | status: ii
566 | - package: libnl-genl-3-200
567 | architecture: arm64
568 | version: "3.4.0-1"
569 | source_package: libnl3
570 | status: ii
571 | - package: libnl-route-3-200
572 | architecture: arm64
573 | version: "3.4.0-1"
574 | source_package: libnl3
575 | status: ii
576 | - package: libnpth0
577 | architecture: arm64
578 | version: "1.6-1"
579 | source_package: npth
580 | status: ii
581 | - package: libp11-kit0
582 | architecture: arm64
583 | version: "0.23.15-2"
584 | source_package: p11-kit
585 | status: ii
586 | - package: libpam-modules
587 | architecture: arm64
588 | version: "1.3.1-5"
589 | source_package: pam
590 | status: ii
591 | - package: libpam-modules-bin
592 | architecture: arm64
593 | version: "1.3.1-5"
594 | source_package: pam
595 | status: ii
596 | - package: libpam-runtime
597 | architecture: all
598 | version: "1.3.1-5"
599 | source_package: pam
600 | status: ii
601 | - package: libpam0g
602 | architecture: arm64
603 | version: "1.3.1-5"
604 | source_package: pam
605 | status: ii
606 | - package: libparted2
607 | architecture: arm64
608 | version: "3.2-25"
609 | source_package: parted
610 | status: ii
611 | - package: libpcre3
612 | architecture: arm64
613 | version: "2:8.39-12"
614 | source_package: pcre3
615 | status: ii
616 | - package: libpcsclite1
617 | architecture: arm64
618 | version: "1.8.24-1"
619 | source_package: pcsc-lite
620 | status: ii
621 | - package: libprocps7
622 | architecture: arm64
623 | version: "2:3.3.15-2"
624 | source_package: procps
625 | status: ii
626 | - package: libpython-stdlib
627 | architecture: arm64
628 | version: "2.7.16-1"
629 | source_package: python-defaults
630 | status: ii
631 | - package: libpython2-stdlib
632 | architecture: arm64
633 | version: "2.7.16-1"
634 | source_package: python-defaults
635 | status: ii
636 | - package: libpython2.7-minimal
637 | architecture: arm64
638 | version: "2.7.16-2+deb10u1"
639 | source_package: python2.7
640 | status: ii
641 | - package: libpython2.7-stdlib
642 | architecture: arm64
643 | version: "2.7.16-2+deb10u1"
644 | source_package: python2.7
645 | status: ii
646 | - package: libpython3-stdlib
647 | architecture: arm64
648 | version: "3.7.3-1"
649 | source_package: python3-defaults
650 | status: ii
651 | - package: libpython3.7-minimal
652 | architecture: arm64
653 | version: "3.7.3-2"
654 | source_package: python3.7
655 | status: ii
656 | - package: libpython3.7-stdlib
657 | architecture: arm64
658 | version: "3.7.3-2"
659 | source_package: python3.7
660 | status: ii
661 | - package: libreadline7
662 | architecture: arm64
663 | version: "7.0-5"
664 | source_package: readline
665 | status: ii
666 | - package: libsasl2-2
667 | architecture: arm64
668 | version: "2.1.27+dfsg-1"
669 | source_package: cyrus-sasl2
670 | status: ii
671 | - package: libsasl2-modules-db
672 | architecture: arm64
673 | version: "2.1.27+dfsg-1"
674 | source_package: cyrus-sasl2
675 | status: ii
676 | - package: libseccomp2
677 | architecture: arm64
678 | version: "2.3.3-4"
679 | source_package: libseccomp
680 | status: ii
681 | - package: libselinux1
682 | architecture: arm64
683 | version: "2.8-1+b1"
684 | source_package: libselinux
685 | status: ii
686 | - package: libsemanage-common
687 | architecture: all
688 | version: "2.8-2"
689 | source_package: libsemanage
690 | status: ii
691 | - package: libsemanage1
692 | architecture: arm64
693 | version: "2.8-2"
694 | source_package: libsemanage
695 | status: ii
696 | - package: libsepol1
697 | architecture: arm64
698 | version: "2.8-1"
699 | source_package: libsepol
700 | status: ii
701 | - package: libsmartcols1
702 | architecture: arm64
703 | version: "2.33.1-0.1"
704 | source_package: util-linux
705 | status: ii
706 | - package: libsqlite3-0
707 | architecture: arm64
708 | version: "3.27.2-3"
709 | source_package: sqlite3
710 | status: ii
711 | - package: libss2
712 | architecture: arm64
713 | version: "1.44.5-1+deb10u2"
714 | source_package: e2fsprogs
715 | status: ii
716 | - package: libssl1.1
717 | architecture: arm64
718 | version: "1.1.1d-0+deb10u2"
719 | source_package: openssl
720 | status: ii
721 | - package: libstdc++6
722 | architecture: arm64
723 | version: "8.3.0-6"
724 | source_package: gcc-8
725 | status: ii
726 | - package: libsystemd0
727 | architecture: arm64
728 | version: "241-7~deb10u2"
729 | source_package: systemd
730 | status: ii
731 | - package: libtasn1-6
732 | architecture: arm64
733 | version: "4.13-3"
734 | source_package: libtasn1-6
735 | status: ii
736 | - package: libtinfo6
737 | architecture: arm64
738 | version: "6.1+20181013-2+deb10u2"
739 | source_package: ncurses
740 | status: ii
741 | - package: libudev1
742 | architecture: arm64
743 | version: "241-7~deb10u2"
744 | source_package: systemd
745 | status: ii
746 | - package: libunistring2
747 | architecture: arm64
748 | version: "0.9.10-1"
749 | source_package: libunistring
750 | status: ii
751 | - package: libuuid1
752 | architecture: arm64
753 | version: "2.33.1-0.1"
754 | source_package: util-linux
755 | status: ii
756 | - package: libwrap0
757 | architecture: arm64
758 | version: "7.6.q-28"
759 | source_package: tcp-wrappers
760 | status: ii
761 | - package: libxtables12
762 | architecture: arm64
763 | version: "1.8.2-4"
764 | source_package: iptables
765 | status: ii
766 | - package: libzstd1
767 | architecture: arm64
768 | version: "1.3.8+dfsg-3"
769 | source_package: libzstd
770 | status: ii
771 | - package: linux-base
772 | architecture: all
773 | version: "4.6"
774 | source_package: linux-base
775 | status: ii
776 | - package: linux-image-4.19.93-v8+
777 | architecture: arm64
778 | version: "4.19.93-v8+-1"
779 | source_package: linux-4.19.93-v8+
780 | status: ii
781 | - package: login
782 | architecture: arm64
783 | version: "1:4.5-1.1"
784 | source_package: shadow
785 | status: ii
786 | - package: lsb-base
787 | architecture: all
788 | version: "10.2019051400"
789 | source_package: lsb
790 | status: ii
791 | - package: lsb-release
792 | architecture: all
793 | version: "10.2019051400"
794 | source_package: lsb
795 | status: ii
796 | - package: mawk
797 | architecture: arm64
798 | version: "1.3.3-17+b3"
799 | source_package: mawk
800 | status: ii
801 | - package: mender-client
802 | architecture: arm64
803 | version: "1.7.0-4+b12"
804 | source_package: mender-client
805 | status: ii
806 | - package: mime-support
807 | architecture: all
808 | version: "3.62"
809 | source_package: mime-support
810 | status: ii
811 | - package: mount
812 | architecture: arm64
813 | version: "2.33.1-0.1"
814 | source_package: util-linux
815 | status: ii
816 | - package: ncurses-base
817 | architecture: all
818 | version: "6.1+20181013-2+deb10u2"
819 | source_package: ncurses
820 | status: ii
821 | - package: ncurses-bin
822 | architecture: arm64
823 | version: "6.1+20181013-2+deb10u2"
824 | source_package: ncurses
825 | status: ii
826 | - package: net-tools
827 | architecture: arm64
828 | version: "1.60+git20180626.aebd88e-1"
829 | source_package: net-tools
830 | status: ii
831 | - package: netbase
832 | architecture: all
833 | version: "5.6"
834 | source_package: netbase
835 | status: ii
836 | - package: openssh-client
837 | architecture: arm64
838 | version: "1:7.9p1-10+deb10u1"
839 | source_package: openssh
840 | status: ii
841 | - package: openssh-server
842 | architecture: arm64
843 | version: "1:7.9p1-10+deb10u1"
844 | source_package: openssh
845 | status: ii
846 | - package: openssh-sftp-server
847 | architecture: arm64
848 | version: "1:7.9p1-10+deb10u1"
849 | source_package: openssh
850 | status: ii
851 | - package: openssl
852 | architecture: arm64
853 | version: "1.1.1d-0+deb10u2"
854 | source_package: openssl
855 | status: ii
856 | - package: parted
857 | architecture: arm64
858 | version: "3.2-25"
859 | source_package: parted
860 | status: ii
861 | - package: passwd
862 | architecture: arm64
863 | version: "1:4.5-1.1"
864 | source_package: shadow
865 | status: ii
866 | - package: perl-base
867 | architecture: arm64
868 | version: "5.28.1-6"
869 | source_package: perl
870 | status: ii
871 | - package: pinentry-curses
872 | architecture: arm64
873 | version: "1.1.0-2"
874 | source_package: pinentry
875 | status: ii
876 | - package: procps
877 | architecture: arm64
878 | version: "2:3.3.15-2"
879 | source_package: procps
880 | status: ii
881 | - package: python
882 | architecture: arm64
883 | version: "2.7.16-1"
884 | source_package: python-defaults
885 | status: ii
886 | - package: python-apt
887 | architecture: arm64
888 | version: "1.8.4"
889 | source_package: python-apt
890 | status: ii
891 | - package: python-apt-common
892 | architecture: all
893 | version: "1.8.4"
894 | source_package: python-apt
895 | status: ii
896 | - package: python-minimal
897 | architecture: arm64
898 | version: "2.7.16-1"
899 | source_package: python-defaults
900 | status: ii
901 | - package: python2
902 | architecture: arm64
903 | version: "2.7.16-1"
904 | source_package: python-defaults
905 | status: ii
906 | - package: python2-minimal
907 | architecture: arm64
908 | version: "2.7.16-1"
909 | source_package: python-defaults
910 | status: ii
911 | - package: python2.7
912 | architecture: arm64
913 | version: "2.7.16-2+deb10u1"
914 | source_package: python2.7
915 | status: ii
916 | - package: python2.7-minimal
917 | architecture: arm64
918 | version: "2.7.16-2+deb10u1"
919 | source_package: python2.7
920 | status: ii
921 | - package: python3
922 | architecture: arm64
923 | version: "3.7.3-1"
924 | source_package: python3-defaults
925 | status: ii
926 | - package: python3-minimal
927 | architecture: arm64
928 | version: "3.7.3-1"
929 | source_package: python3-defaults
930 | status: ii
931 | - package: python3.7
932 | architecture: arm64
933 | version: "3.7.3-2"
934 | source_package: python3.7
935 | status: ii
936 | - package: python3.7-minimal
937 | architecture: arm64
938 | version: "3.7.3-2"
939 | source_package: python3.7
940 | status: ii
941 | - package: readline-common
942 | architecture: all
943 | version: "7.0-5"
944 | source_package: readline
945 | status: ii
946 | - package: resolvconf
947 | architecture: all
948 | version: "1.79"
949 | source_package: resolvconf
950 | status: ii
951 | - package: sed
952 | architecture: arm64
953 | version: "4.7-1"
954 | source_package: sed
955 | status: ii
956 | - package: sensible-utils
957 | architecture: all
958 | version: "0.0.12"
959 | source_package: sensible-utils
960 | status: ii
961 | - package: sudo
962 | architecture: arm64
963 | version: "1.8.27-1+deb10u1"
964 | source_package: sudo
965 | status: ii
966 | - package: systemd
967 | architecture: arm64
968 | version: "241-7~deb10u2"
969 | source_package: systemd
970 | status: ii
971 | - package: systemd-sysv
972 | architecture: arm64
973 | version: "241-7~deb10u2"
974 | source_package: systemd
975 | status: ii
976 | - package: sysvinit-utils
977 | architecture: arm64
978 | version: "2.93-8"
979 | source_package: sysvinit
980 | status: ii
981 | - package: tar
982 | architecture: arm64
983 | version: "1.30+dfsg-6"
984 | source_package: tar
985 | status: ii
986 | - package: tzdata
987 | architecture: all
988 | version: "2019c-0+deb10u1"
989 | source_package: tzdata
990 | status: ii
991 | - package: u-boot-tools
992 | architecture: arm64
993 | version: "2019.01+dfsg-7"
994 | source_package: u-boot
995 | status: ii
996 | - package: ucf
997 | architecture: all
998 | version: "3.0038+nmu1"
999 | source_package: ucf
1000 | status: ii
1001 | - package: udev
1002 | architecture: arm64
1003 | version: "241-7~deb10u2"
1004 | source_package: systemd
1005 | status: ii
1006 | - package: util-linux
1007 | architecture: arm64
1008 | version: "2.33.1-0.1"
1009 | source_package: util-linux
1010 | status: ii
1011 | - package: wireless-tools
1012 | architecture: arm64
1013 | version: "30~pre9-13"
1014 | source_package: wireless-tools
1015 | status: ii
1016 | - package: wpasupplicant
1017 | architecture: arm64
1018 | version: "2:2.7+git20190128+0c1e29f-6+deb10u1"
1019 | source_package: wpa
1020 | status: ii
1021 | - package: xz-utils
1022 | architecture: arm64
1023 | version: "5.2.4-1"
1024 | source_package: xz-utils
1025 | status: ii
1026 | - package: zlib1g
1027 | architecture: arm64
1028 | version: "1:1.2.11.dfsg-1"
1029 | source_package: zlib
1030 | status: ii
1031 |
--------------------------------------------------------------------------------
/configuration/mender/identity/mender-device-identity:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This identity script returns the MAC address of {{ 'end0' if mender_device_type in ['pi4-v3', 'pi5-v3'] else 'eth0' }} as the device identity.
4 |
5 | set -ue
6 |
7 | MAC_FILE=/sys/class/net/{{ 'end0' if mender_device_type in ['pi4-v3', 'pi5-v3'] else 'eth0' }}/address
8 |
9 | if [ ! -f "${MAC_FILE}" ]
10 | then
11 | >&2 echo "Error: ${MAC_FILE} not found!"
12 | exit 1
13 | fi
14 |
15 | echo "mac=$(cat ${MAC_FILE})"
16 |
--------------------------------------------------------------------------------
/configuration/mender/inventory/mender-inventory-bootloader-integration:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Tries to determine which type of bootloader integration has been used for the
4 | # running platform.
5 |
6 | if [ -d /boot/efi/EFI/BOOT/mender_grubenv1 ]; then
7 | case "$(uname -m)" in
8 | arm*|aarch*)
9 | echo mender_bootloader_integration=uboot_uefi_grub
10 | ;;
11 | *86*)
12 | echo mender_bootloader_integration=uefi_grub
13 | ;;
14 | *)
15 | echo mender_bootloader_integration=unknown_uefi_grub
16 | ;;
17 | esac
18 | elif [ -d /boot/grub/mender_grubenv1 ]; then
19 | case "$(uname -m)" in
20 | *86*)
21 | echo mender_bootloader_integration=bios_grub
22 | ;;
23 | *)
24 | echo mender_bootloader_integration=unknown_grub
25 | ;;
26 | esac
27 | elif [ -e /etc/fw_env.config ]; then
28 | echo mender_bootloader_integration=uboot
29 | elif [ -e /usr/share/mender/integration/pi-uboot ]; then
30 | echo mender_bootloader_integration=raspberry-pi
31 | else
32 | echo mender_bootloader_integration=unknown
33 | fi
34 | exit 0
35 |
--------------------------------------------------------------------------------
/configuration/mender/mender.yml:
--------------------------------------------------------------------------------
1 | ---
2 | mender_inventory_poll_interval_seconds: 600
3 | mender_retry_poll_interval_seconds: 30
4 | mender_server_url: https://hosted.mender.io
5 | mender_tenant_token: ""
6 | mender_update_poll_interval_seconds: 60
7 |
--------------------------------------------------------------------------------
/configuration/overlay/pi-cross-dev.global.yml:
--------------------------------------------------------------------------------
1 | general:
2 | parameters:
3 | edi_bootstrap_architecture: {{ edi_host_architecture }}
4 |
5 | playbooks:
6 | 100_os_setup:
7 | parameters:
8 | install_openssh_server: False
9 | authorize_current_user: False
10 | install_documentation: full
11 | translations_filter: ""
12 | target_is_bare_metal: False
13 | install_development_tools: True
14 | install_cross_development_tools: True
15 | cross_development_tools:
16 | - dpkg-cross
17 | - pkg-config
18 | - qemu-user-static
19 | - wget
20 | foreign_base_libraries:
21 | - libc6
22 | - libc6-dev
23 | - libc-dev
24 | - libglib2.0-dev
25 | - liblzma-dev
26 | - libmount-dev
27 | - libssl-dev
28 | - libstdc++6
29 | - linux-libc-dev
30 |
31 | postprocessing_commands:
32 | 100_timestamp:
33 | skip: True
34 | 200_buildah2rootfs:
35 | skip: True
36 | 200_buildah2image:
37 | path: postprocessing_commands/container_image/buildah2image.edi
38 | output:
39 | pp_podman_image_manifest:
40 | location: {{ edi_configuration_name }}_manifest
41 | type: path
42 | pp_podman_image:
43 | location: {{ edi_configuration_name }}-{{ edi_project_directory_hash }}:latest
44 | type: podman-image
45 | 300_rootfs2image:
46 | skip: True
47 | 400_mender:
48 | skip: True
49 | 500_documentation:
50 | skip: True
51 | 600_fully_named_artifacts:
52 | skip: True
53 |
--------------------------------------------------------------------------------
/configuration/overlay/pi2-gitops.global.yml:
--------------------------------------------------------------------------------
1 | general:
2 | parameters:
3 | mender_device_type: pi2
4 | edi_bootstrap_architecture: armhf
5 |
6 | playbooks:
7 | 100_os_setup:
8 | parameters:
9 | kernel_image: linux-image-armmp-lpae
10 | enable_gitops: True
11 |
--------------------------------------------------------------------------------
/configuration/overlay/pi2.global.yml:
--------------------------------------------------------------------------------
1 | general:
2 | parameters:
3 | mender_device_type: pi2
4 | edi_bootstrap_architecture: armhf
5 |
6 | playbooks:
7 | 100_os_setup:
8 | parameters:
9 | kernel_image: linux-image-armmp-lpae
10 |
--------------------------------------------------------------------------------
/configuration/overlay/pi3-gitops.global.yml:
--------------------------------------------------------------------------------
1 | general:
2 | parameters:
3 | mender_device_type: pi3-v3
4 | ebs_bootloader_type: "raspberry-pi"
5 | edi_bootstrap_architecture: arm64
6 | qemu_emulated_cpu: cortex-a57
7 |
8 | playbooks:
9 | 100_os_setup:
10 | parameters:
11 | ebs_template: boot.spec.rpi3.${DEBIAN_ARCHITECTURE}
12 | ebs_bootloader_directory: "/boot/image-kernel"
13 | kernel_image: linux-image-6.6.51-v8+
14 | enable_gitops: True
15 |
--------------------------------------------------------------------------------
/configuration/overlay/pi3.global.yml:
--------------------------------------------------------------------------------
1 | general:
2 | parameters:
3 | mender_device_type: pi3-v3
4 | ebs_bootloader_type: "raspberry-pi"
5 | edi_bootstrap_architecture: arm64
6 | qemu_emulated_cpu: cortex-a57
7 |
8 | playbooks:
9 | 100_os_setup:
10 | parameters:
11 | ebs_template: boot.spec.rpi3.${DEBIAN_ARCHITECTURE}
12 | ebs_bootloader_directory: "/boot/image-kernel"
13 | kernel_image: linux-image-6.6.51-v8+
14 |
15 |
--------------------------------------------------------------------------------
/configuration/overlay/pi4-gitops.global.yml:
--------------------------------------------------------------------------------
1 | general:
2 | parameters:
3 | mender_device_type: pi4-v3
4 | ebs_bootloader_type: "raspberry-pi"
5 | edi_bootstrap_architecture: arm64
6 | qemu_emulated_cpu: cortex-a57
7 |
8 | playbooks:
9 | 100_os_setup:
10 | parameters:
11 | ebs_template: boot.spec.rpi4.${DEBIAN_ARCHITECTURE}
12 | ebs_bootloader_directory: "/boot/image-kernel"
13 | kernel_image: linux-image-6.6.51-v8+
14 | enable_gitops: True
15 |
--------------------------------------------------------------------------------
/configuration/overlay/pi4.global.yml:
--------------------------------------------------------------------------------
1 | general:
2 | parameters:
3 | mender_device_type: pi4-v3
4 | ebs_bootloader_type: "raspberry-pi"
5 | edi_bootstrap_architecture: arm64
6 | qemu_emulated_cpu: cortex-a57
7 |
8 | playbooks:
9 | 100_os_setup:
10 | parameters:
11 | ebs_template: boot.spec.rpi4.${DEBIAN_ARCHITECTURE}
12 | ebs_bootloader_directory: "/boot/image-kernel"
13 | kernel_image: linux-image-6.6.51-v8+
14 |
15 |
--------------------------------------------------------------------------------
/configuration/overlay/pi5-gitops.global.yml:
--------------------------------------------------------------------------------
1 | general:
2 | parameters:
3 | mender_device_type: pi5-v3
4 | ebs_bootloader_type: "raspberry-pi"
5 | edi_bootstrap_architecture: arm64
6 | qemu_emulated_cpu: cortex-a57
7 |
8 | playbooks:
9 | 100_os_setup:
10 | parameters:
11 | ebs_template: boot.spec.rpi5.${DEBIAN_ARCHITECTURE}
12 | ebs_bootloader_directory: "/boot/image-kernel"
13 | kernel_image: linux-image-6.6.51-v8-16k+
14 | enable_gitops: True
15 |
--------------------------------------------------------------------------------
/configuration/overlay/pi5.global.yml:
--------------------------------------------------------------------------------
1 | general:
2 | parameters:
3 | mender_device_type: pi5-v3
4 | ebs_bootloader_type: "raspberry-pi"
5 | edi_bootstrap_architecture: arm64
6 | qemu_emulated_cpu: cortex-a57
7 |
8 | playbooks:
9 | 100_os_setup:
10 | parameters:
11 | ebs_template: boot.spec.rpi5.${DEBIAN_ARCHITECTURE}
12 | ebs_bootloader_directory: "/boot/image-kernel"
13 | kernel_image: linux-image-6.6.51-v8-16k+
14 |
--------------------------------------------------------------------------------
/docs/kernel_build.md:
--------------------------------------------------------------------------------
1 | # Kernel Build Instructions
2 |
3 | The kernel build for the Raspberry Pi 4 and 5 is documented
4 | [here](https://www.get-edi.io/Getting-Started-with-a-new-Embedded-System/#linux-kernel) and gets automatically done by
5 | [this workflow](https://github.com/lueschem/edi-ci-public/blob/main/.github/workflows/kernel-build-rpi.yml).
6 | The Pi 2 and Pi 3 kernels are standard Debian kernels.
7 |
--------------------------------------------------------------------------------
/docs/wifi_setup.md:
--------------------------------------------------------------------------------
1 | # WiFi Setup
2 |
3 | As the SSID and password for the WiFi connection are usually unknown during the image build, the WiFi interface (wlan0)
4 | is initially not configured.
5 |
6 | ## Initial Configuration
7 |
8 | It is recommended to configure the WiFi interface using NetworkManager. Please replace
9 | "SSID" and "PASSWORD" as required by your local wireless LAN setup and replace "CONNECTION-NAME" with
10 | a meaningful name:
11 |
12 | ```
13 | sudo nmcli radio wifi on
14 | sudo nmcli dev wifi con "SSID" password "PASSWORD" name "CONNECTION-NAME"
15 | ```
16 |
17 | ## Configuration Handling During a Mender Upgrade
18 |
19 | As the gateway might only be connected through WiFi it is essential that the WiFi connection gets re-established
20 | immediately after the OS upgrade. For this reason the NetworkManager connections get backed up to
21 | `/data/backup/NetworkManager` during a Mender based OS upgrade. The new OS image will then re-apply this
22 | NetworkManager connections.
23 |
--------------------------------------------------------------------------------
/pi-cross-dev.yml:
--------------------------------------------------------------------------------
1 | configuration/base/common.yml
--------------------------------------------------------------------------------
/pi2-gitops.yml:
--------------------------------------------------------------------------------
1 | configuration/base/common.yml
--------------------------------------------------------------------------------
/pi2.yml:
--------------------------------------------------------------------------------
1 | configuration/base/common.yml
--------------------------------------------------------------------------------
/pi3-gitops.yml:
--------------------------------------------------------------------------------
1 | configuration/base/common.yml
--------------------------------------------------------------------------------
/pi3.yml:
--------------------------------------------------------------------------------
1 | configuration/base/common.yml
--------------------------------------------------------------------------------
/pi4-gitops.yml:
--------------------------------------------------------------------------------
1 | configuration/base/common.yml
--------------------------------------------------------------------------------
/pi4.yml:
--------------------------------------------------------------------------------
1 | configuration/base/common.yml
--------------------------------------------------------------------------------
/pi5-gitops.yml:
--------------------------------------------------------------------------------
1 | configuration/base/common.yml
--------------------------------------------------------------------------------
/pi5.yml:
--------------------------------------------------------------------------------
1 | configuration/base/common.yml
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/collections/ansible_collections:
--------------------------------------------------------------------------------
1 | ../../../../submodules/ansible_collections/
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: all
3 | vars:
4 | apply_proxy_settings: True
5 | create_default_user: False
6 | install_openssh_server: False
7 | disable_ssh_password_authentication: True
8 | authorize_current_user: True
9 | ssh_pub_key_directory: '{{ edi_project_directory }}/ssh_pub_keys'
10 | install_documentation: full
11 | translations_filter: ""
12 | base_system_sources_list_template: ""
13 | kernel_image: linux-image-arm64
14 | ebs_template: boot.cmd.rpi.${DEBIAN_ARCHITECTURE}.multiboot
15 | ebs_bootloader_directory: "/boot"
16 | ebs_bootloader_type: "u-boot"
17 | mender_device_type: ToBeOverwrittenInConfigurationOverlay
18 | enable_gitops: False
19 | gitops_user_name: gitops
20 | gitops_user_group_name: gitops
21 | target_is_bare_metal: True
22 | install_development_tools: False
23 | install_cross_development_tools: False
24 | cross_architectures:
25 | - amd64
26 | - arm64
27 | - armhf
28 | regenerate_openssh_server_keys: True
29 | # revert proxy settings
30 | cleanup_proxy_settings: True
31 | document_build_setup: False
32 | document_installed_packages: False
33 | package_baseline_source_file: "{{ edi_project_directory }}/configuration/documentation/packages-baseline.yml"
34 | qemu_emulated_cpu: max
35 | environment:
36 | QEMU_CPU: "{{ qemu_emulated_cpu }}"
37 | roles:
38 | - role: get_edi_io.debian_setup.proxy_settings
39 | become: True
40 | become_user: root
41 | when: apply_proxy_settings
42 | - role: get_edi_io.debian_setup.apt_setup
43 | become: True
44 | become_user: root
45 | - role: get_edi_io.debian_setup.default_user
46 | become: True
47 | become_user: root
48 | when: create_default_user
49 | - role: get_edi_io.debian_setup.openssh_server
50 | become: True
51 | become_user: root
52 | when: install_openssh_server
53 | - role: repositories
54 | become: True
55 | become_user: root
56 | - role: bootloader
57 | become: True
58 | become_user: root
59 | when: target_is_bare_metal
60 | - role: essential_bare_metal_packages
61 | become: True
62 | become_user: root
63 | when: target_is_bare_metal
64 | - role: mender
65 | become: True
66 | become_user: root
67 | when: target_is_bare_metal
68 | - role: get_edi_io.debian_setup.gitops_user
69 | become: True
70 | become_user: root
71 | when: enable_gitops
72 | - role: get_edi_io.debian_setup.gitops_tools
73 | become: True
74 | become_user: root
75 | when: enable_gitops
76 | - role: get_edi_io.debian_setup.multiarch_support
77 | become: True
78 | become_user: root
79 | when: install_cross_development_tools
80 | - role: get_edi_io.debian_setup.development_tools
81 | become: True
82 | become_user: root
83 | when: install_development_tools or install_cross_development_tools
84 | - role: get_edi_io.debian_setup.openssh_server_keys
85 | become: True
86 | become_user: root
87 | when: regenerate_openssh_server_keys
88 | - role: get_edi_io.debian_setup.apt_cleanup
89 | become: True
90 | become_user: root
91 | - role: get_edi_io.debian_setup.proxy_settings
92 | become: True
93 | become_user: root
94 | vars:
95 | target_http_proxy: ""
96 | target_https_proxy: ""
97 | target_ftp_proxy: ""
98 | target_socks_proxy: ""
99 | target_no_proxy: ""
100 | when: cleanup_proxy_settings
101 | - role: get_edi_io.debian_setup.replace_temp_hostname
102 | become: True
103 | become_user: root
104 | - role: get_edi_io.debian_setup.document_artifact
105 | become: True
106 | become_user: root
107 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | uboot_env_size: '0x4000'
3 | bootloader_location: /boot/firmware
4 | bootloader_image_location: /boot/image-firmware
5 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/boot.scr.txt:
--------------------------------------------------------------------------------
1 | boot_scr_filesize=${filesize}
2 |
3 | # constant values
4 | setenv mender_boot_part_A 3
5 | setenv mender_boot_part_hex_A 3
6 | setenv mender_boot_part_B 4
7 | setenv mender_boot_part_hex_B 4
8 | setenv bootlimit 1
9 |
10 | # initialize and store variables on first boot
11 | if test "${edi_first_boot_done}" != "true"
12 | then
13 | echo "Going to write environment on first boot!"
14 | setenv bootcount 0
15 | setenv upgrade_available 0
16 | setenv mender_boot_part ${mender_boot_part_A}
17 | setenv mender_boot_part_hex ${mender_boot_part_hex_A}
18 | setenv edi_first_boot_done true
19 | saveenv
20 | fi
21 |
22 | if test ${upgrade_available} = 1
23 | then
24 | # mender will reset bootcount within EnableUpdatedPartition
25 | setexpr bootcount ${bootcount} + 1
26 | saveenv
27 | else
28 | setenv bootcount 0
29 | fi
30 |
31 | if test ${bootcount} -gt ${bootlimit}
32 | then
33 | echo "Switching back to previous setup due to hitting bootlimit!"
34 | if test ${mender_boot_part} = ${mender_boot_part_A}
35 | then
36 | setenv mender_boot_part ${mender_boot_part_B}
37 | setenv mender_boot_part_hex ${mender_boot_part_hex_B}
38 | else
39 | setenv mender_boot_part ${mender_boot_part_A}
40 | setenv mender_boot_part_hex ${mender_boot_part_hex_A}
41 | fi
42 | setenv upgrade_available 0
43 | saveenv
44 | fi
45 |
46 | setexpr secondary_scriptaddr ${scriptaddr} + ${boot_scr_filesize}
47 |
48 | setenv edi_mmc_device 0:${mender_boot_part_hex}
49 | setenv edi_root_device /dev/mmcblk0p${mender_boot_part}
50 |
51 | if ext4load mmc ${edi_mmc_device} ${secondary_scriptaddr} /boot/boot.scr
52 | then
53 | echo "Successfully loaded secondary boot script."
54 | else
55 | echo "Trying to reset an environment setup that does not match the current installation!"
56 | setenv edi_first_boot_done false
57 | saveenv
58 | # avoid busy reboot loop
59 | sleep 60
60 | reset
61 | fi
62 |
63 | source ${secondary_scriptaddr}
64 |
65 | if test ${upgrade_available} = 1
66 | then
67 | reset
68 | fi
69 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/cmdline.txt.u-boot:
--------------------------------------------------------------------------------
1 | dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/edi_root_device rw rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
2 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/config.txt.u-boot.arm64:
--------------------------------------------------------------------------------
1 | # Switch the CPU from ARMv7 into ARMv8 (aarch64) mode
2 | arm_64bit=1
3 |
4 | enable_uart=1
5 | disable_overscan=1
6 |
7 | kernel=u-boot.bin
8 |
9 | device_tree_address=0x2600000
10 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/config.txt.u-boot.armhf:
--------------------------------------------------------------------------------
1 | enable_uart=1
2 | disable_overscan=1
3 |
4 | kernel=u-boot.bin
5 |
6 | device_tree_address=0x2600000
7 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/generate-archives:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Small helper utility that creates Broadcom Raspberry Pi
4 | # and u-boot bootloader archives.
5 |
6 | set -o errexit
7 | set -o nounset
8 | set -o pipefail
9 |
10 | echo_usage()
11 | {
12 | echo "Usage: generate-archives BOOTLOADER_TYPE VERSION_LABEL"
13 | echo "Example: generate-archives raspberrypi 1.20180924"
14 | echo "Example: generate-archives u-boot v2019.10"
15 | }
16 |
17 | cleanup()
18 | {
19 | rm -rf ${TEMPDIR}
20 | }
21 |
22 | cleanup_and_error()
23 | {
24 | cleanup
25 | >&2 echo "Error: Abnormal script termination."
26 | }
27 |
28 | create_raspberrypi_archive()
29 | {
30 | echo "Going to create raspberrypi archive!"
31 | tar -xf "${UPSTREAM_ARCHIVE}" -C "${TEMPDIR}/"
32 |
33 | BOOTLOADER_FILES=( "bootcode.bin" "LICENCE.broadcom" "fixup_cd.dat" "start_cd.elf" "fixup.dat"
34 | "start_db.elf" "fixup_db.dat" "start.elf" "fixup_x.dat" "start_x.elf"
35 | "fixup4cd.dat" "fixup4.dat" "fixup4db.dat" "fixup4x.dat"
36 | "start4cd.elf" "start4db.elf" "start4.elf" "start4x.elf" )
37 |
38 | mkdir ${TEMPDIR}/output
39 | for file in "${BOOTLOADER_FILES[@]}"
40 | do
41 | cp "${TEMPDIR}/firmware-${VERSION_LABEL}/boot/${file}" "${TEMPDIR}/output"
42 | done
43 |
44 | echo "${VERSION_LABEL}" > "${TEMPDIR}/output/raspberrypi-bootloader.version"
45 |
46 | FINAL_ARCHIVE="${SCRIPTDIR}/raspberrypi-bootloader.tar.gz"
47 | tar -cf "${FINAL_ARCHIVE}" -C "${TEMPDIR}/output" "."
48 | echo "Successfully created ${FINAL_ARCHIVE}!"
49 | }
50 |
51 | create_u_boot_archive()
52 | {
53 | local ARCHITECTURE=$1
54 | local CONFIGURATION=$2
55 | local COMPILER_PREFIX=$3
56 | local RASPBERRY_PI_TYPE=$4
57 |
58 | echo "Going to create u-boot (${ARCHITECTURE}) archive!"
59 | WORKDIR="${TEMPDIR}/u-boot-${VERSION_LABEL#"v"}"
60 | rm -rf "${WORKDIR}"
61 |
62 | tar -xf "${UPSTREAM_ARCHIVE}" -C "${TEMPDIR}/"
63 |
64 | cd "${WORKDIR}"
65 | export CROSS_COMPILE="${COMPILER_PREFIX}"
66 |
67 | make "${CONFIGURATION}"
68 |
69 | make -j8
70 |
71 | mkdir -p ${TEMPDIR}/output/licenses.u-boot
72 | cp u-boot.bin ${TEMPDIR}/output
73 | cp Licenses/* ${TEMPDIR}/output/licenses.u-boot/
74 | echo "${VERSION_LABEL}" > "${TEMPDIR}/output/u-boot-bootloader.version"
75 |
76 | FINAL_ARCHIVE="${SCRIPTDIR}/u-boot-bootloader.${ARCHITECTURE}.${RASPBERRY_PI_TYPE}.tar.gz"
77 | tar -cf "${FINAL_ARCHIVE}" -C "${TEMPDIR}/output" "."
78 | echo "Successfully created ${FINAL_ARCHIVE}!"
79 | }
80 |
81 | if [[ "$#" -eq 1 && ( "$1" == "-h" || "$1" == "--help" ) ]]
82 | then
83 | echo_usage
84 | exit 0
85 | fi
86 |
87 | if [ "$#" -ne 2 ]
88 | then
89 | >&2 echo "Error: Illegal number of parameters."
90 | echo_usage
91 | exit 1
92 | fi
93 |
94 | if [[ $EUID -eq 0 ]]
95 | then
96 | >&2 echo "Error: Do not run this script as root."
97 | exit 1
98 | fi
99 |
100 | SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
101 | TEMPDIR="$(mktemp -p ${SCRIPTDIR} -d -t .tmp.XXXXXXXX)"
102 |
103 | trap cleanup_and_error EXIT
104 |
105 | BOOTLOADER_TYPE=$1
106 | VERSION_LABEL=$2
107 |
108 | if [[ "${BOOTLOADER_TYPE}" == "raspberrypi" ]]
109 | then
110 | ARCHIVE_URL="https://github.com/raspberrypi/firmware/archive/${VERSION_LABEL}.tar.gz"
111 | PROCESSING_INSTRUCTIONS=( "create_raspberrypi_archive" )
112 | elif [[ "${BOOTLOADER_TYPE}" == "u-boot" ]]
113 | then
114 | ARCHIVE_URL="https://github.com/u-boot/u-boot/archive/${VERSION_LABEL}.tar.gz"
115 | PROCESSING_INSTRUCTIONS=(
116 | "create_u_boot_archive armhf rpi_2_defconfig arm-linux-gnueabihf- pi2"
117 | "create_u_boot_archive armhf rpi_3_32b_defconfig arm-linux-gnueabihf- pi3"
118 | "create_u_boot_archive arm64 rpi_3_defconfig aarch64-linux-gnu- pi3"
119 | "create_u_boot_archive arm64 rpi_4_defconfig aarch64-linux-gnu- pi4"
120 | )
121 | else
122 | >&2 echo "Error: Unknown bootloader type ${BOOTLOADER_TYPE}."
123 | exit 1
124 | fi
125 |
126 | UPSTREAM_ARCHIVE="${SCRIPTDIR}/upstream-${BOOTLOADER_TYPE}-${VERSION_LABEL}.tar.gz"
127 | if [ ! -f "${UPSTREAM_ARCHIVE}" ]
128 | then
129 | wget -O "${UPSTREAM_ARCHIVE}" "${ARCHIVE_URL}"
130 | fi
131 |
132 | for item in "${PROCESSING_INSTRUCTIONS[@]}"
133 | do
134 | ${item}
135 | done
136 |
137 | cleanup
138 | trap - EXIT
139 |
140 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/raspberrypi-bootloader.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lueschem/edi-pi/4af84ad72adccf8736f5beaf3f772163d82b1c21/plugins/playbooks/os_setup/roles/bootloader/files/raspberrypi-bootloader.tar.gz
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/u-boot-bootloader.arm64.pi3.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lueschem/edi-pi/4af84ad72adccf8736f5beaf3f772163d82b1c21/plugins/playbooks/os_setup/roles/bootloader/files/u-boot-bootloader.arm64.pi3.tar.gz
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/u-boot-bootloader.arm64.pi4-v2.tar.gz:
--------------------------------------------------------------------------------
1 | u-boot-bootloader.arm64.pi4.tar.gz
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/u-boot-bootloader.arm64.pi4.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lueschem/edi-pi/4af84ad72adccf8736f5beaf3f772163d82b1c21/plugins/playbooks/os_setup/roles/bootloader/files/u-boot-bootloader.arm64.pi4.tar.gz
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/u-boot-bootloader.armhf.pi2.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lueschem/edi-pi/4af84ad72adccf8736f5beaf3f772163d82b1c21/plugins/playbooks/os_setup/roles/bootloader/files/u-boot-bootloader.armhf.pi2.tar.gz
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/files/u-boot-bootloader.armhf.pi3.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lueschem/edi-pi/4af84ad72adccf8736f5beaf3f772163d82b1c21/plugins/playbooks/os_setup/roles/bootloader/files/u-boot-bootloader.armhf.pi3.tar.gz
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Ensures edi-boot-shim config.d directory exists.
3 | file:
4 | path: /etc/edi-boot-shim/edi-boot-shim.cfg.d
5 | state: directory
6 |
7 | - name: Configure edi-boot-shim for multiboot.
8 | template:
9 | src: multiboot.cfg
10 | dest: /etc/edi-boot-shim/edi-boot-shim.cfg.d
11 |
12 | - name: Install edi-boot-shim.
13 | apt:
14 | name: edi-boot-shim
15 | install_recommends: no
16 |
17 | - name: Create boot firmware directory.
18 | file:
19 | path: "{{ bootloader_location }}"
20 | state: directory
21 |
22 | - name: Create boot firmware image directory.
23 | file:
24 | path: "{{ bootloader_image_location }}"
25 | state: directory
26 | when: ebs_bootloader_type == "raspberry-pi"
27 |
28 | - name: Setup boot configuration (u-boot).
29 | copy:
30 | src: config.txt.{{ ebs_bootloader_type }}.{{ edi_bootstrap_architecture }}
31 | dest: "{{ bootloader_location }}/config.txt"
32 | when: ebs_bootloader_type == "u-boot"
33 |
34 | - name: Setup boot configuration (raspberry-pi).
35 | template:
36 | src: config.txt.{{ ebs_bootloader_type }}.{{ edi_bootstrap_architecture }}
37 | dest: "{{ bootloader_image_location }}/config.txt"
38 | when: ebs_bootloader_type == "raspberry-pi"
39 |
40 | - name: Setup the kernel command line (u-boot).
41 | copy:
42 | src: cmdline.txt.{{ ebs_bootloader_type }}
43 | dest: "{{ bootloader_location }}/cmdline.txt"
44 | when: (mender_device_type in ["pi4", "pi4-v2", "pi4-v3", "pi5-v3"]) and ebs_bootloader_type == "u-boot"
45 |
46 | - name: Setup the kernel command line.
47 | template:
48 | src: cmdline.txt.{{ ebs_bootloader_type }}
49 | dest: "{{ bootloader_image_location }}/cmdline.txt"
50 | when: ebs_bootloader_type == "raspberry-pi"
51 |
52 | - name: Install the raspberrypi bootloader to the image location.
53 | unarchive:
54 | src: raspberrypi-bootloader.tar.gz
55 | dest: "{{ bootloader_image_location }}"
56 | owner: root
57 | group: root
58 | creates: "{{ bootloader_image_location }}/LICENCE.broadcom"
59 | when: ebs_bootloader_type == "raspberry-pi"
60 |
61 | - name: Install the raspberrypi bootloader to the final location.
62 | unarchive:
63 | src: raspberrypi-bootloader.tar.gz
64 | dest: "{{ bootloader_location }}"
65 | owner: root
66 | group: root
67 | creates: "{{ bootloader_location }}/LICENCE.broadcom"
68 | when: ebs_bootloader_type == "u-boot"
69 |
70 | - name: Install the u-boot bootloader.
71 | unarchive:
72 | src: u-boot-bootloader.{{ edi_bootstrap_architecture }}.{{ mender_device_type }}.tar.gz
73 | dest: "{{ bootloader_location }}"
74 | owner: root
75 | group: root
76 | creates: "{{ bootloader_location }}/u-boot.bin"
77 | when: ebs_bootloader_type == "u-boot"
78 |
79 | - name: Install u-boot tools.
80 | apt:
81 | name:
82 | - libubootenv-tool
83 | - u-boot-tools
84 | state: present
85 | install_recommends: no
86 | when: ebs_bootloader_type == "u-boot"
87 |
88 | - name: Copy the raw boot script to the boot folder.
89 | copy:
90 | src: boot.scr.txt
91 | dest: "{{ bootloader_location }}"
92 | when: ebs_bootloader_type == "u-boot"
93 |
94 | - name: Create boot script.
95 | command: mkimage -A arm -T script -O linux -d boot.scr.txt boot.scr
96 | args:
97 | chdir: "{{ bootloader_location }}"
98 | creates: "{{ bootloader_location }}/boot.scr"
99 | when: ebs_bootloader_type == "u-boot"
100 |
101 | - name: Create u-boot directory on data partition.
102 | file:
103 | path: /data/u-boot
104 | state: directory
105 | when: ebs_bootloader_type == "u-boot"
106 |
107 | - name: Configure u-boot-tools.
108 | template:
109 | src: fw_env.config
110 | dest: /data/u-boot
111 | when: ebs_bootloader_type == "u-boot"
112 |
113 | - name: Create symbolic link for the u-boot-tools config.
114 | file:
115 | src: "/data/u-boot/fw_env.config"
116 | dest: "/etc/fw_env.config"
117 | state: link
118 | when: ebs_bootloader_type == "u-boot"
119 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/templates/cmdline.txt.raspberry-pi:
--------------------------------------------------------------------------------
1 | dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p__ROOTFS_PARTITION__ rw rootfstype=ext4 elevator=deadline fsck.repair=yes panic=10 rootdelay=2{{ ' net.ifnames=0' if mender_device_type == 'pi3-v3' }}
2 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/templates/config.txt.raspberry-pi.arm64:
--------------------------------------------------------------------------------
1 | # For more options and information see
2 | # http://rptl.io/configtxt
3 | # Some settings may impact device functionality. See link above for details
4 |
5 | {% if mender_device_type == "pi3-v3" %}
6 | # needs to be 8.3 format and in top level folder
7 | start_file=p__ROOTFS_PARTITION__start.elf
8 | fixup_file=p__ROOTFS_PARTITION__fixup.dat
9 | {% elif mender_device_type == "pi4-v3" %}
10 | # needs to be 8.3 format and in top level folder
11 | start_file=p__ROOTFS_PARTITION__start4.elf
12 | fixup_file=p__ROOTFS_PARTITION__fixup4.dat
13 | {% endif %}
14 |
15 | # Uncomment some or all of these to enable the optional hardware interfaces
16 | #dtparam=i2c_arm=on
17 | #dtparam=i2s=on
18 | #dtparam=spi=on
19 |
20 | # Enable audio (loads snd_bcm2835)
21 | dtparam=audio=on
22 |
23 | # Enable DRM VC4 V3D driver
24 | dtoverlay=vc4-kms-v3d
25 | max_framebuffers=2
26 |
27 | # Don't have the firmware create an initial video= setting in cmdline.txt.
28 | # Use the kernel's default instead.
29 | disable_fw_kms_setup=1
30 |
31 | # Run in 64-bit mode
32 | arm_64bit=1
33 |
34 | enable_uart=1
35 |
36 | # Disable compensation for displays with overscan
37 | disable_overscan=1
38 |
39 | # Run as fast as firmware / board allows
40 | arm_boost=1
41 |
42 | kernel=vmlinuz
43 | os_prefix=p__ROOTFS_PARTITION__/
44 |
45 | [cm4]
46 | # Enable host mode on the 2711 built-in XHCI USB controller.
47 | # This line should be removed if the legacy DWC2 controller is required
48 | # (e.g. for USB device mode) or if USB support is not required.
49 | otg_mode=1
50 |
51 | [cm5]
52 | dtoverlay=dwc2,dr_mode=host
53 |
54 | [all]
55 |
56 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/templates/fw_env.config:
--------------------------------------------------------------------------------
1 | # environment on VFAT (a redundant storage in mmc would be more robust)
2 | {{ bootloader_location }}/uboot.env 0x0000 {{ uboot_env_size }}
3 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/bootloader/templates/multiboot.cfg:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # multiboot configuration
3 | # ----------------------------------------------------------------------------
4 |
5 | BOOTLOADER_TYPE="{{ ebs_bootloader_type }}"
6 |
7 | # Target location of the per partition boot script (boot.scr).
8 | # This location has to match the setup in the primary boot.scr.
9 | BOOTLOADER_DIRECTORY="{{ ebs_bootloader_directory }}"
10 |
11 | # This secondary boot script is on the same partition.
12 | CHECK_MOUNT=false
13 |
14 | # Use the multiboot template.
15 | BOOT_COMMAND_TEMPLATE="/etc/edi-boot-shim/{{ ebs_template }}"
16 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/essential_bare_metal_packages/files/85-systemd_networkd.preset:
--------------------------------------------------------------------------------
1 | disable systemd-networkd-wait-online.service
2 | disable systemd-networkd.service
3 | disable systemd-networkd.socket
4 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/essential_bare_metal_packages/files/95-wpa_supplicant.preset:
--------------------------------------------------------------------------------
1 | disable wpa_supplicant@.service
2 | disable wpa_supplicant-nl80211@.service
3 | disable wpa_supplicant-wired@.service
4 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/essential_bare_metal_packages/files/brcmfmac.conf:
--------------------------------------------------------------------------------
1 | options brcmfmac feature_disable=0x200000
2 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/essential_bare_metal_packages/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install packages that are essential for running on bare metal.
3 | apt:
4 | name: "{{ bare_metal_packages }}"
5 | state: present
6 | install_recommends: no
7 |
8 | - name: Install wpasupplicant on devices that have WiFi.
9 | apt:
10 | name: wpasupplicant
11 | state: present
12 | install_recommends: no
13 | when: mender_device_type != "pi2"
14 |
15 | - name: Preset unused wpa_supplicant and systemd-networkd services to disabled.
16 | copy:
17 | src: "{{ item }}"
18 | dest: /lib/systemd/system-preset/
19 | loop:
20 | - 95-wpa_supplicant.preset
21 | - 85-systemd_networkd.preset
22 |
23 | - name: Disable persistent logging to protect the eMMC/flash.
24 | file:
25 | path: /var/log/journal
26 | state: absent
27 |
28 | - name: Disable DUMP_OBSS on brcmfmac.
29 | copy:
30 | src: brcmfmac.conf
31 | dest: /etc/modprobe.d/
32 |
33 | - name: Create directory for edi-set-hostname customization.
34 | file:
35 | path: /etc/systemd/system/edi-set-hostname.service.d
36 | state: directory
37 | mode: 0755
38 |
39 | - name: Customize edi-set-hostname service.
40 | template:
41 | src: edi-set-hostname.override.conf
42 | dest: /etc/systemd/system/edi-set-hostname.service.d/override.conf
43 | mode: 0644
44 |
45 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/essential_bare_metal_packages/templates/edi-set-hostname.override.conf:
--------------------------------------------------------------------------------
1 | {% set network_interface = 'end0' if mender_device_type in ['pi4-v3', 'pi5-v3'] else 'eth0' %}
2 | [Unit]
3 | After=sys-subsystem-net-devices-{{ network_interface }}.device
4 | Wants=sys-subsystem-net-devices-{{ network_interface }}.device
5 |
6 | [Service]
7 | Environment="NETWORK_INTERFACE={{ network_interface }}"
8 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/essential_bare_metal_packages/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | bare_metal_packages:
3 | - edi-resize-rootfs
4 | - edi-set-hostname
5 | - firmware-brcm80211
6 | - haveged
7 | - iproute2
8 | - "{{ kernel_image }}"
9 | - kmod
10 | - network-manager
11 | - systemd-timesyncd
12 | - udev
13 |
14 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/defaults/main.yml:
--------------------------------------------------------------------------------
1 | mender_config_directory: "{{ edi_project_directory }}/configuration/mender"
2 |
3 | mender_inventory_poll_interval_seconds: 600
4 | mender_retry_poll_interval_seconds: 30
5 | mender_rootfs_part_a: /dev/mmcblk0p3
6 | mender_rootfs_part_b: /dev/mmcblk0p4
7 | mender_server_url: https://hosted.mender.io
8 | mender_tenant_token: ""
9 | mender_update_poll_interval_seconds: 60
10 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/files/05_mender_update:
--------------------------------------------------------------------------------
1 | # exclude some files we do not want to be provided by the mender-updated package
2 | path-exclude /etc/mender/artifact_info
3 | path-exclude /usr/share/mender/identity/mender-device-identity
4 | path-exclude /usr/share/mender/inventory/mender-inventory-bootloader-integration
5 | path-exclude /usr/share/mender/inventory/mender-inventory-geo
6 | path-exclude /usr/share/mender/modules/v3/rpm
7 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/files/empty.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/files/mender-io-archive-keyring.gpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lueschem/edi-pi/4af84ad72adccf8736f5beaf3f772163d82b1c21/plugins/playbooks/os_setup/roles/mender/files/mender-io-archive-keyring.gpg
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/files/override.conf:
--------------------------------------------------------------------------------
1 | [Service]
2 | Environment="PATH=/usr/share/mender/integration:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/files/pi-uboot:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # MIT License
4 | #
5 | # Copyright (c) 2024 Matthias Lüscher
6 | #
7 | # Permission is hereby granted, free of charge, to any person obtaining a copy
8 | # of this software and associated documentation files (the "Software"), to deal
9 | # in the Software without restriction, including without limitation the rights
10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | # copies of the Software, and to permit persons to whom the Software is
12 | # furnished to do so, subject to the following conditions:
13 | #
14 | # The above copyright notice and this permission notice shall be included in all
15 | # copies or substantial portions of the Software.
16 | #
17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | # SOFTWARE.
24 |
25 | set -o nounset
26 | set -o errexit
27 | set -o pipefail
28 |
29 | UBOOT_ENV_OVERLAY=/var/run/uboot-env-overlay
30 | CONFIG_TXT=/boot/firmware/config.txt
31 | TRYBOOT_TXT=/boot/firmware/tryboot.txt
32 |
33 | print_and_exit()
34 | {
35 | local TYPE=$1
36 | local MESSAGE=$2
37 | if [ "${TYPE}" == "ERROR" ] ; then
38 | >&2 echo "error: ${MESSAGE}"
39 | exit 1
40 | else
41 | echo "${MESSAGE}"
42 | exit 0
43 | fi
44 | }
45 |
46 | print_environment()
47 | {
48 | echo "mender_boot_part=${mender_boot_part}"
49 | echo "mender_boot_part_hex=${mender_boot_part_hex}"
50 | echo "upgrade_available=${upgrade_available}"
51 | echo "bootcount=${bootcount}"
52 | echo "mender_uboot_separator=${mender_uboot_separator}"
53 | echo "mender_check_saveenv_canary=0"
54 | }
55 |
56 | update_environment()
57 | {
58 | local SPLIT_NEEDED
59 | local key
60 | local value
61 | SPLIT_NEEDED=$(echo "${1}" | tr -dc '=' | wc -c)
62 |
63 | if [ "${SPLIT_NEEDED}" -eq 1 ]; then
64 | key=$(echo "${1}" | cut -d '=' -f 1)
65 | value=$(echo "${1}" | cut -d '=' -f 2)
66 | else
67 | key=${1}
68 | value=${2}
69 | fi
70 |
71 | case $key in
72 | mender_boot_part)
73 | mender_boot_part=${value}
74 | MENDER_BOOT_PART_UPDATED=1
75 | ;;
76 | mender_boot_part_hex)
77 | mender_boot_part_hex=${value}
78 | ;;
79 | upgrade_available)
80 | upgrade_available=${value}
81 | UPGRADE_AVAILABLE_UPDATED=1
82 | ;;
83 | bootcount)
84 | bootcount=${value}
85 | ;;
86 | mender_uboot_separator)
87 | mender_uboot_separator=${value}
88 | ;;
89 | *)
90 | print_and_exit "ERROR" "unsupported key ${key}"
91 | ;;
92 | esac
93 | }
94 |
95 | if [[ $EUID -ne 0 ]]; then
96 | print_and_exit "ERROR" "use root user to execute this script"
97 | fi
98 |
99 | CURRENT_BOOT_DEVICE=$(mount | sed -n 's|^/dev/\(.*\) on / .*|\1|p')
100 | if [ -z "${CURRENT_BOOT_DEVICE}" ] ; then
101 | print_and_exit "ERROR" "unable to detect root partition device"
102 | fi
103 |
104 | CURRENT_BOOT_PART=$(echo "${CURRENT_BOOT_DEVICE}" | grep -o '[1-9][0-9]*$')
105 | if [ -z "${CURRENT_BOOT_PART}" ] ; then
106 | print_and_exit "ERROR" "unable to extract partition number of ${CURRENT_BOOT_DEVICE}"
107 | fi
108 |
109 | COMMITTED_BOOT_PART=$(< "${CONFIG_TXT}" sed -n 's|^os_prefix=p\([[:digit:]]\)/$|\1|p')
110 | if [ -z "${COMMITTED_BOOT_PART}" ] ; then
111 | print_and_exit "ERROR" "unable to extract committed boot partition from ${CONFIG_TXT}"
112 | fi
113 |
114 | mender_boot_part=${CURRENT_BOOT_PART}
115 | mender_boot_part_hex=$(printf '%x\n' "${CURRENT_BOOT_PART}")
116 |
117 | if [[ ${CURRENT_BOOT_PART} -eq ${COMMITTED_BOOT_PART} ]]
118 | then
119 | upgrade_available=0
120 | else
121 | upgrade_available=1
122 | fi
123 |
124 | bootcount=1
125 | mender_uboot_separator=""
126 |
127 | if [[ -f "${UBOOT_ENV_OVERLAY}" ]]
128 | then
129 | source "${UBOOT_ENV_OVERLAY}"
130 | fi
131 |
132 | if [[ ${0} == *fw_printenv ]]
133 | then
134 | if [[ $# -eq 0 ]]
135 | then
136 | print_environment
137 | else
138 | for cli_arg in "$@"
139 | do
140 | print_environment | grep "^${cli_arg}=.*"
141 | done
142 | fi
143 | elif [[ ${0} == *fw_setenv ]]
144 | then
145 | MENDER_BOOT_PART_UPDATED=0
146 | UPGRADE_AVAILABLE_UPDATED=0
147 |
148 | if [[ $# -eq 0 ]]
149 | then
150 | print_and_exit "ERROR" "variable name missing"
151 | elif [[ $# -eq 1 ]] || [[ $# -eq 2 ]]
152 | then
153 | if [[ $1 == -s ]]
154 | then
155 | if [[ $# -ne 2 ]]
156 | then
157 | print_and_exit "ERROR" "missing script parameter"
158 | fi
159 |
160 | if [[ $2 == - ]]
161 | then
162 | SCRIPT=$(cat)
163 | else
164 | if [[ ! -f ${2} ]]
165 | then
166 | print_and_exit "ERROR" "file ${2} not found"
167 | fi
168 | SCRIPT=$(cat "${2}")
169 | fi
170 |
171 | while IFS= read -r line
172 | do
173 | read -r -a key_value_pair <<< "${line}"
174 |
175 | if [[ ${#key_value_pair[@]} -eq 2 ]]
176 | then
177 | update_environment "${key_value_pair[0]}" "${key_value_pair[1]}"
178 | elif [[ ${#key_value_pair[@]} -eq 1 ]]
179 | then
180 | update_environment "${key_value_pair[0]}" ""
181 | else
182 | print_and_exit "ERROR" "unsupported number of arguments in script"
183 | fi
184 | done <<< "${SCRIPT}"
185 | else
186 | if [[ $# -eq 2 ]]
187 | then
188 | update_environment "${1}" "${2}"
189 | else
190 | update_environment "${1}" ""
191 | fi
192 | fi
193 |
194 | if [[ ${MENDER_BOOT_PART_UPDATED} -eq 1 ]] && [[ ${UPGRADE_AVAILABLE_UPDATED} -eq 1 ]] && [[ ${bootcount} -eq 0 ]] && [[ ${upgrade_available} -eq 1 ]]
195 | then
196 | # mender install transaction
197 | if [[ ${CURRENT_BOOT_PART} -eq ${mender_boot_part} ]]
198 | then
199 | print_and_exit "ERROR" "invalid install transaction - new boot partition is equal to old boot partition"
200 | elif [[ ${COMMITTED_BOOT_PART} -eq ${mender_boot_part} ]]
201 | then
202 | print_and_exit "ERROR" "invalid install transaction - new boot partition is equal to committed boot partition"
203 | else
204 | : # nothing to do - boot partition will be setup by state script
205 | fi
206 | elif [[ ${MENDER_BOOT_PART_UPDATED} -eq 1 ]] && [[ ${UPGRADE_AVAILABLE_UPDATED} -eq 1 ]] && [[ ${upgrade_available} -eq 0 ]]
207 | then
208 | # mender rollback transaction
209 | # nothing to do - reboot will automatically boot into previously committed configuration
210 | :
211 | elif [[ ${MENDER_BOOT_PART_UPDATED} -eq 0 ]] && [[ ${UPGRADE_AVAILABLE_UPDATED} -eq 1 ]] && [[ ${upgrade_available} -eq 0 ]]
212 | then
213 | # mender commit transaction
214 | if [[ ${CURRENT_BOOT_PART} -eq ${COMMITTED_BOOT_PART} ]]
215 | then
216 | : # nothing to do - commit has already been done
217 | elif [[ ! -f "${TRYBOOT_TXT}" ]]
218 | then
219 | print_and_exit "ERROR" "missing file: ${TRYBOOT_TXT}"
220 | else
221 | mv ${TRYBOOT_TXT} ${CONFIG_TXT}
222 | fi
223 | fi
224 |
225 | print_environment > "${UBOOT_ENV_OVERLAY}"
226 | else
227 | print_and_exit "ERROR" "unsupported number of arguments"
228 | fi
229 | elif [[ ${0} == *reboot ]]
230 | then
231 | if [[ $# -ge 1 ]]
232 | then
233 | /usr/sbin/reboot "$@"
234 | elif [[ ${upgrade_available} -eq 1 ]] && [[ ${COMMITTED_BOOT_PART} -ne ${mender_boot_part} ]] && [[ ${bootcount} -eq 0 ]] && [[ -f "${TRYBOOT_TXT}" ]]
235 | then
236 | /usr/sbin/reboot '0 tryboot'
237 | else
238 | /usr/sbin/reboot
239 | fi
240 | fi
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Create mender directories on data partition.
3 | file:
4 | path: /data/{{ item }}
5 | state: directory
6 | loop:
7 | - mender
8 | - mender-monitor
9 |
10 | - name: Create symbolic links to the data partition.
11 | file:
12 | src: /data/{{ item }}
13 | dest: /var/lib/{{ item }}
14 | state: link
15 | loop:
16 | - mender
17 | - mender-monitor
18 |
19 | - name: Create directory for mender-configure configuration.
20 | file:
21 | dest: /var/lib/mender-configure
22 | state: directory
23 | mode: 0755
24 |
25 | - name: Add an empty mender-configure configuration.
26 | copy:
27 | src: empty.json
28 | dest: /var/lib/mender-configure/device-config.json
29 | mode: 0600
30 |
31 | - name: Mask some files that shall not be provided by the mender-update Debian package.
32 | copy:
33 | src: 05_mender_update
34 | dest: /etc/dpkg/dpkg.cfg.d/
35 |
36 | - name: Add Mender repository key.
37 | copy:
38 | src: mender-io-archive-keyring.gpg
39 | dest: /usr/share/keyrings/
40 | mode: 0644
41 |
42 | - name: Add mender repository to sources.list.d.
43 | template:
44 | src: mender-io.list
45 | dest: /etc/apt/sources.list.d/
46 |
47 | - name: Update apt cache.
48 | apt:
49 | update_cache: yes
50 |
51 | - name: Install mender-update, mender-flash, mender-connect, mender-configure and jq.
52 | apt:
53 | name:
54 | - mender-update
55 | - mender-flash
56 | - mender-connect
57 | - mender-configure
58 | - jq
59 | state: present
60 | install_recommends: no
61 |
62 | - name: Load project specific (customized) mender configuration.
63 | include_vars: "{{ item }}"
64 | with_first_found:
65 | - "{{ mender_config_directory }}/mender_custom.yml"
66 | - "{{ mender_config_directory }}/mender.yml"
67 |
68 | - name: Write mender main configuration.
69 | template:
70 | src: mender.conf
71 | dest: /etc/mender/
72 |
73 | - name: Write mender-connect configuration.
74 | template:
75 | src: mender-connect.conf
76 | dest: /etc/mender/
77 |
78 | - name: Configure the device type.
79 | template:
80 | src: device_type
81 | dest: /data/mender/device_type
82 |
83 | - name: Copy inventory scripts.
84 | copy:
85 | src: "{{ item }}"
86 | dest: /usr/share/mender/inventory/
87 | mode: 0755
88 | with_fileglob:
89 | - "{{ mender_config_directory }}/inventory/*"
90 |
91 | - name: Copy identity scripts.
92 | template:
93 | src: "{{ item }}"
94 | dest: /usr/share/mender/identity/
95 | mode: 0755
96 | with_fileglob:
97 | - "{{ mender_config_directory }}/identity/*"
98 |
99 | - name: Create various integration directories.
100 | file:
101 | path: "{{ item }}"
102 | state: directory
103 | with_items:
104 | - /usr/share/mender/integration
105 | - /etc/systemd/system/mender-updated.service.d
106 | when: ebs_bootloader_type == "raspberry-pi"
107 |
108 | - name: Make sure that the mender-updated service picks the modified reboot script.
109 | copy:
110 | src: override.conf
111 | dest: /etc/systemd/system/mender-updated.service.d/
112 | when: ebs_bootloader_type == "raspberry-pi"
113 |
114 | - name: Copy the bootloader integration script.
115 | copy:
116 | src: pi-uboot
117 | dest: /usr/share/mender/integration/
118 | mode: 0755
119 | when: ebs_bootloader_type == "raspberry-pi"
120 |
121 | - name: Create a symbolic link for the reboot command.
122 | file:
123 | src: /usr/share/mender/integration/pi-uboot
124 | dest: /usr/share/mender/integration/reboot
125 | state: link
126 | when: ebs_bootloader_type == "raspberry-pi"
127 |
128 | - name: Create symbolic links for fw_printenv and fw_setenv.
129 | file:
130 | src: /usr/share/mender/integration/pi-uboot
131 | dest: /usr/bin/{{ item }}
132 | state: link
133 | with_items:
134 | - fw_printenv
135 | - fw_setenv
136 | when: ebs_bootloader_type == "raspberry-pi"
137 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/templates/device_type:
--------------------------------------------------------------------------------
1 | device_type={{ mender_device_type }}-{{ edi_bootstrap_architecture }}
2 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/templates/mender-connect.conf:
--------------------------------------------------------------------------------
1 | {
2 | "ReconnectIntervalSeconds": 5,
3 | "SkipVerify": false,
4 | "Limits": {
5 | "Enabled": true,
6 | "FileTransfer": {
7 | "Chroot": "/home/{{ default_user_name }}",
8 | "OwnerGet": ["{{ default_user_name }}"],
9 | "GroupGet": ["{{ default_user_group_name }}"],
10 | "OwnerPut": "{{ default_user_name }}",
11 | "GroupPut": "{{ default_user_group_name }}",
12 | "MaxFileSize": 536870912,
13 | "FollowSymLinks": true,
14 | "AllowOverwrite": true,
15 | "RegularFilesOnly": true,
16 | "PreserveOwner": true,
17 | "PreserveGroup": true,
18 | "PreserveMode": true,
19 | "Counters": {
20 | "MaxBytesTxPerHour": 536870912,
21 | "MaxBytesRxPerHour": 536870912
22 | }
23 | }
24 | },
25 | "FileTransfer": {
26 | "Disable": false
27 | },
28 | "MenderClient": {
29 | "Disable": false
30 | },
31 | "PortForward": {
32 | "Disable": false
33 | },
34 | "ShellCommand": "/usr/bin/bash",
35 | "ShellArguments": [],
36 | "Sessions": {
37 | "ExpireAfterIdle": 3600,
38 | "MaxPerUser": 5,
39 | "StopExpired": false
40 | },
41 | "Terminal": {
42 | "Disable": false,
43 | "Height": 40,
44 | "Width": 80
45 | },
46 | "User": "{{ default_user_name }}"
47 | }
48 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/templates/mender-io.list:
--------------------------------------------------------------------------------
1 | #TODO: Readd mender repository once it is available for Debian trixie.
2 | #deb [arch={{ edi_bootstrap_architecture }} signed-by=/usr/share/keyrings/mender-io-archive-keyring.gpg] https://downloads.mender.io/repos/debian debian/{{ ansible_distribution_release }}/stable main
3 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/mender/templates/mender.conf:
--------------------------------------------------------------------------------
1 | {
2 | "InventoryPollIntervalSeconds": {{ mender_inventory_poll_interval_seconds }},
3 | "RetryPollIntervalSeconds": {{ mender_retry_poll_interval_seconds }},
4 | "RootfsPartA": "{{ mender_rootfs_part_a }}",
5 | "RootfsPartB": "{{ mender_rootfs_part_b }}",
6 | "ServerURL": "{{ mender_server_url }}",
7 | "TenantToken": "{{ mender_tenant_token }}",
8 | "UpdatePollIntervalSeconds": {{ mender_update_poll_interval_seconds }},
9 | "UpdateControlMapExpirationTimeSeconds": {{ mender_update_poll_interval_seconds * 2 }},
10 | "UpdateControlMapBootExpirationTimeSeconds": 600
11 | }
12 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/repositories/files/50-get-edi-io:
--------------------------------------------------------------------------------
1 | Package: *
2 | Pin: origin packagecloud.io
3 | Pin-Priority: 750
4 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/repositories/files/get-edi-io-archive-keyring.gpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lueschem/edi-pi/4af84ad72adccf8736f5beaf3f772163d82b1c21/plugins/playbooks/os_setup/roles/repositories/files/get-edi-io-archive-keyring.gpg
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/repositories/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Check Debian release compatibility.
3 | fail:
4 | msg: "Error: The playbooks can not be applied to the given target as the distribution release is incompatible!
5 | Only Debian {{ debian_distribution_release }} is currently supported!"
6 | when: ansible_distribution_release != debian_distribution_release
7 |
8 | - name: Install ca-certificates.
9 | apt:
10 | name: ca-certificates
11 | install_recommends: no
12 |
13 | - name: Add edi repository key.
14 | copy:
15 | src: get-edi-io-archive-keyring.gpg
16 | dest: /usr/share/keyrings/
17 | mode: 0644
18 |
19 | - name: Add edi repository.
20 | template:
21 | src: get-edi-io.list
22 | dest: /etc/apt/sources.list.d/get-edi-io.list
23 | mode: 0644
24 |
25 | # TODO: Remove preference as soon as packages are available directly from Mender or Debian.
26 | - name: Prefer packages from get-edi-io repository.
27 | copy:
28 | src: 50-get-edi-io
29 | dest: /etc/apt/preferences.d/
30 |
31 | - name: Update apt cache.
32 | apt:
33 | update_cache: yes
34 |
35 |
--------------------------------------------------------------------------------
/plugins/playbooks/os_setup/roles/repositories/templates/get-edi-io.list:
--------------------------------------------------------------------------------
1 | deb [signed-by=/usr/share/keyrings/get-edi-io-archive-keyring.gpg] https://packagecloud.io/get-edi/debian/debian/ {{ ansible_distribution_release }} main
2 | # deb-src [signed-by=/usr/share/keyrings/get-edi-io-archive-keyring.gpg] https://packagecloud.io/get-edi/debian/debian/ {{ ansible_distribution_release }} main
3 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/container_image/buildah2image.edi:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright (C) 2024 Matthias Luescher
4 | #
5 | # Authors:
6 | # Matthias Luescher
7 | #
8 | # This file is part of the edi project configuration.
9 | #
10 | # This script is free software: you can redistribute it and/or modify
11 | # it under the terms of the GNU Lesser General Public License as published by
12 | # the Free Software Foundation, either version 3 of the License, or
13 | # (at your option) any later version.
14 | #
15 | # This script is distributed in the hope that it will be useful,
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | # GNU Lesser General Public License for more details.
19 | #
20 | # You should have received a copy of the GNU Lesser General Public License
21 | # along with the edi project configuration. If not, see .
22 |
23 | set -o errexit
24 | set -o pipefail
25 | set -o nounset
26 |
27 | LOG_LEVEL="{{ edi_log_level }}"
28 | PODMAN_IMAGE="{{ pp_podman_image }}"
29 | BUILDAH_CONTAINER="{{ edi_project_container }}"
30 | PODMAN_IMAGE_MANIFEST="{{ pp_podman_image_manifest }}"
31 | DEBIAN_RELEASE="{{ debian_distribution_release }}"
32 | DEBIAN_ARCHITECTURE="{{ edi_bootstrap_architecture }}"
33 |
34 | if [ "${LOG_LEVEL}" == "DEBUG" ]; then
35 | set -x
36 | fi
37 |
38 | cat << EOF >> "${PODMAN_IMAGE_MANIFEST}"
39 | podman_image=${PODMAN_IMAGE}
40 | debian_architecture=${DEBIAN_ARCHITECTURE}
41 | debian_release=${DEBIAN_RELEASE}
42 | EOF
43 |
44 | buildah commit "${BUILDAH_CONTAINER}" "${PODMAN_IMAGE}"
45 |
46 | echo "********************************************************************************"
47 | echo " Hint: Use distrobox to launch a container."
48 | echo " Examples:"
49 | echo " distrobox create --image ${PODMAN_IMAGE} --name CONTAINER_NAME --unshare-all"
50 | echo " distrobox create --image ${PODMAN_IMAGE} --name CONTAINER_NAME --init --unshare-all --additional-packages \"systemd libpam-systemd\""
51 | echo "********************************************************************************"
52 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/documentation/write_doc:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright (C) 2020 Matthias Luescher
4 | #
5 | # Authors:
6 | # Matthias Luescher
7 | #
8 | # This file is part of the edi project configuration.
9 | #
10 | # This script is free software: you can redistribute it and/or modify
11 | # it under the terms of the GNU Lesser General Public License as published by
12 | # the Free Software Foundation, either version 3 of the License, or
13 | # (at your option) any later version.
14 | #
15 | # This script is distributed in the hope that it will be useful,
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | # GNU Lesser General Public License for more details.
19 | #
20 | # You should have received a copy of the GNU Lesser General Public License
21 | # along with the edi project configuration. If not, see .
22 |
23 | set -o errexit
24 | set -o pipefail
25 | set -o nounset
26 |
27 | print_usage()
28 | {
29 | cat <&2 echo -e "\033[91mError: ${MESSAGE}\033[0m"
49 | }
50 |
51 | print_error_and_exit()
52 | {
53 | local MESSAGE="${1}"
54 | print_error "${MESSAGE}"
55 | exit 1
56 | }
57 |
58 | unexpected_exit()
59 | {
60 | local TEMPDIR="${1}"
61 | print_error "Going to clean up after abnormal script termination."
62 | clean_up "${TEMPDIR}"
63 | trap - EXIT
64 | print_error_and_exit "Abnormal script termination."
65 | }
66 |
67 | clean_up()
68 | {
69 | local TEMPDIR="${1}"
70 | rm -rf "${TEMPDIR}"
71 | }
72 |
73 | if ! options=$(getopt -o p:r:a:i:o:c:hw: -l project:,release:,author:,input:,output:,config:,help,log: -- "$@")
74 | then
75 | print_usage
76 | print_error_and_exit "Invalid option."
77 | fi
78 | eval set -- "$options"
79 |
80 | PROJECT="missing-project"
81 | RELEASE="missing-release"
82 | AUTHOR="missing-author"
83 | RAW_INPUT="missing-input"
84 | RENDERED_OUTPUT="missing-output"
85 | CONFIG="missing-config"
86 | LOG_LEVEL="INFO"
87 |
88 | while true
89 | do
90 | case "${1}" in
91 | -h|--help) print_usage && exit 0;;
92 | -p|--project) PROJECT="${2}"; shift 2;;
93 | -r|--release) RELEASE="${2}"; shift 2;;
94 | -a|--author) AUTHOR="${2}"; shift 2;;
95 | -i|--input) RAW_INPUT="${2}"; shift 2;;
96 | -o|--output) RENDERED_OUTPUT="${2}"; shift 2;;
97 | -c|--config) CONFIG="${2}"; shift 2;;
98 | --log) LOG_LEVEL="${2}"; shift 2;;
99 | *) break ;;
100 | esac
101 | done
102 |
103 | if [ "${LOG_LEVEL}" == "DEBUG" ]; then
104 | set -x
105 | fi
106 |
107 | if [[ ${EUID} -eq 0 ]]; then
108 | print_error_and_exit "This script should not be run as root."
109 | fi
110 |
111 | if [ -d "${RENDERED_OUTPUT}" ]; then
112 | print_error_and_exit "The directory ${RENDERED_OUTPUT} already exists."
113 | fi
114 |
115 | mkdir -p "${RENDERED_OUTPUT}"
116 | trap 'unexpected_exit "${RENDERED_OUTPUT}"' EXIT
117 |
118 | cd "${RENDERED_OUTPUT}"
119 | sphinx-quickstart --quiet -p "${PROJECT}" -a "${AUTHOR}" -r "${RELEASE}"
120 | rm index.rst
121 | edi --log="${LOG_LEVEL}" documentation render "${RAW_INPUT}" "${RENDERED_OUTPUT}" "${CONFIG}"
122 |
123 | trap - EXIT
124 |
125 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/documentation/write_doc.edi:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o errexit
4 | set -o nounset
5 |
6 | source {{ pp_timestamp }}
7 |
8 | LOG_LEVEL="{{ edi_log_level }}"
9 | WORKDIR="{{ edi_work_directory }}"
10 |
11 | print_error()
12 | {
13 | local MESSAGE="${1}"
14 | >&2 echo -e "\033[91mError: ${MESSAGE}\033[0m"
15 | }
16 |
17 | print_error_and_exit()
18 | {
19 | local MESSAGE="${1}"
20 | print_error "${MESSAGE}"
21 | exit 1
22 | }
23 |
24 | unexpected_exit()
25 | {
26 | local TEMPDIR="${1}"
27 | print_error "Going to clean up after abnormal script termination."
28 | clean_up "${TEMPDIR}"
29 | trap - EXIT
30 | print_error_and_exit "Abnormal script termination."
31 | }
32 |
33 | clean_up()
34 | {
35 | local TEMPDIR="${1}"
36 | rm -rf "${TEMPDIR}"
37 | }
38 |
39 | if [ "${LOG_LEVEL}" == "DEBUG" ]; then
40 | set -x
41 | fi
42 |
43 | if [[ ${EUID} -eq 0 ]]; then
44 | print_error_and_exit "This script must not be run as root."
45 | fi
46 |
47 | TEMPDIR="$(mktemp -p ${WORKDIR} -d -t .tmp.XXXXXXXX)"
48 |
49 | trap "unexpected_exit ${TEMPDIR}" EXIT
50 |
51 | pushd "${TEMPDIR}" > /dev/null
52 | tar -xf "{{ pp_rootfs_archive }}" ./usr/share/doc
53 | popd > /dev/null
54 |
55 | {{ edi_current_plugin_directory }}/write_doc --project "{{ edi_configuration_name }}-{{ debian_distribution_release }}-{{ edi_bootstrap_architecture }}" --release "${BUILD_TIMESTAMP}" --author "{{ author }}" --input "${TEMPDIR}/usr/share/doc" --output "{{ pp_documentation }}" --config "{{ edi_project_directory }}/{{ edi_configuration_name }}.yml" --log "{{ edi_log_level }}"
56 |
57 | clean_up "${TEMPDIR}"
58 |
59 | trap - EXIT
60 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/fully_named_artifacts/create_full_names.edi:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o nounset
4 | set -o errexit
5 |
6 | source {{ pp_timestamp }}
7 |
8 | mkdir -p "{{ pp_fully_named_artifacts }}"
9 | ln -f "{{ pp_mender_artifact }}" "{{ pp_fully_named_artifacts }}/${BUILD_TIMESTAMP}_{{ edi_configuration_name }}-{{ debian_distribution_release }}-{{ edi_bootstrap_architecture }}.mender"
10 | ln -f "{{ pp_image }}" "{{ pp_fully_named_artifacts }}/${BUILD_TIMESTAMP}_{{ edi_configuration_name }}-{{ debian_distribution_release }}-{{ edi_bootstrap_architecture }}.img"
11 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/genimage/exclude-patterns:
--------------------------------------------------------------------------------
1 | ./usr/share/doc/*/changelog.Debian.gz
2 | ./usr/share/doc/*/changelog.gz
3 | ./run/*
4 | ./tmp/*
5 | ./var/cache/debconf/*
6 | ./var/cache/ldconfig/aux-cache
7 | ./var/log/apt/*
8 | ./var/log/alternatives.log
9 | ./var/log/dpkg.log
10 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/genimage/fstab:
--------------------------------------------------------------------------------
1 | # Custom fstab added by lxd2rootfs script.
2 | #
3 | /dev/root / ext4 rw 0 1
4 | /dev/mmcblk0p1 /boot/firmware vfat rw 0 2
5 | /dev/mmcblk0p2 /data ext4 defaults 0 0
6 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/genimage/genimage.cfg:
--------------------------------------------------------------------------------
1 | config {
2 | mkdosfs = "/sbin/mkdosfs"
3 | mke2fs = "/sbin/mke2fs"
4 | e2fsck = "/sbin/e2fsck"
5 | }
6 |
7 | image disk-image.img {
8 | hdimage {
9 | align = "1M"
10 | partition-table-type = "mbr"
11 | fill = "true"
12 | }
13 |
14 | partition boot {
15 | offset = "1M"
16 | partition-type = 0x0c
17 | image = "boot.fat32"
18 | bootable = "true"
19 | }
20 |
21 | partition data {
22 | partition-type = 0x83
23 | image = "data.ext4"
24 | }
25 |
26 | partition root {
27 | partition-type = 0x83
28 | image = "root.ext4"
29 | }
30 | }
31 |
32 | image boot.fat32 {
33 | name = "boot"
34 | vfat {
35 | label = "boot"
36 | }
37 | size = "128M"
38 | mountpoint = "/boot/firmware"
39 | }
40 |
41 | image data.ext4 {
42 | name = "data"
43 | ext4 {
44 | label = "data"
45 | use-mke2fs = "true"
46 | }
47 | size = "256M"
48 | mountpoint = "/data"
49 | }
50 |
51 | image root.ext4 {
52 | name = "root"
53 | ext4 {
54 | label = "root"
55 | use-mke2fs = "true"
56 | }
57 | size = "125%"
58 | mountpoint = "/"
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/genimage/hostname:
--------------------------------------------------------------------------------
1 | __HOSTNAME__
2 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/genimage/hosts:
--------------------------------------------------------------------------------
1 | 127.0.0.1 localhost
2 | 127.0.1.1 __HOSTNAME__
3 |
4 | # The following lines are desirable for IPv6 capable hosts
5 | ::1 ip6-localhost ip6-loopback
6 | fe00::0 ip6-localnet
7 | ff00::0 ip6-mcastprefix
8 | ff02::1 ip6-allnodes
9 | ff02::2 ip6-allrouters
10 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/genimage/rootfs2image.edi:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright (C) 2024 Matthias Luescher
4 | #
5 | # Authors:
6 | # Matthias Luescher
7 | #
8 | # This file is part of the edi project configuration.
9 | #
10 | # This script is free software: you can redistribute it and/or modify
11 | # it under the terms of the GNU Lesser General Public License as published by
12 | # the Free Software Foundation, either version 3 of the License, or
13 | # (at your option) any later version.
14 | #
15 | # This script is distributed in the hope that it will be useful,
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | # GNU Lesser General Public License for more details.
19 | #
20 | # You should have received a copy of the GNU Lesser General Public License
21 | # along with the edi project configuration. If not, see .
22 |
23 | set -o errexit
24 | set -o pipefail
25 | set -o nounset
26 |
27 | source "{{ pp_timestamp }}"
28 |
29 | LOG_LEVEL="{{ edi_log_level }}"
30 | INPUT_ARCHIVE="{{ pp_rootfs_archive }}"
31 | PLUGIN_DIRECTORY="{{ edi_current_plugin_directory }}"
32 | DISK_IMAGE="{{ pp_image }}"
33 | PARTITION_IMAGE="{{ pp_partition_image }}"
34 | WORKDIR="{{ edi_work_directory }}"
35 | HOSTNAME="{{ hostname }}"
36 | ARTIFACT_NAME="${BUILD_TIMESTAMP}-{{ edi_configuration_name }}-{{ debian_distribution_release }}-{{ edi_bootstrap_architecture }}"
37 | MENDER_DEVICE_TYPE="{{ mender_device_type }}"
38 |
39 | print_error()
40 | {
41 | local MESSAGE="${1}"
42 | >&2 echo -e "\033[91mError: ${MESSAGE}\033[0m"
43 | }
44 |
45 | print_error_and_exit()
46 | {
47 | local MESSAGE="${1}"
48 | print_error "${MESSAGE}"
49 | exit 1
50 | }
51 |
52 | unexpected_exit()
53 | {
54 | local TEMPDIR="${1}"
55 | print_error "Going to clean up after abnormal script termination."
56 | rm -rf "${TEMPDIR}"
57 | trap - EXIT
58 | print_error_and_exit "Abnormal script termination."
59 | }
60 |
61 | if [ "${LOG_LEVEL}" == "DEBUG" ]; then
62 | set -x
63 | fi
64 |
65 | if touch /etc/edi-fakeroot-check > /dev/null 2>&1; then
66 | print_error_and_exit "This script must not be run as real root - please use fakeroot."
67 | fi
68 |
69 | if [[ ${EUID} -ne 0 ]]; then
70 | print_error_and_exit "This script must be run using fakeroot."
71 | fi
72 |
73 | TEMPDIR="$(mktemp -p "${WORKDIR}" -d -t .tmp.XXXXXXXX)"
74 | trap "unexpected_exit ${TEMPDIR}" EXIT
75 |
76 | pushd "${TEMPDIR}" > /dev/null
77 |
78 | mkdir rootfs
79 |
80 | tar --numeric-owner --exclude-from "${PLUGIN_DIRECTORY}/exclude-patterns" -C rootfs/ -axf "${INPUT_ARCHIVE}"
81 |
82 | # Copy kernel, initrd and dtbs to firmware partition
83 | if [ -d "rootfs/boot/image-kernel" ]; then
84 | cp -r -L rootfs/boot/image-kernel rootfs/boot/firmware/p3
85 | sed -i "s@^BOOTLOADER_DIRECTORY=.*@BOOTLOADER_DIRECTORY=\"/boot/firmware/p3\"@" "rootfs/etc/edi-boot-shim/edi-boot-shim.cfg.d/multiboot.cfg"
86 | fi
87 |
88 | if [ -d "rootfs/boot/image-firmware" ]; then
89 | cp rootfs/boot/image-firmware/cmdline.txt rootfs/boot/firmware/p3/cmdline.txt
90 | sed -i 's@__ROOTFS_PARTITION__@3@' rootfs/boot/firmware/p3/cmdline.txt
91 | cp rootfs/boot/image-firmware/config.txt rootfs/boot/firmware/config.txt
92 | sed -i 's@__ROOTFS_PARTITION__@3@' rootfs/boot/firmware/config.txt
93 | if [ "${MENDER_DEVICE_TYPE}" == "pi3-v3" ]; then
94 | cp rootfs/boot/image-firmware/bootcode.bin rootfs/boot/firmware/bootcode.bin
95 | cp rootfs/boot/image-firmware/start.elf rootfs/boot/firmware/p3start.elf
96 | cp rootfs/boot/image-firmware/fixup.dat rootfs/boot/firmware/p3fixup.dat
97 | elif [ "${MENDER_DEVICE_TYPE}" == "pi4-v3" ]; then
98 | cp rootfs/boot/image-firmware/start4.elf rootfs/boot/firmware/p3start4.elf
99 | cp rootfs/boot/image-firmware/fixup4.dat rootfs/boot/firmware/p3fixup4.dat
100 | fi
101 | fi
102 |
103 | # Remove /etc/machine-id and /var/lib/dbus/machine-id (it should be unique for each system).
104 | rm rootfs/etc/machine-id
105 | rm rootfs/var/lib/dbus/machine-id
106 | # Add fstab.
107 | cp "${PLUGIN_DIRECTORY}/fstab" rootfs/etc/
108 |
109 | # Add artifact information to rootfs.
110 | mkdir -p "rootfs/etc/mender/"
111 | echo "artifact_name=${ARTIFACT_NAME}" > rootfs/etc/mender/artifact_info
112 |
113 | # Adjust hostname.
114 | cp "${PLUGIN_DIRECTORY}/hosts" rootfs/etc/
115 | chmod 0644 rootfs/etc/hosts
116 | sed -i "s@__HOSTNAME__@${HOSTNAME}@" rootfs/etc/hosts
117 | cp "${PLUGIN_DIRECTORY}/hostname" rootfs/etc/
118 | sed -i "s@__HOSTNAME__@${HOSTNAME}@" rootfs/etc/hostname
119 |
120 | genimage --rootpath rootfs --config "${PLUGIN_DIRECTORY}/genimage.cfg" --tmppath genimage-workdir
121 |
122 | popd > /dev/null
123 |
124 | mv "${TEMPDIR}/images/disk-image.img" "${DISK_IMAGE}"
125 | mv "${TEMPDIR}/images/root.ext4" "${PARTITION_IMAGE}"
126 |
127 | rm -rf "${TEMPDIR}"
128 | trap - EXIT
129 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/mender/ArtifactInstall_Enter_50_BootpartitionSetup:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # MIT License
4 | #
5 | # Copyright (c) 2021 Matthias Lüscher
6 | #
7 | # Permission is hereby granted, free of charge, to any person obtaining a copy
8 | # of this software and associated documentation files (the "Software"), to deal
9 | # in the Software without restriction, including without limitation the rights
10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | # copies of the Software, and to permit persons to whom the Software is
12 | # furnished to do so, subject to the following conditions:
13 | #
14 | # The above copyright notice and this permission notice shall be included in all
15 | # copies or substantial portions of the Software.
16 | #
17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | # SOFTWARE.
24 |
25 | set -o nounset
26 | set -o errexit
27 | set -o pipefail
28 |
29 | TRYBOOT_TXT=/boot/firmware/tryboot.txt
30 | NEXT_ROOT_MNT=""
31 | source /data/mender/device_type
32 |
33 | print_and_exit()
34 | {
35 | local TYPE=$1
36 | local MESSAGE=$2
37 | trap - EXIT
38 | if [ "${TYPE}" == "ERROR" ] ; then
39 | >&2 echo "error: ${MESSAGE}"
40 | exit 1
41 | else
42 | echo "${MESSAGE}"
43 | exit 0
44 | fi
45 | }
46 |
47 | trap_exit()
48 | {
49 | trap - EXIT
50 | if [[ -n "${NEXT_ROOT_MNT}" ]]
51 | then
52 | umount "${NEXT_ROOT_MNT}" || true
53 | fi
54 | >&2 echo "Error: Script ${0} failed!"
55 | exit 1
56 | }
57 |
58 | if [[ $EUID -ne 0 ]]; then
59 | print_and_exit "ERROR" "use root user to execute this script"
60 | fi
61 |
62 | trap "trap_exit" EXIT
63 |
64 | CURRENT_BOOT_DEVICE=$(mount | sed -n 's|^/dev/\(.*\) on / .*|\1|p')
65 | if [ -z "${CURRENT_BOOT_DEVICE}" ] ; then
66 | print_and_exit "ERROR" "unable to detect root partition device"
67 | fi
68 |
69 | CURRENT_BOOT_PART=$(echo "${CURRENT_BOOT_DEVICE}" | grep -o '[1-9][0-9]*$')
70 | if [ -z "${CURRENT_BOOT_PART}" ] ; then
71 | print_and_exit "ERROR" "unable to extract partition number of ${CURRENT_BOOT_DEVICE}"
72 | fi
73 |
74 | BOOT_PART_NUMBER_A=3
75 | BOOT_PART_NUMBER_B=4
76 |
77 | NEXT_BOOT_PART=""
78 |
79 | if [[ ${CURRENT_BOOT_PART} -eq ${BOOT_PART_NUMBER_A} ]]
80 | then
81 | NEXT_BOOT_PART=${BOOT_PART_NUMBER_B}
82 | elif [[ ${CURRENT_BOOT_PART} -eq ${BOOT_PART_NUMBER_B} ]]
83 | then
84 | NEXT_BOOT_PART=${BOOT_PART_NUMBER_A}
85 | else
86 | print_and_exit "ERROR" "unable to determine next boot partition number"
87 | fi
88 |
89 | NEXT_BOOT_FOLDER="/boot/firmware/p${NEXT_BOOT_PART}"
90 | NEXT_ROOT_MNT=$(mktemp -d -t next-root-XXXXXXXX --tmpdir=/tmp)
91 |
92 | mount "/dev/mmcblk0p${NEXT_BOOT_PART}" "${NEXT_ROOT_MNT}"
93 |
94 | rm -rf "${NEXT_BOOT_FOLDER}"
95 | cp -r -L "${NEXT_ROOT_MNT}/boot/image-kernel" "${NEXT_BOOT_FOLDER}"
96 | sed -i "s@^BOOTLOADER_DIRECTORY=.*@BOOTLOADER_DIRECTORY=\"/boot/firmware/p${NEXT_BOOT_PART}\"@" "${NEXT_ROOT_MNT}/etc/edi-boot-shim/edi-boot-shim.cfg.d/multiboot.cfg"
97 |
98 | cp "${NEXT_ROOT_MNT}/boot/image-firmware/cmdline.txt" "${NEXT_BOOT_FOLDER}/cmdline.txt"
99 | sed -i "s@__ROOTFS_PARTITION__@${NEXT_BOOT_PART}@" "${NEXT_BOOT_FOLDER}/cmdline.txt"
100 |
101 | if [ "${device_type}" == "pi3-v3-arm64" ]
102 | then
103 | cp "${NEXT_ROOT_MNT}/boot/image-firmware/start.elf" "/boot/firmware/p${NEXT_BOOT_PART}start.elf"
104 | cp "${NEXT_ROOT_MNT}/boot/image-firmware/fixup.dat" "/boot/firmware/p${NEXT_BOOT_PART}fixup.dat"
105 | elif [ "${device_type}" == "pi4-v3-arm64" ]
106 | then
107 | cp "${NEXT_ROOT_MNT}/boot/image-firmware/start4.elf" "/boot/firmware/p${NEXT_BOOT_PART}start4.elf"
108 | cp "${NEXT_ROOT_MNT}/boot/image-firmware/fixup4.dat" "/boot/firmware/p${NEXT_BOOT_PART}fixup4.dat"
109 | fi
110 |
111 | cp "${NEXT_ROOT_MNT}/boot/image-firmware/config.txt" "${TRYBOOT_TXT}"
112 | sed -i "s@__ROOTFS_PARTITION__@${NEXT_BOOT_PART}@" "${TRYBOOT_TXT}"
113 |
114 | umount "${NEXT_ROOT_MNT}"
115 |
116 | trap - EXIT
117 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/mender/ArtifactInstall_Leave_50_ConfigurationBackup:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o nounset
4 | set -o errexit
5 | set -o pipefail
6 |
7 | copy_configuration_files()
8 | {
9 | local src_folder=${1}
10 | local dst_folder=${2}
11 | shift 2
12 | local file_list=("$@")
13 |
14 | mkdir -p ${dst_folder}
15 |
16 | for config_file in "${file_list[@]}"
17 | do
18 | config_file_path="${src_folder}/${config_file}"
19 | if [ -e ${config_file_path} ]
20 | then
21 | cp -a ${config_file_path} ${dst_folder}/
22 | else
23 | log_message "Info: File ${config_file_path} does not exist."
24 | fi
25 | done
26 | }
27 |
28 | copy_configuration_folders()
29 | {
30 | local src_folder=${1}
31 | local dst_folder=${2}
32 | shift 2
33 | local folder_list=("$@")
34 |
35 | mkdir -p ${dst_folder}
36 |
37 | for config_folder in "${folder_list[@]}"
38 | do
39 | config_folder_path="${src_folder}/${config_folder}"
40 | if [ -e ${config_folder_path} ]
41 | then
42 | cp -a -r ${config_folder_path} ${dst_folder}/
43 | else
44 | log_message "Info: Folder ${config_folder_path} does not exist."
45 | fi
46 | done
47 | }
48 |
49 | log_message()
50 | {
51 | local message=${1}
52 |
53 | echo "${message}" >> ${backup_log_file_path}
54 | }
55 |
56 | print_error_and_exit()
57 | {
58 | >&2 echo "Error: Script ${0} failed!"
59 | exit 1
60 | }
61 |
62 | trap "print_error_and_exit" EXIT
63 |
64 | if [[ $EUID -ne 0 ]]
65 | then
66 | >&2 echo "Error: Please run this script as root."
67 | trap - EXIT
68 | exit 1
69 | fi
70 |
71 | backup_folder="/data/backup"
72 | backup_log_file_path="${backup_folder}/log"
73 |
74 | ssh_config_folder="/etc/ssh"
75 | ssh_backup_folder="${backup_folder}/ssh"
76 |
77 | ssh_host_key_file_list=(
78 | ssh_host_dsa_key
79 | ssh_host_dsa_key.pub
80 | ssh_host_ecdsa_key
81 | ssh_host_ecdsa_key.pub
82 | ssh_host_ed25519_key
83 | ssh_host_ed25519_key.pub
84 | ssh_host_rsa_key
85 | ssh_host_rsa_key.pub
86 | )
87 |
88 | network_manager_config_folder="/etc/NetworkManager"
89 | network_manager_backup_folder="${backup_folder}/NetworkManager"
90 |
91 | network_manager_backup_folder_list=(
92 | system-connections
93 | )
94 |
95 | if [[ ${0} == *ConfigurationBackup* ]]
96 | then
97 | # remove any old backup
98 | rm -rf ${backup_folder}
99 | mkdir -p ${backup_folder}
100 | log_message "*** backup - start ***"
101 |
102 | source /etc/mender/artifact_info
103 | log_message "performing backup on ${artifact_name}"
104 |
105 | log_message "+++ ssh host keys +++"
106 | copy_configuration_files ${ssh_config_folder} ${ssh_backup_folder} ${ssh_host_key_file_list[@]}
107 |
108 | log_message "+++ network manager connections +++"
109 | copy_configuration_folders ${network_manager_config_folder} ${network_manager_backup_folder} ${network_manager_backup_folder_list[@]}
110 |
111 | log_message "*** backup - end ***"
112 | elif [[ ${0} == *ConfigurationRestore* ]]
113 | then
114 | # make sure that the backup folder is present for logging
115 | mkdir -p ${backup_folder}
116 | log_message "*** restore - start ***"
117 |
118 | source /etc/mender/artifact_info
119 | log_message "performing restore on ${artifact_name}"
120 |
121 | # Note: ssh host keys will be restored by dedicated service script.
122 |
123 | log_message "+++ network manager connections +++"
124 | if dpkg -s network-manager > /dev/null 2>&1
125 | then
126 | systemctl stop NetworkManager
127 | copy_configuration_folders ${network_manager_backup_folder} ${network_manager_config_folder} ${network_manager_backup_folder_list[@]}
128 | systemctl start NetworkManager
129 | fi
130 |
131 | log_message "*** restore - end ***"
132 | fi
133 |
134 | trap - EXIT
135 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/mender/ArtifactReboot_Leave_50_ConfigurationRestore:
--------------------------------------------------------------------------------
1 | ArtifactInstall_Leave_50_ConfigurationBackup
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/mender/image2mender:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright (C) 2020 Matthias Luescher
4 | #
5 | # Authors:
6 | # Matthias Luescher
7 | #
8 | # This file is part of the edi project configuration.
9 | #
10 | # This script is free software: you can redistribute it and/or modify
11 | # it under the terms of the GNU Lesser General Public License as published by
12 | # the Free Software Foundation, either version 3 of the License, or
13 | # (at your option) any later version.
14 | #
15 | # This script is distributed in the hope that it will be useful,
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | # GNU Lesser General Public License for more details.
19 | #
20 | # You should have received a copy of the GNU Lesser General Public License
21 | # along with the edi project configuration. If not, see .
22 |
23 | set -o errexit
24 | set -o pipefail
25 | set -o nounset
26 |
27 | print_usage()
28 | {
29 | cat <&2 echo -e "\033[91mError: ${MESSAGE}\033[0m"
48 | }
49 |
50 | print_error_and_exit()
51 | {
52 | local MESSAGE="${1}"
53 | print_error "${MESSAGE}"
54 | exit 1
55 | }
56 |
57 | unexpected_exit()
58 | {
59 | print_error "Going to clean up after abnormal script termination."
60 | rm -f "${MENDER_ARTIFACT}"
61 | trap - EXIT
62 | print_error_and_exit "Abnormal script termination."
63 | }
64 |
65 | if ! options=$(getopt -o hi:o:a:t:b: -l help,log:,input:,output:,artifact:,type:,bootloader: -- "$@")
66 | then
67 | print_usage
68 | print_error_and_exit "Invalid option."
69 | fi
70 | eval set -- "$options"
71 |
72 | SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
73 | INPUT_IMAGE=""
74 | MENDER_ARTIFACT=""
75 | ARTIFACT_NAME=""
76 | DEVICE_TYPE=""
77 | LOG_LEVEL="INFO"
78 | BOOTLOADER=""
79 |
80 | while true
81 | do
82 | case "${1}" in
83 | -h|--help) print_usage && exit 0;;
84 | -i|--input) INPUT_IMAGE="${2}"; shift 2;;
85 | -o|--output) MENDER_ARTIFACT="${2}"; shift 2;;
86 | -a|--artifact) ARTIFACT_NAME="${2}"; shift 2;;
87 | -t|--type) DEVICE_TYPE="${2}"; shift 2;;
88 | -b|--bootloader) BOOTLOADER="${2}"; shift 2;;
89 | --log) LOG_LEVEL="${2}"; shift 2;;
90 | *) break ;;
91 | esac
92 | done
93 |
94 | if [ "${LOG_LEVEL}" == "DEBUG" ]; then
95 | set -x
96 | fi
97 |
98 | if [ -z "${INPUT_IMAGE}" ]
99 | then
100 | print_usage
101 | print_error_and_exit "Missing input image parameter."
102 | fi
103 |
104 | if [ -z "${MENDER_ARTIFACT}" ]
105 | then
106 | print_usage
107 | print_error_and_exit "Missing output artifact parameter."
108 | fi
109 |
110 | if [ -z "${DEVICE_TYPE}" ]
111 | then
112 | print_usage
113 | print_error_and_exit "Missing device type parameter."
114 | fi
115 |
116 | if [ -z "${BOOTLOADER}" ]
117 | then
118 | print_usage
119 | print_error_and_exit "Missing bootloader parameter."
120 | fi
121 |
122 | if ! which mender-artifact > /dev/null
123 | then
124 | print_error "Missing mender-artifact executable. Mender update artifact will not be built."
125 | # Ignore this error for now since the update image might not be needed for every use case.
126 | echo "Mender update artifact not built due to missing mender-artifact executable." >> "${MENDER_ARTIFACT}"
127 | exit 0
128 | fi
129 |
130 | if [ "${DEVICE_TYPE}" == "pi2-armhf" ]
131 | then
132 | COMPATIBLE_DEVICE=( "--device-type" "rpi-armhf" )
133 | elif [ "${DEVICE_TYPE}" == "pi3-armhf" ]
134 | then
135 | COMPATIBLE_DEVICE=( "--device-type" "rpi-armhf" )
136 | elif [ "${DEVICE_TYPE}" == "pi3-arm64" ]
137 | then
138 | COMPATIBLE_DEVICE=( "--device-type" "rpi-arm64" )
139 | else
140 | COMPATIBLE_DEVICE=()
141 | fi
142 |
143 | INPUT_OPTION="--file"
144 | MENDER_ARTIFACT_VERSION=$(mender-artifact --version)
145 | MENDER_ARTIFACT_MAJOR_VERSION=$(echo "${MENDER_ARTIFACT_VERSION}" | cut -d' ' -f 3 | cut -d'.' -f 1)
146 |
147 | if [[ ${MENDER_ARTIFACT_MAJOR_VERSION} -eq 2 ]]
148 | then
149 | INPUT_OPTION="--update"
150 | fi
151 |
152 | # Special treatment for the Debian buster mender-artifact package:
153 | if [[ ${MENDER_ARTIFACT_VERSION} == *"really2"* ]]
154 | then
155 | INPUT_OPTION="--update"
156 | fi
157 |
158 | BOOTPARTITION_SETUP_SCRIPT=()
159 | if [ "${BOOTLOADER}" == "raspberry-pi" ]
160 | then
161 | BOOTPARTITION_SETUP_SCRIPT=( "--script" "${SCRIPTDIR}/ArtifactInstall_Enter_50_BootpartitionSetup" )
162 | fi
163 |
164 | mender-artifact write rootfs-image --device-type "${DEVICE_TYPE}" "${COMPATIBLE_DEVICE[@]}" \
165 | --artifact-name "${ARTIFACT_NAME}" ${INPUT_OPTION} "${INPUT_IMAGE}" --version 3 \
166 | --script "${SCRIPTDIR}/ArtifactInstall_Leave_50_ConfigurationBackup" \
167 | --script "${SCRIPTDIR}/ArtifactReboot_Leave_50_ConfigurationRestore" \
168 | "${BOOTPARTITION_SETUP_SCRIPT[@]}" \
169 | --output-path "${MENDER_ARTIFACT}"
170 |
171 | trap - EXIT
172 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/mender/image2mender.edi:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o nounset
4 | set -o errexit
5 |
6 | source {{ pp_timestamp }}
7 |
8 | {{ edi_current_plugin_directory }}/image2mender --input {{ pp_partition_image }} --output {{ pp_mender_artifact }} --log {{ edi_log_level }} --artifact ${BUILD_TIMESTAMP}-{{ edi_configuration_name }}-{{ debian_distribution_release }}-{{ edi_bootstrap_architecture }} --type {{ mender_device_type }}-{{ edi_bootstrap_architecture }} --bootloader {{ ebs_bootloader_type }}
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/rootfs/buildah2rootfs.edi:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o errexit
4 | set -o nounset
5 | set -o pipefail
6 |
7 | WORKDIR="{{ edi_work_directory }}"
8 | CONTAINER_NAME="{{ edi_project_container }}"
9 | ROOTFS_ARCHIVE="{{ pp_rootfs_archive }}"
10 | LOG_LEVEL="{{ edi_log_level }}"
11 |
12 | print_error()
13 | {
14 | local MESSAGE="${1}"
15 | >&2 echo -e "\033[91mError: ${MESSAGE}\033[0m"
16 | }
17 |
18 | print_error_and_exit()
19 | {
20 | local MESSAGE="${1}"
21 | print_error "${MESSAGE}"
22 | exit 1
23 | }
24 |
25 | unexpected_exit()
26 | {
27 | local TEMPDIR="${1}"
28 | print_error "Going to clean up after abnormal script termination."
29 | clean_up "${TEMPDIR}"
30 | trap - EXIT
31 | print_error_and_exit "Abnormal script termination."
32 | }
33 |
34 | clean_up()
35 | {
36 | local TEMPDIR="${1}"
37 | rm -rf "${TEMPDIR}"
38 | }
39 |
40 | if [ "${LOG_LEVEL}" == "DEBUG" ]; then
41 | set -x
42 | fi
43 |
44 | if [[ ${EUID} -eq 0 ]]; then
45 | print_error_and_exit "This script must not be run as root."
46 | fi
47 |
48 | if ! buildah inspect "${CONTAINER_NAME}" > /dev/null 2>&1; then
49 | print_error_and_exit "The container ${CONTAINER_NAME} does not exist."
50 | fi
51 |
52 | TEMPDIR="$(mktemp -p ${WORKDIR} -d -t .tmp.XXXXXXXX)"
53 |
54 | trap "unexpected_exit ${TEMPDIR}" EXIT
55 |
56 | TEMP_ARCHIVE="${TEMPDIR}/archive.tar"
57 | NESTED_COMMAND="tar --numeric-owner -C "'"${container_root}"'" -acf ${TEMP_ARCHIVE} ."
58 | buildah unshare --mount container_root="${CONTAINER_NAME}" -- bash -c "${NESTED_COMMAND}"
59 |
60 | mv "${TEMP_ARCHIVE}" "${ROOTFS_ARCHIVE}"
61 |
62 | clean_up "${TEMPDIR}"
63 |
64 | trap - EXIT
65 |
66 |
--------------------------------------------------------------------------------
/plugins/postprocessing_commands/timestamp/timestamp.edi:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o errexit
4 | set -o nounset
5 |
6 | echo "BUILD_TIMESTAMP=$(date +'%Y-%m-%d-%H%M')" > {{ pp_timestamp }}
7 |
8 |
--------------------------------------------------------------------------------
/plugins/preprocessing_commands/bootstrap/mmdebstrap.edi:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o nounset
4 | set -o errexit
5 |
6 | LOG_LEVEL="{{ edi_log_level }}"
7 | ROOTFS_ARCHIVE="{{ edi_bootstrapped_rootfs }}"
8 | DISTRIBUTION_RELEASE="{{ debian_distribution_release }}"
9 | DEBIAN_ARCHITECTURE="{{ edi_bootstrap_architecture }}"
10 | WORKDIR="{{ edi_work_directory }}"
11 | QEMU_EMULATED_CPU="{{ qemu_emulated_cpu }}"
12 |
13 | print_error()
14 | {
15 | local MESSAGE="${1}"
16 | >&2 echo -e "\033[91mError: ${MESSAGE}\033[0m"
17 | }
18 |
19 | print_error_and_exit()
20 | {
21 | local MESSAGE="${1}"
22 | print_error "${MESSAGE}"
23 | exit 1
24 | }
25 |
26 | unexpected_exit()
27 | {
28 | local TEMPDIR="${1}"
29 | print_error "Going to clean up after abnormal script termination."
30 | rm -rf "${TEMPDIR}"
31 | trap - EXIT
32 | print_error_and_exit "Abnormal script termination."
33 | }
34 |
35 | if [ "${LOG_LEVEL}" == "DEBUG" ]; then
36 | set -x
37 | fi
38 |
39 | TEMPDIR="$(mktemp -p "${WORKDIR}" -d -t .tmp.XXXXXXXX)"
40 | trap "unexpected_exit ${TEMPDIR}" EXIT
41 |
42 | if [ ! -z "${QEMU_EMULATED_CPU}" ]; then
43 | export QEMU_CPU="${QEMU_EMULATED_CPU}"
44 | fi
45 |
46 | TEMP_ARCHIVE="${TEMPDIR}/archive.tar"
47 | mmdebstrap --include=python3-apt,sudo,systemd,systemd-sysv --arch="${DEBIAN_ARCHITECTURE}" --variant=minbase "${DISTRIBUTION_RELEASE}" "${TEMP_ARCHIVE}"
48 |
49 | mv "${TEMP_ARCHIVE}" "${ROOTFS_ARCHIVE}"
50 |
51 | rm -rf "${TEMPDIR}"
52 | trap - EXIT
53 |
--------------------------------------------------------------------------------
/plugins/preprocessing_commands/prerequisites/check_prerequisites:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o nounset
4 | set -o errexit
5 | set -o pipefail
6 |
7 | required_packages=(
8 | "ansible-core 2.14.16"
9 | "buildah 1.28.2"
10 | "mmdebstrap 1.3.5"
11 | )
12 |
13 | is_package_installed()
14 | {
15 | local package="${1}"
16 | # shellcheck disable=SC2091
17 | dpkg -s "${package}" > /dev/null 2>&1
18 | }
19 |
20 | version_greater_equal()
21 | {
22 | local lhs_version="${1}"
23 | local rhs_version="${2}"
24 | [ "$(echo -e "${lhs_version}\n${rhs_version}" | sort --reverse --version-sort | head -n 1)" == "${lhs_version}" ]
25 | }
26 |
27 | check_passed=0
28 |
29 | for item in "${required_packages[@]}"
30 | do
31 | IFS=' ' read -r package required_version <<< "${item}"
32 | if is_package_installed "${package}"
33 | then
34 | actual_version=$(dpkg-query --showformat='${Version}' --show "${package}")
35 | if version_greater_equal "${actual_version}" "${required_version}"
36 | then
37 | echo "${package} $actual_version: OK"
38 | else
39 | echo "${package} $actual_version: NOK"
40 | >&2 echo "Error: Package ${package} does not meet the version requirements (>= ${required_version})!"
41 | check_passed=1
42 | fi
43 | else
44 | echo "${package} (missing): NOK"
45 | >&2 echo "Error: Package ${package} is not installed!"
46 | check_passed=1
47 | fi
48 | done
49 |
50 | exit "${check_passed}"
51 |
--------------------------------------------------------------------------------
/plugins/preprocessing_commands/prerequisites/check_prerequisites.edi:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -o nounset
4 | set -o errexit
5 | set -o pipefail
6 |
7 | PLUGIN_DIRECTORY="{{ edi_current_plugin_directory }}"
8 | OUTPUT="{{ edi_prerequisites_log }}"
9 |
10 | if result=$("${PLUGIN_DIRECTORY}"/check_prerequisites)
11 | then
12 | echo "${result}" > "${OUTPUT}"
13 | exit 0
14 | else
15 | exit 1
16 | fi
--------------------------------------------------------------------------------
/ssh_pub_keys/README.txt:
--------------------------------------------------------------------------------
1 | All ssh public keys within this folder will be added to the authorized_keys
2 | file (/home/pi/.ssh/authorized_keys) of the pi user of the generated target
3 | system (container or OS image).
4 |
5 | This will then allow the corresponding people to have a convenient access
6 | to the target system using ssh (e.g. ssh pi@IP_OF_TARGET_SYSTEM).
7 |
8 | This is especially useful within a company setup where one employee (or a build
9 | server) generates the images and multiple other employees want to access the
10 | systems that are running those images in a secure way without sharing a static
11 | password.
12 |
13 | This folder of course will remain empty within this repository but you can do
14 | your private fork and add public keys there.
15 |
16 | The extension of the public key files must be .pub.
17 |
18 | Examples:
19 | coworker1_id_rsa.pub
20 | coworker2_id_rsa.pub
21 | ben.pub
22 | karl_id_rsa.pub
23 |
24 | For your convenience there is also a second mechanism in place that adds the public
25 | key of the user that generates the artifacts. This is part of the "base_system" Ansible
26 | playbook plugin (you can use "authorize_current_user: False" to turn this feature off).
27 | For more details please take a look at this documentation:
28 | https://docs.get-edi.io/en/latest/config_management/plugins.html
29 |
30 | For even more information please read this blog post:
31 | https://www.get-edi.io/Secure-by-Default-ssh-Setup/
32 |
33 | Please note that password based login via ssh is disabled by default within this
34 | edi project configuration.
35 |
--------------------------------------------------------------------------------