Created
August 31, 2010 23:33
-
-
Save bixu/559973 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
# CDDL HEADER START | |
# | |
# The contents of this file are subject to the terms of the | |
# Common Development and Distribution License (the "License"). | |
# You may not use this file except in compliance with the License. | |
# | |
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
# or http://www.opensolaris.org/os/licensing. | |
# See the License for the specific language governing permissions | |
# and limitations under the License. | |
# | |
# When distributing Covered Code, include this CDDL HEADER in each | |
# file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
# If applicable, add the following below this CDDL HEADER, with the | |
# fields enclosed by brackets "[]" replaced with your own identifying | |
# information: Portions Copyright [yyyy] [name of copyright owner] | |
# | |
# CDDL HEADER END | |
# | |
# | |
# Copyright 2009 Sun Microsystems, Inc. All rights reserved. | |
# Use is subject to license terms. | |
# | |
import sys | |
import os | |
import getopt | |
import subprocess | |
import commands | |
import time | |
import tempfile | |
import string | |
def disk_get_size(disk): | |
command = ['/usr/sbin/fdisk', '-g', '/dev/rdsk/' + disk + 'p0'] | |
try: | |
p = subprocess.Popen(command, stdin=open("/dev/null"), | |
stdout=subprocess.PIPE, stderr=open("/dev/null")) | |
rc = p.wait() | |
if rc != 0: | |
print >> sys.stderr, "ERROR: unable to run fdisk" | |
return None | |
except: | |
print >> sys.stderr, "ERROR: unable to run fdisk" | |
return None | |
output = p.stdout | |
for line in output: | |
list = line.lstrip(" \t").rstrip(" \n\t\r").split() | |
if len(list) < 7: | |
continue | |
try: | |
if list[0] == "*": | |
continue | |
# PCYL NCYL ACYL BCYL NHEAD NSECT SECSIZ | |
# diskSize = NCYL * NHEAD * NSECT * SECSIZ | |
diskSize = int(list[1]) * int(list[4]) * int(list[5]) * int(list[6]) | |
break | |
except: | |
continue | |
return diskSize | |
def disk_get_all(): | |
diskDimensions={} | |
diskList=[] | |
disk=[] | |
command = ['/usr/sbin/format'] | |
try: | |
p = subprocess.Popen(command, stdin=open("/dev/null"), | |
stdout=subprocess.PIPE, stderr=open("/dev/null")) | |
# ignore return value for wait() | |
p.wait() | |
except: | |
print >> sys.stderr, "ERROR: unable to run format" | |
return None | |
output = p.stdout | |
for line in output: | |
list = line.lstrip(" \t").rstrip(" \n\t\r").split(" ") | |
if len(list) < 2: | |
continue | |
try: | |
diskNum = int(list[0].rstrip(".")) | |
except: | |
diskNum = -1 | |
if diskNum != -1: | |
disk = [diskNum, list[1], disk_get_size(list[1])] | |
diskList.append(disk) | |
return diskList | |
def disk_get(): | |
diskList=[] | |
diskList = disk_get_all() | |
if diskList == None: | |
print >> sys.stderr, "ERROR: no disks found" | |
return None | |
waitForSelection = True | |
while waitForSelection: | |
print >> sys.stdout, "Please Select Install Disk\n" | |
print >> sys.stdout, " AVAILABLE DISK SELECTIONS:" | |
for disk in diskList: | |
print >> sys.stdout, "\t" + str(disk[0]) + "." + " /dev/dsk/" + disk[1] + "p0 " + str(disk[2]) + " bytes" | |
selection=raw_input("Specify disk (enter its number or 'q' to quit): ") | |
if selection == "q": | |
print >> sys.stdout, "\n\n" | |
return None | |
try: | |
diskNum = int(selection) | |
except: | |
print >> sys.stdout, "\n ERROR: invalid disk selection\n" | |
continue | |
for disk in diskList: | |
if (diskNum == disk[0]): | |
waitForSelection = False | |
break | |
if waitForSelection: | |
print >> sys.stdout, "\n ERROR: invalid disk selection\n" | |
print >> sys.stdout, "\nNOTE: ALL DATA ON THIS DISK WILL BE DESTROYED.\n" | |
waitForSelection = True | |
while waitForSelection: | |
selection=raw_input("Install on /dev/rdsk/" + disk[1] + "p0 (yes or no): ") | |
if selection == "no": | |
print >> sys.stdout, "\n\n" | |
return None | |
if selection == "yes": | |
waitForSelection = False | |
continue | |
print >> sys.stdout, "\nYou must type is yes or no\n" | |
return disk[1] | |
def disk_get_default_label(disk): | |
command = ['/usr/sbin/fdisk', '-g', '/dev/rdsk/' + disk + 'p0'] | |
try: | |
p = subprocess.Popen(command, stdin=open("/dev/null"), | |
stdout=subprocess.PIPE, stderr=open("/dev/null")) | |
rc = p.wait() | |
if rc != 0: | |
print >> sys.stderr, "ERROR: unable to run fdisk" | |
return None | |
except: | |
print >> sys.stderr, "ERROR: unable to run fdisk" | |
return None | |
output = p.stdout | |
sectorCount = -1 | |
for line in output: | |
list = line.lstrip(" \t").rstrip(" \n\t\r").split() | |
if len(list) < 7: | |
continue | |
try: | |
if list[0] == "*": | |
continue | |
# PCYL NCYL ACYL BCYL NHEAD NSECT SECSIZ | |
sectorsPerCylinder = int(list[5]) * int(list[4]) | |
sectorCount = sectorsPerCylinder * int(list[1]) | |
break | |
except: | |
continue | |
if (sectorCount == -1): | |
print >> sys.stderr, "ERROR: internal error building label" | |
return None | |
label = "0 2 00 " + str(sectorsPerCylinder) + " " + str(sectorCount - sectorsPerCylinder) + " " + str(sectorCount -1) + "\n" + \ | |
"2 5 00 0 " + str(sectorCount) + " " + str(sectorCount -1) + "\n" + \ | |
"8 1 01 0 " + str(sectorsPerCylinder) + " " + str(sectorsPerCylinder - 1) + "\n" | |
return label | |
def disk_fdisk_format(disk): | |
rawDisk = '/dev/rdsk/' + disk + 'p0' | |
command = ['/usr/sbin/fdisk', '-n', '-B', rawDisk] | |
try: | |
p = subprocess.Popen(command, stdin=open("/dev/null"), | |
stdout=open("/dev/null"), stderr=open("/dev/null")) | |
rc = p.wait() | |
if rc != 0: | |
print >> sys.stderr, "ERROR: unable to fdisk" | |
return False | |
except: | |
print >> sys.stderr, "ERROR: unable to fdisk" | |
return False | |
label = disk_get_default_label(disk) | |
if (label == None): | |
return False | |
command = ['/usr/sbin/fmthard', '-s', '-', rawDisk] | |
try: | |
p = subprocess.Popen(command, stdin=subprocess.PIPE, | |
stdout=open("/dev/null"), stderr=open("/dev/null")) | |
p.stdin.write(label) | |
p.stdin.close() | |
rc = p.wait() | |
if rc != 0: | |
print >> sys.stderr, "ERROR: unable to format disk" | |
return False | |
except: | |
print >> sys.stderr, "ERROR: unable to format disk" | |
return False | |
return True | |
def create_zfs_root(disk, swapSize=512, dumpSize=512): | |
diskDev = "/dev/dsk/" + disk + "s0" | |
mountDir = tempfile.mkdtemp() | |
cmdList = [ | |
"/usr/sbin/zpool create -R " + mountDir + " -f rpool " + diskDev, | |
"/usr/sbin/zfs umount rpool", | |
"/usr/sbin/zfs create rpool/ROOT", | |
"/usr/sbin/zfs set mountpoint=legacy rpool/ROOT", \ | |
"/usr/sbin/zfs set canmount=off rpool/ROOT", \ | |
"/usr/sbin/zfs create rpool/ROOT/opensolaris", \ | |
"/usr/sbin/zfs set canmount=noauto rpool/ROOT/opensolaris", \ | |
"/usr/sbin/zfs set mountpoint='/' rpool/ROOT/opensolaris", \ | |
"/usr/sbin/zfs mount rpool/ROOT/opensolaris", \ | |
"/usr/sbin/zfs set mountpoint='/rpool' rpool", \ | |
"/usr/sbin/zfs mount rpool", \ | |
"/usr/sbin/zpool set bootfs='rpool/ROOT/opensolaris' rpool", \ | |
"/usr/sbin/zfs create rpool/export", \ | |
"/usr/sbin/zfs set mountpoint='/export' rpool/export", | |
] | |
if swapSize > 0: | |
cmdList.append("/usr/sbin/zfs create -b 4k -V " + str(swapSize) + "m rpool/swap") | |
if dumpSize > 0: | |
cmdList.append("/usr/sbin/zfs create -b 128k -V " + str(dumpSize) + "m rpool/dump") | |
sys.stdout.write("Configuring ZFS Root:") | |
sys.stdout.flush() | |
for cmd in cmdList: | |
sys.stdout.write(".") | |
sys.stdout.flush() | |
(s, o) = commands.getstatusoutput(cmd) | |
if (s != 0): | |
print >> sys.stderr, "ERROR: Failure in ", cmd | |
return None | |
print >> sys.stdout, " COMPLETE" | |
return mountDir | |
def get_package_list(profile): | |
vagrant_min = [ | |
"entire", | |
"SUNWPython", | |
"SUNWPython-extra", | |
"SUNWTcl", | |
"SUNWTk", | |
"SUNWadmap", | |
"SUNWadmlib-sysid", | |
"SUNWadmr", | |
"SUNWahci", | |
"SUNWarc", | |
"SUNWaudd", | |
"SUNWbash", | |
"SUNWbeadm", | |
"SUNWbind", | |
"SUNWbinutils", | |
"SUNWbip", | |
"SUNWbzip", | |
"SUNWcakr", | |
"SUNWcar", | |
"SUNWckr", | |
"SUNWcnetr", | |
"SUNWcs", | |
"SUNWcsd", | |
"SUNWcsl", | |
"SUNWesu", | |
"SUNWfmd", | |
"SUNWgcc", | |
"SUNWgccruntime", | |
"SUNWgmake", | |
"SUNWgnu-coreutils", | |
"SUNWgrub", | |
"SUNWgss", | |
"SUNWhea", | |
"SUNWinstall", | |
"SUNWinstall-libs", | |
"SUNWintgige", | |
"SUNWipf", | |
"SUNWipkg", | |
"SUNWkey", | |
"SUNWkrb", | |
"SUNWkvm", | |
"SUNWless", | |
"SUNWlexpt", | |
"SUNWlibm", | |
"SUNWlibms", | |
"SUNWlibsasl", | |
"SUNWloc", | |
"SUNWlxml", | |
"SUNWmd", | |
"SUNWmkcd", | |
"SUNWopenssl", | |
"SUNWos86r", | |
"SUNWperl584core", | |
"SUNWpicl", | |
"SUNWpkgcmds", | |
"SUNWpool", | |
"SUNWpr", | |
"SUNWpsdcr", | |
"SUNWpsdir", | |
"SUNWpsdpr", | |
"SUNWpython-cherrypy", | |
"SUNWpython-mako", | |
"SUNWpython-ply", | |
"SUNWpython-pyopenssl", | |
"SUNWpython24-simplejson", | |
"SUNWrcmdc", | |
"SUNWrmodr", | |
"SUNWruby18", | |
"SUNWsmagt", | |
"SUNWsmapi", | |
"SUNWssh", | |
"SUNWsshcu", | |
"SUNWsshd", | |
"SUNWsudo", | |
"SUNWtecla", | |
"SUNWtls", | |
"SUNWtoo", | |
"SUNWuiu8", | |
"SUNWuprl", | |
"SUNWusb", | |
"SUNWusbs", | |
"SUNWvim", | |
"SUNWwbsup", | |
"SUNWwsr2", | |
"SUNWxwrtl", | |
"SUNWzfs", | |
"SUNWzfskr", | |
"SUNWzlib", | |
"SUNWzone", | |
"SUNWcsd", | |
"SUNWcs", | |
"SUNWcar", | |
"SUNWcakr", | |
"SUNWos86r", | |
"SUNWkvm", | |
"SUNWrmodr", | |
"SUNWpsdcr", | |
"SUNWpsdir", | |
"SUNWcnetr", | |
"SUNWesu", | |
"SUNWkey", | |
"SUNWuprl", | |
"SUNWkrb", | |
"SUNWbip", | |
"SUNWzfskr", | |
"SUNWbash", | |
"SUNWipf", | |
"SUNWgrub", | |
"SUNWtoo", | |
"SUNWbind", | |
"SUNWrcmdc", | |
"SUNWmkcd", | |
"SUNWPython", | |
"SUNWPython-extra", | |
"SUNWipkg", | |
"SUNWinstall", | |
"SUNWbeadm", | |
"SUNWadmap", | |
"SUNWadmlib-sysid", | |
"SUNWadmr", | |
"SUNWintgige", | |
"SUNWahci", | |
"SUNWpsdcr", | |
"SUNWpsdpr", | |
"SUNWos86r", | |
"SUNWusb"] | |
xvm_min = [ | |
"entire", | |
"SUNWcsd", | |
"SUNWcs", | |
"SUNWcarx", | |
"SUNWcakrx", | |
"SUNWos86r", | |
"SUNWkvm", | |
"SUNWrmodr", | |
"SUNWpsdcr", | |
"SUNWpsdir", | |
"SUNWcnetr", | |
"SUNWesu", | |
"SUNWkey", | |
"SUNWuprl", | |
"SUNWkrb", | |
"SUNWbip", | |
"SUNWzfskr", | |
"SUNWbash", | |
"SUNWipf", | |
"SUNWgrub", | |
"SUNWtoo", | |
"SUNWbind", | |
"SUNWrcmdc", | |
"SUNWmkcd", | |
"SUNWPython", | |
"SUNWPython-extra", | |
"SUNWipkg", | |
"SUNWinstall", | |
"SUNWbeadm", | |
"SUNWadmap", | |
"SUNWadmlib-sysid", | |
"SUNWadmr"] | |
vbox_min = [ | |
"entire", | |
"SUNWcsd", | |
"SUNWcs", | |
"SUNWcar", | |
"SUNWcakr", | |
"SUNWos86r", | |
"SUNWkvm", | |
"SUNWrmodr", | |
"SUNWpsdcr", | |
"SUNWpsdir", | |
"SUNWcnetr", | |
"SUNWesu", | |
"SUNWkey", | |
"SUNWuprl", | |
"SUNWkrb", | |
"SUNWbip", | |
"SUNWzfskr", | |
"SUNWbash", | |
"SUNWipf", | |
"SUNWgrub", | |
"SUNWtoo", | |
"SUNWbind", | |
"SUNWrcmdc", | |
"SUNWmkcd", | |
"SUNWPython", | |
"SUNWPython-extra", | |
"SUNWipkg", | |
"SUNWinstall", | |
"SUNWbeadm", | |
"SUNWadmap", | |
"SUNWadmlib-sysid", | |
"SUNWadmr", | |
"SUNWintgige", | |
"SUNWahci", | |
"SUNWpsdcr", | |
"SUNWpsdpr", | |
"SUNWos86r", | |
"SUNWusb"] | |
slim = [ | |
"entire", | |
"SUNWcsd", | |
"slim_install"] | |
if profile == "vagrant-guest": | |
return vagrant_min | |
if profile == "xvm-guest": | |
return xvm_min | |
if profile == "vbox-guest": | |
return vbox_min | |
if profile == "slim": | |
return slim | |
return None | |
def install_packages(mountDir, profile="minimal-xvm-guest", repo="http://pkg.opensolaris.org/"): | |
print >> sys.stdout, "Installing packages..." | |
command = ['/bin/pkg', 'image-create', '-f', '-F', '-a', | |
'opensolaris.org=' + repo, mountDir] | |
try: | |
p = subprocess.Popen(command) | |
rc = p.wait() | |
if rc != 0: | |
print >> sys.stderr, "ERROR: unable to setup repo" | |
return None | |
except: | |
print >> sys.stderr, "ERROR: unable to setup repo" | |
return None | |
pkgList = get_package_list(profile) | |
if pkgList == None: | |
print >> sys.stderr, "ERROR: Invalid profile: ", profile | |
return False | |
command = ['/bin/pkg', '-R', mountDir, 'install'] + pkgList | |
try: | |
p = subprocess.Popen(command) | |
rc = p.wait() | |
if rc != 0: | |
print >> sys.stderr, "ERROR: unable to install packages" | |
return None | |
except: | |
print >> sys.stderr, "ERROR: unable to install packages" | |
return None | |
print >> sys.stdout, " COMPLETE" | |
return True | |
def configure_root(mountDir, disk, swap): | |
diskDev = "/dev/rdsk/" + disk + "s0" | |
cmdList = [ | |
"/bin/rm -rf " + mountDir + "/var/pkg/download/*", | |
"/usr/bin/cp " + mountDir + "/lib/svc/seed/global.db " + mountDir + "/etc/svc/repository.db", | |
"/bin/chown root:sys " + mountDir + "/etc/svc/repository.db", | |
"/bin/chmod 600 " + mountDir + "/etc/svc/repository.db", | |
"/usr/sbin/devfsadm -R " + mountDir, | |
"/bin/mkdir -p " + mountDir + "/rpool/boot/grub/bootsign", | |
"/bin/mkdir -p " + mountDir + "/rpool/etc", | |
"/bin/touch " + mountDir + "/rpool/boot/grub/bootsign/pool_rpool", | |
"/bin/cp " + mountDir + "/boot/grub/capability " + mountDir + "/rpool/boot/grub/", | |
"/sbin/installgrub " + mountDir + "/boot/grub/stage1 " + mountDir + "/boot/grub/stage2 " + diskDev, | |
"/bin/touch " + mountDir + "/etc/.UNCONFIGURED", | |
] | |
sys.stdout.write("Configuring OS:") | |
sys.stdout.flush() | |
for cmd in cmdList: | |
sys.stdout.write(".") | |
sys.stdout.flush() | |
(s, o) = commands.getstatusoutput(cmd) | |
if (s != 0): | |
print >> sys.stderr, "ERROR: Failure in ", cmd | |
return False | |
if swap: | |
vfstabSwap = "/dev/zvol/dsk/rpool/swap - - swap - no -" | |
f = open(mountDir + "/etc/vfstab", "a") | |
f.write(vfstabSwap) | |
f.close() | |
f = open(mountDir + "/rpool/etc/bootsign\n", "w") | |
f.write("pool_rpool") | |
f.close() | |
sysid = "/lib/svc/method/sshd\n" +\ | |
"/usr/sbin/sysidkbd\n" +\ | |
"/usr/sbin/sysidpm\n" +\ | |
"/lib/svc/method/net-nwam\n" +\ | |
"/usr/lib/cc-ccr/bin/eraseCCRRepository\n" | |
f = open(mountDir + "/etc/.sysidconfig.apps", "w") | |
f.write(sysid) | |
f.close() | |
grubMenu = "default 0\n\n" +\ | |
"title OpenSolaris 2009.06\n" +\ | |
"findroot (pool_rpool,0,a)\n" +\ | |
"bootfs rpool/ROOT/opensolaris\n" +\ | |
"kernel$ /platform/i86pc/kernel/$ISADIR/unix -B $ZFS-BOOTFS\n" +\ | |
"module$ /platform/i86pc/$ISADIR/boot_archive\n" | |
f = open(mountDir + "/rpool/boot/grub/menu.lst", "w") | |
f.write(grubMenu) | |
f.close() | |
origCwd = os.getcwd() | |
os.chdir(mountDir + "/var/svc/profile/") | |
os.symlink("generic_limited_net.xml", "generic.xml") | |
os.symlink("ns_files.xml", "name_service.xml") | |
os.symlink("inetd_generic.xml", "inetd_services.xml") | |
os.symlink("platform_none.xml", "platform.xml") | |
os.chdir(origCwd) | |
print >> sys.stdout, " COMPLETE" | |
cmdList = [ | |
"/usr/sbin/sys-unconfig -R " + mountDir, | |
"/usr/sbin/bootadm update-archive -R " + mountDir, | |
] | |
sys.stdout.write("Building boot archive:") | |
sys.stdout.flush() | |
for cmd in cmdList: | |
sys.stdout.write(".") | |
sys.stdout.flush() | |
(s, o) = commands.getstatusoutput(cmd) | |
if (s != 0): | |
print >> sys.stderr, "ERROR: Failure in ", cmd | |
return False | |
print >> sys.stdout, " COMPLETE" | |
return True | |
def usage(): | |
print >> sys.stderr, "\nUSAGE:", sys.argv[0], "[--profile=<xvm-guest | vbox-guest | slim>] [--repo=<opensolaris repo, e.g. http://pkg.opensolaris.org/dev>] [--swap=<swap size in MB>] [--dump=<dumpsize in MB>]\n" | |
# | |
# main() | |
# | |
if __name__ == "__main__": | |
# defaults | |
repo="http://pkg.opensolaris.org/" | |
profile="xvm-guest" | |
swapSize = 512 | |
dumpSize = 512 | |
try: | |
opts, args = getopt.getopt(sys.argv[1:], "", | |
["profile=", "swap=", "dump=", "repo="]) | |
for o, a in opts: | |
if o == "--profile": | |
profile = a | |
elif o == "--repo": | |
repo = a | |
elif o == "--swap": | |
swapSize = int(a) | |
elif o == "--dump": | |
dumpSize = int(a) | |
else: | |
print >> sys.stdout, o, a | |
usage() | |
sys.exit(-1) | |
except: | |
usage() | |
sys.exit(-1) | |
print >> sys.stdout, "\nThanks for choosing to install the OpenSolaris OS! Before you start, review\nthe Release Notes for this release for a list of known problems. The release\nnotes can be found at\n http://opensolaris.org/os/project/indiana/resources/relnotes/200906/x86\n" | |
print >> sys.stdout, "****\nNOTICE: THIS INSTALLER ONLY SUPPORTS INSTALLING TO A WHOLE DISK. ALL DATA\nON THE DISK YOU INSTALL TO WILL BE DESTROYED.\n****\n" | |
installDisk = disk_get() | |
if installDisk == None: | |
sys.exit(0) | |
if not disk_fdisk_format(installDisk): | |
sys.exit(-1) | |
mountDir = create_zfs_root(installDisk, swapSize=swapSize, dumpSize=dumpSize) | |
if (mountDir == None): | |
sys.exit(-1) | |
if not install_packages(mountDir, profile, repo): | |
sys.exit(-1) | |
if (swapSize > 0): | |
swap = True | |
else: | |
swap = False | |
if not configure_root(mountDir, installDisk, swap): | |
sys.exit(-1) | |
print >> sys.stdout, "*** INSTALL COMPLETE ***" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment