Put all install_packages related lines into one block and fix up the
comments:
* The list of packages to be installed is not listed at this point (and
it does not make sense there, if we would want to list it, it should
be done in the next block at 'if args.build_pkgs_on_install).
* Remove "including the ones specified by --add", as it doesn't add any
value.
Don't have the set_user() call weirdly between multiple commands
building the install_packages list. Move it up, together with the log
message announcing that the device rootfs is being built.
Update the comment above set_user(): there is no 'build' user anymore,
and at this point we only call it before actually installing the
packages for legacy reasons.
Do not attempt to upgrade packages in the rootfs chroot when running
"pmbootstrap install".
This was responsible for placing every single package in /etc/apk/world
(which should only hold the packages explicitly installed), because the
upgrade function was literally implemented as getting a list of
installed packages and explicitly running pmb.chroot.apk.install on each
of them. The intention was to rebuild these packages if they were outdated,
I guess I didn't realize that this makes /etc/apk/world unusable when I
introduced this three years ago in 51bdc243 ("Properly rebuild/install
packages when something changed").
Remove pmb.chroot.apk.upgrade altogether, because:
1) pmb.install.install builds and upgrades outdated pmaports
2) pmb.install.install is the only user of pmb.chroot.apk.upgrade
3) 'pmbootstrap init' is warning that the chroots do not get upgraded
automatically, so let's not go against that expectation. users who
want an updated rootfs chroot can simply run zap and install again.
Replace it with a call to pmb.helpers.repo.update, because we still need
to update the APKINDEX files before attempting to build/install the
generated list of packages.
Let tail attempt to open the file again, if it becomes inaccessible.
This is useful, when writing a reproducer that deletes pmbootstrap's
log.txt while at the same time running 'pmbootstrap log'.
(027724) [17:57:34] Done
tail: '/home/user/.local/var/pmbootstrap/log.txt' has become inaccessible: No such file or directory
tail: '/home/user/.local/var/pmbootstrap/log.txt' has appeared; following new file
(003493) [17:57:35] % cd /home/user/.local/var/pmbootstrap/cache_git/pmaports; git remote -v
Packages like binutils-*, busybox-static-*, gcc-*, grub-efi-*, musl-*
are only needed for the native architecture during cross compilation.
Don't bother with trying to build them for other arches to save time and
to avoid getting stuck frequently at "armv7/binutils-aarch64" etc.
A few people like to use pmbootstrap on aarch64 hosts (e.g. PineBook
Pro), so let's make it available for aarch64 again when we can build
aarch64 packages natively in CI and bpo. (They do get stuck there right
now, because of qemu user emulation.)
Related: https://gitlab.com/postmarketOS/build.postmarketos.org/-/issues/75
Use a deterministic mirror URL instead of CDN for aportgen. Otherwise we
may generate a pmaport that wraps an apk from Alpine (e.g. musl-armv7)
locally with one up-to-date mirror given by the CDN. But then the build
will fail if CDN picks an outdated mirror for CI or BPO.
This adds support for specifying an arbitrary git ref (e.g. commits,
tags, branches) to upgrade to. This can be useful if a specific commit
needs to be packaged instead of the latest available. Alternatively you
can also specify a branch to be used if the default branch is 'stable'
but 'develop' should be packaged.
This also removes old code to use the 'bionic' branch for UBports Lomiri
(formerly Unity 8) packages.
The Nokia n900 XkbLayout is a bit peculiar and sometimes
join two keymaps into one, for example:
Option "XkbLayout" "fise"
For the combined finnish/swedish layout. Add the common
joined keymaps, even if not all of these countries are
yet supported.
For details see:
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/blob/master/symbols/nokia_vndr/rx-51
I also include this link in the code so no-one gets confused.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Some Mediatek devices have a special 512-byte header around the zImage
which must be generated so the device boots.
Support for that exists for a while in postmarketOS but detection was
missing. Add that.
Do not fail in "pmbootstrap setup" if a keymap was selected, but no
/etc/X11/xorg.conf.d path exists in the rootfs chroot. The grep output
is not empty in that case (it would be empty if the directory exists and
there are no matches), so we need to add this extra check:
(rootfs_nokia-n900) % grep -rl XkbLayout /etc/X11/xorg.conf.d/
grep: /etc/X11/xorg.conf.d/: No such file or directory
Replace dl-cdn mirror with dl-2 temporarily to avoid "BAD signature"
errors.
This is related to the rebuild of Alpine edge x86, armhf, armv7 packages
against musl-1.2, that is currently going on. The packages are rebuilt
without a version change and therefore have the same resulting file
name, but a different checksum. Due to caching of the CDN and due to the
same file name, users may get an old package from before the rebuild.
The APKINDEX has a checksum of the new package, and so the download will
fail with a "BAD signature" error.
Alpine developers clear the cache every now and then, but this issue
will happen over and over again, until all packages are rebuilt (some
packages are still not rebuilt and have been disabled).
Let's switch back in two months or so.
Before this fix tab completion of names with hyphens were not done:
try for example to complete UI package name in 'pmbootstrap init' with
hyphen, like "plasma-mobile" / "plasma-desktop". Now this is handled
correctly (hyphen is not considered as delimeter).
Let UI meta-packages specify apps in "pmb_recommends" to be explicitly
installed by default, and not implicitly as dependency of the UI
meta-package ("depends"). Therefore make these apps uninstallable,
without removing the meta-package.
Add pmbootstrap install --no-recommends to disable this feature.
Add a question at the end of "pmbootstrap init", to ask if the user
wants to build outdated packages during "pmbootstrap install". Store the
result in the new pmbootstrap.cfg key "build_pkgs_on_install". I've put it at
the end, because it is a rather complicated question compared to the rest.
This is useful to speed up the installation for casual users who can now
avoid compiling packages. But also for the official images where we only
want to ship the official binary packages and not build anything
on-the-fly.
This is likely to fail with the new default cryptsetup cipher of
aes-xts-plain64, as many downstream kernels used in recovery OS (like
TWRP) do not have CRYPTO_XTS set.
Put a minimum version check for postmarketos-ondev in the pmbootstrap
install code and verify it before starting the installation. This avoids
using incompatible versions, similar to the pmaports.cfg version check
we already have. Set the minimum required version to 0.2.0.
Do not pass the arguments to ondev-prepare as command-line arguments in
a specific order, but instead as environment variables. New arguments
will be added in a follow-up patch.
Checkout the aports.git branch for the current channel (e.g.
3.12-stable), before trying to find the APKBUILD.
I had tried to auto-unshallow the git repository earlier, but then the
tags were missing. I decided that it's not worth to provide a migration
path: "pmbootstrap aportgen" is only used by few advanced users (to
maintain the pmaports repo).
This made sense for Alpine's aports.git repository as we were only using
the master branch. But now that we are using more branches, we need the
entire git repository with all its branches cloned.
Add the Alpine mirrordir (e.g. "edge", "v3.12") to the distfile, so
musl-*.apk files of the same version and arch but from different
mirrordirs do not collide.
Let "abuild checksum" download these apks and generate the checksums,
instead of letting apk download them as side-effect of initializing
foreign arch chroots. The latter did not work anymore, because we would
copy the apk file with a glob that may matches the hash of either mirrordir.
Essentially:
glob.glob(f"{args.work}/cache_apk_{arch}/{subpkgname}-{version}.*.apk")[0]
In the context of the on-device installer, I found that calculating this
hash is not trivial, so let's just avoid it here as well.
While at it, order the imports of musl.py alphabetically.
Add initial support for the on-device installer in pmbootstrap. Let
pmbootstrap create a regular split image, then prepare a new installer
rootfs and copy the previously generated rootfs image into the installer
rootfs. Put the installer rootfs into a new image, with reserved space.
There is more to do from here, such as disabling the generation of the
user account when using --ondev. But this requires support in
postmarketos-ondev first, so let's build that iteratively.
Related: https://wiki.postmarketos.org/wiki/On-device_installer
Related: https://gitlab.com/postmarketOS/postmarketos-ondev/-/issues
Move code that prints flashing information from install_system_image()
to its own function. For the on-device installer, we'll need to call
install_system_image() twice, without printing the flashing information
each time. While at it, add "step" and "steps" parameters.
Prepare for a future patch, that adds reserved space in MiB, by changing
size_boot and size_root from bytes to MB everywhere. This is what we need
most of the time and allows to drop some /1024**2 statements.
Add a "split" argument to the function, instead of using "args.split"
directly. "args.split" is only defined when calling "pmbootstrap install",
but the next patch will add a code path that calls the function from
"pmbootstrap chroot".
Alpine APKBUILDs have the concept of "provider priorities" that affect
the choice of the provider to install when multiple packages provide
a virtual package.
One use case for this is to allow installation of different firmware
versions. bq-paella can run unsigned firmware, therefore you have the
choice between using the original firmware from the manufacturer, or
a slightly newer version from Qualcomm for the Dragonboard 410c.
We add provides="firmware-qcom-msm8916-wcnss" (the "virtual package")
to both firmware-qcom-db410c-wcnss and firmware-bq-picmt-wcnss.
At this point, attempting to install "firmware-qcom-msm8916-wcnss"
would still fail with apk. (Because it does not know which provider
to install.)
To pick a default we can set e.g. provider_priority=100 for
firmware-qcom-db410c-wcnss (the slightly newer version).
In that case, firmware-qcom-db410c-wcnss should be installed by default.
However, the user can choose to do "apk add firmware-bq-picmt-wcnss"
to override the default choice in case of problems. In that case,
the conflicting firmware-qcom-db410c-wcnss will be automatically removed.
At the moment, pmbootstrap does not respect the "provider_priority" at all.
In the above case, it would always install "firmware-bq-picmt-wcnss"
during "pmbootstrap install" since that has the shortest name.
Extend the pmbootstrap code to pick a provider with the highest priority
(if any of the providers has a priority set).
Do not substract the estimated size of the home and boot directories
from the root directory size. While that would be the correct way if we
were able to get exact sizes, it isn't helpful with the very rough
estimates we are getting from pmb.helpers.other.folder_size. Replace
"calculate" wording with "estimate".
"Chassis" defines the what kind of device a device is. Currently the
following standardized types exist:
"desktop", "laptop", "convertible", "server", "tablet", "handset",
"watch", "embedded", "vm", "container"
This property is exposed by org.freedesktop.hostname1 (e.g.
openrc-settingsd) and can be used by applications for example to display
appropriate strings instead of "About this phone" for non-phone devices.
Migrate to workdir version 5 and move already built packages into the edge
channel subdir, for example:
$WORK/packages/x86_64/hello-world-1-r5.apk
to:
$WORK/packages/edge/x86_64/hello-world-1-r5.apk
The build.postmarketos.org code has already been adjusted to find built
packages in either directory structure.
Do not go through the pmb.chroot.init() code path when running
pmb.install.losetup.umount() inside pmb.chroot.shutdown(). This is not
necessary, as pmb.install.losetup.umount() only gets called if the
chroot is already initialized and /dev/loop-control is mounted inside
the chroot.
Not going through this code path is important for the upcoming workdir
migration patch. Without this fix, it will fail with the following if
running "pmbootstrap install" before the work migration:
ERROR: Could not figure out on which release channel the 'native' chroot is
Replace the call to this function with the almost identical
pmb.helpers.repo.apkindex_files(), so release channel related changes
only need to be done in one place.
Use mirrordir_pmos and mirrordir_alpine from channels.cfg to generate
the mirror URLs for postmarketOS and Alpine, which get written to
/etc/apk/repositories and which postmarketOS uses to download the
APKINDEX files.
Remove hardcoded "master" at the end of the postmarketOS mirror and use
mirrordir_pmos instead (which is "master" for the edge channel). Let the
postmarketOS mirror end in a '/' for consistency with the Alpine mirror
in pmb/config/__init__.py.
Remove obsolete --alpine-version. To experiment with a different Alpine
version, one should pass a custom --config-channels from now on.
Don't generate the postmarketOS mirror URLs here, let the urls()
function do it. A follow-up commit will touch this code, hence it's
important to have it de-duplicated.
Ask for release channel and switch pmaports branch to the related branch
defined in channels.cfg.
Store in pmbootstrap.cfg whether the user chose a channel (boolean). If
the user did not choose a channel yet, suggest the recommended channel
from channels.cfg (currently "edge").
Do not make the parsed pmaports.cfg from pmaports.git available as
args.pmaports anymore. This de-bloats the args variable a bit.
First I thought that we didn't even need to cache it, but it was pointed
out that later patches do access it frequently to read the current channel
from pmaports.cfg. Therefore it is using a cache now.
Related: #1879, #1855
New pmaports.cfg has the "channel" key described in [1]. This will be
used in "pmbootstrap init" to determine on which release channel a
forked branch is.
[1] https://postmarketos.org/pmaports.cfg
Prepare to base postmarketOS on Alpine stable by parsing the new
channels.cfg file in pmaports.git, that describes which channel
needs which branches and mirror dirs from postmarketOS and Alpine.
Use the information in pmb.helpers.git.get_branches_official() first,
more is coming in follow-up commits.
Read the file from origin/master, so we get the latest fetched version
even if the last checked out master branch is not up-to-date (think of
currently checked out release branch instead of master, master will
never be updated to point to latest origin/master). Allow to override
the file with a new --config-channels parameter.
Related: https://postmarketos.org/channels.cfg
Most device ports that are added to pmaports (particularly the testing
category) are not actually "maintained". Many of them are never updated
after the initial contribution. There is little reason to list a
"Maintainer:" if the device package is actually not actively maintained
by that person.
Let's stop generating the Maintainer: line by default.
Instead, contributors should add the lines themselves if they are willing
to (actively) maintain the device package for a longer period of time.
Once they no longer want to maintain the package, the Maintainer:
line should be removed again.
Let apkbuild-lint check options again, and pass the pmbootstrap specific
options with the new CUSTOM_VALID_OPTIONS variable. Add a test case and
adjust pmb.helpers.lint.check to return the output of apkbuild-lint, so
we can properly test it.
Related: https://gitlab.alpinelinux.org/Leo/atools/-/merge_requests/28
Fixes: pmaports#553
The `mesa-dri-swrast` package was merged into `mesa-dri-gallium` in Alpine.
(See 298e20d04f)
The old alias might be removed in the future, so change the generated APKBUILDs
to depend on `mesa-dri-gallium` instead.
Many of the multi-line strings already contain a new line at the
end of the file. When using .split("\n") this will result in an empty
line at the end of the file that is again followed by a new line.
In other words: we have two new lines at the end, which looks weird.
.rstrip() the whitespace at the end of the string to avoid this.
In case a package can't be built using crossdirect, add an APKBUILD
option to unconditionally disable crossdirect and use the slower
distcc approach instead. This is needed e.g. when using LD_PRELOAD during
the build as crossdirect cannot work with that.
Have explicit selection of the "native" cross compilation method with a
new "pmb:cross-native" option. Deprecate the implicit pkgname pattern
matching.
Related: #1910
The ui-extras questions will attempt to find a postmarketos-ui-<ui>
package in pmaports. If the package does not exist as "root" APKBUILD
it currently attempts to parse all APKBUILDs in case it is somewhere
defined as a subpackage. This is really slow (up to 2-3 seconds),
which feels weird during "pmbootstrap init".
For the UI packages we specifically look for the root UI package,
not the subpackage, so let's skip searching for subpackages in this
case. This makes selecting the "none" UI nice and fast again.
Fix the function, so it does not crash anymore when the
replace_subpkgnames argument is set and a dependency cannot be resolved.
Instead, print a useful warning that shows which pmaport caused the
error (that has always been a pain to figure out), and simply don't
replace the potential subpkgname with the real pkgname, just use the
dependency name as-is.
Resolve annoying crashes in bpo dependency resolving, like this one
(caused by a few linux-* pmaports for bad downstream kernels that depend
on python, not apparent at all from the message):
[09:08:15] Calculate packages that need to be built (all packages, aarch64)
[09:08:26] ERROR: Package 'python': Could not find aport, and could not find this package in any APKINDEX!
Related: https://builds.sr.ht/~postmarketos/job/184022
Previously these two commands would both print the current value:
pmbootstrap config extra_packages
pmbootstrap config extra_packages ''
With this change, the second command will instead set the given config
value to the empty string.
Prevent "pmbootstrap pull" from failing with:
NOTE: your pmaports folder has version 4, but version 6 is required.
ERROR: Run 'pmbootstrap pull' to update your pmaports.
Fixes: #1900
Use pmb.helpers.args.add_cache() with the args used during
autocompletion, so pmb.helpers.pmaports._find_apkbuilds() does not fail
when trying to access args.cache.
No build is necessary if pmaport can't be built for given arch.
pmbootstrap must use Alpine's binary package in that case, even if the
pmaport version is higher than Alpine's binary package version.
Fixes: #1897
The --no-depends option is supposed to stop pmbootstrap if it was
instructed to build a package, but a dependency must be built first. So
far, this only covers the case if there is no binary package for a dependency.
Make it stop if the binary package exists, but is outdated, too.
Fixes: #1895
At the moment we set samsung-i9100 as default device.
This is probably only for historical reasons.
For someone/something using pmbootstrap without a specific device in mind
(e.g. CI) it's really better to use a generic device. QEMU runs natively
in a virtual machine so everyone can use it for testing.
Flashes device vbmeta partition (can be overriden with
"flash_fastboot_partition_vbmeta" setting in deviceinfo)
with custom vbmeta.img which has verity flag disabled,
so device can boot postmarketOS with no problems.
The kconfig check searches the aport with the "linux-" prefix to the
package name passed as argument. This is not working with the full
package name like linux-device-name because it searches a
linux-linux-device-name and fails.
Use the timestamp of .git/FETCH_HEAD in each git repository, to
determine if too much time has passed since the last fetch/pull.
Modify pmb.helpers.git.clone, so FETCH_HEAD is always created if it does
not exist (because "git clone" would not create it).
Related: #1829
Extend "pmbootstrap status" with checks for all git repositories,
derived from relevant checks in pmb.helpers.git.pull (using shared
code):
* on official branch
* workdir is clean
* tracking proper remote
* up to date
Related: #1829
Add dummy function that only returns ["master"] for now, so we can use it
in the upcoming git checks for "pmbootstrap status". More sophisticated
logic to figure out the branches will be added soon, see project
direction 2020 issue.
Related: #1829
Device ports should be under the device/testing/* directory for now.
In the future, devices may be moved to device/{main,community} after
certain preconditions are met.
In the future, device ports will be located in a subdirectory
below device/... (e.g. device/testing/device-...).
Replace all occurrences of device/* with a glob that checks the
subdirectories instead.
Note: To ensure that this always works properly we should also add some
checks that all devices are indeed located under one of the supported
subdirectories (i.e. testing/community/main).
Change the glob for pmaports to <aports>/**/APKBUILD.
This allows using subdirectories for organization outside of device/
as well.
For KVM the code is run pretty much natively on the host CPU, so all
CPU extensions available on the host CPU can be also used inside the VM.
To expose that information to the VM we should pass "-cpu host", so the
VM is aware of which CPU is in use.
For CPU emulation, QEMU uses a rather minimal CPU on x86_64 by default.
It does not have support for SSE3/4 etc, which may be required for some
applications to work properly (e.g. Android in Anbox). Add a --cpu flag
to make the emulated CPU configurable. Useful values are for example
--cpu max to emulate all implemented CPU features.
To test QEMU's CPU emulation it is useful to have a switch to disable
KVM, even when it is available (and potentially working fine).
Add --no-kvm for that purpose.
For some reason, the SDL display backend changes the video resolution
to 1024x768, while the GTK display keeps it at 640x480.
This is annoying, because at the moment we can only set one display
resolution for a device in postmarketOS (e.g. for the splash screen).
At the moment, the resolution for the splash screen is set to 640x480,
which therefore shows up too small with the default SDL display.
It seems like the display resolution can be only changed in the guest
directly. Linux has a video= kernel parameter that can be used to
implement this. (See: https://www.kernel.org/doc/html/latest/fb/modedb.html)
Let's set 1024x768 by default, but make it configurable through --video.
The QEMU 'tablet' input device reports absolute positions instead
of relative mouse pointer movements. This can be used to automatically
grab/release the mouse pointer when entering/leaving the QEMU window,
instead of having to release it with CTRL + ALT + G manually.
This is quite convenient and should be the default option normally,
but at least on my PC the mouse pointer is reported with some vertical
offset for some reason (you can't reach the top and it extends below
the QEMU window...). Let's add it as an optional --tablet option for now.
To ensure consistent behavior for QEMU on all architectures,
it is helpful to try to use the same hardware elements where possible.
A few examples of current inconsistent behavior:
- x86_64 uses a SCSI disk, while aarch64 uses virtio-blk
- x86_64 uses e1000 network, while aarch64 uses virtio-net-device
- x86_64 uses PS/2 mouse, while aarch64 uses usb-mouse
- only x86_64 prints serial output to console
At least the virtio components are usually independent of the selected
architecture, so we can use them for both architectures.
This commit makes most of the hardware configuration shared:
- Redirect serial output to stdio
- virtio-blk for the disk image
- virtio-gpu-pci (this was already implicit for both architectures)
- virtio-net-pci for the network interface
- virtio-mouse-pci/virtio-keyboard-pci as input devices
- intel-hda for audio
We also set -nodefaults to avoid setting up unneeded devices
especially for x86_64.
Now that we try to use the IP assigned by QEMU via DHCP,
the debug-shell is no longer working via telnet.
This is because the VM does not have any IP assigned when it is running.
We would need to start a DHCP client from the initfs to make it work.
busybox provides both udhcpc (client) and udhcpd (server) so this is
not a big problem. But the question is: Is it worth it?
The debug-shell will be only used for debugging, and NetworkManager
handles starting a proper DHCP client once the rootfs is mounted.
Meanwhile the debug-shell can be also accessed via serial output/input,
(available in the pmbootstrap stdout/stdin). So overall it does not
seem worth the effort. Let's just recommend using serial instead.
The current network setup has weird side effects.
Normally, QEMU would automatically make the guest set up necessary
IP routes through its integrated DHCP server.
When running QEMU through pmbootstrap they are missing.
First, we change the DHCP range in a way that could potentially
conflict with default IPs used for QEMU's own services:
QEMU has the default gateway at <network>.2, and DNS at <network>.3.
We set the DHCP range to start at <network>.1, and will therefore
potentially give out one of these addresses (QEMU's default starts at
<network>.15).
See: https://wiki.qemu.org/Documentation/Networking#User_Networking_.28SLIRP.29
In practice this does not cause immediate problems because there is
just one guest in the network, and it will get <network>.1, which is
not used by QEMU.
More problematic is that we start a DHCP server from postmarketOS
at the same time (normally used for the USB network) and there are
actually two DHCP servers running at the same time.
QEMU's user networking is local to the process, therefore it is not
possible to access the QEMU guest through its IP from the host.
That's why we have the port forwardings so you can access SSH at
localhost:2222 for example.
In practice the network interface in the QEMU guest is only used to
access the Internet. For that, we don't care which IP address we get,
we just want to get a working setup (IP + routes + DNS) automatically
through DHCP.
To make this work nicely we just need to stop trying to fit QEMU's
network setup into our usual setup for USB networking. When we remove
the custom DHCP option, and avoid starting a DHCP server from postmarketOS
(deviceinfo_disable_dhcpd) everything is suddenly working fine. :)
device-qemu-vexpress appears to be completely broken at the moment.
I was not able to make it show anything, get a log or even just get
any indication that it is actually doing something.
In general, it does also not fit well to the other QEMU ports.
The vexpress machine type in QEMU seems to be quite limited,
e.g. it has no PCIe bus and therefore it is impossible to configure it
with virtio-gpu. (Unlike already configured for x86_64 and aarch64).
I had some success with a setup similar to aarch64 with -M virt,highmem=off
but was unable to make it work in the end:
- Alpine's virt kernel was missing some options preventing boot completely
- Alpine's lts kernel was missing PCI support for virtio-gpu
- Even after adding the options the VM usually freezed after boot
Overall it does not quite seem worth the effort at the moment,
compared to how well x86_64 and aarch64 are working.
In any case, vexpress is too different (and broken) to continue maintaining it.
When using pmbootstrap, you usually select the device you want to work
on using 'pmbootstrap init', generate the rootfs and can then run more
commands in the context of the device.
The same needs to be done before using QEMU (to generate the rootfs).
But for some reason 'pmbootstrap qemu' requires setting the --arch
parameter when running QEMU for a foreign architecture, even when the
device is still selected in pmbootstrap.
Even more confusing is that setting "--arch arm" always selects
device-qemu-vexpress, but this is not immediately clear from the name.
Let's make this a lot more intuitive by making sure there is a QEMU
device selected when running 'pmbootstrap qemu'. We can then use the
device information to infer the architecture automatically.
At the moment, the --display argument is a bit complicated to use.
A common use would be to switch between the UIs (sdl, gtk, none)
or to enable the software rasterizer. Split the two use cases
to separate arguments to make it more intuitive.
So far we tried to configure virtio-gpu using "-vga virtio" only
when the target architecture matches the host architecture.
But that's actually not what it depends on.
virtio-gpu and virgl can be also used when emulating a foreign
architecture. In fact, we already force usage of virtio-gpu for
aarch64 through "-device virtio-gpu-pci".
However, the "-vga virtio" parameter does not exist on aarch64,
no matter if we run QEMU natively on aarch64 or emulate it on x86_64.
(Apparently, -vga is mainly about legacy VGA framebuffer stuff that
we don't necessarily need. This is quite visible since the display
stays uninitialized on aarch64 until the kernel driver loads,
whereas on x86_64 it is initialized by the BIOS...)
In other words, "-vga virtio" belongs to the parameters specific to x86_64.
Now that we have removed the setup question for the Mesa driver to use
(since it was ineffective), it would still be nice to have some way to
choose if you want to use virtio-gpu/virgl or not.
But actually virtio-gpu can be also used with swrast, without virgl.
This happens automatically when QEMU is started without GL support.
We already have a --display parameter for this, so it is possible to
force swrast by using "--display sdl" (instead of the default sdl,gl=on).
Overall this allows simplifying the QEMU package setup because there is
only a single GPU driver in use (virtio-gpu) instead of the 3 we had before
(virtio, qxl, bochs).
mesa-dri-swrast and mesa-dri-virtio are both provided by mesa-dri-gallium
now, so this option does not have much use anymore. With both selections,
exactly the same packages are installed.
The SPICE UI option tends to be broken (see #1836), and even when it is
working, it is not working particularly well. QXL requires special handling
in our QEMU packages, when now virtio-gpu (virgl) is working quite well overall.
Apparently it is possible to use virgl with SPICE; but only when using
a Unix socket instead of a TCP port. That again is a bit complicated
because we run QEMU outside the chroot and the SPICE client within.
Overall it does no longer seem to be worth the effort.
The default QEMU UI is working just fine (for the purposes of testing
postmarketOS at least).
Fix finding subpackages in pmaports, if no binary repo exists (-mp "" makes
pmbootstrap not use a binary packages mirror for pmOS packages). Discovered
with failing "test_depends_SLOW_40s" in bpo.
$ pmbootstrap -v -mp "" repo_missing --built --arch x86_64
[18:40:51] Calculate packages that need to be built (all packages, x86_64)
[18:40:56] ERROR: Package 'musl-dev-aarch64': Could not find aport, and could not find this package in any APKINDEX!
Newer kernels require "bison" and "flex", so to easy porting we should
add them to generated APKBUILDs by default. While we are it, clean up
the default set of dependencies a bit:
- installkernel is only needed when using "make zinstall", which
we are not using in downstream_package (it requires special kernel
configuration, so it's not really suitable for downstream...)
- most kernels seem to compile fine without gmp-dev and elfutils-dev,
so they should only be added when needed
- the kernel has its own headers, why do we need linux-headers?
(probably copied from Alpine, but anyway...)
- add openssl-dev since it is needed for building/signing kernel modules
Useful reference: https://www.kernel.org/doc/html/latest/process/changes.html
Although it mentions much more than what is really needed...
Building the QCDT image in build() complicates use of envkernel.sh
- in that case, make is done independently of the APKBUILD, and only
the package() function is run to assemble the kernel package.
Building it entirely in package() allows using envkernel.sh without
having to set up some "post make script" (see
https://wiki.postmarketos.org/wiki/Compiling_kernels_with_envkernel.sh#Post_make_scripts).
package() might actually fit better in general, since QCDT is only
a special "package" format for (multiple) DTB files at the end :)
Add a helper class that provides readline-based tab completion and an
extra optional argument "completion_choices" with possible completion
targets.
While at this, also improve paramters documentation for ask() func.
Add new "pmbootstrap status" command, which does a quick health check
for the work dir. As first health check, verify that the chroots are not
too old. Replace the reminder text at the end of "pmbootstrap init" to
tell users to run "pmbootstrap status" instead of "pmbootstrap zap" once
a day before working with pmbootstrap.
Related: #1829
Whenever initializing new chroots, save the date in $WORK/workdir.cfg.
Add pmb.config.workdir.chroots_outdated() to check if it's time to zap
the chroots or not (since we don't update them automatically). Mark them
as outdated after two days.
This will be the first check in "pmbootstrap status" (future patches).
Related: #1829
While at it, also remove unnecessary "#!/usr/bin/env python3" in files
that only get imported, and adjust other empty/comment lines in the
beginnings of the files for consistency.
This makes files easier to read, and makes the pmbootstrap codebase more
consistent with the build.postmarketos.org codebase.
At the moment we have a simple subpkgdesc() function that can only
parse "pkgdesc" from subpackages, without support for any variables.
But we have a quite nice variable parser now that can be extended
to work for subpackages.
Simply put this works by:
- Finding the lines that belong to the subpackage function
- Stripping indentation (tab)
- Parsing relevant attributes similar to the apkbuild() function
The "subpackages" in the parsed APKBUILD are replaced by a dict
of subpkgname: {"pkgdesc": "...", "depends": "..."} which are
parsed from the subpackage function (if found).
This makes it possible to get the "depends" of a subpackage.
At the moment we parse all attributes, split them, and eventually
join them back together for variable replacement.
Replacing variables immediately after parsing (before splitting)
has several advantages:
- No need to handle different value types
(e.g. lists by joining them every time they are accessed)
- Variables like depends="$depends ..." are handled directly
by the variable parser
- APKBUILDs are shell scripts, so we match abuild more closely
if variables defined later do not affect previous attributes
Theoretically it is possible to reference variables before they are defined.
In the shell, these will simply be evaluated to an empty string.
In preparation of replacing variables immediately after parsing attributes,
these variables will be no longer replaced correctly.
We can simplify the code further, and avoid this problem by initializing
the dict with the default values, replacing them with the real values
from the APKBUILD.
This will also avoid a (somewhat unrelated) error in the bootimg test:
File "pmb/parse/_apkbuild.py", line 46, in replace_variable
apkbuild["pkgname"], match.group(0),
KeyError: 'pkgname'
The gist of this action is upgrading the specified aport to the latest
version. There are implementations for both stable packages (which check
via the release-monitoring.org API for new versions) and git packages
(which check the GitLab/GitHub API for new commits on the main branch).
There's also the possibility to pass --all, --all-stable & --all-git to
the action which either loops through all packages, or just stable or
git packages and upgrades them.
The --dry argument is also respected.
Note, that the implementation does update the variables pkgver, pkgrel
and _commit but it doesn't update the checksums because that would slow
down the process a lot, and is potentially undesirable.
asus-me176c has a Fastboot interface that can be used for flashing,
but in postmarketOS we do not use Android boot images for it.
This is because is it not very practical - the boot partition is
quite small and there is a (custom) EFI bootloader that can boot
directly from any other FAT32 partition.
At the moment the installation process is manual:
1. pmbootstrap install --split to have separated boot (FAT32)
and rootfs images
2. pmbootstrap export
3. Flash boot and rootfs images manually using Fastboot
The "fastboot-bootpart" flasher implements that process in a more
convenient way. When a device uses the "fastboot-bootpart" flasher:
- We generate --split images on "pmbootstrap install" by default.
(This can be disabled using --no-split instead.)
- pmbootstrap flasher flash_kernel flashes the raw boot partition
(not an Android boot image) using Fastboot, just like the rootfs.
There are some limitations that could be improved in the future:
- "fastboot-bootpart" is not offered in the device wizard.
I think it is special enough that no-one will be starting with it,
and the difference to normal "fastboot" might be confusing.
- Support "pmbootstrap flasher boot". asus-me176c does not support
"fastboot boot" properly, but theoretically we could still generate
Android boot images to use when booting an image directly.
- At the moment the boot partition image is not regenerated when
using "pmbootstrap flasher flash_kernel" (unlike when using Android
boot images). "pmbootstrap install" needs to be run manually first.
Create add_packages_add() function, so we don't need to write the three
lines for adding the "packages" argument to an action with proper
autocompletion.
Remove in favor of similar, but more visible "--no-install" option for
"pmbootstrap flasher" and "pmbootstrap export".
It seems that the option wasn't really used by anybody, so let's just
remove it without a deprication period. If dear reader thinks otherwise
after this is merged, and is not happy with "--no-install", please state
your reasoning in a new issue, so we can discuss it.
Related: !1863
Avoid generating an APKBUILD with the following linting issues:
- unnecesary usage of braces: ${_flavor}
- unnecesary usage of braces: ${arch}
- unnecesary usage of braces: ${_commit}
- unnecesary usage of braces: ${_repository}
Commit 43520967 ("pmb.qemu.run.install_depends: adjust to mesa pkgs (!1865)")
replaced mesa-dri-swrast, mesa-dri-virtio and mesa-dri-vmwgfx with
mesa-va-gallium. But the Gallium DRI drivers are actually provided by
mesa-dri-gallium. mesa-va-gallium contains libva drivers for hardware
video acceleration.
Fortunately this did not break anything because mesa-dri-gallium
was still installed as dependency of mesa-dri-ati/intel/nouveau.
QEMU does not make use of libva, so lets just replace mesa-va-gallium
with mesa-dri-gallium. While we are at it, stop depending on the
deprecated mesa-dri-ati/intel/nouveau packages. Those are only kept
for compatibility reasons and install more dependencies than necessary.
At the moment, pmbootstrap updates the kernel and the initfs whenever
using the flasher or export. This is useful, but sometimes you just want
to boot exactly the same kernel several times. In that case, having to wait
several seconds for the (redundant) update to complete is quite annoying.
Add a --no-install option that allows skipping the kernel/initfs update.
At the moment, sparse images are generated if the device sets
deviceinfo_flash_sparse="true". But for testing purposes it can be
useful to specifically enable or disable the default behavior.
Add a --sparse and --no-sparse option that enables or disables
sparse image generation.
Adjust the mesa related packages installed for running in qemu, after
the mesa APKBUILD in Alpine was changed. Install mesa-va-gallium instead
of:
* mesa-dri-freedreno
* mesa-dri-swrast
* mesa-dri-virtio
* mesa-dri-vmwgfx
Fix error in pmbootstrap-qemu CI test:
ERROR: Could not find dependency 'mesa-dri-freedreno' in any aports folder or APKINDEX.
Related: 298e20d04f
Now that the qemu-user binary is bind-mounted, we no longer copy
the binary to the device rootfs. However, there is still the empty
stub file that we used as a destination mount point.
Let's remove it before copying it to the device rootfs.
It is automatically re-created the next time the qemu-user binary
is needed.
Right now we explicitly add ttf-droid to /etc/apk/world, and force
installation of it on every postmarketOS installation. But there really
is no reason to force this from pmbootstrap:
- If ttf-droid is really required for every postmarketOS installation,
it should be a depends of postmarketos-base.
- Even with this change it is still installed on every device,
because postmarketos-splash depends on it.
- There is no need for fonts when using the "none" UI.
For now, the only difference of this change is that we no longer add
ttf-droid explicitly to the APK world. Instead, it is installed as
dependency of postmarketos-splash.
At the moment we assume that everyone running QEMU is either using
ALSA, or has the ALSA PulseAudio plugin configured on the host system.
(Since we run QEMU outside of the chroot at the moment, configuration
files are read from the host system instead of the chroot...)
Other distributions have much wider support for PulseAudio,
so not everyone will actually have the ALSA PulseAudio plugin configured.
In that case, it is better to use QEMU's PulseAudio backend since that
does not require any configuration. It also lets us drop the alsa-lib
fork, since that was only needed for loading the ALSA PulseAudio plugin.
In general, it seems difficult to detect which audio backend the user
wants to run (if any). Selecting the wrong one results in ugly warnings
when running QEMU. So let's not assume any by default, and add a
--audio option instead which accepts one of QEMU's audio backends
(alsa, pa or sdl).
Add a shortcut for "git pull --ff-only" in all repositories cloned by
pmbootstrap (currently pmaports and aports_upstream, new pmdevices
repository coming soon).
'pmbootstrap pull' will only update the repositories, if:
* they are on an officially supported branch (e.g. master)
* the history is not conflicting (fast-forward is possible)
* the git workdirs are clean
Otherwise it shows the user a descriptive message about what to do. The
list of supported branches is only "master" right now, and will be
extended in later commits, so we can have a stable branch for pmaports
based on Alpine's releases. More about that in the project direction
2020 issue.
Closes: #1858
Remove a legacy code path from back in the day, where pmaports were in
the same repository as pmbootstrap ([1]). Nowadays, pmaports are always in a
git repository, so this is not necessary anymore. If git fails at this
point, crash hard and don't carry on with an empty string.
This is in preparation for using rev_parse in new code paths, so we
don't need to check the return value of rev_parse.
[1] 39548835 "Write custom os-release (closes#324) (#439)"
https://github.com/postmarketOS/pmbootstrap/pull/439
When defining a new kernel subpackage with a "-" in it
(e.g. $pkgname-kernel-mainline-modem), then pmbootstrap is unable to
find the function that builds the subpackage:
ERROR: Could not find subpackage function, no line starts with 'kernel_mainline-modem() {'
This is because it assumes that a $pkgname-kernel-<name> subpackage
is built by a kernel_<name> function, but this does not have to be the case.
We should really respect the name of the subpackage function that
is specified when defining the subpackage, but unfortunately it is
stripped away in cut_off_function_names().
For now let's fix this by replacing "-" with "_", but ideally the
APKBUILD parser API should be refactored to expose the subpackage
function in the future.
This adds a new deviceinfo parameter, 'boot_part_start' which accepts an
int and indicates the number of sectors from the start of the drive to
place the boot partition.
The librem5 devkit (and actual phone) u-boot has grown beyond the 2048
sector space previously before the boot partition, so this is necessary in
order to boot pmos on this device.
Install rust (rustc) in native chroot, if it is in the APKBUILD's
build dependencies. Add a test to verify that crossdirect + rust works
as expected.
Closes: #1861
Rust packaging is new and still a bit weird in Alpine and postmarketOS.
As of writing, we only have one package (squeekboard), and use cargo to
download the source of all dependencies at build time (several git
repositories!) and compile it. Usually, this is a no-go, but at least
until this is resolved properly, let's cache the downloads as suggested
in: https://doc.rust-lang.org/cargo/guide/cargo-home.html
Related: #1861
When initializing the building chroots, some symlinks are created to
/mnt/pmbootstrap* dirs. With upcoming rust-related symlinks, they will
point to subdirs in /mnt/pmbootstrap-rust, such as
/mnt/pmbootstrap-rust/registry/cache. Create this directory structure if
it does not exist.
Do not install git in the native chroot and use it from there. Remove the
chown_to_user argument from pmb.helpers.git.clone(), the resulting dir
is now always owned by the user. While at it, refactor the function and
display the clone URL.
Previously we had cloned aports_upstream (from Alpine) with
chown_to_user=False (legacy) and pmaports with chown_to_user=True.
pmb.helpers.git.rev_parse() would only work after chown_to_user=True.
Check if git is installed in "pmbootstrap init", and remove the same
check from rev_parse(). Add a new work dir version, that checks for git
and changes ownership of already checked out aports_upstream to the
host system's user.
When creating a new work dir, create cache_git instead of cache_http.
cache_http is created on demand already, with proper permissions. But
cache_git must be created, otherwise pmb.helpers.mount.bind will create it
as root.
This is in preparation for the "pmbootstrap pull" feature, as it allows
using the host system's git in all new code paths. We will be able to
handle repositories even if they were cloned outside of the work dir
(which we do in a few CI scripts for example).
Related: #1858
Remove /home/pmos/git from pmb.config.chroot_home_symlinks, so
pmb.chroot.init.init() will not change the ownership of the
$WORK/cache_git dir.
The symlink was added two years ago in [1] as compatibility to previous
behavior, because the mountpoint of cache_git was changed from
/home/user/git to /mnt/pmbootstrap-git. Forcing the ownership of that
dir to be the pmos user inside the chroot made sense, because the only
cloned repository (aports_upstream) would also be owned by the pmos
user. With the upcoming change to have all cloned repos owned by the
host-system's user, this is just confusing.
The /home/pmos/git symlink does not seem to be used by anybody, it is
not mentioned in the pmbootstrap code and in the wiki.
[1] b4dd7a89 "Close #709: Improve user creation (#725)"
https://github.com/postmarketOS/pmbootstrap/pull/725
The APKBUILD reference for "provides" [1] is not worded clearly; but
after reading it over and over again, my understanding is:
* package with provides='foo=1.2' will be automatically installed if
user requests installing "foo"
* package with provides='foo' (without version) will NOT get
automatically installed if user requests installing "foo"
For pmbootstrap, this means, that we must not attempt to build a package
where the pkgname mentioned in provides matches what we are currently
resolving, unless there is an equals sign in the provides entry.
Fixes: #1862, pmaports#404
[1] https://wiki.alpinelinux.org/wiki/APKBUILD_Reference#provides says:
"List of package names (and optionally version info) this package
provides.
If package with a version is provided (provides='foo=1.2') apk will
consider it as an alternate name and it will automatically consider the
package for installation by the alternate name, and conflict with other
packages having the same name, or provides.
If version is not provided (provides='foo'), apk will consider it as
virtual package name. Several package with same non-versioned provides
can be installed simultaneously. However, none of them will be installed
by default when requested by the virtual name - instead, error message
is given and user is asked to choose which package providing the virtual
name should be installed."
Changes:
* Added the ALSA_PLUGIN_DIRS environment variable otherwise it tries
to load the plugins of the host pc and they fails.
* Added the /usr/lib/pulseaudio path to the library-path argument
* Added the audiodev and soundhw parameters to the qemu command
* Added the required packages necessary to be installed in the chroot
Adjust to new text that "file" outputs for ARM linux kernels:
"ARM OpenFirmware FORTH Dictionary..."
Make test_bootimg_kernel pass again, which was failing with:
AssertionError: assert 'heimdall-isorec' in 'File is not an Android ...
This fixes#1845 without breaking #1717 (closed). The amount of inodes
only needs to be explicitly set when we don't know the size of the
filesystem before hand, for example when using fastboot or Heimdall. In
all other cases it's actually better to let it figure out automatically
how many inodes is set.
On my 16GB sdcard the amount of available inodes got increased by 10
times (from ~100K to ~1M).
Add default user to netdev group. Together with MR [1] in pmaports.git,
this fixes the permissions to use nmtui and nm-applet from the user.
[1] https://gitlab.com/postmarketOS/pmaports/merge_requests/777
Signed-off-by: Danct12 <danct12@disroot.org>
Properly ignore comments at the end of lines, instead of assuming that
all lines below belong to the attribute:
subpackages="$pkgname-dev" # $pkgname-lang
Fixes build.postmarketos.org#61, where pmbootstrap would assume that a
random package provides "make", just because the word "make" is written
somewhere below subpackages=" in the APKBUILD and it is parsed
incorrectly.
While at it, also support the ' character for quotations and detect if
a quotation for a value was started, but there is no end quotation sign
in the rest of the file.
I've added tests, and manually checked that this did not introduce any
parsing bugs for all the APKBUILDs in pmaports.git, by running
'pmbootstrap apkbuild_parse' with the old and new code, and diffing the
result.
Because of an APKINDEX subpkg parsing bug, pmbootstrap currently assumes
that "ktp-common-internals" provides "make". It fails with a cryptic
error when trying to build a package without an existing postmarketOS
binary packages mirror (like done in the build.postmarketos.org
testsuite):
File "/home/user/code/pmbootstrap/pmb/chroot/apk.py", line 174, in replace_aports_packages_with_path
package + "-" + data_repo["version"] + ".apk")
TypeError: 'NoneType' object is not subscriptable
Replace this error with a more meaningful message, that points to the
issue analyzing this bug.
Related: https://gitlab.com/postmarketOS/build.postmarketos.org/issues/61
Always install git when building packages, so abuild won't behave
slightly different if it is (not) installed. As nice side-effect, we
will always get the pmaports.git commit saved in the resulting .apk file
from now on (in .PKGINFO).