Re: foreign rootfs without root priviliges with multistrap, fakeroot, fakechroot and qemu user emulation
On Thu, Jun 16, 2011 at 07:15:35PM +0200, Stappers wrote:
> On Thu, Jun 16, 2011 at 10:40:01AM +0200, Johannes Schauer wrote:
> > hi,
> >
> > as a follow up for "fakechroot + qemu user emulation" in january 2011 and my
> > solution explained in "fakechroot + qemu user emulation (it works now)" in
> > april 2011 and by the request of wookey who suggested I should post it here,
> > let me just paste the links to four scripts of mine.
> >
> > notioninkadam: http://mister-muffin.de/p/_8K5
> > touchbook: http://mister-muffin.de/p/9nQ4
> > openmoko: http://mister-muffin.de/p/wFep
> > kirkwood: http://mister-muffin.de/p/l0U_
>
> The openmoko one for further (in-line) discussion
> fetched with `wget -O - openmoko: http://mister-muffin.de/p/wFep`
fetched with `wget -O - http://mister-muffin.de/p/wFep`
>
> --2011-06-16 19:09:47-- http://mister-muffin.de/p/wFep
> Herleiden van mister-muffin.de... 62.75.187.73
> Verbinding maken met mister-muffin.de|62.75.187.73|:80... verbonden.
> HTTP-verzoek is verzonden; wachten op antwoord... 200 OK
> Lengte: 5838 (5,7K) [text/plain]
> Wordt geschreven naar: `STDOUT'
> #!/bin/sh -ex
>
> if [ "$LOGNAME" = "root" ] \
> || [ "$USER" = "root" ] \
> || [ "$USERNAME" = "root" ] \
> || [ "$SUDO_COMMAND" != "" ] \
> || [ "$SUDO_USER" != "" ] \
> || [ "$SUDO_UID" != "" ] \
> || [ "$SUDO_GID" != "" ]; then
> echo "don't run this script as root - there is no need to"
> exit
> fi
>
> if [ "$FAKEROOTKEY" = "" ]; then
> echo "re-executing script inside fakeroot"
> fakeroot $0;
> exit
> fi
>
> DIST="sid"
> ROOTDIR="debian-$DIST-multistrap"
> MIRROR="http://127.0.0.1:3142/ftp.de.debian.org/debian"
> MIRROR_REAL="http://ftp.de.debian.org/debian"
> #MIRROR="http://127.0.0.1:3142/ftp.debian-ports.org/debian"
> #MIRROR_REAL="http://ftp.debian-ports.org/debian"
>
> export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C
>
> rm -rf $ROOTDIR $ROOTDIR.tar
>
> PACKAGES="locales udev module-init-tools procps mtd-utils curl wget ntpdate"
> PACKAGES=$PACKAGES" screen less vim-tiny console-tools vpnc rsync conspy"
> PACKAGES=$PACKAGES" man-db fbset input-utils openssh-server wpasupplicant"
> PACKAGES=$PACKAGES" bluez bluez-utils bluez-alsa bluez-gstreamer iputils-ping"
> PACKAGES=$PACKAGES" iproute dnsutils nodm xserver-xorg-input-evdev xterm"
> PACKAGES=$PACKAGES" xserver
> 0K .-xorg xserver-xorg-video-fbdev"
>
> cat > multistrap.conf << __END__
> [General]
> #arch=armhf
> arch=armel
> directory=$ROOTDIR
> cleanup=true
> unpack=true
> noauth=true
> #bootstrap=Debian_bootstrap Debian_unreleased
> bootstrap=Debian_bootstrap
> aptsources=Debian
> allowrecommends=false
> addimportant=false
>
> [Debian_bootstrap]
> packages=$PACKAGES
> source=$MIRROR
> suite=$DIST
> omitdebsrc=true
>
> #[Debian_unreleased]
> #packages=$PACKAGES
> #source=$MIRROR
> #suite=unreleased
> #omitdebsrc=true
>
> [Debian]
> source=$MIRROR_REAL
> keyring=debian-archive-keyring
> suite=$DIST
> omitdebsrc=true
> __END__
>
> multistrap -f multistrap.conf
>
> cp /usr/bin/qemu-arm-static $ROOTDIR/usr/bin
>
> # stop invoke-rc.d from starting services
> cat > $ROOTDIR/usr/sbin/policy-rc.d << __END__
> #!/bin/sh
> echo "sysvinit: All runlevel operations denied by policy" >&2
> exit 101
> __END__
> chmod +x $ROOTDIR/usr/sbin/policy-rc.d
>
> # fix for ldconfig inside fakechroot
> mv $ROOTDIR/sbin/ldconfig $ROOTDIR/sbin/ldconfig.REAL
> mv $ROOTDIR/usr/bin/ldd $ROOTDIR/usr/bin/ldd.REAL
> ln -s ../bin/true $ROOTDIR/sbin/ldconfig
>
> # get fake ldd (needs objdump from binutils) for mkinitramfs
> # https://github.com/fakechroot/fakechroot/raw/master/scripts/ldd.pl
> curl http://mister-muffin.de/p/a3Dt > $ROOTDIR/usr/bin/ldd
fetched with `wget -O - http://mister-muffin.de/p/a3Dt`
--2011-06-16 20:01:51-- http://mister-muffin.de/p/a3Dt
Herleiden van mister-muffin.de... 62.75.187.73
Verbinding maken met mister-muffin.de|62.75.187.73|:80... verbonden.
HTTP-verzoek is verzonden; wachten op antwoord... 200 OK
Lengte: 4464 (4,4K) [text/plain]
Wordt geschreven naar: `STDOUT'
#!/usr/bin/perl
# fakeldd
#
# Replacement for ldd with usage of objdump
#
# (c) 2003-2010 Piotr Roszatycki <dexter@debian.org>, LGPL
use strict;
my @Libs = ();
my %Libs = ();
my $Status = 0;
my $Dynamic = 0;
my $Format = '';
my $Ldsodir = "/lib";
my @Ld_Library_Path = qw(/usr/lib /lib /usr/lib32 /lib32 /usr/lib64 /lib64);
sub ldso {
my ($lib) = @_;
return if $Libs{$lib};
my $path;
if ($lib =~ /^\//) {
$path = $lib;
}
else {
foreach my $dir (@Ld_Library_Path) {
next unless -f "$dir/$lib";
my $badformat = 0;
local *PIPE;
open PIPE, "objdump -p '$dir/$lib' 2>/dev/null |";
while (my $line = <PIPE>) {
if ($line =~ /file format (\S*)$/) {
$badformat = 1 unless $1 eq $Format;
last;
}
}
close PIPE;
next if $badformat;
$path = "$dir/$lib";
last;
}
}
push @Libs, $lib;
if (-f $path) {
$Libs{$lib} = $path;
objdump($path);
}
}
sub objdump {
my (@files) = @_;
foreach my $file (@files) {
local *PIPE
0K .;
open PIPE, "objdump -p '$file' 2>/dev/null |";
while (my $line = <PIPE>) {
$line =~ s/^\s+//;
if ($line =~ /file format (\S*)$/) {
if (not $Format) {
$Format = $1;
if ($^O eq 'linux') {
if ($Format =~ /^elf64-/) {
push @Libs, 'linux-vdso.so.1';
$Libs{'linux-vdso.so.1'} = '';
}
else {
push @Libs, 'linux-gate.so.1';
$Libs{'linux-gate.so.1'} = '';
}
}
foreach my $lib (split /:/, $ENV{LD_PRELOAD}||'') {
ldso($lib);
}
}
else {
next unless $Format eq $1;
}
}
if (not $Dynamic and $line =~ /^Dynamic Section:/) {
$Dynamic = 1;
}
next unless $line =~ /^ \s* NEEDED \s+ (.*) \s* $/x;
my $needed = $1;
if ($needed =~ /^ld(-linux)?(\.|-)/) {
$needed = "$Ldsodir/$needed";
}
ldso($needed);
}
close PIPE;
}
}
sub load_ldsoconf {
my ($file) = @_;
local *FH;
open FH, $file;
while (my $line = <FH>) {
chomp $line.;
$line =~ s/#.*//;
next if $line =~ /^\s*$/;
if ($line =~ /^include\s+(.*)\s*/) {
my $include = $1;
foreach my $incfile (glob $include) {
load_ldsoconf($incfile);
}
next;
}
unshift @Ld_Library_Path, $line;
}
close FH;
}
MAIN: {
my @args = @ARGV;
if (not @args) {
print STDERR "fakeldd: missing file arguments\n";
exit 1;
}
if (not `which objdump`) {
print STDERR "fakeldd: objdump: command not found: install binutils package\n";
exit 1;
}
load_ldsoconf('/etc/ld.so.conf');
unshift @Ld_Library_Path, split(/:/, $ENV{LD_LIBRARY_PATH}||'');
while ($args[0] =~ /^-/) {
my $arg = $args[0];
shift @ARGV;
last if $arg eq "--";
}
foreach my $file (@args) {
%Libs = ();
$Dynamic = 0;
if (@args > 1) {
print "$file:\n";
}
if (not -f $file) {
print STDERR "ldd: $file: No such file or directory\n";
$Status = 1;
next;
}
objdump($file);
if ($Dynamic == 0) {
print "\tnot a dynamic executable\n";
$Status = 1;
}
elsif (scalar %Libs eq "0") {
print "\tstatically linked\n";
}
my $address = '0x' . '0' x ($Format =~ /^elf64-/ ? 16 : 8);
forea.ch my $lib (@Libs) {
if ($lib =~ /^\//) {
printf "\t%s (%s)\n", $lib, $address;
}
elsif (defined $Libs{$lib}) {
printf "\t%s => %s (%s)\n", $lib, $Libs{$lib}, $address;
}
else {
printf "\t%s => not found\n", $lib;
}
}
}
}
END {
$? = $Status;
}
. 100% 140K=0,03s
2011-06-16 20:01:51 (140 KB/s) - geschreven naar stdout [4464/4464]
> chmod +x $ROOTDIR/usr/bin/ldd
>
> # supply ld.so.conf for fake ldd (running libc6 postinst script will fail)
> echo "include /etc/ld.so.conf.d/*.conf" > $ROOTDIR/etc/ld.so.conf
>
> # do not generate ssh host keys
> mkdir -p. $ROOTDIR/etc/ssh/
> touch "$ROOTDIR/etc/ssh/ssh_host_rsa_key"
> touch "$ROOTDIR/etc/ssh/ssh_host_dsa_key"
> touch "$ROOTDIR/etc/ssh/ssh_host_ecdsa_key"
>
> cat > $ROOTDIR/tmp/debconfseed.txt << __END__
> # put debconf options here
> __END__
> fakechroot chroot $ROOTDIR debconf-set-selections /tmp/debconfseed.txt
> rm $ROOTDIR/tmp/debconfseed.txt
>
> # run preinst scripts
> for script in $ROOTDIR/var/lib/dpkg/info/*.preinst; do
> [ "$script" = "$ROOTDIR/var/lib/dpkg/info/bash.preinst" ] && continue
> fakechroot chroot $ROOTDIR ${script##$ROOTDIR} install
> done
>
> # run dpkg --configure -a twice because of errors during the first run
> fakechroot chroot $ROOTDIR /usr/bin/dpkg --configure -a || fakechroot chroot $ROOTDIR /usr/bin/dpkg --configure -a
>
> fakechroot chroot $ROOTDIR update-locale LANG=en_US.UTF-8 LANGUAGE=en_US:en
> echo en_US.UTF-8 UTF-8 > $ROOTDIR/etc/locale.gen
> fakechroot chroot $ROOTDIR locale-gen
>
> cat > $ROOTDIR/etc/fstab << __END__
> # <file system> <mount point> <type> <options> <dump> <pass>
> rootfs / auto defaults,errors=remount-ro,noatime 0 1
> /dev/mmcblk0p2 /home auto defaults,errors=remount-ro,noatime 0 2
> proc /proc proc defaults 0 0
> tmpfs /tmp tmpfs defaults,noatime 0 0
> tmpfs /var/lock tmpfs defaults,noatime 0 0
> t.mpfs /var/run tmpfs defaults,noatime 0 0
> tmpfs /var/log tmpfs defaults,noatime 0 0
> tmpfs /etc/network/run tmpfs defaults,noatime 0 0
> __END__
>
> echo openmoko > $ROOTDIR/etc/hostname
>
> cat > $ROOTDIR/etc/hosts << __END__
> 127.0.0.1 localhost
> 127.0.0.1 openmoko
> __END__
>
> cat > $ROOTDIR/etc/default/nodm << __END__
> NODM_ENABLED=true
> NODM_USER=user
> NODM_XINIT=/usr/bin/xinit
> NODM_FIRST_VT=7
> NODM_XSESSION=/etc/X11/Xsession
> NODM_X_OPTIONS='-nolisten tcp'
> NODM_MIN_SESSION_TIME=60
> __END__
>
> # activate a tty on serial
> echo "T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100" >> $ROOTDIR/etc/inittab
>
> fakechroot chroot $ROOTDIR useradd user -p `openssl passwd -crypt -salt // ""` -s /bin/bash --create-home
> fakechroot chroot $ROOTDIR usermod -a -G audio,dialout user
>
> sed -i 's/\(root:\)[^:]*\(:\)/\1'`openssl passwd -crypt -salt // "" | sed 's/\(\/\|\\\|&\)/\\&/g'`'\2/' $ROOTDIR/etc/shadow
> sed -i 's/\(PermitEmptyPasswords\) no/\1 yes/' $ROOTDIR/etc/ssh/sshd_config
> echo 'APT::Install-Recommends "0";' > $ROOTDIR/etc/apt/apt.conf.d/99no-install-recommends
> echo 'Acquire::PDiffs "0";' > $ROOTDIR/etc/apt/apt.conf.d/99no-pdiffs
>
> #cleanup
> rm $ROOTDIR/sbin/ldconfig $ROOTDIR/usr/bin/ldd
> mv $ROOTDIR/sbin/ldconfig.REAL $ROOTDIR/sbin/ldconfig
> mv $ROOTDIR/usr/bin/ldd.REAL $ROOTDIR/usr/bin/ldd
> rm $ROOTDIR/usr/sbin/policy-rc.d
> rm $ROOTDIR/etc/ssh/ssh_host_*
> cp /etc/resolv.conf $ROOTDIR/etc/resolv.conf
>
> # need to generate tar inside fakechroot so that absolute symlinks are correct
> fakechroot chroot $ROOTDIR tar -cf $ROOTDIR.tar -C / .
> mv $ROOTDIR/$ROOTDIR.tar .
>
> tar --delete -f $ROOTDIR.tar ./usr/bin/qemu-arm-static
> rm $ROOTDIR/usr/bin/qemu-arm-static
> .. 100% 144K=0,04s
>
> 2011-06-16 19:09:47 (144 KB/s) - geschreven naar stdout [5838/5838]
Reply to: