aboutsummaryrefslogtreecommitdiffstats
path: root/tools/examples/createlinuxdom.py
blob: e183b422f8b6358d8ef74c56e256c26899c60033 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env python

#
# Example script for creating and building a new Linux guest OS for Xen.
# It takes an optional parameter that specifies offsets to be added to the
# ip address and root partition numbers, enabling multiple domains to be
# started from the one script.
#
# Edit as required...
#

import Xc, XenoUtil, string, sys, os, time, socket

# initialize a few variables that might come in handy
thishostname = socket.gethostname()
guestid = 0
if sys.argv >= 2:
    guestid = string.atoi(sys.argv[1])
    print "Offset to add to guest's IP etc : %d\n" % guestid
 
##### This section of the code establishes various settings to be used 
##### for this guest virtual machine

# STEP 1. Specify kernel image file. Can be gzip'ed.
image = "../../../install/boot/xenolinux.gz"

# STEP 2. How many megabytes of memory for the new domain?
memory_megabytes = 64

# STEP 3. A handy name for your new domain.
domain_name = "This is VM %d" % guestid

# STEP 4. Specify IP address(es), netmask and gateway for the new
# domain.  You need to configure IP addrs within the domain just as
# you do normally.  This is just to let Xen know about them so it can
# route packets appropriately. 

#ipaddr = ["111.222.333.444","222.333.444.555"]
ipaddr  = [XenoUtil.add_offset_to_ip(XenoUtil.get_current_ipaddr(),guestid)]
netmask = XenoUtil.get_current_ipmask()
gateway = XenoUtil.get_current_ipgw()
nfsserv = '169.254.1.0'  # You need to set this if you're using NFS root

# STEP 5. Identify any physcial partitions or virtual disks you want the
# domain to have access to, and what you want them accessible as
# e.g. vbds = [ ('phy:sda1','sda1', 'w'),
#	 ('phy:sda4','sda%d' % (3+guestid), 'r'), 
#	 ('vd:as73gd784dh','hda1','w') ]

vbds = [ ('phy:sda%d'%(7+guestid),'sda1','w' ), 
	 ('phy:sda6','sda6','r'),
	 ('phy:cdrom','hdd','r') ]

# STEP 6. Build the command line for the new domain. Edit as req'd.
# You only need the ip= line if you're NFS booting or the root file system
# doesn't set it later e.g. in ifcfg-eth0 or via DHCP
# You can use 'extrabit' to set the runlevel and custom environment
# variables used by custom rc scripts (e.g. DOMID=, usr= )

ipbit = "ip="+ipaddr[0]+":"+nfsserv+":"+gateway+":"+netmask+"::eth0:off"
rootbit = "root=/dev/sda1 ro"
#rootbit = "root=/dev/nfs nfsroot=/full/path/to/root/directory"
extrabit = "4 DOMID=%d usr=/dev/sda6" % guestid 
cmdline = ipbit +" "+ rootbit +" "+ extrabit

# STEP 7. Set according to whether you want the script to watch the domain 
# and auto-restart it should it die or exit.

auto_restart = False
#auto_restart = True


##### Print some debug info just incase things don't work out...
##### 

print "Domain image          : ", image
print "Domain memory         : ", memory_megabytes
print "Domain IP address(es) : ", ipaddr 
print "Domain block devices  : ", vbds
print 'Domain cmdline        : "%s"' % cmdline


##### Code beyond this point is actually used to manage the mechanics of
##### starting (and watching if necessary) guest virtual machines.

# Obtain an instance of the Xen control interface
xc = Xc.new()

# This function creates, builds and starts a domain, using the values
# in the global variables, set above.  It is used in the subsequent
# code for starting the new domain and rebooting it if appropriate.
def make_domain():
    """Create, build and start a domain.
    Returns: [int] the ID of the new domain.
    """

    # set up access to the global variables declared above
    global image, memory_megabytes, domain_name, ipaddr, netmask
    global vbds, cmdline, xc
    	
    if not os.path.isfile( image ):
        print "Image file '" + image + "' does not exist"
        sys.exit()

    id = xc.domain_create( mem_kb=memory_megabytes*1024, name=domain_name )
    print "Created new domain with id = " + str(id)
    if id <= 0:
        print "Error creating domain"
        sys.exit()

    ret = xc.linux_build( dom=id, image=image, cmdline=cmdline )
    if ret < 0:
        print "Error building Linux guest OS: "
        print "Return code from linux_build = " + str(ret)
        xc.domain_destroy ( dom=id )
        sys.exit()

    # setup the virtual block devices
    for ( uname, virt_name, rw ) in vbds:
	virt_dev = XenoUtil.blkdev_name_to_number( virt_name )

	segments = XenoUtil.lookup_disk_uname( uname )
	if not segments:
	    print "Error looking up %s\n" % uname
	    xc.domain_destroy ( dom=id )
	    sys.exit()

	if xc.vbd_create( dom=id, vbd=virt_dev, writeable= rw=='w' ):
	    print "Error creating VBD vbd=%d writeable=%d\n" % (virt_dev,rw)
	    xc.domain_destroy ( dom=id )
	    sys.exit()

	for (s_dev,s_start,s_len,s_type) in segments:
	    if xc.vbd_grow( dom=id,
			    vbd=virt_dev,
			    device=s_dev,
			    start_sector=s_start,
			    nr_sectors=s_len ):
		print "Error populating VBD vbd=%d\n" % virt_dev
		xc.domain_destroy ( dom=id )
		sys.exit()

    # setup virtual firewall rules for all aliases
    for ip in ipaddr:
	XenoUtil.setup_vfr_rules_for_vif( id, 0, ip )

    if xc.domain_start( dom=id ) < 0:
        print "Error starting domain"
        xc.domain_destroy ( dom=id )
        sys.exit()

    return id
# end of make_domain()



# The starting / monitoring of the domain actually happens here...

# start the domain and record its ID number
current_id = make_domain()

# if the auto_restart flag is set then keep polling to see if the domain is
# alive - restart if it is not by calling make_domain() again (it's necessary
# to update the id variable, since the new domain may have a new ID)

while auto_restart:
    time.sleep(1)
    if not xc.domain_getinfo(current_id):
        print "The virtual machine has terminated, restarting in a new domain"
        current_id = make_domain()