From c38f1d8ace7ba12d05954ab3374f3bbea6c13d46 Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Thu, 18 Oct 2007 11:16:37 -0700 Subject: initial import of systel-level scripts from fairfield/xorp and ofr-eureka/rl-system. (this is the "mess-with-your-system-config" package.) --- .gitignore | 19 + AUTHORS | 1 + COPYING | 27 ++ Makefile.am | 10 + NEWS | 1 + README | 1 + configure.ac | 30 ++ debian/README | 6 + debian/autogen.sh | 37 ++ debian/changelog | 5 + debian/compat | 1 + debian/control | 22 + debian/copyright | 34 ++ debian/docs | 2 + debian/linda | 1 + debian/lintian | 2 + debian/rules | 101 +++++ scripts/install-system.in | 918 +++++++++++++++++++++++++++++++++++++++ scripts/progress-indicator | 24 + scripts/quick-install | 907 ++++++++++++++++++++++++++++++++++++++ scripts/rl-system.init | 349 +++++++++++++++ scripts/standalone_root_pw_reset | 83 ++++ scripts/vyatta-functions | 44 ++ 23 files changed, 2625 insertions(+) create mode 100644 .gitignore create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 configure.ac create mode 100644 debian/README create mode 100755 debian/autogen.sh create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/docs create mode 100644 debian/linda create mode 100644 debian/lintian create mode 100755 debian/rules create mode 100755 scripts/install-system.in create mode 100755 scripts/progress-indicator create mode 100755 scripts/quick-install create mode 100755 scripts/rl-system.init create mode 100755 scripts/standalone_root_pw_reset create mode 100755 scripts/vyatta-functions 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 + diff --git a/NEWS b/NEWS new file mode 100644 index 00000000..78fdaa6e --- /dev/null +++ b/NEWS @@ -0,0 +1 @@ +see http://www.vyatta.com/news/ diff --git a/README b/README new file mode 100644 index 00000000..64b37b4d --- /dev/null +++ b/README @@ -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 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 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 +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 on +Thu, 18 Oct 2007 11:03:18 -0700. + +It's original content from the GIT repository + +Upstream Author: + + + +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 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 +# 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: 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 "\.*\<$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 +# 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 +} + -- cgit v1.2.3