Merge pull request #9 from morphis/improve-snap-pkg

Improve snap pkg
This commit is contained in:
Simon Fels 2016-12-06 08:05:39 +01:00 committed by GitHub
commit 0887abe263
13 changed files with 124 additions and 176 deletions

4
.gitignore vendored
View file

@ -1,2 +1,6 @@
build*/
parts/
stage/
prime/
*.snap
CMakeLists.txt.user

View file

@ -27,6 +27,53 @@ For more details have a look at the following documentation pages:
* The Android "qemud" multiplexing daemon (https://goo.gl/DeYa5J)
* Android Qemud services (https://goo.gl/W8Lx6t)
## Installation
Anbox is available as a snap in the public Ubuntu Store. Currently it
is only available in the edge channel and requires to be installed in
devmode as we don't have proper confinement for it in place yet.
Additionally you need to manually load the binder and ashmem kernel
drivers everytime as we build them out-of-tree with a hack as this
isn't officially supported. Before you start anbox you always need
to execute
$ cd anbox
$ scripts/load-kmods.sh
Anbox can be installed from the Ubuntu Store with
$ snap install --edge --devmode anbox
Afterwards run it with
$ anbox
After the first installation the container management service needs
a few minutes to setup the container the first time before it is
available.
Applications can be launched via the launch subcommand of the anbox
binary. For example
$ anbox launch --package com.android.settings
## Build from source
To build the Anbox runtime itself there is nothing special to know
about. We're using cmake as build system.
$ mkdir build
$ cd build
$ cmake ..
$ make
That will build the whole stack. A simple
$ make install
will install the necessary bits into your system.
## Copyright and Licensing
Anbox reuses code from other projects like the Android Qemu emulator

View file

@ -1,27 +0,0 @@
#!/bin/sh
set -e
set -x
if [ ! -e android-rootfs.tar ] ; then
echo "ERROR: Missing Android rootfs package!"
exit 1
fi
./cross-compile-chroot.sh -a armhf -d vivid
if [ -e click ] ; then
rm -rf click
fi
mkdir click
cp data/manifest.json click/
cp data/apparmor.json click/
cp data/anbox.desktop click/
(cd click ; tar xf ../android-rootfs.tar ; mv rootfs android-rootfs)
cp build-armhf-vivid/src/anbox click/
cp build-armhf-vivid/src/anbox-container click/
(cd click ; click build .)

View file

@ -23,34 +23,6 @@ function prepare_filesystem() {
chown system:system /dev/$f
chmod 0666 /dev/$f
done
if [ ! -e /.anbox_setup_done ] ; then
echo "Fixing up all permissions ..."
# Fixup permissions of the android binaries in /system
while read line
do
file=`echo $line | cut -d' ' -f 1`
user=`echo $line | cut -d' ' -f 2`
group=`echo $line | cut -d' ' -f 3`
mode=`echo $line | cut -d' ' -f 4`
# Avoid changing symlinks
if [ ! -h /$file ] ; then
chmod $mode /$file
chown -h $user:$group /$file
fi
done < "/filesystem_config.txt"
# Additional ones not listed in the config generated from the build
for f in qemu_pipe qemu_trace goldfish_pipe ; do
[ ! -e /dev/$f ] && continue
chown system:system /dev/$f
chmod 0666 /dev/$f
done
echo "Setup done!"
echo $VERSION > /.anbox_setup_done
fi
}
prepare_filesystem &

View file

@ -5,27 +5,56 @@
# Other than that nothing should ever modify the content of the
# rootfs.
ROOTFS_PATH=$SNAP_COMMON/var/lib/anbox/rootfs
ROOTFS_VERSION=1
DATA_PATH=$SNAP_COMMON/var/lib/anbox
ROOTFS_PATH=$DATA_PATH/rootfs
RAMDISK_PATH=$DATA_PATH/ramdisk
INITRD=$SNAP/ramdisk.img
SYSTEM_IMG=$SNAP/system.img
ANDROID_DATA_PATH=$DATA_PATH/android-data
if [ ! -e $ROOTFS_PATH ] || [ "$ROOTFS_VERSION" != "$(cat $ROOTFS_PATH/.version)" ] ; then
rm -rf $ROOTFS_PATH
echo "Copying rootfs into $ROOTFS_PATH .."
mkdir -p $ROOTFS_PATH
tar xf $SNAP/android-rootfs.tar -C $ROOTFS_PATH/ --strip-components=1
echo $ROOTFS_VERSION > $ROOTFS_PATH/.version
if [ ! -e $INITRD ]; then
echo "ERROR: boot ramdisk does not exist"
exit 1
fi
# Load binder and ashmem kernel drivers. This will just horrible break
# if kernel versions are changing ...
insmod $SNAP/binder_linux.ko || true
chmod 666 /dev/binder
insmod $SNAP/ashmem_linux.ko || true
chmod 666 /dev/ashmem
if [ ! -e $SYSTEM_IMG ]; then
echo "ERROR: system image does not exist"
exit 1
fi
# Extract ramdisk content instead of trying to bind mount the
# cpio image file to allow modifications.
rm -Rf $RAMDISK_PATH
mkdir -p $RAMDISK_PATH
cd $RAMDISK_PATH
cat $INITRD | gzip -d | cpio -i
# FIXME those things should be fixed in the build process
chmod +x $RAMDISK_PATH/anbox-init.sh
# Setup the read-only rootfs
mkdir -p $ROOTFS_PATH
mount -o bind,ro $RAMDISK_PATH $ROOTFS_PATH
mount -o loop,ro $SYSTEM_IMG $ROOTFS_PATH/system
# ... but we keep /data in the read/write space
mkdir -p $ANDROID_DATA_PATH
mount -o bind $ANDROID_DATA_PATH $ROOTFS_PATH/data
# Make sure our setup path for the container rootfs
# is present as lxc is statically configured for
# this path.
mkdir -p $SNAP_COMMON/lxc
exec $SNAP/bin/anbox-wrapper.sh container-manager
# We start the bridge here as long as a oneshot service unit is not
# possible. See snapcraft.yaml for further details.
$SNAP/bin/anbox-bridge.sh start
$SNAP/usr/sbin/aa-exec -p unconfined -- $SNAP/bin/anbox-wrapper.sh container-manager
pid=$!
waitpid $pid
$SNAP/bin/anbox-bridge.sh stop
umount $ROOTFS_PATH/system
umount $ROOTFS_PATH/data

View file

@ -1,11 +0,0 @@
#!/bin/bash
$SNAP/bin/lxc-attach \
--lxcpath=$SNAP_COMMON/var/lib/anbox/containers \
--name default \
--clear-env \
--set-var PATH=/system/bin:/system/sbin:/system/xbin \
--set-var ANDROID_DATA=/data \
--set-var ANDROID_ROOT=/system \
-- \
/system/bin/sh

View file

@ -1,2 +0,0 @@
#!/system/bin/sh
echo "Dummy iptables wrapper"

View file

@ -1,60 +0,0 @@
#!/bin/bash
set -e
set -x
basepath=/home/phablet/android-box
rootfs=$basepath/rootfs
rootfs_overrides=$basepath/overrides
ramdisk=$basepath/ramdisk.img
systemdisk=$basepath/system.img
init_cmd="/init"
if [ "$1" = "shell" ] ; then
init_cmd=/system/bin/sh
fi
if [ -d $rootfs ] ; then
sudo umount --recursive $rootfs || true
rm -rf $rootfs
fi
mkdir -p $rootfs
sudo mount -t tmpfs none $rootfs
(cd $rootfs ; cat $ramdisk | gzip -d | cpio -i)
mkdir -p $rootfs/dev/pts
sudo mount -o ro,loop $systemdisk $rootfs/system
if [ -d "$rootfs_overrides" ] ; then
for f in `ls $rootfs_overrides` ; do
if [ "$f" = "system" ] ; then
for f2 in `find $rootfs_overrides/system -type f` ; do
real_path=`echo $f2 | sed -e s:$rootfs_overrides::g`
sudo mount -o bind $f2 $rootfs/$real_path
done
else
cp $rootfs_overrides/$f $rootfs
fi
done
fi
/home/phablet/bwrap \
--ro-bind $rootfs / \
--bind /home/phablet/android-box/iptables-wrapper /system/bin/iptables \
--bind /home/phablet/android-box/iptables-wrapper /system/bin/ip6tables \
--dev /dev \
--proc /proc \
--tmpfs /data \
--unshare-user \
--unshare-ipc \
--unshare-pid \
--unshare-net \
--unshare-uts \
--uid 0 \
--gid 0 \
--setenv PATH /system/bin:/system/sbin:/system/xbin \
--chdir / \
$init_cmd
sudo umount --recursive $rootfs
rm -rf $rootfs

View file

@ -1,16 +0,0 @@
#!/bin/bash
# We need to put the rootfs somewhere where we can modify some
# parts of the content on first boot (namely file permissions).
# Other than that nothing should ever modify the content of the
# rootfs.
ROOTFS_PATH=$SNAP_COMMON/var/lib/anbox/rootfs
if [ -d $ROOTFS_PATH ] ; then
rm -rf $ROOTFS_PATH
fi
echo "Copying rootfs into $ROOTFS_PATH .."
mkdir -p $ROOTFS_PATH
tar xf $SNAP/android-rootfs.tar -C $ROOTFS_PATH/ --strip-components=1

View file

@ -1,3 +0,0 @@
#!/bin/bash
exec /bin/bash $@

View file

@ -10,21 +10,24 @@ grade: devel
apps:
anbox:
command: bin/anbox-wrapper.sh run
command: bin/anbox-wrapper.sh
container-manager:
command: bin/container-manager.sh
daemon: simple
bridge:
command: bin/anbox-bridge.sh start
stop-command: bin/anbox-bridge.sh stop
daemon: oneshot
# FIXME: a oneshot unit with start/stop commands needs also RemainAfterExit=yes
# but this isn't supported by snapd yet. See LP #1647169 for details.
# bridge:
# command: bin/anbox-bridge.sh start
# stop-command: bin/anbox-bridge.sh stop
# daemon: oneshot
parts:
android-rootfs:
android:
plugin: copy
source: .
files:
android-rootfs.tar: android-rootfs.tar
system.img: system.img
ramdisk.img: ramdisk.img
anbox-common:
plugin: copy
source: .
@ -36,6 +39,10 @@ parts:
- bin/anbox-bridge.sh
- bin/anbox-wrapper.sh
- bin/container-manager.sh
apparmor:
plugin: nil
stage-packages:
- apparmor
lxc:
source: git://github.com/morphis/lxc
source-branch: snappy-support

View file

@ -113,9 +113,11 @@ void LxcContainer::start(const Configuration &configuration) {
"lxc.logfile",
utils::string_format("%s/container.log", config::log_path()).c_str());
set_config_item("lxc.network.type", "veth");
set_config_item("lxc.network.flags", "up");
set_config_item("lxc.network.link", "anboxbr0");
if (fs::exists("/sys/class/net/anboxbr0")) {
set_config_item("lxc.network.type", "veth");
set_config_item("lxc.network.flags", "up");
set_config_item("lxc.network.link", "anboxbr0");
}
#if 0
// Android uses namespaces as well so we have to allow nested namespaces for LXC
@ -136,9 +138,12 @@ void LxcContainer::start(const Configuration &configuration) {
if (fs::is_directory(bind_mount.first)) create_type = "dir";
auto target_path = bind_mount.second;
// LXC wants target paths relative to the container rootfs so
// prividing an absolute path doesn't work.
if (utils::string_starts_with(target_path, "/")) target_path.erase(0, 1);
// The target path needs to be absolute and pointing to the right
// location inside the target rootfs as otherwise we get problems
// when running in confined environments like snap's.
if (!utils::string_starts_with(target_path, "/"))
target_path = std::string("/") + target_path;
target_path = config::rootfs_path() + target_path;
set_config_item(
"lxc.mount.entry",

View file

@ -42,7 +42,10 @@ Daemon::Daemon()
}
int Daemon::Run(const std::vector<std::string> &arguments) try {
return cmd.run({std::cin, std::cout, arguments});
auto argv = arguments;
if (arguments.size() == 0)
argv = {"run"};
return cmd.run({std::cin, std::cout, argv});
} catch (std::exception &err) {
ERROR("%s", err.what());
return EXIT_FAILURE;