How to setup a chroot for use during installation #314

Open
netdesk opened this Issue Nov 22, 2015 · 18 comments

Projects

None yet

5 participants

@netdesk
netdesk commented Nov 22, 2015

I tried to find a solution the whole weekind, but I don't find any way to do additional setup stuff after the installation. That is installing nodejs and pilight from third-party repositories (nodejs.org and pilight.org) and installing wiringPi (git clone and then build). chrooting into /rootfs in the post-install.txt doesn't work properly, errors occouring and I don't think the unbooted chrooted environment is not really suited for this tasks. Then I tried a cronjob "@reboot root /testscript". But the job is executed in the background, the user doesn't see that there is still something going on. As installing nodejs, pilight and building wiringPi takes some time, I want to inform the user about that, he should see the process like the initial installation. I also tried a systemd service or a init.d script which should delete itself after it's done, but no success at all, they stay in the background too.

Is there a preferred way to execute additional tasks on the first boot, which isn't forked invisibly to the background? Did I miss an option of raspbian-ua-netinst?

@goranche
Contributor

chrooting into /rootfs in the post-install.txt doesn't work properly

what do you mean by "doesn't work properly"? I use this method to install several things (including node.js)

@netdesk
netdesk commented Nov 25, 2015

There occoured a couple of errors and warnings during the installation. I was afraid that e.g. node works, but that some features could be broken. Then when I get errors using node.js it could be because of unproper installation. Meanwhile I populate /proc, /sys and /dev before chrooting (just finished a testrun a couple of minutes ago):

mount -t proc proc /rootfs/proc/
mount -t sysfs sys /rootfs/sys/
mount -o bind /dev /rootfs/dev/

There are still warnings during apt-get commands:

dpkg-preconfigure: unable to re-open stdin: No such file or directory

and

E: Can not write log (Is /dev/pts mounted?) - posix_openpt (2: No such file or directory)

I googled a few hints which suggest to ignore those messages. So I guess I'll just have to try it and don't give too much about what apt-get is complaining about.

@netdesk netdesk closed this Nov 25, 2015
@diederikdehaas diederikdehaas changed the title from Script after first boot to How to setup a chroot for use during installation Nov 25, 2015
@diederikdehaas
Member

Let's use this issue to share notes on how to setup a chroot.
I've played with it a bit while experimenting starting the HWRNG of the Pi and encountered several issues too.

E: Can not write log (Is /dev/pts mounted?) - posix_openpt (2: No such file or directory)

That one sounds familiar IIRC. Don't know if it could be problematic though.

@netdesk
netdesk commented Nov 25, 2015

Ok, this is how I do it, there only the two warnings which I mentioned above occour when using apt-get (if you leave out the three mount lines, then there are some more errors and warnings):

cat <<EOF > /rootfs/opt/some-setup-script.sh
#!/bin/bash
# Script doing some tasks ...
# For example installing node.js from the nodejs.org repositories
# (requires curl to be installed e.g. with packages=curl in installer-config.txt
curl -sL https://deb.nodesource.com/setup_4.x | bash -
apt-get install -y nodejs
EOF

chmod u+x /rootfs/opt/some-setup-script.sh
mount -t proc proc /rootfs/proc/
mount -t sysfs sys /rootfs/sys/
mount -o bind /dev /rootfs/dev/
chroot /rootfs /opt/some-setup-script.sh

# if the script should not be kept for later usage:
rm -f /rootfs/opt/some-setup-script.sh
@diederikdehaas
Member

Here's my post-install.txt when experimenting with installing rng-tools, which succeeds, but I do get errors, IIRC it complained about /dev/pts not being available:


echo "Mounting /proc in chroot... "
if [ ! -d /rootfs/proc ] ; then
    mkdir -p /rootfs/proc
    echo "Created /rootfs/proc"
fi
mount -t proc -o nosuid,noexec,nodev proc /rootfs/proc
echo "OK"

echo "Mounting /sys in chroot... "
if [ ! -d /rootfs/sys ] ; then
    mkdir -p /rootfs/sys
    echo "Created /rootfs/sys"
fi
mount -t sysfs -o nosuid,noexec,nodev sysfs /rootfs/sys
echo "OK"

echo "Mounting /dev/ and /dev/pts in chroot... "
mkdir -p -m 755 /rootfs/dev/pts
mount -t devtmpfs -o mode=0755,nosuid devtmpfs /rootfs/dev
mount -t devpts -o gid=5,mode=620 devpts /rootfs/dev/pts
echo "OK"

echo "Trying to start a service ..."
chroot /rootfs /etc/init.d/loadcpufreq restart
echo "Should've restarted the cpufrequtils service..."

echo -n "Loading the hrnd module in the chroot... "
chroot /rootfs /sbin/modprobe bcm2708-rng
if [ $? -eq 0 ]; then
    echo "OK"
else
    echo "FAILED !"
fi

echo -n "Installing rng-tools... "
chroot /rootfs /usr/bin/apt-get -y install rng-tools
if [ $? -eq 0 ]; then
    echo "OK"
else
    echo "FAILED !"
fi
echo "bcm2708-rng" >> /rootfs/etc/modules

if [ ! -d /rootfs/var/log ] ; then
    mkdir -p /rootfs/var/log
    echo "Created /var/log in chroot."
fi

chroot /rootfs /bin/ps aux | grep rng
chroot /rootfs /sbin/lsmod
@goranche goranche closed this Nov 26, 2015
@goranche goranche reopened this Nov 26, 2015
@goranche
Contributor

ooops... "Cancel comment" and "Close Issue" apparently aren't the same thing ๐Ÿ‘ผ

@netdesk
netdesk commented Nov 26, 2015

I'm interested in how you test things like this? Until now I generated the *.xz image, flashed it to an SD card and booted the Pi with it. So every test run, each typo and each syntax error, needs another 15-20 minutes to wait until the post-installation comes up. It's like compiling a kernel 10 years ago :D
Is there a better way? Any Raspberry emulators or virtual machines which handle the basic installation faster?

@diederikdehaas
Member

I'm interested in how you test things like this? ... wait until the post-installation comes up.

For one I'm using the Pi 2, simply because it's faster. Secondly, I try to do these kinds of test/experiments in one of the plain text configuration files and/or use the online configuration files. All that so that I can fix things easily, without having to rebuild the installer, flash it, etc. When things go wrong, I edit the failing config file with vi (build-in to busybox) and reinstall the system. You will need a serial connection to be able to do that.

Any Raspberry emulators or virtual machines

You can use QEMU emulation, but right now it's somewhat cumbersome. But hopefully that will improve.
I'm not aware of a virtual machine that can be used for this, apart from QEMU.

@Jodes81
Jodes81 commented Sep 25, 2016 edited

It would be brilliant if there was an easy way for people to attach an install script which gets executed after installation when it boots up. As @netdesk demonstrated, using post-install.txt is fraught with difficulties (my experience too!), and from his efforts, there doesn't seem to be a way of running such scripts in other ways that don't end up doing so in the background. (systemd, cron...).

Has anyone had any success with this? I can think of one obvious hack:

  1. In the installation files on the SD card, add some script, on-first-login.sh.
  2. In post-install.txt, add the following line:
    echo "source /boot/on-first-login.sh" >> /rootfs/root/.bashrc. That way on-first-login.sh will be run when the user first logs in as root.
  3. In on-first-login.sh, have something to remove that line in .bashrc, something like sed '/on-first-login/d' /root/.bashrc - although this bit is totally untested

My issue with that is the installation would no longer be unattendable.

@Mausy5043
Contributor
Mausy5043 commented Sep 25, 2016 edited

Sometimes things cannot be done during the installation. Then you need to do them after the first boot. I use my repo raspboot to do that. Check it out here. For installing wiringPi and building pigpio check out the folder rbagain in that repo.

All it needs is this in my post-install.txt:

USRHOME="home/pi"
# GIT
echo "Create raspboot..."
mkdir /rootfs/$USRHOME/raspboot
echo "Pull sources from github..."
chroot /rootfs /usr/bin/git clone -b master https://github.com/Mausy5043/raspboot.git /$USRHOME/raspboot
echo master > /rootfs/$USRHOME/.raspboot.branch
echo "Set permissions..."
chmod -R 0755 /rootfs/$USRHOME/raspboot

Obviously you need to tell your users that they need to wait for the second reboot. On my servers a full install can take about 45mins. But, I have a lot to install after first boot ;-) so YMMV.
I also have a Python script on a local server that is executed after booting and that sends me an email when the Pi has booted...

Hope this helps

@Mausy5043
Contributor
Mausy5043 commented Sep 25, 2016 edited

@Jodes81 nothing is holding you back to do just that.

Please remember that this installer is advertised as "for power users" and that it provides a basic system. You, the user, can then build on top of that and extend/expand with whatever else you need. The installation of the basic system is unattended. What happens after that is up to you.

Other OSes also require multiple boots to finish their installation. Why do you think this would be different for your use-case? As you install more complex packages additional reboots may be required.

@netdesk
netdesk commented Sep 25, 2016

For the sake of being unattended I agree that there shouldn't be anything which breaks or could break with this. Though it would add value to this installer, if there would be an easy entrypoint to do additional things on the first boot. It would take the idea of the post-install.txt file just one step further while keeping it unattended. At least one can screw the unattendable quality already with the post-install.txt.

@netdesk
netdesk commented Sep 25, 2016 edited

To clarify my intention: There are two groups of Raspberry Pi users: 1) The ones who don't know exactly what to do with their Pi, they just want some fun. Those are picked up by the offcial Raspbian. 2) And the ones, who have specific tasks and don't want the crap-filled official raspbian. They use an installer like this to set up one or more Pis specifically for their task. And this usually doesn't end after the basic installation. They install LAMPs, home automation stuff, software for integration of Pis in some network infrastructure and other things. If those repeating tasks are not done by ansible or some other orchestration and provisioning toolset, they have to be done on the Pi itself, manually or by install scripts. So it makes really sense to include an easy way to execute scripts after installation, on first boot.

@netdesk netdesk closed this Sep 25, 2016
@Mausy5043
Contributor

@netdesk : I must agree because for that very reason I've created the raspboot repo. You might want to take a look at that. Maybe the concept is what you're looking for?

@netdesk
netdesk commented Sep 25, 2016

Damn, hit the close button on my mobile instead of the normal one ... evil github ux design ...

@netdesk netdesk reopened this Sep 25, 2016
@netdesk
netdesk commented Sep 25, 2016

@Mausy5043 Thanks, I'll have a look at it!

@Jodes81
Jodes81 commented Sep 25, 2016 edited

@Mausy5043 Your report solution sounds brilliant! I have nothing against multiple reboots. I am just after a solution which requires minimal knowledge to reinstall. One reason being I want to design a system once and not have to fuss for future installs - perhaps it's just me but chances are in 6 months I'll have forgotten 90% of what I'm learning now, since I rarely work with Linux, let alone the RPi. @netdesk hit the nail on the head. I have a technical background and am not afraid to get my hands dirty, but I do find linux particularly challenging without guidance - but your Repo solution gives me exactly that!

I'm extremely grateful that you offered it. Perhaps it could at least be mentioned in the documentation so people like me know how to take the unattended installer further. (Saying that, this thread is great!) Is it feasible to bundle the repo on the SD card rather than have it offline?

@diederikdehaas
Member

Is it feasible to bundle the repo on the SD card rather than have it offline?

Assuming you meant whether it is possible to have the repo (offline) on the SD card, then yes.

On your PC, do the git clone and just copy the directory to the sd card.
You can also download the latest version, without the git part, at https://github.com/Mausy5043/raspboot/archive/master.zip which you can (also) reach via the Clone or download button on the repo page (https://github.com/Mausy5043/raspboot/)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment