Skip to content

Instantly share code, notes, and snippets.

@bixu
Created August 31, 2010 23:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bixu/559973 to your computer and use it in GitHub Desktop.
Save bixu/559973 to your computer and use it in GitHub Desktop.
#!/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