Mac Build Scripts: Python
Revision as of 10:12, 6 March 2007 by Tonyr (talk | contribs) (→platform.py: update, os action prevented)
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
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 g3(Platform): def __init__(self): Platform.__init__(self) self.name = "g3" self.hd_device = "hdc" self.cd_device = "hda" self.image_type = "gx" class g4(Platform): def __init__(self): Platform.__init__(self) self.name = "g4" self.hd_device = "hda" self.cd_device = "hdc" self.image_type = "gx" class host(Platform): def __init__(self): Platform.__init__(self) self.name = "host" self.hd_device = None self.cd_device = None self.of_bootdev = None def aPlatform(name): if name == "imac": return imac() elif name == "g3": return g3() elif name == "g4": return g4() elif name == "host": return host() 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("g4") dump_platform(p)