The following post appears to be older than 100 days. I therefore cannot guarantee that any technical information in this post is still valid today.

Please consider to also look for other, more up to date resources!
2009/03/05

A DokuWiki Development Wiki Factory In Bash

I recently made a script which makes it easy to setup a new development DokuWiki instance. So, if you're into DokuWiki development this might be interesting for you (the script could also be used as a starting point to create a quick dokuwiki setup script).

The script takes two arguments, the first one is a configuration file which holds some information about the different source repositories for plugins and templates you might want to use or you are working on. The second argument can be used to specify a target directory where the Wiki should be installed to. If no target directory is given the script works in the current directory.

dwmakedev [configuration] <target dir>

When executed the following steps are performed:

  1. fetching the dokuwiki darcs repo
  2. installing sample data if provided via config
  3. alter file permissions
  4. setup default configuration, including an admin account (username: admin, password: admin)
  5. install plugins / templates supplied via config

The configuration file is just a normal bash file which gets sourced. It's pretty much selfexplaining. Here's an example. You can of course use URLs in the repository lists (note: it's intentional that I didn't use bash arrays here, easier to parse in this case):

# title of the wiki (defaults to Development Wiki)
wiki_title="Dev Wiki"
 
# the template to use (defaults to the default template)
wiki_template="arctic" 

# wiki localization (defaults to en)
wiki_lang="de"

# admin mail (defaults to foo@bar.baz)    
wiki_adminmail="chi@chimeric.de"

# default ACLs used (defaults to 0)
wiki_acl=1

# sample data (empty by default, you can use a local file too 
# but it has to be .tgz .tar.gz or .tar.bz2)
dev_data=http://chimeric.de/_src/dev-data.tgz

# a user with root rights (defaults to root, eplained later)
root_user="rootuser"

# default group for the chown command issued on the data dir
# (default to the output of whoami)  
dev_group=chi          

# list of darcs plugin repositories
darcs_plugins="
/home/chi/public_html/dev/darcs/dokuwiki/plugins/avatar
/home/chi/public_html/dev/darcs/dokuwiki/plugins/bbcode
/home/chi/public_html/dev/darcs/dokuwiki/plugins/blog
/home/chi/public_html/dev/darcs/dokuwiki/plugins/changemarks
/home/chi/public_html/dev/darcs/dokuwiki/plugins/cloud
/home/chi/public_html/dev/darcs/dokuwiki/plugins/comment
"

# list of git plugin repositories
git_plugins="
/home/chi/public_html/dev/git/dw-plugin-archiveupload.git archiveupload
/home/chi/public_html/git/dw-plugin-backlinks.git backlinks
/home/chi/public_html/git/dw-plugin-blogtng.git blogtng
/home/chi/public_html/git/dw-plugin-clearfloat.git clearfloat
/home/chi/public_html/git/dw-plugin-feedmod.git feedmod
"

# list of svn plugin repositories
svn_plugins=

# list of darcs template repositories
darcs_templates=

# list of git template repositories
git_templates="
/home/chi/public_html/dev/src/git/dw-tpl-arctic.git arctic
/home/chi/public_html/dev/src/git/dw-tpl-dokubook.git dokubook
/home/chi/public_html/dev/src/git/dw-tpl-dokubrick.git dokubrick
/home/chi/public_html/dev/src/git/dw-tpl-simple.git simple
"

# list of svn template repositories
svn_templates=

Each line of a repository list must contain one reference to a repository (repositories on remote websites can be used too). You can also append a destination directory name to which the repository should be cloned to (like I did for $git_plugins and $git_templates).

The script will also change the permissions and ownership for the data/, config/ and lib/plugins/ folders. It tries to detect the webserver user automatically and it'll use the setgid bit and the $dev_group. This ensures that you'll be able to delete the whole dev wiki without being root. To perform this task su is used. You can specify a $root_user with root rights too if you like/need (defaults to root).

And here's the script. You can also download it at http://chimeric.de/_src/dwmakedev.

If you have any questions or remarks please let me know in the comments.

dwmakedev.sh
#!/bin/bash
###############################################################################
# Copyright 2008 by Michael Klier <chi@chimeric.de>
#
# dwmakedev - bash script to easily setup dokuwiki development wikis
#
# dwmakedev is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License version 2 only, as published by
# the Free Software Foundation.
#
# dwmakedev 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 version 3 for more
# details (a copy is included in the LICENSE file that accompanied this code).
#
# You should have received a copy of the GNU General Public License version 3
# along with dwmakedev. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
# for a copy of the GPLv2 License.
###############################################################################
 
# read configuration file
if [[ $1 ]]; then
	echo ">> Creating new devlopment wiki"
	echo -n ">> Reading configuration file ... "
	source $1
	echo "done"
else
	echo "ERROR: No configuration file given!"
	echo "Usage: $(basename $0) [config] <dest dir>"
	exit 1
fi
 
# set work dir if given
if [[ $2 ]]; then
	if [[ -d $2 ]]; then
		echo -n ">> Setting working dir to ${work_dir} ... "
		work_dir=$(readlink -f $2)
		echo "done"
	elif [[ ! -d $2 ]]; then
		echo "ERROR: Working dir ${2} does not exist!"
		exit 1
	fi
fi
 
if [[ -d ${work_dir}/dokuwiki ]]; then
	echo "ERROR: DokuWiki directory exists in working directory!"
	exit 1
fi
 
# setting defaults 
: ${dev_group:=$(whoami)}
: ${root_user:="root"}
: ${work_dir:=$(pwd)}
: ${wiki_acl:=0}
: ${wiki_lang:="en"}
: ${wiki_title:="Development Wiki"}
: ${wiki_template:="default"}
: ${wiki_adminmail}:="foo@bar.baz"}
 
# find out www user
echo -n ">> Determining www-user ... "
for search in "www" "http"; do
	if [[ -z $www_user ]]; then
		www_user=$(grep "${search}" /etc/passwd)
		if [[ $? == 0 ]]; then
			www_user=${www_user/:*/}
		fi
	fi
done
if [[ -z ${www_user} ]]; then
	echo "error"
	exit 1
else 
	echo "done"
fi
 
echo -n ">> Fetching DokuWiki ... "
cd ${work_dir} && darcs get --quiet --partial http://dev.splitbrain.org/darcs/dokuwiki
if [[ $? == 0 ]]; then
	echo "done"
else 
	echo " failed. Webserver down? Missing uplink?"
	exit 1
fi
 
echo ">> Installing development data"
if [[ ${dev_data:0:4} == 'http' ]] || [[ ${dev_data:0:3} == 'ftp' ]]; then
	echo -n "   URL given, starting download ... "
	wget --quiet ${dev_data}
	if [[ $? == 0 ]]; then
		echo "done"
		echo -n "   Unpacking data ... "
		dev_data=$(basename ${dev_data})
		tar xzf $dev_data -C ${work_dir}/dokuwiki/data/
		rm ${dev_data}
		echo "done"
	else
		echo "ERROR: Failed to download demo data!"
	fi
elif [[ -f ${dev_data} ]]; then
	echo "   Using local file ... "
	echo -n "   Unpacking data ... "
	tar xf ${dev_data} -C ${work_dir}/dokuwiki/data/
	echo "done"
else
	echo "   No data given ..."
fi
 
echo -n ">> Creating empty configuration files ..."
touch ${work_dir}/dokuwiki/conf/{local.php,local.protected.php,acl.auth.php,users.auth.php}
echo "done"
 
echo -n ">> Setting up basic configuration ..."
echo "<?php
\$conf['title'] = '${wiki_title}';
\$conf['lang'] = '${wiki_lang}';
\$conf['template'] = '${wiki_template}';
\$conf['useacl'] = 1;
\$conf['superuser'] = '@admin';
\$conf['dmode'] = 0775;
\$conf['fmode'] = 0664;
@include(DOKU_CONF.'local.protected.php');" > ${work_dir}/dokuwiki/conf/local.php
echo "done"
 
echo -n ">> Setting up basic ACLs ... "
echo "# <?php exit()?>
* @admin 255
* @ALL ${wiki_acl}" > ${work_dir}/dokuwiki/conf/acl.auth.php
echo "done"
 
echo -n ">> Adding admin user ... "
echo "# <?php exit()?>
admin:\$1\$cce258b2\$U9o5nK0z4MhTfB5QlKF23/:admin:${wiki_adminmail}:admin,user" > ${work_dir}/dokuwiki/conf/users.auth.php
echo "done"
 
echo -n ">> Setting file permissions ..."
chmod 2775 ${work_dir}/dokuwiki/data ${work_dir}/dokuwiki/conf ${work_dir}/dokuwiki/lib/plugins
find ${work_dir}/dokuwiki/data/ -type d -exec chmod 2775 {} \;
find ${work_dir}/dokuwiki/data/ -type f -exec chmod 664 {} \;
echo "done"
 
echo ">> Setting file ownership ... give root password"
okay=1
while [[ $okay != 0 ]]; do
	su ${root_user} -c "chown -R ${www_user}:${dev_group} ${work_dir}/dokuwiki/data ${work_dir}/dokuwiki/conf \
	&& chown ${www_user}:${dev_group} ${work_dir}/dokuwiki/lib/plugins"
	okay=$?
done
 
echo ">> Fetching plugin repositories"
errors=()
for cvs in "darcs" "git" "svn"; do
	for type in "plugins" "templates"; do
		eval "repositories=\$${cvs}_${type}"
		[[ $type == "plugins" ]] && cd ${work_dir}/dokuwiki/lib/plugins
		[[ $type == "templates" ]] && cd ${work_dir}/dokuwiki/lib/tpl
		while read line; do
			[[ $line == "" ]] && continue
			repo=${line/ */}
			dest=${line/* /}
			[[ $repo == $dest ]] && dest=
			echo -n "   ${repo} ... "
			case $cvs in
				darcs)
					darcs get --quiet $repo $dest &>/dev/null
					;;
				git)
					git clone --quiet $repo $dest &>/dev/null
					;;
				svn)
					svn checkout --quiet $repo $dest &>/dev/null
					;;
			esac
			if [[ $? != 0 ]]; then
				errors[$((${#errors[@]}+1))]=${repo}
				echo "failed"
			else 
				echo "done"
			fi
		done < <(echo "$repositories")
	done
done
if [[ ${#errors[@]} > 0 ]]; then
	echo ">> Failed to fetch ${#errors[@]} repositories"
	for repo in $(seq 1 ${#errors[@]}); do
		echo "   ${errors[$repo]}"
	done
fi
 
echo ">> Bye!"

Comments




FGLKJ