Difference between revisions of "Mac Build Scripts: Python"
Jump to navigation
Jump to search
(→scripts.py: added try/except protection; needs testing) |
(→replicate.py: various bug fixes) |
||
Line 85: | Line 85: | ||
except: | except: | ||
errExit(9,"error: could not read partition map for verification") | errExit(9,"error: could not read partition map for verification") | ||
− | print 'os.system( | + | print 'os.system(mkfs.ext3 ' + host.get_linuxPart() + ')' |
print 'os.system(mkswap ' + host.get_swapPart() + ')' | print 'os.system(mkswap ' + host.get_swapPart() + ')' | ||
try: | try: | ||
Line 101: | Line 101: | ||
## linux target | ## linux target | ||
mntPath = '/mnt/' + host.get_hd() + linuxpart | mntPath = '/mnt/' + host.get_hd() + linuxpart | ||
− | if os.path.exists(mntPath): | + | 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: | else: | ||
# it does not exist, so create it | # it does not exist, so create it | ||
print 'os.mkdir(' + mntPath + ',0644)' | print 'os.mkdir(' + mntPath + ',0644)' | ||
− | os.mkdir(mntPath,0644) | + | try: |
+ | os.mkdir(mntPath,0644) | ||
+ | except: | ||
+ | errExit(12,'error: cannot create mount point ' + mntPath) | ||
+ | |||
# mount target linux partition | # mount target linux partition | ||
cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart() + ' ' + mntPath | cmd = 'mount -t ext3 -o rw ' + host.get_linuxPart() + ' ' + mntPath | ||
Line 118: | Line 123: | ||
errExit(13,'error: mount target linux partition failed: ' \ | errExit(13,'error: mount target linux partition failed: ' \ | ||
+ host.get_linuxPart() + ' to ' + mntPath) | + host.get_linuxPart() + ' to ' + mntPath) | ||
− | |||
− | |||
## boot target | ## boot target | ||
Line 158: | Line 161: | ||
errExit(17,'error: mount target boot partition failed: ' \ | errExit(17,'error: mount target boot partition failed: ' \ | ||
+ host.get_bootPart() + ' to ' + mntPath) | + host.get_bootPart() + ' to ' + mntPath) | ||
− | + | os.system('umount ' + mntPath) | |
− | |||
# copy the linux partition | # copy the linux partition | ||
Line 171: | Line 173: | ||
errExit(18,'error: mount target linux partition failed: ' \ | errExit(18,'error: mount target linux partition failed: ' \ | ||
+ host.get_linuxPart() + ' to ' + mntPath) | + host.get_linuxPart() + ' to ' + mntPath) | ||
− | + | os.system('umount ' + mntPath) | |
− | |||
def tweakConfigFiles(host,pfm): | def tweakConfigFiles(host,pfm): | ||
Line 189: | Line 190: | ||
print 'os.popen(' + cmd + ')' | print 'os.popen(' + cmd + ')' | ||
try: | try: | ||
− | + | for line in os.popen(cmd).readlines(): | |
− | + | print line | |
− | + | m = r1.search(line) | |
− | + | if (m): | |
− | + | swapuuid = m.group(1) | |
− | + | break | |
except: | except: | ||
errExit(20,'error: failed to get swap partition uuid') | errExit(20,'error: failed to get swap partition uuid') | ||
Line 214: | Line 215: | ||
except: | except: | ||
errExit(23,"error: failed to mount linux partition for config files") | errExit(23,"error: failed to mount linux partition for config files") | ||
− | cmd = 'cp ' + | + | cmd = 'cp ' + ybconfFile + ' ' + mntPath + '/etc/yaboot.conf' |
print 'os.system(' + cmd + ')' | print 'os.system(' + cmd + ')' | ||
try: | try: | ||
Line 220: | Line 221: | ||
except: | except: | ||
errExit(24,"error: failed to copy yaboot.conf") | errExit(24,"error: failed to copy yaboot.conf") | ||
− | cmd = 'cp ' + | + | cmd = 'cp ' + fstabFile + ' ' + mntPath + '/etc/fstab' |
print 'os.system(' + cmd + ')' | print 'os.system(' + cmd + ')' | ||
try: | try: | ||
Line 226: | Line 227: | ||
except: | except: | ||
errExit(25,"error: failed to copy fstab") | errExit(25,"error: failed to copy fstab") | ||
− | cmd = 'mkofboot -b ' + host | + | cmd = 'mkofboot -b ' + host.get_bootPart() \ |
+ ' -o ' + pfm.get_bootdev() + ' -C ' + mntPath \ | + ' -o ' + pfm.get_bootdev() + ' -C ' + mntPath \ | ||
+ '/etc/yaboot.conf ' + '--nonvram' | + '/etc/yaboot.conf ' + '--nonvram' |
Revision as of 16:00, 7 March 2007
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 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 tweakConfigFiles(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") cmd = 'mkofboot -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') 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)
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()