#!/bin/ash
###########################################################
# prepostinst, a prepost-aware deployment postinst script
###########################################################
# Copyright (C) 2006 INRIA
# Produced at Institut National de Recherche en Informatique
# Written by Xavier Delaruelle <xavier.delaruelle@loria.fr>
# Written by Julien Leduc <julien.leduc@lri.fr>
#  
# This file is part of Grid'5000 project.
# For details, see <https://www.grid5000.fr>.
#  
# 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.
###########################################################

# argument check
[ -z "$1" ] && exit 1

# versioning
POSTINST_VERSION=1.0

# where are we ?
POST_DIR=$1
PREPOST_DIR=$1/prepost

# cp options keep file mode but not ownership : user owns his 
# postinstall files but they must be owned by root on the deployed system.
CP_OPTS='-dr --preserve=mode'

# load site-specific variables
. $PREPOST_DIR/postvar-1.0.ash 

# to disable reporting option remove REPORT_FILE variable
REPORT_FILE=$DEST_DIR/root/postinst.log


# Functions
###########################################################

# List all files of a dir and its subdirs without find
# Usage: filelist dir
filelist()
{

local curdir=''

# produce the output of "find $1 -not -type d" 
# with ls, echo and sed instead of find
ls --almost-all --format=single-column --recursive --file-type $1 \
| while read line; do
  case "$line" in
  *:) curdir=$(echo "$line" | sed -e 's|:||') ;;
  */) ;;
  *) [ -n "$line" ] && echo "$curdir/$line" ;;
  esac
done

}


# Set specific file's ownership on destination system
# Usage: setown ownfile
setown()
{

# ownership definition are stored into a file
local ownfile=$1

# Set ownership on destination system for each ownership definition
grep --extended-regexp --invert-match '^(#|$)' $ownfile 2>/dev/null \
  | while read own file; do \
      chroot $DEST_DIR chown $own $file; \
    done

# log ownership settings
report "$(cat $ownfile | sed -e 's|^|  |')"

}


# Copy a data tree to destination system
# Usage: copydir srcdir
copydir()
{

local srcdir=$1

# copy data tree
cp $CP_OPTS $srcdir/* $DEST_DIR

# log copied files
report "$(filelist $srcdir | sed -e s\|$srcdir\|\ \ \|)"

}


# Replace variable references to their values in one file
# Usage: substfile file
substfile()
{

local file=$1
local sedfile=${file}.sed
local tmpfile=${file}.subst

# collect file's variable references
grep --extended-regexp --only-matching '<\[[A-Z_]+\]>' $file \
  | grep --extended-regexp --only-matching '[A-Z_]+' \
  | while read varref; do
      # fetch reference value and format it to escape newline
      varval=$(echo "$(eval echo \"\$${varref}\")" | sed -e '$!s|$|\\|')
      # build reference replacement expression
      echo "s|<\\[${varref}\\]>|$varval|"
    done >>$sedfile

# replace each reference by its corresponding value
if [ -s $sedfile ]; then
  sed -f $sedfile $file > $tmpfile
  # replace original file in a way preserving original permission
  cp $tmpfile $file
  rm $tmpfile
fi

# remove temp file
rm $sedfile

}

# Replace variable references in each files of a specified directory
# Usage: substdir dir
substdir()
{

filelist $1 | while read file; do
  substfile $file
done

}


# Output text in report's file
# Uage: report text
report()
{

if [ -n "$REPORT_FILE" ]; then
  echo "$1" >>$REPORT_FILE
fi

}

# Initialize report generation
# Usage: reportinit
reportinit()
{

if [ -n "$REPORT_FILE" ]; then
  # init report file
  cat /dev/null >$REPORT_FILE

  # generate header
  report "# postinst: ${POSTINST_VERSION}"
  report "# postvar: ${_VERSION}-${_RELEASE}"
fi

}

# Begin a new section in the report
# Usage: reportsect title
reportsect()
{

if [ -n "$REPORT_FILE" ]; then
  report ''
  report "$1"
fi

}


# Main
###########################################################

# init log redirection
reportinit


# preinstall dir copies
reportsect 'Preinstall files'
copydir $NODE_DIR

# preinstall ownership settings
if [ -s $NODE_OWN ]; then
  reportsect 'Preinstall ownerships'
  setown $NODE_OWN
fi

# postinstall dir copy
reportsect 'Postinstall files'
substdir $POST_DIR/dest
copydir $POST_DIR/dest

# postinstall ownership setting
if [ -s $POST_DIR/dest.own ]; then 
  reportsect 'Postinstall ownerships'
  setown $POST_DIR/dest.own
fi


# init root's SSH dir if missing
[ ! -d $DEST_DIR/root/.ssh ] && mkdir --mode=700 $DEST_DIR/root/.ssh

# authorize root & deploy without harming user's keys
if [ -s $DEST_DIR/root/.ssh/authorized_keys ]; then
  grep --extended-regexp --invert-match '(deploy|root)@' \
    $DEST_DIR/root/.ssh/authorized_keys >>$SITE_AUTH_KEYS
fi

# install new file
cp $CP_OPTS $SITE_AUTH_KEYS $DEST_DIR/root/.ssh/authorized_keys


exit 0
