This commit is contained in:
Santosh D 2017-06-01 20:10:26 +02:00
commit d172dc1a4c
23 changed files with 125 additions and 93 deletions

View File

@ -13,6 +13,8 @@ Sophisticated chroot/build/flash tool to develop and install [postmarketOS](http
## Usage
**Check out the [porting guide](https://github.com/postmarketOS/pmbootstrap/wiki/Porting-to-a-new-device) for a practical start!**
**Porting progess: Wiki/[Devices](https://github.com/postmarketOS/pmbootstrap/wiki/Devices)**
Run `./pmbootstrap.py init` first, to select a target device and the work folder, which will contain all the chroots and other data.
After that, you can run any command. All dependencies (e.g. chroots) will be installed automatically, if they are not available yet.

View File

@ -7,7 +7,7 @@ pkgrel=2
pkgdesc="Enable ccache for cross-compilers with symlinks"
url="https://ccache.samba.org/"
arch="noarch"
license="GPL3+"
license="MIT"
depends="ccache"
makedepends=""
source=""

View File

@ -4,7 +4,7 @@ pkgrel=2
pkgdesc="Google Nexus 4"
url="https://github.com/postmarketOS"
arch="noarch"
license="FIXME"
license="MIT"
depends="linux-lg-mako"
makedepends=""
install=""

View File

@ -4,7 +4,7 @@ pkgrel=2
pkgdesc="Samsung Galaxy SII"
url="https://github.com/postmarketOS"
arch="noarch"
license="FIXME"
license="MIT"
depends="linux-samsung-i9100"
makedepends=""
install=""

View File

@ -370,7 +370,10 @@ package() {
rm -f "$pkgdir"/usr/lib/libffi* "$pkgdir"/usr/share/man/man3/ffi*
find "$pkgdir" -name 'ffi*.h' | xargs rm -f
mkdir -p "$pkgdir"/usr/share/gdb/python/auto-load/usr/lib
local gdblib=${_target:+$CTARGET/}lib
mkdir -p "$pkgdir"/usr/share/gdb/python/auto-load/usr/$gdblib
mv "$pkgdir"/usr/$gdblib/*-gdb.py \
"$pkgdir"/usr/share/gdb/python/auto-load/usr/$gdblib/
paxmark -pmrs "$pkgdir"/$_gcclibexec/cc1

View File

@ -4,7 +4,7 @@ pkgrel=1
pkgdesc="GCC wrappers pointing to cross-compilers (for distcc + ccache)"
url="https://github.com/postmarketOS"
arch="noarch"
license="GPL3+"
license="MIT"
depends=""
makedepends=""
source=""

View File

@ -29,7 +29,7 @@ makedepends="perl sed installkernel bash gmp-dev bc linux-headers elfutils-dev"
options="!strip !check !tracedeps"
install=
source="
https://github.com/LineageOS/${_vendor}-kernel-mako/archive/${_hash}.zip
$pkgname-$_hash.zip::https://github.com/LineageOS/${_vendor}-kernel-mako/archive/${_hash}.zip
$_config
compiler-gcc6.h
gpu-msm-fix-gcc5-compile.patch
@ -101,7 +101,7 @@ package() {
"$pkgdir/usr/share/kernel/$_flavor/kernel.release"
}
sha512sums="5a1636374ea0d2b219de5b501035e8b03935c9cf31a5c1aaa831805318d9ff780b0e13f11c73343c63c74a026c4846215ec7954a1b23740bb690b9723d5d9e11 1495bfcf93f9e0e896331f29e1850387c31d6714.zip
sha512sums="5a1636374ea0d2b219de5b501035e8b03935c9cf31a5c1aaa831805318d9ff780b0e13f11c73343c63c74a026c4846215ec7954a1b23740bb690b9723d5d9e11 linux-lg-mako-1495bfcf93f9e0e896331f29e1850387c31d6714.zip
091f0a6d604653098e3d06a834fa3d4a9c34cbdb4b742c949950bada118e58cc858dce817e763023fe7ac5dd7ae17930ef7a3de765e5b7d84b1971572dbf37a1 config-lg-mako.armhf
d80980e9474c82ba0ef1a6903b434d8bd1b092c40367ba543e72d2c119301c8b2d05265740e4104ca1ac5d15f6c4aa49e8776cb44264a9a28dc551e0d1850dcc compiler-gcc6.h
7be03a9e78b7ac330a54b1f00509caa0621a95c0c55901878ad757f9dd69cc05ba2c8b5ea987063ae1224f92c4d090d515fa5d369e7755181a4871b0d0f82881 gpu-msm-fix-gcc5-compile.patch"

View File

@ -38,7 +38,7 @@ findutils busybox-static"
options="!strip !check !tracedeps"
install=
source="
https://github.com/LineageOS/android_kernel_samsung_smdk4412/archive/${_hash}.zip
$pkgname-$_hash.zip::https://github.com/LineageOS/android_kernel_samsung_smdk4412/archive/${_hash}.zip
$_config
compiler-gcc6.h
init
@ -125,7 +125,7 @@ package() {
"$pkgdir/usr/share/kernel/$_flavor/kernel.release"
}
sha512sums="28198b1312d66a1af28e112f3252aa9fbbbee8bf373776c556cdbc1c75517072a1eec6522717df0b2bc4f6b5f06b9ce07d2cb29a2de07fc56c4ea072f4d46c82 349a3e91e76d17e67ef6213e1f6712e700695631.zip
sha512sums="28198b1312d66a1af28e112f3252aa9fbbbee8bf373776c556cdbc1c75517072a1eec6522717df0b2bc4f6b5f06b9ce07d2cb29a2de07fc56c4ea072f4d46c82 linux-samsung-i9100-349a3e91e76d17e67ef6213e1f6712e700695631.zip
7ce82e81ca8d472f01f8097e3a434fe0130d66b16b29ed3d4c5ce94870fb4efe3b5e79523802b078fcdc737e5a1ee6351bc8427d1271a098eab8e9f35b95e6b1 config-samsung-i9100.armhf
d80980e9474c82ba0ef1a6903b434d8bd1b092c40367ba543e72d2c119301c8b2d05265740e4104ca1ac5d15f6c4aa49e8776cb44264a9a28dc551e0d1850dcc compiler-gcc6.h
dd4094d5f4ec281d32f12af88cb22a782e497c8e52f69cf60b73ac7d6171fc95f1f8040b3d0ad2ff3f016d22ac1d91c5b522e5d03203534a76742bc55a082af5 init"

View File

@ -7,7 +7,7 @@ pkgrel=9
subpackages="musl-dev-armhf:package_dev"
_arch="armhf"
_mirror="https://mirror1.hs-esslingen.de/pub/Mirrors/alpine/"
_mirror="https://nl.alpinelinux.org/alpine/"
url="https://musl-libc.org"
license="MIT"

View File

@ -1,7 +1,7 @@
pkgname=qemu-user-static-repack
pkgver=2.8
_debver=${pkgver}+dfsg-5+b1_amd64
pkgrel=5
_debver=${pkgver}+dfsg-6_amd64
pkgrel=6
pkgdesc="QEMU user mode emulation binaries (static version)"
arch=x86_64
url="https://wiki.debian.org/DebianKernel/ARMMP"
@ -18,7 +18,7 @@ unpack() {
*.deb) ar x ${i##*/} || return 1 ;;
esac
done
# postinst in this archive contains the binfmt information
tar -xf "$srcdir/control.tar.gz" || return 1
}
@ -38,16 +38,16 @@ build() {
do
echo "$line" >> $_binfmtout || return 1
done
for suffix in mask magic; do
grep "_${suffix}=" postinst >> $_binfmtout || return 1
done
}
binfmt() {
binfmt() {
mkdir -p "$pkgdir-binfmt"
install -Dm644 $_binfmtout \
"$pkgdir-binfmt/usr/share/qemu-user-binfmt.txt" || return 1
}
sha512sums="4dd4aab9a8c1040d93d0846b419b2b5b206c18cc92ec6e292ba0b8ffd347dd66ec76065e6737b4dd7c3504439d9332e1cda3865bdcd03f470330990d6cb1b6e6 qemu-user-static_2.8+dfsg-5+b1_amd64.deb"
sha512sums="fb3f2f711b7ee393b0f3ef34f6b7157483a240112d88906e13116a91c583377afae1a297b7d158c31b2e7de38a104db34dc3532e64edae5b063c5531eb56bac9 qemu-user-static_2.8+dfsg-6_amd64.deb"

View File

@ -0,0 +1,21 @@
pkgname=unpackbootimg
pkgver="14.1"
pkgrel=1
pkgdesc="Android bootimg (zimage + initramfs) extraction tool"
url="https://github.com/LineageOS/android_system_core"
arch="noarch"
license="APACHE2"
depends="python3"
source="$pkgname-$pkgver.py::https://raw.githubusercontent.com/LineageOS/android_system_core/cm-${pkgver}/mkbootimg/${pkgname}"
options="!check"
build() {
cp "$srcdir"/"$pkgname"-"$pkgver".py "$srcdir"/"$pkgname"
sed -i -e 's./usr/bin/env python./usr/bin/env python3.' "$srcdir"/"$pkgname"
}
package() {
install -Dm755 "$srcdir"/"$pkgname" "$pkgdir"/usr/bin/"$pkgname"
}
sha512sums="b86022b3f16a6a35c68a7dd00b0ce2dcac667162f11581090bdb07d50a3ea93a74c2f493405d3d6751d40bf463c022216738ad8bcafc457dfc55e08aa5c2ed0e unpackbootimg-14.1.py"

View File

@ -57,10 +57,6 @@ def generate(args, pkgname):
# Do not package libstdc++
'*subpackages="$subpackages libstdc++:libcxx:*':
' subpackages="$subpackages g++$_target:gpp"',
# Do not move gdb.py
'*-gdb.py*': None,
'*/usr/share/gdb/python/auto-load/usr/lib/*': None,
}
pmb.aportgen.core.rewrite(

View File

@ -26,6 +26,20 @@ import pmb.chroot.binfmt
import pmb.helpers.run
def executables_absolute_path():
"""
Get the absolute paths to the sh and chroot executables.
"""
ret = {}
for binary in ["sh", "chroot"]:
path = shutil.which(binary, path=pmb.config.chroot_host_path)
if not path:
raise RuntimeError("Could not find the '" + binary +
"' executable. Make sure, that it is in" " your current user's PATH.")
ret[binary] = path
return ret
def root(args, cmd, suffix="native", working_dir="/", log=True,
auto_init=True, return_stdout=False, check=True):
"""
@ -43,20 +57,19 @@ def root(args, cmd, suffix="native", working_dir="/", log=True,
# Run the args with sudo chroot, and with cleaned environment
# variables
sh_bin = shutil.which("sh")
chroot_bin = shutil.which("chroot")
executables = executables_absolute_path()
for i in range(len(cmd)):
cmd[i] = shlex.quote(cmd[i])
cmd_inner_shell = ("cd " + shlex.quote(working_dir) + ";" +
" ".join(cmd))
cmd_full = ["sudo", sh_bin, "-c",
cmd_full = ["sudo", executables["sh"], "-c",
"unset $(env | cut -d= -f1);" + # unset all
" CHARSET=UTF-8" +
" PATH=" + pmb.config.chroot_path +
" SHELL=/bin/ash" +
" HISTFILE=~/.ash_history" +
" " + chroot_bin +
" " + executables["chroot"] +
" " + chroot +
" sh -c " + shlex.quote(cmd_inner_shell)
]

View File

@ -75,6 +75,11 @@ chroot_path = ":".join([
"/bin"
])
# The PATH variable used on the host, to find the "chroot" and "sh"
# executables. As pmbootstrap runs as user, not as root, the location
# for the chroot executable may not be in the PATH (Debian).
chroot_host_path = os.environ["PATH"] + ":/usr/sbin/"
# Folders, that get mounted inside the chroot
# $WORK gets replaced with args.work
# $ARCH gets replaced with the chroot architecture (eg. x86_64, armhf)

View File

@ -39,7 +39,7 @@ def init(args):
logging.info("Location of the 'work' path. Multiple chroots (native,"
" device arch, device rootfs) will be created in there.")
cfg["pmbootstrap"]["work"] = pmb.helpers.cli.ask(args, "Work path",
None, args.work)
None, args.work, False)
os.makedirs(cfg["pmbootstrap"]["work"], 0o700, True)
# Parallel job count

View File

@ -32,20 +32,26 @@ def core(args, cmd, log_message, log, return_stdout, check=True):
ret = None
if log:
if return_stdout:
ret = subprocess.run(cmd, stdout=subprocess.PIPE,
check=check).stdout.decode('utf-8')
ret = subprocess.check_output(cmd).decode("utf-8")
args.logfd.write(ret)
else:
subprocess.run(cmd, stdout=args.logfd, stderr=args.logfd,
check=check)
subprocess.check_call(cmd, stdout=args.logfd,
stderr=args.logfd)
args.logfd.flush()
else:
logging.debug("*** output passed to pmbootstrap stdout, not" +
" to this log ***")
subprocess.run(cmd, check=check)
subprocess.check_call(cmd)
except subprocess.CalledProcessError as exc:
raise RuntimeError("Command failed: " + log_message) from exc
if check:
if log:
logging.debug("^" * 70)
logging.info("NOTE: The failed command's output is above"
" the ^^^ line in the logfile: " + args.log)
raise RuntimeError("Command failed: " + log_message) from exc
else:
pass
return ret

View File

@ -30,38 +30,59 @@ import pmb.parse.apkindex
@pytest.fixture
def args():
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
setattr(args, "logfd", open("/dev/null", "a+"))
yield args
args.logfd.close()
request.addfinalizer(args.logfd.close)
return args
def test_read_signature_info(tmpdir):
with tarfile.open(tmpdir + "/test.apk", "w:gz") as tar:
# No signature found
def test_read_signature_info(args):
# Tempfolder inside chroot for fake apk files
tmp_path = "/tmp/test_read_signature_info"
tmp_path_chroot = args.work + "/chroot_native" + tmp_path
if os.path.exists(tmp_path_chroot):
pmb.chroot.root(args, ["rm", "-r", tmp_path])
pmb.chroot.user(args, ["mkdir", "-p", tmp_path])
# No signature found
pmb.chroot.user(args, ["tar", "-czf", tmp_path + "/no_sig.apk",
"/etc/issue"])
with tarfile.open(tmp_path_chroot + "/no_sig.apk", "r:gz") as tar:
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.read_signature_info(tar)
assert "Could not find signature" in str(e.value)
# Add signature file with invalid name
tar.add(__file__, "sbin/apk.static.SIGN.RSA.invalid.pub")
# Signature file with invalid name
pmb.chroot.user(args, ["mkdir", "-p", tmp_path + "/sbin"])
pmb.chroot.user(args, ["cp", "/etc/issue", tmp_path +
"/sbin/apk.static.SIGN.RSA.invalid.pub"])
pmb.chroot.user(args, ["tar", "-czf", tmp_path + "/invalid_sig.apk",
"sbin/apk.static.SIGN.RSA.invalid.pub"],
working_dir=tmp_path)
with tarfile.open(tmp_path_chroot + "/invalid_sig.apk", "r:gz") as tar:
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.read_signature_info(tar)
assert "Invalid signature key" in str(e.value)
# Add signature file with realistic name
# Signature file with realistic name
path = glob.glob(pmb_src + "/keys/*.pub")[0]
name = os.path.basename(path)
path_archive = "sbin/apk.static.SIGN.RSA." + name
with tarfile.open(tmpdir + "/test2.apk", "w:gz") as tar:
tar.add(__file__, path_archive)
pmb.chroot.user(args, ["mv", tmp_path + "/sbin/apk.static.SIGN.RSA.invalid.pub",
tmp_path + "/" + path_archive])
pmb.chroot.user(args, ["tar", "-czf", tmp_path + "/realistic_name_sig.apk",
path_archive], working_dir=tmp_path)
with tarfile.open(tmp_path_chroot + "/realistic_name_sig.apk", "r:gz") as tar:
sigfilename, sigkey_path = pmb.chroot.apk_static.read_signature_info(
tar)
assert sigfilename == path_archive
assert sigkey_path == path
assert sigfilename == path_archive
assert sigkey_path == path
# Clean up
pmb.chroot.user(args, ["rm", "-r", tmp_path])
def test_successful_extraction(args, tmpdir):

View File

@ -28,15 +28,15 @@ import pmb.aportgen
@pytest.fixture
def args(tmpdir):
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
setattr(args, "logfd", open("/dev/null", "a+"))
setattr(args, "_aports_real", args.aports)
args.aports = str(tmpdir)
yield args
args.logfd.close()
request.addfinalizer(args.logfd.close)
return args
def test_aportgen(args):

View File

@ -27,13 +27,13 @@ import pmb.aportgen
@pytest.fixture
def args(tmpdir):
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
setattr(args, "logfd", open("/dev/null", "a+"))
yield args
args.logfd.close()
request.addfinalizer(args.logfd.close)
return args
def test_build(args):

View File

@ -30,13 +30,12 @@ import pmb.helpers.git
@pytest.fixture
def args():
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
setattr(args, "logfd", open("/dev/null", "a+"))
yield args
args.logfd.close()
request.addfinalizer(args.logfd.close)
return args

View File

@ -29,13 +29,13 @@ import pmb.chroot.user
@pytest.fixture
def args():
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
setattr(args, "logfd", open("/dev/null", "a+"))
yield args
args.logfd.close()
request.addfinalizer(args.logfd.close)
return args
def test_shell_escape(args):

View File

@ -1,33 +0,0 @@
"""
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 os
import glob
def test_use_pmb_helpers_run_instead_of_subprocess_run():
src = os.path.abspath(os.path.dirname(__file__) + "/..")
files = glob.glob(src + "/pmb/**/*.py",
recursive=True) + glob.glob(src + "*.py")
okay = os.path.abspath(src + "/pmb/helpers/run.py")
for file in files:
with open(file, "r") as handle:
source = handle.read()
if file != okay and "subprocess.run" in source:
raise RuntimeError("File " + file + " use pmb.helpers.run.user()"
" instead of subprocess.run()!")

View File

@ -28,13 +28,12 @@ import pmb.helpers.git
@pytest.fixture
def args():
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
setattr(args, "logfd", open("/dev/null", "a+"))
yield args
args.logfd.close()
request.addfinalizer(args.logfd.close)
return args