#!/bin/bash # Performs installation and updates of the Drupal core and # contrib modules and themes via CVS. # # The script provides the ability to install and update a single Drupal # site in an "install group". # # Can be run with the environment variable DRUPAL_REV set to override the # revision tag for checkouts. See below for default value. # # Generally requires the availability of wget in path. # # Terms/variables used below (generally): # install name -- the installation within an install group. Typically something like 'foo.org'. # install group root dir -- the directory that forms the base of the install group. # # Based on the script 'drupal-cvs-deploy' by Paul Suda (manufaxure.com) # include library file . "`dirname ${0}`/drupalLibrary.sh" # Default CVS revision tag used for CVS installations and updates. DEFAULT_DRUAPL_CVS_REVISION=DRUPAL-6 # Dumps out script usage printUsage() { echo -e " " echo -e "Updates/Installs/Removes, via CVS, drupal installations (drupal core)" echo -e "or themes and modules hosted at drupal.org." echo -e "For more info, see script header." echo -e " " echo -e "Usage: " echo -e "\t`basename $0` [-noconfirm] [-versiontag ] [-latestversion] [-quiet] [install group root dir]" echo -e " " echo -e "-noconfirm supresses comfirmation request." echo -e "-versiontag " echo -e "\tspecifies the CVS tag used in an installation/update operation." echo -e "\tdefaults to '${DEFAULT_DRUAPL_CVS_REVISION}' for drupal installs or" echo -e "\tthe latest version available for module/theme installations." echo -e "\tsee http://drupal.org/node/93997 for drupal core" echo -e "\thttp://drupal.org/node/97084 for contrib branches" echo -e "\tCannot be specified with -latestversion" echo -e "-latestversion" echo -e "\tSpecifies that contrib module/theme updates will use the latest version" echo -e "\tavailable for the version of the owning Drupal installation." echo -e "\tOnly works with Drupal-5 and later." echo -e "\tCannot be specified with -versiontag" echo -e "-quiet minimizes output. Does not supress CVS messages." echo -e " " echo -e " specifies the operation. Options consist of:" echo -e "\tinstall - installs a new drupal installation," echo -e "\t\tmodule, or theme within an existing Drupal installation." echo -e "\tupdate - updates an existing module or Drupal install." echo -e "\tremove - removes an existng theme or module." echo -e " " echo -e " specifies what to operate on. It can take the following values:" echo -e "\tdrupal - a Drupal installation. (Cannot be 'remove'd.)" echo -e "\tmodule a partular contrib module w/in an installation." echo -e "\t\tModule is specified by 'moduleName' cooresponding to the module checkout name." echo -e "\ttheme a partular theme w/in an installation." echo -e "\tall Drupal installation & all of the contrib modules w/in the installation." echo -e "\tallmodules all of the contrib modules w/in an installation." echo -e "\t\t('all' and 'allmodules' valid only w/ the 'update' operation.)" echo -e " " outputInstallGroupUsage echo -e " " } ######### # Param handling if [ $# -eq 0 ]; then printUsage exit 0 fi # Handle flags while (true); do case "${1}" in -noconfirm ) pNoConfirm="-noconfirm"; shift ;; -versiontag ) if [ -n "${pLatestVersion}" ]; then echo -e "** Cannot specify '-versiontag' and '-latestversion' at same time. Aborting.\n" printUsage exit 1 fi pVersionTag="-versiontag ${2}" pRevision="${2}" shift; shift ;; -latestversion ) if [ -n "${pRevision}" ]; then echo -e "** Cannot specify '-versiontag' and '-latestversion' at same time. Aborting.\n" printUsage exit 1 fi pLatestVersion="-latestversion" shift ;; -quiet ) pQuiet="-quiet" shift ;; * ) break ;; esac done if [ -z "${pQuiet}" ]; then echo " " fi # handle OP parameter pOp="${1}" shift case "${pOp}" in install | update | remove ) ;; * ) echo -e "** Invalid OP parameter specified: '${pOp}'. Aborting.\n" printUsage exit 1 esac # handle WHAT parameter pWhat="${1}" shift pWhatSpecific="" case "${pWhat}" in drupal ) if [[ "${pOp}" == "remove" ]]; then echo -e "** Can not 'remove' 'drupal' (needs to be done manually). Aborting.\n" printUsage exit 1 fi ;; module | theme ) if [ $# -lt 2 ]; then echo -e "** Need to specify a ${pWhat}. Aborting.\n" printUsage exit 1 fi pWhatSpecific="${1}" shift ;; all | allmodules ) if [[ "${pOp}" != "update" ]]; then echo -e "** Can only 'update' '${pWhat}'. Aborting.\n" printUsage exit 1 fi ;; * ) echo -e "** Invalid WHAT parameter specified: '${pWhat}'. Aborting.\n" printUsage exit 1 esac # handle INSTALL parameter pInstall="${1}" if [ -z "${pInstall}" ]; then echo -e "** Incorrect number of parameters specified for requested operation (parsing INSTALL). Aborting.\n" printUsage exit 1 fi # process Group Root Dir pRootDir="`getGroupRootDir "${2}"`" errorStr="`validateGroupRootDir "${pRootDir}"`" if [ -n "${errorStr}" ]; then echo -e "${errorStr}\n" printUsage exit 1 fi ########################## # Startup # Get confirm message case "${pWhat}" in drupal ) whatStr="Drupal" ;; module ) whatStr="module '${pWhatSpecific}'" ;; theme ) whatStr="theme '${pWhatSpecific}'" ;; all ) whatStr="Drupal & all modules" ;; allmodules ) whatStr="all modules" ;; esac if [ -z "${pQuiet}" ]; then case "${pOp}" in install ) echo "Installing ${whatStr} to installation '${pInstall}'." ;; update ) echo "Updating ${whatStr} on installation '${pInstall}'." ;; remove ) echo "Removing ${whatStr} from installation '${pInstall}'." ;; esac echo -e "\tDrupal group root directory: '${pRootDir}'" fi if [ -z "${pNoConfirm}" ]; then echo "" echo "Press to continue, or ^C to quit..." read fi ########################## # Do requested work. case "${pOp}" in install ) case "${pWhat}" in drupal ) # Installation target directory targetDir="`getTargetDir "${pInstall}" "${pRootDir}"`" # Cannot deploy into an existing directory if [ -d "${targetDir}" ]; then echo "** Target install directory '${targetDir}' already exists. Aborting." exit 1 fi # Can we create the directory? mkdir -p "${targetDir}" 2> /dev/null || { echo "** Cannot create target install directory '${targetDir}'. Aborting." exit 1 } # Default version? if [ -z "${pRevision}" ]; then pRevision="${DEFAULT_DRUAPL_CVS_REVISION}" fi # Check out Drupal ( pushd "${pRootDir}" 2>&1 >/dev/null ; cvs -q -d ${DRUPAL_CVS} checkout -d "${pInstall}" -r ${pRevision} drupal ; popd 2>&1 >/dev/null ) || { echo -e "** Error performing CVS checkout of Drupal. Aborting.\n" exit 1 } # Create site directory and then files, modules, and themes directories within it. siteDir="`getSiteDir "${pInstall}" "${pRootDir}"`" mkdir "${siteDir}" 2> /dev/null || { echo -e "** Error creating site directory (${siteDir}). Aborting.\n" exit 1 } fileUploadDir="`getFileUploadDir "${pInstall}" "${pRootDir}"`" mkdir "${fileUploadDir}" 2> /dev/null || { echo -e "** Error creating files directory (${fileUploadDir}). Aborting.\n" exit 1 } moduleDir="`getModuleDir "${pInstall}" "${pRootDir}"`" mkdir "${moduleDir}" 2> /dev/null || { echo -e "** Error creating modules directory (${moduleDir}). Aborting.\n" exit 1 } contribModuleDir="`getContribModuleDir "${pInstall}" "${pRootDir}"`" mkdir "${contribModuleDir}" 2> /dev/null || { echo -e "** Error creating contrib modules directory (${contribModuleDir}). Aborting.\n" exit 1 } themeDir="`getThemeDir "${pInstall}" "${pRootDir}"`" mkdir "${themeDir}" 2> /dev/null || { echo -e "** Error creating themes directory (${themeDir}). Aborting.\n" exit 1 } contribThemeDir="`getContribThemeDir "${pInstall}" "${pRootDir}"`" mkdir "${contribThemeDir}" 2> /dev/null || { echo -e "** Error creating contrib themes directory (${contribThemeDir}). Aborting.\n" exit 1 } backupDir="`getBackupDir "${pInstall}" "${pRootDir}"`" mkdir "${backupDir}" 2> /dev/null || { echo -e "** Error creating backup directory (${backupDir}). Aborting.\n" exit 1 } # Create site module stub. drupalMajorVer="`getSiteDrupalMajorVersion "${pInstall}" "${pRootDir}"`" generateSiteModule "${pInstall}" "${moduleDir}" "${drupalMajorVer}" # Copy/chmod settings.php file # On Drupal v6, this file is called "default.settings.php" if [ -f "${targetDir}/sites/default/settings.php" ]; then defaultSettingsFile="${targetDir}/sites/default/settings.php" elif [ -f "${targetDir}/sites/default/default.settings.php" ]; then defaultSettingsFile="${targetDir}/sites/default/default.settings.php" else echo -e "** Could not find default site settings file. Aborting.\n" exit 1 fi ( cp "${defaultSettingsFile}" "${siteDir}/settings.php" ; chmod 0666 "${siteDir}/settings.php" ) || { echo -e "** Error copying/chmodding site settings file. Aborting.\n" exit 1 } # Done! if [ -z "${pQuiet}" ]; then echo "Install of Drupal complete in ${targetDir}" echo -e "** Remember to run drupalSetPerms.sh on new site after Drupal init." fi ;; module | theme ) if [ "${pWhat}" == "module" ]; then installDir="`getContribModuleDir "${pInstall}" "${pRootDir}"`" installTargetDir="`getDirForContribModule "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" cvsRepoDir="modules" else # theme installDir="`getContribThemeDir "${pInstall}" "${pRootDir}"`" installTargetDir="`getDirForContribTheme "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" cvsRepoDir="themes" fi # Validate the installation errorStr="`validateSite "${pInstall}" "${pRootDir}"`" if [ -n "${errorStr}" ]; then echo -e "** error with specified install: ${errorStr}. Aborting.\n" exit 1 fi # Ensure install dir exists if [ ! -d "${installDir}" ]; then echo -e "** Contrib ${pWhat} directory '${installDir}' does not exist. Aborting.\n" exit 1 fi # Cannot deploy into an existing directory if [ -d "${installTargetDir}" ]; then echo "** Target install directory '${installTargetDir}' already exists. Aborting." exit 1 fi # Default version? if [ -z "${pRevision}" ]; then ver="`getSiteDrupalMajorVersion "${pInstall}" "${pRootDir}"`" pRevision="`getLatestContribTag "${pWhat}" "${pWhatSpecific}" "${ver}"`" if [ -z "${pRevision}" ]; then echo -e "** Error getting latest tag for ${pWhat} '${pWhatSpecific}'. Aborting.\n" exit 1 fi fi # Check out module/theme ( pushd "${installDir}" 2>&1 >/dev/null ; cvs -q -d ${CONTRIB_CVS} checkout -d "./${pWhatSpecific}" -r ${pRevision} "contributions/${cvsRepoDir}/${pWhatSpecific}" ; popd 2>&1 >/dev/null ) || { echo -e "** Error performing CVS checkout of ${pWhat} '${pWhatSpecific}'. Aborting.\n" exit 1 } if [ -z "${pQuiet}" ]; then echo "Install of ${pWhat} complete in ${installDir}/${pWhatSpecific}" fi ;; * ) echo -e "** ** WTF: install ${pWhat}.\n" exit 1 ;; esac ;; update ) # Validate the installation errorStr="`validateSite "${pInstall}" "${pRootDir}"`" if [ -n "${errorStr}" ]; then echo -e "** Error with specified install: ${errorStr}. Aborting\n"; exit 1 fi case "${pWhat}" in drupal | all ) # Installation target directory targetDir="`getTargetDir "${pInstall}" "${pRootDir}"`" # Determine target tag, if any. if [ -n "${pRevision}" ]; then revisionParameter="-r ${pRevision}" fi if [[ "${pWhat}" == "all" ]]; then if [ -z "${pQuiet}" ]; then echo "Updating Drupal core." fi fi # update Drupal cd "${targetDir}" && cvs -q -d ${DRUPAL_CVS} update -d ${revisionParameter} || { echo -e "** Error performing CVS update of Drupal. Aborting.\n" exit 1 } if [[ "${pWhat}" == "all" ]]; then if [ -z "${pQuiet}" ]; then echo "Update of Drupal core complete in ${targetDir}" fi # For each module in installed modules list, update it. for module in `getInstalledContribModuleList "${pInstall}" "${pRootDir}"`; do if [ -z "${pQuiet}" ]; then echo "Updating module '${module}'... " fi "${0}" -noconfirm -quiet ${pVersionTag} ${pLatestVersion} update module ${module} "${pInstall}" "${pRootDir}" if [ -z "${pQuiet}" ]; then echo -e "done\n" fi done fi if [ -z "${pQuiet}" ]; then echo "** Remember to run update script at http://${pInstall}/update.php" fi ;; module | theme ) if [ "${pWhat}" == "module" ]; then installDir="`getDirForContribModule "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" else # (theme) installDir="`getDirForContribTheme "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" fi # Ensure installed module/theme dir exists if [ ! -d "${installDir}" ]; then echo -e "** Contrib ${pWhat} install directory '${installDir}' does not exist. Aborting.\n" exit 1 fi # Determine target tag, if any. if [ -n "${pLatestVersion}" ]; then ver="`getSiteDrupalMajorVersion "${pInstall}" "${pRootDir}"`" pRevision="`getLatestContribTag "${pWhat}" "${pWhatSpecific}" "${ver}"`" if [ -z "${pRevision}" ]; then echo -e "** Error getting latest tag for ${pWhat} '${pWhatSpecific}'. Aborting.\n" exit 1 fi fi if [ -n "${pRevision}" ]; then revisionParameter="-r ${pRevision}" fi # update module/theme cd "${installDir}" && cvs -q -d ${DRUPAL_CVS} update -d ${revisionParameter} || { echo -e "** Error performing CVS update of ${pWhat} '${pWhatSpecific}'. Aborting.\n" exit 1 } if [ -z "${pQuiet}" ]; then echo "Update of ${pWhat} '${pWhatSpecific}' complete in ${installDir}" if [ "${pWhat}" == "module" ]; then echo "** Remember to run update script at http://${pInstall}/update.php" fi fi ;; allmodules ) # For each module in installed modules list, update it. for module in `getInstalledContribModuleList "${pInstall}" "${pRootDir}"`; do if [ -z "${pQuiet}" ]; then echo "Updating module '${module}'... " fi "${0}" -noconfirm -quiet ${pVersionTag} ${pLatestVersion} update module ${module} "${pInstall}" "${pRootDir}" if [ -z "${pQuiet}" ]; then echo -e "done\n" fi done if [ -z "${pQuiet}" ]; then echo "** Remember to run update script at http://${pInstall}/update.php" fi ;; * ) echo -e "** ** WTF: update ${pWhat}.\n" exit 1 esac ;; remove ) # Validate the installation errorStr="`validateSite "${pInstall}" "${pRootDir}"`" if [ -n "${errorStr}" ]; then echo -e "** Error with specified install: ${errorStr}. Aborting.\n"; exit 1 fi case "${pWhat}" in module | theme ) if [ "${pWhat}" == "module" ]; then installDir="`getDirForContribModule "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" else # (theme) installDir="`getDirForContribTheme "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" fi # Ensure installed module/theme dir exists if [ ! -d "${installDir}" ]; then echo -e "** Contrib ${pWhat} install directory '${installDir}' does not exist. Aborting.\n" exit 1 fi # remove directory /bin/rm -r "${installDir}" if [ -z "${pQuiet}" ]; then echo "Removal of ${pWhat} '${pWhatSpecific}' complete." fi ;; * ) echo -e "** ** WTF: remove ${pWhat}.\n" exit 1 esac ;; * ) echo -e "** ** WTF: op=${pOp}.\n" exit 1 esac # Done if [ -z "${pQuiet}" ]; then echo -e "\n** Done." fi