-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Pwnagotchi image buildable #1120
base: master
Are you sure you want to change the base?
Conversation
Fixes: - Updates packer version - Updates packer-plugin-arm-image name - Downloads packer plugin via packer CLI instead of building from source - Supports image builds on more machines by downloading the correct packer release for the current build machine's CPU type - Dependencies added to 'image' target to ensure that packer is installed and that the image is only rebuilt when the input files are updated - Prevents Ansible from changing build machine's hostname Signed-off-by: llamasoft <[email protected]>
Raspbian has been deprecated in favor of RaspiOS. As a consequence, the Raspbian repo has changed from 'stable' to 'oldstable' which causes the apt-get update command to fail. This is the minimal change required to get the outdated image to build correctly. Signed-off-by: llamasoft <[email protected]>
The PGP signature file for the re4son-kernel repo expired on August 29, 2022. The re-signed PGP key is available from the MIT PGP keyserver. Signed-off-by: llamasoft <[email protected]>
flask, Jinja2, Werkzeug, and itsdangerous are all from Pallets Projects who seemingly refuse to use PEP-440's ~= "compatible release" clause. Instead, all of their project dependencies are ">=" which eventually causes things to break. Their canned response is to recommend always staying on the latest version and to use something like pip-tools to pin dependencies. pallets/markupsafe#282 (comment) Signed-off-by: llamasoft <[email protected]>
Raspbian has been renamed to Raspberry Pi OS. RasPiOS on buster is considered legacy but images are still released for it. A few packages have to be uninstalled (from the main repo) and reinstalled (from the re4son-kernel repo) to fix dependency issues. Signed-off-by: llamasoft <[email protected]>
The default ARM CPU emulated by qemu is armv7l. While this is fine for most packages, it leads to the wrong opencv and tensorflow being installed. By emulating the correct CPU, we're guaranteed to end up with the correct binaries. Signed-off-by: llamasoft <[email protected]>
If the monitor interface is created before the wlan0 interface is up, the resulting mon0 interface will be in a permanently broken state. Since the "[email protected]" is disabled and getting timing guarantees from systemd is a challenge, we manually up the interface. Signed-off-by: llamasoft <[email protected]>
An interface in static mode is required to have an address defined, otherwise ifup will throw an error and fail to bring the interface up. The Debian wiki provided the pre-up/post-down solution: https://wiki.debian.org/NetworkConfiguration#Bringing_up_an_interface_without_an_IP_address Signed-off-by: llamasoft <[email protected]>
The installation of system files has been moved into the 'install' command instead of running unconditionally. This makes it possible to create a source code distribution of that doesn't immediately clobber the build machine's system files. This will also allow the image build to be simplified as it will only need to copy the sdist archive instead of multiple directories worth of files. Signed-off-by: llamasoft <[email protected]>
The idea here is that the requirements.in file should be the loosest allowed requirements for the project itself, then it should be pip-compile'd into a concrete requirements.txt that has known working values. This prevents unnecessarily pinning packages to specific releases which makes it easier to keep package versions up-to-date going forward. Signed-off-by: llamasoft <[email protected]>
Bah, I just spotted an issue with this build. Going to be pushing an update in a bit. |
Firstly, all requirements were sorted. Then, any dependencies not directly used by pwnagotchi were removed (e.g. gast isn't used directly, but it will eventually be installed as an indirect dependency of tensorflow). Next, every single dependency was researched and documented to determine how it's used in addition to what versions it can be safely upgraded to. Most dependencies have been updated to use the PEP-440 "compatible release" feature. Lastly, the --extra-index and --prefer-binary options have been added. As a result of some unfortunate publication issues (e.g. grpcio v1.46.X), some non-yanked libraries simply cannot be built from source. The --prefer-binary option allows pip to prefer an older library version if it has a binary wheel available. This also results in faster builds as fewer requirements actually need to be compiled from source. Signed-off-by: llamasoft <[email protected]>
In theory, this file shouldn't need to be regenerated very often. One thing of note is that pip-compile strongly recommends that it be run on the target system in order to ensure it selects the correct versions. This is because pip-compile doesn't (yet) have a way to specify the Python version, platform, and machine type during compilation. The setup.py file was also tweaked to ignore any --options in the requirements.txt file. Signed-off-by: llamasoft <[email protected]>
Despite the fact that a headless version of opencv exists, stable-baselines and gym both request the regular opencv which has a dependency on libgtk3 despite the fact that they don't use any of the GUI functionality. Signed-off-by: llamasoft <[email protected]>
Installing pwnagotchi using the local sdist has a few key benefits: - We're no longer installing all of the data files twice, once in packer and once in the setup.py script. - The image is built using the code in the current local repo, not whatever code is currently pushed to the remote master branch. This makes it much easier to create and test custom images. - Installs pwnagotchi using pip, just like the auto-update plugin does. Signed-off-by: llamasoft <[email protected]>
As the added comments describe, the options available to us from Ansible's apt module don't actually clean the apt cache. Manually running apt-get clean recovers around 400MB of space. Signed-off-by: llamasoft <[email protected]>
There we go, all fixed up and ready for review! Changes since the last push:
|
Somewhat related, but my PR for packer-plugin-arm-image was merged and included in their latest release. 🎉 What that means for this PR: because the Makefile downloads the correct build of packer and packer-plugin-arm-image for the current CPU architecture, it's now possible to build a Pwnagotchi image from a Raspberry Pi! (It takes around 90 minutes on my RasPi 4, but it works!) |
I just wanted to say thanks for this. I was able to get a buildable image after making the changes. After that the only issues I had where from python not having the correct libraries installed and it being my first time building an image on Linux |
Thanks for keeping this project alive. It looks abandoned to me.
Did I miss something? EDIT: yes, I think I missed the switch to the branch RE-EDIT: |
One of the biggest issues that I'm seeing with your code is that it isn't future proof. You're specifying a version of the programs to download instead of having it always try to build with the most recent versions of the programs. This means that anyone building this three years from now will be using outdated software to do so. Personally, I would suggest always downloading the latest version when possible (which doesn't include in apt or curl since they're outdated as well). |
@D337z you say :
No code is future proof. See https://en.wikipedia.org/wiki/Software_rot.
Pinning versions is actually good practice. Not updating code for three years would be the problem in your description. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It takes a very good approach to fixing many of the bugs. I'm not sure about the ld.so.prefect method, but it seems to work.
This was a deliberate decision, although I tried to keep it as flexible as possible. Unfortunately, many of the Python packages that pwnagotchi depends on either A) don't follow semantic versioning or B) are still in their 0.X release cycle. The best compromise I was able to come up with is using PEP-440 "compatible release" syntax and using pip-compile to get point-in-time values that are guaranteed to work. I documented a portion of this in the commit messages: 1, 2. As for system packages, most of them are being installed at the latest version. The system image itself can't default to the latest version because there's no guarantee that its supported by Kali-Pi. Even a seemingly benign system image update within the same major release ended up requiring some manual fixing.
Yeah... it's a bit hackish, but unfortunately it (or something like it) is required because of how packer works. Once packer mounts the image and chroots into it, the ld.so.prefetch is going to be seen as if it's the host system's ld.so.preload. This can result it in loading libraries of the mounted image's CPU architecture before qemu has a chance to kick in.
It's not doing that any more. It now downloads a static build of packer instead of building it from source (so it no longer needs golang installed on the host) and stores it in As an added bonus, attempting to compile the setup.py script doesn't result it in automatically clobbering the build system's files. Like I said, it's not perfect but I tried to A) keep the changes as minimal as possible and B) not change the overall architecture of the project. |
I am wondering, how are the files being put into the image via packer? All I'm seeing in the json file is that they're being tossing into the src directory instead of the usr/bin of the image. I ran into that small snag. Also, the {{user pwnagotchi_version}} line does not work properly. |
Most of the files are bundled into the python package. Packer copies the
archive into the src directory, then the pip install places them in the
correct locations inside the image (via setup.py).
Putting the system files in the python archive is required because of how
pwnagotchi's update mechanism works.
…On Sat, Apr 15, 2023, 2:39 PM D337z ***@***.***> wrote:
I am wondering, how are the files being put into the image via packer? All
I'm seeing in the json file is that they're being tossing into the src
directory instead of the usr/bin of the image. I ran into that small snag.
—
Reply to this email directly, view it on GitHub
<#1120 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABDK7ATPC3FQS4G3EMSP7SDXBLTO5ANCNFSM6AAAAAAQ4DJAQI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
So after numpy problems with the latest official release (see all the numpy issues, AI not starting) I came by this PR, ran make, flashed the image on a RPI0W and it still works like a charm! Kudos @llamasoft |
Fixes #1115 and #1073
Description
This PR fixes the many small things (and some big things) required to get the pwnagotchi image buildable again.
I tried to keep each commit's changes as small as possible while also including a commit message that fully explains the reasoning or requirement for the changes. The full diff may appear large, but the individual commits tell a story that makes the final result easier to understand.
Also, there are a few intermediate changes that are made redundant by later commits. I did this primarily to make reviewing the commits easier but also so you don't have to accept the whole PR if you don't want to. If you disagree with any of the commits or feel that the changes go too far, you can decide which commits to keep and discard everything after it.
Summary of changes:
(See individual commit messages for a more detailed explanation.)
93b6104
to4748cb6
: The absolute minimum amount of changes to get the image to build (similar to Add support for Pi Zero 2W #1108).The image boots but is unstable. The build process is still likely to break at any time.
6634015
tof910f04
: Fixes image instability caused by the previous set of commits.6634015
: (Optional) Ensures that the correct CPU type is emulated during the build process.This ensures that all packages from
apt
andpip
support armv6 and removes the need to handle opencv and tensorflow separately.e88301e
andf910f04
: Fixes issues related to the updated base image.de8559a
to3d28df6
: (Optional) Fixes pwnagotchi's python packaging issues.3e0fdc4
tof17f784
: A sustainable (and hopefully permanent) fix to requirements.txt version pinning usingpip-compile
.This gives pwnagotchi a requirements.txt file that pins everything to the exact versions without having to worry about indirect dependencies causing build issues at a later date.
The inclusion of a requirements.in file ensures that a working requirements.txt file can be built even if the base image or python version is updated.
3d28df6
: Installs pwnagotchi's python and system files from the local branch.Previously, the build process would install system files from the local
builder/data
directory but overwrite them when installing pwnagotchi's python files from the remote master branch.This made development for this PR a constant struggle. Each build attempt required me to push changes to my forked repo, update the URLs in the build scripts, build the image, then revert the changes.
This should also help if you ever wanted to implement automated image builds 😉😉.
Motivation and Context
I wanted to build my own pwnagotchi but could only obtain a Waveshare v3 display. I saw that support for the Waveshare v3 was added to the repo but no image had been released since then. I tried to build the image myself but quickly ran into issues. While using the available image and copying the updated files would be the easy approach, I felt that getting pwnagotchi images buildable again would be the best for everyone.
How Has This Been Tested?
I've built the image multiple times and use it on my personal RPi0W pwnagotchi. One commenter merged the commits into their test branch and said it was working for them as well.
I don't have a way to confirm that this adds RPi0W2 support, some of the changes in this PR are similar to those in #1108.
Types of changes
This PR is focuses primarily on bug fixes.
There are a few incidental new features (like being able to install pwnagotchi from an sdist) but they are the result of fixes to the build process and should not affect the functionality of the pwnagotchi application itself.
Checklist:
git commit -s
I was not able to find the documentation source in order to update it. 🤐
The only documentation update is that the image build prerequisites no longer require
go
orkpartx
:go
is no longer required because Packer and the ARM image plugin are downloaded as binary releases.kpartx
is no longer required because Packer now useslosetup
as of v0.2.2.