TurnKey Linux Virtual Appliance Library
Liraz Siri's picture

Usage scenarios

It shouldn't be difficult to build appliance images that can support PXE boot, but there are a lot of other features competing for our development time so when we get to that is a matter of priorities.

Can you describe your usage scenario? (That would be helpful)

s_digicom's picture

re: Usage scenario

I have 5-6 PC's - P III, 256 MB RAM, 10GB HDD, 10/100 LAN, no fdd, no cd, no usb boot - which I want to use for LAMP servers - 1 for home, 1 for work and etc. LAMP appliance is ideal for what I want. On CentOS 5.2 I have set a fully functional PXE enviroment and booting start normally, but stops when setup brings up LAN interface. Here is default file for PXE
default LAMP
timeout 50
prompt 0
ONERROR reboot

LABEL LAMP
kernel images/TKLamp/casper/vmlinuz
append boot=casper initrd=images/TKLamp/casper/initrd.gz ramdisk_size=196000 ip=dhcp showmounts debug toram=196 netboot=nfs nfsroot=172.16.10.1:/home/OSImages/TKLamp/casper --

In log I can see that after interface is up, a new dhcp request is served, but after this moment there is no any other communication between PXE server and LAMP. I am not so experienced in Linux and it is quite possible to exists other simple solutions, but I want to use Turnkey LAMP, because your rails appliance is a great tool for me.
Liraz Siri's picture

A few resources...

We've never tested PXE booting our appliances, so you are in a highly experimental area and we have limited ability to help you (e.g., we don't even have a test environment setup for PXE just yet). However, before you give up, keep in mind that Ubuntu Live CDs have been made to boot via PXE before so it should be possible to do what you want:

https://wiki.ubuntu.com/LiveCDNetboot

We're very interested to hear more about your experience with this, especially if you manage to get it to work...

Good luck!

Liraz Siri's picture

Try disabling load to ram

Try removing toram=196 boot option...
s_digicom's picture

Confirmation: successfull installation

Dear Sir,
With this, I want to confirm that with your help, the LAMP appliance was successfully installed via PXE boot sequence.
I already use the resource, that you propose, but my errors was:
1. In configuration of PXE I used by mistake one more time /casper - which was already set from boot directive.
2. Removing toram= directive do the final job
Thank you very much.
Liraz Siri's picture

Thanks for sharing...

You're welcome, and thanks for sharing your experience!

One last thing, could you please post the exact configuration that worked so that other users have a known-good configuration to work with as reference?

s_digicom's picture

How to boot LAMP (any?) Turnkey appliance via PXE

I'll try to share my experience on how to boot/install the TurnKey LAMP appliance via PXE.

This is the first time I try to write something like this, plus I'm not a native English speaker, so please accept my apologies for any mistakes I make. I welcome any assistance to improve this material.

It is necessary to ensure working PXE and NFS servers. There is a lot of information online clarifying how can this be done.

Note that the PXE server and NFS server can actually be on different machines, but it's important they are both connected to the same network segment.

Create on your NFS server a shared folder. Ensure that the properties of this share are:

(ro,async,no_subtree_check,no_root_squash)
Extract the contents of .iso file in this share and check again that you have the following subdirectories:
casper/
isolinux/
Copy from the casper/ the vmlinuz and initrd.gz files into /tftpboot core directory.

If you have other systems you are booting with PXE, you can use an additional directory. For example:

/tftpboot/OS_Images/LAMP
For this to work you'll also need to set the correct paths in your configuration file:
kernel=OS_Images/LAMP/vmlinuz initrd=OS_Images/LAMP/initrd.gz
Here is the minimal configuration in /tftpboot/pxelinux.cfg/default file, which ensure correct environment for booting(installing) appliance:
default LAMP
prompt 0

LABEL LAMP
        kernel vmlinuz
        append boot=casper initrd=initrd.gz ip=dhcp showmounts debug netboot=nfs nfsroot=xxx.xxx.xxx.xxx:/path/to/your/NFS/share --

Replace xxx.xxx.xxx.xxx with the real IP address of your NFS server and /path/to/your/NFS/share with your real shared folder.

With this configuration you will have live environment and you can use configuration console to take additional actions, like install.

If instead of a live environment you want to install, add the di-live noconfconsole
after boot options after the debug directive.

First, I used this configuration to install 2 LAMP servers, but now I find it very useful for live Rails development because it doesn't need to touch anything else on my laptop.

Once again I want to thank liraz for his advice and encouragement.

Liraz Siri's picture

This is great!

Thank you so much, this is very helpful!

I edited your post a bit to improve readability and we'll probably use your material later to create a new node in our community documentation section.

We'll also be looking into seeing if there is any way we can make setting up PXE boot of our appliances any easier from our end.

Guest's picture

Is this still valid?

I've spent a few days messing with pxe and ipxe, with variying success. 

I can boot clonezilla-live from ipxe servering kernel, initrd and squashfs over http, but I'm getting nowhere with Turnkey Linux.

Even following the instructions here, I'm unable to boot it from nfs. So before I keep digging, am I digging in the right place?

If you want to make it easier to PXE boot appliances, can I suggest hosting a ipxe menu script listing all available appliances and host the relevant kernel, initrd ans squashfs files over http? Then installing could be as easy as point ipxe to an url at turnkeylinux.org and choose from the menu. To use ipxe one can either reflash existing vendor pxe rom, chainload it from pxelinux.0 or from grub and it opens up vast possibilities.

Jeremy Davis's picture

Cool idea!

I love your idea. I'm not sure when we'll get a chance to implement it but I think it's a cool idea.

WRT your issues installing TurnKey via PXE TBH I haven't played with PXE for a long time, so I can't give you any advice or guidance. This thread is really dated (2009!) so I'm sure stuff has changed.

FWIW TurnKey v14.x is based on Debian Jessie (8). We (still) use our own custom installer that was originally forked from Ubuntu but has been tweaked to support Debian Jessie (and previously for Wheezy and Squeeze).

Bottom line is that in theory I'm sure you should be able to boot TurnKey from PXE but I have no idea on the details... Not much help really...

Guest's picture

Well, at least i know I

Well, at least i know I should probably be digging more around Jessie. Thanks! Is there any docs on how to make changes to the kernel or initrd stuff of the turnkey core in tkldev? I've only browsed the docs a little today, but coudn't find any spesific refrences to those bits.

Jessie live cd boots okay, so proably there is some difference in the initrd stuff, I just don't know enough about how it works (yet?). I'll decomress the two initrd images and see if I can spot any obvious differences.

For refrence this boots the debian-live-8.4.0-i386-standard.iso with extracted kernel, initrd and squashfs files over http:
#!ipxe
kernel http://10.10.0.100/boot/jessie-live/vmlinuz1
initrd http://10.10.0.100/boot/jessie-live/initrd1.img
imgargs vmlinuz1 boot=live config hooks=filesystem username=live noeject fetch=http://10.10.0.100/boot/jessie-live/filesystem.squashfs
boot || shell

 

Guest's picture

After some more digging I've

After some more digging I've come to the conclusion that NFS should have worked with the same setup as listed above.

The difference between the current Jessie live cd and TKL is that uses boot=live instead of boot=casper to boot the live sytem in the squashfs image. So when/if TKL moves from casper to live it will automagically support http booting as well. Casper only support NFS and CIFS

I need (or want) to launch the installer on a machine i only have vnc access to a running ubuntu installation, and i can get NFS traffic thru the firewalls so I need to hack in a wget line into initrd/scripts/casper to fetch the squashfs. And add ipxe to the existing grub menu. Sadly it won't be pretty.

Jeremy Davis's picture

Thanks for the info

We forked Ubuntu's live code when we moved to a Debian base back in 2012 as Debian didn't support live boot at that point. Since then we have just updated our forked code so it works with Debian stable (Squeeze, Wheezy and now Jessie).

However, now that Debian supports live boot, we would really like to rebase on the Debian code. It's just one of those jobs though that keeps getting pushed back in favour of other higher priority items.

Your info adds weight to making this item higher priority but TBH I still don't know when we'll get to it...

In the meantime, please feel free to share your code as no doubt other users will find it handy. Ideally it should go in our docs...

Also WRT to our docs, they are sadly missing lots of detail. We have plans to improve our docs but it's work in progress...

Guest's picture

after poking around and

after poking around and around I ended up replacing the # Scan local devices for the image section in initrd/scripts/casper with

        ifconfig eth0 up
        udhcpc -i eth0
        livefs_root=/tmp/root
        mkdir -p ${livefs_root}
        mount -t tmpfs -o size=196m tmpfs ${livefs_root}
        mkdir -p ${livefs_root}/casper
        wget http://x.x.x.x/boot/tklcore/10root.squashfs -O ${livefs_root}/casper/root.squashfs

and rest of the initrd image unchanged picked up the squashfs image and booted the installer, the following ipxe script downloaded kernel, initrd and squashfs all over http

#!ipxe
kernel http://x.x.x.x/boot/tklcore/vmlinuz
initrd http://x.x.x.x/boot/tklcore/initrd.gz
imgargs vmlinuz boot=casper di-live single noinithooks
​boot || shell

Its probably doable to add support for the fetch=http:///.... notation in the do_netmount code, but I didn't quite get to grips with it, and while dirty this did the trick for my one off use case. To modify an existing initrd.gz image i found this helpful http://backreference.org/2010/07/04/modifying-initrdinitramfs-files/

 

Guest's picture

looks like ip configuration may be broken

spamfilter took the lengthy reply - http://pastebin.com/fGc431fG

To me it seems like the netboot code is broken, passing parameter ip=dhcp or ip=[CLIENT_IP]:[SERVER_IP]:[GATEWAY_IP]:[NETMASK]:[HOSTNAME]:[DEVICE]:[AUTOCONF] as exampled by ip=10.0.0.1::10.0.0.254:255.255.255.0::eth0 or ip=:::::eth0:dhcp does not allow the configure_network() function to establish networking in the exisitng code. After realising it was the network config that was throwing me off I've put together a patch that replaces configure_network() with a simple ipconfig statement and adds support for netboot=http fetch=http://..../root.squashfs. There is a limitation in the initramfs where there is not dns resolver so url and nfsroot has to be IP address only. iPXE can work around it by letting iPXE resolve dns names and pass IP to kernel.

As far as I can tell it works with both nfs and http, dhcp and static ip.

casper-http-simple.patch
 
--- initrd/scripts/casper    2016-05-26 11:11:48.505135324 +0200
+++ initrd-http/scripts/casper    2016-05-26 11:20:21.969120753 +0200
@@ -32,6 +32,10 @@
 parse_cmdline() {
     for x in $(cat /proc/cmdline); do
         case $x in
+            netboot=*)
+                export NETBOOT="${x#netboot=}";;
+            fetch=*)
+                export URL="${x#fetch=}";;
             showmounts|show-cow)
                 export SHOWMOUNTS='Yes' ;;
             persistent)
@@ -191,26 +195,48 @@
     /sbin/udevadm trigger
     /sbin/udevadm settle
 
-    ipconfig ${DEVICE} /tmp/net-${DEVICE}.conf | tee /netboot.config
+    #this seems broken.
+    #ipconfig ${DEVICE} /tmp/net-${DEVICE}.conf | tee /netboot.config
+    #replace with very basic netconfig based on ip= parameter
+    case ${STATICIP} in
+        dhcp)
+            ipconfig :::::eth0:dhcp
+            ;;
+        *)
+        ipconfig ${STATICIP}
+        ;;
+    esac
 
     if [ "${NFSROOT}" = "auto" ]; then
         NFSROOT=${ROOTSERVER}:${ROOTPATH}
     fi
 
-    [ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}"
-
-    if [ "${NETBOOT}" != "nfs" ] && do_cifsmount ; then
-        rc=0
-    elif do_nfsmount ; then
-        NETBOOT="nfs"
-        export NETBOOT
-        rc=0
-    fi
+    case ${NETBOOT} in
+        nfs)
+            [ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}"
+            if do_nfsmount ; then rc=0; fi     ;;
+        cifs)
+            [ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}"
+            if do_cifsmount ; then rc=0; fi ;;
+        http|httpfs)
+            [ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${URL}"
+            if do_httpmount ; then rc=0; fi ;;
+    esac
 
     [ "$quiet" != "y" ] && log_end_msg
     return ${rc}
 }
 
+do_httpmount() {
+        rc=1
+        livefs_root=/tmp/root
+        mkdir -p ${livefs_root}
+        mount -t tmpfs -o size=`wget ${URL} --spider --server-response -O - 2>&1 | sed -ne '/Content-Length/{s/.*: //;p}'` tmpfs ${livefs_root}
+        mkdir -p ${livefs_root}/casper
+        if wget ${URL} -O ${livefs_root}/casper/root.squashfs; then rc=0; fi
+        return ${rc}
+}
+
 do_nfsmount() {
     rc=1
     modprobe "${MP_QUIET}" nfs
patch-initrd-from-iso.sh (asume .iso and .patch is in pwd to start with)
 
export TKL=turnkey-core-14.1-jessie-amd64
rm -rf ~/${TKL}
mount -o loop ${TKL}.iso /mnt
mkdir ~/${TKL}
cp casper-http-simple.patch ~/${TKL}
cd ~/${TKL}
cp -r /mnt/casper .
umount /mnt
mkdir -p casper/initrd
cd casper/initrd
gunzip -c ../initrd.gz | cpio -i
patch -p1 < ~/${TKL}/casper-http-simple.patch
find . | cpio -H newc -o | gzip -9 > ../initrd.gz
cd ..
rm -r initrd
tkl.ipxe
 
#!ipxe
set server x.x.x.x
set path boot/tkl
#nslookup serverip ${server}
#set server ${serverip}
dhcp
kernel http://${server}/${path}/vmlinuz
initrd http://${server}/${path}/initrd.gz
imgargs vmlinuz boot=casper di-live single noinithooks ip=dhcp netboot=http fetch=http://${server}/${path}/10root.squashfs
boot || shell
 
menu entry for pxelinux.0 to chainload iPXE
 
label iPXE-TKL
        menu label iPXE ^Turnkey Linux
        kernel ipxe.krn dhcp && chain http://x.x.x.x/boot/tkl.ipxe || shell
 
menuentry "iPXE Turnkey Linux" for grub
 
{
linux16 /ipxe.lkrn
initrd16 /tkl.ipxe
​}
bjorn's picture

Patch for http based booting

There are two parts to making the move away from tftp to http. (Might still need tftp to boot iPXE, but can be chainloaded by grub or burned into existing vendor option rom)

Use iPXE to load the kernel and initrd image over http, and secondly to fetch the squashfs using http. The latter requires changes to initrd.gz image. Required changes are shown in the patch below. This includes a change to override the current casper scripts configure_network() to accept ip= as a parameter to the kernel. Examples follows:

  • ip=dhcp
  • ip=[CLIENT_IP]:[SERVER_IP]:[GATEWAY_IP]:[NETMASK]:[HOSTNAME]:[DEVICE]:[AUTOCONF]
  • ip=10.0.0.1::10.0.0.254:255.255.255.0::eth0
  • ip=:::::eth1:dhcp

The patch also describe changes to do_netmount() and parse_cmdline() needed to handle NFS, CIFS or the new HTTP booting, and a do_httpmount() to handle the case of HTTP. The casper initrd image does not have a working DNS resolver so NFSROOT= or fetch= have to use IP addresses, iPXE can work around this by resolving the hostname and passing the IP address, but it will not work with virtual http hosting based on hostname.

I "needed" to do this in order to install turnkey linux on a VPS server where I only had root access to running linux and VNC access to the console (no access to dhcp). Adding iPXE to grub and booting into the installer via static ip and http was my best option. If lacking VNC access to the console adding a preseed file to the installer and using grub-reboot might let you replace a headless running linux server with Turnkey.

casper-http-simple.patch
--- initrd/scripts/casper	2016-05-26 11:11:48.505135324 +0200
+++ initrd-patched/scripts/casper	2016-05-31 21:31:30.266314223 +0200
@@ -32,6 +32,10 @@
 parse_cmdline() {
     for x in $(cat /proc/cmdline); do
         case $x in
+            netboot=*)
+                export NETBOOT="${x#netboot=}";;
+            fetch=*)
+                export URL="${x#fetch=}";;
             showmounts|show-cow)
                 export SHOWMOUNTS='Yes' ;;
             persistent)
@@ -191,26 +195,47 @@
     /sbin/udevadm trigger
     /sbin/udevadm settle
 
-    ipconfig ${DEVICE} /tmp/net-${DEVICE}.conf | tee /netboot.config
+	#this seems broken.
+    #ipconfig ${DEVICE} /tmp/net-${DEVICE}.conf | tee /netboot.config
+	#replace with very basic netconfig based on ip= parameter
+	case ${STATICIP} in 
+		dhcp)
+			ipconfig :::::eth0:dhcp
+			;;
+		*)
+			ipconfig ${STATICIP}
+			;;
+	esac
 
     if [ "${NFSROOT}" = "auto" ]; then
         NFSROOT=${ROOTSERVER}:${ROOTPATH}
     fi
 
-    [ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}"
-
-    if [ "${NETBOOT}" != "nfs" ] && do_cifsmount ; then
-        rc=0
-    elif do_nfsmount ; then
-        NETBOOT="nfs"
-        export NETBOOT
-        rc=0
-    fi
+	case ${NETBOOT} in 
+		nfs)
+			[ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}"
+			if do_nfsmount ; then rc=0; fi 	;;
+		cifs)
+			[ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}"
+			if do_cifsmount ; then rc=0; fi ;;
+		http|httpfs)
+			[ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${URL}"
+			if do_httpmount ; then rc=0; fi ;;
+	esac
 
     [ "$quiet" != "y" ] && log_end_msg
     return ${rc}
 }
 
+do_httpmount() {
+		rc=1
+		mkdir -p ${mountpoint}
+		mount -t tmpfs -o size=`wget ${URL} --spider --server-response -O - 2>&1 | sed -ne '/Content-Length/{s/.*: //;p}'` tmpfs ${mountpoint}
+		mkdir -p ${mountpoint}/casper
+        if wget ${URL} -O ${mountpoint}/casper/root.squashfs; then rc=0; fi
+		return ${rc}
+}
+
 do_nfsmount() {
     rc=1
     modprobe "${MP_QUIET}" nfs
boot.ipxe
#!ipxe
set server x.x.x.x
set path turnkey-core-14.1-jessie-amd64
#nslookup serverip ${server}
#set server ${serverip}
dhcp
kernel http://${server}/${path}/vmlinuz
initrd http://${server}/${path}/initrd.gz
imgargs vmlinuz boot=casper di-live single noinithooks ip=dhcp netboot=http fetch=http://${server}/${path}/10root.squashfs
boot || shell
pxelinux.cfg menu entry
label iPXE-TKL
        menu label iPXE ^Turnkey Linux
        kernel ipxe.krn dhcp && chain http://x.x.x.x/boot.ipxe || shell
grub2 menu entry (/etc/grub.d/99ipxe)
menuentry "iPXE" {
linux16 /ipxe.lkrn
initrd16 /boot.ipxe
}
patch-tkl-iso.sh

Sample shell script to extract kernel, initrd.gz and 10root.squashfs from a turnkey .iso file, and patch the initrd.gz image. Asumes .iso and .patch file is in the current working directory when run. Feel free to change according to taste.

(
export TKL=turnkey-core-14.1-jessie-amd64
rm -rf ./${TKL}
mkdir -p ./${TKL}.tmp.iso
mount -o loop ${TKL}.iso ${TKL}.tmp.iso
mkdir ./${TKL}
cd ./${TKL}
cp -r ../${TKL}.tmp.iso/casper/* .
umount ../${TKL}.tmp.iso
rm -r ../${TKL}.tmp.iso
mkdir -p initrd
cd initrd
gunzip -c ../initrd.gz | cpio -i
pwd
patch -p1 < ../../casper-http-simple.patch
find . | cpio -H newc -o | gzip -9 > ../initrd.gz
cd ..
rm -r initrd 
)

Previous post you've edited in from the pastebin contained the wrong patch, and some minor changes, as well as adding formatting to make the various file boundries clearer. Feel free to remove the chitchat and move this to the top after your reply Tue, 2016/05/17 - 10:59 . Cheers.

Jeremy Davis's picture

Awesome. Thanks tons for posting

I'm sure that others will find your info really useful!

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account, used to display your avatar.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <p> <span> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td> <em> <b> <u> <i> <strong> <font> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <strike> <caption>

More information about formatting options

Leave this field empty. It's part of a security mechanism.
(Dear spammers: moderators are notified of all new posts. Spam is deleted immediately)