Close #709: Improve user creation (#725)

* Allow to specify a custom username in "pmbootstrap init"
* Build chroots have "pmos" instead of "user" as username now
* Installation user UID is 1000 now (as in all other Linux distributions)
* Adjust autologins
* postmarketos-base: enable wheel group for sudo, removed previous sudoers file
* Implement safe upgrade path:
We save the version of the work folder format now, in $WORK/version.
When this file does not exist, it defaults to 0.
In case it does not match the currently required version
(pmb.config.work_version), then ask the user if it should
automatically be upgraded.
This commit is contained in:
Pablo Castellano 2017-10-12 22:08:10 +02:00 committed by Oliver Smith
parent 75210b5cb5
commit b4dd7a89d2
45 changed files with 229 additions and 106 deletions

View File

@ -24,7 +24,6 @@ makedepends=""
install="$pkgname.post-install"
subpackages="$pkgname-x11"
source="
sudoers
firmwareload.sh
50-firmware.rules
swapfile/swapfile
@ -34,8 +33,6 @@ source="
options="!check"
package() {
install -D -m644 "$srcdir"/sudoers \
"$pkgdir"/etc/sudoers.d/postmarketos
install -D -m644 "$srcdir"/50-firmware.rules \
"$pkgdir"/etc/udev/rules.d/50-firmware.rules
install -D -m755 "$srcdir"/firmwareload.sh \
@ -65,10 +62,9 @@ x11() {
mkdir "$subpkgdir"
}
sha512sums="c6de3b44bc45b9f9c641a7e34c69a481ee39b99ac0251cd28f2b3aae49c1a8d1ca448f4936b7942b1a8b8f7c18a5415c938098765ed8cf08456543800160e64b sudoers
38dc75c0ed32b76dccd3d8e7e8173e8b7d91847cf2b07123f376b95af46b4f89798b24f45302a0726fdc1cf253aecaac140f431735ac5c6511553f790badd0af firmwareload.sh
sha512sums="38dc75c0ed32b76dccd3d8e7e8173e8b7d91847cf2b07123f376b95af46b4f89798b24f45302a0726fdc1cf253aecaac140f431735ac5c6511553f790badd0af firmwareload.sh
0b098828080055d3646ea54891cb0e1b578cbc30f5e16f7284f2814c08192f18079a38fb686d192715ae6a3d2cd6625d9e3cf99f234a6f0d94088bb0cb2ce43d 50-firmware.rules
3ceeee37f558e7c95ad973692b6a437f997e6b46c3d1c2257ddfb1529a5633477373aa123c7f08164e818daae50acb203d151379f27ca11bd458809e6a0d4de7 swapfile
f5cc0f1265955d2646e5f099dd4b5d4c287945bfc18c16044db57670d456f55c678fc11cc59e6dab3fa340832ce869d516302a3a35c13518539ed0cedca51819 swapfile.init
e0d2d48b82a03239a4c0a00acaf83e00d397c23a8d7c71053d4e2a383357c22dcedef9e81b0e12a1d7514e1fdbe0bb3eb82613d18b29034a7ce5447f13c84a53 swapfile.conf
8b022c5b45d02cbce64137e085838e7d7748b2f3c563faa1a1b02f91472cef96ad254f3f5ee35d80c982d80bd5959ceab0f8127534f7742134ca07a3d595be34 postmarketos-base.post-install"
4f00ad8ce8533fb884b083c094adada26ef845718a229e3ae94986997997297d9bec073babbe8829c29d28aaf31a01ebf28c041395ae7d8631be574b88059e34 postmarketos-base.post-install"

View File

@ -70,5 +70,9 @@ if ! grep -q Dwext /etc/conf.d/wpa_supplicant; then
fi
touch /etc/wpa_supplicant/wpa_supplicant.conf
# Enable the 'wheel' group
sed -i 's/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/' /etc/sudoers
# Add user to video group for proper framebuffer permissions
usermod -a -G video user
username="$(getent passwd 1000 | cut -d ":" -f 1)"
usermod -a -G video "$username"

View File

@ -1,2 +0,0 @@
# Allow running all commands as root, when the user password is known
user ALL=(ALL) ALL

View File

@ -1,6 +1,6 @@
pkgname=postmarketos-ui-hildon
pkgver=1
pkgrel=0
pkgrel=1
pkgdesc="Lightweight desktop, optimized for single-touch touchscreen devices"
url="https://github.com/postmarketOS"
arch="noarch"
@ -29,6 +29,6 @@ package() {
install -D -m644 "$srcdir"/xinitrc_hildon.sh \
"$pkgdir"/etc/postmarketos-ui/xinitrc_hildon.sh
}
sha512sums="e50c2bd90ef7915278eb5071d3f3ce26794e620617a6d9b2c49a7a1df1da2809437e6d20387bbb61f2ae471c5610ad1e1a30db0d5272f081980764a7c06c221f start_hildon.sh
sha512sums="c75466e0a279da1aec11605b422c0a0d91a6fc38c27cdd819fb277badc84e220bbd8b87b217123b3801411aae0b93f98c6c0b449a5a33fc725bd6279a39d9741 start_hildon.sh
5ef5710bee7bde99e1f240eb8873239c452b55c6dc943930e181d091835824094cf56bf29ae1b34d792ba0ce27f76e30ea69f3c125dda3bf286eaaaba8c8e6ae xinitrc_hildon.sh
a091157afccf19d25dd86d52edf819435da01bb8933f45f5a207e4085b044b80e1790b5e2bb02dbd8f479fdf9d54b06d388a1a1a2995adf9da7d3000449a7f7f postmarketos-ui-hildon.post-install"
64007cebcfbb9d8cdc4db7f889722509e1090af0712802300611fb805e00e1de474e4e6b538d0d99be05ca25f983e94aab57e04b4cc8282ba0ae44609d1a7366 postmarketos-ui-hildon.post-install"

View File

@ -1,7 +1,7 @@
#!/bin/sh
# Autologin on tty1, let busybox autoconfigure 2-6
autologin="user"
autologin="$(getent passwd 1000 | cut -d ":" -f 1)"
for i in 1 2 3 4 5 6; do
old="^tty$i::respawn:/sbin/getty 38400 tty$i"
new="# tty$i::respawn:/sbin/getty 38400 tty$i"

View File

@ -4,7 +4,7 @@
# /etc/inittab by postmarketos-base post-install.hook).
# This is a temporary solution, we'll need something like a
# display manager in the long run (#656).
if [ "$(id -u)" = "12345" ] && [ "$(tty)" = "/dev/tty1" ]; then
if [ "$(id -u)" = "1000" ] && [ "$(tty)" = "/dev/tty1" ]; then
# Start X11 with Hildon
startx /etc/postmarketos-ui/xinitrc_hildon.sh > ~/x11.log 2>&1

View File

@ -1,6 +1,6 @@
pkgname=postmarketos-ui-weston
pkgver=3
pkgrel=0
pkgrel=1
pkgdesc="Meta package for weston"
url="https://github.com/postmarketOS"
arch="noarch"
@ -18,5 +18,5 @@ package() {
install -D -m644 "$srcdir"/start_weston.sh \
"$pkgdir"/etc/profile.d/start_weston.sh
}
sha512sums="1fb3dff37e7db7277f713958eeb9b9b8eae730aec2fe02d2c87d036d23b7f3a79779288f5ddf9a3b05465beea5410133fb4b0268b0544a07c08b9d53cdce4745 start_weston.sh
066071c0fa1b35079c28dc18ce66ac56575d49df06f1a217e308ea0b4587436e76432817091737eb9a17e7eecfc855d4d488e5850c77ccbaa3ee4e6a3949dbb8 postmarketos-ui-weston.post-install"
sha512sums="9281ec20d0367d11e8219cc248ebab94194c703fe87e3e4fcbd128d54a67f77d17781b006721a04e5bd3fd4a95616f22a79e88cbdc6d5cc29f86fcfb4fc07755 start_weston.sh
23958764613a14a49b300d7f4c6044fce75d8bdf23c2c5a6e9ffe7228a8fa2d0b2c8188dc0021f56f5c1bc6599d3691ede4e5a5c2a228a09bd7a804ae935bf29 postmarketos-ui-weston.post-install"

View File

@ -39,7 +39,7 @@ if [ ! -f $weston_config ]; then
fi
# Autologin on tty1, let busybox autoconfigure 2-6
autologin="user"
autologin="$(getent passwd 1000 | cut -d ":" -f 1)"
for i in 1 2 3 4 5 6; do
old="^tty$i::respawn:/sbin/getty 38400 tty$i"
new="# tty$i::respawn:/sbin/getty 38400 tty$i"
@ -49,4 +49,5 @@ done
# Create weston-launch group and add user to it
[ $(getent group weston-launch) ] || groupadd weston-launch
usermod -a -G weston-launch user
username="$(getent passwd 1000 | cut -d ":" -f 1)"
usermod -a -G weston-launch "$username"

View File

@ -12,7 +12,7 @@ if test -z "${XDG_RUNTIME_DIR}"; then
# Weston autostart on tty1 (Autologin on tty1 is enabled in
# /etc/inittab by postmarketos-base post-install.hook)
if [ "$(id -u)" = "12345" ] && [ $(tty) = "/dev/tty1" ]; then
if [ "$(id -u)" = "1000" ] && [ $(tty) = "/dev/tty1" ]; then
if test -n "${deviceinfo_weston_pixman_type}"; then
WESTON_OPTS=" --pixman-type=${deviceinfo_weston_pixman_type}"
fi

View File

@ -1,6 +1,6 @@
pkgname=postmarketos-ui-xfce4
pkgver=0.0
pkgrel=1
pkgrel=2
pkgdesc="Meta package for xfce4"
url="https://github.com/postmarketOS/xfce4-phone"
arch="noarch"
@ -18,6 +18,6 @@ package() {
install -d -m755 "$pkgdir"/etc/skel
cp -a "${srcdir}/xfce4-phone-${pkgver}"/config "$pkgdir"/etc/skel/.config
}
sha512sums="6aa496acf16a5348050ed7aca07203f20f4663b37acd63255c31561e0931f90886050aa3c221db2224e3dc357fe5329dc703ec06f5938e7cea8606ad6b741ee6 start_xfce4.sh
86b0d3d83da393aafc5d17552457030d9dfae071a35dbe93125e101361962f1752575f17c7dd4140d2a5c6cd4e09367bb2226b532a0194c26c5a77899e80842f postmarketos-ui-xfce4.post-install
sha512sums="f51d88e1a4f8cd9156e62601c1b2ca40d3c6d7079480888471f21359f417398224722c42677cb28336efc8245d9b6b0851a2d1dc16b9f6c79d48ef284944b8b2 start_xfce4.sh
916f80ebd1ab86c17bb09158ca470bbc53c1fac53771a38e2422672c29cb07fd35906804a5b00eb852e6f1d08abaf31a6db13452765d1cceefc06c57479d3984 postmarketos-ui-xfce4.post-install
758562d2820a11b2c96e1805e00450f78203e6fd224115c373825f041b344985490a84b74d2880b423d5606140d5ffb41e79b0a8eb3e5b9a0ce7874c4ccfb666 postmarketos-ui-xfce4-0.0.tar.gz"

View File

@ -3,7 +3,7 @@
. /etc/deviceinfo
# Autologin on tty1, let busybox autoconfigure 2-6
autologin="user"
autologin="$(getent passwd 1000 | cut -d ":" -f 1)"
for i in 1 2 3 4 5 6; do
old="^tty$i::respawn:/sbin/getty 38400 tty$i"
new="# tty$i::respawn:/sbin/getty 38400 tty$i"

View File

@ -1,5 +1,5 @@
if [ "$(id -u)" = "12345" ] && [ "$(tty)" = "/dev/tty1" ]; then
if [ "$(id -u)" = "1000" ] && [ "$(tty)" = "/dev/tty1" ]; then
startxfce4 > ~/x11.log 2>&1
# In case of failure, restart after 1s

View File

@ -48,6 +48,10 @@ def main():
" 'pmbootstrap init' to generate one.")
return 1
# Migrate work folder if necessary
if args.action not in ["shutdown", "zap", "log"]:
other.migrate_work_folder(args)
# Run the function with the action's name (in pmb/helpers/frontend.py)
if args.action:
getattr(frontend, args.action)(args)

View File

@ -69,6 +69,6 @@ def write(args, apk_path, arch, suffix, apkbuild):
handle.write(json.dumps(buildinfo, indent=4, sort_keys=True) + "\n")
# Move to packages
pmb.chroot.root(args, ["chown", "user:user", "/tmp/buildinfo"])
pmb.chroot.user(args, ["mv", "/tmp/buildinfo", "/home/user/packages/user/" +
pmb.chroot.root(args, ["chown", "pmos:pmos", "/tmp/buildinfo"])
pmb.chroot.user(args, ["mv", "/tmp/buildinfo", "/home/pmos/packages/pmos/" +
apk_path + ".buildinfo.json"])

View File

@ -29,9 +29,9 @@ def checksum(args, pkgname):
pmb.build.copy_to_buildpath(args, pkgname)
logging.info("(native) generate checksums for " + pkgname)
pmb.chroot.user(args, ["abuild", "checksum"],
working_dir="/home/user/build")
working_dir="/home/pmos/build")
# Copy modified APKBUILD back
source = args.work + "/chroot_native/home/user/build/APKBUILD"
source = args.work + "/chroot_native/home/pmos/build/APKBUILD"
target = pmb.build.other.find_aport(args, pkgname) + "/"
pmb.helpers.run.user(args, ["cp", source, target])

View File

@ -42,13 +42,13 @@ def init(args, suffix="native"):
# Generate package signing keys
chroot = args.work + "/chroot_" + suffix
if not os.path.exists(chroot + "/home/user/.abuild/abuild.conf"):
if not os.path.exists(args.work + "/config_abuild/abuild.conf"):
logging.info("(" + suffix + ") generate abuild keys")
pmb.chroot.user(args, ["abuild-keygen", "-n", "-q", "-a"],
suffix)
# Copy package signing key to /etc/apk/keys
for key in glob.glob(chroot + "/home/user/.abuild/*.pub"):
for key in glob.glob(chroot + "/home/pmos/.abuild/*.pub"):
key = key[len(chroot):]
pmb.chroot.root(args, ["cp", key, "/etc/apk/keys/"], suffix)
@ -75,7 +75,7 @@ def init(args, suffix="native"):
pmb.chroot.root(args, ["chmod", "+x", "/usr/local/bin/gzip"], suffix)
# Add user to group abuild
pmb.chroot.root(args, ["adduser", "user", "abuild"], suffix)
pmb.chroot.root(args, ["adduser", "pmos", "abuild"], suffix)
# abuild.conf: Don't clean the build folder after building, so we can
# inspect it afterwards for debugging

View File

@ -49,10 +49,10 @@ def menuconfig(args, pkgname, arch):
# Patch and extract sources
pmb.build.copy_to_buildpath(args, pkgname)
logging.info("(native) extract kernel source")
pmb.chroot.user(args, ["abuild", "unpack"], "native", "/home/user/build")
pmb.chroot.user(args, ["abuild", "unpack"], "native", "/home/pmos/build")
logging.info("(native) apply patches")
pmb.chroot.user(args, ["CARCH=" + arch, "abuild", "prepare"], "native",
"/home/user/build", log=False)
"/home/pmos/build", log=False)
# Run abuild menuconfig
cmd = []
@ -61,12 +61,12 @@ def menuconfig(args, pkgname, arch):
cmd += [key + "=" + value]
cmd += ["abuild", "-d", "menuconfig"]
logging.info("(native) run menuconfig")
pmb.chroot.user(args, cmd, "native", "/home/user/build", log=False)
pmb.chroot.user(args, cmd, "native", "/home/pmos/build", log=False)
# Update config + checksums
config = "config-" + apkbuild["_flavor"] + "." + arch
logging.info("Copy kernel config back to aport-folder")
source = args.work + "/chroot_native/home/user/build/" + config
source = args.work + "/chroot_native/home/pmos/build/" + config
if not os.path.exists(source):
raise RuntimeError("No kernel config generated!")
target = aport + "/" + config

View File

@ -77,15 +77,15 @@ def copy_to_buildpath(args, package, suffix="native"):
aport)
# Clean up folder
build = args.work + "/chroot_" + suffix + "/home/user/build"
build = args.work + "/chroot_" + suffix + "/home/pmos/build"
if os.path.exists(build):
pmb.chroot.root(args, ["rm", "-rf", "/home/user/build"],
pmb.chroot.root(args, ["rm", "-rf", "/home/pmos/build"],
suffix=suffix)
# Copy aport contents
pmb.helpers.run.root(args, ["cp", "-r", aport + "/", build])
pmb.chroot.root(args, ["chown", "-R", "user:user",
"/home/user/build"], suffix=suffix)
pmb.chroot.root(args, ["chown", "-R", "pmos:pmos",
"/home/pmos/build"], suffix=suffix)
def aports_files_out_of_sync_with_git(args, package=None):
@ -247,7 +247,7 @@ def index_repo(args, arch=None):
for path in paths:
path_arch = os.path.basename(path)
path_repo_chroot = "/home/user/packages/user/" + path_arch
path_repo_chroot = "/home/pmos/packages/pmos/" + path_arch
logging.debug("(native) index " + path_arch + " repository")
commands = [
["apk", "-q", "index", "--output", "APKINDEX.tar.gz_",
@ -270,7 +270,7 @@ def symlink_noarch_packages(args):
architectures = pmb.config.build_device_architectures
logging.debug("Symlink noarch-packages to " + ", ".join(architectures))
for arch in architectures:
arch_folder = "/home/user/packages/user/" + arch
arch_folder = "/mnt/pmbootstrap-packages/" + arch
arch_folder_outside = args.work + "/packages/" + arch
if not os.path.exists(arch_folder_outside):
pmb.chroot.user(args, ["mkdir", "-p", arch_folder])
@ -280,7 +280,7 @@ def symlink_noarch_packages(args):
index = "/tmp/APKINDEX_without_replaced_archs"
index_outside = args.work + "/chroot_native" + index
pmb.chroot.user(args, ["apk", "-q", "index", "--output", index, "*.apk"],
working_dir="/home/user/packages/user/" + args.arch_native)
working_dir="/mnt/pmbootstrap-packages/" + args.arch_native)
# Iterate over noarch packages
for package, data in pmb.parse.apkindex.parse(args, index_outside).items():
@ -292,7 +292,7 @@ def symlink_noarch_packages(args):
for arch in architectures:
if os.path.exists(args.work + "/packages/" + arch + "/" + apk_file):
continue
arch_folder = "/home/user/packages/user/" + arch
arch_folder = "/mnt/pmbootstrap-packages/" + arch
source = "../" + args.arch_native + "/" + apk_file
pmb.chroot.user(args, ["ln", "-sf", source, "."],
working_dir=arch_folder)

View File

@ -111,7 +111,7 @@ def package(args, pkgname, carch, force=False, buildinfo=False, strict=False):
cmd += ["-d"] # do not install depends with abuild
if force:
cmd += ["-f"]
pmb.chroot.user(args, cmd, suffix, "/home/user/build")
pmb.chroot.user(args, cmd, suffix, "/home/pmos/build")
# Verify output file
path = args.work + "/packages/" + output
@ -133,6 +133,6 @@ def package(args, pkgname, carch, force=False, buildinfo=False, strict=False):
carch_buildenv + "/APKINDEX.tar.gz")
if strict:
logging.info("(" + suffix + ") uninstall makedepends")
pmb.chroot.user(args, ["abuild", "undeps"], suffix, "/home/user/build")
pmb.chroot.user(args, ["abuild", "undeps"], suffix, "/home/pmos/build")
return output

View File

@ -20,5 +20,6 @@ from pmb.chroot.init import init
from pmb.chroot.mount import mount
from pmb.chroot.root import root
from pmb.chroot.user import user
from pmb.chroot.user import exists as user_exists
from pmb.chroot.shutdown import shutdown
from pmb.chroot.zap import zap

View File

@ -171,7 +171,7 @@ def replace_aports_packages_with_path(args, packages, suffix, arch):
aport = pmb.build.find_aport(args, package, False)
if aport:
apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD")
apk_path = ("/home/user/packages/user/" + arch + "/" +
apk_path = ("/home/pmos/packages/pmos/" + arch + "/" +
package + "-" + apkbuild["pkgver"] + "-r" +
apkbuild["pkgrel"] + ".apk")
if os.path.exists(args.work + "/chroot_" + suffix + apk_path):

View File

@ -29,7 +29,7 @@ def get_running_pid(args):
"""
:returns: the running distccd's pid as integer or None
"""
pidfile = args.work + "/chroot_native/home/user/distccd.pid"
pidfile = args.work + "/chroot_native/home/pmos/distccd.pid"
if not os.path.exists(pidfile):
return None
with open(pidfile, "r") as handle:
@ -74,7 +74,7 @@ def is_running(args):
os.kill(pid, 0)
except OSError as err:
if err.errno == errno.ESRCH: # no such process
pmb.chroot.root(args, ["rm", "/home/user/distccd.pid"])
pmb.chroot.root(args, ["rm", "/home/pmos/distccd.pid"])
return False
elif err.errno == errno.EPERM: # access denied
return get_running_info(args)
@ -88,11 +88,11 @@ def generate_cmdline(args, arch):
path = "/usr/lib/gcc-cross-wrappers/" + arch + "/bin:" + pmb.config.chroot_path
ret = ["PATH=" + path,
"distccd",
"--pid-file", "/home/user/distccd.pid",
"--pid-file", "/home/pmos/distccd.pid",
"--listen", "127.0.0.1",
"--allow", "127.0.0.1",
"--port", args.port_distccd,
"--log-file", "/home/user/distccd.log",
"--log-file", "/home/pmos/distccd.log",
"--jobs", args.jobs,
"--nice", "19",
"--job-lifetime", "60",

View File

@ -113,9 +113,16 @@ def init(args, suffix="native"):
pmb.chroot.root(args, ["apk", "fix"], suffix,
auto_init=False)
# Add user (-D: don't assign password)
logging.debug("Add user")
pmb.chroot.root(args, ["adduser", "-D", "user", "-u", pmb.config.chroot_uid_user],
suffix, auto_init=False)
pmb.chroot.root(args, ["chown", "-R", "user:user", "/home/user"],
suffix)
# Building chroots: create "pmos" user, add symlinks to /home/pmos
if not suffix.startswith("rootfs_"):
pmb.chroot.root(args, ["adduser", "-D", "pmos", "-u",
pmb.config.chroot_uid_user], suffix, auto_init=False)
# Create the links (with subfolders if necessary)
for target, link_name in pmb.config.chroot_home_symlinks.items():
link_dir = os.path.dirname(link_name)
if not os.path.exists(chroot + link_dir):
pmb.chroot.user(args, ["mkdir", "-p", link_dir], suffix)
pmb.chroot.user(args, ["ln", "-s", target, link_name], suffix)
pmb.chroot.root(args, ["chown", "pmos:pmos", target],
suffix)

View File

@ -78,7 +78,7 @@ def shutdown(args, only_install_related=False):
# Umount all losetup mounted images
chroot = args.work + "/chroot_native"
if pmb.helpers.mount.ismount(chroot + "/dev/loop-control"):
pattern = chroot + "/home/user/rootfs/*.img"
pattern = chroot + "/home/pmos/rootfs/*.img"
for path_outside in glob.glob(pattern):
path = path_outside[len(chroot):]
pmb.install.losetup.umount(args, path)

View File

@ -27,6 +27,18 @@ def user(args, cmd, suffix="native", working_dir="/", log=True,
:param log: When set to true, redirect all output to the logfile
:param auto_init: Automatically initialize the chroot
"""
cmd = ["su", "user", "-c", " ".join(cmd)]
cmd = ["su", "pmos", "-c", " ".join(cmd)]
return pmb.chroot.root(args, cmd, suffix, working_dir, log,
auto_init, return_stdout, check)
def exists(args, username, suffix="native"):
"""
Checks if username exists in the system
:param username: User name
:returns: bool
"""
output = pmb.chroot.root(args, ["getent", "passwd", username],
suffix, return_stdout=True, check=False)
return (output is not None)

View File

@ -39,6 +39,11 @@ apk_keys_path = pmb_src + "/keys"
# exploit the system!)
apk_tools_static_min_version = "2.7.2-r0"
# Version of the work folder (as asked during 'pmbootstrap init'). Increase
# this number, whenever migration is required and provide the migration code,
# see migrate_work_folder()).
work_version = "1"
# Config file/commandline default values
# $WORK gets replaced with the actual value for args.work (which may be
# overriden on the commandline)
@ -56,6 +61,7 @@ defaults = {
"work": os.path.expanduser("~") + "/.local/var/pmbootstrap",
"port_distccd": "33632",
"ui": "weston",
"user": "user",
"keymap": "",
# aes-xts-plain64 would be better, but this is not supported on LineageOS
@ -97,12 +103,21 @@ chroot_host_path = os.environ["PATH"] + ":/usr/sbin/"
chroot_mount_bind = {
"/proc": "/proc",
"$WORK/cache_apk_$ARCH": "/var/cache/apk",
"$WORK/cache_ccache_$ARCH": "/home/user/.ccache",
"$WORK/cache_ccache_$ARCH": "/mnt/pmbootstrap-ccache",
"$WORK/cache_distfiles": "/var/cache/distfiles",
"$WORK/cache_git": "/home/user/git",
"$WORK/config_abuild": "/home/user/.abuild",
"$WORK/cache_git": "/mnt/pmbootstrap-git",
"$WORK/config_abuild": "/mnt/pmbootstrap-abuild-config",
"$WORK/config_apk_keys": "/etc/apk/keys",
"$WORK/packages": "/home/user/packages/user",
"$WORK/packages": "/mnt/pmbootstrap-packages",
}
# Building chroots (all chroots, except for the rootfs_ chroot) get symlinks in
# the "pmos" user's home folder pointing to mountfolders from above.
chroot_home_symlinks = {
"/mnt/pmbootstrap-abuild-config": "/home/pmos/.abuild",
"/mnt/pmbootstrap-ccache": "/home/pmos/.ccache",
"/mnt/pmbootstrap-git": "/home/pmos/git",
"/mnt/pmbootstrap-packages": "/home/pmos/packages/pmos",
}
# The package alpine-base only creates some device nodes. Specify here, which

View File

@ -41,7 +41,14 @@ def ask_for_work_path(args):
try:
ret = os.path.expanduser(pmb.helpers.cli.ask(
args, "Work path", None, args.work, False))
os.makedirs(ret, 0o700, True)
# 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
os.makedirs(ret + "/cache_http", 0o700, True)
return ret
except OSError:
@ -97,6 +104,10 @@ def init(args):
if device_exists:
cfg["pmbootstrap"]["keymap"] = ask_for_keymaps(args, device=cfg["pmbootstrap"]["device"])
# Username
cfg["pmbootstrap"]["user"] = pmb.helpers.cli.ask(args, "Username", None,
args.user, False,
"[a-z_][a-z0-9_-]*")
# UI and work folder
cfg["pmbootstrap"]["ui"] = ask_for_ui(args)
cfg["pmbootstrap"]["work"] = ask_for_work_path(args)

View File

@ -14,7 +14,7 @@ def frontend(args):
pmb.helpers.run.user(args, ["mkdir", "-p", target])
# System image note
img_path = "/home/user/rootfs/" + args.device + ".img"
img_path = "/home/pmos/rootfs/" + args.device + ".img"
if not os.path.exists(args.work + "/chroot_native" + img_path):
logging.info("NOTE: To export the system image, run 'pmbootstrap"
" install' first (without the 'sdcard' parameter).")

View File

@ -87,15 +87,15 @@ def odin(args, flavor, folder):
pmb.chroot.root(args, command, suffix)
# Move Odin flashable tar to native chroot and cleanup temp folder
pmb.chroot.user(args, ["mkdir", "-p", "/home/user/rootfs"])
pmb.chroot.user(args, ["mkdir", "-p", "/home/pmos/rootfs"])
pmb.chroot.root(args, ["mv", "/mnt/rootfs_" + args.device + temp_folder +
"/" + odin_device_tar_md5, "/home/user/rootfs/"]),
pmb.chroot.root(args, ["chown", "user:user",
"/home/user/rootfs/" + odin_device_tar_md5])
"/" + odin_device_tar_md5, "/home/pmos/rootfs/"]),
pmb.chroot.root(args, ["chown", "pmos:pmos",
"/home/pmos/rootfs/" + odin_device_tar_md5])
pmb.chroot.root(args, ["rmdir", temp_folder], suffix)
# Create the symlink
file = args.work + "/chroot_native/home/user/rootfs/" + odin_device_tar_md5
file = args.work + "/chroot_native/home/pmos/rootfs/" + odin_device_tar_md5
link = folder + "/" + odin_device_tar_md5
pmb.helpers.file.symlink(args, file, link)

View File

@ -49,7 +49,7 @@ def symlinks(args, flavor, folder):
path_boot = args.work + "/chroot_rootfs_" + args.device + "/boot"
path_buildroot = args.work + "/chroot_buildroot_" + args.deviceinfo["arch"]
patterns = [path_boot + "/*-" + flavor,
path_native + "/home/user/rootfs/" + args.device + ".img",
path_native + "/home/pmos/rootfs/" + args.device + ".img",
path_buildroot +
"/var/lib/postmarketos-android-recovery-installer/pmos-" +
args.device + ".zip"]

View File

@ -52,7 +52,7 @@ def kernel(args):
" encryption is disabled):")
logging.info("telnet " + pmb.config.default_ip)
logging.info("Then you can connect to your device using ssh:")
logging.info("ssh user@" + pmb.config.default_ip)
logging.info("ssh " + args.user + "@" + pmb.config.default_ip)
def list_flavors(args):
@ -64,7 +64,7 @@ def list_flavors(args):
def system(args):
# Generate system image, install flasher
img_path = "/home/user/rootfs/" + args.device + ".img"
img_path = "/home/pmos/rootfs/" + args.device + ".img"
if not os.path.exists(args.work + "/chroot_native" + img_path):
raise RuntimeError("The system image has not been generated yet,"
" please run 'pmbootstrap install' first.")

View File

@ -33,7 +33,7 @@ def variables(args, flavor, method):
vars = {
"$BOOT": "/mnt/rootfs_" + args.device + "/boot",
"$FLAVOR": flavor if flavor is not None else "",
"$IMAGE": "/home/user/rootfs/" + args.device + ".img",
"$IMAGE": "/home/pmos/rootfs/" + args.device + ".img",
"$KERNEL_CMDLINE": _cmdline,
"$PARTITION_KERNEL": args.deviceinfo["flash_heimdall_partition_kernel"] or "KERNEL",
"$PARTITION_INITFS": args.deviceinfo["flash_heimdall_partition_initfs"] or "RECOVERY",

View File

@ -209,7 +209,7 @@ def log(args):
def log_distccd(args):
logpath = "/home/user/distccd.log"
logpath = "/home/pmos/distccd.log"
if args.clear_log:
pmb.chroot.user(args, ["truncate", "-s", "0", logpath], log=False)
pmb.chroot.user(args, ["tail", "-f", logpath, "-n", args.lines], log=False)

View File

@ -33,7 +33,7 @@ def clone(args, repo_name):
pmb.chroot.apk.install(args, ["git"])
logging.info("(native) git clone " + pmb.config.git_repos[repo_name])
pmb.chroot.user(args, ["git", "clone", "--depth=1",
pmb.config.git_repos[repo_name], repo_name], working_dir="/home/user/git/")
pmb.config.git_repos[repo_name], repo_name], working_dir="/home/pmos/git/")
def rev_parse(args, revision="HEAD"):

View File

@ -74,15 +74,21 @@ def init(args):
Set log format and add the log file descriptor to args.logfd, add the
verbose log level.
"""
# Create work folder (because usually the log file is in there)
if not os.path.exists(args.work):
os.makedirs(args.work)
# Open logfile
# Set log file descriptor (logfd)
if args.details_to_stdout:
setattr(args, "logfd", sys.stdout)
else:
setattr(args, "logfd", open(args.log, "a+"))
# Require containing directory to exist (so we don't create the work
# folder and break the folder migration logic, which needs to set the
# version upon creation)
dir = os.path.dirname(args.log)
if os.path.exists(dir):
setattr(args, "logfd", open(args.log, "a+"))
else:
setattr(args, "logfd", open(os.devnull, "a+"))
if args.action != "init":
print("WARNING: Can't create log file in '" + dir + "', path"
" does not exist!")
# Set log format
root_logger = logging.getLogger()

View File

@ -17,6 +17,9 @@ You should have received a copy of the GNU General Public License
along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
"""
import os
import logging
import pmb.chroot
import pmb.config
import pmb.helpers.run
@ -53,3 +56,54 @@ def check_grsec(args):
" Alternatively, it would be awesome if you want to add"
" support for hardened/grsec kernels, please see this for"
" more details: <" + link + ">")
def migrate_success(args):
logging.info("Migration done")
with open(args.work + "/version", "w") as handle:
handle.write(pmb.config.work_version + "\n")
def migrate_work_folder(args):
# Read current version
current = "0"
path = args.work + "/version"
if os.path.exists(path):
with open(path, "r") as f:
current = f.read().rstrip()
# Compare version, print warning or do nothing
required = pmb.config.work_version
if current == required:
return
logging.info("WARNING: Your work folder version needs to be migrated"
" (from version " + current + " to " + required + ")!")
# 0 => 1
if current == "0" and required == "1":
# Ask for confirmation
logging.info("Changelog:")
logging.info("* Building chroots have a different username: "
"<https://github.com/postmarketOS/pmbootstrap/issues/709>")
logging.info("Migration will do the following:")
logging.info("* Zap your chroots")
logging.info("* Adjust '" + args.work + "/config_abuild/abuild.conf'")
if not pmb.helpers.cli.confirm(args):
raise RuntimeError("Aborted.")
# Zap and update abuild.conf
pmb.chroot.zap(args, False)
conf = args.work + "/config_abuild/abuild.conf"
if os.path.exists(conf):
pmb.helpers.run.root(args, ["sed", "-i",
"s./home/user/./home/pmos/.g", conf])
# Update version file
migrate_success(args)
return
# Can't migrate, user must delete it
raise RuntimeError("Sorry, we can't migrate that automatically. Please run"
" 'pmbootstrap shutdown', then delete your current work"
" folder manually ('sudo rm -rf " + args.work +
"') and start over with 'pmbootstrap init'. All your"
" binary packages will be lost.")

View File

@ -101,7 +101,7 @@ def urls(args, user_repository=True, postmarketos_mirror=True):
ret = []
# Local user repository (for packages compiled with pmbootstrap)
if user_repository:
ret.append("/home/user/packages/user")
ret.append("/mnt/pmbootstrap-packages")
# Upstream postmarketOS binary repository
if postmarketos_mirror and args.mirror_postmarketos:

View File

@ -54,7 +54,7 @@ def create_and_mount_image(args, size):
"""
# Short variables for paths
chroot = args.work + "/chroot_native"
img_path = "/home/user/rootfs/" + args.device + ".img"
img_path = "/home/pmos/rootfs/" + args.device + ".img"
img_path_outside = chroot + img_path
# Umount and delete existing image
@ -76,7 +76,7 @@ def create_and_mount_image(args, size):
raise RuntimeError("Aborted.")
# Create empty image file
pmb.chroot.user(args, ["mkdir", "-p", "/home/user/rootfs"])
pmb.chroot.user(args, ["mkdir", "-p", "/home/pmos/rootfs"])
pmb.chroot.root(args, ["truncate", "-s", mb, img_path])
# Mount to /dev/install

View File

@ -92,29 +92,40 @@ def copy_files_from_chroot(args):
def copy_files_other(args):
"""
Copy over keys, create /home/user.
Copy over keys, create /home/{user}.
"""
# Copy over keys
rootfs = args.work + "/chroot_native/mnt/install"
for key in glob.glob(args.work + "/config_apk_keys/*.pub"):
pmb.helpers.run.root(args, ["cp", key, rootfs + "/etc/apk/keys/"])
# Create /home/user
# Create /home/{user}
homedir = rootfs + "/home/" + args.user
pmb.helpers.run.root(args, ["mkdir", rootfs + "/home"])
pmb.helpers.run.root(args, ["cp", "-a", rootfs + "/etc/skel", rootfs + "/home/user"])
pmb.helpers.run.root(args, ["chown", "-R", pmb.config.chroot_uid_user,
rootfs + "/home/user"])
pmb.helpers.run.root(args, ["cp", "-a", rootfs + "/etc/skel", homedir])
pmb.helpers.run.root(args, ["chown", "-R", "1000", homedir])
def set_user(args):
"""
Create user with UID 1000 if it doesn't exist
"""
suffix = "rootfs_" + args.device
if not pmb.chroot.user_exists(args, args.user, suffix):
pmb.chroot.root(args, ["adduser", "-D", "-u", "1000", args.user],
suffix)
pmb.chroot.root(args, ["addgroup", args.user, "wheel"], suffix)
def set_user_password(args):
"""
Loop until the passwords for user and root have been changed successfully.
"""
logging.info(" *** SET LOGIN PASSWORD FOR: 'user' ***")
logging.info(" *** SET LOGIN PASSWORD FOR: '" + args.user + "' ***")
suffix = "rootfs_" + args.device
while True:
try:
pmb.chroot.root(args, ["passwd", "user"], suffix, log=False)
pmb.chroot.root(args, ["passwd", args.user], suffix, log=False)
break
except RuntimeError:
logging.info("WARNING: Failed to set the password. Try it"
@ -147,12 +158,12 @@ def copy_ssh_key(args):
outfile.write("%s" % key)
outfile.close()
target = args.work + "/chroot_native/mnt/install/home/user/.ssh"
target = args.work + "/chroot_native/mnt/install/home/" + args.user + "/.ssh"
pmb.helpers.run.root(args, ["mkdir", target])
pmb.helpers.run.root(args, ["chmod", "700", target])
pmb.helpers.run.root(args, ["cp", authorized_keys, target + "/authorized_keys"])
pmb.helpers.run.root(args, ["rm", authorized_keys])
pmb.helpers.run.root(args, ["chown", "-R", "12345:12345", target])
pmb.helpers.run.root(args, ["chown", "-R", "1000:1000", target])
def setup_keymap(args):
@ -199,9 +210,9 @@ def install_system_image(args):
sys_image = args.device + ".img"
sys_image_sparse = args.device + "-sparse.img"
pmb.chroot.user(args, ["img2simg", sys_image, sys_image_sparse],
working_dir="/home/user/rootfs/")
working_dir="/home/pmos/rootfs/")
pmb.chroot.user(args, ["mv", "-f", sys_image_sparse, sys_image],
working_dir="/home/user/rootfs/")
working_dir="/home/pmos/rootfs/")
# Kernel flash information
logging.info("*** (5/5) FLASHING TO DEVICE ***")
@ -223,7 +234,7 @@ def install_system_image(args):
logging.info("* pmbootstrap flasher flash_system")
logging.info(" Flashes the system image, that has been"
" generated to your device:")
logging.info(" " + args.work + "/chroot_native/home/user/rootfs/" +
logging.info(" " + args.work + "/chroot_native/home/pmos/rootfs/" +
args.device + ".img")
logging.info(" (NOTE: This file has a partition table,"
" which contains a boot- and root subpartition.)")
@ -273,6 +284,9 @@ def install(args):
suffix = "rootfs_" + args.device
pmb.chroot.apk.upgrade(args, suffix)
# Create final user and remove 'build' user
set_user(args)
# Explicitly call build on the install packages, to re-build them or any
# dependency, in case the version increased
if args.extra_packages.lower() != "none":

View File

@ -30,7 +30,7 @@ def partitions_mount(args):
"""
prefix = args.sdcard
if not args.sdcard:
img_path = "/home/user/rootfs/" + args.device + ".img"
img_path = "/home/pmos/rootfs/" + args.device + ".img"
prefix = pmb.install.losetup.device_by_back_file(args, img_path)
partition_prefix = None

View File

@ -66,8 +66,8 @@ def create_zip(args, suffix):
# Move config file from /tmp/ to zip root
["mv", "/tmp/install_options", "install_options"],
# Create tar archive of the rootfs
["tar", "-pczf", "rootfs.tar.gz", "--exclude", "./home/user/*",
"-C", rootfs, "."],
["tar", "-pczf", "rootfs.tar.gz", "--exclude",
"./home/" + args.user + "/*", "-C", rootfs, "."],
["build-recovery-zip"]]
for command in commands:
pmb.chroot.root(args, command, suffix, working_dir=zip_root)

View File

@ -37,7 +37,7 @@ def system_image(args, device):
Returns path to system image for specified device. In case that it doesn't
exist, raise and exception explaining how to generate it.
"""
path = args.work + "/chroot_native/home/user/rootfs/" + device + ".img"
path = args.work + "/chroot_native/home/pmos/rootfs/" + device + ".img"
if not os.path.exists(path):
logging.debug("Could not find system image: " + path)
img_command = "pmbootstrap install"
@ -253,7 +253,7 @@ def run(args):
print()
logging.info("You can connect to the virtual machine using the"
" following services:")
logging.info("(ssh) ssh -p " + str(args.port) + " user@localhost")
logging.info("(ssh) ssh -p {port} {user}@localhost".format(**vars(args)))
logging.info("(telnet) telnet localhost " + str(args.port + 1))
logging.info("(telnet debug) telnet localhost " + str(args.port + 2))

View File

@ -56,7 +56,7 @@ def temp_aports_repo(args):
# aports_upstream repo also gets used in test_aportgen.py, so we use that.
pmb.chroot.apk.install(args, ["git"])
pmb.helpers.git.clone(args, "aports_upstream")
pmb.chroot.user(args, ["cp", "-r", "/home/user/git/aports_upstream",
pmb.chroot.user(args, ["cp", "-r", "/home/pmos/git/aports_upstream",
temp + "/aports"])
# Configure git

View File

@ -52,7 +52,7 @@ def test_challenge_build(args):
version = apkbuild["pkgver"] + "-r" + apkbuild["pkgrel"]
temp_path = pmb.chroot.other.tempfolder(args, "/tmp/test_challenge_build/" +
args.arch_native)
packages_path = "/home/user/packages/user/" + args.arch_native
packages_path = "/home/pmos/packages/pmos/" + args.arch_native
apk_path = packages_path + "/" + pkgname + "-" + version + ".apk"
pmb.chroot.user(args, ["cp", apk_path, apk_path + ".buildinfo.json",
temp_path])

View File

@ -30,7 +30,7 @@ def test_umount_all_list(tmpdir):
fake_mounts = str(tmpdir + "/mounts")
with open(fake_mounts, "w") as handle:
handle.write("source /test/var/cache\n")
handle.write("source /test/home/user/packages\n")
handle.write("source /test/home/pmos/packages\n")
handle.write("source /test\n")
handle.write("source /test/proc\n")
@ -41,5 +41,5 @@ def test_umount_all_list(tmpdir):
assert ret == ["/test/var/cache"]
ret = pmb.helpers.mount.umount_all_list("/test", fake_mounts)
assert ret == ["/test/var/cache", "/test/proc", "/test/home/user/packages",
assert ret == ["/test/var/cache", "/test/proc", "/test/home/pmos/packages",
"/test"]