Mac Build Scripts: Python
Revision as of 09: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)