Skip to content

Instantly share code, notes, and snippets.

@jclulow

jclulow/xx.patch Secret

Created March 14, 2013 03:40
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 jclulow/f43a4911d06a04c4c551 to your computer and use it in GitHub Desktop.
Save jclulow/f43a4911d06a04c4c551 to your computer and use it in GitHub Desktop.
diff --git a/smartdc/bin/smartos_prompt_config.sh b/smartdc/bin/smartos_prompt_config.sh
index c51fa99..be4e641 100644
--- a/smartdc/bin/smartos_prompt_config.sh
+++ b/smartdc/bin/smartos_prompt_config.sh
@@ -6,6 +6,9 @@
PATH=/usr/sbin:/usr/bin
export PATH
+
+. /lib/svc/share/smf_include.sh
+
. /lib/sdc/config.sh
load_sdc_sysinfo
load_sdc_config
@@ -22,6 +25,22 @@ declare -a states
declare -a nics
declare -a assigned
declare -a DISK_LIST
+declare -a DISK_LAYOUT
+declare -a CONSOLE_TYPE
+
+detect_console()
+{
+ local tty=$(tty)
+ local console=$(bootparams | awk -F= '$1 == "console" { print $2 }')
+
+ CONSOLE_TYPE=serial
+ if [[ $tty == "/dev/console" && $console == "text" ]]; then
+ CONSOLE_TYPE=vga
+ elif [[ $tty == "/dev/wscons" ]]; then
+ CONSOLE_TYPE=vga
+ fi
+ export CONSOLE_TYPE
+}
sigexit()
{
@@ -31,6 +50,19 @@ sigexit()
exit 0
}
+fatal()
+{
+ echo
+ if [[ -n "$1" ]]; then
+ echo "ERROR: $1"
+ fi
+ echo
+ echo "System configuration failed."
+ echo "You must reboot to re-run system configuration."
+ echo
+ exit $SMF_EXIT_ERR_FATAL
+}
+
#
# Get the max. IP addr for the given field, based in the netmask.
# That is, if netmask is 255, then its just the input field, otherwise its
@@ -242,7 +274,7 @@ promptpw()
else
break
fi
- else
+ else
echo "A value must be provided."
fi
done
@@ -264,36 +296,118 @@ promptpw()
done
}
+printdisklayout()
+{
+ json -f "$1" | json -e '
+ out = "vdevs:\n";
+ disklist = [];
+ for (var i = 0; i < vdevs.length; i++) {
+ var x = vdevs[i];
+ if (!x.type) {
+ out += " " + x.name + "\n";
+ }
+ if (x.type === "mirror") {
+ out += " " + x.type + " " + x.devices[0].name + " " +
+ x.devices[1].name + "\n";
+ continue;
+ }
+ out += " " + x.type + "\n";
+ var lout = " ";
+ for (var j = 0; j < x.devices.length; j++) {
+ if ((lout + x.devices[j].name).length > 80) {
+ out += lout + "\n";
+ lout = " " + x.devices[j].name + " ";
+ } else {
+ lout += x.devices[j].name + " ";
+ }
+ }
+ out += lout + "\n";
+ }
+ if (spares && spares.length > 0) {
+ out += "spares:\n";
+ var lout = " ";
+ for (var i = 0; i < spares.length; i++) {
+ if ((lout + spares[i].name).length > 80) {
+ out += lout + "\n";
+ lout += " " + spares[i].name + " ";
+ } else {
+ lout += spares[i].name + " ";
+ }
+ }
+ out += lout + "\n";
+ }
+ if (logs && logs.length > 0) {
+ out += "logs:\n";
+ var lout = " ";
+ for (var i = 0; i < logs.length; i++) {
+ if ((lout + logs[i].name).length > 80) {
+ out += lout + "\n";
+ lout += " " + logs[i].name + " ";
+ } else {
+ lout += logs[i].name + " ";
+ }
+ }
+ out += lout + "\n";
+ }
+ out += "total capacity: " + Number(capacity / 1073741824).toFixed(2)
+ + " GB";
+ ' out
+}
+
promptpool()
{
- disks=$(disklist -n)
+ local layout=mirror
+ local disks=
while [[ /usr/bin/true ]]; do
- echo "Please select disks for the storage pool, space separated"
+ diskinfo -Hp > /var/tmp/mydisks
+ disklayout -f /var/tmp/mydisks $layout > /var/tmp/disklayout.json
+ printdisklayout /var/tmp/disklayout.json
echo ""
- printf "Valid choices are ${disks}"
+ echo "This is the '${layout}' storage configuration. To use it, type 'yes'."
+ echo " To see a different configuration, type: 'raidz2' or 'mirror'. "
+ echo " To specify a manual configuration, type: 'manual'."
echo ""
- bad=""
read val
- if [[ $val == "" ]]; then
- echo "At least one disk must be specified"
- echo ""
- continue
- fi
- for disk in $(echo $val | tr " " "\n"); do
- if [[ -z $disk ]]; then continue; fi;
- echo $disks | grep $disk 1>&2 > /dev/null
- if [[ $? != 0 ]]; then
- bad="$disk $bad"
- fi
- done
- if [[ $bad != "" ]]; then
- printf "The disks %s are not valid choices" $bad
- else
- DISK_LIST="$val"
+ if [[ $val == "raidz2" || $val == "mirror" ]]; then
+ # go around again
+ layout=$val
+ elif [[ $val == "yes" ]]; then
+ DISK_LAYOUT=/var/tmp/disklayout.json
+ return
+ elif [[ $val == "manual" ]]; then
+ # let the user specify a list of disks, as we used to do
+ DISK_LAYOUT="manual"
+ disks=$(disklist -n)
+ while [[ /usr/bin/true ]]; do
+ echo ""
+ echo "Please select disks for the storage pool, space separated"
+ echo ""
+ printf "Valid choices are ${disks}"
+ echo ""
+ bad=""
+ read val
+ if [[ $val == "" ]]; then
+ echo "At least one disk must be specified"
+ echo ""
+ continue
+ fi
+ for disk in $(echo $val | tr " " "\n"); do
+ if [[ -z $disk ]]; then continue; fi;
+ echo $disks | grep $disk 1>&2 > /dev/null
+ if [[ $? != 0 ]]; then
+ bad="$disk $bad"
+ fi
+ done
+ if [[ $bad != "" ]]; then
+ printf "The disks %s are not valid choices" $bad
+ else
+ DISK_LIST="$val"
+ return
+ fi
+ done
break
fi
done
-
}
create_dump()
@@ -396,62 +510,75 @@ setup_datasets()
create_zpool()
{
- disks=$1
+ layout=$1
+ disks=$2
pool=zones
# If the pool already exists, don't create it again.
if /usr/sbin/zpool list -H -o name $pool; then
+ printf "%-56s" "Pool '$pool' exists, skipping creation... "
return 0
fi
- disk_count=$(echo "${disks}" | wc -w | tr -d ' ')
printf "%-56s" "Creating pool $pool... "
- # If no pool profile was provided, use a default based on the number of
- # devices in that pool.
- if [[ -z ${profile} ]]; then
- case ${disk_count} in
- 0)
- fatal "no disks found, can't create zpool";;
- 1)
- profile="";;
- 2)
- profile=mirror;;
- *)
- profile=raidz;;
- esac
- fi
-
- zpool_args=""
-
- # When creating a mirrored pool, create a mirrored pair of devices out of
- # every two disks.
- if [[ ${profile} == "mirror" ]]; then
- ii=0
- for disk in ${disks}; do
- if [[ $(( $ii % 2 )) -eq 0 ]]; then
- zpool_args="${zpool_args} ${profile}"
- fi
- zpool_args="${zpool_args} ${disk}"
- ii=$(($ii + 1))
- done
+ if [[ $layout != 'manual' ]]; then
+ # If this is not a manual layout, then we've been given
+ # a JSON file describing the desired pool, so use that:
+ mkzpool -f $pool $layout || \
+ fatal "failed to create pool ${pool}"
else
- zpool_args="${profile} ${disks}"
+ # Otherwise, we have a list of disks to use:
+ disk_count=$(echo "${disks}" | wc -w | tr -d ' ')
+ # If no pool profile was provided, use a default based on the number of
+ # devices in that pool.
+ if [[ -z ${profile} ]]; then
+ case ${disk_count} in
+ 0)
+ fatal "no disks found, can't create zpool";;
+ 1)
+ profile="";;
+ 2)
+ profile=mirror;;
+ *)
+ profile=raidz;;
+ esac
+ fi
+
+ zpool_args=""
+
+ # When creating a mirrored pool, create a mirrored pair of devices out of
+ # every two disks.
+ if [[ ${profile} == "mirror" ]]; then
+ ii=0
+ for disk in ${disks}; do
+ if [[ $(( $ii % 2 )) -eq 0 ]]; then
+ zpool_args="${zpool_args} ${profile}"
+ fi
+ zpool_args="${zpool_args} ${disk}"
+ ii=$(($ii + 1))
+ done
+ else
+ zpool_args="${profile} ${disks}"
+ fi
+
+ zpool create -f ${pool} ${zpool_args} || \
+ fatal "failed to create pool ${pool}"
fi
- zpool create -f ${pool} ${zpool_args} || \
- fatal "failed to create pool ${pool}"
zfs set atime=off ${pool} || \
fatal "failed to set atime=off for pool ${pool}"
printf "%4s\n" "done"
}
+
create_zpools()
{
- devs=$1
+ layout=$1
+ devs=$2
export SYS_ZPOOL="zones"
- create_zpool "$devs"
+ create_zpool "$layout" "$devs"
sleep 5
svccfg -s svc:/system/smartdc/init setprop config/zpool="zones"
@@ -480,22 +607,64 @@ updatenicstates()
done < <(dladm show-phys -po link,state 2>/dev/null)
}
-printheader()
+clear_screen()
{
- local newline=
- local cols=`tput cols`
- local subheader=$1
-
- if [ $cols -gt 80 ] ;then
- newline='\n'
+ if [[ $CONSOLE_TYPE == "vga" ]]; then
+ #
+ # Only clear the screen if we're on a VGA console.
+ #
+ clear
+ else
+ #
+ # Otherwise, it is more helpful to retain output in the scrollback buffer
+ # of the terminal attached to the serial console.
+ #
+ printf "\n\n"
fi
-
- clear
- for i in {1..80} ; do printf "-" ; done && printf "$newline"
- printf " %-40s\n" "SmartOS Setup"
- printf " %-40s%38s\n" "$subheader" "http://wiki.smartos.org/install"
- for i in {1..80} ; do printf "-" ; done && printf "$newline"
+}
+#
+# Print a Horizontal Rule, i.e.
+# ----------------------------------------------
+#
+printhr()
+{
+ local bold=$(tput bold)
+ local reset=$(tput sgr0)
+ local width=$1
+ printf "${bold}"
+ (( i = 0 ))
+ while (( i < $width )); do
+ printf "-"
+ (( i++ ))
+ done
+ printf "${reset}"
+}
+
+printheader()
+{
+ local cols=$(tput cols)
+ local subheader=$1
+ local bold=$(tput bold)
+ local reset=$(tput sgr0)
+
+ clear_screen
+
+ [[ CONSOLE_TYPE == "vga" ]] && tput cup 0 0 || printf "\n"
+ printhr $cols
+
+ [[ CONSOLE_TYPE == "vga" ]] && tput cup 1 0 || printf "\n"
+ printf " ${bold}%-40s${reset}" \
+ "SmartOS Setup"
+
+ [[ CONSOLE_TYPE == "vga" ]] && tput cup 2 0 || printf "\n"
+ printf " ${bold}%-40s${reset}%38s" \
+ "$subheader" "http://wiki.smartos.org/install"
+
+ [[ CONSOLE_TYPE == "vga" ]] && tput cup 3 0 || printf "\n"
+ printhr $cols
+
+ printf "\n"
}
trap sigexit SIGINT
@@ -520,9 +689,23 @@ fi
ifconfig -a plumb
updatenicstates
-export TERM=sun-color
-export TERM=xterm-color
-stty erase ^H
+#
+# Detect the console and set TERM appropriately:
+#
+detect_console
+if [[ $CONSOLE_TYPE == "vga" ]]; then
+ #
+ # Deal with our Most Exotic VGA Console:
+ #
+ export TERM=sun-color
+ stty erase ^H
+else
+ #
+ # Everybody else is probably on a real computer attached via serial:
+ #
+ export TERM=xterm-color
+fi
+stty sane
printheader "Copyright 2011, Joyent, Inc."
@@ -605,14 +788,14 @@ while [ /usr/bin/true ]; do
fi
promptval "Is this correct?" "y"
[ "$val" == "y" ] && break
- clear
+ clear_screen
done
admin_network="$net_a.$net_b.$net_c.$net_d"
#
# Generate config file
#
-tmp_config=/tmp_config
+tmp_config=/tmp/config
touch $tmp_config
chmod 600 $tmp_config
@@ -652,20 +835,25 @@ echo >>$tmp_config
echo
echo "Your configuration is about to be applied."
promptval "Would you like to edit the final configuration file?" "n"
-[ "$val" == "y" ] && vi $tmp_config
-clear
+[[ "$val" == "y" ]] && vi $tmp_config
+clear_screen
echo
echo "Your data pool will be created with the following disks:"
-echo $DISK_LIST
+if [[ $DISK_LAYOUT == "manual" ]]; then
+ echo $DISK_LIST
+else
+ printdisklayout $DISK_LAYOUT
+fi
echo "*********************************************"
echo "* This will erase *ALL DATA* on these disks *"
echo "*********************************************"
promptval "are you sure?" "n"
-[ "$val" == "y" ] && (create_zpools "$DISK_LIST")
+[[ "$val" == "y" ]] && (create_zpools "$DISK_LAYOUT" "$DISK_LIST")
+
+printf "\n\nThe system will now finish configuration and reboot."
+printf "\n\nPlease wait...\n\n"
-clear
-echo "The system will now finish configuration and reboot. Please wait..."
mv $tmp_config /usbkey/config
# set the root password
@@ -674,7 +862,8 @@ sed -e "s|^root:[^\:]*:|root:${root_shadow}:|" /etc/shadow > /usbkey/shadow \
&& chmod 400 /usbkey/shadow
cp -rp /etc/ssh /usbkey/ssh
-cp /usr/img/etc/sources.list.sample /var/db/imgadm/sources.list
+if [[ -f /usr/img/etc/sources.list.sample ]]; then
+ cp /usr/img/etc/sources.list.sample /var/db/imgadm/sources.list
+fi
reboot
-
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment