virt-preview for Fedora 12
[ovirt-node-image.git] / livecd-iso-to-iscsi
blobfd3934d2c48adcd520a4795f9e9b178a3b84a504
1 #!/usr/bin/python
2 # Convert a live CD iso into iscsi root bootable format
3 # iSCSI lun must be accessible via this script
4 # Copyright 2009 Red Hat, Inc.
5 # Written by Joey boggs <jboggs@redhat.com>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; version 2 of the License.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Library General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 from optparse import OptionParser
21 from tempfile import mkdtemp
22 import dbus
23 import dbus.glib
24 import sys
25 import os
26 import subprocess
27 import shutil
29 parser = OptionParser()
30 parser.add_option("--iso", dest="iso", help="LiveCD iso filename")
31 parser.add_option("--target", dest="target", help="iSCSI target ip address")
32 parser.add_option("--targetname", dest="targetname", help="iSCSI target lun")
33 parser.add_option("--targetport", dest="targetport", default="3260", help="iSCSI port number, defaults to 3260")
34 parser.add_option("--user", dest="user", help="Target username(optional)")
35 parser.add_option("--password", dest="password", help="Target password")
36 parser.add_option("--reverse_user", dest="reverse_user", help="Reverse CHAP username(optional)")
37 parser.add_option("--reverse_password", dest="reverse_password", help="Reverse CHAP password(optional)")
38 parser.add_option("--disk", dest="disk", help="iSCSI disk device name")
39 parser.add_option("--disk-label", dest="disk_label", default="ovirt-node-root", help="file system label")
41 (options, args) = parser.parse_args()
43 def fail(msg):
44 print(msg)
45 sys.exit(1)
47 if os.geteuid () != 0:
48 fail("You must run as root")
50 if options.iso is None:
51 fail("ERROR: iso file must be defined")
52 else:
53 options.iso = os.path.abspath(options.iso)
55 if options.target is None:
56 fail("ERROR: iscsi target must be defined")
58 if options.targetname is None:
59 fail("ERROR: iscsi targetname must be defined")
61 if len(options.disk_label.strip()) > 15:
62 fail("ERROR: disk label must be 14 characters or less")
64 try:
65 file = os.mkdir("tftpboot")
66 except OSError, e:
67 tftp_remove = raw_input("tftpboot directory exists, overwrite? (y/N)? ")
68 if tftp_remove.lower() == "y":
69 shutil.rmtree("tftpboot")
70 os.mkdir("tftpboot")
71 else:
72 print "Aborting"
73 sys.exit(1)
75 if options.disk is None:
76 print "Below are the detected disks, if the iscsi disk is not shown, please ensure you are logged into the correct target\n"
77 bus = dbus.SystemBus ()
78 hal_obj = bus.get_object ('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
79 hal = dbus.Interface (hal_obj, 'org.freedesktop.Hal.Manager')
80 udis = hal.FindDeviceByCapability ('storage')
81 dev_dict = {}
82 dev_count = 1
83 for udi in udis:
84 dev_obj = bus.get_object ('org.freedesktop.Hal', udi)
85 dev = dbus.Interface (dev_obj, 'org.freedesktop.Hal.Device')
86 dev_bus=dev.GetProperty ('storage.bus')
87 dev_name=dev.GetProperty ('block.device')
88 dev_size=dev.GetProperty ('storage.size')
89 dev_size=(dev_size/1024/1024)
90 basename=os.path.basename(udi)
91 if dev_bus == "scsi":
92 print "%s. %s %sM %s \n" % (dev_count,dev_name,dev_size,basename)
93 dev_dict[str(dev_count)] = dev_name
94 dev_count = dev_count + 1
95 print "Enter Q to Quit"
96 dev_choice = raw_input("Which device? ")
97 while not dev_dict.has_key(dev_choice):
98 if dev_choice.lower() == "q":
99 print "Aborting"
100 sys.exit(1)
101 else:
102 print "%s is an invalid choice" % dev_choice
103 dev_choice = raw_input("Which device? ")
104 options.disk = dev_dict[dev_choice]
106 cont = raw_input("Creating file system on %s, do you wish to continue (y/N) " % options.disk)
107 if cont.lower() != "y":
108 print "Aborting"
109 sys.exit(1)
111 isomount = mkdtemp()
112 isomount_ret = subprocess.call(["mount", "-o", "loop", options.iso, isomount])
113 if isomount_ret != 0:
114 fail("Error mounting %s" % options.iso)
116 kernel="%s/isolinux/vmlinuz0" % isomount
117 initrd="%s/isolinux/initrd0.img" % isomount
118 squashfs="%s/LiveOS/squashfs.img" % isomount
119 ext3fs="tftpboot/squashfs-root/LiveOS/ext3fs.img"
120 shutil.copy(kernel,"tftpboot")
121 shutil.copy(initrd,"tftpboot")
123 unsquash = subprocess.call(["unsquashfs", squashfs])
125 # workaround until bug is fixed with squashfs -d option
126 shutil.move("squashfs-root","tftpboot/squashfs-root")
128 print "Placing embedded file system on %s" % options.disk
129 dd_cmd="dd if=%s of=%s" % (ext3fs,options.disk)
130 copy_iscsi_ret = subprocess.call(dd_cmd, shell=True)
131 if copy_iscsi_ret != 0:
132 fail("Error copying to %s" % options.disk)
134 umount_ret = subprocess.call(["umount", isomount])
135 if umount_ret != 0:
136 fail("Error unmounting %s, continuing" % isomount)
137 else:
138 os.rmdir(isomount)
139 shutil.rmtree("tftpboot/squashfs-root")
141 pxe_template = """
143 # pxelinux configuration.
144 DEFAULT pxeboot
145 TIMEOUT 20
146 PROMPT 0
147 LABEL ovirt-node-iscsi
148 KERNEL /vmlinuz0
149 APPEND initrd=/initrd0.img ro root=LABEL=%(disk_label)s netroot=iscsi:%(user)s%(password)s@%(target)s::%(target_port)s::%(target_name)s ip=eth0:dhcp
150 ipappend 2
151 ONERROR LOCALBOOT 0
154 # insert empty values for unneeded variables in the pxe template
155 if not options.user is None:
156 options.user = options.user + ":"
157 else:
158 options.user = ""
160 if not options.password is None:
161 options.password = options.password + ":"
162 else:
163 options.password = ""
165 if not options.reverse_user is None:
166 options.reverse_user = options.reverse_user + ":"
167 else:
168 options.reverse_user = ""
170 if not options.reverse_password is None:
171 options.reverse_password = options.reverse_password + ":"
172 else:
173 options.reverse_password = ""
175 os.mkdir("tftpboot/pxelinux.cfg")
176 pxe_cfg = pxe_template % {
177 "disk_label": options.disk_label,
178 "target": options.target,
179 "target_port": options.targetport,
180 "target_name": options.targetname,
181 "user": options.user,
182 "password": options.password,
183 "reverse_user": options.reverse_user,
184 "reverse_password": options.reverse_password
187 pxe_conf = open("tftpboot/pxelinux.cfg/default", 'w')
188 pxe_conf.write(pxe_cfg)
189 pxe_conf.close()
191 if os.path.exists("/usr/share/syslinux/pxelinux.0"):
192 shutil.copy("/usr/share/syslinux/pxelinux.0","tftpboot")
193 elif os.path.exists("/usr/lib/syslinux/pxelinux.0"):
194 shutil.copy("/usr/lib/syslinux/pxelinux.0","tftpboot")
195 else:
196 print "Warning: You need to add pxelinux.0 to tftpboot/ subdirectory"
198 print "Your iscsiroot has been setup on %s" % options.disk
199 print ""
200 print "Copy the tftpboot/ subdirectory to your tftpserver root directory"
201 print "Set up your DHCP, TFTP and PXE server to serve /tftpboot/.../pxeboot.0"