diff options
author | An-Cheng Huang <ancheng@vyatta.com> | 2007-10-18 11:16:37 -0700 |
---|---|---|
committer | An-Cheng Huang <ancheng@vyatta.com> | 2007-10-18 11:16:37 -0700 |
commit | c38f1d8ace7ba12d05954ab3374f3bbea6c13d46 (patch) | |
tree | fc4824137889159bb3423a34fd02dbaadb104dc9 | |
download | vyatta-cfg-system-upstream.tar.gz vyatta-cfg-system-upstream.zip |
initial import of systel-level scripts from fairfield/xorp andupstream
ofr-eureka/rl-system.
(this is the "mess-with-your-system-config" package.)
-rw-r--r-- | .gitignore | 19 | ||||
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | COPYING | 27 | ||||
-rw-r--r-- | Makefile.am | 10 | ||||
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | configure.ac | 30 | ||||
-rw-r--r-- | debian/README | 6 | ||||
-rwxr-xr-x | debian/autogen.sh | 37 | ||||
-rw-r--r-- | debian/changelog | 5 | ||||
-rw-r--r-- | debian/compat | 1 | ||||
-rw-r--r-- | debian/control | 22 | ||||
-rw-r--r-- | debian/copyright | 34 | ||||
-rw-r--r-- | debian/docs | 2 | ||||
-rw-r--r-- | debian/linda | 1 | ||||
-rw-r--r-- | debian/lintian | 2 | ||||
-rwxr-xr-x | debian/rules | 101 | ||||
-rwxr-xr-x | scripts/install-system.in | 918 | ||||
-rwxr-xr-x | scripts/progress-indicator | 24 | ||||
-rwxr-xr-x | scripts/quick-install | 907 | ||||
-rwxr-xr-x | scripts/rl-system.init | 349 | ||||
-rwxr-xr-x | scripts/standalone_root_pw_reset | 83 | ||||
-rwxr-xr-x | scripts/vyatta-functions | 44 |
23 files changed, 2625 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ef8441c2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +*~ +.*.swp +/aclocal.m4 +/autom4te.cache +/build-stamp +/ChangeLog +/config +/config.log +/config.guess +/config.status +/config.sub +/configure +/debian/files +/debian/vyatta-cfg-system +/INSTALL +/Makefile.in +/Makefile +/scripts/install-system + diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..ee635b2e --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +eng@vyatta.com diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..1c08bf46 --- /dev/null +++ b/COPYING @@ -0,0 +1,27 @@ +/* + * Package: vyatt-cfg-system + * + * **** License **** + * Version: VPL 1.0 + * + * The contents of this file are subject to the Vyatta Public License + * Version 1.0 ("License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.vyatta.com/vpl + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * This code was originally developed by Vyatta, Inc. + * Portions created by Vyatta are Copyright (C) "YEAR" Vyatta, Inc. + * All Rights Reserved. + * + * Author: eng@vyatta.com + * Date: 2007 + * Description: Vyatta system-level configuration templates/scripts + * + * **** End License **** + * + */ diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..5d3ebe15 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,10 @@ +bin_SCRIPTS = +sbin_SCRIPTS = + +bin_SCRIPTS += scripts/progress-indicator +bin_SCRIPTS += scripts/vyatta-functions +sbin_SCRIPTS += scripts/rl-system.init +sbin_SCRIPTS += scripts/install-system +sbin_SCRIPTS += scripts/quick-install +sbin_SCRIPTS += scripts/standalone_root_pw_reset + @@ -0,0 +1 @@ +see http://www.vyatta.com/news/ @@ -0,0 +1 @@ +This package has the Vyatta system-level configuration templates and scripts. diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000..aca95c7f --- /dev/null +++ b/configure.ac @@ -0,0 +1,30 @@ +# Process this file with autoconf to produce a configure script. +AC_PREREQ(2.59) + +m4_define([VERSION_ID], [m4_esyscmd([ + if test -f .version ; then + head -n 1 .version | tr -d \\n + else + echo -n 2.4 + fi])]) +AC_INIT([vyatta-cfg-system], VERSION_ID, [vyatta-support@vyatta.com]) + +test -n "$VYATTA_VERSION" || VYATTA_VERSION=$PACKAGE_VERSION + +AC_CONFIG_AUX_DIR([config]) +AM_INIT_AUTOMAKE([gnu no-dist-gzip dist-bzip2 subdir-objects]) +AC_PREFIX_DEFAULT([/opt/vyatta]) + +AC_ARG_ENABLE([nostrip], + AC_HELP_STRING([--enable-nostrip], + [include -nostrip option during packaging]), + [NOSTRIP=-nostrip], [NOSTRIP=]) + +AC_CONFIG_FILES( + [Makefile] + [scripts/install-system]) + +AC_SUBST(NOSTRIP) + +AC_OUTPUT + diff --git a/debian/README b/debian/README new file mode 100644 index 00000000..6a03a024 --- /dev/null +++ b/debian/README @@ -0,0 +1,6 @@ +The Debian Package vyatta-cfg-system +---------------------------- + +This package has the Vyatta systel-level configuration templates and scripts. + + -- An-Cheng Huang <ancheng@vyatta.com> Mon, 1 Oct 2007 diff --git a/debian/autogen.sh b/debian/autogen.sh new file mode 100755 index 00000000..ff125d1d --- /dev/null +++ b/debian/autogen.sh @@ -0,0 +1,37 @@ +#!/bin/sh + + +if [ -d .git ] ; then +# generate GNU/Debian format ChangeLog from git log + + rm -f ChangeLog + + if which git2cl >/dev/null ; then + git-log --pretty --numstat --summary | git2cl >> ChangeLog + else + git-log --pretty=short >> ChangeLog + fi + +# append repository reference + + url=` git repo-config --get remote.origin.url` + test "x$url" = "x" && url=`pwd` + + branch=`git-branch --no-color | sed '/^\* /!d; s/^\* //'` + test "x$branch" = "x" && branch=master + + sha=`git log --pretty=oneline --no-color -n 1 | cut -c-8` + test "x$sha" = "x" && sha=00000000 + + echo "$url#$branch-$sha" >> ChangeLog + +fi + +rm -rf config +rm -f aclocal.m4 config.guess config.statusconfig.sub configure INSTALL + +autoreconf --force --install + +rm -f config.sub config.guess +ln -s /usr/share/misc/config.sub . +ln -s /usr/share/misc/config.guess . diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 00000000..3e74860a --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +vyatta-cfg-system (0.1) unstable; urgency=low + + * Initial Release. + + -- An-Cheng Huang <ancheng@vyatta.com> Thu, 18 Oct 2007 11:03:18 -0700 diff --git a/debian/compat b/debian/compat new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 00000000..275ce680 --- /dev/null +++ b/debian/control @@ -0,0 +1,22 @@ +Source: vyatta-cfg-system +Section: contrib/net +Priority: extra +Maintainer: An-Cheng Huang <ancheng@vyatta.com> +Build-Depends: debhelper (>= 5), autotools-dev +Standards-Version: 3.7.2 + +Package: vyatta-cfg-system +Architecture: all +Depends: bash (>= 3.1), + sed (>= 4.1.5), + perl (>= 5.8.8), + procps (>= 1:3.2.7-3), + coreutils (>= 5.97-5.3), + vyatta-cfg +Suggests: util-linux (>= 2.13-5), + net-tools, + ethtool, + ncurses-bin (>= 5.5-5), + ntpdate +Description: Vyatta system-level configuration templates/scripts + Vyatta system-level configuration templates and scripts. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 00000000..8690d57f --- /dev/null +++ b/debian/copyright @@ -0,0 +1,34 @@ +This package was debianized by An-Cheng Huang <ancheng@vyatta.com> on +Thu, 18 Oct 2007 11:03:18 -0700. + +It's original content from the GIT repository <http://vyatt.com/git/vyatta-cfg-system> + +Upstream Author: + + <eng@vyatta.com> + +Copyright: + + Copyright (C) 2007 Vyatta, Inc. + All Rights Reserved. + +License: + + The contents of this package are subject to the Vyatta Public License + Version 1.0 ("License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.vyatta.com/vpl + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + This code was originally developed by Vyatta, Inc. + Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc. + +On Debian systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL'. + +The Debian packaging is (C) 2007, An-Cheng Huang <ancheng@vyatta.com> and +is licensed under the GPL, see above. diff --git a/debian/docs b/debian/docs new file mode 100644 index 00000000..50bd824b --- /dev/null +++ b/debian/docs @@ -0,0 +1,2 @@ +NEWS +README diff --git a/debian/linda b/debian/linda new file mode 100644 index 00000000..0381d9d0 --- /dev/null +++ b/debian/linda @@ -0,0 +1 @@ +Tag: file-in-opt diff --git a/debian/lintian b/debian/lintian new file mode 100644 index 00000000..cf586ff3 --- /dev/null +++ b/debian/lintian @@ -0,0 +1,2 @@ +vyatta-cfg-system: file-in-unusual-dir +vyatta-cfg-system: dir-or-file-in-opt diff --git a/debian/rules b/debian/rules new file mode 100755 index 00000000..7955e31c --- /dev/null +++ b/debian/rules @@ -0,0 +1,101 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +PACKAGE=vyatta-cfg-system +PKGDIR=$(CURDIR)/debian/$(PACKAGE) + +CFLAGS = -Wall -g + +configure = ./configure +configure += --host=$(DEB_HOST_GNU_TYPE) +configure += --build=$(DEB_BUILD_GNU_TYPE) +configure += --prefix=/opt/vyatta +configure += --mandir=\$${prefix}/share/man +configure += --infodir=\$${prefix}/share/info +configure += CFLAGS="$(CFLAGS)" +configure += LDFLAGS="-Wl,-z,defs" + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +configure: configure.ac Makefile.am + chmod +x debian/autogen.sh + debian/autogen.sh + +config.status: configure + dh_testdir + rm -f config.cache + $(configure) + +build: build-stamp + +build-stamp: config.status + dh_testdir + $(MAKE) + touch $@ + +clean: clean-patched + +# Clean everything up, including everything auto-generated +# at build time that needs not to be kept around in the Debian diff +clean-patched: + dh_testdir + dh_testroot + if test -f Makefile ; then $(MAKE) clean distclean ; fi + rm -f build-stamp + rm -f config.status config.sub config.guess config.log + rm -f aclocal.m4 configure Makefile.in Makefile INSTALL + rm -rf config + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + $(MAKE) DESTDIR=$(PKGDIR) install + + install -D --mode=0644 debian/lintian $(PKGDIR)/usr/share/lintian/overrides/$(PACKAGE) + install -D --mode=0644 debian/linda $(PKGDIR)/usr/share/linda/overrides/$(PACKAGE) + +# Build architecture-independent files here. +binary-indep: build install + dh_testdir + dh_testroot + dh_installchangelogs ChangeLog + dh_installdocs + dh_install + dh_installdebconf + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +# Build architecture-dependent files here. +binary-arch: build install +# This is an architecture independent package +# so; we have nothing to do by default. + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/scripts/install-system.in b/scripts/install-system.in new file mode 100755 index 00000000..84a69649 --- /dev/null +++ b/scripts/install-system.in @@ -0,0 +1,918 @@ +#!/bin/sh +# +# Module: install-system +# +# **** License **** +# Version: VPL 1.0 +# +# The contents of this file are subject to the Vyatta Public License +# Version 1.0 ("License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.vyatta.com/vpl +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc. +# All Rights Reserved. +# +# Author: Robert Bays +# Date: 2006 +# Description: +# +# **** End License **** +# +# Vyatta system installer script. +# +# +# If you set VYATTA_AUTO_INSTALL I will try to do an automated install for you + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +sbindir=@sbindir@ +sysconfdir=@sysconfdir@ +ofrconfdir=$sysconfdir/config +fdconfdir=/media/floppy/config +rootfsdir=/mnt/rootfs + +# install log file name +INSTALL_LOG="install.log" +# root partition minimum size in MB +ROOT_MIN="450" +# config partition minium size in MB +CONFIG_MIN="10" +# the base install drive e.g. sda +if [ -n "$INSTALL_DRIVE" ]; then + INSTALL_DRIVE="" +fi +# the install partition e.g. sda1 +if [ -n "$ROOT_PARTITION" ]; then + ROOT_PARTITION="" +fi +# the config partition e.g. sda2 +if [ -n "$CONFIG_PARTITION" ]; then + CONFIG_PARTITION="" +fi +# the size of the root partition +if [ -n "$ROOT_PARTITION_SIZE" ]; then + ROOT_PARTITION_SIZE="" +fi +# the size of the config partition +if [ -n "$CONFIG_PARTITION_SIZE" ]; then + CONFIG_PARTITION_SIZE="" +fi +# global holding variable used in the select_partition sub +PARTITION='' + +# Process ID of this script for the lame marketing spinner +SPID=$$ + +# Path to standalone root password reset script +PWRESET=/opt/vyatta/sbin/standalone_root_pw_reset + +# trap signals so we can kill runaway progress indicators +trap 'progress_indicator "stop"; exit 1' 1 +trap 'progress_indicator "stop"; exit 1' 2 + +# turn off any mounted swap partitions +turnoffswap () { + if [ -f "/proc/swaps" ]; then + myresponse=$(cat /proc/swaps) + if [ -n "$myresponse" ]; then + echo "turning off swaps..." >> $INSTALL_LOG + swapoff -a + fi + fi +} + +# Validates a user response. Returns the response if valid. +# Returns the default is the user just hits enter. +# Returns nothing if not valid. Default parameter is $1. +# Options are in $2. If options are defined return must be a member +# of the enum. +get_response () { + ldefault=$(echo "$1" | tr [:upper:] [:lower:]) + loptions=$(echo "$2" | tr [:upper:] [:lower:]) + + # get the response from the user + read myresponse + myresponse=$(echo "$myresponse" | awk '{ printf (tolower($0)) }') + + # Check to see if the user accepts the default + if [ -z "$myresponse" ]; then + echo -n $ldefault + # if we are passing in options to check, make sure response is a valid option + elif [ -n "$loptions" ]; then + for token in $loptions + do + if [ "$token" == "$myresponse" ]; then + echo -n "$myresponse" + return 0 + fi + done + return 1 + else + echo -n "$myresponse" + fi + + return 0 +} + +# Return the size of the drive in MB +get_drive_size () { + ldrive=$1 + + # Make sure you can print disk info using parted + parted /dev/$ldrive p >/dev/null 2>&1 + + # If unable to read disk, it's likely it needs a disklabel + if [ "$?" != "0" ]; then + echo "Creating a new disklabel on $ldrive" >> $INSTALL_LOG + echo "parted /dev/$ldrive mklabel msdos" >> $INSTALL_LOG + output=$(parted /dev/$ldrive mklabel msdos) + + # Get the drive size from parted + lsize=$(parted /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }') + + if [ $(echo $lsize | grep error) ]; then + echo "Unable to read disk label. Exiting." + exit 1 + fi + fi + + # Get the drive size from parted + lsize=$(parted /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }') + # Get the reported units (mB, GB, kB) + lmodifier=$(echo $lsize | sed 's/[0-9\.]//g') + # remove the modifier + lsize=$(echo $lsize | sed 's/[a-z,A-Z]//g') + # Remove any fractions + lsize=$(echo $lsize | cut -f1 -d'.') + # Translate our size into mB if not there already + if [ $lmodifier = "GB" ]; then + lsize=$(($lsize * 1000)) + elif [ $lmodifier = "kB" ]; then + lsize=$(($lsize / 1000)) + fi + + echo $lsize +} + +# Probe hardrives not shown in /proc/partitions by default +probe_drives () { + # find IDE drives. Not all drives show up in /proc/partitions for + # some reason. + # TODO: not sure we have to do this for anything but compact flash + # when we test on other platforms, we will find out and modify this section + # as appropriate + drive=$(find /proc/ide/ide* -name "hd*" 2>/dev/null | /usr/bin/awk -F"/" '{ print $5 }') + + # now exclude all drives but disks + for drive in $drive + do + media=$(cat /proc/ide/$drive/media) + if [ "$media" = "disk" ]; then + output=$(mount | grep $drive) + if [ -z "$output" ]; then + output=$(parted /dev/$DRIVE p) + fi + fi + done +} + +# Takes an argument to display text before choice +# Sets INSTALL_DRIVE. Note that select_drive should be wrapped +# in the verification loop, not the included get_response. +select_drive () { + # list the drives in /proc/partitions. Remove partitions and empty lines. + drives=$(cat /proc/partitions | awk '{ if ($4!="name") { print $4 } }' | egrep -v "[0-9]$" | egrep -v "^$") + + # take the first drive as the default + INSTALL_DRIVE=$(echo $drives | /usr/bin/awk '{ print $1 }') + + # Add the drive sizes to the display to help the user decide + display='' + for drive in $drives + do + size=$(get_drive_size $drive) + display="$display $drive\t$size"MB"\n" + done + + # Display the drives and ask the user which one to install to + echo -e "$display" + echo + echo -n "$1 [$INSTALL_DRIVE]:" + + INSTALL_DRIVE=$(get_response "$INSTALL_DRIVE" "$drives") + echo + + # Assume no dma if the disk is smaller than 10G (such as a CF drive) + size=$(get_drive_size $INSTALL_DRIVE) + if [ $size -lt 11000 ] + then + ISCF="ide=nodma" + fi +} + +# Allow the user to select a partition to work with +# sets the global PARTITION +# $1 is the text to display before prompt +select_partition () { + minsize=$1 + text=$2 + + echo -n "Looking for appropriate partitions: " + progress_indicator "start" + + # initialize out global var. using globals in this way is bad form. I know. + PARTITION='' + + # list only the partitions in /proc/partitions. + parts=$(cat /proc/partitions | awk '{ if ($4!="name") { print $4 " "} }' | egrep "[0-9]" | egrep -v "loop" | tr -d '\n') + + # Get the partition sizes for display + # only show partitions that have sizes, i.e. remove loops + display='' + for part in $parts + do + lsize=$(get_drive_size $part) + if [ "$lsize" -a $lsize -ge $minsize ]; then + display="$display $part\t\t$lsize"MB"\n" + fi + done + + progress_indicator "stop" + echo "OK" + + if [ -n "$parts" ]; then + lpartition='' + while [ -z "$lpartition" ] + do + # take the first partition as the default + lpartition=$(echo $parts | /usr/bin/awk '{ print $1 }') + + echo "I found the following partitions suitable for the Vyatta image:" + echo -e "Partition\tSize" + echo -e "$display" + echo + echo -n "$text [$lpartition]: " + + lpartition=$(get_response "$lpartition" "$parts") + echo + done + else + echo "No suitable partition sizes found. Exiting..." | tee $INSTALL_LOG + exit 1 + fi + PARTITION=$lpartition +} + +# Delete all existing partitions for an automated install +# $1 is the drive to delete partitions from +delete_partitions () { + ldrive=$1 + + # get the partitions on the drive + partitions=$(cat /proc/partitions | grep $ldrive[0-9] | awk '{ print $4 }' | sed 's/[a-z]//g') + + # now for each part, blow it away + for part in $partitions + do + # Look to see if this is a config partition + mkdir -p /mnt/tmp + output=$(mount /dev/$ldrive$part /mnt/tmp 2>&1) + if [ $? != 0 ]; then + echo -e "Cannot mount /dev/$ldrive$part"."\nPlease see $INSTALL_LOG for more details.\nExiting.." + echo -e "Cannot mount /dev/$ldrive$part"."\nmount /dev/$ldrive$part /mnt/tmp\nExiting..." >> $INSTALL_LOG + echo "$output" >> $INSTALL_LOG + exit 1 + fi + + # Look to see if the old config marker file is there. + if [ -f /mnt/tmp/.vyatta_config ]; then + response='' + while [ -z "$response" ] + do + echo "/dev/$ldrive$part is a config partition!" + echo -ne "Would you like me to save the data on it\nbefore I delete it? (Yes/No) [Yes]: " + response=$(get_response "Yes" "Yes No Y N") + if [ "$response" == "yes" ] || [ "$response" == "y" ]; then + mkdir -p /mnt/config + output=$(cp -pR /mnt/tmp/* /mnt/config) + if [ -n "$output" ]; then + echo -e "Warning: error in copying the old config partition.\nSee $INSTALL_LOG for more details." + echo -e "Warning: error in copying the old config partition.\ncp -pR /mnt/tmp/* /mnt/config\n$output\n" >> $INSTALL_LOG + fi + fi + done + fi + umount /mnt/tmp + + echo "Removing partition $part on /dev/$ldrive" >> $INSTALL_LOG + output=$(parted /dev/$ldrive rm $part) + status=$? + if [ "$status" != 0 ]; then + echo -e "Warning: cannot delete partition $part on $ldrive.\nPlease see $INSTALL_LOG for more details." + echo -e "Warning: cannot delete partition $part on $ldrive.\nparted /dev/$ldrive rm $part\n$output" >> $INSTALL_LOG + fi + + # We add a bogus sleep here because the loop needs to wait for udev + sleep 5 + done +} + +# make a filesystem on the drive +# $1 is the drive to format +make_filesystem () { + ldrive=$1 + + echo -n "Creating filesystem on /dev/$ldrive: " + echo "Creating filesystem on /dev/$ldrive..." >> $INSTALL_LOG + + progress_indicator "start" + output=$(mke2fs -j /dev/$ldrive 2>&1) + status=$? + if [ "$status" != 0 ]; then + echo -e "Error: couldn't create the root filesystem.\nSee $INSTALL_LOG for further details.\nExiting..." + echo -e "Error: couldn't create the root filesystem.\n/sbin/mke2fs -j /dev/$lDRIVE\n$output" + exit 1 + fi + progress_indicator "stop" + echo "OK" +} + +# create the root partition +# $1 is the install drive e.g. sda +# $2 is the partition size e.g. 512 +# $3 config partition size e.g. 100 +# This will set the globals ROOT_PARTITION and CONFIG_PARTITION +create_partitions() { + ldrive=$1 + root_part_size=$2 + config_part_size=$3 + + total=$(($root_part_size + $config_part_size)) + head=$(($root_part_size)) + tail=$(($root_part_size + $config_part_size)) + + # Make sure there is enough space on drive + size=$(get_drive_size "$ldrive") + if [ "$total" -gt "$size" ]; then + echo "Error: $ldrive is only $size"MB" large." + exit 1 + fi + + echo "Creating root partition on /dev/$ldrive" >> $INSTALL_LOG + + # make the root partition + output=$(parted /dev/$ldrive mkpart primary 0 $root_part_size) + status=$? + if [ "$status" != 0 ]; then + echo -e "Error creating primary partition on $ldrive.\nPlease see $INSTALL_LOG for more details.\nExiting..." + echo -e "Error creating primary partition on $ldrive.\nparted /dev/$ldrive mkpart primary 0 $root_part_size\n$output" >> $INSTALL_LOG + exit 1 + fi + + ROOT_PARTITION=$ldrive"1" + # udev takes time to re-add the device file, so wait for it + while [ ! -b "/dev/$ROOT_PARTITION" ] + do + sleep 1 + done + + echo "Creating configuration partition on /dev/$ldrive" >> $INSTALL_LOG + echo "parted /dev/$ldrive mkpart primary $root_part_size $config_part_size" >> $INSTALL_LOG + + output=$(parted /dev/$ldrive mkpart primary $head $tail) + status=$? + if [ "$status" != 0 ]; then + echo -e "Error creating primary partition on $ldrive.\nPlease see $INSTALL_LOG for more details.\nExiting..." + echo -e "Error creating primary partition on $ldrive.\nparted /dev/$ldrive mkpart primary $root_part_size $config_part_size\n$output" + exit 1 + fi + + CONFIG_PARTITION=$ldrive"2" + # udev takes time to re-add the device file, so wait for it + while [ ! -b "/dev/$CONFIG_PARTITION" ] + do + sleep 1 + done + + # make the root and config ext3 file systems. + make_filesystem "$ROOT_PARTITION" + make_filesystem "$CONFIG_PARTITION" +} + +# Install the root filesystem +# $1 is the partition to install on +install_root_filesystem () { + ldrive=$1 + + dpkg="/usr/bin/dpkg --force-all --root=$rootfsdir" + echo "Mounting /dev/$ldrive " + echo "Mounting /dev/$ldrive..." >> $INSTALL_LOG + + # make the mount point + output=$(/bin/mkdir -p $rootfsdir) + + # mount the partition + output=$(mount -t ext3 /dev/$ldrive $rootfsdir) + status=$? + + if [ "$status" != 0 ]; then + echo -e "Error trying to mount the new root partition.\nPlease see $INSTALL_LOG for details.\nExiting..." + echo -e "Error trying to mount the new root partition.\nmount -t ext3 /dev/$ldrive $rootfsdir\n$output" >> $INSTALL_LOG + exit 1 + fi + + echo -n "Copying system image files to /dev/$ROOT_PARTITION: " + progress_indicator "start" + # Mount the squashfs for copying + output=$(mkdir -p /mnt/squashfs) + output=$(mount /live_media/casper/filesystem.squashfs /mnt/squashfs -t squashfs -o loop) + status=$? + + if [ "$status" != 0 ]; then + echo -e "Error trying to mount the squashfs.\nPlease see install log for more details.\nExiting..." + echo -e "Error trying to mount the squashfs.\nmount /live_media/casper/filesystem.squashfs /mnt/squashfs -t squashfs -o loop\n$output" >> $INSTALL_LOG + exit 1 + fi + + output=$(cp -pR /mnt/squashfs/* $rootfsdir/) + status=$? + + if [ "$status" != 0 ]; then + echo -e "Error trying to copy the rootfs.\nPlease see install log for more details.\nExiting. +.." + echo -e "Error trying to copy the rootfs.\ncp -pR /mnt/squashfs/* $rootfsdir/\n$output" >> $INSTALL_LOG + exit 1 + fi + + # unmount the squashfs. No big deal if it fails. + output=$(umount /mnt/squashfs) + + # make the dir for the boot files and copy em' over + mkdir -p $rootfsdir/boot + output=$(cp -pR /boot/* $rootfsdir/boot/) + status=$? + output+=$(cp /live_media/boot/initrd.img $rootfsdir/boot/) + status=$status || $? + if [ "$status" != 0 ]; then + echo -e "Error trying to copy the bootfiles.\nPlease see install log for more details.\nExiting. +.." + echo -e "Error trying to copy the bootfiles.\ncp /live_media/boot/initrd.img $rootfsdir/boot/\n$output" >> $INSTALL_LOG + exit 1 + fi + + # create the fstab + echo -e "/dev/$CONFIG_PARTITION\t$ofrconfdir\text3\tdefaults\t1 2" >> $rootfsdir/etc/fstab + echo -e "/dev/$ROOT_PARTITION\t/\text3\tdefaults\t0 1" >> $rootfsdir/etc/fstab + progress_indicator "stop" + echo "OK" +} + +# copy the configuration to the config partition +# $1 is the config partition device +copy_config () { + config_partition=$1 + lerror='' + config_default=$sysconfdir/config.boot.default + tmp_config_default=/tmp/${sysconfdir//\//__} + + # Copy the config.boot.default to tmp + output=$(cp $config_default $tmp_config_default) + + # create the config directory on the union file system + output=$(mount -t ext3 /dev/$config_partition $rootfsdir$ofrconfdir) + status=$? + + if [ "$status" != 0 ]; then + echo -e "Error trying to mount the new config partition.\nPlease see $INSTALL_LOG for details.\nExiting..." + echo -e "Error trying to mount the new config partition.\nmount -t ext3 /dev/$config_partition $rootfsdir$ofrconfdir\n$output" >> $INSTALL_LOG + exit 1 + fi + + # create the proper perms on the new config partition + chgrp xorp $rootfsdir$ofrconfdir + chmod 775 $rootfsdir$ofrconfdir + + # Copy /tmp/config.boot.default to new config partition + cp $tmp_config_default $rootfsdir$config_default + rm -f $tmp_config_default + + # create our config partition marker + touch $rootfsdir$ofrconfdir/.vyatta_config + + if [ -d /mnt/config ]; then + echo "Copying old configurations to config partition." + cp -pR /mnt/config/* $rootfsdir$ofrconfdir + else + # Find the config files and give the user the option to copy config files + # TODO: this needs cleaned up + if [ -f $ofrconfdir/config.boot ]; then + config=$ofrconfdir/config.boot + fi + if [ -f $fdconfdir/config.boot ]; then + if [ -z "$config" ]; then + config="$fdconfdir/config.boot" + else + config="$config\n$fdconfdir/config.boot" + fi + fi + + if [ -n "$config" ]; then + echo "I found the following configuration files" + echo -e "$config" + default=$(echo -e $config| head -1) + + resp='' + while [ -z "$configfile" ] + do + echo -n "Which one should I copy to $INSTALL_DRIVE? [$default]: " + configfile=$(get_response "$default" "$config") + done + + echo + output=$(cp $configfile $rootfsdir$ofrconfdir) + if [ -n "$output" ]; then + echo "Error copying file $configfile to config directory. Exiting..." >> $INSTALL_LOG + exit 1 + fi + fi + fi + + # set the permissions on the new config file + if [ -f $rootfsdir$ofrconfdir/config.boot ]; then + chgrp xorp $rootfsdir$ofrconfdir/config.boot + chmod 775 $rootfsdir$ofrconfdir/config.boot + fi +} + +# setup grub on thje boot sector of a user queried drive +install_grub () { + orig_install_drive="$INSTALL_DRIVE" + # we now use INSTALL_DRIVE to reference the grub boot drive. + # that way I can re-use select_drive. I'm lazy that way. + INSTALL_DRIVE='' + + mkdir -p $rootfsdir/boot/grub + # Let the user choose the boot sector + + while [ -z "$INSTALL_DRIVE" ] + do + echo "I need to install the GRUB bootloader." + echo "I found the following drives on your system:" + select_drive "Which drive should GRUB modify the boot partition on?" + done + + echo -n "Setting up grub: " + echo "Setting up grub..." >> $INSTALL_LOG + + # Install grub in the boot sector of the primary drive + progress_indicator "start" + grub-install --no-floppy --root-directory=$rootfsdir /dev/$INSTALL_DRIVE >>$INSTALL_LOG 2>&1 + progress_indicator "stop" + + # TODO: This needs to be changed to map to the correct drive + part=$(echo $ROOT_PARTITION | sed 's/[^0-9]//g') + part=$(($part - 1)) + if [ "$(cat /sys/block/$orig_install_drive/removable)" == 0 ]; then + root=$(grep $orig_install_drive $rootfsdir/boot/grub/device.map | /usr/bin/awk -F')' '{ print $1 }') + root="$root,$part)" + else + echo "This looks like a removable device. Setting root grub device to (0,0)." + echo "This looks like a removable device. Setting root grub device to (0,0)." >> $INSTALL_LOG + root="(hd0,$part)" + fi + + # create the menu.lst file for grub + grub_file="$rootfsdir/boot/grub/menu.lst" + echo -e "default=0\ntimeout=5\n#splashimage=(hd0,0)/grub/splash.xpm.gz\nhiddenmenu" > $grub_file + # set serial console options + echo -e "serial --unit=0 --speed=9600\nterminal --timeout=5 console serial\n\n" >> $grub_file + # set primary boot option + echo -e "title Vyatta OFR\n\troot $root" >> $grub_file + echo -en "\tkernel /boot/vmlinuz root=/dev/$ROOT_PARTITION $ISCF console=ttyS0,9600 console=tty0 \n" >> $grub_file + echo -e "\tinitrd /boot/initrd.img" >> $grub_file + + # Set root password reset option + echo >> $grub_file + echo -e "title Root password reset to factory (serial console)" >> $grub_file + echo -e "\troot $root" >> $grub_file + echo -e "\tkernel /boot/vmlinuz root=/dev/$ROOT_PARTITION $ISCF console=ttyS0,9600 init=$PWRESET" >> $grub_file + echo -e "\tinitrd /boot/initrd.img" >> $grub_file + + echo "OK" +} + +# ask for user input on the parted and skip setup methods +# $1 is whether or not to run parted +# sets globals INSTALL_DRIVE, ROOT_PARTITION, CONFIG_PARTITION +setup_method_manual() { + parted=$1 + + echo "The Vyatta install needs a minimum $ROOT_MIN"MB" root" + echo "and a minimum $CONFIG_MIN"MB" config partition. These" + echo "partitions need to be set to partiton type 83 (Linux)." + echo -e "\n\n" + + # if this is parted, let the user create the partitions + if [ "$method" == "parted" ] || [ "$method" == "p" ]; then + while [ -z "$INSTALL_DRIVE" ] + do + # TODO: right now we only run parted on a single drive + echo -e "\nI found the following drives on your system:" + select_drive "Which drive would you like to run parted on?" + + done + + # Unmount the install drive if it is mounted + unmount "$INSTALL_DRIVE" + + # Run parted and let the user configure + parted /dev/$INSTALL_DRIVE + fi + + # Ask for the root partition and make sure it's valid + while [ -z "$ROOT_PARTITION" ] + do + select_partition 500 "Which partition should I install the root on?" + # Note that PARTITION is defined in select partition + ROOT_PARTITION=$PARTITION + unmount "$ROOT_PARTITION" + vd=$(grep $ROOT_PARTITION /proc/partitions | awk '{ print $4 }') + + if [ -z "$vd" ]; then + echo + echo "$ROOT_PARTITION is an invalid partition. Please try again." + ROOT_PARTITION="" + fi + done + + # Ask for the config partition and make sure it's valid + # TODO: need to do better error checking here to insure + # the user doesn't select the same part for both drives. + while [ -z "$CONFIG_PARTITION" ] + do + while true + do + select_partition 5 "Which partition should I use for configurations?" + # Note that PARTITION is defined in select partition + if [ "$PARTITION" != "$ROOT_PARTITION" ] + then + break + fi + echo "The config partition cannot be the same as the root partition ($ROOT_PARTITION)!" + echo + done + + CONFIG_PARTITION=$PARTITION + unmount "$CONFIG_PARTITION" + vd=$(grep $CONFIG_PARTITION /proc/partitions | awk '{ print $4 }') + + if [ -z "$vd" ]; then + echo + echo "$CONFIG_PARTITION is an invalid partition. Please try again." + CONFIG_PARTITION="" + fi + done + + # create the ext3 fs on the part + make_filesystem "$ROOT_PARTITION" + + # Create the ext3 fs on the part + make_filesystem $CONFIG_PARTITION + + # We need to set the INSTALL_DRIVE if it wasn't set when the user ran parted + # We assume that we will use the boot sector of the same drive that the partition is on + # TODO: Allow different drives to function as the boot device + if [ -z "INSTALL_DRIVE" ]; then + INSTALL_DRIVE=$(echo $ROOT_PARTITION | sed 's/[0-9]//g') + fi +} + +# Walk the user through the auto setup method +# sets globals INSTALL_DRIVE, ROOT_PARTITION, CONFIG_PARTITION +setup_method_auto() { + while [ -z "$INSTALL_DRIVE" ] + do + echo "I found the following drives on your system:" + select_drive "Install the image on?" + + # check to make sure the drive is large enough to hold the image + if [ -n "$INSTALL_DRIVE" ]; then + lsize=$(get_drive_size "$INSTALL_DRIVE") + total=$(($ROOT_MIN + $CONFIG_MIN)) + if [ "$total" -gt "$lsize" ]; then + echo "Unfortunately, the OFR requires a total of at least $total"MB" to properly install." + echo "$INSTALL_DRIVE is below the minimum required capacity and therefore, cannot be used to" + echo -e "complete the installation.\n" + echo "If other drives are present" + echo -e "Please select another drive...\n" + + INSTALL_DRIVE='' + fi + fi + done + + # Give the user a requisite warning that we are about to nuke their drive + response='' + while [ -z $response ] + do + echo "This will destroy all data on /dev/$INSTALL_DRIVE." + echo -n "Continue? (Yes/No) [No]: " + response=$(get_response "No" "Yes No Y N") + + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo "Ok then. Exiting..." + exit 1 + fi + done + + echo + + # make sure we aren't working on a mounted part + unmount "$INSTALL_DRIVE" + + # remove any existing partitions on that drive + delete_partitions "$INSTALL_DRIVE" + + # Enforce minimum partion size requirement. + ROOT_PARTITION_SIZE=0 + while [ $ROOT_MIN -gt $ROOT_PARTITION_SIZE ]; do + # Get the size of the drive + size=$(get_drive_size $INSTALL_DRIVE) + # Subtract our minimum config part so the user doesn't fill the entire drive + size=$(($size - $CONFIG_MIN)) + echo -n "How big of a root partition should I create? ($ROOT_MIN"MB" - $size"MB") [$size]MB: " + response=$(get_response "$size") + # TODO: need to have better error checking on this value + ROOT_PARTITION_SIZE=$(echo "$response" | sed 's/[^0-9]//g') + if [ $ROOT_PARTITION_SIZE -lt $ROOT_MIN ] || [ $ROOT_PARTITION_SIZE -gt $size ]; then + echo "Root partion must be between $ROOT_MIN"MB" and $size"MB"" + echo + ROOT_PARTITION_SIZE=0 + fi + done + + # Enforce minimum partion size requirement. + CONFIG_PARTITION_SIZE=0 + while [ $CONFIG_MIN -gt $CONFIG_PARTITION_SIZE ]; do + # Get the size of the drive + size=$(get_drive_size $INSTALL_DRIVE) + # Subtract our minimum config part so the user doesn't fill the entire drive + size=$(($size - $ROOT_PARTITION_SIZE)) + echo -n "How big of a config partition should I create? ($CONFIG_MIN"MB" - $size"MB") [$CONFIG_MIN]MB: " + response=$(get_response "$CONFIG_MIN") + CONFIG_PARTITION_SIZE=$(echo "$response" | sed 's/[^0-9]//g') + if [ $CONFIG_PARTITION_SIZE -lt $CONFIG_MIN ] || [ $CONFIG_PARTITION_SIZE -gt $size ]; then + echo "Config partion must be between $CONFIG_MIN"MB" and $size"MB"" + echo + CONFIG_PARTITION_SIZE=0 + fi + done + + echo + + # now take the data and create the partitions + create_partitions "$INSTALL_DRIVE" "$ROOT_PARTITION_SIZE" "$CONFIG_PARTITION_SIZE" +} + +unmount () { + # grab the list of mounted drives + # make sure to reverse sort so as to unmount up the tree + mounted=$(mount | grep "$1" | cut -f3 -d' ' | sort -r) + if [ -n "$mounted" ]; then + echo "I need to unmount: " + echo "$mounted" + + response='' + while [ -z $response ] + do + echo -n "Continue (Yes/No) [No]: " + response=$(get_response "No" "Yes No Y N") + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo -e "Ok then. Need to unmount to continue.\nExiting..." + exit 1 + fi + done + + for parts in "$mounted" + do + echo "umount $parts" >> $INSTALL_LOG + output=$(umount $parts) + status=$? + if [ "$status" != 0 ]; then + echo -e "Exiting: error unmounting $parts.\nPlease see $INSTALL_LOG for more details." + echo -e "Exiting: error unmounting $parts.\numount $parts\n$output" >> $INSTALL_LOG + exit 1 + fi + done + fi +} + +progress_indicator () { + case "$1" in + "start") /usr/bin/progress-indicator $SPID & + ;; + "stop") rm -f /tmp/pi.$SPID + sleep 1 + echo -n -e "\b" + ;; + esac +} + +##### Main +## +# clean up existing log files +if [ -f $INSTALL_LOG.old ]; then + rm -f $INSTALL_LOG.old +fi +if [ -f $INSTALL_LOG ]; then + mv $INSTALL_LOG $INSTALL_LOG.old + rm -f $INSTALL_LOG +fi + +# turn off any mounted swap files +turnoffswap + +# Print welcome and instructions. +echo "Welcome to the Vyatta install program. This script" +echo "will walk you through the process of installing the" +echo "Vyatta image to a local hard drive." +echo + +response='' +while [ -z $response ] +do + echo -n "Would you like to continue? (Yes/No) [Yes]: " + response=$(get_response "Yes" "Yes No Y N") + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo "Ok then. Exiting..." + exit 1 + fi +done + +# some drives don't show up in /proc/partitions so we need to bootstrap them +echo -n "Probing drives: " +progress_indicator "start" +probe_drives +progress_indicator "stop" +echo "OK" + +echo "The Vyatta image will require a minimum $ROOT_MIN"MB" root" +echo "partition and a minimum $CONFIG_MIN"MB" configuration partition." +echo "Would you like me to try to partition a drive automatically" +echo "or would you rather partition it manually with parted? If" +echo "you have already setup your partitions, you may skip this step." +echo + +method='' +while [ -z $method ] +do + echo -n "Partition (Auto/Parted/Skip) [Auto]: " + method=$(get_response "Auto" "Auto Parted Skip A P S") +done + +echo + +# TODO: Note installs assume an LBA BIOS. So no boot partition currently. +# also note that we are not creating a swap partition right now. +if [ "$method" == "parted" ] || [ "$method" == "p" ]; then + setup_method_manual "parted" +elif [ "$method" == "skip" ] || [ "$method" == "s" ]; then + setup_method_manual "skip" +elif [ "$method" == "auto" ] || [ "$method" == "a" ]; then + setup_method_auto +elif [ "$method" == "vyatta" ]; then + echo "Automated install..." + echo "unmounting $INSTALL_DRIVE" + unmount "$INSTALL_DRIVE" + echo "deleting partitions on $INSTALL_DRIVE" + delete_partitions "$INSTALL_DRIVE" + echo "creating config partition" + create_partitions "$INSTALL_DRIVE" "$ROOT_PARTITION_SIZE" "$CONFIG_PARTITION_SIZE" +fi + +# Install the root filesystem +install_root_filesystem "$ROOT_PARTITION" + +# Copy the config files +copy_config "$CONFIG_PARTITION" + +# Install grub +install_grub + +cp $INSTALL_LOG $rootfsdir/install.log + +umount $rootfsdir$ofrconfdir +umount $rootfsdir + +echo "Done!" +echo "Done!" >> $INSTALL_LOG + +exit 0 diff --git a/scripts/progress-indicator b/scripts/progress-indicator new file mode 100755 index 00000000..aa263b36 --- /dev/null +++ b/scripts/progress-indicator @@ -0,0 +1,24 @@ +#!/bin/sh +# Propeller progress indicator +FRAME="A" +PID=$1 + +touch "/tmp/pi.$PID" +while [ -f "/tmp/pi.$PID" ]; +do + case $FRAME in + A) echo -n -e "\b" + echo -n '|' + FRAME=B;; + B) echo -n -e "\b" + echo -n '/' + FRAME=C;; + C) echo -n -e "\b" + echo -n '-' + FRAME=D;; + D) echo -n -e "\b" + echo -n '\' + FRAME=A;; + esac + sleep 1 +done diff --git a/scripts/quick-install b/scripts/quick-install new file mode 100755 index 00000000..41941e3f --- /dev/null +++ b/scripts/quick-install @@ -0,0 +1,907 @@ +#!/bin/sh +# +# Module: install-system +# +# **** License **** +# Version: VPL 1.0 +# +# The contents of this file are subject to the Vyatta Public License +# Version 1.0 ("License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.vyatta.com/vpl +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc. +# All Rights Reserved. +# +# Author: Robert Bays +# Date: 2006 +# Description: +# +# **** End License **** +# +# Vyatta system installer script. +# +# +# If you set VYATTA_AUTO_INSTALL I will try to do an automated install for you + +INSTALL_LOG="install.log" # install log file name +ROOT_MIN="450" # root partition minimum size in MB +CONFIG_MIN="10" # config partition minium size in MB +VYATTA_CONFIG_DIRECTORY="/opt/vyatta/etc/config/" # the configuration directory + +# environmental variables +#$INSTALL_DRIVE the base install drive e.g. sda +#$ROOT_PARTITION the install partition e.g. sda1 +#$CONFIG_PARTITION the config partition e.g. sda2 +#$ROOT_PARTITION_SIZE the size of the root partition +#$CONFIG_PARTITION_SIZE the size of the config partition + +# Use "classic" prompts? +CLASSIC=$1 + +# global holding variable used in the select_partition sub +PARTITION='' + +# Process ID of this script for the lame marketing spinner +SPID=$$ + +# trap signals so we can kill runaway progress indicators +trap 'progress_indicator "stop"; exit 1' 1 +trap 'progress_indicator "stop"; exit 1' 2 + +# turn off any mounted swap partitions +turnoffswap () { + if [ -f "/proc/swaps" ]; then + myresponse=$(cat /proc/swaps) + if [ -n "$myresponse" ]; then + echo "turning off swaps..." >> $INSTALL_LOG + swapoff -a + fi + fi +} + +# Validates a user response. Returns the response if valid. +# Returns the default is the user just hits enter. +# Returns nothing if not valid. Default parameter is $1. +# Options are in $2. If options are defined return must be a member +# of the enum. +get_response () { + ldefault=$(echo "$1" | tr [:upper:] [:lower:]) + loptions=$(echo "$2" | tr [:upper:] [:lower:]) + + # get the response from the user + read myresponse + myresponse=$(echo "$myresponse" | awk '{ printf (tolower($0)) }') + + # Check to see if the user accepts the default + if [ -z "$myresponse" ]; then + echo -n $ldefault + # if we are passing in options to check, make sure response is a valid option + elif [ -n "$loptions" ]; then + for token in $loptions + do + if [ "$token" == "$myresponse" ]; then + echo -n "$myresponse" + return 0 + fi + done + return 1 + else + echo -n "$myresponse" + fi + + return 0 +} + +# Return the size of the drive in MB +get_drive_size () { + ldrive=$1 + + # Make sure you can print disk info using parted + parted /dev/$ldrive p >/dev/null 2>&1 + + # If unable to read disk, it's likely it needs a disklabel + if [ "$?" != "0" ]; then + echo "Creating a new disklabel on $ldrive" >> $INSTALL_LOG + echo "parted /dev/$ldrive mklabel msdos" >> $INSTALL_LOG + output=$(parted /dev/$ldrive mklabel msdos) + + # Get the drive size from parted + lsize=$(parted /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }') + + if [ $(echo $lsize | grep error) ]; then + echo "Unable to read disk label. Exiting." + exit 1 + fi + fi + + # Get the drive size from parted + lsize=$(parted /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }') + # Get the reported units (mB, GB, kB) + lmodifier=$(echo $lsize | sed 's/[0-9\.]//g') + # remove the modifier + lsize=$(echo $lsize | sed 's/[a-z,A-Z]//g') + # Remove any fractions + lsize=$(echo $lsize | cut -f1 -d'.') + # Translate our size into mB if not there already + if [ $lmodifier = "GB" ]; then + lsize=$(($lsize * 1000)) + elif [ $lmodifier = "kB" ]; then + lsize=$(($lsize / 1000)) + fi + + echo $lsize +} + +# Probe hardrives not shown in /proc/partitions by default +probe_drives () { + # find IDE drives. Not all drives show up in /proc/partitions for + # some reason. + # TODO: not sure we have to do this for anything but compact flash + # when we test on other platforms, we will find out and modify this section + # as appropriate + drive=$(find /proc/ide/ide* -name "hd*" 2>/dev/null | /usr/bin/awk -F"/" '{ print $5 }') + + # now exclude all drives but disks + for drive in $drive + do + media=$(cat /proc/ide/$drive/media) + if [ "$media" = "disk" ]; then + output=$(mount | grep $drive) + if [ -z "$output" ]; then + output=$(parted /dev/$DRIVE p) + fi + fi + done +} + +# Takes an argument to display text before choice +# Sets INSTALL_DRIVE. Note that select_drive should be wrapped +# in the verification loop, not the included get_response. +select_drive () { + # list the drives in /proc/partitions. Remove partitions and empty lines. + drives=$(cat /proc/partitions | awk '{ if ($4!="name") { print $4 } }' | egrep -v "[0-9]$" | egrep -v "^$") + + # take the first drive as the default + INSTALL_DRIVE=$(echo $drives | /usr/bin/awk '{ print $1 }') + + # Add the drive sizes to the display to help the user decide + display='' + for drive in $drives + do + size=$(get_drive_size $drive) + display="$display $drive\t$size"MB"\n" + done + + n=`echo $drives|wc -w` + if [ $n = 1 -a x$CLASSIC != xCLASSIC ] + then + # Only one drive to choose from, no need to ask + INSTALL_DRIVE=$drives + else + # Display the drives and ask the user which one to install to + echo -e "$display" + echo + echo -ne "$1 [$INSTALL_DRIVE]:" + + INSTALL_DRIVE=$(get_response "$INSTALL_DRIVE" "$drives") + echo + fi + + # Assume no dma if the disk is smaller than 10G (such as a CF drive) + size=$(get_drive_size $INSTALL_DRIVE) + if [ $size -lt 11000 ] + then + ISCF="ide=nodma" + fi +} + +# Allow the user to select a partition to work with +# sets the global PARTITION +# $1 is the text to display before prompt +select_partition () { + minsize=$1 + text=$2 + + echo -n "Looking for appropriate partitions: " + progress_indicator "start" + + # initialize out global var. using globals in this way is bad form. I know. + PARTITION='' + + # list only the partitions in /proc/partitions. + parts=$(cat /proc/partitions | awk '{ if ($4!="name") { print $4 " "} }' | egrep "[0-9]" | egrep -v "loop" | tr -d '\n') + + # Get the partition sizes for display + # only show partitions that have sizes, i.e. remove loops + display='' + for part in $parts + do + lsize=$(get_drive_size $part) + if [ "$lsize" -a $lsize -ge $minsize ]; then + display="$display $part\t\t$lsize"MB"\n" + fi + done + + progress_indicator "stop" + echo "OK" + + if [ -n "$parts" ]; then + lpartition='' + while [ -z "$lpartition" ] + do + # take the first partition as the default + lpartition=$(echo $parts | /usr/bin/awk '{ print $1 }') + + echo "I found the following partitions suitable for the Vyatta image:" + echo -e "Partition\tSize" + echo -e "$display" + echo + echo -n "$text [$lpartition]: " + + lpartition=$(get_response "$lpartition" "$parts") + echo + done + else + echo "No suitable partition sizes found. Exiting..." | tee $INSTALL_LOG + exit 1 + fi + PARTITION=$lpartition +} + +# Delete all existing partitions for an automated install +# $1 is the drive to delete partitions from +delete_partitions () { + ldrive=$1 + + # get the partitions on the drive + partitions=$(cat /proc/partitions | grep $ldrive[0-9] | awk '{ print $4 }' | sed 's/[a-z]//g') + + # now for each part, blow it away + for part in $partitions + do + # Look to see if this is a config partition + mkdir -p /mnt/tmp + output=$(mount /dev/$ldrive$part /mnt/tmp 2>&1) + if [ $? != 0 ]; then + echo -e "Cannot mount /dev/$ldrive$part"."\nPlease see $INSTALL_LOG for more details.\nExiting.." + echo -e "Cannot mount /dev/$ldrive$part"."\nmount /dev/$ldrive$part /mnt/tmp\nExiting..." >> $INSTALL_LOG + echo "$output" >> $INSTALL_LOG + exit 1 + fi + + # Look to see if the old config marker file is there. + if [ -f /mnt/tmp/.vyatta_config ]; then + response='' + while [ -z "$response" ] + do + echo "/dev/$ldrive$part is a config partition!" + echo -ne "Would you like me to save the data on it before I delete it? (Yes/No) [Yes]: " + response=$(get_response "Yes" "Yes No Y N") + if [ "$response" == "yes" ] || [ "$response" == "y" ]; then + mkdir -p /mnt/config + output=$(cp -pR /mnt/tmp/* /mnt/config) + if [ -n "$output" ]; then + echo -e "Warning: error in copying the old config partition.\nSee $INSTALL_LOG for more details." + echo -e "Warning: error in copying the old config partition.\ncp -pR /mnt/tmp/* /mnt/config\n$output\n" >> $INSTALL_LOG + fi + fi + done + fi + umount /mnt/tmp + + echo "Removing partition $part on /dev/$ldrive" >> $INSTALL_LOG + output=$(parted /dev/$ldrive rm $part) + status=$? + if [ "$status" != 0 ]; then + echo -e "Warning: cannot delete partition $part on $ldrive.\nPlease see $INSTALL_LOG for more details." + echo -e "Warning: cannot delete partition $part on $ldrive.\nparted /dev/$ldrive rm $part\n$output" >> $INSTALL_LOG + fi + + # We add a bogus sleep here because the loop needs to wait for udev + sleep 5 + done +} + +# make a filesystem on the drive +# $1 is the drive to format +make_filesystem () { + ldrive=$1 + + echo -n "Creating filesystem on /dev/$ldrive: " + echo "Creating filesystem on /dev/$ldrive..." >> $INSTALL_LOG + + progress_indicator "start" + output=$(mke2fs -j /dev/$ldrive 2>&1) + status=$? + if [ "$status" != 0 ]; then + echo -e "Error: couldn't create the root filesystem.\nSee $INSTALL_LOG for further details.\nExiting..." + echo -e "Error: couldn't create the root filesystem.\n/sbin/mke2fs -j /dev/$lDRIVE\n$output" + exit 1 + fi + progress_indicator "stop" + echo "OK" +} + +# create the root partition +# $1 is the install drive e.g. sda +# $2 is the partition size e.g. 512 +# $3 config partition size e.g. 100 +# This will set the globals ROOT_PARTITION and CONFIG_PARTITION +create_partitions() { + ldrive=$1 + root_part_size=$2 + config_part_size=$3 + + total=$(($root_part_size + $config_part_size)) + head=$(($root_part_size)) + tail=$(($root_part_size + $config_part_size)) + + # Make sure there is enough space on drive + size=$(get_drive_size "$ldrive") + if [ "$total" -gt "$size" ]; then + echo "Error: $ldrive is only $size"MB" large." + exit 1 + fi + + echo "Creating root partition on /dev/$ldrive" >> $INSTALL_LOG + + # make the root partition + output=$(parted /dev/$ldrive mkpart primary 0 $root_part_size) + status=$? + if [ "$status" != 0 ]; then + echo -e "Error creating primary partition on $ldrive.\nPlease see $INSTALL_LOG for more details.\nExiting..." + echo -e "Error creating primary partition on $ldrive.\nparted /dev/$ldrive mkpart primary 0 $root_part_size\n$output" >> $INSTALL_LOG + exit 1 + fi + + ROOT_PARTITION=$ldrive"1" + # udev takes time to re-add the device file, so wait for it + while [ ! -b "/dev/$ROOT_PARTITION" ] + do + sleep 1 + done + + echo "Creating configuration partition on /dev/$ldrive" >> $INSTALL_LOG + echo "parted /dev/$ldrive mkpart primary $root_part_size $config_part_size" >> $INSTALL_LOG + + output=$(parted /dev/$ldrive mkpart primary $head $tail) + status=$? + if [ "$status" != 0 ]; then + echo -e "Error creating primary partition on $ldrive.\nPlease see $INSTALL_LOG for more details.\nExiting..." + echo -e "Error creating primary partition on $ldrive.\nparted /dev/$ldrive mkpart primary $root_part_size $config_part_size\n$output" + exit 1 + fi + + CONFIG_PARTITION=$ldrive"2" + # udev takes time to re-add the device file, so wait for it + while [ ! -b "/dev/$CONFIG_PARTITION" ] + do + sleep 1 + done + + # make the root and config ext3 file systems. + make_filesystem "$ROOT_PARTITION" + make_filesystem "$CONFIG_PARTITION" +} + +# Install the root filesystem +# $1 is the partition to install on +install_root_filesystem () { + ldrive=$1 + + dpkg="/usr/bin/dpkg --force-all --root=/mnt/rootfs" + echo "Mounting /dev/$ldrive..." | tee $INSTALL_LOG + + # make the mount point + output=$(/bin/mkdir -p /mnt/rootfs) + + # mount the partition + output=$(mount -t ext3 /dev/$ldrive /mnt/rootfs) + status=$? + + if [ "$status" != 0 ]; then + echo -e "Error trying to mount the new root partition.\nPlease see $INSTALL_LOG for details.\nExiting..." + echo -e "Error trying to mount the new root partition.\nmount -t ext3 /dev/$ldrive /mnt/rootfs\n$output" >> $INSTALL_LOG + exit 1 + fi + + echo -n "Copying system image files to /dev/$ROOT_PARTITION: " + progress_indicator "start" + # Mount the squashfs for copying + output=$(mkdir -p /mnt/squashfs) + output=$(mount /live_media/casper/filesystem.squashfs /mnt/squashfs -t squashfs -o loop) + status=$? + + if [ "$status" != 0 ]; then + echo -e "Error trying to mount the squashfs.\nPlease see install log for more details.\nExiting..." + echo -e "Error trying to mount the squashfs.\nmount /live_media/casper/filesystem.squashfs /mnt/squashfs -t squashfs -o loop\n$output" >> $INSTALL_LOG + exit 1 + fi + + output=$(cp -pR /mnt/squashfs/* /mnt/rootfs/) + status=$? + + if [ "$status" != 0 ]; then + echo -e "Error trying to copy the rootfs.\nPlease see install log for more details.\nExiting. +.." + echo -e "Error trying to copy the rootfs.\ncp -pR /mnt/squashfs/* /mnt/rootfs/\n$output" >> $INSTALL_LOG + exit 1 + fi + + # unmount the squashfs. No big deal if it fails. + output=$(umount /mnt/squashfs) + + # make the dir for the boot files and copy em' over + mkdir -p /mnt/rootfs/boot + output=$(cp -pR /boot/* /mnt/rootfs/boot/) + status=$? + output+=$(cp /live_media/boot/initrd.img /mnt/rootfs/boot/) + status=$status || $? + if [ "$status" != 0 ]; then + echo -e "Error trying to copy the bootfiles.\nPlease see install log for more details.\nExiting. +.." + echo -e "Error trying to copy the bootfiles.\ncp /live_media/boot/initrd.img /mnt/rootfs/boot/\n$output" >> $INSTALL_LOG + exit 1 + fi + + # create the fstab + echo -e "/dev/$CONFIG_PARTITION\t/opt/vyatta/etc/config\text3\tdefaults\t1 2" >> /mnt/rootfs/etc/fstab + echo -e "/dev/$ROOT_PARTITION\t/\text3\tdefaults\t0 1" >> /mnt/rootfs/etc/fstab + progress_indicator "stop" + echo "OK" +} + +# copy the configuration to the config partition +# $1 is the config partition device +copy_config () { + config_partition=$1 + lerror='' + + # Copy the config.boot.default to tmp + output=$(cp $VYATTA_CONFIG_DIRECTORY/config.boot.default /tmp/config.boot.default.install) + + # create the config directory on the union file system + output=$(mount -t ext3 /dev/$config_partition /mnt/rootfs/$VYATTA_CONFIG_DIRECTORY) + status=$? + + if [ "$status" != 0 ]; then + echo -e "Error trying to mount the new config partition.\nPlease see $INSTALL_LOG for details.\nExiting..." + echo -e "Error trying to mount the new config partition.\nmount -t ext3 /dev/$config_partition /mnt/rootfs/$VYATTA_CONFIG_DIRECTORY\n$output" >> $INSTALL_LOG + exit 1 + fi + + # create the proper perms on the new config partition + chgrp xorp /mnt/rootfs/$VYATTA_CONFIG_DIRECTORY + chmod 775 /mnt/rootfs/$VYATTA_CONFIG_DIRECTORY + + # Copy /tmp/config.boot.default to new config partition + cp /tmp/config.boot.default.install /mnt/rootfs/$VYATTA_CONFIG_DIRECTORY/config.boot.default + rm -f /tmp/config.boot.default.install + + # create our config partition marker + touch /mnt/rootfs/$VYATTA_CONFIG_DIRECTORY/.vyatta_config + + if [ -d /mnt/config ]; then + echo "Copying old configurations to config partition." + cp -pR /mnt/config/* /mnt/rootfs/$VYATTA_CONFIG_DIRECTORY + else + # Find the config files and give the user the option to copy config files + # TODO: this needs cleaned up + [ -f $VYATTA_CONFIG_DIRECTORY/config.boot ] && config="$VYATTA_CONFIG_DIRECTORY/config.boot" + fd_config=/media/floppy/config/config.boot + if [ ! -f $fd_config ]; then + configfile="$config" + else + if [ "$config" ]; then + config="$config\n$fd_config" + else + config="$fd_config" + configfile="$config" + fi + fi + + if [ "$config" -a ! $configfile ]; then + echo "I found the following configuration files:" + echo -e "$config" + default=$(echo -e $config| head -1) + + resp='' + while [ -z "$configfile" ] + do + echo -n "Which one should I copy to $INSTALL_DRIVE? [$default]: " + configfile=$(get_response "$default" "$config") + done + + echo + if ! cp $configfile /mnt/rootfs/$VYATTA_CONFIG_DIR; then + echo "Error copying file $configfile to config directory. Exiting..." >> $INSTALL_LOG + exit 1 + fi + fi + fi + + # set the permissions on the new config file + if [ -f "/mnt/rootfs/$VYATTA_CONFIG_DIR/config.boot" ]; then + chgrp xorp /mnt/rootfs/$VYATTA_CONFIG_DIR/config.boot + chmod 775 /mnt/rootfs/$VYATTA_CONFIG_DIR/config.boot + fi +} + +# setup grub on thje boot sector of a user queried drive +install_grub () { + orig_install_drive="$INSTALL_DRIVE" + # we now use INSTALL_DRIVE to reference the grub boot drive. + # that way I can re-use select_drive. I'm lazy that way. + INSTALL_DRIVE='' + + mkdir -p /mnt/rootfs/boot/grub + # Let the user choose the boot sector + + while [ -z "$INSTALL_DRIVE" ] + do + select_drive "I need to install the GRUB bootloader.\nI found the following drives on your system:\nWhich drive should GRUB modify the boot partition on?" + done + + echo -n "Setting up grub: " + echo "Setting up grub..." >> $INSTALL_LOG + + # Install grub in the boot sector of the primary drive + progress_indicator "start" + grub-install --no-floppy --root-directory=/mnt/rootfs /dev/$INSTALL_DRIVE >>$INSTALL_LOG 2>&1 + progress_indicator "stop" + + # TODO: This needs to be changed to map to the correct drive + part=$(echo $ROOT_PARTITION | sed 's/[^0-9]//g') + part=$(($part - 1)) + if [ $(cat /sys/block/$orig_install_drive/removable) == 0 ]; then + root=$(grep $orig_install_drive /mnt/rootfs/boot/grub/device.map | /usr/bin/awk -F')' '{ print $1 }') + root="$root,$part)" + else + echo "This looks like a removable device. Setting root grub device to (0,0)." | tee $INSTALL_LOG + root="(hd0,$part)" + fi + + # create the menu.lst file for grub + grub_file="/mnt/rootfs/boot/grub/menu.lst" + echo -e "default=0\ntimeout=5\n#splashimage=(hd0,0)/grub/splash.xpm.gz\nhiddenmenu" > $grub_file + # set serial console options + echo -e "serial --unit=0 --speed=9600\nterminal --timeout=5 console serial\n\n" >> $grub_file + # set primary boot option + echo -e "title Vyatta OFR\n\troot $root" >> $grub_file + echo -en "\tkernel /boot/vmlinuz root=/dev/$ROOT_PARTITION $ISCF console=ttyS0,9600 console=tty0\n" >> $grub_file + echo -e "\tinitrd /boot/initrd.img" >> $grub_file + + echo "OK" +} + +# ask for user input on the parted and skip setup methods +# $1 is whether or not to run parted +# sets globals INSTALL_DRIVE, ROOT_PARTITION, CONFIG_PARTITION +setup_method_manual() { + parted=$1 + + echo "The Vyatta install needs a minimum $ROOT_MIN"MB" root" + echo "and a minimum $CONFIG_MIN"MB" config partition. These" + echo "partitions need to be set to partiton type 83 (Linux)." + echo -e "\n\n" + + # if this is parted, let the user create the partitions + if [ "$method" == "parted" ] || [ "$method" == "p" ]; then + while [ -z "$INSTALL_DRIVE" ] + do + # TODO: right now we only run parted on a single drive + select_drive "\nI found the following drives on your system:\nWhich drive would you like to run parted on?" + done + + # Unmount the install drive if it is mounted + unmount "$INSTALL_DRIVE" + + # Run parted and let the user configure + parted /dev/$INSTALL_DRIVE + fi + + # Ask for the root partition and make sure it's valid + while [ -z "$ROOT_PARTITION" ] + do + select_partition 500 "Which partition should I install the root on?" + # Note that PARTITION is defined in select partition + ROOT_PARTITION=$PARTITION + unmount "$ROOT_PARTITION" + vd=$(grep $ROOT_PARTITION /proc/partitions | awk '{ print $4 }') + + if [ -z "$vd" ]; then + echo + echo "$ROOT_PARTITION is an invalid partition. Please try again." + ROOT_PARTITION="" + fi + done + + # Ask for the config partition and make sure it's valid + # TODO: need to do better error checking here to insure + # the user doesn't select the same part for both drives. + while [ -z "$CONFIG_PARTITION" ] + do + while true + do + select_partition 5 "Which partition should I use for configurations?" + # Note that PARTITION is defined in select partition + if [ "$PARTITION" != "$ROOT_PARTITION" ] + then + break + fi + echo "The config partition cannot be the same as the root partition ($ROOT_PARTITION)!" + echo + done + + # Note that PARTITION is defined in select partition + CONFIG_PARTITION=$PARTITION + unmount "$CONFIG_PARTITION" + vd=$(grep $CONFIG_PARTITION /proc/partitions | awk '{ print $4 }') + + if [ -z "$vd" ]; then + echo + echo "$CONFIG_PARTITION is an invalid partition. Please try again." + CONFIG_PARTITION="" + fi + done + + # create the ext3 fs on the part + make_filesystem "$ROOT_PARTITION" + + # Create the ext3 fs on the part + make_filesystem $CONFIG_PARTITION + + # We need to set the INSTALL_DRIVE if it wasn't set when the user ran parted + # We assume that we will use the boot sector of the same drive that the partition is on + # TODO: Allow different drives to function as the boot device + if [ -z "INSTALL_DRIVE" ]; then + INSTALL_DRIVE=$(echo $ROOT_PARTITION | sed 's/[0-9]//g') + fi +} + +# Walk the user through the auto setup method +# sets globals INSTALL_DRIVE, ROOT_PARTITION, CONFIG_PARTITION +setup_method_auto() { + while [ -z "$INSTALL_DRIVE" ] + do + select_drive "I found the following drives on your system:\nInstall the image on?" + + # check to make sure the drive is large enough to hold the image + if [ -n "$INSTALL_DRIVE" ]; then + lsize=$(get_drive_size "$INSTALL_DRIVE") + total=$(($ROOT_MIN + $CONFIG_MIN)) + if [ "$total" -gt "$lsize" ]; then + echo "Unfortunately, the OFR requires a total of at least $total"MB" to properly install." + echo "$INSTALL_DRIVE is below the minimum required capacity and therefore, cannot be used to" + echo -e "complete the installation.\n" + echo "If other drives are present" + echo -e "Please select another drive...\n" + + INSTALL_DRIVE='' + fi + fi + done + + # Give the user a requisite warning that we are about to nuke their drive + response='' + while [ -z $response ] + do + echo -n "This will destroy all data on /dev/$INSTALL_DRIVE. Continue? (Yes/No) [No]: " + response=$(get_response "No" "Yes No Y N") + + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo "Ok then. Exiting..." + exit 1 + fi + done + + echo + + # make sure we aren't working on a mounted part + unmount "$INSTALL_DRIVE" + + # remove any existing partitions on that drive + delete_partitions "$INSTALL_DRIVE" + + # Enforce minimum partion size requirement. + ROOT_PARTITION_SIZE=0 + while [ $ROOT_MIN -gt $ROOT_PARTITION_SIZE ]; do + # Get the size of the drive + size=$(get_drive_size $INSTALL_DRIVE) + # Subtract our minimum config part so the user doesn't fill the entire drive + size=$(($size - $CONFIG_MIN)) + if [ $ROOT_MIN = $size ] + then + response=$size + else + echo -ne "\nHow big of a root partition should I create? ($ROOT_MIN"MB" - $size"MB") [$size]MB: " + response=$(get_response "$size") + fi + + # TODO: need to have better error checking on this value + ROOT_PARTITION_SIZE=$(echo "$response" | sed 's/[^0-9]//g') + if [ $ROOT_PARTITION_SIZE -lt $ROOT_MIN ] || [ $ROOT_PARTITION_SIZE -gt $size ]; then + echo "Root partion must be between $ROOT_MIN"MB" and $size"MB"" + echo + ROOT_PARTITION_SIZE=0 + fi + done + + # Enforce minimum partion size requirement. + CONFIG_PARTITION_SIZE=0 + while [ $CONFIG_MIN -gt $CONFIG_PARTITION_SIZE ]; do + # Get the size of the drive + size=$(get_drive_size $INSTALL_DRIVE) + # Subtract our minimum config part so the user doesn't fill the entire drive + size=$(($size - $ROOT_PARTITION_SIZE)) + if [ $CONFIG_MIN = $size ] + then + response=$size + else + echo -n "How big of a config partition should I create? ($CONFIG_MIN"MB" - $size"MB") [$CONFIG_MIN]MB: " + response=$(get_response "$CONFIG_MIN") + fi + CONFIG_PARTITION_SIZE=$(echo "$response" | sed 's/[^0-9]//g') + if [ $CONFIG_PARTITION_SIZE -lt $CONFIG_MIN ] || [ $CONFIG_PARTITION_SIZE -gt $size ]; then + echo "Config partion must be between $CONFIG_MIN"MB" and $size"MB"" + echo + CONFIG_PARTITION_SIZE=0 + fi + done + + echo + + # now take the data and create the partitions + create_partitions "$INSTALL_DRIVE" "$ROOT_PARTITION_SIZE" "$CONFIG_PARTITION_SIZE" +} + +unmount () { + # grab the list of mounted drives + # make sure to reverse sort so as to unmount up the tree + mounted=$(mount | grep "$1" | cut -f3 -d' ' | sort -r) + if [ -n "$mounted" ]; then + echo "I need to unmount: " + echo "$mounted" + + response='' + while [ -z $response ] + do + echo -n "Continue (yes/No) [No]: " + response=$(get_response "No" "Yes No Y N") + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo -e "Ok then. Need to unmount to continue.\nExiting..." + exit 1 + fi + done + + for parts in "$mounted" + do + echo "umount $parts" >> $INSTALL_LOG + output=$(umount $parts) + status=$? + if [ "$status" != 0 ]; then + echo -e "Exiting: error unmounting $parts.\nPlease see $INSTALL_LOG for more details." + echo -e "Exiting: error unmounting $parts.\numount $parts\n$output" >> $INSTALL_LOG + exit 1 + fi + done + fi +} + +progress_indicator () { + case "$1" in + "start") /usr/bin/progress-indicator $SPID & + ;; + "stop") rm -f /tmp/pi.$SPID + sleep 1 + echo -n -e "\b" + ;; + esac +} + +##### Main +## +# clean up existing log files +if [ -f $INSTALL_LOG.old ]; then + rm -f $INSTALL_LOG.old +fi +if [ -f $INSTALL_LOG ]; then + mv $INSTALL_LOG $INSTALL_LOG.old + rm -f $INSTALL_LOG +fi + +# turn off any mounted swap files +turnoffswap + +# Print welcome and instructions. +echo "Welcome to the Vyatta install program. This script will walk you through" +echo "the process of installing the Vyatta image to a local hard drive." +echo + +if [ x$CLASSIC = xCLASSIC ] +then + response='' + while [ -z $response ] + do + echo -n "Would you like to continue? (Yes/No) [Yes]: " + response=$(get_response "Yes" "Yes No Y N") + if [ "$response" == "no" ] || [ "$response" == "n" ]; then + echo "Ok then. Exiting..." + exit 1 + fi + done +fi + +echo "The image will require a minimum $ROOT_MIN"MB" root partition and" +echo "a minimum $CONFIG_MIN"MB" configuration partition." +echo +echo "Disk partitioning can be done automatically or manually (with parted)." +echo "If you have already set up your partitions, you may skip the Partition step." +echo + +# some drives don't show up in /proc/partitions so we need to bootstrap them +echo -n "Probing drives: " +progress_indicator "start" +probe_drives +progress_indicator "stop" +echo "OK" + +method='' +while [ -z $method ] +do + echo -n "Partition (Auto/parted/skip) [Auto]: " + method=$(get_response "Auto" "Auto Parted Skip A P S") +done + +echo + +# TODO: Note installs assume an LBA BIOS. So no boot partition currently. +# also note that we are not creating a swap partition right now. +if [ "$method" == "parted" ] || [ "$method" == "p" ]; then + setup_method_manual "parted" +elif [ "$method" == "skip" ] || [ "$method" == "s" ]; then + setup_method_manual "skip" +elif [ "$method" == "auto" ] || [ "$method" == "a" ]; then + setup_method_auto +elif [ "$method" == "vyatta" ]; then + echo "Automated install..." + echo "unmounting $INSTALL_DRIVE" + unmount "$INSTALL_DRIVE" + echo "deleting partitions on $INSTALL_DRIVE" + delete_partitions "$INSTALL_DRIVE" + echo "creating config partition" + create_partitions "$INSTALL_DRIVE" "$ROOT_PARTITION_SIZE" "$CONFIG_PARTITION_SIZE" +fi + +# Install the root filesystem +install_root_filesystem "$ROOT_PARTITION" + +# Copy the config files +copy_config "$CONFIG_PARTITION" + +# Install grub +install_grub + +cp $INSTALL_LOG /mnt/rootfs/install.log + +umount /mnt/rootfs/opt/vyatta/etc/config +umount /mnt/rootfs + +echo "Done!" | tee $INSTALL_LOG +echo "Don't forget to remove the live CD after system shutdown" + +echo -ne "Reboot the system now? (Yes/No) [Yes]: " +response=$(get_response "Yes" "Yes No Y N") +if [ $response = yes -o $response = y ] +then + reboot +fi + +exit 0 diff --git a/scripts/rl-system.init b/scripts/rl-system.init new file mode 100755 index 00000000..21851ef0 --- /dev/null +++ b/scripts/rl-system.init @@ -0,0 +1,349 @@ +#!/bin/bash +# **** License **** +# Version: VPL 1.0 +# +# The contents of this file are subject to the Vyatta Public License +# Version 1.0 ("License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.vyatta.com/vpl +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc. +# All Rights Reserved. +# +# Author: Tom Grennan <tgrennan@vyatta.com> +# Description: Vyatta Router system setup +# this is an indirect init sub-script executed by ofr.init +# +# **** End License **** + +ACTION=$1 + +[[ $PATH == *${ofr_bindir}* ]] || PATH+=:${ofr_bindir} +[[ $PATH == *${ofr_sbindir}* ]] || PATH+=:${ofr_sbindir} + +export PATH + +. /lib/lsb/init-functions + +IPROUTE2IP=ip +INIT_PID=$$ +IFTAB=/etc/iftab + +## BOOTFILE is provided by ofr.init +: ${BOOTFILE:=$prefix/etc/config/config.boot} + +declare -a cfg_eth_hwid +declare -a sys_eth_mac +declare -a sys_vmnets + +# load hwid array from config file as follows +# interface { +# ... +# ethernet eth# { +# ... +# hw-id: XX:XX:XX:XX:XX:XX +# ... +# } +# } +# +# cfg_eth_hwid[#]=xx:xx:xx:xx:xx:xx + +load_cfg_eth_hwid () +{ + eval $( sed -n ' + /^interfaces {/,/^}/ { + /^ *ethernet eth[0-9]* {/,/^ $/ { + /^ *ethernet/ { + s/.* eth\([0-9]\+\) {$/cfg_eth_hwid[\1]=/ +# hold interface name + h + } + /^.*hw-id:/ { +# translate field name + s/.*hw-id: *// +# tolower hex mac address + y/ABCDEF/abcdef/ +# exchange hold and pattern space + x +# concatenate hold and pattern + G + s/\n//p + } + } + }' $BOOTFILE ) +} + +# load system eth mac tabled from ip link + +load_sys_eth_mac () +{ + eval $( ip link show | sed -n ' + /^[0-9]*: eth[0-9]*: /,+1 { +# combine 2 line interface output... +# 2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000 +# link/ether 00:13:72:57:48:f9 brd ff:ff:ff:ff:ff:ff + h + n + x + G + s/\n// +# translate to: +# #=00:13:72:57:48:f9 + s/^.*eth\([0-9]\+\):.*link\/ether \([0-9A-Fa-f:]\+\) .*$/sys_eth_mac[\1]=\2/p + }' ) +} + +load_sys_vmnets () +{ + sys_vmnets=( $( ip link show | + sed -n 's/^[0-9]*: \(vmnet[0-9]*\).*$/\1/p' ) ) +} + + +have_cfg_eth_hwid () +{ + local mac=$1 + + for hwid in ${cfg_eth_hwid[@]} ; do + [ $hwid == $mac ] && return 0 + done + false +} + +have_sys_eth_mac () +{ + local hwid=$1 + + for mac in ${sys_eth_mac[@]} ; do + [ $hwid == $mac ] && return 0 + done + false +} + +# update cfg table with results from system mac detection +# first remove cfg itfs that are no longer in sys table +# if sys mac is already in cfg table, use cfg itf assignment; +# if sys mac isnot in cfg table but given index has hwid of +# another sys itf, add to cfg table in first available slot +# otherwise, [re-]assign cfg eth hwid with sys mac + +update_cfg_eth_hwid () +{ + local -i i + + for i in ${!cfg_eth_hwid[@]} ; do + if ! have_sys_eth_mac ${cfg_eth_hwid[$i]} ; then + unset cfg_eth_hwid[$i] + fi + done + for i in ${!sys_eth_mac[@]} ; do + if ! have_cfg_eth_hwid ${sys_eth_mac[$i]} ; then + if [ -n "${cfg_eth_hwid[$i]}" ] ; then + # cfg[#] has mac of another sys itf; + # so, add another cfg itf for this mac + # to the first available slot + for (( j=0 ; true ; j++ )) ; do + if [ -z "${cfg_eth_hwid[$j]}" ] ; then + cfg_eth_hwid[$j]=${sys_eth_mac[$i]} + break 1 + fi + done + else + cfg_eth_hwid[$i]=${sys_eth_mac[$i]} + fi + fi + done +} + +write_iftab () +{ + local -i i + + rm -f $IFTAB + for i in ${!cfg_eth_hwid[@]} ; do + echo "eth$i mac ${cfg_eth_hwid[$i]}" >> $IFTAB + done +} + +mod_bootfile_eth_hwid () +{ + local eth=$1 hwid=$2 + + sed -i '/^interfaces {$/,/^}/ { + /^ ethernet '"$eth"' {$/,/^ }$/ { + /^ *hw-id/c\ + hw-id: '"$hwid"' + }}' $BOOTFILE +} + +add_bootfile_eth_hwid () +{ + local eth=$1 hwid=$2 + + sed -i '/^interfaces {$/,/^}$/ { + /^}$/i\ + ethernet '"$eth"' {\ + hw-id: '"$hwid"'\ + } + }' $BOOTFILE +} + +update_bootfile_eth_hwid () +{ + local -i i + + for i in ${!cfg_eth_hwid[@]} ; do + if grep -q "ethernet eth$i {" $BOOTFILE ; then + mod_bootfile_eth_hwid eth$i ${cfg_eth_hwid[$i]} + else + add_bootfile_eth_hwid eth$i ${cfg_eth_hwid[$i]} + fi + done +} + +add_bootfile_vmnet () +{ + local vmnet=$1 + + sed -i '/^interfaces {/,/^}$/ { + /^}$/i\ + ethernet '"$vmnet"' {\ + } + }' $BOOTFILE +} + +update_bootfile_vmnets () +{ + for vmnet in ${sys_vmnets[@]} ; do + if ! grep -q "ethernet $vmnet {" $BOOTFILE ; then + add_bootfile_vmnet $vmnet + fi + done +} + +itfmess () +{ + load_cfg_eth_hwid + load_sys_eth_mac + load_sys_vmnets + update_cfg_eth_hwid + write_iftab + update_bootfile_eth_hwid + update_bootfile_vmnets +} + +maybe_ifrename () { + if [ -e $IFTAB ] ; then + ifrename -d -p -t + fi +} + +search_config_if_wan () { + grep "\<serial\>.*\<$1\>" $BOOTFILE >/dev/null +} + +add_new_serial_if () { + __config_additions=/tmp/__config_additions + rm -f $__config_additions + ip link show | + sed -n '/^[0-9]*: wan[0-9]*:/ s/.* \([^:]*\):.*$/\1/p' | + while read wan ; do + if ! search_config_if_wan $wan ; then + echo " serial $wan" >> $__config_additions + fi + done + if [ -e $__config_additions ]; then + rm -f /tmp/__bootfile + sed '/^interfaces {$/ r '$__config_additions \ + $BOOTFILE > /tmp/__bootfile + mv /tmp/__bootfile $BOOTFILE + rm -f $__config_additions + fi +} + +reset_promiscous_arp_response () { + echo 1 > /proc/sys/net/ipv4/conf/default/arp_filter +} + +set_ip_forwarding () { + echo 1 > /proc/sys/net/ipv4/ip_forward +} + +## if a primary address is removed from an interface promote and +## secondary available +set_promote_secondaries () { + echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries +} + +## if present use hostname from config file +maybe_hostname () { + hn=$(sed -n '/^system {$/,/^}$/ { + /^ \+host-name:/ { + s/^[^:]*: *// + s/"//g + p + } + }' $BOOTFILE ) + test -n "$hn" && hostname ${hn} +} + +## Update the version information +update_version_info () { + if [ -f ${ofr_sysconfdir}/version.master ]; then + cp ${ofr_sysconfdir}/version.master ${ofr_sysconfdir}/version + fi +} + +## Clear out apt config file--it will be filled in by rtrmgr +clear_apt_config() +{ + >/etc/apt/sources.list +} + +## snmp should be a separate package, +## but for now load the kernel module here +add_snmp_stats_module() +{ + modprobe ipt_rlsnmpstats +} + +set_reboot_on_panic() +{ + echo 1 > /proc/sys/kernel/panic_on_oops + echo 60 > /proc/sys/kernel/panic +} + +start () { + set_reboot_on_panic + itfmess + maybe_ifrename + add_new_serial_if + reset_promiscous_arp_response + set_ip_forwarding + set_promote_secondaries + maybe_hostname + update_version_info + clear_apt_config + add_snmp_stats_module +} + +case "$ACTION" in + start) start ;; + stop|restart|force-reload) true ;; # nothing to stop/restart + *) log_failure_msg "action unknown: $ACTION" ; + false ;; +esac + +exit $? + + +# Local Variables: +# mode: shell-script +# sh-indentation: 4 +# End: diff --git a/scripts/standalone_root_pw_reset b/scripts/standalone_root_pw_reset new file mode 100755 index 00000000..2d2a3d25 --- /dev/null +++ b/scripts/standalone_root_pw_reset @@ -0,0 +1,83 @@ +#!/bin/bash +# **** License **** +# Version: VPL 1.0 +# +# The contents of this file are subject to the Vyatta Public License +# Version 1.0 ("License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.vyatta.com/vpl +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc. +# All Rights Reserved. +# +# Author: Bob Gilligan <gilligan@vyatta.com> +# Description: Standalone script to reset the root passwd to factory default +# value. Note: This script can ONLY be run as a standalone +# init program by grub. +# +# **** End License **** + +# The Vyatta config file: +CF=/opt/vyatta/etc/config/config.boot + +echo "Standalone root password recovery tool." + +# +# Check to see if we are running in standalone mode. We'll +# know that we are if our pid is 1. +# +if [ "$$" != "1" ]; then + echo "This tool can only be run in standalone mode." + exit 1 +fi + +# +# OK, now we know we are running in standalone mode. Talk to the +# user. +# +echo "Do you wish to reset the reset the root password to its" +echo -n "factory setting value of \"vyatta\"? (Yes/No) [No]: " + +# +# Parse the user's response +# +read response +response=${response:0:1} + +if [ "$response" != "y" -a "$response" != "Y" ]; then + echo "OK, the root password will not be reset." + echo -n "Rebooting in 5 seconds..." + sleep 5 + echo + /sbin/reboot -f +fi + +echo "Starting process to reset the root password..." + +echo "Re-mounting root filesystem read/write..." +mount -o remount,rw / + +echo "Mounting the config filesystem..." +mount /opt/vyatta/etc/config/ + +echo "Saving backup copy of config.boot..." +cp $CF ${CF}.before_pwrecovery + +echo "Reseting the root password..." +sed -i -e "/^.* user root {/,/^.* }/s/encrypted-password: .*$/encrypted-password: \"\$1\$\$Ht7gBYnxI1xCdO\/JOnodh.\"/" $CF + +echo "Root password has been reset." +echo "Logging the activity..." +echo "`date`: Root password reset to factory value" >> /var/log/messages + +echo -n "Machine will reboot in 5 seconds..." +sync +sleep 5 +echo +/sbin/reboot -f diff --git a/scripts/vyatta-functions b/scripts/vyatta-functions new file mode 100755 index 00000000..d35b81d1 --- /dev/null +++ b/scripts/vyatta-functions @@ -0,0 +1,44 @@ +#!/bin/sh +# +# Module: vyatta-functions +# +# **** License **** +# Version: VPL 1.0 +# +# The contents of this file are subject to the Vyatta Public License +# Version 1.0 ("License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.vyatta.com/vpl +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc. +# All Rights Reserved. +# +# Author: Tom Grennan +# Date: 2006 +# Description: +# +# **** End License **** +# +# + +trap 'progress_indicator "stop"; echo; exit 1' 1 +trap 'progress_indicator "stop"; echo; exit 1' 2 + +# progress indicator for long running programs +progress_indicator () { + case "$1" in + "start") /usr/bin/progress-indicator $2& + ;; + "stop") rm -f /tmp/pi.$2 + sleep 2 + echo -n -e "\b" + ;; + esac +} + |