Fedora
Dec 22, 2011
xen: Running a Fedora 14 DomU under a Fedora 16 Dom0
xen is a server virtualization environment. These instructions will get you started, including using boxgrinder to create appliance images.
Starting with Fedora 16, you can again use Fedora as a Dom0 environment for running virtual machines under xen.
Install xen
It's fairly simple to get Fedora 16 set up as the Dom0. Just install Fedora 16 as usual. After the installation is complete and you have rebooted, install xen:
# yum -y install xen
This will install a large number of package dependencies.
After installing xen, I disable selinux. While it's probably possible to get selinux running in the Dom0, for my testing purposes I've not gone through the hassle.
The next step is to configure Fedora 16 to automatically boot into xen. To do that, you must tell grub2 to use xen as the default:
# grub2-set-default "Xen 4.1"
Configure network bridging
Next, you'll want to enable network bridging. This will allow all of your DomU's to act as if they're on the same network as your Dom0. To do so, edit /etc/sysconfig/network-scripts/ifcfg-virbr0 to contain:
DEVICE=virbr0 TYPE=bridge ONBOOT=yes USERCTL=no BOOTPROTO=dhcp NM_CONTROLLED=no
And set your primary ethernet interface to use the bridge. For me, the interface is p49p1, so in /etc/sysconfig/network-scripts/ifcfg-p49p1 I have:
DEVICE=p49p1 HWADDR="01:23:45:67:89:ab" # actual MAC address here ONBOOT=yes TYPE=Ethernet USERCTL=no BOOTPROTO=none BRIDGE=virbr0 NM_CONTROLLED=no
After rebooting, I see this output from ifconfig (with various values hidden):
lo link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
p49p1 Link encap:Ethernet HWaddr 01:23:45:67:89:ab
inet6 addr: xxxx::yyy:zzzz:aaaa:bbb/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:201 errors:0 dropped:0 overruns:0 frame:0
TX packets:140 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:25946 (25.3 KiB) TX bytes:15704 (15.3 KiB)
Interrupt:16 Memory:fbce0000-fbd00000
virbr0 Link encap:Ethernet HWaddr 01:23:45:67:89:ab
inet addr:10.10.10.2 Bcast:10.10.10.255 Mask:255.255.255.0
inet6 addr: xxxx::yyy:zzzz:aaaa:bbb/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:197 errors:0 dropped:0 overruns:0 frame:0
TX packets:148 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:21884 (21.3 KiB) TX bytes:16488 (16.1 KiB)
Build the Fedora 14 appliance
The next step is to build and install a Fedora 14 appliance. For this, I use boxgrinder:
# yum -y install rubygem-boxgrinder-build
Then, create a Fedora 14 appliance configuration file named f14.appl:
name: f14-jeos
summary: Just Enough Operating System based on Fedora 14
os:
name: fedora
version: 14
hardware:
partitions:
"/":
size: 2
packages:
- @core
Run boxgrinder to create the appliance:
# boxgrinder-build f14.appl
boxgrinder will download all of the Fedora packages from the installation mirrors and create a Fedora 14 appliance, ready to install and run.
Install virt-install, which will be used to launch the appliance:
# yum -y install python-virtinst
Launch the appliance
Then run virt-install to launch the appliance:
# virt-install --graphics=none --name=f14 --ram=768 --import \ --disk=build/appliances/i686/fedora/14/f14-jeos/1.0/fedora-plugin/f14-jeos-sda.raw \ --network=bridge:virbr0
I'm installing with --graphics=none, meaning that only a text mode console is supported (no VNC). You should now be connected to the DomU's console. From within the Fedora 14 DomU you will be able to find your appliance's IP address and be able to connect to it via ssh.
Adding additional storage
For my Fedora 14 instance, I wanted to add some additional storage. The easiest way is to create a file in the Dom0 storage, then mount that in the DomU. In the Dom0, create the file to be used as storage. In my case, it's 65GB of space:
# dd if=/dev/zero of=build-f14-repository bs=1G count=65
Still in Dom0, attach the block device to the DomU:
# xm block-attach f14 file:$PWD/build-f14-repository xvdb w
Then switch to the DomU and format the device:
# mkfs.ext4 /dev/xvdb
Finally, mount the device in the Fedora 14 DomU:
# mount /dev/xvdb /mnt # df -h Filesystem Size Used Avail Use% Mounted on rootfs 1.9G 604M 1.3G 32% / udev 362M 116K 362M 1% /dev tmpfs 374M 0 374M 0% /dev/shm /dev/xvda1 1.9G 604M 1.3G 32% / udev 362M 116K 362M 1% /dev /dev/xvdb 64G 180M 61G 1% /mnt
We've added 61GB of usable space on /mnt.
Nov 04, 2009
User input during a Fedora Kickstart
Kickstart is Fedora's automated installation facility. Sometimes we need to get user input on the computer being built. Read on for how to do that.
In order to reliably build our servers, we use kickstart and PXE to give us a simple, repeatable process. During this build process, we need user input to decide exactly which configuration to apply to the system being built.
In order to do that, we run a Python script in the ks.cfg %pre section that uses the snack library to get information from the user. Snack is the (poorly documented) UI toolkit that comes with kickstart/anaconda. Here's how you use it in %pre.
First, you need a %pre section that runs the python interpreter. To do that, start the section with:
%pre --interpreter /usr/bin/python
Next, you need to realize that the kickstart screen you usually see runs on tty3. But the snack UI will show up on tty1. So we use a little routine to switch tty's:
def set_tty(n):
f = open('/dev/tty%d' % n, 'a')
os.dup2(f.fileno(), sys.stdin.fileno())
os.dup2(f.fileno(), sys.stdout.fileno())
os.dup2(f.fileno(), sys.stderr.fileno())
Next comes the function that actually calls snack to get the user input. Don't worry about the host_config parameter, instead focus on how snack is used. This code build a dialog box with a listbox and an OK button:
def get_user_input(host_config, default=None):
# get the hostname, from it the other params are computed
# return the hostname and everything that's derived from it
# which for now is just the disk layout scheme
from snack import SnackScreen, Listbox, Grid, Label, Entry, Button, GridForm
def host_list():
def hosts():
return sorted(host_config.keys())
lb = Listbox(height=len(host_config), returnExit=True)
for host in hosts():
lb.append(host, host)
if default in host_config.keys():
lb.setCurrent(default)
return lb
screen = SnackScreen()
form = GridForm(screen, 'Select host to configure', 1, 2)
form.add(host_list(), 0, 0, (0, 0, 0, 1))
form.add(Button('OK'), 0, 1)
# now run the form
result = form.runOnce()
screen.finish()
hostname = form.childList[0].current()
return {'layout': host_config[hostname],
'hostname': hostname,
}
Finally, put it all together:
set_tty(1) # change to tty1, we're called by kickstart with stdout as tty3
user_args = get_user_input(host_config, args.args.get('tb-host'))
set_tty(3) # restore
If you ever need to find information on snack, it helps to know that it's a wrapper for newt. So you can Google on "snack newt python" to get some useful answers. But be warned that there's not much there and you might have to look through the source code to snack.

