Currently packages that are not in the systemd channel cannot be
sideloaded when using the systemd channel. This is because apk sideload
uses the global aports channel and not the channel of the package. Fix
it with this patch.
Some shells, in particular Nushell, replace the built-in
POSIX-compatible uname with a custom one that does not support common
flags. I opened an issue in the Nushell repository about this, but it
was rejected on the grounds that POSIX compatibility is not a goal. As
such, run this in a subshell to ensure that we get the expected uname
interface.
Nushell issue: https://github.com/nushell/nushell/issues/12570
Now that we have target-version = "py310" in [tool.ruff] in
pyproject.toml, ruff check complains about using typing.Optional and
typing.Union instead of newer syntax. Run the tool to fix it.
Rename build.package() to build.packages() and take a list of packages
to build, since every caller was inside a for loop this simplifies
usage and let's us give nicer log output by doing all the builds first,
so log messages don't get lost in the middle.
Behaviour is cleaned up so this shouuuuld work pretty well now. It
properly descends into dependencies and will build dependencies even if
the package given doesn't need building. Technically this was only done
before during install where the dependencies were recursed in
chroot.apk.install().
It probably makes the most sense to have a mode where it doesn't build
dependencies but warns the user about it, at least when invoked via
pmbootstrap build.
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
Move pmb/parse/arch.py over to core and refactor it as an Arch type,
similar to how Chroot was done. Fix all the uses (that I can find) of
arch in the codebase that need adjusting.
The new Arch type is an Enum, making it clear what architectures can be
represented and making it much easier to reason about. Since we support
~5 (kinda) different representations of an Architecture (Alpine, Kernel,
target triple, platform, and QEMU), we now formalise that the Alpine
format is what we represent internally, with methods to convert to any
of the others as-needed.
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
Building the command strings and entering the chroot is a
not-insubstantial amount of overhead. Implement support for running
multiple commands with a new pmb.chroot.rootm() function.
TODO: add alternative for chroot.user and run.root/user.
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
Cease merging pmbootstrap.cfg into args, implement a Context type to let
us pull globals out of thin air (as an intermediate workaround) and rip
args out of a lot of the codebase.
This is just a first pass, after this we can split all the state that
leaked over into Context into types with narrower scopes (like a
BuildContext(), etc).
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
With the new chroot type, we can now write fancy paths in the pythonic
way. Convert most of the codebase over, as well as adding various other
type hints.
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
We use a custom verbose log level in pmbootstrap, unfortunately it isn't
possible to correctly type this due to some limitations in the logging
library [1], [2].
Given that our usecase is fairly simple, we can just wrap the module
with our own so we only have to tell mypy to ignore the error once
instead of at every callsite.
[1]: https://github.com/cryptax/droidlysis/issues/15
[2]: https://github.com/python/typing/discussions/980
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
Introduce a new module: pmb.core to contain explicitly typed pmbootstrap
API. The first component being Suffix and SuffixType. This explicitly
defines what suffixes are possible, future changes should aim to further
constrain this API (e.g. by validating against available device
codenames or architectures for buildroot suffixes).
Additionally, migrate the entire codebase over to using pathlib.Path.
This is a relatively new part of the Python standard library that uses a
more object oriented model for path handling. It also uses strong type
hinting and has other features that make it much cleaner and easier to
work with than pure f-strings. The Chroot class overloads the "/"
operator the same way the Path object does, allowing one to write paths
relative to a given chroot as:
builddir = chroot / "home/pmos/build"
The Chroot class also has a string representation ("native", or
"rootfs_valve-jupiter"), and a .path property for directly accessing the
absolute path (as a Path object).
The general idea here is to encapsulate common patterns into type hinted
code, and gradually reduce the amount of assumptions made around the
codebase so that future changes are easier to implement.
As the chroot suffixes are now part of the Chroot class, we also
implement validation for them, this encodes the rules on suffix naming
and will cause a runtime exception if a suffix doesn't follow the rules.
Previously, if this was the first time you were connecting to a device,
the output of the ssh command would contain a warning about that the
host was added to the list of trusted hosts. This causes problems as
this gets included in the output where the code previously expected the
string-representation of the architecture to be.
As such, remove the irrelevant output by splitting it into lines and
only using the last line as we assume ssh won't print anything after the
actual output of the invoked command.
Closes https://gitlab.com/postmarketOS/pmbootstrap/-/issues/2335
[ci:skip-build]: already built successfully in CI
I have Nushell set up on my Librem 5, and it is not a POSIX-compatible
shell. As such, the rc=$? variable assignment in this snippet fails.
Running this in a sh subshell works around this problems and will likely
fix it for other non-POSIX shells as well given that /bin/sh should at
least be POSIX-compatible on any sensible system.
Instead of assuming the architecture of the foreign device to be what
the user selected in pmbootstrap init, actually query the architecture
from the device and use that.
This does mean that one extra ssh connection is necessary, which does
slow down the procedure somewhat. However, I think that is worth the
user experience improvement this brings.
Also, the deduction process can be skipped by manually specifying
--arch in the sideload invocation should it fail, or if one really wants
to skip that extra ssh roundtrip.
Related: https://gitlab.com/postmarketOS/pmbootstrap/-/issues/2317
Even add_cmd has exited with code 99, it will be overwritten by clean_cmd
later. Exit with code returned by add_cmd to raise a runtime error when
an error occurs.
This can be used for example to sideload packages to
pmbootstrap's QEMU which is running on the port 2222
by default, as follows:
pmbootstrap sideload --host localhost --port 2222 --user user <pkg>
This adds a `--port` parameter to sideload subcommand.
If not specified, port defaults to 22.
The sideload command runs the supplied names through the pmbootstrap
buildsystem to make sure they're up-to-date, then uses scp from the host
to copy the built apks to /tmp on the phone and installs them through
ssh.
If the --install-key option is set then it will also copy over the apk
key that's used for signing the packages built by pmbootstrap in case
the postmarketOS install on the device isn't build by the same machine
as you're sideloading from.