Mac Build Scripts: Python
Now let's try that Linux Disk Replication script in Python.
Disk Replication
replicate.py
#!/usr/bin/python from platform import * from globals import * from scripts import * import sys, getopt, string 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 r = os.popen(cmd) status = r.close() if status is not None: errExit(8,'error: device ' + devPath + ' does not seem to exist') cmd = ('fdisk -l ' + devPath + '| grep ' + devPath + ' | wc -l') nPartitions = map(string.strip, os.popen(cmd).readlines()) if nPartitions: errExit(9,'error: there appear to be existing partitions on ' + 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() genFdiskScript(devPath) cmd = 'fdisk ' + devPath + ' < ' + fdiskScript # os.system(cmd) print 'os.system(' + cmd + ')' # verify partition existence, and create linux filesystem and swap space cmd = 'fdisk -l ' + devPath + ' | grep ' + host.get_linuxPart() \ + ' | wc -l' 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(10, err) # os.system('mkfs3.ext3' + host.get_linuxPart()) # os.system('mkswap' + host.get_swapPart()) print 'os.system(mkfs3.ext3 ' + host.get_linuxPart() + ')' print 'os.system(mkswap ' + host.get_swapPart() + ')' def setupForCopy(host): """ verify/create all the necessary mount points """ ## linux target mntPath = '/mnt/' + host.get_hd() + linuxpart if os.path.exists(mntPath): if not os.path.isdir(mntPath): errExit(18,'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 # os.path.mkdir(mntPath,0644) print 'os.path.mkdir(' + mntPath + ',0644)' # mount target linux partition cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart() + ' ' + mntPath # status = os.system(cmd) print 'os.system(' + cmd + ')' # if (status is not 0): # errExit(12,'error: mount target linux partition failed: ' \ # + host.get_linuxPart() + ' to ' + mntPath) # else: # os.system('umount ' + mntPath) ## boot target mntPath = '/mnt/' + host.get_hd() + swappart if os.path.exists(mntPath): if not os.path.isdir(mntPath): errExit(18,'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 # os.path.mkdir(mntPath,0644) print 'os.path.mkdir(' + mntPath + ',0644)' 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=' + mntPath # os.system(cmd) print 'os.system(' + cmd + ')' # mount/verify target boot partition cmd = 'mount -t hfs ' + host.get_bootPart() + ' ' + mntPath # status = os.system(cmd) print 'os.system(' + cmd + ')' # if (status is not 0): # errExit(12,'error: mount target swap partition failed: ' \ # + host.get_swapPart() + ' to ' + mntPath) # else: # 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 + '/' # status = os.system(cmd) print 'os.system(' + cmd + ')' # if (status is not 0): # errExit(12,'error: mount target linux partition failed: ' \ # + host.get_linuxPart() + ' to ' + mntPath) # else: # os.system('umount ' + mntPath) def tweakConfigFiles(host,pfm): r1=re.compile(r'UUID=([0-9a-fA-F\-]+)') cmd = 'vol_id ' + host.get_linuxPart() + ' | grep -i uuid' print 'os.system(' + cmd + ')' for line in os.popen(cmd).readlines(): m = r1.search(line) if (m): linuxuuid = m.group(1) break cmd = 'vol_id ' + host.get_swapPart() + ' | grep -i uuid' print 'os.system(' + cmd + ')' for line in os.popen(cmd).readlines(): print line m = r1.search(line) if (m): swapuuid = m.group(1) break try: genYbConf(pfm) except: errExit(19,"error: failed to generate yaboot configuration") try: genFstab(pfm,linuxuuid,swapuuid) except: errExit(20,"error: failed to generate fstab") mntPath = '/mnt/' + host.get_hd() + linuxpart cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart() + ' ' + mntPath # status = os.system(cmd) print 'os.system(' + cmd + ')' cmd = 'cp ' + fstabFile + ' ' + mntPath + '/etc/yaboot.conf' # os.system(cmd) print 'os.system(' + cmd + ')' cmd = 'cp ' + ybConfFile + ' ' + mntPath + '/etc/fstab' # os.system(cmd) print 'os.system(' + cmd + ')' cmd = 'mkofboot -b ' + host.get_bootPart() + ' ' + pfm.get_bootPart() \ + ' -o ' + pfm.get_bootdev() + ' -C ' + mntPath \ + '/etc/yaboot.conf ' + '--nonvram' # status = os.system(cmd) print 'os.system(' + cmd + ')' # if (status is not 0): # errExit(15,'error:failed to update boot partition') # else: # os.system('umount ' + mntPath) 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) tweakConfigFiles(h,p) if __name__ == "__main__": main()
globals.py
linuxroot = "/root/rootdir" bootpartimg = "/root/bootpart.img"
platform.py
class Platform: def __init__(self): self.name = "prototype" self.hd_device = "hda" self.cd_device = "hdc" self.of_bootdev = "hd:" 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 = device def get_cd(self): return self.cd_device def set_cd(self,device): self.cd_device = device def get_bootdev(self): return self.of_bootdev def set_cd(self,ofpath): self.of_bootdev = ofpath class imac(Platform): def __init__(self): self.name = "iMac" self.hd_device = "hda" self.cd_device = "hdb" self.of_bootdev = "/pci@f2000000/mac-io@17/ata-4@1f000/disk@0:" class g3(Platform): def __init__(self): self.name = "g3" self.hd_device = "hdc" self.cd_device = "hda" self.of_bootdev = "/pci@80000000/pci-bridge@d/pci-ata@1/@0/disk@0:" class g4(Platform): def __init__(self): self.name = "g4" self.hd_device = "hda" self.cd_device = "hdc" self.of_bootdev = "/pci@f2000000/pci-bridge@d/mac-io@7/ata-4@1f000/disk@0:" class g4q(Platform): def __init__(self): self.name = "g4q" self.hd_device = "hda" self.cd_device = "hdc" self.of_bootdev = "/pci@f2000000/mac-io@17/ata-4@1f000/disk@0:" def aPlatform(name): if name == "imac": return imac() elif name == "g3": return g3() elif name == "g4": return g4() elif name == "g4q": return g4q() else: return Platform() def dump_platform(p): print 'name : %s '% p.get_name().upper() print 'hd : %s '% p.get_hd() print 'cd : %s '% p.get_cd() print 'of_bootdev: %s '% p.get_bootdev() print if __name__ == "__main__": dump_platform(aPlatform("g4")) dump_platform(aPlatform("imac")) dump_platform(aPlatform("g3")) dump_platform(aPlatform("g4q"))