Difference between revisions of "Mac Build Scripts: Python"

From FreekiWiki
Jump to navigation Jump to search
(→‎replicate.py: update, os action prevented)
 
(23 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Now let's try that Linux Disk Replication script in Python.  
+
{{delete}} These scripts are 5 years out of date and no longer reflect the methods or hardware we work on.
 +
 
 +
Now let's try that Linux Disk Replication script in Python.  Not fully tested.  The current version (6mar07) has potentially destructive '''os''' module calls commented out for testing purposes.
  
 
==Disk Replication==
 
==Disk Replication==
 
===replicate.py===
 
===replicate.py===
#!/usr/bin/python
+
#!/usr/bin/python
from platform import *
+
from platform import *
from globals import *
+
from globals import *
from scripts import *
+
from scripts import *
import sys, getopt, string
+
import sys, getopt, string, datetime
 
+
def usage():
+
def usage():
    errExit(2,"usage: replicate -t macType targetdev")
+
    errExit(2,"usage: replicate -t macType targetdev")
 
+
def getArgs():
+
def getArgs():
    macType = target = None
+
    macType = target = None
    try:
+
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ht:", ["help"])
+
        opts, args = getopt.getopt(sys.argv[1:], "ht:", ["help"])
    except getopt.GetoptError:
+
    except getopt.GetoptError:
        # print help information and exit:
+
        # print help information and exit:
        usage()
+
        usage()
    if not opts:  
+
    if not opts:  
        usage()
+
        usage()
    for o, a in opts:
+
    for o, a in opts:
        if o == "-t":
+
        if o == "-t":
            macType = a
+
            macType = a
        if o in ("-h", "--help"):
+
        if o in ("-h", "--help"):
            usage()
+
            usage()
    if args:
+
    if args:
        target = args[0]
+
        target = args[0]
    else:
+
    else:
        target = os.environ.get('REPL_TARGET_DRIVE')
+
        target = os.environ.get('REPL_TARGET_DRIVE')
    if target is None:
+
    if target is None:
        print "error: no target drive specified"
+
        print "error: no target drive specified"
        usage()
+
        usage()
    return macType, target
+
    return macType, target
       
+
       
 
+
def verifyTarget(host):
+
def verifyTarget(host):
    """ target device must exist and have no partition map.  Existence
+
    """ target device must exist and have no partition map.  Existence
        is tested by probing with hdparm; partition map is probed with
+
        is tested by probing with hdparm; partition map is probed with
        fdisk.
+
        fdisk.
    """  
+
    """  
    devPath = host.get_hdPath()
+
    devPath = host.get_hdPath()
    cmd = 'hdparm -i ' +  devPath
+
    cmd = 'hdparm -i ' +  devPath
    r = os.popen(cmd)
+
    try:
    status = r.close()
+
        os.popen(cmd)
    if status is not None:
+
    except:
        errExit(8,'error: device ' + devPath + ' does not seem to exist')
+
        errExit(3,'error: device ' + devPath + ' does not seem to exist')
    cmd = ('fdisk -l ' + devPath + '| grep ' + devPath + ' | wc -l')
+
    cmd = ('fdisk -l ' + devPath + '| grep ' + devPath + ' | wc -l')
    nPartitions = map(string.strip, os.popen(cmd).readlines())
+
    try:
    if nPartitions:
+
        nPartitions = map(string.strip, os.popen(cmd).readlines())
        errExit(9,'error: there appear to be existing partitions on ' + devPath)
+
        if nPartitions[0] is 0:
 
+
            errExit(4,'error: there appear to be existing partitions on ' + devPath)
def createPartitions(host):
+
    except:
    """ create an fdisk script for creating partitions on the local
+
            errExit(5,'error: could not read partition map from ' + devPath)
        target drive; create an ext3 filesystem on the linux partition,  
+
        and initinitialize the swap partition.  Initialializing the swap  
+
def createPartitions(host):
        partition has the benefit of creating a UUID for it.
+
    """ create an fdisk script for creating partitions on the local
    """
+
        target drive; create an ext3 filesystem on the linux partition,  
    # generate fdisk script and apply it
+
        and initinitialize the swap partition.  Initialializing the swap  
    devPath = host.get_hdPath()
+
        partition has the benefit of creating a UUID for it.
    genFdiskScript(devPath)
+
    """
    cmd = 'fdisk ' + devPath + ' < ' + fdiskScript
+
    # generate fdisk script and apply it
#    os.system(cmd)
+
    devPath = host.get_hdPath()
    print 'os.system(' + cmd + ')'
+
    try:
 
+
        genFdiskScript(devPath)
    # verify partition existence, and create linux filesystem and swap space
+
    except:
    cmd = 'fdisk -l ' + devPath + ' | grep ' + host.get_linuxPart() \
+
        errExit(6,"error: failed to generate fdisk script")
          + ' | wc -l'
+
    cmd = 'fdisk ' + devPath + ' < ' + fdiskScript
    n_partitions = map(string.strip, os.popen(cmd).readlines())
+
    print 'os.system(' + cmd + ')'
    if (not n_partitions or n_partitions[0] is not '1'):
+
    try:
        err = 'error: no linux partition ' + host.get_linuxPart() \
+
        os.system(cmd)
              + ' for fs creation'
+
    except:
        errExit(10, err)
+
        errExit(7,"error: failed to create partitions")
#    os.system('mkfs3.ext3' + host.get_linuxPart())
+
#    os.system('mkswap' + host.get_swapPart())
+
    # verify partition existence, and create linux filesystem and swap space
    print 'os.system(mkfs3.ext3 ' + host.get_linuxPart() + ')'
+
    cmd = 'fdisk -l ' + devPath + ' | grep ' + host.get_linuxPart() \
    print 'os.system(mkswap ' + host.get_swapPart() + ')'
+
            + ' | wc -l'
 
+
    try:
def setupForCopy(host):
+
        n_partitions = map(string.strip, os.popen(cmd).readlines())
    """ verify/create all the necessary mount points
+
        if (not n_partitions or n_partitions[0] is not '1'):
    """
+
            err = 'error: no linux partition ' + host.get_linuxPart() \
    ## linux target
+
                + ' for fs creation'
    mntPath = '/mnt/' + host.get_hd() + linuxpart
+
            errExit(8, err)
    if os.path.exists(mntPath):
+
    except:
        if not os.path.isdir(mntPath):
+
        errExit(9,"error: could not read partition map for verification")
            errExit(18,'error: mount point ' + mntPath + 'is a regular file;'
+
    print 'os.system(mkfs.ext3 ' + host.get_linuxPart() + ')'
                        + 'it must be a directory')
+
    print 'os.system(mkswap ' + host.get_swapPart() + ')'
        # else it exists and it is a directory
+
    try:
    else:
+
        os.system('mkfs.ext3 ' + host.get_linuxPart())
        # it does not exist, so create it
+
    except:
#        os.path.mkdir(mntPath,0644)
+
        errExit(10,"error: could not create ext3 filesystem")
        print 'os.path.mkdir(' + mntPath + ',0644)'
+
    try:
    # mount target linux partition
+
        os.system('mkswap ' + host.get_swapPart())
    cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart()  + ' ' + mntPath
+
    except:
#    status = os.system(cmd)
+
        errExit(11,"error: could not create swapspace")
    print 'os.system(' + cmd + ')'
+
#    if (status is not 0):
+
def setupForCopy(host):
#        errExit(12,'error: mount target linux partition failed: ' \
+
    """ verify/create all the necessary mount points
#                    + host.get_linuxPart() + ' to ' + mntPath)
+
    """
#    else:
+
    ## linux target
#        os.system('umount ' + mntPath)
+
    mntPath = '/mnt/' + host.get_hd() + linuxpart
 
+
    if os.path.exists(mntPath) and os.path.isdir(mntPath):
    ## boot target
+
        pass
    mntPath = '/mnt/' + host.get_hd() + swappart
+
        # all well and good
    if os.path.exists(mntPath):
+
    elif os.path.exists(mntPath) and not os.path.isdir(mntPath):
        if not os.path.isdir(mntPath):
+
        errExit(12,'error: mount point '  
            errExit(18,'error: mount point ' + mntPath + 'is a regular file;'
+
                    + mntPath + 'is not a directory')
                        + 'it must be a directory')
+
    else:
        # else it exists and it is a directory
+
        # it does not exist, so create it
    else:
+
        print 'os.mkdir(' + mntPath + ',0644)'
        # it does not exist, so create it
+
        try:
#        os.path.mkdir(mntPath,0644)
+
            os.mkdir(mntPath,0644)
        print 'os.path.mkdir(' + mntPath + ',0644)'
+
        except:
 
+
            errExit(12,'error: cannot create mount point ' + mntPath)
def copyPartitions(host,pfm):
+
    """ copy boot partition with dd, and copy linux install image with  
+
    # mount target linux partition
        rsync; verify boot partition by mounting it as an hfs filesystem
+
    cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart()  + ' ' + mntPath
    """
+
    print 'os.system(' + cmd + ')'
    # copy the boot partition
+
    try:
    mntPath = '/mnt/' + host.get_hd() + bootpart
+
        os.system(cmd)
    bootimgPath = srcHome + '/' + pfm.get_imageType() + '/' + bootpartImg
+
    except:
    cmd = 'dd if=' + bootimgPath + ' of=' + mntPath
+
        errExit(13,'error: mount target linux partition failed: ' \
#    os.system(cmd)
+
                    + host.get_linuxPart() + ' to ' + mntPath)
    print 'os.system(' + cmd + ')'
+
   
+
    ## boot target
    # mount/verify target boot partition
+
    mntPath = '/mnt/' + host.get_hd() + swappart
    cmd = 'mount -t hfs ' + host.get_bootPart() + ' ' + mntPath
+
    if os.path.exists(mntPath):
#   status = os.system(cmd)
+
        if not os.path.isdir(mntPath):
    print 'os.system(' + cmd + ')'
+
            errExit(14,'error: mount point ' + mntPath + 'is a regular file;'
#    if (status is not 0):
+
                        + 'it must be a directory')
#        errExit(12,'error: mount target swap partition failed: ' \
+
        # else it exists and it is a directory
#                    + host.get_swapPart() + ' to ' + mntPath)
+
    else:
#    else:
+
        # it does not exist, so create it
#        os.system('umount ' + mntPath)
+
        print 'os.mkdir(' + mntPath + ',0644)'
 
+
        try:
    # copy the linux partition
+
            os.mkdir(mntPath,0644)
    mntPath = '/mnt/' + host.get_hd() + linuxpart
+
        except:
    linuximgPath = srcHome + '/' + pfm.get_imageType() + '/' + linuxImg
+
            errExit(15,"error: could not create directory " + mntPath1)
    cmd = 'rsync -av ' + linuximgPath + '/ ' + mntPath + '/'
+
#    status = os.system(cmd)
+
def copyPartitions(host,pfm):
    print 'os.system(' + cmd + ')'
+
    """ copy boot partition with dd, and copy linux install image with  
#    if (status is not 0):
+
        rsync; verify boot partition by mounting it as an hfs filesystem
#        errExit(12,'error: mount target linux partition failed: ' \
+
    """
#                    + host.get_linuxPart() + ' to ' + mntPath)
+
    # copy the boot partition
#    else:
+
    mntPath = '/mnt/' + host.get_hd() + bootpart
#        os.system('umount ' + mntPath)
+
    bootimgPath = srcHome + '/' + pfm.get_imageType() + '/' + bootpartImg
 
+
    cmd = 'dd if=' + bootimgPath + ' of=' + host.get_bootPart()
def tweakConfigFiles(host,pfm):
+
    print 'os.system(' + cmd + ')'
    r1=re.compile(r'UUID=([0-9a-fA-F\-]+)')
+
    try:
    cmd = 'vol_id ' + host.get_linuxPart() + ' | grep -i uuid'
+
        os.system(cmd)
    print 'os.system(' + cmd + ')'
+
    except:
    for line in os.popen(cmd).readlines():
+
        errExit(16,'error: dd failed to copy boot image')
        m = r1.search(line)
+
   
        if (m):
+
    # mount/verify target boot partition
            linuxuuid = m.group(1)
+
    cmd = 'mount -t hfs ' + host.get_bootPart() + ' ' + mntPath
            break
+
    print 'os.system(' + cmd + ')'
    cmd = 'vol_id ' + host.get_swapPart() + ' | grep -i uuid'
+
    try:
    print 'os.system(' + cmd + ')'
+
        os.system(cmd)
    for line in os.popen(cmd).readlines():
+
    except:
        print line
+
        errExit(17,'error: mount target boot partition failed: ' \
        m = r1.search(line)
+
                    + host.get_bootPart() + ' to ' + mntPath)
        if (m):
+
    os.system('umount ' + mntPath)
            swapuuid = m.group(1)
+
            break
+
    # copy the linux partition
 
+
    mntPath = '/mnt/' + host.get_hd() + linuxpart
    try:
+
    linuximgPath = srcHome + '/' + pfm.get_imageType() + '/' + linuxImg
        genYbConf(pfm)
+
    cmd = 'rsync -av ' + linuximgPath + '/ ' + mntPath + '/'
    except:
+
    print 'os.system(' + cmd + ')'
        errExit(19,"error: failed to generate yaboot configuration")
+
    try:
    try:
+
        os.system(cmd)
        genFstab(pfm,linuxuuid,swapuuid)
+
    except:
    except:
+
        errExit(18,'error: mount target linux partition failed: ' \
        errExit(20,"error: failed to generate fstab")  
+
                    + host.get_linuxPart() + ' to ' + mntPath)
 
+
    os.system('umount ' + mntPath)
    mntPath = '/mnt/' + host.get_hd() + linuxpart
+
    cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart()  + ' ' + mntPath
+
def tweakAndTune(host,pfm):
#    status = os.system(cmd)
+
    r1=re.compile(r'UUID=([0-9a-fA-F\-]+)')
    print 'os.system(' + cmd + ')'
+
    cmd = 'vol_id ' + host.get_linuxPart() + ' | grep -i uuid'
    cmd = 'cp ' + fstabFile + ' ' + mntPath + '/etc/yaboot.conf'  
+
    print 'os.popen(' + cmd + ')'
#    os.system(cmd)
+
    try:
    print 'os.system(' + cmd + ')'
+
        for line in os.popen(cmd).readlines():
    cmd = 'cp ' + ybConfFile + ' ' + mntPath + '/etc/fstab'  
+
            m = r1.search(line)
#    os.system(cmd)
+
            if (m):
    print 'os.system(' + cmd + ')'
+
                linuxuuid = m.group(1)
    cmd = 'mkofboot -b ' + host.get_bootPart() + ' ' + pfm.get_bootPart() \
+
                break
          + ' -o ' + pfm.get_bootdev() + ' -C ' + mntPath \
+
    except:
          + '/etc/yaboot.conf ' + '--nonvram'
+
        errExit(19,'error: failed to get linux partition uuid')
#    status = os.system(cmd)
+
    cmd = 'vol_id ' + host.get_swapPart() + ' | grep -i uuid'
    print 'os.system(' + cmd + ')'
+
    print 'os.popen(' + cmd + ')'
#    if (status is not 0):
+
    try:
#        errExit(15,'error:failed to update boot partition')
+
    for line in os.popen(cmd).readlines():
#   else:
+
            print line
#        os.system('umount ' + mntPath)
+
            m = r1.search(line)
 
+
            if (m):
def main():
+
            swapuuid = m.group(1)
    # first, ensure root user
+
            break
    if os.getuid() is not 0:
+
    except:
        errExit(1 ,"You must be root to run this script; try using sudo")
+
        errExit(20,'error: failed to get swap partition uuid')
   
+
    macType, target = getArgs()
+
    try:
    h = aPlatform("host")
+
        genYbConf(pfm)
    p = aPlatform(macType)
+
    except:
    h.set_hd(target)
+
        errExit(21,"error: failed to generate yaboot configuration")
    verifyTarget(h)
+
    try:
    createPartitions(h)
+
        genFstab(pfm,linuxuuid,swapuuid)
    setupForCopy(h)
+
    except:
    copyPartitions(h,p)
+
        errExit(22,"error: failed to generate fstab")  
    tweakConfigFiles(h,p)
+
 
+
    mntPath = '/mnt/' + host.get_hd() + linuxpart
if __name__ == "__main__":
+
    cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart()  + ' ' + mntPath
    main()
+
    print 'os.system(' + cmd + ')'
 +
    try:
 +
        os.system(cmd)
 +
    except:
 +
        errExit(23,"error: failed to mount linux partition for config files")
 +
    cmd = 'cp ' + ybconfFile + ' ' + mntPath + '/etc/yaboot.conf'  
 +
    print 'os.system(' + cmd + ')'
 +
    try:
 +
        os.system(cmd)
 +
    except:
 +
        errExit(24,"error: failed to copy yaboot.conf")
 +
    cmd = 'cp ' + fstabFile + ' ' + mntPath + '/etc/fstab'  
 +
    print 'os.system(' + cmd + ')'
 +
    try:
 +
        os.system(cmd)
 +
    except:
 +
        errExit(25,"error: failed to copy fstab")  
 +
    # make the new boot partition using info on mounted linux partition;
 +
    # suppress confirmation queries (-f option to mkofboot)
 +
    cmd = 'mkofboot -f -b ' + host.get_bootPart() \
 +
          + ' -o ' + pfm.get_bootdev() + ' -C ' + mntPath \
 +
          + '/etc/yaboot.conf ' + '--nonvram'
 +
    print 'os.system(' + cmd + ')'
 +
    try:
 +
        os.system(cmd)
 +
    except:
 +
        errExit(26,'error:failed to update boot partition')
 +
 +
    # all done now
 +
    try:
 +
        os.system('umount ' + mntPath)
 +
    except:
 +
        errExit(28,'error:failed to umount' + mntpath)
 +
 +
    # force time-last-checked on linux partition so that boot
 +
    # won't think it's way old
 +
    datespec = datetime.datetime.now().strftime("%Y%m%d")
 +
    cmd = 'tune2fs -T ' + datespec + ' ' + host.get_linuxPart()
 +
    print 'os.system(' + cmd + ')'
 +
    try:
 +
        os.system(cmd)
 +
    except:
 +
        errExit(27,'error:failed to set time-last-checked on ' + host.get_linuxPart())
 +
 +
def main():
 +
    # first, ensure root user
 +
    if os.getuid() is not 0:
 +
        errExit(1 ,"You must be root to run this script; try using sudo")
 +
   
 +
    macType, target = getArgs()
 +
    h = aPlatform("host")
 +
    p = aPlatform(macType)
 +
    h.set_hd(target)
 +
    verifyTarget(h)
 +
    createPartitions(h)
 +
    setupForCopy(h)
 +
    copyPartitions(h,p)
 +
    tweakAndTune(h,p)
 +
 +
if __name__ == "__main__":
 +
    main()
  
 
===globals.py===
 
===globals.py===
  linuxroot = "/root/rootdir"
+
  import sys
  bootpartimg = "/root/bootpart.img"
+
 
+
srcHome    = "/root"
 +
bootpartImg = "bootpart.img"
 +
linuxImg    = "rootdir"
 +
fdiskScript = "/tmp/fdisk.script"
 +
ybconfFile  = "/tmp/yaboot.conf"
 +
  fstabFile  = "/tmp/fstab"
 +
bootpart   = "2"
 +
linuxpart  = "3"
 +
swappart    = "4"
 +
macType    = "imac"
 +
 +
 +
def errExit(errno, msg):
 +
    print msg
 +
    sys.exit(errno)
  
 
===platform.py===
 
===platform.py===
 +
from globals import *
 +
import os, sys
 +
 
  class Platform:
 
  class Platform:
 
     def __init__(self):
 
     def __init__(self):
 
         self.name = "prototype"
 
         self.name = "prototype"
         self.hd_device = "hda"
+
         self.hd_device = None
         self.cd_device = "hdc"
+
         self.cd_device = None
 
         self.of_bootdev = "hd:"
 
         self.of_bootdev = "hd:"
 +
        self.image_type = None
 
   
 
   
 
     def get_name(self):
 
     def get_name(self):
Line 232: Line 312:
 
         return self.hd_device
 
         return self.hd_device
 
     def set_hd(self,device):
 
     def set_hd(self,device):
         self.hd_device = device
+
         self.hd_device = os.path.basename(device)
 
     def get_cd(self):
 
     def get_cd(self):
 
         return self.cd_device
 
         return self.cd_device
 
     def set_cd(self,device):
 
     def set_cd(self,device):
         self.cd_device = device
+
         self.cd_device = os.path.basename(device)
 
     def get_bootdev(self):
 
     def get_bootdev(self):
 
         return self.of_bootdev
 
         return self.of_bootdev
     def set_cd(self,ofpath):
+
     def set_bootdev(self,ofpath):
 
         self.of_bootdev = ofpath
 
         self.of_bootdev = ofpath
 +
    def get_hdPath(self):
 +
        return '/dev/' + self.hd_device
 +
    def get_cdPath(self):
 +
        return '/dev/' + self.cd_device
 +
    def get_linuxPart(self):
 +
        return '/dev/' + self.hd_device + linuxpart
 +
    def get_bootPart(self):
 +
        return '/dev/' + self.hd_device + bootpart
 +
    def get_swapPart(self):
 +
        return '/dev/' + self.hd_device + swappart
 +
    def get_imageType(self):
 +
        return self.image_type
 
   
 
   
 
   
 
   
 
  class imac(Platform):
 
  class imac(Platform):
 
     def __init__(self):
 
     def __init__(self):
         self.name = "iMac"
+
        Platform.__init__(self)
 +
        self.name = "imac"
 +
        self.hd_device = "hda"
 +
        self.cd_device = "hdb"
 +
        self.image_type = "imac"
 +
 +
class dvse(Platform):
 +
    def __init__(self):
 +
        Platform.__init__(self)
 +
         self.name = "dvse"
 
         self.hd_device = "hda"
 
         self.hd_device = "hda"
 
         self.cd_device = "hdb"
 
         self.cd_device = "hdb"
         self.of_bootdev = "/pci@f2000000/mac-io@17/ata-4@1f000/disk@0:"
+
         self.image_type = "dvse"
 +
 
   
 
   
 
  class g3(Platform):
 
  class g3(Platform):
 
     def __init__(self):
 
     def __init__(self):
 +
        Platform.__init__(self)
 
         self.name = "g3"
 
         self.name = "g3"
 
         self.hd_device = "hdc"
 
         self.hd_device = "hdc"
 
         self.cd_device = "hda"
 
         self.cd_device = "hda"
         self.of_bootdev = "/pci@80000000/pci-bridge@d/pci-ata@1/@0/disk@0:"
+
         self.image_type = "g3"
 
   
 
   
 
  class g4(Platform):
 
  class g4(Platform):
 
     def __init__(self):
 
     def __init__(self):
 +
        Platform.__init__(self)
 
         self.name = "g4"
 
         self.name = "g4"
 
         self.hd_device = "hda"
 
         self.hd_device = "hda"
 
         self.cd_device = "hdc"
 
         self.cd_device = "hdc"
         self.of_bootdev = "/pci@f2000000/pci-bridge@d/mac-io@7/ata-4@1f000/disk@0:"  
+
         self.image_type = "g4"
 +
 +
class host(Platform):
 +
    def __init__(self):
 +
        Platform.__init__(self)
 +
        self.name = "host"
 +
        self.hd_device = None
 +
        self.cd_device = None
 +
        self.of_bootdev = None
 
   
 
   
  class g4q(Platform):
+
  class test(Platform):
 
     def __init__(self):
 
     def __init__(self):
         self.name = "g4q"
+
        Platform.__init__(self)
 +
         self.name = "test"
 
         self.hd_device = "hda"
 
         self.hd_device = "hda"
         self.cd_device = "hdc"
+
         self.cd_device = "hdb"
         self.of_bootdev = "/pci@f2000000/mac-io@17/ata-4@1f000/disk@0:"  
+
         self.image_type = "test"
 
          
 
          
 
 
  def aPlatform(name):
 
  def aPlatform(name):
 
     if name == "imac":
 
     if name == "imac":
 
         return imac()
 
         return imac()
 +
    elif name == "dvse":
 +
        return dvse()
 
     elif name == "g3":
 
     elif name == "g3":
 
         return g3()
 
         return g3()
 
     elif name == "g4":
 
     elif name == "g4":
 
         return g4()
 
         return g4()
     elif name == "g4q":
+
     elif name == "host":
         return g4q()
+
         return host()
 +
    elif name == "test":
 +
        return test()
 
     else:  
 
     else:  
         return Platform()
+
         errExit(17,'error: unknown platform type ' + name)
 
   
 
   
 
  def dump_platform(p):
 
  def dump_platform(p):
     print 'name      : %s '% p.get_name().upper()
+
     print 'name      : %s '% p.get_name()
 
     print 'hd        : %s '% p.get_hd()
 
     print 'hd        : %s '% p.get_hd()
 
     print 'cd        : %s '% p.get_cd()
 
     print 'cd        : %s '% p.get_cd()
 
     print 'of_bootdev: %s '% p.get_bootdev()
 
     print 'of_bootdev: %s '% p.get_bootdev()
     print ''
+
     print  
 
   
 
   
 
  if __name__ == "__main__":
 
  if __name__ == "__main__":
     dump_platform(aPlatform("g4"))
+
     p = aPlatform("test")
     dump_platform(aPlatform("imac"))
+
     dump_platform(p)
     dump_platform(aPlatform("g3"))
+
 
     dump_platform(aPlatform("g4q"))
+
===scripts.py===
 +
from globals import *
 +
import os, re
 +
 +
def genFdiskScript(device):
 +
    """create an fdisk script, overwriting any exiting file"""
 +
    global fdiskScript
 +
 +
    # length of target drive
 +
    ## get the hd geometry using hdparm
 +
    cmd = 'hdparm -g ' + device
 +
    r1=re.compile(r'sectors = ([0-9]+)')
 +
    try:
 +
        for line in os.popen(cmd).readlines():
 +
                m = r1.search(line)
 +
                if (m):
 +
                    hdlen = int(m.group(1))
 +
                          hdlen = hdlen - 1
 +
                    break
 +
    except:
 +
        errExit(27,'error: failed to get sector count from ' + device)
 +
 +
    # known values
 +
    mapstart = 1
 +
    maplen  = 63
 +
    bootlen  = 1954
 +
    swaplen  = 1494848
 +
 +
    # calculated values
 +
    bootstart  = mapstart + maplen
 +
    linuxstart = bootstart + bootlen
 +
    linuxlen  = hdlen - (maplen + bootlen + swaplen)
 +
    swapstart  = linuxstart + linuxlen
 +
 +
    cmd_list = ['i\n',
 +
                '\n',
 +
                'p\n',
 +
                'C\n',
 +
                str(bootstart),'\n',
 +
                str(bootlen),'\n',
 +
                'untitled\n',
 +
                'Apple_Bootstrap\n'
 +
                'p\n',
 +
                'c\n',
 +
                str(linuxstart),'\n',
 +
                str(linuxlen),'\n',
 +
                'untitled\n',
 +
                'p\n',
 +
                'c\n',
 +
                str(swapstart),'\n',
 +
                str(swaplen),'\n',
 +
                'untitled\n',
 +
                'p\n',
 +
                'w\n',
 +
                'y\n',
 +
                'q\n'
 +
                ]
 +
 +
    script = open(fdiskScript, 'w')
 +
    script.writelines(cmd_list)
 +
    script.close()
 +
   
 +
 +
def genYbConf(pfm):
 +
     conf = ['## yaboot.conf generated by the Ubuntu installer\n',
 +
            '##\n' ,
 +
            '## run: "man yaboot.conf" for details. Do not make changes until you have!!\n' ,
 +
            '## see also: /usr/share/doc/yaboot/examples for example configurations.\n' ,
 +
            '##\n' ,
 +
            '## For a dual-boot menu, add one or more of:\n' ,
 +
            '## bsd=/dev/hdaX, macos=/dev/hdaY, macosx=/dev/hdaZ\n' ,
 +
            '\n',
 +
            'boot=' + pfm.get_bootPart() + '\n' ,
 +
            'device=' + pfm.get_bootdev() + '\n' ,
 +
            'partition=3\n' ,
 +
            'root=' + pfm.get_linuxPart() + '\n' ,
 +
            'timeout=50\n' ,
 +
            'install=/usr/lib/yaboot/yaboot\n' ,
 +
            'magicboot=/usr/lib/yaboot/ofboot\n' ,
 +
            'enablecdboot\n' ,
 +
            '\n' ,
 +
            'image=/boot/vmlinux\n' ,
 +
            '        label=Linux\n' ,
 +
            '        read-only\n' ,
 +
            '        initrd=/boot/initrd.img\n' ,
 +
            '        append="quiet splash"\n' ,
 +
              '\n' ,
 +
            'image=/boot/vmlinux.old\n' ,
 +
            '        label=old\n' ,
 +
            '        read-only\n' ,
 +
            '        initrd=/boot/initrd.img.old\n' ,
 +
            '        append="quiet splash"\n'
 +
            ]
 +
    file = open(ybconfFile,'w')
 +
    file.writelines(conf)
 +
    file.close()
 +
 +
def genFstab(pfm, l_uuid, s_uuid):
 +
     fstab = [
 +
            '# /etc/fstab: static file system information.\n',
 +
            '#\n',
 +
            '# <file system> <mount point>  <type>  <options>      <dump>  <pass>\n',
 +
            'proc            /proc          proc    defaults        0      0\n',
 +
            '# ' + pfm.get_linuxPart() + '\n',
 +
            'UUID=' + l_uuid + ' /              ext3    defaults,errors=remount-ro 0      1\n',
 +
            '# ' + pfm.get_swapPart() + '\n',
 +
            'UUID=' + s_uuid + ' none            swap    sw              0      0\n',
 +
            pfm.get_cdPath()  + '        /media/cdrom0  udf,iso9660 user,noauto    0      0\n',
 +
            ]
 +
    file = open(fstabFile,'w')
 +
    file.writelines(fstab)
 +
    file.close()
 +
 
 +
==Desktop Execution==
 +
===zenity shell script: replicate.sh===
 +
To be placed in '''$HOME/bin''' (in the local case, '''/home/oem/bin''')
 +
#!/bin/bash
 +
type=$(zenity --width=150 --height=250 --list --radiolist \ 
 +
      --title "Select machine type" --column "select"  --column "type" \
 +
      TRUE imac FALSE dvse FALSE g3 FALSE g4)
 +
target=$(zenity --width=150 --height=250 --list --radiolist \ 
 +
      --title "Select local target drive" --column  "select"  \
 +
      --column "target device" FALSE hdb TRUE hdd)
 +
cd /home/oem/python
 +
./replicate.py -t $type $target
 +
zenity --width=200 --title "Replicate" --info --text "Replicate: Done"
 +
 
 +
===Desktop Launcher: replicate.desktop===
 +
Note that the '''Exec''' entry uses '''/home/oem/bin''' specifically
 +
[Desktop Entry]
 +
Version=1.0
 +
Encoding=UTF-8
 +
Name=replicate
 +
Type=Application
 +
Terminal=true
 +
Name[en_US]=replicate
 +
Exec=/home/oem/bin/replicate.sh
 +
Comment[en_US]=replicate ppc linux hd
 +
Comment=replicate ppc linux hd
 +
GenericName[en_US]=
 +
Icon=/usr/share/pixmaps/python.xpm
 +
 
  
==scripts.py==
 
  
  
[[Category:Macintosh]]
+
[[Category:Delete]]

Latest revision as of 17:51, 11 September 2013

deletion

This page has been requested to be deleted.
If you disagree, discuss on the talk page.
Whenever possible, could an Admin please remove this page?

These scripts are 5 years out of date and no longer reflect the methods or hardware we work on.

Now let's try that Linux Disk Replication script in Python. Not fully tested. The current version (6mar07) has potentially destructive os module calls commented out for testing purposes.

Disk Replication

replicate.py

#!/usr/bin/python
from platform import *
from globals import *
from scripts import *
import sys, getopt, string, datetime

def usage():
    errExit(2,"usage: replicate -t macType targetdev")

def getArgs():
    macType = target = None
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ht:", ["help"])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
    if not opts: 
        usage()
    for o, a in opts:
        if o == "-t":
            macType = a
        if o in ("-h", "--help"):
            usage()
    if args:
        target = args[0]
    else:
        target = os.environ.get('REPL_TARGET_DRIVE')
    if target is None:
        print "error: no target drive specified"
        usage()
    return macType, target
        

def verifyTarget(host):
    """ target device must exist and have no partition map.  Existence
        is tested by probing with hdparm; partition map is probed with
        fdisk.
    """ 
    devPath = host.get_hdPath()
    cmd = 'hdparm -i ' +  devPath
    try:
        os.popen(cmd)
    except:
        errExit(3,'error: device ' + devPath + ' does not seem to exist')
    cmd = ('fdisk -l ' + devPath + '| grep ' + devPath + ' | wc -l')
    try:
        nPartitions = map(string.strip, os.popen(cmd).readlines())
        if nPartitions[0] is 0:
            errExit(4,'error: there appear to be existing partitions on ' + devPath)
    except:
            errExit(5,'error: could not read partition map from ' + devPath)

def createPartitions(host):
    """ create an fdisk script for creating partitions on the local
        target drive; create an ext3 filesystem on the linux partition, 
        and initinitialize the swap partition.  Initialializing the swap 
        partition has the benefit of creating a UUID for it.
    """
    # generate fdisk script and apply it
    devPath = host.get_hdPath()
    try:
        genFdiskScript(devPath)
    except:
        errExit(6,"error: failed to generate fdisk script")
    cmd = 'fdisk ' + devPath + ' < ' + fdiskScript
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(7,"error: failed to create partitions")

    # verify partition existence, and create linux filesystem and swap space
    cmd = 'fdisk -l ' + devPath + ' | grep ' + host.get_linuxPart() \
           + ' | wc -l'
    try:
        n_partitions = map(string.strip, os.popen(cmd).readlines())
        if (not n_partitions or n_partitions[0] is not '1'):
            err = 'error: no linux partition ' + host.get_linuxPart() \
                + ' for fs creation'
            errExit(8, err)
    except: 
        errExit(9,"error: could not read partition map for verification")
    print 'os.system(mkfs.ext3 ' + host.get_linuxPart() + ')'
    print 'os.system(mkswap ' + host.get_swapPart() + ')'
    try:
        os.system('mkfs.ext3 ' + host.get_linuxPart())
    except:
        errExit(10,"error: could not create ext3 filesystem")
    try:
        os.system('mkswap ' + host.get_swapPart())
    except:
        errExit(11,"error: could not create swapspace")

def setupForCopy(host):
    """ verify/create all the necessary mount points
    """
    ## linux target
    mntPath = '/mnt/' + host.get_hd() + linuxpart
    if os.path.exists(mntPath) and os.path.isdir(mntPath):
        pass
        # all well and good
    elif os.path.exists(mntPath) and not os.path.isdir(mntPath):
        errExit(12,'error: mount point ' 
                   + mntPath + 'is not a directory')
    else:
        # it does not exist, so create it
        print 'os.mkdir(' + mntPath + ',0644)'
        try:
            os.mkdir(mntPath,0644)
        except:
            errExit(12,'error: cannot create mount point ' + mntPath)

    # mount target linux partition
    cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart()  + ' ' + mntPath
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(13,'error: mount target linux partition failed: ' \
                    + host.get_linuxPart() + ' to ' + mntPath)

    ## boot target
    mntPath = '/mnt/' + host.get_hd() + swappart
    if os.path.exists(mntPath):
        if not os.path.isdir(mntPath):
            errExit(14,'error: mount point ' + mntPath + 'is a regular file;'
                        + 'it must be a directory')
        # else it exists and it is a directory
    else:
        # it does not exist, so create it
        print 'os.mkdir(' + mntPath + ',0644)'
        try:
            os.mkdir(mntPath,0644)
        except:
            errExit(15,"error: could not create directory " + mntPath1)

def copyPartitions(host,pfm):
    """ copy boot partition with dd, and copy linux install image with 
        rsync; verify boot partition by mounting it as an hfs filesystem
    """
    # copy the boot partition
    mntPath = '/mnt/' + host.get_hd() + bootpart
    bootimgPath = srcHome + '/' + pfm.get_imageType() + '/' + bootpartImg
    cmd = 'dd if=' + bootimgPath + ' of=' + host.get_bootPart()
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(16,'error: dd failed to copy boot image')
    
    # mount/verify target boot partition
    cmd = 'mount -t hfs ' + host.get_bootPart()  + ' ' + mntPath
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(17,'error: mount target boot partition failed: ' \
                    + host.get_bootPart() + ' to ' + mntPath)
    os.system('umount ' + mntPath)

    # copy the linux partition
    mntPath = '/mnt/' + host.get_hd() + linuxpart
    linuximgPath = srcHome + '/' + pfm.get_imageType() + '/' + linuxImg
    cmd = 'rsync -av ' + linuximgPath + '/ ' + mntPath + '/'
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(18,'error: mount target linux partition failed: ' \
                    + host.get_linuxPart() + ' to ' + mntPath)
    os.system('umount ' + mntPath)

def tweakAndTune(host,pfm):
    r1=re.compile(r'UUID=([0-9a-fA-F\-]+)')
    cmd = 'vol_id ' + host.get_linuxPart() + ' | grep -i uuid'
    print 'os.popen(' + cmd + ')'
    try:
        for line in os.popen(cmd).readlines():
            m = r1.search(line)
            if (m):
                linuxuuid = m.group(1)
                break
    except:
        errExit(19,'error: failed to get linux partition uuid')
    cmd = 'vol_id ' + host.get_swapPart() + ' | grep -i uuid'
    print 'os.popen(' + cmd + ')'
    try:
    	for line in os.popen(cmd).readlines():
       	    print line
            m = r1.search(line)
            if (m):
            	swapuuid = m.group(1)
            	break
    except:
        errExit(20,'error: failed to get swap partition uuid')

    try:
        genYbConf(pfm)
    except:
        errExit(21,"error: failed to generate yaboot configuration")
    try:
        genFstab(pfm,linuxuuid,swapuuid)
    except:
        errExit(22,"error: failed to generate fstab") 

    mntPath = '/mnt/' + host.get_hd() + linuxpart
    cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart()  + ' ' + mntPath
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(23,"error: failed to mount linux partition for config files") 
    cmd = 'cp ' + ybconfFile + ' ' + mntPath + '/etc/yaboot.conf' 
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(24,"error: failed to copy yaboot.conf") 
    cmd = 'cp ' + fstabFile + ' ' + mntPath + '/etc/fstab' 
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(25,"error: failed to copy fstab") 
    # make the new boot partition using info on mounted linux partition;
    # suppress confirmation queries (-f option to mkofboot)
    cmd = 'mkofboot -f -b ' + host.get_bootPart() \
          + ' -o ' + pfm.get_bootdev() + ' -C ' + mntPath \
          + '/etc/yaboot.conf ' + '--nonvram'
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(26,'error:failed to update boot partition')

    # all done now
    try:
        os.system('umount ' + mntPath)
    except:
        errExit(28,'error:failed to umount' + mntpath)

    # force time-last-checked on linux partition so that boot
    # won't think it's way old
    datespec = datetime.datetime.now().strftime("%Y%m%d")
    cmd = 'tune2fs -T ' + datespec + ' ' + host.get_linuxPart()
    print 'os.system(' + cmd + ')'
    try:
        os.system(cmd)
    except:
        errExit(27,'error:failed to set time-last-checked on ' + host.get_linuxPart())

def main():
    # first, ensure root user
    if os.getuid() is not 0:
        errExit(1 ,"You must be root to run this script; try using sudo")
    
    macType, target = getArgs()
    h = aPlatform("host")
    p = aPlatform(macType)
    h.set_hd(target)
    verifyTarget(h)
    createPartitions(h)
    setupForCopy(h)
    copyPartitions(h,p)
    tweakAndTune(h,p)

if __name__ == "__main__":
    main()

globals.py

import sys

srcHome     = "/root"
bootpartImg = "bootpart.img"
linuxImg    = "rootdir"
fdiskScript = "/tmp/fdisk.script"
ybconfFile  = "/tmp/yaboot.conf"
fstabFile   = "/tmp/fstab"
bootpart    = "2"
linuxpart   = "3"
swappart    = "4"
macType     = "imac"


def errExit(errno, msg):
    print msg
    sys.exit(errno)

platform.py

from globals import *
import os, sys

class Platform:
    def __init__(self):
        self.name = "prototype"
        self.hd_device = None
        self.cd_device = None
        self.of_bootdev = "hd:"
        self.image_type = None

    def get_name(self):
        return self.name
    def set_name(self,name):
        self.name = name
    def get_hd(self):
        return self.hd_device
    def set_hd(self,device):
        self.hd_device = os.path.basename(device)
    def get_cd(self):
        return self.cd_device
    def set_cd(self,device):
        self.cd_device = os.path.basename(device)
    def get_bootdev(self):
        return self.of_bootdev
    def set_bootdev(self,ofpath):
        self.of_bootdev = ofpath
    def get_hdPath(self):
        return '/dev/' + self.hd_device
    def get_cdPath(self):
        return '/dev/' + self.cd_device
    def get_linuxPart(self):
        return '/dev/' + self.hd_device + linuxpart
    def get_bootPart(self):
        return '/dev/' + self.hd_device + bootpart
    def get_swapPart(self):
        return '/dev/' + self.hd_device + swappart
    def get_imageType(self):
        return self.image_type


class imac(Platform):
    def __init__(self):
        Platform.__init__(self)
        self.name = "imac"
        self.hd_device = "hda"
        self.cd_device = "hdb"
        self.image_type = "imac"

class dvse(Platform):
    def __init__(self):
        Platform.__init__(self)
        self.name = "dvse"
        self.hd_device = "hda"
        self.cd_device = "hdb"
        self.image_type = "dvse"


class g3(Platform):
    def __init__(self):
        Platform.__init__(self)
        self.name = "g3"
        self.hd_device = "hdc"
        self.cd_device = "hda"
        self.image_type = "g3"

class g4(Platform):
    def __init__(self):
        Platform.__init__(self)
        self.name = "g4"
        self.hd_device = "hda"
        self.cd_device = "hdc"
        self.image_type = "g4"

class host(Platform):
    def __init__(self):
        Platform.__init__(self)
        self.name = "host"
        self.hd_device = None
        self.cd_device = None
        self.of_bootdev = None

class test(Platform):
    def __init__(self):
        Platform.__init__(self)
        self.name = "test"
        self.hd_device = "hda"
        self.cd_device = "hdb"
        self.image_type = "test"
        
def aPlatform(name):
    if name == "imac":
        return imac()
    elif name == "dvse":
        return dvse()
    elif name == "g3":
        return g3()
    elif name == "g4":
        return g4()
    elif name == "host":
        return host()
    elif name == "test":
        return test()
    else: 
        errExit(17,'error: unknown platform type ' + name)

def dump_platform(p):
    print 'name      : %s '% p.get_name()
    print 'hd        : %s '% p.get_hd()
    print 'cd        : %s '% p.get_cd()
    print 'of_bootdev: %s '% p.get_bootdev()
    print 

if __name__ == "__main__":
    p = aPlatform("test")
    dump_platform(p)

scripts.py

from globals import *
import os, re

def genFdiskScript(device):
    """create an fdisk script, overwriting any exiting file"""
    global fdiskScript

    # length of target drive
    ## get the hd geometry using hdparm
    cmd = 'hdparm -g ' + device
    r1=re.compile(r'sectors = ([0-9]+)')
    try:
        for line in os.popen(cmd).readlines():
                m = r1.search(line)
                if (m):
                    hdlen = int(m.group(1))
                         hdlen = hdlen - 1
                    break
    except:
        errExit(27,'error: failed to get sector count from ' + device)

    # known values
    mapstart = 1
    maplen   = 63
    bootlen  = 1954
    swaplen  = 1494848

    # calculated values
    bootstart  = mapstart + maplen
    linuxstart = bootstart + bootlen
    linuxlen   = hdlen - (maplen + bootlen + swaplen)
    swapstart  = linuxstart + linuxlen

    cmd_list = ['i\n',
                '\n',
                'p\n',
                'C\n',
                str(bootstart),'\n',
                str(bootlen),'\n',
                'untitled\n',
                'Apple_Bootstrap\n'
                'p\n',
                'c\n',
                str(linuxstart),'\n',
                str(linuxlen),'\n',
                'untitled\n',
                'p\n',
                'c\n',
                str(swapstart),'\n',
                str(swaplen),'\n',
                'untitled\n',
                'p\n',
                'w\n',
                'y\n',
                'q\n'
               ]

    script = open(fdiskScript, 'w')
    script.writelines(cmd_list)
    script.close()
    

def genYbConf(pfm):
    conf = ['## yaboot.conf generated by the Ubuntu installer\n',
            '##\n' ,
            '## run: "man yaboot.conf" for details. Do not make changes until you have!!\n' ,
            '## see also: /usr/share/doc/yaboot/examples for example configurations.\n' ,
            '##\n' ,
            '## For a dual-boot menu, add one or more of:\n' ,
            '## bsd=/dev/hdaX, macos=/dev/hdaY, macosx=/dev/hdaZ\n' ,
            '\n', 
            'boot=' + pfm.get_bootPart() + '\n' ,
            'device=' + pfm.get_bootdev() + '\n' ,
            'partition=3\n' ,
            'root=' + pfm.get_linuxPart() + '\n' ,
            'timeout=50\n' ,
            'install=/usr/lib/yaboot/yaboot\n' ,
            'magicboot=/usr/lib/yaboot/ofboot\n' ,
            'enablecdboot\n' ,
            '\n' ,
            'image=/boot/vmlinux\n' ,
            '        label=Linux\n' ,
            '        read-only\n' ,
            '        initrd=/boot/initrd.img\n' ,
            '        append="quiet splash"\n' ,
             '\n' ,
            'image=/boot/vmlinux.old\n' ,
            '        label=old\n' ,
            '        read-only\n' ,
            '        initrd=/boot/initrd.img.old\n' ,
            '        append="quiet splash"\n'
           ]
    file = open(ybconfFile,'w')
    file.writelines(conf)
    file.close()

def genFstab(pfm, l_uuid, s_uuid):
    fstab = [
            '# /etc/fstab: static file system information.\n',
            '#\n',
            '# <file system> <mount point>   <type>  <options>       <dump>  <pass>\n',
            'proc            /proc           proc    defaults        0       0\n',
            '# ' + pfm.get_linuxPart() + '\n',
            'UUID=' + l_uuid + ' /               ext3    defaults,errors=remount-ro 0       1\n',
            '# ' + pfm.get_swapPart() + '\n',
            'UUID=' + s_uuid + ' none            swap    sw              0       0\n',
            pfm.get_cdPath()  + '        /media/cdrom0   udf,iso9660 user,noauto     0       0\n',
            ]
    file = open(fstabFile,'w')
    file.writelines(fstab)
    file.close()

Desktop Execution

zenity shell script: replicate.sh

To be placed in $HOME/bin (in the local case, /home/oem/bin)

#!/bin/bash
type=$(zenity --width=150 --height=250 --list --radiolist \  
     --title "Select machine type" --column "select"  --column "type" \
     TRUE imac FALSE dvse FALSE g3 FALSE g4)
target=$(zenity --width=150 --height=250 --list --radiolist \  
     --title "Select local target drive" --column   "select"  \
     --column "target device" FALSE hdb TRUE hdd)
cd /home/oem/python
./replicate.py -t $type $target
zenity --width=200 --title "Replicate" --info --text "Replicate: Done"

Desktop Launcher: replicate.desktop

Note that the Exec entry uses /home/oem/bin specifically

[Desktop Entry]
Version=1.0
Encoding=UTF-8
Name=replicate
Type=Application
Terminal=true
Name[en_US]=replicate
Exec=/home/oem/bin/replicate.sh
Comment[en_US]=replicate ppc linux hd
Comment=replicate ppc linux hd
GenericName[en_US]=
Icon=/usr/share/pixmaps/python.xpm