New location for GRUB2 config on UEFI (#851220)
[livecd.git] / tools / mkbiarch.py
blob5178785d907468d4da31433f710aebbbc4abe803
1 #!/usr/bin/python
2 import os
3 import sys
5 import shutil
6 import parted
7 import subprocess
8 import optparse
9 import tempfile
10 import re
13 def main():
16 def usage():
17 usage = 'usage: mkbiarch.py <x86 Live ISO File> <x64 Live ISO File> <Target Multi Arch Image File>'
18 print >> sys.stdout, usage
21 def mount(src, dst, options=None):
22 if os.path.exists(src):
23 if not os.path.exists(dst):
24 os.makedir(dst)
25 if options is None:
26 args = ("/bin/mount", src, dst)
27 else:
28 args = ("/bin/mount", options, src, dst)
29 rc = subprocess.call(args)
30 return rc
31 return
34 def umount(src):
35 if os.path.exists(src):
36 args = ("/bin/umount", src)
37 rc = subprocess.call(args)
38 return rc
39 return
42 def copy(src, dst):
43 if os.path.exists(src):
44 if not os.path.exists(dst):
45 if not os.path.isfile(src):
46 mkdir(dst)
47 shutil.copy(src, dst)
50 def move(src, dst):
51 if os.path.exists(src):
52 shutil.move(src, dst)
54 def mkdir(dir=None):
55 if dir is None:
56 tmp = tempfile.mkdtemp()
57 return tmp
58 else:
59 args = ("/bin/mkdir", "-p", dir)
60 rc = subprocess.call(args)
63 def losetup(src, dst, offset=None):
64 if os.path.exists(src):
65 if os.path.exists(dst):
66 if offset is None:
67 args = ("/sbin/losetup", src, dst)
68 else:
69 args = ("/sbin/losetup", "-o", str(offset), src, dst)
70 rc = subprocess.call(args)
71 return rc
73 def lounset(device):
74 args = ("/sbin/losetup", "-d", device)
75 rc = subprocess.call(args)
77 def null():
78 fd = open(os.devnull, 'w')
79 return fd
81 def dd(file, target):
82 args = ("/bin/dd", "if=%s"%file, "of=%s"%target)
83 rc = subprocess.call(args)
85 def lo():
86 args = ("/sbin/losetup", "--find")
87 rc = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0].rstrip()
88 return rc
90 def lodev(file):
91 args = ("/sbin/losetup", "-j", file)
92 rc = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0].split(":")
93 return rc[0]
96 def mkimage(bs, count):
97 tmp = tempfile.mkstemp()
98 image = tmp[1]
99 args = ("/bin/dd", "if=/dev/zero",
100 "of=%s"%image, "bs=%s"%bs,
101 "count=%s"%count)
102 rc = subprocess.call(args)
103 return image
106 def size(ent):
107 if os.path.exists(ent):
108 return os.stat(ent).st_size
110 def bs(size):
111 return size / 2048
113 def partition(device):
114 dev = parted.Device(path=device)
115 disk = parted.freshDisk(dev, 'msdos')
116 constraint = parted.Constraint(device=dev)
118 new_geom = parted.Geometry(device=dev,
119 start=1,
120 end=(constraint.maxSize - 1))
121 filesystem = parted.FileSystem(type="ext2",
122 geometry=new_geom)
123 partition = parted.Partition(disk=disk,
124 fs=filesystem,
125 type=parted.PARTITION_NORMAL,
126 geometry=new_geom)
127 constraint = parted.Constraint(exactGeom=new_geom)
128 partition.setFlag(parted.PARTITION_BOOT)
129 disk.addPartition(partition=partition,
130 constraint=constraint)
132 disk.commit()
134 def format(partition):
135 args = ("/sbin/mke2fs", "-j", partition)
136 rc = subprocess.call(args)
138 def mbr(target):
139 mbr = "/usr/share/syslinux/mbr.bin"
140 dd(mbr, target)
142 def getuuid(device):
143 args = ("/sbin/blkid", "-s", "UUID", "-o", "value", device)
144 rc = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0].rstrip()
145 return rc
147 def syslinux(multitmp, config, **args):
148 arg = ("/sbin/extlinux", "--install", multitmp + "/extlinux/")
149 rc = subprocess.call(arg)
151 content = """
152 default vesamenu.c32
153 timeout 100
155 menu background splash.jpg
156 menu title Welcome to Fedora 13
157 menu color border 0 #ffffffff #00000000
158 menu color sel 7 #ffffffff #ff000000
159 menu color title 0 #ffffffff #00000000
160 menu color tabmsg 0 #ffffffff #00000000
161 menu color unsel 0 #ffffffff #00000000
162 menu color hotsel 0 #ff000000 #ffffffff
163 menu color hotkey 7 #ffffffff #ff000000
164 menu color timeout_msg 0 #ffffffff #00000000
165 menu color timeout 0 #ffffffff #00000000
166 menu color cmdline 0 #ffffffff #00000000
167 menu hidden
168 menu hiddenrow 5
170 label Fedora-13-x86
171 menu label Fedora-13-x86
172 kernel vmlinuz0
173 append initrd=initrd0.img root=UUID=%(uuid)s rootfstype=auto ro live_dir=/x86/LiveOS liveimg
175 label Fedora-13-x64
176 menu label Fedora-13-x64
177 kernel vmlinuz1
178 append initrd=initrd1.img root=UUID=%(uuid)s rootfstype=auto ro live_dir=/x64/LiveOS liveimg
179 """ % args
180 fd = open(config, 'w')
181 fd.write(content)
182 fd.close()
184 def verify():
185 # use md5 module to verify image files
186 pass
188 def setup(x86, x64, multi):
190 sz = size(x86) + size(x64)
191 count = bs(sz)
192 blsz = str(2048)
194 count = count + 102400
196 multi = mkimage(blsz, count)
197 losetup(lo(), multi)
199 mbr(lodev(multi))
200 partition(lodev(multi))
202 lounset(lodev(multi))
204 losetup(lo(), multi, offset=512)
205 format(lodev(multi))
207 multitmp = mkdir()
208 mount(lodev(multi), multitmp)
210 losetup(lo(), x86)
211 losetup(lo(), x64)
213 x86tmp = mkdir()
214 x64tmp = mkdir()
216 mount(lodev(x86), x86tmp)
217 mount(lodev(x64), x64tmp)
220 dirs = ("/extlinux/", "/x86/", "/x64/")
221 for dir in dirs:
222 mkdir(multitmp + dir)
223 dirs = ("/x86/", "/x64/")
224 for dir in dirs:
225 mkdir(multitmp + dir + "/LiveOS/")
227 intermediate = tempfile.mkdtemp() # loopdev performance is slow
228 # copy to here first then back
229 # to multitmp + dir which is looback also
231 imgs = ("squashfs.img", "osmin.img")
232 for img in imgs:
233 copy(x86tmp + "/LiveOS/" + img, intermediate)
234 copy(intermediate + "/" + img, multitmp + "/x86/LiveOS/")
235 for img in imgs:
236 copy(x64tmp + "/LiveOS/" + img, intermediate)
237 copy(intermediate + "/" + img, multitmp + "/x64/LiveOS/")
239 for file in os.listdir(x86tmp + "/isolinux/"):
240 copy(x86tmp + "/isolinux/" + file, multitmp + "/extlinux/")
242 copy(x64tmp + "/isolinux/vmlinuz0", multitmp + "/extlinux/vmlinuz1")
243 copy(x64tmp + "/isolinux/initrd0.img", multitmp + "/extlinux/initrd1.img")
247 uuid = getuuid(lodev(multi))
250 config = (multitmp + "/extlinux/extlinux.conf")
251 syslinux(multitmp,
252 config,
253 uuid=uuid)
257 umount(x86tmp)
258 umount(x64tmp)
259 umount(multitmp)
261 lounset(lodev(x86))
262 lounset(lodev(x64))
263 lounset(lodev(multi))
265 shutil.rmtree(x86tmp)
266 shutil.rmtree(x64tmp)
267 shutil.rmtree(multitmp)
268 shutil.rmtree(intermediate)
272 if os.path.exists(sys.argv[3]):
273 os.unlink(sys.argv[3])
274 move(multi, sys.argv[3])
277 def parse(x86, x64, multi):
278 for file in x86, x64:
279 if os.path.exists(file):
280 pass
281 else:
282 usage()
283 if not multi:
284 usage()
285 setup(x86, x64, multi)
291 try:
292 parse(sys.argv[1], sys.argv[2], sys.argv[3])
293 except:
294 usage()
302 if __name__ == "__main__":
303 sys.exit(main())