Virtual Machines vs Chroots for Software Developers

in #development8 years ago (edited)

In my recent activities I have become quite diverted because in order to instruct those who might wish to build and run applications that I create, they need to know how to set up the prerequisites of the system. The biggest sticking point has been in the accessibility of the VM filesystem, between the host and the hosted machine. Every solution I have tried has been cumbersome.

But then I realised: If I am simply wanting a base system that I can replicate and then use this to establish dependencies for an application, a chroot is better. Even more than better, because I use the btrfs filesystem, and using its' clever Copy on Write (CoW) architecture, I can make a base installation, then make a snapshot, which only writes new data to the actual filesystem, when the copy's contents differ from the original.

I have plenty of experience working with chroots from my work with debian's debootstrap and arch linux, so for me, writing a simple shell script that lets me handle all the mounting of the essential binds to the root folders like /dev, /sys, /proc, etc, and I know that I can deconstruct it with one command, 'umount -l chroot-root-folder-path ' after exiting the chroot, assuming I have not set the current working directory to one of these bind mounts, poof it's gone.

I am implementing this solution right now, so at last I can get back to my porting project.

Here is the solution that I made:

First, I migrated my installation image that I copied out of the raw disk image I used to install using virtualbox. Making the installation filesystem can be done other ways, like debootstrap for debian or pacstrap for arch linux.

I made a folder ~/chroots, and inside that I made a folder, in my case, I called it lubuntu, because that's the installation that lives in there.

This script I made in the ~/chroots folder, and called it chroot.sh, set it to executable with 'chmod +x chroot.sh'. It takes one parameter, namely, the folder of the chroot. This will allow me to make multiple folders. I will briefly mention the advantage of doing this on a btrfs filesystem for making snapshots shortly.

#!/bin/bash
for i in dev dev/pts sys proc run; do sudo mount -o bind /$i $1/$i; done
sudo cp -f /etc/resolv.conf $1/etc/
sudo chroot $1 /root/startup.sh `whoami` $1
for i in dev/pts dev sys proc run; do sudo umount $1/$i; done

I have added a second parameter to the script startup.sh, which will change the hostname within the chroot, making it obvious you are not in kansas anymore, dorothy. It will be the folder of the chroot. I thought I had added the prefix to the prompt, but it turns out in ubuntu, it automatically adds 'chroot ' to the front of the prompt. I removed it, and it didn't go away. Then I realised it's a built in feature.

A variation you can add to this, to save on download time (for me this is important, being on a metered 4g connect that is currently shaped), if your chroot is the same as the host (doesn't matter which flavour of ubuntu, if there is a difference, most of the packages are the same), is to add this to that script after the for line at the top:

sudo mount -o bind /var/cache/apt/archives $1/var/cache/apt/archives

and then before the for line at the bottom, the following line:

sudo umount $1/var/cache/apt/archives

This is necessary because it would otherwise be cumbersome to share these folders between the chroots (with multiple snapshots) - btrfs snapshots don't, as far as I know, allow cross-volume links, or at least, within a chroot, they won't work properly without using bind mounts. I could be wrong but I know this will work.

The little thing between backticks (`) where it says 'whoami' gets your username. This script is meant to be run as a regular user with administrative rights, the default in most linux systems. This parameter is used by the next script to set it so your user becomes the user in the chroot.

Next, inside the chroot (which in my case lives in ~/chroots/lubuntu) in /root I made a startup script for inside the chroot after it starts. Like so:

!/bin/bash
source /etc/profile
source $HOME/.bashrc
hostname $2
cd $HOME
su $1

The hostname command, takes the parameter from the first script, which is the name of the folder you are chrooting into. This changes the suffix after the username@ in the default ubuntu shell prompt. This makes it obvious you are no longer inside the main system, in case you forget. You also need to delete /etc/hostname from the chroot. Otherwise things will get confused.

The xhost command sets the redirect for applications you want to run that use a GUI to use the X server in the host system.

With this setup, once you have a working installation inside (I will leave how to do that as an exercise for the user, there is too many ways you can use), voila. Inside the chroot, with regular user privileges.

The last little hint I will give is as follows. If the location where you do this, is on a btrfs filesystem, you should create a submount using btrfs like so:

sudo btrfs subvolume create *chrootname*

And then copy the system into it. Next, when you have got it at a point you like, you can almost instantly make a backup, in the form of a snapshot, like so:

sudo btrfs subvolume snapshot *chrootname* *copyname*

and voila, you can chroot into the snapshot, change it, and the original will not be changed. Plus thanks to the wonders of Copy on Write in btrfs, the whole thing only takes as much space as the original, plus whatever is added to the snapshot.

I hope this helps someone. I am filing this also under #steemportal to try and keep my work in one place for people to easily find it, as this all relates to the project, as well as partly being, like the solution I am outlining here, some training for developers who may know some linux and code on a different platform, but who might want to try working with ubuntu, as I am.

I am not getting huge amounts of votes for these posts, but little bits help. Steembits, shall we say, a few steemcents here and a few steemcents there. I have learned how to use the buy/sell interface so I can consolidate my assets into steem, and as I accumulate enough to make a trade on shapeshift.io, I push it across to my wirex card, using the handy shapeshift link that wirex have now added. I don't like that I am selling my steem, really, but I need to eat and get my supplies, and every little bit helps right now. Hopefully as I continue this helpful work to get others also up and running doing development, and my own projects progress, I will gain a higher reputation, slowly my SP will tick up, and more people will follow this and start upvoting as well. I don't want to work alone, I hope that eventually someone else with the same idea will realise that we can mutually benefit from working together, so that is also another goal in this activity.

You might say that I am a would-be Steem INC manager, and I am working towards setting up a team for a new department that I am petitioning to set up. It will help people a lot when more people understand that Steem is an ad-hoc corporation, in which you can directly invest, directly start projects connected to steem, locate parters in your little sub-ventures, and work towards bringing more value to the Company.

This gives me an idea for a new post, actually.

I should be coding, but what the hell. I need to get noticed, upvoted, and find collaborators. The best way to do that is to promote my ideas, others can help me refine them where they are needing refinement, and we can get a movement going where everyone starts to realise exactly what Steem is.

Sort:  

I have heard of it, but never looked closely. Being that I have limited bandwidth at the moment, I am just applying the simplest measures to solve the issue I have - how to identify what packages from the package manager in Ubuntu, in this case, are required to run some software that I am developing. With the chroot set up, I can then just copy in my project, and attempt to run it, and it will flag all the missing packages from a base install, then I install everything that gets rid of these errors, and I have a log in the shell scrollback history that I can use to add this list to the documentation for my project. From what I understand of Docker, its application is not really directly relevant to this, as it is more or less like a revamp of package management systems, and it handles dependencies, so either way I would still be in the same situation, not able to know for certain exactly which packages my project requires exactly.

Once I do know, it probably will mostly apply to any project I do based on the same set of libraries imported in the code. Anything new after that, will probably be obvious. The Piston library has a particular set of requirements, and my code may not directly require them but will still require them to be present for Piston to work. Later on maybe I will add other elements, perhaps I will create chart renderers, for example, which will involve Cairo and maybe OpenGL.

But I probably only need to solve this main problem once. I am just doing it so that when someone goes and looks at my github repositories, they have enough information to get it running and see it in action. This is important from a marketing perspective, since personal testimony is good for sales, as is for organisation, the ability for an interested person to get up and running quickly to start contributing.

Marketing is still important, even if you are not trying to sell something. Finding collaborators requires marketing. Gaining votes for ideas and projects is marketing.

Coin Marketplace

STEEM 0.19
TRX 0.16
JST 0.033
BTC 64186.90
ETH 2759.80
USDT 1.00
SBD 2.66