# pmbootstrap [**Introduction**](https://postmarketos.org/blog/2017/05/26/intro/) | [**Security Warning**](https://ollieparanoid.github.io/post/security-warning/) | [**Devices**](https://wiki.postmarketos.org/wiki/Devices) Sophisticated chroot/build/flash tool to develop and install [postmarketOS](https://postmarketos.org). Package build scripts live in the [`pmaports`](https://gitlab.com/postmarketOS/pmaports) repository now. ## Requirements * 2 GB of RAM recommended for compiling * Linux distribution on the host system (`x86`, `x86_64`, or `aarch64`) * [Windows subsystem for Linux (WSL)](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux) does **not** work! Please use [VirtualBox](https://www.virtualbox.org/) instead. * Kernels based on the grsec patchset [do **not** work](https://github.com/postmarketOS/pmbootstrap/issues/107) * [Linux kernel 3.17 or higher](https://postmarketos.org/oldkernel) * Python 3.6+ * OpenSSL * git ## Usage Examples Please refer to the [postmarketOS wiki](https://wiki.postmarketos.org) for in-depth coverage of topics such as [porting to a new device](https://wiki.postmarketos.org/wiki/Porting_to_a_new_device) or [installation](https://wiki.postmarketos.org/wiki/Installation_guide). The help output (`pmbootstrap -h`) has detailed usage instructions for every command. Read on for some generic examples of what can be done with `pmbootstrap`. ### Installing pmbootstrap ### Basics Initial setup: ``` $ pmbootstrap init ``` Run this in a second window to see all shell commands that get executed: ``` $ pmbootstrap log ``` Quick health check and config overview: ``` $ pmbootstrap status ``` ### Packages Build `aports/main/hello-world`: ``` $ pmbootstrap build hello-world ``` Cross-compile to `armhf`: ``` $ pmbootstrap build --arch=armhf hello-world ``` Build with source code from local folder: ``` $ pmbootstrap build linux-postmarketos-mainline --src=~/code/linux ``` Update checksums: ``` $ pmbootstrap checksum hello-world ``` Generate a template for a new package: ``` $ pmbootstrap newapkbuild "https://gitlab.com/postmarketOS/osk-sdl/-/archive/0.52/osk-sdl-0.52.tar.bz2" ``` ### Chroots Enter the `armhf` building chroot: ``` $ pmbootstrap chroot -b armhf ``` Run a command inside a chroot: ``` $ pmbootstrap chroot -- echo test ``` Safely delete all chroots: ``` $ pmbootstrap zap ``` ### Device Porting Assistance Analyze Android [`boot.img`](https://wiki.postmarketos.org/wiki/Glossary#boot.img) files (also works with recovery OS images like TWRP): ``` $ pmbootstrap bootimg_analyze ~/Downloads/twrp-3.2.1-0-fp2.img ``` Check kernel configs: ``` $ pmbootstrap kconfig check ``` Edit a kernel config: ``` $ pmbootstrap kconfig edit --arch=armhf postmarketos-mainline ``` ### Root File System Build the rootfs: ``` $ pmbootstrap install ``` Build the rootfs with full disk encryption: ``` $ pmbootstrap install --fde ``` Update existing installation on SD card: ``` $ pmbootstrap install --sdcard=/dev/mmcblk0 --rsync ``` Run the image in QEMU: ``` $ pmbootstrap qemu --image-size=1G ``` Flash to the device: ``` $ pmbootstrap flasher flash_kernel $ pmbootstrap flasher flash_rootfs --partition=userdata ``` Export the rootfs, kernel, initramfs, `boot.img` etc.: ``` $ pmbootstrap export ``` Extract the initramfs ``` $ pmbootstrap initfs extract ``` Build and flash Android recovery zip: ``` $ pmbootstrap install --android-recovery-zip $ pmbootstrap flasher --method=adb sideload ``` ### Repository Maintenance List pmaports that don't have a binary package: ``` $ pmbootstrap repo_missing --arch=armhf --overview ``` Increase the `pkgrel` for each aport where the binary package has outdated dependencies (e.g. after soname bumps): ``` $ pmbootstrap pkgrel_bump --auto ``` Generate cross-compiler aports based on the latest version from Alpine's aports: ``` $ pmbootstrap aportgen binutils-armhf gcc-armhf ``` Manually rebuild package index: ``` $ pmbootstrap index ``` Delete local binary packages without existing aport of same version: ``` $ pmbootstrap zap -m ``` ### Debugging Use `-v` on any action to get verbose logging: ``` $ pmbootstrap -v build hello-world ``` Parse a single deviceinfo and return it as JSON: ``` $ pmbootstrap deviceinfo_parse pine64-pinephone ``` Parse a single APKBUILD and return it as JSON: ``` $ pmbootstrap apkbuild_parse hello-world ``` Parse a package from an APKINDEX and return it as JSON: ``` $ pmbootstrap apkindex_parse $WORK/cache_apk_x86_64/APKINDEX.8b865e19.tar.gz hello-world ``` `ccache` statistics: ``` $ pmbootstrap stats --arch=armhf ``` `distccd` log: ``` $ pmbootstrap log_distccd ``` ### Use alternative sudo pmbootstrap supports `doas` and `sudo`. If multiple sudo implementations are installed, pmbootstrap will use `doas`. You can set the `PMB_SUDO` environmental variable to define the sudo implementation you want to use. ### Select SSH keys to include and make authorized in new images If the config file option `ssh_keys` is set to `True` (it defaults to `False`), then all files matching the glob `~/.ssh/id_*.pub` will be placed in `~/.ssh/authorized_keys` in the user's home directory in newly-built images. Sometimes, for example if you have a large number of SSH keys, you may wish to select a different set of public keys to include in an image. To do this, set the `ssh_key_glob` configuration parameter in the pmbootstrap config file to a string containing a glob that is to match the file or files you wish to include. For example, a `~/.config/pmbootstrap.cfg` may contain: [pmbootstrap] # ... ssh_keys = True ssh_key_glob = ~/.ssh/postmarketos-dev.pub # ... ## Development ### Requirements for running tests * [Shellcheck](https://shellcheck.net/) You also need to install the following python packages (pip can be useful if you distribution hasn't got them packaged): * `pytest` * `pytest-cov` * `flake8` On Alpine Linux it can be done with: ```shell $ sudo apk add grep shellcheck py3-pytest py3-pytest-cov py3-flake8 ``` ### Running linters The easiest way is to run the same script CI runs: ```shell $ ./test/static_code_analysis.sh ``` ### Running tests You can now run `pytest -vv` inside the pmbootstrap folder to run all available tests. CI runs slightly reduces set of tests (it skips tests that require running qemu) by this: ```shell $ .ci/pytest.sh ``` This is the easiest way to do the same as CI. Alternatively you can run a single test file if you wish: ```shell $ pytest -vv ./test/test_keys.py ``` ## License [GPLv3](LICENSE)