From 00b3ae0c3f59ff639d8d95ab6a94ff335ed488ee Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 18 Sep 2011 18:56:50 +0200 Subject: add ppsnapback-install wizard --- ppsnapback-install | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100755 ppsnapback-install diff --git a/ppsnapback-install b/ppsnapback-install new file mode 100755 index 0000000..a42a84c --- /dev/null +++ b/ppsnapback-install @@ -0,0 +1,267 @@ +#!/bin/bash +# +# ppsnapback-install - ppsnapback installation wizard +# +# Copyright (C) 2011 Nicolas Schodet. +# +# See end of file for documentation, copyright and license. +# +# Man page can be generated using: +# +# $ pod2man -c '' -r '' ppsnapback-install > ppsnapback-install.1 +# + +fatal () { + echo $* >&2 + exit 1 +} +usage () { + fatal "Usage: $0 [options] MODULE [BACKUP_DIR]" +} +ask () { + local question=$1 + local default=$2 + local validate=$3 + local response + [[ -n $default ]] && question="$question [$default]" + while true; do + echo -n "$question " >&2 + read response + [[ -z $response ]] && response="$default" + [[ -z $validate ]] && break + response=$($validate "$response") && break + done + echo "$response" +} +validate_yesno () { + case "$1" in + [yY]|[yY][eE][sS]) echo yes ;; + [nN]|[nN][oO]) echo no ;; + *) + echo "please answer yes or no" >&2 + return 1 + ;; + esac + return 0 +} + +# Check parameter and check configuration does not exists. +btype=push +bpath= +hostname=ASK +remote= +rppsnapback= +while getopts 't:p:h:r:R:' option; do + case "$option" in + t) btype="$OPTARG" ;; + p) bpath="$OPTARG" ;; + h) hostname="$OPTARG" ;; + r) remote="$OPTARG" ;; + R) rppsnapback="$OPTARG" ;; + ?) usage ;; + esac +done +shift $((OPTIND-1)) + +MODULE=${1:-NONE} +BASEDIR=${2:-$HOME/backups} +MD=$BASEDIR/$MODULE + +[[ $MODULE = NONE ]] && usage +[[ ! -d $BASEDIR ]] && fatal "backup directory '$BASEDIR' does not exist" +[[ -e $MD ]] && fatal "module directory for '$MODULE' exists" + +# Cleanup code. +cleanup () { + echo "cleaning up..." + [[ -f $MD/config ]] && rm "$MD/config" + [[ -f $MD/exclude ]] && rm "$MD/exclude" + [[ -f $MD/$MODULE-backup-key ]] && rm "$MD/$MODULE-backup-key" + [[ -f $MD/$MODULE-backup-key.pub ]] && rm "$MD/$MODULE-backup-key.pub" + [[ -d $MD ]] && rmdir "$MD" +} + +# Request functions. +validate_path () { + if [[ ! -d $1 ]]; then + echo "path does not exist" >&2 + return 1 + fi + echo "$1" +} +need_path () { + [[ -d $bpath ]] && return + bpath=$(ask "Path to backup?" "$PWD/" validate_path) +} +need_hostname () { + [[ $hostname = ASK ]] || return + local use_hostname=$(ask "Use from= in SSH authorized_keys?" yes \ + validate_yesno) + if [[ $use_hostname = yes ]]; then + hostname=$(ask "Hostname?" "$(hostname -f)") + else + hostname= + fi +} +validate_remote () { + case "$1" in + *:*) + echo "remote should not include path, only host" >&2 + return 1 + ;; + '') + echo "please enter something" >&2 + return 1 + ;; + esac + echo "$1" +} +need_remote () { + if [[ -n $remote ]]; then + remote=$(validate_remote "$remote") || exit 1 + else + remote=$(ask "Remote host?" '' validate_remote) + fi +} +validate_rppsnapback () { + case "$1" in + /?*) echo "$1" ;; + *) + echo "please enter absolute path" >&2 + return 1 + ;; + esac +} +need_rppsnapback () { + [[ -n $rppsnapback ]] && return + rppsnapback=$(ask "Path to remote ppsnapback script?" \ + '/usr/local/bin/ppsnapback' validate_rppsnapback) +} + +# Proceed with installation. +case "$btype" in + push) + need_path + need_hostname + need_remote + need_rppsnapback + trap cleanup EXIT + mkdir "$MD" || fatal "cannot create module directory" + ssh-keygen -t rsa -f "$MD/$MODULE-backup-key" \ + -C "${hostname:+$hostname }$MODULE backup key" -N '' \ + || fatal "cannot create backup key" + cat > "$MD/config" <<-EOF || fatal "cannot write module configuration" + path="$bpath" + remote="$remote" + privkey="$MODULE-backup-key" + EOF + touch "$MD/exclude" + authorized_keys="${hostname:+from=\"$hostname\",}\ +command=\"$rppsnapback $MODULE\",\ +no-pty,no-port-forwarding,no-x11-forwarding,no-agent-forwarding \ +$(< "$MD/$MODULE-backup-key.pub")" + RMD="backups/$MODULE" + echo $authorized_keys | ssh "$remote" "mkdir \"$RMD\" \ + && touch \"$RMD/config\" \ + && cat >> .ssh/authorized_keys" || fatal "cannot configure remote" + ;; + *) + fatal "only push type supported" + ;; +esac +trap - EXIT + +exit 0 + +__END__ + +=head1 NAME + +ppsnapback-install - ppsnapback installation wizard + +=head1 SYNOPSIS + +B [I] I [I] + +=head1 DESCRIPTION + +B will ask for parameters to create a new B +module. This include: + +=over + +=item * creation of the local configuration, + +=item * creation of a SSH backup key, + +=item * creation of the remote configuration, + +=item * update of remote authorized_keys file. + +=back + +=head1 OPTIONS + +Options can be used to avoid a parameter prompt. If a parameter is missing, +B will ask the user to provide it. + +=over + +=item B<-t> I + +Choose configuration type. For the moment, the only syported type is I. + +=item B<-p> I + +Path to backup. Will default to current directory. + +=item B<-h> I + +Local machine hostname. This is used to limit SSH authorization to the +current machine address. Use an empty string to disable. + +=item B<-r> I + +Remote machine or location. + +=item B<-R> I + +Absolute path to ppsnapback on the remote machine. + +=back + +=head1 RESTRICTIONS + +For the moment, the only supported configuration type is I, which +corresponds to the paragraph "Push Remote Backup Repository With Snapshot +Rotation" in B man page. + +Remote backup directory is always $HOME/backups. + +=head1 SEE ALSO + +ppsnapback(1) + +=head1 AUTHOR + +Nicolas Schodet, http://ni.fr.eu.org/ppsnapback + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2011 Nicolas Schodet. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place - Suite 330, Boston, MA 02111-1307, USA. + +=cut + -- cgit v1.2.3