2020-02-20 20:07:28 +00:00
|
|
|
# Copyright 2020 Oliver Smith
|
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2017-05-26 20:08:45 +00:00
|
|
|
import logging
|
2017-08-18 16:25:58 +00:00
|
|
|
import glob
|
2017-05-26 20:08:45 +00:00
|
|
|
import os
|
2019-12-22 09:58:36 +00:00
|
|
|
import shutil
|
2017-05-26 20:08:45 +00:00
|
|
|
|
|
|
|
import pmb.config
|
2018-09-05 05:57:38 +00:00
|
|
|
import pmb.config.pmaports
|
2017-05-26 20:08:45 +00:00
|
|
|
import pmb.helpers.cli
|
|
|
|
import pmb.helpers.devices
|
2018-09-05 05:57:38 +00:00
|
|
|
import pmb.helpers.logging
|
2019-12-22 10:30:51 +00:00
|
|
|
import pmb.helpers.other
|
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
|
2018-02-24 21:49:10 +00:00
|
|
|
import pmb.parse._apkbuild
|
2017-05-26 20:08:45 +00:00
|
|
|
|
|
|
|
|
2019-12-22 09:58:36 +00:00
|
|
|
def require_programs():
|
|
|
|
missing = []
|
|
|
|
for program in pmb.config.required_programs:
|
|
|
|
if not shutil.which(program):
|
|
|
|
missing.append(program)
|
|
|
|
if missing:
|
|
|
|
raise RuntimeError("Can't find all programs required to run"
|
|
|
|
" pmbootstrap. Please install first: " +
|
|
|
|
", ".join(missing))
|
|
|
|
|
|
|
|
|
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.
|
2018-09-05 05:57:38 +00:00
|
|
|
:returns: (path, exists)
|
|
|
|
* path: is the full path, with expanded ~ sign
|
|
|
|
* exists: is False when the folder did not exist before we tested
|
|
|
|
whether we can create it
|
2017-07-26 17:05:06 +00:00
|
|
|
"""
|
|
|
|
logging.info("Location of the 'work' path. Multiple chroots"
|
|
|
|
" (native, device arch, device rootfs) will be created"
|
|
|
|
" in there.")
|
|
|
|
while True:
|
|
|
|
try:
|
2018-09-05 05:57:38 +00:00
|
|
|
work = os.path.expanduser(pmb.helpers.cli.ask(
|
2017-07-26 17:05:06 +00:00
|
|
|
args, "Work path", None, args.work, False))
|
2018-09-05 05:57:38 +00:00
|
|
|
work = os.path.realpath(work)
|
|
|
|
exists = os.path.exists(work)
|
2017-11-04 02:04:55 +00:00
|
|
|
|
|
|
|
# Work must not be inside the pmbootstrap path
|
2018-09-05 05:57:38 +00:00
|
|
|
if (work == pmb.config.pmb_src or
|
|
|
|
work.startswith(pmb.config.pmb_src + "/")):
|
2017-11-04 02:04:55 +00:00
|
|
|
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
|
2018-09-05 05:57:38 +00:00
|
|
|
if not exists:
|
|
|
|
os.makedirs(work, 0o700, True)
|
|
|
|
with open(work + "/version", "w") as handle:
|
2018-03-30 21:46:31 +00:00
|
|
|
handle.write(str(pmb.config.work_version) + "\n")
|
2017-10-12 20:08:10 +00:00
|
|
|
|
2019-12-22 11:11:21 +00:00
|
|
|
# Create cache_git dir, so it is owned by the host system's user
|
|
|
|
# (otherwise pmb.helpers.mount.bind would create it as root)
|
|
|
|
os.makedirs(work + "/cache_git", 0o700, True)
|
2018-09-05 05:57:38 +00:00
|
|
|
return (work, exists)
|
2017-07-26 17:05:06 +00:00
|
|
|
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) + "): ")
|
2020-02-18 15:02:59 +00:00
|
|
|
ui_completion_list = []
|
2018-01-07 03:55:27 +00:00
|
|
|
for ui in ui_list:
|
|
|
|
logging.info("* " + ui[0] + ": " + ui[1])
|
2020-02-18 15:02:59 +00:00
|
|
|
ui_completion_list.append(ui[0])
|
2017-07-26 17:05:06 +00:00
|
|
|
while True:
|
2020-02-18 15:02:59 +00:00
|
|
|
ret = pmb.helpers.cli.ask(args, "User interface", None, args.ui, True,
|
|
|
|
complete=ui_completion_list)
|
2018-01-07 03:55:27 +00:00
|
|
|
if ret in dict(ui_list).keys():
|
2017-07-26 17:05:06 +00:00
|
|
|
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):
|
2018-01-08 15:18:37 +00:00
|
|
|
info = pmb.parse.deviceinfo(args, device)
|
2017-08-19 21:40:20 +00:00
|
|
|
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))
|
2019-02-02 22:30:49 +00:00
|
|
|
if args.keymap == "":
|
2017-08-19 21:40:20 +00:00
|
|
|
args.keymap = options[0]
|
|
|
|
|
|
|
|
while True:
|
2020-02-18 15:02:59 +00:00
|
|
|
ret = pmb.helpers.cli.ask(args, "Keymap", None, args.keymap,
|
|
|
|
True, complete=options)
|
2017-08-19 21:40:20 +00:00
|
|
|
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"
|
|
|
|
|
|
|
|
|
pmbootstrap init: kernel selection / remove linux-pmos-lts (#1363)
* As discussed in IRC/matrix, we're removing `linux-postmarketos-lts`
for now. The kernel isn't used right now, and we save lots of
maintenance effort with not updating it every week or so.
* new config option `"kernel"` with possible values:
`"downstream", "mainline", "stable"` (downstream is always
`linux-$devicename`)
* ask for the kernel during `pmbootstrap init` if the device package
has kernel subpackages and install it in `_install.py`
* postmarketos-mkinitfs: display note instead of exit with error when
the `deviceinfo_dtb` file is missing (because we expect it to be
missing for downstream kernels)
* device-sony-amami:
* add kernel subpackages for downstream, mainline
* set `deviceinfo_dtb`
* device-qemu-amd64: add kernel subpackages for stable, lts, mainline
* test cases and test data for new functions
* test case that checks all aports for right usage of the feature:
* don't mix specifying kernels in depends *and* subpackages
* 1 kernel in depends is maximum
* kernel subpackages must have a valid name
* Test if devices packages reference at least one kernel
* Remove `_build_device_depends_note()` which informs the user that
`--ignore-depends` can be used with device packages to avoid building
the kernel. The idea was to make the transition easier after a change
we did months ago, and now the kernel doesn't always get built before
building the device package so it's not relevant anymore.
* pmb/chroot/other.py:
* Add autoinstall=True to kernel_flavors_installed(). When the flag
is set, the function makes sure that at least one kernel for the
device is installed.
* Remove kernel_flavor_autodetect() function, wherever it was used,
it has been replaced with kernel_flavors_installed()[0].
* pmb.helpers.frontend.py: remove code to install at least one kernel,
kernel_flavors_installed() takes care of that now.
2018-04-03 23:50:09 +00:00
|
|
|
def ask_for_device_kernel(args, device):
|
|
|
|
"""
|
|
|
|
Ask for the kernel that should be used with the device.
|
|
|
|
|
|
|
|
:param device: code name, e.g. "lg-mako"
|
|
|
|
:returns: None if the kernel is hardcoded in depends without subpackages
|
|
|
|
:returns: kernel type ("downstream", "stable", "mainline", ...)
|
|
|
|
"""
|
|
|
|
# Get kernels
|
|
|
|
kernels = pmb.parse._apkbuild.kernels(args, device)
|
|
|
|
if not kernels:
|
|
|
|
return args.kernel
|
|
|
|
|
|
|
|
# Get default
|
|
|
|
default = args.kernel
|
|
|
|
if default not in kernels:
|
|
|
|
default = list(kernels.keys())[0]
|
|
|
|
|
|
|
|
# Ask for kernel (extra message when downstream and upstream are available)
|
|
|
|
logging.info("Which kernel do you want to use with your device?")
|
|
|
|
if "downstream" in kernels:
|
|
|
|
logging.info("Downstream kernels are typically the outdated Android"
|
|
|
|
" kernel forks.")
|
|
|
|
if "downstream" in kernels and len(kernels) > 1:
|
|
|
|
logging.info("Upstream kernels (mainline, stable, ...) get security"
|
|
|
|
" updates, but may have less working features than"
|
|
|
|
" downstream kernels.")
|
|
|
|
|
|
|
|
# List kernels
|
|
|
|
logging.info("Available kernels (" + str(len(kernels)) + "):")
|
|
|
|
for type in sorted(kernels.keys()):
|
|
|
|
logging.info("* " + type + ": " + kernels[type])
|
|
|
|
while True:
|
2020-02-18 15:02:59 +00:00
|
|
|
ret = pmb.helpers.cli.ask(args, "Kernel", None, default, True,
|
|
|
|
complete=kernels)
|
pmbootstrap init: kernel selection / remove linux-pmos-lts (#1363)
* As discussed in IRC/matrix, we're removing `linux-postmarketos-lts`
for now. The kernel isn't used right now, and we save lots of
maintenance effort with not updating it every week or so.
* new config option `"kernel"` with possible values:
`"downstream", "mainline", "stable"` (downstream is always
`linux-$devicename`)
* ask for the kernel during `pmbootstrap init` if the device package
has kernel subpackages and install it in `_install.py`
* postmarketos-mkinitfs: display note instead of exit with error when
the `deviceinfo_dtb` file is missing (because we expect it to be
missing for downstream kernels)
* device-sony-amami:
* add kernel subpackages for downstream, mainline
* set `deviceinfo_dtb`
* device-qemu-amd64: add kernel subpackages for stable, lts, mainline
* test cases and test data for new functions
* test case that checks all aports for right usage of the feature:
* don't mix specifying kernels in depends *and* subpackages
* 1 kernel in depends is maximum
* kernel subpackages must have a valid name
* Test if devices packages reference at least one kernel
* Remove `_build_device_depends_note()` which informs the user that
`--ignore-depends` can be used with device packages to avoid building
the kernel. The idea was to make the transition easier after a change
we did months ago, and now the kernel doesn't always get built before
building the device package so it's not relevant anymore.
* pmb/chroot/other.py:
* Add autoinstall=True to kernel_flavors_installed(). When the flag
is set, the function makes sure that at least one kernel for the
device is installed.
* Remove kernel_flavor_autodetect() function, wherever it was used,
it has been replaced with kernel_flavors_installed()[0].
* pmb.helpers.frontend.py: remove code to install at least one kernel,
kernel_flavors_installed() takes care of that now.
2018-04-03 23:50:09 +00:00
|
|
|
if ret in kernels.keys():
|
|
|
|
return ret
|
|
|
|
logging.fatal("ERROR: Invalid kernel specified, please type in one"
|
|
|
|
" from the list above.")
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
2018-02-24 21:49:10 +00:00
|
|
|
def ask_for_device_nonfree(args, device):
|
|
|
|
"""
|
|
|
|
Ask the user about enabling proprietary firmware (e.g. Wifi) and userland
|
|
|
|
(e.g. GPU drivers). All proprietary components are in subpackages
|
|
|
|
$pkgname-nonfree-firmware and $pkgname-nonfree-userland, and we show the
|
|
|
|
description of these subpackages (so they can indicate which peripherals
|
|
|
|
are affected).
|
|
|
|
|
|
|
|
:returns: answers as dict, e.g. {"firmware": True, "userland": False}
|
|
|
|
"""
|
|
|
|
# Parse existing APKBUILD or return defaults (when called from test case)
|
|
|
|
apkbuild_path = args.aports + "/device/device-" + device + "/APKBUILD"
|
|
|
|
ret = {"firmware": args.nonfree_firmware,
|
|
|
|
"userland": args.nonfree_userland}
|
|
|
|
if not os.path.exists(apkbuild_path):
|
|
|
|
return ret
|
|
|
|
apkbuild = pmb.parse.apkbuild(args, apkbuild_path)
|
|
|
|
|
|
|
|
# Only run when there is a "nonfree" subpackage
|
|
|
|
nonfree_found = False
|
2020-01-27 23:23:09 +00:00
|
|
|
for subpackage in apkbuild["subpackages"].keys():
|
2018-02-24 21:49:10 +00:00
|
|
|
if subpackage.startswith("device-" + device + "-nonfree"):
|
|
|
|
nonfree_found = True
|
|
|
|
if not nonfree_found:
|
|
|
|
return ret
|
|
|
|
|
|
|
|
# Short explanation
|
|
|
|
logging.info("This device has proprietary components, which trade some of"
|
|
|
|
" your freedom with making more peripherals work.")
|
|
|
|
logging.info("We would like to offer full functionality without hurting"
|
|
|
|
" your freedom, but this is currently not possible for your"
|
|
|
|
" device.")
|
|
|
|
|
|
|
|
# Ask for firmware and userland individually
|
|
|
|
for type in ["firmware", "userland"]:
|
|
|
|
subpkgname = "device-" + device + "-nonfree-" + type
|
2020-01-27 23:23:09 +00:00
|
|
|
subpkg = apkbuild["subpackages"].get(subpkgname, {})
|
|
|
|
if subpkg is None:
|
|
|
|
raise RuntimeError("Cannot find subpackage function for " + subpkgname)
|
|
|
|
if subpkg:
|
|
|
|
logging.info(subpkgname + ": " + subpkg["pkgdesc"])
|
2018-02-24 21:49:10 +00:00
|
|
|
ret[type] = pmb.helpers.cli.confirm(args, "Enable this package?",
|
|
|
|
default=ret[type])
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
2017-10-30 19:56:38 +00:00
|
|
|
def ask_for_device(args):
|
2019-10-13 14:09:32 +00:00
|
|
|
vendors = sorted(pmb.helpers.devices.list_vendors(args))
|
|
|
|
logging.info("Choose your target device vendor (either an "
|
|
|
|
"existing one, or a new one for porting).")
|
|
|
|
logging.info("Available vendors (" + str(len(vendors)) + "): " +
|
|
|
|
", ".join(vendors))
|
|
|
|
|
|
|
|
current_vendor = None
|
|
|
|
current_codename = None
|
|
|
|
if args.device:
|
|
|
|
current_vendor = args.device.split("-", 1)[0]
|
|
|
|
current_codename = args.device.split("-", 1)[1]
|
|
|
|
|
2017-10-30 19:56:38 +00:00
|
|
|
while True:
|
2019-10-13 14:09:32 +00:00
|
|
|
vendor = pmb.helpers.cli.ask(args, "Vendor", None, current_vendor,
|
2020-02-18 15:02:59 +00:00
|
|
|
False, r"[a-z0-9]+", vendors)
|
2019-10-13 14:09:32 +00:00
|
|
|
|
|
|
|
new_vendor = vendor not in vendors
|
2020-02-18 15:02:59 +00:00
|
|
|
codenames = []
|
2019-10-13 14:09:32 +00:00
|
|
|
if new_vendor:
|
2019-11-03 14:31:45 +00:00
|
|
|
logging.info("The specified vendor ({}) could not be found in"
|
|
|
|
" existing ports, do you want to start a new"
|
|
|
|
" port?".format(vendor))
|
2019-10-13 14:09:32 +00:00
|
|
|
if not pmb.helpers.cli.confirm(args, default=True):
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
devices = sorted(pmb.helpers.devices.list_codenames(args, vendor))
|
|
|
|
# Remove "vendor-" prefixes from device list
|
|
|
|
codenames = [x.split('-', 1)[1] for x in devices]
|
|
|
|
logging.info("Available codenames (" + str(len(codenames)) + "): " +
|
|
|
|
", ".join(codenames))
|
|
|
|
|
|
|
|
if current_vendor != vendor:
|
|
|
|
current_codename = ''
|
|
|
|
codename = pmb.helpers.cli.ask(args, "Device codename", None,
|
2020-02-18 15:02:59 +00:00
|
|
|
current_codename, False, r"[a-z0-9]+",
|
|
|
|
codenames)
|
2019-10-13 14:09:32 +00:00
|
|
|
|
|
|
|
device = vendor + '-' + codename
|
2017-10-30 19:56:38 +00:00
|
|
|
device_exists = os.path.exists(args.aports + "/device/device-" +
|
|
|
|
device + "/deviceinfo")
|
|
|
|
if not device_exists:
|
2018-08-22 21:30:16 +00:00
|
|
|
if device == args.device:
|
|
|
|
raise RuntimeError(
|
|
|
|
"This device does not exist anymore, check"
|
|
|
|
" <https://postmarketos.org/renamed>"
|
|
|
|
" to see if it was renamed")
|
2017-10-30 19:56:38 +00:00
|
|
|
logging.info("You are about to do a new device port for '" +
|
|
|
|
device + "'.")
|
|
|
|
if not pmb.helpers.cli.confirm(args, default=True):
|
2019-10-13 14:09:32 +00:00
|
|
|
current_vendor = vendor
|
2017-10-30 19:56:38 +00:00
|
|
|
continue
|
|
|
|
|
2019-10-13 14:09:32 +00:00
|
|
|
# New port creation confirmed
|
2019-11-03 14:31:45 +00:00
|
|
|
logging.info("Generating new aports for: {}...".format(device))
|
2017-10-30 19:56:38 +00:00
|
|
|
pmb.aportgen.generate(args, "device-" + device)
|
|
|
|
pmb.aportgen.generate(args, "linux-" + device)
|
|
|
|
break
|
2017-07-24 20:55:55 +00:00
|
|
|
|
pmbootstrap init: kernel selection / remove linux-pmos-lts (#1363)
* As discussed in IRC/matrix, we're removing `linux-postmarketos-lts`
for now. The kernel isn't used right now, and we save lots of
maintenance effort with not updating it every week or so.
* new config option `"kernel"` with possible values:
`"downstream", "mainline", "stable"` (downstream is always
`linux-$devicename`)
* ask for the kernel during `pmbootstrap init` if the device package
has kernel subpackages and install it in `_install.py`
* postmarketos-mkinitfs: display note instead of exit with error when
the `deviceinfo_dtb` file is missing (because we expect it to be
missing for downstream kernels)
* device-sony-amami:
* add kernel subpackages for downstream, mainline
* set `deviceinfo_dtb`
* device-qemu-amd64: add kernel subpackages for stable, lts, mainline
* test cases and test data for new functions
* test case that checks all aports for right usage of the feature:
* don't mix specifying kernels in depends *and* subpackages
* 1 kernel in depends is maximum
* kernel subpackages must have a valid name
* Test if devices packages reference at least one kernel
* Remove `_build_device_depends_note()` which informs the user that
`--ignore-depends` can be used with device packages to avoid building
the kernel. The idea was to make the transition easier after a change
we did months ago, and now the kernel doesn't always get built before
building the device package so it's not relevant anymore.
* pmb/chroot/other.py:
* Add autoinstall=True to kernel_flavors_installed(). When the flag
is set, the function makes sure that at least one kernel for the
device is installed.
* Remove kernel_flavor_autodetect() function, wherever it was used,
it has been replaced with kernel_flavors_installed()[0].
* pmb.helpers.frontend.py: remove code to install at least one kernel,
kernel_flavors_installed() takes care of that now.
2018-04-03 23:50:09 +00:00
|
|
|
kernel = ask_for_device_kernel(args, device)
|
2018-02-24 21:49:10 +00:00
|
|
|
nonfree = ask_for_device_nonfree(args, device)
|
pmbootstrap init: kernel selection / remove linux-pmos-lts (#1363)
* As discussed in IRC/matrix, we're removing `linux-postmarketos-lts`
for now. The kernel isn't used right now, and we save lots of
maintenance effort with not updating it every week or so.
* new config option `"kernel"` with possible values:
`"downstream", "mainline", "stable"` (downstream is always
`linux-$devicename`)
* ask for the kernel during `pmbootstrap init` if the device package
has kernel subpackages and install it in `_install.py`
* postmarketos-mkinitfs: display note instead of exit with error when
the `deviceinfo_dtb` file is missing (because we expect it to be
missing for downstream kernels)
* device-sony-amami:
* add kernel subpackages for downstream, mainline
* set `deviceinfo_dtb`
* device-qemu-amd64: add kernel subpackages for stable, lts, mainline
* test cases and test data for new functions
* test case that checks all aports for right usage of the feature:
* don't mix specifying kernels in depends *and* subpackages
* 1 kernel in depends is maximum
* kernel subpackages must have a valid name
* Test if devices packages reference at least one kernel
* Remove `_build_device_depends_note()` which informs the user that
`--ignore-depends` can be used with device packages to avoid building
the kernel. The idea was to make the transition easier after a change
we did months ago, and now the kernel doesn't always get built before
building the device package so it's not relevant anymore.
* pmb/chroot/other.py:
* Add autoinstall=True to kernel_flavors_installed(). When the flag
is set, the function makes sure that at least one kernel for the
device is installed.
* Remove kernel_flavor_autodetect() function, wherever it was used,
it has been replaced with kernel_flavors_installed()[0].
* pmb.helpers.frontend.py: remove code to install at least one kernel,
kernel_flavors_installed() takes care of that now.
2018-04-03 23:50:09 +00:00
|
|
|
return (device, device_exists, kernel, nonfree)
|
2017-10-30 19:56:38 +00:00
|
|
|
|
|
|
|
|
2017-12-21 16:42:29 +00:00
|
|
|
def ask_for_build_options(args, cfg):
|
|
|
|
# Allow to skip build options
|
|
|
|
logging.info("Build options: Parallel jobs: " + args.jobs +
|
2018-01-28 23:27:33 +00:00
|
|
|
", ccache per arch: " + args.ccache_size)
|
2017-12-21 16:42:29 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
2018-03-17 18:41:41 +00:00
|
|
|
def ask_for_hostname(args, device):
|
|
|
|
while True:
|
|
|
|
ret = pmb.helpers.cli.ask(args, "Device hostname (short form, e.g. 'foo')",
|
|
|
|
None, (args.hostname or device), True)
|
|
|
|
if not pmb.helpers.other.validate_hostname(ret):
|
|
|
|
continue
|
|
|
|
# Don't store device name in user's config (gets replaced in install)
|
|
|
|
if ret == device:
|
|
|
|
return ""
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
2018-04-08 14:12:01 +00:00
|
|
|
def ask_for_ssh_keys(args):
|
|
|
|
if not len(glob.glob(os.path.expanduser("~/.ssh/id_*.pub"))):
|
|
|
|
return False
|
|
|
|
return pmb.helpers.cli.confirm(args,
|
|
|
|
"Would you like to copy your SSH public keys to the device?",
|
|
|
|
default=args.ssh_keys)
|
|
|
|
|
|
|
|
|
2017-10-30 19:56:38 +00:00
|
|
|
def frontend(args):
|
2019-12-22 09:58:36 +00:00
|
|
|
require_programs()
|
|
|
|
|
2018-09-05 05:57:38 +00:00
|
|
|
# Work folder (needs to be first, so we can create chroots early)
|
2017-10-30 19:56:38 +00:00
|
|
|
cfg = pmb.config.load(args)
|
2018-09-05 05:57:38 +00:00
|
|
|
work, work_exists = ask_for_work_path(args)
|
|
|
|
cfg["pmbootstrap"]["work"] = work
|
|
|
|
|
|
|
|
# Update args and save config (so chroots and 'pmbootstrap log' work)
|
|
|
|
pmb.helpers.args.update_work(args, work)
|
|
|
|
pmb.config.save(args, cfg)
|
2017-10-30 19:56:38 +00:00
|
|
|
|
2019-12-22 10:30:51 +00:00
|
|
|
# Migrate work dir if necessary
|
|
|
|
pmb.helpers.other.migrate_work_folder(args)
|
|
|
|
|
2018-09-05 05:57:38 +00:00
|
|
|
# Clone pmaports
|
|
|
|
pmb.config.pmaports.init(args)
|
2018-01-02 04:38:28 +00:00
|
|
|
|
2017-10-30 19:56:38 +00:00
|
|
|
# Device
|
pmbootstrap init: kernel selection / remove linux-pmos-lts (#1363)
* As discussed in IRC/matrix, we're removing `linux-postmarketos-lts`
for now. The kernel isn't used right now, and we save lots of
maintenance effort with not updating it every week or so.
* new config option `"kernel"` with possible values:
`"downstream", "mainline", "stable"` (downstream is always
`linux-$devicename`)
* ask for the kernel during `pmbootstrap init` if the device package
has kernel subpackages and install it in `_install.py`
* postmarketos-mkinitfs: display note instead of exit with error when
the `deviceinfo_dtb` file is missing (because we expect it to be
missing for downstream kernels)
* device-sony-amami:
* add kernel subpackages for downstream, mainline
* set `deviceinfo_dtb`
* device-qemu-amd64: add kernel subpackages for stable, lts, mainline
* test cases and test data for new functions
* test case that checks all aports for right usage of the feature:
* don't mix specifying kernels in depends *and* subpackages
* 1 kernel in depends is maximum
* kernel subpackages must have a valid name
* Test if devices packages reference at least one kernel
* Remove `_build_device_depends_note()` which informs the user that
`--ignore-depends` can be used with device packages to avoid building
the kernel. The idea was to make the transition easier after a change
we did months ago, and now the kernel doesn't always get built before
building the device package so it's not relevant anymore.
* pmb/chroot/other.py:
* Add autoinstall=True to kernel_flavors_installed(). When the flag
is set, the function makes sure that at least one kernel for the
device is installed.
* Remove kernel_flavor_autodetect() function, wherever it was used,
it has been replaced with kernel_flavors_installed()[0].
* pmb.helpers.frontend.py: remove code to install at least one kernel,
kernel_flavors_installed() takes care of that now.
2018-04-03 23:50:09 +00:00
|
|
|
device, device_exists, kernel, nonfree = ask_for_device(args)
|
2018-01-08 15:18:37 +00:00
|
|
|
cfg["pmbootstrap"]["device"] = device
|
pmbootstrap init: kernel selection / remove linux-pmos-lts (#1363)
* As discussed in IRC/matrix, we're removing `linux-postmarketos-lts`
for now. The kernel isn't used right now, and we save lots of
maintenance effort with not updating it every week or so.
* new config option `"kernel"` with possible values:
`"downstream", "mainline", "stable"` (downstream is always
`linux-$devicename`)
* ask for the kernel during `pmbootstrap init` if the device package
has kernel subpackages and install it in `_install.py`
* postmarketos-mkinitfs: display note instead of exit with error when
the `deviceinfo_dtb` file is missing (because we expect it to be
missing for downstream kernels)
* device-sony-amami:
* add kernel subpackages for downstream, mainline
* set `deviceinfo_dtb`
* device-qemu-amd64: add kernel subpackages for stable, lts, mainline
* test cases and test data for new functions
* test case that checks all aports for right usage of the feature:
* don't mix specifying kernels in depends *and* subpackages
* 1 kernel in depends is maximum
* kernel subpackages must have a valid name
* Test if devices packages reference at least one kernel
* Remove `_build_device_depends_note()` which informs the user that
`--ignore-depends` can be used with device packages to avoid building
the kernel. The idea was to make the transition easier after a change
we did months ago, and now the kernel doesn't always get built before
building the device package so it's not relevant anymore.
* pmb/chroot/other.py:
* Add autoinstall=True to kernel_flavors_installed(). When the flag
is set, the function makes sure that at least one kernel for the
device is installed.
* Remove kernel_flavor_autodetect() function, wherever it was used,
it has been replaced with kernel_flavors_installed()[0].
* pmb.helpers.frontend.py: remove code to install at least one kernel,
kernel_flavors_installed() takes care of that now.
2018-04-03 23:50:09 +00:00
|
|
|
cfg["pmbootstrap"]["kernel"] = kernel
|
2018-02-24 21:49:10 +00:00
|
|
|
cfg["pmbootstrap"]["nonfree_firmware"] = str(nonfree["firmware"])
|
|
|
|
cfg["pmbootstrap"]["nonfree_userland"] = str(nonfree["userland"])
|
2017-08-19 16:04:53 +00:00
|
|
|
|
2017-08-19 21:40:20 +00:00
|
|
|
# Device keymap
|
|
|
|
if device_exists:
|
2018-01-08 15:18:37 +00:00
|
|
|
cfg["pmbootstrap"]["keymap"] = ask_for_keymaps(args, 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_-]*")
|
2018-01-02 04:38:28 +00:00
|
|
|
# UI and various build options
|
2017-07-26 17:05:06 +00:00
|
|
|
cfg["pmbootstrap"]["ui"] = ask_for_ui(args)
|
2017-12-21 16:42:29 +00:00
|
|
|
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\"")
|
2018-07-09 20:53:34 +00:00
|
|
|
extra = pmb.helpers.cli.ask(args, "Extra packages", None,
|
|
|
|
args.extra_packages,
|
2019-07-26 21:45:24 +00:00
|
|
|
validation_regex=r"^([-.+\w]+)(,[-.+\w]+)*$")
|
2018-07-09 20:53:34 +00:00
|
|
|
cfg["pmbootstrap"]["extra_packages"] = extra
|
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)
|
|
|
|
|
2018-03-17 18:41:41 +00:00
|
|
|
# Hostname
|
|
|
|
cfg["pmbootstrap"]["hostname"] = ask_for_hostname(args, device)
|
|
|
|
|
2018-04-08 14:12:01 +00:00
|
|
|
# SSH keys
|
|
|
|
cfg["pmbootstrap"]["ssh_keys"] = str(ask_for_ssh_keys(args))
|
|
|
|
|
2018-12-14 03:07:45 +00:00
|
|
|
# pmaports path (if users change it with: 'pmbootstrap --aports=... init')
|
|
|
|
cfg["pmbootstrap"]["aports"] = args.aports
|
|
|
|
|
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
|
2018-09-05 05:57:38 +00:00
|
|
|
if (work_exists and device_exists and
|
2017-08-19 16:04:53 +00:00
|
|
|
len(glob.glob(args.work + "/chroot_*")) and
|
|
|
|
pmb.helpers.cli.confirm(args, "Zap existing chroots to apply configuration?", default=True)):
|
2018-01-08 15:18:37 +00:00
|
|
|
setattr(args, "deviceinfo", pmb.parse.deviceinfo(args, device=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)
|
|
|
|
|
2020-02-04 20:39:53 +00:00
|
|
|
logging.info("WARNING: The chroots and git repositories in the work dir do"
|
|
|
|
" not get updated automatically.")
|
|
|
|
logging.info("Run 'pmbootstrap status' once a day before working with"
|
|
|
|
" pmbootstrap to make sure that everything is up-to-date.")
|
2017-05-26 20:08:45 +00:00
|
|
|
logging.info("Done!")
|