2017-05-26 20:08:45 +00:00
|
|
|
"""
|
|
|
|
Copyright 2017 Oliver Smith
|
|
|
|
|
|
|
|
This file is part of pmbootstrap.
|
|
|
|
|
|
|
|
pmbootstrap is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
pmbootstrap is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
"""
|
|
|
|
import logging
|
2017-08-18 16:25:58 +00:00
|
|
|
import glob
|
2017-05-26 20:08:45 +00:00
|
|
|
import os
|
|
|
|
|
|
|
|
import pmb.config
|
|
|
|
import pmb.helpers.cli
|
|
|
|
import pmb.helpers.devices
|
2017-10-13 19:18:24 +00:00
|
|
|
import pmb.helpers.run
|
2017-07-24 20:55:55 +00:00
|
|
|
import pmb.helpers.ui
|
2017-08-18 16:25:58 +00:00
|
|
|
import pmb.chroot.zap
|
2017-08-19 21:40:20 +00:00
|
|
|
import pmb.parse.deviceinfo
|
2017-05-26 20:08:45 +00:00
|
|
|
|
|
|
|
|
2017-07-26 17:05:06 +00:00
|
|
|
def ask_for_work_path(args):
|
|
|
|
"""
|
2017-07-27 17:33:23 +00:00
|
|
|
Ask for the work path, until we can create it (when it does not exist) and
|
|
|
|
write into it.
|
2017-07-26 17:05:06 +00:00
|
|
|
:returns: the work path
|
|
|
|
"""
|
|
|
|
logging.info("Location of the 'work' path. Multiple chroots"
|
|
|
|
" (native, device arch, device rootfs) will be created"
|
|
|
|
" in there.")
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
ret = os.path.expanduser(pmb.helpers.cli.ask(
|
|
|
|
args, "Work path", None, args.work, False))
|
2017-11-04 02:04:55 +00:00
|
|
|
ret = os.path.realpath(ret)
|
|
|
|
|
|
|
|
# Work must not be inside the pmbootstrap path
|
|
|
|
if ret == pmb.config.pmb_src or ret.startswith(pmb.config.pmb_src +
|
|
|
|
"/"):
|
|
|
|
logging.fatal("ERROR: The work path must not be inside the"
|
|
|
|
" pmbootstrap path. Please specify another"
|
|
|
|
" location.")
|
|
|
|
continue
|
2017-10-12 20:08:10 +00:00
|
|
|
|
|
|
|
# Create the folder with a version file
|
|
|
|
if not os.path.exists(ret):
|
|
|
|
os.makedirs(ret, 0o700, True)
|
|
|
|
with open(ret + "/version", "w") as handle:
|
|
|
|
handle.write(pmb.config.work_version + "\n")
|
|
|
|
|
|
|
|
# Make sure, that we can write into it
|
2017-08-18 16:25:58 +00:00
|
|
|
os.makedirs(ret + "/cache_http", 0o700, True)
|
2017-07-26 17:05:06 +00:00
|
|
|
return ret
|
|
|
|
except OSError:
|
|
|
|
logging.fatal("ERROR: Could not create this folder, or write"
|
|
|
|
" inside it! Please try again.")
|
|
|
|
|
|
|
|
|
|
|
|
def ask_for_ui(args):
|
|
|
|
ui_list = pmb.helpers.ui.list(args)
|
|
|
|
logging.info("Available user interfaces (" +
|
2017-10-16 20:01:21 +00:00
|
|
|
str(len(ui_list) - 1) + "): ")
|
|
|
|
for ui, description in ui_list.items():
|
|
|
|
logging.info("* " + ui + ": " + description)
|
2017-07-26 17:05:06 +00:00
|
|
|
while True:
|
2017-07-27 17:33:23 +00:00
|
|
|
ret = pmb.helpers.cli.ask(args, "User interface", None, args.ui, True)
|
2017-07-26 17:05:06 +00:00
|
|
|
if ret in ui_list:
|
|
|
|
return ret
|
|
|
|
logging.fatal("ERROR: Invalid user interface specified, please type in"
|
|
|
|
" one from the list above.")
|
|
|
|
|
|
|
|
|
2017-08-19 21:40:20 +00:00
|
|
|
def ask_for_keymaps(args, device):
|
|
|
|
info = pmb.parse.deviceinfo(args, device=device)
|
|
|
|
if "keymaps" not in info or info["keymaps"].strip() == "":
|
|
|
|
return ""
|
|
|
|
options = info["keymaps"].split(' ')
|
|
|
|
logging.info("Available keymaps for device (" + str(len(options)) +
|
|
|
|
"): " + ", ".join(options))
|
|
|
|
if args.keymap is "":
|
|
|
|
args.keymap = options[0]
|
|
|
|
|
|
|
|
while True:
|
|
|
|
ret = pmb.helpers.cli.ask(args, "Keymap", None, args.keymap, True)
|
|
|
|
if ret in options:
|
|
|
|
return ret
|
|
|
|
logging.fatal("ERROR: Invalid keymap specified, please type in"
|
|
|
|
" one from the list above.")
|
|
|
|
|
|
|
|
|
2017-10-13 19:18:24 +00:00
|
|
|
def ask_for_timezone(args):
|
|
|
|
localtimes = ["/etc/zoneinfo/localtime", "/etc/localtime"]
|
|
|
|
zoneinfo_path = "/usr/share/zoneinfo/"
|
|
|
|
for localtime in localtimes:
|
|
|
|
if not os.path.exists(localtime):
|
|
|
|
continue
|
|
|
|
tz = ""
|
|
|
|
if os.path.exists(localtime):
|
|
|
|
tzpath = os.path.realpath(localtime)
|
|
|
|
tzpath = tzpath.rstrip()
|
|
|
|
if os.path.exists(tzpath):
|
|
|
|
try:
|
|
|
|
_, tz = tzpath.split(zoneinfo_path)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
if tz:
|
|
|
|
logging.info("Your host timezone: " + tz)
|
|
|
|
if pmb.helpers.cli.confirm(args, "Use this timezone instead of GMT?",
|
|
|
|
default="y"):
|
|
|
|
return tz
|
2017-12-21 16:42:29 +00:00
|
|
|
logging.info("WARNING: Unable to determine timezone configuration on host,"
|
|
|
|
" using GMT.")
|
2017-10-13 19:18:24 +00:00
|
|
|
return "GMT"
|
|
|
|
|
|
|
|
|
2017-10-30 19:56:38 +00:00
|
|
|
def ask_for_device(args):
|
2017-05-26 20:08:45 +00:00
|
|
|
devices = sorted(pmb.helpers.devices.list(args))
|
|
|
|
logging.info("Target device (either an existing one, or a new one for"
|
2017-07-05 16:49:52 +00:00
|
|
|
" porting).")
|
|
|
|
logging.info("Available (" + str(len(devices)) + "): " +
|
|
|
|
", ".join(devices))
|
2017-10-30 19:56:38 +00:00
|
|
|
while True:
|
|
|
|
device = pmb.helpers.cli.ask(args, "Device", None, args.device, False,
|
|
|
|
"[a-z0-9]+-[a-z0-9]+")
|
|
|
|
device_exists = os.path.exists(args.aports + "/device/device-" +
|
|
|
|
device + "/deviceinfo")
|
|
|
|
if not device_exists:
|
|
|
|
logging.info("You are about to do a new device port for '" +
|
|
|
|
device + "'.")
|
|
|
|
if not pmb.helpers.cli.confirm(args, default=True):
|
|
|
|
continue
|
|
|
|
|
|
|
|
pmb.aportgen.generate(args, "device-" + device)
|
|
|
|
pmb.aportgen.generate(args, "linux-" + device)
|
|
|
|
break
|
2017-07-24 20:55:55 +00:00
|
|
|
|
2017-10-30 19:56:38 +00:00
|
|
|
return (device, device_exists)
|
|
|
|
|
|
|
|
|
Close #453: Support mesa-dri-virtio in Qemu (#861)
The mesa driver, which ends up in the installation image, needs to be known
before the installation is done (in other words: when running the qemu action,
it is to late as the image has already been generated). That's why one can
choose the Qemu mesa driver in `pmbootstrap init` now:
```
Device [qemu-amd64]:
Which mesa driver do you prefer for your Qemu device? Only select something other
than the default if you are having graphical problems (such as glitches).
Mesa driver (dri-swrast/dri-virtio) [dri-virtio]:
```
It is still possible to select `dri-swrast`, because `dri-virtio` may not work
in all cases, and that way we could easily debug it or experiment with other
mesa drivers (e.g. the "vmware" one, which is supported by mesa and Qemu).
Other changes:
* `pmbootstrap qemu` accepts a `--display` variable now, which passes the value
directly to `qemu`'s `display` option. It defaults to `sdl,gl=on` (@PureTryOut
reported that to work best with plasma mobile on his PC). `--display` and
`--spice` (which is still working) are mutually exclusive.
* Removed obsolete telnet port pass-through: We only use the debug telnet port
since osk-sdl has been merged.
* Add show-cursor to the Qemu command line, so it shows a cursor in X11
* Refactored the spice code (`command_spice` only returns the spice command,
because it has all necessary information already) and the spice port can be
specified on the commandline now (previously it was hardcoded in one place and
then always looked up from there).
* Start comments with capital letters.
* Keep the log on the screen a bit shorter (e.g. Qemu command is written to the
"pmbootstrap log" anyway, so there's no need to display it again).
* linux-postmarketos-stable: Adjust kernel configs
x86_64, armhf: enable as modules:
CONFIG_DRM_VIRTIO_GPU, CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_BALLOON
aarch64: all 3 options were already enabled as built-in (no change)
* Set '-vga virtio' for mesa-dri-virtio
2017-11-05 13:48:49 +00:00
|
|
|
def ask_for_qemu_mesa_driver(args):
|
|
|
|
drivers = pmb.config.qemu_mesa_drivers
|
|
|
|
logging.info("Which mesa driver do you prefer for your Qemu device? Only"
|
|
|
|
" select something other than the default if you are having"
|
|
|
|
" graphical problems (such as glitches).")
|
|
|
|
while True:
|
|
|
|
ret = pmb.helpers.cli.ask(args, "Mesa driver", drivers,
|
|
|
|
args.qemu_mesa_driver)
|
|
|
|
if ret in drivers:
|
|
|
|
return ret
|
|
|
|
logging.fatal("ERROR: Please specify a driver from the list. To change"
|
|
|
|
" it, see qemu_mesa_drivers in pmb/config/__init__.py.")
|
|
|
|
|
|
|
|
|
2017-12-21 16:42:29 +00:00
|
|
|
def ask_for_build_options(args, cfg):
|
|
|
|
# Allow to skip build options
|
|
|
|
ts_rebuild = "True" if args.timestamp_based_rebuild else "False"
|
|
|
|
logging.info("Build options: Parallel jobs: " + args.jobs +
|
|
|
|
", ccache per arch: " + args.ccache_size +
|
|
|
|
", timestamp based rebuilds: " + ts_rebuild)
|
|
|
|
|
|
|
|
if not pmb.helpers.cli.confirm(args, "Change them?",
|
|
|
|
default=False):
|
|
|
|
return
|
|
|
|
|
|
|
|
# Parallel job count
|
|
|
|
logging.info("How many jobs should run parallel on this machine, when"
|
|
|
|
" compiling?")
|
|
|
|
answer = pmb.helpers.cli.ask(args, "Jobs", None, args.jobs,
|
|
|
|
validation_regex="[1-9][0-9]*")
|
|
|
|
cfg["pmbootstrap"]["jobs"] = answer
|
|
|
|
|
|
|
|
# Ccache size
|
|
|
|
logging.info("We use ccache to speed up building the same code multiple"
|
|
|
|
" times. How much space should the ccache folder take up per"
|
|
|
|
" architecture? After init is through, you can check the current"
|
|
|
|
" usage with 'pmbootstrap stats'. Answer with 0 for infinite.")
|
|
|
|
regex = "0|[0-9]+(k|M|G|T|Ki|Mi|Gi|Ti)"
|
|
|
|
answer = pmb.helpers.cli.ask(args, "Ccache size", None, args.ccache_size,
|
|
|
|
lowercase_answer=False, validation_regex=regex)
|
|
|
|
cfg["pmbootstrap"]["ccache_size"] = answer
|
|
|
|
|
|
|
|
# Timestamp based rebuilds
|
|
|
|
logging.info("Rebuild packages, when the last modified timestamp changed,"
|
|
|
|
" even if the version did not change?"
|
|
|
|
" This makes pmbootstrap behave more like 'make'.")
|
|
|
|
answer = pmb.helpers.cli.confirm(args, "Timestamp based rebuilds",
|
|
|
|
default=args.timestamp_based_rebuild)
|
|
|
|
cfg["pmbootstrap"]["timestamp_based_rebuild"] = str(answer)
|
|
|
|
|
|
|
|
|
2017-10-30 19:56:38 +00:00
|
|
|
def frontend(args):
|
|
|
|
cfg = pmb.config.load(args)
|
|
|
|
|
|
|
|
# Device
|
|
|
|
cfg["pmbootstrap"]["device"], device_exists = ask_for_device(args)
|
2017-08-19 16:04:53 +00:00
|
|
|
|
Close #453: Support mesa-dri-virtio in Qemu (#861)
The mesa driver, which ends up in the installation image, needs to be known
before the installation is done (in other words: when running the qemu action,
it is to late as the image has already been generated). That's why one can
choose the Qemu mesa driver in `pmbootstrap init` now:
```
Device [qemu-amd64]:
Which mesa driver do you prefer for your Qemu device? Only select something other
than the default if you are having graphical problems (such as glitches).
Mesa driver (dri-swrast/dri-virtio) [dri-virtio]:
```
It is still possible to select `dri-swrast`, because `dri-virtio` may not work
in all cases, and that way we could easily debug it or experiment with other
mesa drivers (e.g. the "vmware" one, which is supported by mesa and Qemu).
Other changes:
* `pmbootstrap qemu` accepts a `--display` variable now, which passes the value
directly to `qemu`'s `display` option. It defaults to `sdl,gl=on` (@PureTryOut
reported that to work best with plasma mobile on his PC). `--display` and
`--spice` (which is still working) are mutually exclusive.
* Removed obsolete telnet port pass-through: We only use the debug telnet port
since osk-sdl has been merged.
* Add show-cursor to the Qemu command line, so it shows a cursor in X11
* Refactored the spice code (`command_spice` only returns the spice command,
because it has all necessary information already) and the spice port can be
specified on the commandline now (previously it was hardcoded in one place and
then always looked up from there).
* Start comments with capital letters.
* Keep the log on the screen a bit shorter (e.g. Qemu command is written to the
"pmbootstrap log" anyway, so there's no need to display it again).
* linux-postmarketos-stable: Adjust kernel configs
x86_64, armhf: enable as modules:
CONFIG_DRM_VIRTIO_GPU, CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_BALLOON
aarch64: all 3 options were already enabled as built-in (no change)
* Set '-vga virtio' for mesa-dri-virtio
2017-11-05 13:48:49 +00:00
|
|
|
# Qemu mesa driver
|
|
|
|
if cfg["pmbootstrap"]["device"].startswith("qemu-"):
|
|
|
|
cfg["pmbootstrap"]["qemu_mesa_driver"] = ask_for_qemu_mesa_driver(args)
|
|
|
|
|
2017-08-19 21:40:20 +00:00
|
|
|
# Device keymap
|
|
|
|
if device_exists:
|
2017-12-21 16:42:29 +00:00
|
|
|
cfg["pmbootstrap"]["keymap"] = ask_for_keymaps(
|
|
|
|
args, device=cfg["pmbootstrap"]["device"])
|
2017-08-19 21:40:20 +00:00
|
|
|
|
2017-10-12 20:08:10 +00:00
|
|
|
# Username
|
|
|
|
cfg["pmbootstrap"]["user"] = pmb.helpers.cli.ask(args, "Username", None,
|
|
|
|
args.user, False,
|
|
|
|
"[a-z_][a-z0-9_-]*")
|
2017-07-26 17:05:06 +00:00
|
|
|
# UI and work folder
|
|
|
|
cfg["pmbootstrap"]["ui"] = ask_for_ui(args)
|
|
|
|
cfg["pmbootstrap"]["work"] = ask_for_work_path(args)
|
2017-05-26 20:08:45 +00:00
|
|
|
|
2017-12-21 16:42:29 +00:00
|
|
|
# Various build options
|
|
|
|
ask_for_build_options(args, cfg)
|
2017-05-26 20:08:45 +00:00
|
|
|
|
2017-08-01 15:31:33 +00:00
|
|
|
# Extra packages to be installed to rootfs
|
|
|
|
logging.info("Additional packages that will be installed to rootfs."
|
|
|
|
" Specify them in a comma separated list (e.g.: vim,file)"
|
|
|
|
" or \"none\"")
|
|
|
|
cfg["pmbootstrap"]["extra_packages"] = pmb.helpers.cli.ask(args, "Extra packages",
|
|
|
|
None, args.extra_packages,
|
2017-09-10 10:25:23 +00:00
|
|
|
validation_regex="^(|[-.+\w\s]+(?:,[-.+\w\s]*)*)$")
|
2017-08-01 15:31:33 +00:00
|
|
|
|
2017-10-13 19:18:24 +00:00
|
|
|
# Configure timezone info
|
|
|
|
cfg["pmbootstrap"]["timezone"] = ask_for_timezone(args)
|
|
|
|
|
2017-05-26 20:08:45 +00:00
|
|
|
# Save config
|
|
|
|
pmb.config.save(args, cfg)
|
|
|
|
|
2017-09-07 19:58:19 +00:00
|
|
|
# Zap existing chroots
|
|
|
|
setattr(args, "work", cfg["pmbootstrap"]["work"])
|
2017-08-19 16:04:53 +00:00
|
|
|
if (device_exists and
|
|
|
|
len(glob.glob(args.work + "/chroot_*")) and
|
|
|
|
pmb.helpers.cli.confirm(args, "Zap existing chroots to apply configuration?", default=True)):
|
2017-12-21 16:42:29 +00:00
|
|
|
setattr(args, "deviceinfo", pmb.parse.deviceinfo(
|
|
|
|
args, device=cfg["pmbootstrap"]["device"]))
|
2017-08-18 16:25:58 +00:00
|
|
|
# Do not zap any existing packages or cache_http directories
|
|
|
|
pmb.chroot.zap(args, confirm=False)
|
|
|
|
|
2017-05-26 20:08:45 +00:00
|
|
|
logging.info(
|
|
|
|
"WARNING: The applications in the chroots do not get updated automatically.")
|
|
|
|
logging.info("Run 'pmbootstrap zap' to delete all chroots once a day before"
|
|
|
|
" working with pmbootstrap!")
|
|
|
|
logging.info("It only takes a few seconds, and all packages are cached.")
|
2017-08-18 16:25:58 +00:00
|
|
|
|
2017-05-26 20:08:45 +00:00
|
|
|
logging.info("Done!")
|