#!/bin/sh

# Make sure we're using a sane PATH
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

script_name=`basename $0`

print_toplevel_warning()
{
  echo
  echo "In order for repositories to interact with each other, all directories"
  echo "directly below the repository root (/vesta) must have globally unique"
  echo "names.  The established convention is to use an Internet domain name"
  echo "or host name that belongs to you.  You may want to use the same value"
  echo "as your realm name.  (If your realm name is 'example.com', you can use"
  echo "'/vesta/example.com'.)  As with your realm name, if you don't own a"
  echo "domain you can use your e-mail address with '@' replaced by '_'.  (If"
  echo "your e-mail address is 'john.smith@bigisp.net', you can use"
  echo "'/vesta/john.smith_bigisp.net'.)"
  echo
  echo "WARNING: The convention of deriving the name of such directories from"
  echo "domain names or e-mail addresses is the only protection against two"
  echo "people creating the same top-level directory in two different"
  echo "repositories.  If you fail to chose a globally unique name when you"
  echo "create a top-level directory, you can cause serious problems later if"
  echo "you ever try to have your Vesta installation cooperate with anyone"
  echo "else's.  For these reasons, only the special vwizard user is allowed"
  echo "to create top-level directories. (See the vrepl(1) man page for more"
  echo "information on this subject.)"
  echo
}

print_toplevel_reminder()
{
  echo
  echo "As mentioned earlier, top-level directory names must be globally"
  echo "unique.  This applies here as well, so please base the name of this"
  echo "directory on either a domain name you control (/vesta/example.com) or"
  echo "an e-mail address (/vesta/john.smith_bigisp.net)"
  echo
}

toplevel_warning_printed=0

print_toplevel_message()
{
  if [ $toplevel_warning_printed -gt 0 ]; then
    print_toplevel_reminder
  else
    print_toplevel_warning
    toplevel_warning_printed=1
  fi
}

# Make sure we're running as root
if [ `id -u` -ne 0 ]; then
  echo "$script_name: Must be run as root"
  exit 1
fi

# Check to see if we're initializing a brand new repository.
repos_md_root=`/usr/bin/vgetconfig Repository metadata_root 2>/dev/null || echo "/var/lib/vesta/"`
repos_log_dir=`/usr/bin/vgetconfig Repository log_dir 2>/dev/null || echo "repos/log/"`
repos_log_version="${repos_md_root}${repos_log_dir}version"
if [ -e "$repos_log_version" ]; then

  echo "It looks like you've already run the Vesta repository before.  This"
  echo "setup script is intended for use when you *first* install Vesta."
  echo 
  echo -n "Continue anyway? [y/n]"
  read continue

  if [ "$continue" != "y" ]; then
    echo "OK, exiting."
    exit 0
  fi
fi

echo "---------------------------------"
echo "Choose a realm name for your site"
echo "---------------------------------"
echo 
echo "Your realm name is used to form global user names of users at your"
echo "site.  Each user's global user name is formed by appending '@realm' to"
echo "their UNIX login name.  Global user names are used when interacting"
echo "with other Vesta installations for replication and remote"
echo "checkout/checkin.  Your realm name should be unique across all Vesta"
echo "installations, so it's best to use a domain name you own or a hostname"
echo "within it.  (If you chose the maildrop host for your system's users,"
echo "this can have the added benefit of making Vesta global user names work"
echo "as e-mail addresses.)"
echo 
echo "If you do not have a registered domain name of your own, a good"
echo "alternative is to use a working email address that you intend to keep"
echo "permanently.  Simply change the '@' to an '_', and you have a globally"
echo "unique string which you can use as your realm name. (If your e-mail"
echo "address is 'john.smith@bigisp.net', you can use"
echo "'john.smith_bigisp.net' for your realm name.)"
echo 
echo "See the repository(8) man page section on access control for more"
echo "information on realm names, global user names, and how they are used."

realm=""
while [ -z "$realm" ]; do

  echo
  echo -n "Realm name? "

  # Default the realm based on the DNS domain name, as long as it
  # contains a dot.
  default_realm=`hostname -d`
  if ! echo $default_realm | grep -q '\.'; then
    default_realm=""
  else
    echo -n " [$default_realm] " 
  fi

  # Read the realm, defaulting if necessary.
  read realm
  if [ -z "$realm" ]; then
    realm=$default_realm
  fi

  # Still empty?  Can't continue until the user gives us a realm name.
  if [ -z "$realm" ]; then
    echo
    echo "You MUST enter a realm name."
  fi

done

echo
echo "---------------"
echo "Server hostname"
echo "---------------"
echo
echo "What hostname will clients use to contact your Vesta server?  For a"
echo "single host installation 'localhost' is acceptable.  However,"
echo "collaborating with remote repositories will be easier if you use a"
echo "globally unique hostname (i.e. one in a domain name you control)."

default_host=`hostname --long`
echo
echo -n "Server hostname? [$default_host] "

# Read the hostname, defaulting if necessary.
read server_host
if [ -z "$server_host" ]; then
  server_host=$default_host
fi

echo
echo "---------------------"
echo "Alternate master hint"
echo "---------------------"
echo 
echo "When you create new objects in your repository, it is the 'master'"
echo "copy of those objects.  When collaborating with remote repositories,"
echo "Vesta uses attributes that record the address of the master"
echo "repository.  By default this uses the same host and port that local"
echo "clients connect with:"
echo
echo "  $server_host:21776"
echo
echo "But you can set an alternate.  You can think of this as the 'public'"
echo "or 'advertised' address of your repository.  (Laptop users may want"
echo "set this to the hostname your laptop has when attached to a"
echo "particular network.)"
echo
echo -n "Would you like to set an alternate master hint? [y/n] "
read add_master_hint
if [ \( "$add_master_hint" = "y" \) -o \( "$add_master_hint" = "Y" \) ]; then
  echo
  echo "The master hint must be a hostname followed by a colon followed by a"
  echo "port number like this:"
  echo
  echo "  vesta.example.com:1234"
  echo
  echo -n "Enter alternate master hint: "

  read master_hint
fi

echo
echo "-----------------"
echo "Export file setup"
echo "-----------------"
echo 
echo "This script will write a default repository export file"
echo "(/etc/vesta/repos.export) which grants access ONLY from the server"
echo "machine itself.  If you plan on having other hosts act as clients to"
echo "this server, you'll need to modify the export file.  See the"
echo "repository(8) man page for the format of the export file."
echo
echo -n "Press return to continue."
read unused

case "`uname -m`" in
  alpha)
    if [ -f /etc/redhat-release ] && grep -q "Red Hat Linux release 7" /etc/redhat-release; then
	default_model_fname="linux_alpha_rh7.main.ves linux_alpha.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '4\.0' /etc/debian_version; then
	default_model_fname="linux_alpha_deb_etch.main.ves linux_alpha_deb_sarge.main.ves linux_alpha.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '3\.1' /etc/debian_version; then
	default_model_fname="linux_alpha_deb_sarge.main.ves linux_alpha.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '3\.0' /etc/debian_version; then
	default_model_fname="linux_alpha_deb_woody.main.ves linux_alpha.main.ves"
    else
	default_model_fname="linux_alpha.main.ves"
    fi
  ;;
  i[3-9]86)
    if [ -f /etc/redhat-release ] && grep -q "Red Hat Linux release 7" /etc/redhat-release; then
	default_model_fname="linux_i386_rh7.main.ves linux_i386.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '4\.0' /etc/debian_version; then
	default_model_fname="linux_i386_deb_etch.main.ves linux_i386_deb_sarge.main.ves linux_i386.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '3\.1' /etc/debian_version; then
	default_model_fname="linux_i386_deb_sarge.main.ves linux_i386.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '3\.0' /etc/debian_version; then
	default_model_fname="linux_i386_deb_woody.main.ves linux_i386.main.ves"
    else
	default_model_fname="linux_i386.main.ves"
    fi
  ;;
  ppc)
    if [ -f /etc/debian_version ] && grep -q '4\.0' /etc/debian_version; then
	default_model_fname="linux_i386_deb_etch.main.ves linux_ppc_deb_sarge.main.ves linux_ppc.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '3\.1' /etc/debian_version; then
	default_model_fname="linux_ppc_deb_sarge.main.ves linux_ppc.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '3\.0' /etc/debian_version; then
	default_model_fname="linux_ppc_deb_woody.main.ves linux_ppc.main.ves"
    else
	default_model_fname="linux_ppc.main.ves"
    fi
  ;;
  sparc)
    if [ -f /etc/debian_version ] && grep -q '4\.0' /etc/debian_version; then
	default_model_fname="linux_sparc_deb_etch.main.ves linux_sparc_deb_sarge.main.ves linux_sparc.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '3\.1' /etc/debian_version; then
	default_model_fname="linux_sparc_deb_sarge.main.ves linux_sparc.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '3\.0' /etc/debian_version; then
	default_model_fname="linux_sparc_deb_woody.main.ves linux_sparc.main.ves"
    else
	default_model_fname="linux_sparc.main.ves"
    fi
    default_model_fname="linux_sparc.main.ves"
  ;;
  x86_64)
    if [ -f /etc/debian_version ] && grep -q '4\.0' /etc/debian_version; then
	default_model_fname="linux_x86_64_deb_etch.main.ves linux_x86_64_deb_sarge.main.ves linux_x86_64.main.ves"
    elif [ -f /etc/debian_version ] && grep -q '3\.1' /etc/debian_version; then
	default_model_fname="linux_x86_64_deb_sarge.main.ves linux_x86_64.main.ves"
    else
	default_model_fname="linux_x86_64.main.ves"
    fi
  ;;
  *)
    default_model_fname="linux_i386.main.ves"
  ;;
esac

echo
echo "------------------"
echo "Default model name"
echo "------------------"
echo 
echo "Often a Vesta package will contain build descriptions for multiple"
echo "platforms.  There's a configuration setting for which model name(s)"
echo "should be evaluated by default.  This should match the platform you're"
echo "running on.  (The same value will also be used late in this script to"
echo "replicate from pub.vestasys.org.)"
echo
echo "In most cases you can use the default value.  If you chose to enter a"
echo "different one, please choose one of the established names:"
echo
echo "  linux_alpha.main.ves"
echo "  linux_i386.main.ves"
echo "  linux_ppc.main.ves"
echo "  linux_sparc.main.ves"
echo
echo -n "Default model name [$default_model_fname]: "

# Read the hostname, defaulting if necessary.
read model_fname
if [ -z "$model_fname" ]; then
  model_fname=$default_model_fname
fi

echo
echo "----------------------------"
echo "Create a 'foreign' hierarchy"
echo "----------------------------"
echo 
echo "If you would like to make local branches of packages you replicate"
echo "from peer repositories (e.g. if you would like to modify the source"
echo "code for Vesta), you'll need a directory in which to place those local"
echo "branches."
echo
echo "This is useful if the master repository of the package you want to"
echo "modify is inaccessible or won't grant write permission within its"
echo "directory hierarchy."
echo
echo "You probably want to set up a foreign hierarchy if you're installing"
echo "Vesta onto a laptop or other machine which is not always connect to"
echo "the Internet."
echo
echo "(You can set up a foreign hierarchy later by creating a directory"
echo "under /vesta and setting [UserInterface]ForeignParent in the"
echo "configuration file.)"
echo
echo -n "Create a top-level directory for use as a foreign hierarchy? [y/n] "
read make_foreign_dir
if [ \( "$make_foreign_dir" = "y" \) -o \( "$make_foreign_dir" = "Y" \) ]; then
  print_toplevel_message
  echo -n "Name of foreign directory? [foreign.$realm] "
  read foreign_dir_name
  if [ -z "$foreign_dir_name" ]; then
    foreign_dir_name="foreign.$realm"
  fi
else
  foreign_dir_name=""
fi

echo
echo "---------------------------"
echo "Writing configuration files"
echo "---------------------------"
echo 
echo "Based on the responses you've given:"
echo 
echo "  realm              : $realm"
echo "  server host        : $server_host"
echo "  default model name : $model_fname"
if [ ! -z "$master_hint" ]; then
  echo "  master hint        : $master_hint"
fi
if [ ! -z "$foreign_dir_name" ]; then
  echo "  foreign hierarchy  : $foreign_dir_name"
fi
echo 
echo "This script will overwrite the following files:"
echo 
echo "  /etc/vesta/repos.export"
echo "  /var/lib/vesta/vesta.cfg"
echo 
echo -n "Proceed? [y/n] "

read continue
if [ \( "$continue" != "y" \) -a \( "$continue" != "Y" \) ]; then
  echo "Exiting."
  exit 0
fi
echo -n "Save a backup of the old files before overwriting? [y/n] "

read backup
if [ \( "$backup" = "y" \) -o \( "$backup" = "Y" \) ]; then
  if [ -e /etc/vesta/repos.export ]; then
    mv /etc/vesta/repos.export /etc/vesta/repos.export.bak
  fi
  if [ -e /var/lib/vesta/vesta.cfg ]; then
    mv /var/lib/vesta/vesta.cfg /var/lib/vesta/vesta.cfg.bak
  fi
fi

# Write the export file

echo "# `date`: generated by $script_name" > /etc/vesta/repos.export
echo "# See the repository(8) man page for the format of this file." >> /etc/vesta/repos.export
echo >> /etc/vesta/repos.export
echo "# The explicitly given server host:" >> /etc/vesta/repos.export
echo "$server_host: allow unix, allow global $realm" >> /etc/vesta/repos.export
echo >> /etc/vesta/repos.export
echo '# The hostnames returned by "hostname" and "hostname --long":' >> /etc/vesta/repos.export
for host in `hostname ; hostname --long`; do
  echo "$host: allow unix, allow global $realm" >> /etc/vesta/repos.export
done
echo >> /etc/vesta/repos.export
echo "# All the IPs on active interfaces when $script_name was run:" >> /etc/vesta/repos.export
for ip in `/sbin/ifconfig | grep 'inet addr:' | sed -e 's/.*inet addr:\([0-9.]*\) .*/\1/'`; do
  echo "$ip: allow unix, allow global $realm">> /etc/vesta/repos.export
done

chown vadmin.vadmin /etc/vesta/repos.export
chmod 664 /etc/vesta/repos.export

# Write the vesta.cfg file

# Determine the vforeign UID/GID
vforeign_uid=`id -u vforeign`
vforeign_gid=`id -g vforeign`

if [ ! -z "$master_hint" ]; then
  master_hint="master_hint = $master_hint"
fi

if [ ! -z "$foreign_dir_name" ]; then
  foreign_dir_cfg_line="ForeignParent = /vesta/$foreign_dir_name"
else
  foreign_dir_cfg_line=""
fi 

echo "; `date`: generated by $script_name" > /var/lib/vesta/vesta.cfg
cat /var/lib/vesta/vesta.cfg.template | sed \
  -e "s/%%%%%Repository realm%%%%%/$realm/" \
  -e "s/%%%%%host name%%%%%/$server_host/" \
  -e "s/%%%%%vforeign uid%%%%%/$vforeign_uid/" \
  -e "s/%%%%%vforeign gid%%%%%/$vforeign_gid/" \
  -e "s/%%%%%DefaultMain%%%%%/$model_fname/" \
  -e "s/%%%%%master_hint%%%%%/$master_hint/" \
  -e "s|%%%%%ForeignParent%%%%%|$foreign_dir_cfg_line|" \
  >> /var/lib/vesta/vesta.cfg

chown vadmin.vadmin /var/lib/vesta/vesta.cfg
chmod 664 /var/lib/vesta/vesta.cfg

# Start the repository
if /etc/init.d/vrepository status; then
  /etc/init.d/vrepository restart
else
  /etc/init.d/vrepository start
fi

# Mount the repository (which creates the mount points if needed)
if /etc/init.d/vmount status; then
  /etc/init.d/vmount restart
else
  /etc/init.d/vmount start
fi

# Create /vesta-work/.tmp, which is used by vupdate
if [ ! -e /vesta-work/.tmp ]; then
  mkdir /vesta-work/.tmp
  chown vadmin /vesta-work/.tmp
  chmod 777 /vesta-work/.tmp
fi

# Make sure that normal users can create a directory work their
# chekcout working directories.
chown vadmin /vesta-work
chmod 777 /vesta-work

# Start (or restart) the RunToolServer and cache server
if /etc/init.d/vruntool status; then
  /etc/init.d/vruntool restart
else
  /etc/init.d/vruntool start
fi
if /etc/init.d/vcache status; then
  /etc/init.d/vcache restart
else
  /etc/init.d/vcache start
fi

# If the user asked for a top-level directory for foreign checkouts,
# create it before replicating
if [ ! -z "$foreign_dir_name" ]; then
  echo
  echo "Creating /vesta/$foreign_dir_name (as previously requested)."
  echo "(The following warning from vmkdir is just a repeat of the "
  echo "earlier warning from this script.  You can safely ignore it.)"
  echo
  su - vwizard --command="cd /vesta ; echo y | vmkdir -p '$foreign_dir_name' ; chmod 777 '$foreign_dir_name'"
fi

echo
echo "-------------------------------"
echo "Replicate from pub.vestasys.org"
echo "-------------------------------"
echo 
echo "This script can invoke the Vesta replicator (see vrepl(1)) to populate"
echo "your repository with:"
echo 
echo "  - The source code and build instructions for Vesta"
echo "  - Examples"
echo "  - A build environment for your platform"
echo 
echo "This is recommended for new users, but will take several minutes."
echo 
echo -n "Run the replicator? [y/n] "
read replicate
if [ \( "$replicate" = "y" \) -o \( "$replicate" = "Y" \) ]; then
    direcs=''
    for m in $model_fname; do
	direcs="$direcs -e@ '/vesta/vestasys.org/examples/*/LAST/$m' -e@ '/vesta/vestasys.org/vesta/release/LAST/$m'"
    done
    su - vadmin --command="vattrib -a '#replicate-from' pub.vestasys.org:21776 /vesta ; vrepl -v -s pub.vestasys.org:21776 $direcs"
fi

echo
echo "-----------------------------------------------------------------"
echo "Make a directory tree for new packages created at your repository"
echo "-----------------------------------------------------------------"
echo 
echo "If you'd like to create your own packages in Vesta (as opposed to"
echo "using and checking out packages replicated from a peer repository),"
echo "you'll need to create your own top-level directory."
echo
echo -n "Would you like to create a top-level directory? [y/n] "
read make_top_level
if [ \( "$make_top_level" = "y" \) -o \( "$make_top_level" = "Y" \) ]; then
  print_toplevel_message
  echo -n "Name of top-level directory? [play.$realm] "
  read top_level_name
  if [ -z "$top_level_name" ]; then
    top_level_name="play.$realm"
  fi
  echo
  echo "(The following warning from vmkdir is just a repeat of the "
  echo "earlier warning from this script.  You can safely ignore it.)"
  echo
  su - vwizard --command="cd /vesta ; echo y | vmkdir -p '$top_level_name' ; chmod 777 '$top_level_name'"
fi
