Home | History | Annotate | Download | only in site_utils
      1 #!/bin/bash
      2 #
      3 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 set -e
      7 
      8 function usage() {
      9   cat >&2 <<EOT
     10 Usage: setup_dev_autotest.sh [-pavnms]
     11 
     12 Install and configure software needed to run autotest locally.
     13 If you're just working on tests, you do not need to run this.
     14 Options:
     15   -p Desired Autotest DB password. Must be non-empty.
     16   -a Absolute path to autotest source tree.
     17   -v Show info logging from build_externals.py and compile_gwt_clients.py
     18   -n Non-interactive mode, doesn't ask for any user input.
     19      Requires -p and -a to be set.
     20   -m Allow remote access for database.
     21   -s Skip steps handled via puppet in prod.
     22      This is a transitional flag used to skip certain steps as they are migrated
     23      to puppet for use in the autotest lab. Not to be used by developers.
     24 
     25 EOT
     26 }
     27 
     28 
     29 function get_y_or_n_interactive {
     30     local ret
     31     while true; do
     32         read -p "$2" yn
     33         case $yn in
     34             [Yy]* ) ret="y"; break;;
     35             [Nn]* ) ret="n"; break;;
     36             * ) echo "Please enter y or n.";;
     37         esac
     38     done
     39     eval "$1=\$ret"
     40 }
     41 
     42 function get_y_or_n {
     43   local ret=$3
     44   if [ "${noninteractive}" = "FALSE" ]; then
     45     get_y_or_n_interactive sub "$2"
     46     ret=$sub
     47   fi
     48   eval "$1=\$ret"
     49 }
     50 
     51 AUTOTEST_DIR=
     52 PASSWD=
     53 verbose="FALSE"
     54 noninteractive="FALSE"
     55 remotedb="FALSE"
     56 skip_puppetized_steps="FALSE"
     57 while getopts ":p:a:vnmsh" opt; do
     58   case ${opt} in
     59     a)
     60       AUTOTEST_DIR=$OPTARG
     61       ;;
     62     p)
     63       PASSWD=$OPTARG
     64       ;;
     65     v)
     66       verbose="TRUE"
     67       ;;
     68     n)
     69       noninteractive="TRUE"
     70       ;;
     71     m)
     72       remotedb="TRUE"
     73       ;;
     74     s)
     75       skip_puppetized_steps="TRUE"
     76       ;;
     77     h)
     78       usage
     79       exit 0
     80       ;;
     81     \?)
     82       echo "Invalid option: -$OPTARG" >&2
     83       usage
     84       exit 1
     85       ;;
     86     :)
     87       echo "Option -$OPTARG requires an argument." >&2
     88       usage
     89       exit 1
     90       ;;
     91   esac
     92 done
     93 
     94 if [[ "${skip_puppetized_steps}" == "TRUE" ]]; then
     95   echo "Requested to skip certain steps. Will tell you when I skip things."
     96 fi
     97 
     98 if [[ $EUID -eq 0 ]]; then
     99   echo "Running with sudo / as root is not recommended"
    100   get_y_or_n verify "Continue as root? [y/N]: " "n"
    101   if [[ "${verify}" = 'n' ]]; then
    102     echo "Bailing!"
    103     exit 1
    104   fi
    105 fi
    106 
    107 if [ "${noninteractive}" = "TRUE" ]; then
    108   if [ -z "${AUTOTEST_DIR}" ]; then
    109     echo "-a must be specified in non-interactive mode." >&2
    110     exit 1
    111   fi
    112   if [ -z "${PASSWD}" ]; then
    113     echo "-p must be specified in non-interactive mode." >&2
    114     exit 1
    115   fi
    116 fi
    117 
    118 
    119 if [ -z "${PASSWD}" ]; then
    120   read -s -p "Autotest DB password: " PASSWD
    121   echo
    122   if [ -z "${PASSWD}" ]; then
    123     echo "Empty passwords not allowed." >&2
    124     exit 1
    125   fi
    126   read -s -p "Re-enter password: " PASSWD2
    127   echo
    128   if [ "${PASSWD}" != "${PASSWD2}" ]; then
    129     echo "Passwords don't match." >&2
    130     exit 1
    131   fi
    132 fi
    133 
    134 if [ -z "${AUTOTEST_DIR}" ]; then
    135   CANDIDATE=$(dirname "$(readlink -f "$0")" | egrep -o '(/[^/]+)*/files')
    136   read -p "Enter autotest dir [${CANDIDATE}]: " AUTOTEST_DIR
    137   if [ -z "${AUTOTEST_DIR}" ]; then
    138     AUTOTEST_DIR="${CANDIDATE}"
    139   fi
    140 fi
    141 
    142 
    143 # Sanity check AUTOTEST_DIR. If it's null, or doesn't exist on the filesystem
    144 # then die.
    145 if [ -z "${AUTOTEST_DIR}" ]; then
    146   echo "No AUTOTEST_DIR. Aborting script."
    147   exit 1
    148 fi
    149 
    150 if [ ! -d "${AUTOTEST_DIR}" ]; then
    151   echo "Directory $AUTOTEST_DIR does not exist. Aborting script."
    152   exit 1
    153 fi
    154 
    155 
    156 SHADOW_CONFIG_PATH="${AUTOTEST_DIR}/shadow_config.ini"
    157 echo "Autotest supports local overrides of global configuration through a "
    158 echo "'shadow' configuration file.  Setting one up for you now."
    159 CLOBBER=0
    160 if [ -f ${SHADOW_CONFIG_PATH} ]; then
    161   get_y_or_n clobber "Clobber existing shadow config? [Y/n]: " "n"
    162   if [[ "${clobber}" = 'n' ]]; then
    163     CLOBBER=1
    164     echo "Refusing to clobber existing shadow_config.ini."
    165   else
    166     echo "Clobbering existing shadow_config.ini."
    167   fi
    168 fi
    169 
    170 CROS_CHECKOUT=$(readlink -f "$AUTOTEST_DIR/../../../..")
    171 
    172 # Create clean shadow config if we're replacing it/creating a new one.
    173 if [ $CLOBBER -eq 0 ]; then
    174   cat > "${SHADOW_CONFIG_PATH}" <<EOF
    175 [AUTOTEST_WEB]
    176 host: localhost
    177 password: ${PASSWD}
    178 readonly_host: localhost
    179 readonly_user: chromeosqa-admin
    180 readonly_password: ${PASSWD}
    181 
    182 [SERVER]
    183 hostname: localhost
    184 
    185 [SCHEDULER]
    186 drones: localhost
    187 
    188 [CROS]
    189 source_tree: ${CROS_CHECKOUT}
    190 # Edit the following line as needed.
    191 #dev_server: http://10.10.10.10:8080
    192 enable_ssh_tunnel_for_servo: True
    193 enable_ssh_tunnel_for_chameleon: True
    194 enable_ssh_connection_for_devserver: True
    195 enable_ssh_tunnel_for_moblab: True
    196 EOF
    197   echo -e "Done!\n"
    198 fi
    199 
    200 echo "Installing needed Ubuntu packages..."
    201 PKG_LIST="libapache2-mod-wsgi gnuplot apache2-mpm-prefork unzip \
    202 python-imaging libpng12-dev libfreetype6-dev \
    203 sqlite3 python-pysqlite2 git-core pbzip2 openjdk-6-jre openjdk-6-jdk \
    204 python-crypto  python-dev subversion build-essential python-setuptools \
    205 python-numpy python-scipy libmysqlclient-dev"
    206 
    207 if ! sudo apt-get install -y ${PKG_LIST}; then
    208   echo "Could not install packages: $?"
    209   exit 1
    210 fi
    211 echo -e "Done!\n"
    212 
    213 AT_DIR=/usr/local/autotest
    214 echo -n "Bind-mounting your autotest dir at ${AT_DIR}..."
    215 sudo mkdir -p "${AT_DIR}"
    216 sudo mount --bind "${AUTOTEST_DIR}" "${AT_DIR}"
    217 echo -e "Done!\n"
    218 
    219 sudo chown -R "$(whoami)" "${AT_DIR}"
    220 
    221 EXISTING_MOUNT=$(egrep "/.+[[:space:]]${AT_DIR}" /etc/fstab || /bin/true)
    222 if [ -n "${EXISTING_MOUNT}" ]; then
    223   echo "${EXISTING_MOUNT}" | awk '{print $1 " already automounting at " $2}'
    224   echo "We won't update /etc/fstab, but you should have a line line this:"
    225   echo -e "${AUTOTEST_DIR}\t${AT_DIR}\tbind defaults,bind\t0\t0"
    226 else
    227   echo -n "Adding aforementioned bind-mount to /etc/fstab..."
    228   # Is there a better way to elevate privs and do a redirect?
    229   sudo su -c \
    230     "echo -e '${AUTOTEST_DIR}\t${AT_DIR}\tbind defaults,bind\t0\t0' \
    231     >> /etc/fstab"
    232   echo -e "Done!\n"
    233 fi
    234 
    235 echo -n "Reticulating splines..."
    236 
    237 if [ "${verbose}" = "TRUE" ]; then
    238   "${AT_DIR}"/utils/build_externals.py
    239   "${AT_DIR}"/utils/compile_gwt_clients.py -a
    240 else
    241   "${AT_DIR}"/utils/build_externals.py &> /dev/null
    242   "${AT_DIR}"/utils/compile_gwt_clients.py -a &> /dev/null
    243 fi
    244 
    245 echo -e "Done!\n"
    246 
    247 echo "Start setting up Database..."
    248 get_y_or_n clobberdb "Clobber MySQL database if it exists? [Y/n]: " "n"
    249 opts_string="-p ${PASSWD} -a ${AT_DIR}"
    250 if [[ "${clobberdb}" = 'y' ]]; then
    251   opts_string="${opts_string} -c"
    252 fi
    253 if [[ "${remotedb}" = 'TRUE' ]]; then
    254   opts_string="${opts_string} -m"
    255 fi
    256 "${AT_DIR}"/site_utils/setup_db.sh ${opts_string}
    257 
    258 echo -e "Done!\n"
    259 
    260 echo "Configuring apache to run the autotest web interface..."
    261 if [ ! -d /etc/apache2/run ]; then
    262   sudo mkdir /etc/apache2/run
    263 fi
    264 sudo ln -sf "${AT_DIR}"/apache/apache-conf \
    265   /etc/apache2/sites-available/autotest-server.conf
    266 
    267 # Disable currently active default
    268 sudo a2dissite 000-default default || true
    269 sudo a2ensite autotest-server.conf
    270 
    271 sudo a2enmod rewrite
    272 sudo a2enmod wsgi
    273 sudo a2enmod version || true  # built-in on trusty
    274 sudo a2enmod headers
    275 sudo a2enmod cgid
    276 
    277 # Setup permissions so that Apache web user can read the proper files.
    278 chmod -R o+r "${AT_DIR}"
    279 find "${AT_DIR}"/ -type d -print0 | xargs --null chmod o+x
    280 chmod o+x "${AT_DIR}"/tko/*.cgi
    281 # restart server
    282 sudo /etc/init.d/apache2 restart
    283 
    284 # Setup lxc and base container for server-side packaging support.
    285 sudo apt-get install lxc -y
    286 sudo python "${AT_DIR}"/site_utils/lxc.py -s
    287 
    288 # Set up keys for www-data/apache user.
    289 APACHE_USER=www-data
    290 APACHE_HOME=/var/www
    291 APACHE_SSH_DIR="$APACHE_HOME/.ssh"
    292 SSH_KEYS_PATH=src/third_party/chromiumos-overlay/chromeos-base/chromeos-ssh-testkeys/files
    293 sudo mkdir -p "$APACHE_SSH_DIR"
    294 sudo bash <<EOF
    295 cd "${APACHE_SSH_DIR:-/dev/null}" || exit 1
    296 sudo cp "$CROS_CHECKOUT/$SSH_KEYS_PATH/"* .
    297 sudo tee config >/dev/null <<EOF2
    298 Host *
    299 User root
    300 IdentityFile ~/.ssh/testing_rsa
    301 EOF2
    302 sudo chown -R "$APACHE_USER:" .
    303 sudo chmod -R go-rwx .
    304 EOF
    305 if [ $? -ne 0 ]; then
    306   echo "apache user SSH setup failed."
    307 fi
    308 
    309 echo "Browse to http://localhost to see if Autotest is working."
    310 echo "For further necessary set up steps, see https://sites.google.com/a/chromium.org/dev/chromium-os/testing/autotest-developer-faq/setup-autotest-server?pli=1"
    311