Makefile          |    2 
 docs/mkbiarch.8   |   89 +++++++++++++++
 tools/mkbiarch.py |  315 +++++++++++++++++++++++++++++++++++++++---------------
 3 files changed, 324 insertions(+), 82 deletions(-)

New commits:
commit 32674c1516525504fcf813dcaf06dd7247d9224c
Author: Jasper Hartline <[email protected]>
Date:   Sat Sep 11 21:56:06 2010 -0500

    Updated version of mkbiarch with docs and install.
    
    Signed-off-by: Bruno Wolff III <[email protected]>

diff --git a/Makefile b/Makefile
index 8818236..faa3d78 100644
--- a/Makefile
+++ b/Makefile
@@ -26,6 +26,7 @@ install: man
        $(INSTALL_PROGRAM) -D tools/image-creator 
$(DESTDIR)/usr/bin/image-creator
        $(INSTALL_PROGRAM) -D tools/livecd-iso-to-disk.sh 
$(DESTDIR)/usr/bin/livecd-iso-to-disk
        $(INSTALL_PROGRAM) -D tools/livecd-iso-to-pxeboot.sh 
$(DESTDIR)/usr/bin/livecd-iso-to-pxeboot
+       $(INSTALL_PROGRAM) -D tools/mkbiarch.py $(DESTDIR)/usr/bin/mkbiarch
        $(INSTALL_DATA) -D AUTHORS 
$(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)/AUTHORS
        $(INSTALL_DATA) -D COPYING 
$(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)/COPYING
        $(INSTALL_DATA) -D README 
$(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)/README
@@ -41,6 +42,7 @@ uninstall:
        rm -f $(DESTDIR)/usr/bin/livecd-creator
        rm -rf $(DESTDIR)/usr/lib/livecd-creator
        rm -rf $(DESTDIR)/usr/share/doc/livecd-tools-$(VERSION)
+       rm -f $(DESTDIR)/usr/bin/mkbiarch
 
 dist : all
        git archive --format=tar --prefix=livecd-tools-$(VERSION)/ HEAD | bzip2 
-9v > livecd-tools-$(VERSION).tar.bz2
diff --git a/docs/mkbiarch.8 b/docs/mkbiarch.8
new file mode 100644
index 0000000..4ec1396
--- /dev/null
+++ b/docs/mkbiarch.8
@@ -0,0 +1,89 @@
+.\" PROCESS THIS FILE WITH
+.\" groff -man -Tascii mkbiarch.8 
+.\" 
+.TH mkbiarch 8 "2010-8-24" "LiveCD Tools" "User Manuals"
+
+.SH NAME
+mkbiarch.py - make a multiple architecture Live boot disk image
+for USB, CF SSD or any disk from 2 architecturally different 
+LiveCD ISO9660 image files.
+
+.SH SYNOPSIS
+mkbiarch <LiveCDx86ISO>  <LiveCDx64ISO>  <MultipleArch Disk IMG File>
+
+.SH DESCRIPTION
+.B mkbiarch(8)
+create a multiple architecture, bootable Live Disk image file (IMG)
+for use on USB or any disk (CF, SSD) 
+from 2 LiveCD ISO9660 files of different architecture (ISO).
+.BR
+
+.SH USAGE
+.B mkbiarch.py
+Fedora-13-i686-Live.iso
+Fedora-13-x86_64-Live.iso
+Fedora-13-MultiArch.img
+
+Then to write it 
+/bin/dd if=Fedora-13-MultiArch.img of=/dev/sdb bs=4M
+
+In the above example, mkbiarch.py
+creates Fedora-Multi-arch.img
+from the two existing ISO9660 LiveCD image files. 
+The resulting image file, 
+is written to a raw disk device using 
+.B dd(1)
+.BR
+
+
+.SH UNDER THE HOOD
+.B mkbiarch.py(8)
+first checks that the two ISO9660 image files exist. It will create a blank
+file using dd(1) writing data from /dev/zero, the size of the two ISO9660 
images files combined.
+The blank file is then bound via loopback using
+.B losetup(8)
+partitioned, and bound at an offset via loopback
+of 512 bytes, this second loopback device is formatted type ext3 using 
+.B mke2fs(8)
+This filesystem is mounted using 
+.B mount(8)
+on a temporary directory. The two ISO9660 files are then mounted via loopback, 
+files are copied using shutil module in Python, from them to the newly 
formatted 
+filesystem in the image file. Data is gathered from the ISO9660 image files 
from it's isolinux.cfg,
+after the files are copied the loopbacked ISO9660 image files are released.
+.B extlinux(1)
+is installed to the loopback mounted filesystem on the target image file and 
an extlinux.conf
+is written. The temporary directories are unmounted using 
+.B umount(8)
+and the looback devices are released. 
+The temporary directories are then removed, and the resulting Multiple 
Architecture Disk Image
+File is moved using shutil to the specified location on the command line, 
which is provided as 
+argument 3 to mkbiarch.py
+
+.SH BUGS
+Please report any bugs to 
+http://bugzilla.redhat.com 
+under component livecd-tools 
+
+.SH AVAILABILITY
+To check out the git version of this program
+ git clone git://git.fedorahosted.org/livecd
+
+.SH AUTHOR
+Jasper Hartline <[email protected]>
+
+.SH CONTRIBUTORS
+.B Richard Shaw <[email protected]> 
+pyparted suggestions and feedback
+
+.B Jan Kratochvil <[email protected]>  
+for the original bash script which 
+the python version was derived 
+
+.SH "SEE ALSO"
+.BR livecd-creator(8),
+.BR livecd-iso-to-disk(8),
+.BR mke2fs(8),
+.BR losetup(8),
+.BR dd(1),
+.BR exlinux(1)
diff --git a/tools/mkbiarch.py b/tools/mkbiarch.py
index 71fd54a..5178785 100644
--- a/tools/mkbiarch.py
+++ b/tools/mkbiarch.py
@@ -1,40 +1,34 @@
-#!/usr/bin/env python
-
-__author__ = "Jasper Hartline"
-__credits__ = ""
-__license__ = "GPL?"
-__version__ = "Alpha"
-__description__ = "Attempts to create a 32/64 bit combination live Fedora 
image."
-
+#!/usr/bin/python
 import os
 import sys
+
 import shutil
 import parted
 import subprocess
+import optparse
 import tempfile
-import math
+import re
 
-from optparse import OptionParser
 
 def main():
 
-    def cleanup():
-        pass
+
+    def usage():
+        usage = 'usage: mkbiarch.py <x86 Live ISO File> <x64 Live ISO File> 
<Target Multi Arch Image File>'
+        print >> sys.stdout, usage
 
 
     def mount(src, dst, options=None):
-        if os.path.exists(src):         # Is src the lodev device?
-            if not os.path.exists(dst): 
+        if os.path.exists(src):
+            if not os.path.exists(dst):
                 os.makedir(dst)
-            if options:                 # None is the same as Null so you can 
test for existence instead.
-                args = ("/bin/mount", options, src, dst)
-            else:
+            if options is None:
                 args = ("/bin/mount", src, dst)
-                
+            else:
+                args = ("/bin/mount", options, src, dst)
             rc = subprocess.call(args)
             return rc
-        else:                           # Let's make sure only one return 
statement get's triggered.
-            return False                # Might as well return something 
useful so we can test for failure.
+        return
 
 
     def umount(src):
@@ -42,111 +36,268 @@ def main():
                 args = ("/bin/umount", src)
                 rc = subprocess.call(args)
                 return rc
-        else:
-            return False
+        return
 
 
     def copy(src, dst):
         if os.path.exists(src):
+            if not os.path.exists(dst):
+                if not os.path.isfile(src):
+                    mkdir(dst)
             shutil.copy(src, dst)
-            return True
-        else:
-            return False
 
 
     def move(src, dst):
         if os.path.exists(src):
-            shutil.mopve(src, dst)
-            return True
+            shutil.move(src, dst)
+
+    def mkdir(dir=None):
+        if dir is None:
+            tmp = tempfile.mkdtemp()
+            return tmp
         else:
-            return False
+            args = ("/bin/mkdir", "-p", dir)
+            rc = subprocess.call(args)
 
 
     def losetup(src, dst, offset=None):
-        if os.path.exists(src) and os.path.exists(dst):
-            if offset:
-                args = ("/sbin/losetup", "-o", offset, src, dst)
-            else:
-                args = ("/sbin/losetup", src, dst)
-                    
-            rc = subprocess.call(args)
-            return rc
-        else:
-            return False
-        
+        if os.path.exists(src):
+            if os.path.exists(dst):
+                if offset is None:
+                    args = ("/sbin/losetup", src, dst)
+                else:
+                    args = ("/sbin/losetup", "-o", str(offset), src, dst)
+                rc = subprocess.call(args)
+        return rc
+
+    def lounset(device):
+        args = ("/sbin/losetup", "-d", device)
+        rc = subprocess.call(args) 
 
     def null():
-        fd = open("/dev/null", "w")
+        fd = open(os.devnull, 'w')
         return fd
 
+    def dd(file, target):
+        args = ("/bin/dd", "if=%s"%file, "of=%s"%target)
+        rc = subprocess.call(args)
+
     def lo():
         args = ("/sbin/losetup", "--find")
-        rc = subprocess.call(args, 
stdout=open(null())).communicate()[0].rstrip()
+        rc = subprocess.Popen(args, 
stdout=subprocess.PIPE).communicate()[0].rstrip()
         return rc
 
+    def lodev(file):
+        args = ("/sbin/losetup", "-j", file)
+        rc = subprocess.Popen(args, 
stdout=subprocess.PIPE).communicate()[0].split(":")
+        return rc[0]
+
 
     def mkimage(bs, count):
         tmp = tempfile.mkstemp()
         image = tmp[1]
-        args = ("/bin/dd",
-                "if=/dev/zero",
-                "of=%s" % image,
-                "bs=%s" % bs,
-                "count=%s" % count)
+        args = ("/bin/dd", "if=/dev/zero",
+                 "of=%s"%image, "bs=%s"%bs,
+                 "count=%s"%count)
         rc = subprocess.call(args)
         return image
 
 
     def size(ent):
-        size = os.path.getsize(ent)
-        if size >= 0:
-            return os.path.getsize(ent)
-        else:
-            print "Something is wrong, %s has no size." % ent
-            return False
+        if os.path.exists(ent):
+            return os.stat(ent).st_size
+
+    def bs(size):
+        return size / 2048
+
+    def partition(device):
+        dev = parted.Device(path=device)
+        disk = parted.freshDisk(dev, 'msdos')
+        constraint = parted.Constraint(device=dev)
+
+        new_geom = parted.Geometry(device=dev,
+                                   start=1,
+                                   end=(constraint.maxSize - 1))
+        filesystem = parted.FileSystem(type="ext2",
+                                       geometry=new_geom)
+        partition = parted.Partition(disk=disk,
+                                     fs=filesystem,
+                                     type=parted.PARTITION_NORMAL,
+                                     geometry=new_geom)
+        constraint = parted.Constraint(exactGeom=new_geom)
+        partition.setFlag(parted.PARTITION_BOOT)
+        disk.addPartition(partition=partition,
+                          constraint=constraint)
+        
+        disk.commit()
+
+    def format(partition):
+        args = ("/sbin/mke2fs", "-j", partition)
+        rc = subprocess.call(args)
+
+    def mbr(target):
+        mbr = "/usr/share/syslinux/mbr.bin"
+        dd(mbr, target)
+
+    def getuuid(device):
+        args = ("/sbin/blkid", "-s", "UUID", "-o", "value", device)
+        rc = subprocess.Popen(args, 
stdout=subprocess.PIPE).communicate()[0].rstrip()
+        return rc
+
+    def syslinux(multitmp, config, **args):
+        arg = ("/sbin/extlinux", "--install", multitmp + "/extlinux/")
+        rc = subprocess.call(arg)
+
+        content = """
+        default vesamenu.c32
+        timeout 100
 
+        menu background splash.jpg
+        menu title Welcome to Fedora 13
+        menu color border 0 #ffffffff #00000000
+        menu color sel 7 #ffffffff #ff000000
+        menu color title 0 #ffffffff #00000000
+        menu color tabmsg 0 #ffffffff #00000000
+        menu color unsel 0 #ffffffff #00000000
+        menu color hotsel 0 #ff000000 #ffffffff
+        menu color hotkey 7 #ffffffff #ff000000
+        menu color timeout_msg 0 #ffffffff #00000000
+        menu color timeout 0 #ffffffff #00000000
+        menu color cmdline 0 #ffffffff #00000000
+        menu hidden
+        menu hiddenrow 5
 
-    def blocks(block_size, size):
-        # Round up to nearest block
-        # Make sure floating math, not integer math or we don't get remainders.
-        # Turn back into an integer for return statement.
-        return int(math.ceil(size / float(block_size)))
+        label Fedora-13-x86
+        menu label Fedora-13-x86
+        kernel vmlinuz0
+        append initrd=initrd0.img root=UUID=%(uuid)s rootfstype=auto ro 
live_dir=/x86/LiveOS liveimg
+        
+        label Fedora-13-x64
+        menu label Fedora-13-x64
+        kernel vmlinuz1
+        append initrd=initrd1.img root=UUID=%(uuid)s rootfstype=auto ro 
live_dir=/x64/LiveOS liveimg
+        """ % args
+        fd = open(config, 'w')
+        fd.write(content)
+        fd.close()
 
+    def verify():
+        # use md5 module to verify image files
+        pass
 
     def setup(x86, x64, multi):
-        # Reworked the logic a bit.
-        block_size = 2048               # Should this be a global constant 
instead?
+
         sz = size(x86) + size(x64)
-        count = blocks(block_size, sz)
+        count = bs(sz)
+        blsz = str(2048)
+
+        count = count + 102400
+
+        multi = mkimage(blsz, count)    
+        losetup(lo(), multi)
+ 
+        mbr(lodev(multi))
+        partition(lodev(multi))
+ 
+        lounset(lodev(multi))
+     
+        losetup(lo(), multi, offset=512)
+        format(lodev(multi))
+
+        multitmp = mkdir()
+        mount(lodev(multi), multitmp)
+
+        losetup(lo(), x86)
+        losetup(lo(), x64)
+ 
+        x86tmp = mkdir()
+        x64tmp = mkdir()
+
+        mount(lodev(x86), x86tmp)
+        mount(lodev(x64), x64tmp)
+
+
+        dirs = ("/extlinux/", "/x86/", "/x64/")
+        for dir in dirs:
+            mkdir(multitmp + dir)
+        dirs = ("/x86/", "/x64/")
+        for dir in dirs:
+            mkdir(multitmp + dir + "/LiveOS/")
+
+        intermediate = tempfile.mkdtemp() # loopdev performance is slow
+                                          # copy to here first then back
+                                          # to multitmp + dir which is looback 
also
+
+        imgs = ("squashfs.img", "osmin.img")
+        for img in imgs:
+            copy(x86tmp + "/LiveOS/" + img, intermediate)
+            copy(intermediate + "/" + img, multitmp + "/x86/LiveOS/")
+        for img in imgs:
+            copy(x64tmp + "/LiveOS/" + img, intermediate)
+            copy(intermediate + "/" + img, multitmp + "/x64/LiveOS/")
+
+        for file in os.listdir(x86tmp + "/isolinux/"):
+            copy(x86tmp + "/isolinux/" + file, multitmp + "/extlinux/")
+
+        copy(x64tmp + "/isolinux/vmlinuz0", multitmp + "/extlinux/vmlinuz1")
+        copy(x64tmp + "/isolinux/initrd0.img", multitmp + 
"/extlinux/initrd1.img")
+            
+
+       
+        uuid = getuuid(lodev(multi))
+
+  
+        config = (multitmp + "/extlinux/extlinux.conf")
+        syslinux(multitmp,
+                 config,
+                 uuid=uuid)
+
+
+
+        umount(x86tmp)
+        umount(x64tmp)
+        umount(multitmp)
+
+        lounset(lodev(x86))
+        lounset(lodev(x64))
+        lounset(lodev(multi))
+
+        shutil.rmtree(x86tmp)
+        shutil.rmtree(x64tmp)
+        shutil.rmtree(multitmp)
+        shutil.rmtree(intermediate)   
         
-        multi = mkimage(str(blsz), count)
-        losetup(multi, lo())         
+
+
+        if os.path.exists(sys.argv[3]):
+            os.unlink(sys.argv[3])
+        move(multi, sys.argv[3])
  
 
     def parse(x86, x64, multi):
-        for file in x86, x64, multi:    # Do we expect that multi exists yet?
-            if os.path.exists(file):    # Should we test for existance or 
isfile?
+        for file in x86, x64:
+            if os.path.exists(file):
                 pass
             else:
-                parser.error("One of the images does not exist.")
+                usage()
+        if not multi:
+            usage()
         setup(x86, x64, multi)
 
-    # Generate parser and fill with options.
-    usage = "usage: %prog [options] <32bit image> <64bit image> <biarch image>"
-    version = "%prog " + __version__
-    parser = OptionParser(usage=usage, description=__description__, 
version=version)
-    parser.add_option("--test", action="store_true", default=False,
-                      dest="test", help="Doesn't do anything yet.")
-    (options, args) = parser.parse_args()
-    if len(args) != 3:
-        parser.error("You must specify all three arguments.")
-        sys.exit(0)
-        
-    try:                                # Any reason this would fail?
-        parse(args[0], args[1], args[2])
+
+
+
+
+    try: 
+        parse(sys.argv[1], sys.argv[2], sys.argv[3])
     except:
-        parser.error("Something failed. Better luck next time!")
-        sys.exit(1)
-               
+        usage()
+
+
+
+        
+        
+
+
 if __name__ == "__main__":
-    sys.exit(main())
\ No newline at end of file
+    sys.exit(main())


--
livecd mailing list
[email protected]
https://admin.fedoraproject.org/mailman/listinfo/livecd

Reply via email to