3

I would like to set up a continuous delivery cycle for my open source application. It is based on Linux's Filesystem in Userspace (FUSE). I tried to set it up on CloudBees' Jenkins, which provided decent free accounts, but I did not have root access, which is problematic as my project has many dependencies. I went on to use Travis CI, which works great for testing internal APIs, since I have root access to install dependencies. But it does not support FUSE, so I cannot run tests on the filesystem directly. According to my experience with Travis CI, a Continuous Delivery approach would likely prevent many bugs from being released and could help to identify problems more quickly.

Is there a service similar to Travis CI, which integrates with Github, allows root access, and supports FUSE?

[EDIT]
Vi. suggests to run User Mode Linux on a Travis-ci machine, to emulate FUSE. To summarize the progress achieved with Vi.s help:

  1. For setting up UML with more memory, network access and access to the file system execute:

    /usr/bin/linux.uml init=script_to_run.sh rootfstype=hostfs rw eth0=slirp mem=2G
    

Inside the user script, call:

# Enable fuse module.
insmod /usr/lib/uml/modules/`uname -r`/kernel/fs/fuse/fuse.ko

# Set up TCP/UDP network access.
ifconfig lo up
ifconfig eth0 10.0.2.15
ip route add default via 10.0.2.1
  1. If you work with gcc, set your PATH variable:

    export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    
  2. If you need procfs, execute this inside UML:

    mount none /proc -t hppfs
    
  3. For Python, you should activate the virtual environment inside UML:

    source /home/travis/virtualenv/python2.6.9/bin/activate
    

The path to activate can be found by issuing the following command before starting UML:

echo "Path to Python executable: "$(which python)

Still I cannot run FUSE:

In short:

`fuse' likely not compiled with -mcmodel=kernel
insmod: error inserting '/usr/lib/uml/modules/3.2.2/kernel/fs/fuse/fuse.ko': -1 Invalid module format
modprobe: FATAL: Could not load /lib/modules/3.2.2/modules.dep: No such file or directory
modprobe: FATAL: Could not load /lib/modules/3.2.2/modules.dep: No such file or directory
[...]
fuse: device not found, try 'modprobe fuse' first        
phobic
  • 914
  • 10
  • 24
  • Maybe UML (User mode linux) can be used as a workaround? – Vi. Jan 20 '15 at 23:41
  • If I understand it correctly, this is similar to a virtual machine. I would have to check how much resources it takes to set it up for each and every test, too see if this solution is feasible. Thanks for the suggestion. – phobic Jan 21 '15 at 09:27

1 Answers1

3

Travis-CI allows installing system packages, including UML (User Mode Linux).

You can start your application inside UML (with a helper script). Example: https://travis-ci.org/vi/execfuse/builds/47789978

Here is the helper script:

#!/bin/bash

CURDIR="`pwd`"

cat > umltest.inner.sh <<EOF
#!/bin/sh
(
   export PATH="$PATH"
   set -e
   set -x
   insmod /usr/lib/uml/modules/\`uname -r\`/kernel/fs/fuse/fuse.ko
   cd "$CURDIR"
   ./tests.sh
   echo Success
)
echo "\$?" > "$CURDIR"/umltest.status
halt -f
EOF

chmod +x umltest.inner.sh

/usr/bin/linux.uml init=`pwd`/umltest.inner.sh rootfstype=hostfs rw

exit $(<umltest.status)

Supplementary commands in .travis.yml:

- sudo apt-get install -qq libfuse-dev pkg-config fuse user-mode-linux
- sudo mknod /dev/fuse c 10 229
- sudo chmod 666 /dev/fuse
Vi.
  • 37,014
  • 18
  • 93
  • 148
  • I tried to use your setup, but I cannot get network access which is required for my tests. I added the argument 'eth0=tuntap,,,$myip', but ifconfig -a does not show any device. – phobic Jan 25 '15 at 15:00
  • 1
    @phobic, I can create a networking-enabled version of the script. Easiest mode: `eth0=slirp` to `linux.uml` command line, then `ifconfig lo up; ifconfig eth0 10.0.2.15; ip route add default via 10.0.2.1` inside the script. Note that pings won't work, but TCP and UDP should work. `slirp` package needs to be installed. Manual: http://user-mode-linux.sourceforge.net/old/UserModeLinux-HOWTO-6.html – Vi. Jan 25 '15 at 15:32
  • @phobic, If you need incoming connections, you need either to setup more proper tun/tap network or to activate Slirp's port forwarding (note that connections from localhost address like `127.0.0.1` may fail to work). – Vi. Jan 25 '15 at 20:53
  • :. Thanks, network seems ok now, I also needed to mount procfs and allowed UML to use more memory, I will update in the evening if I get it to work. – phobic Jan 26 '15 at 13:56
  • 1
    @phobic, There are appropriate options in UML. Try `linux.uml --help`. You can mount procfs from inside the container like usual `mount -t proc proc /proc`. For performance, I expect about 50-fold slowdown for syscalls any maybe 2-fold slowdown for CPU-bound calculations. – Vi. Jan 26 '15 at 14:48
  • I still cannot get it to work. I have trouble with python psutil, for which I needed to enable procfs. In UML python actually tells me that psutil does not exist, even though I installed it on the host. I tried to install it inside UML, but it is rather difficult (no access to sudoers, gcc complains about missing executable cc1, limits.h, and stddef.h). I started UML with root privileges to install psutil, linked /bin/cc to /bin/cc1, and tried to get the header files, but I am still not there yet. – phobic Feb 01 '15 at 22:59
  • Can you post a simple isolated example of Python failing to find something (that works on host, but fails in UML)? I can `strace` it on my side and try to fix. I don't think installation of some "psutil" (what is it?) should be done from inside UML (or that it would change anything). – Vi. Feb 01 '15 at 23:08
  • Just now solved the issue; I installed python-psutil using apt-get instead of python pip (a python package manager). Probably using pip did not work due to the virtual environment in travis.ci. The next problem occurred, which is similar, but I hope I will get it to work eventually. Thanks for the help. – phobic Feb 01 '15 at 23:16
  • Now I've experimented and noticed that "gcc" fails to work (fails to find `ld`) in this setup and I don't know why. Trying to figure out. – Vi. Feb 01 '15 at 23:21
  • 1
    Looks like setting corrent `PATH` (i.e. `export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`) fixed `gcc`. Maybe it would fix other programs as well. – Vi. Feb 01 '15 at 23:35
  • @phobic, So, has it worked? Are more adjustments needed? – Vi. Feb 08 '15 at 03:20
  • So, I solved the Python related problems. But I cannot seem to use FUSE: https://travis-ci.org/joe42/CloudFusion/jobs/50845662 – phobic Feb 15 '15 at 16:43
  • 1
    @phobic, It is telling you to load the module. Try loading it explicitly with `insmod`. See the example script in this answer; note the escaped backticks around `uname -r`. They are to load UML's module, not host kernel's one. You can also specify `init=/bin/bash` (not on Travis's side, on your localhost) and experiment inside UML more directly before deploying onto Travis. – Vi. Feb 16 '15 at 00:10
  • I tried insmod, which didn't work: https://travis-ci.org/joe42/CloudFusion/jobs/50873977 On my PC it works fine though. I don't really know where the problem is, as it seems to work in your case. – phobic Feb 16 '15 at 07:46
  • 1
    I see this error: `overflow in relocation type 11 val e15d0fc0; 'fuse' likely not compiled with -mcmodel=kernel`. Have you changed anything in UML parameters or things have changed on Travis's side? I'll try re-testing my case. Update: restared my build: https://travis-ci.org/vi/execfuse/builds/48371659 , it worked. Maybe `mem=2G`? – Vi. Feb 16 '15 at 11:56
  • @Vi. The error went away for me at `mem=256M` (first try of a different number). For future adventurers (needs a thorough cleanup, but proves the point): https://travis-ci.org/suffuse/go-suffuse/builds/69668142 – EECOLOR Jul 06 '15 at 01:12