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-c38f1d8ace7ba12d05954ab3374f3bbea6c13d46.tar.gz vyatta-cfg-system-c38f1d8ace7ba12d05954ab3374f3bbea6c13d46.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    +} + | 
