Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
# cmd muninpks pokersource.info muninpks.pokersource.mksp.tld loic@dachary.org
set -e
meta="$1"
name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
realm="$(xmlstarlet sel -t -v /appliance/@realm < <(dog --no-header $meta))"
domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
vserver_realm="$(xmlstarlet sel -t -m /appliance/vserver_master/vserver -v ../@realm < <(dog --no-header $meta))"
view_host=$name.$realm.$vserver_realm.tld
name="$1"
domain="$2"
host="$3"
author="$4"
cd /etc/bind
test -f views/$domain.view
if ! grep "^$name" views/$domain.view > /dev/null
then
echo -e "$name\t\tIN\tCNAME\t$host." >> views/$domain.view
/etc/init.d/bind9 reload
hg commit -u $author -m "bind $name to $host in $domain view" /etc/bind
fi
* ''Apache appliance on a laptop inside a LAN''
** Proppy wants to run a new online service available to the general public.
** Proppy creates a vlan on his GNU/Linux laptop and name it eth0.2.
** The eth0.2 interface is assigned a permanent private IP address range of 192.168.50.0/24.
** Proppy adds shorewall rules to NAT all outgoing packets from eth0.2 and route them to eth0 or eth1 (the wifi interface).
** The 37000:38000 port range is abitrarily DNAT to eth0.2.
** Proppy creates a new Debian etch based vserver with address 192.168.50.10 on eth0.2 and names it VOD.
** Apache2 is installed in VOD and bound to 37080 in addtion to the 80 port.
** The laptop is run from inside a ~NATed LAN and and has a fixed DHCP allocated fixed IP based on his MAC address.
** Proppy adds a rule to the firewall ~NATing the LAN so that ports 37000:38000 are redirected to the laptop fixed IP.
# cmd openalpp osgal dachary.org
set -e
name="$1"
newname="$2"
domain="$3"
cd /etc/apache2
a2dissite $name.$domain
mv sites-available/$name.$domain sites-available/$newname.$domain
perl -pi -e "s/\b$name\b/$newname/g" sites-available/$newname.$domain
! grep -l $name sites-available/$newname.$domain
a2ensite $newname.$domain
for log in /var/log/apache2/*$name* ; do
newlog=$(echo $log | perl -p -e "s/\b$name\b/$newname/g")
mv $log $newlog
done
/etc/init.d/apache2 reload
* Request for inclusion in debian package http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=425008;repeatmerged=no
* One liner that will work on a newly installed apache2 from Debian GNU/Linux etch
{{{
author=loic@dachary.org ; app=apache2 ; apt-get install -y --force-yes $app && hg addremove && hg commit -u $author -m "apt-get install $app"
app=patch ; apt-get install -y --force-yes $app && hg addremove && hg commit -u $author -m "apt-get install $app"
cd / ; wget -O - http://hg.nagios.fsffrance.org/raw-rev/22ed4d555572 | patch -p1
hg commit -m 'Apache x-forwarded-for log when behind a proxy' /etc/apache2
/etc/init.d/apache2 reload
}}}
* Emacs macro
{{{
; C-x e on the CustomLog line
(setq last-kbd-macro "\C-k\C-k\C-y\C-y\C-p\C-p\C-e env=!from_proxy\C-n_forwarded env=from_proxy")
}}}
* Complete patch
{{{
cd /
patch -p1 <<'EOF'
--- a/etc/apache2/apache2.conf Thu May 03 23:57:15 2007 +0200
+++ b/etc/apache2/apache2.conf Thu May 03 23:59:07 2007 +0200
@@ -199,9 +199,12 @@ Include /etc/apache2/conf.d/
# a CustomLog directive (see below).
#
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined_forwarded
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
+
+SetEnvIfNoCase X-Forwarded-For "." from_proxy=1
#
# ServerTokens
--- a/etc/apache2/sites-available/default Thu May 03 23:57:15 2007 +0200
+++ b/etc/apache2/sites-available/default Thu May 03 23:59:07 2007 +0200
@@ -34,7 +34,8 @@ NameVirtualHost *
# alert, emerg.
LogLevel warn
- CustomLog /var/log/apache2/access.log combined
+ CustomLog /var/log/apache2/access.log combined env=!from_proxy
+ CustomLog /var/log/apache2/access.log combined_forwarded env=from_proxy
ServerSignature On
EOF
}}}
{{{
diff -r 36c2ae3235c9ea8a3d640b6dba5811ed6a54f9f0 -r b03e45844f4ee52e777288dad5c2cf3a361f92bd bind/db.aminche.com
--- a/bind/db.aminche.com Mon Apr 02 00:16:32 2007 +0200
+++ b/bind/db.aminche.com Thu May 17 21:32:08 2007 +0200
@@ -1,6 +1,6 @@
$ttl 3d
@ IN SOA ns.aminche.com. hostmaster.aminche.com. (
- 2007040102 ; serial, todays date + todays serial #
+ 2007041602 ; serial, todays date + todays serial #
28800 ; refresh, seconds
7200 ; retry, seconds
604800 ; expire, seconds
@@ -28,4 +28,5 @@ muzine IN A 88.191.13.165
muzine IN A 88.191.13.165
hg IN A 88.191.13.165
zanna IN A 88.191.13.165
+*.aminche.com. IN A 88.191.13.165
aminche.com. IN A 88.191.13.165
}}}
** Proppy boots the real machine using a live CD
** Proppy installs and run the ssh daemon
** The ssh daemon allows root access and the password is set
** The hard disk is explored using fdisk
** Proppy mounts the file systems in /mnt as if it was / (for instance /dev/sda2 on /mnt and /dev/sda3 on /mnt/home)
** From the vserver host, proppy copies all the files (could also be done using the rsync vserver build method but it would not cross the file system boundaries because of the -x option and would therefore miss files)
{{{
rsync -avH --numeric-ids root@mekensleep.com:/mnt/ /var/lib/vservers/newmachine/
}}}
mkdir app
cd app
mkdir universe
ruby /usr/bin/tiddlywiki_cp -a http://garden.dachary.org/universe.html universe
emacs meta.xml # use model http://yocto-reader.flouzo.net/meta/meta.xml
meta=http://localhost/app/meta.xml
script_url="$(xmlstarlet sel -t -v /appliance/public_ns/@create < <(dog --no-header "$meta"))" ; \
ssh -p $(xmlstarlet sel -t -v /appliance/public_ns/@ns_port < <(dog --no-header "$meta")) \
root@$(xmlstarlet sel -t -v /appliance/public_ns/@public_ns < <(dog --no-header "$meta")) \
bash -x '<(dog --no-header '$script_url')' $meta
script_url="$(xmlstarlet sel -t -v /appliance//ns/@create < <(dog --no-header "$meta"))" ; \
ssh root@$(xmlstarlet sel -t -m /appliance/vserver_master/ns -v ../@host < <(dog --no-header "$meta")) \
bash -x '<(dog --no-header '$script_url')' $meta
script_url="$(xmlstarlet sel -t -v /appliance//vserver/@create < <(dog --no-header "$meta"))" ; \
ssh root@$(xmlstarlet sel -t -m /appliance/vserver_master/vserver -v ../@host < <(dog --no-header "$meta")) \
bash -x '<(dog --no-header '$script_url')' $meta
script_url="$(xmlstarlet sel -t -v /appliance//garden/@create < <(dog --no-header "$meta"))" ; \
ssh root@$(xmlstarlet sel -t -m /appliance//garden -v ../@host < <(dog --no-header "$meta")) \
cat '<(dog --no-header '$script_url')' \| vserver $(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header "$meta")) exec "bash -x -s '$meta'"
script_url="$(xmlstarlet sel -t -v /appliance//mercurial/@create < <(dog --no-header "$meta"))" ; \
ssh root@$(xmlstarlet sel -t -m /appliance//mercurial -v ../@host < <(dog --no-header "$meta")) \
cat '<(dog --no-header '$script_url')' \| vserver $(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header "$meta")) exec "bash -x -s '$meta'"
script_url="$(xmlstarlet sel -t -v /appliance//http_proxy/@create < <(dog --no-header "$meta"))" ; \
ssh root@$(xmlstarlet sel -t -m /appliance//http_proxy -v ../@host < <(dog --no-header "$meta")) \
cat '<(dog --no-header '$script_url')' \| vserver $(xmlstarlet sel -t -v /appliance//http_proxy/@vserver_name < <(dog --no-header "$meta")) exec "bash -x -s '$meta'"
view_host=$name.$realm.$vserver_realm.tld
scp 'universe/Add DNS name in view.tiddler' root@$vserver_host:/tmp/step6
ssh root@$vserver_host bash -x /tmp/step6 $name $domain $view_host $author
ssh root@$vserver_host bash -x /tmp/step6 hg.$name $domain $view_host $author
script_url="$(xmlstarlet sel -t -v /appliance//nagios/@create < <(dog --no-header "$meta"))" ; \
ssh root@$(xmlstarlet sel -t -m /appliance//nagios -v ../@host < <(dog --no-header "$meta")) \
cat '<(dog --no-header '$script_url')' \| vserver $(xmlstarlet sel -t -v /appliance//nagios/@vserver_name < <(dog --no-header "$meta")) exec "bash -x -s '$meta'"
nagios_vserver_host=mango.pokersource.info
nagios_name=nagiosfsf
parent_in_nagios_graph=mango
#nagios_host=hg.$name.$realm.$vserver_realm.tld.
nagios_host=hg.$name.$domain.
scp universe/Monitor\ the\ mercurial\ server\ with\ nagios.tiddler root@$nagios_vserver_host:/var/lib/vservers/$nagios_name/tmp/step7
ssh root@$nagios_vserver_host vserver $nagios_name exec "bash -x /tmp/step7 hg.$name $domain $parent_in_nagios_graph $nagios_host $author"
script_url="$(xmlstarlet sel -t -v /appliance/rss/@create < <(dog --no-header "$meta"))" ; \
ssh root@$(xmlstarlet sel -t -v /appliance/rss/@host < <(dog --no-header $meta)) bash -x '<(dog --no-header '$script_url')' $meta
rss_host=dachary.org
#rss_url=http://hg.$name.$domain/rss-log
rss_url=http://$name.conf.tld:8000/rss-log
scp universe/Syndicate\ the\ mercurial\ changes.tiddler root@$rss_host:/tmp/step8
ssh root@$rss_host bash -x /tmp/step8 $rss_url $name
service=ssh
zone=tld
scp 'universe/open firewall port for appliance.tiddler' root@$vserver_host:/tmp/step9
ssh -t root@$vserver_host bash -x /tmp/step9 $name $domain $service $realm $vserver_realm $zone
set -e
meta="$1"
name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
author="$(xmlstarlet sel -t -v /appliance/@author < <(dog --no-header $meta))"
vserver_realm="$(xmlstarlet sel -t -m /appliance/vserver_master/vserver -v ../@realm < <(dog --no-header $meta))"
realm="$(xmlstarlet sel -t -v /appliance/@realm < <(dog --no-header $meta))"
vserver_name="$name.$realm.$vserver_realm.tld"
apt-get install debootstrap util-vserver
ip=$(getent hosts $vserver_name | cut -f1 -d' ')
test "$ip"
fqdn=$name.$domain
method="$(xmlstarlet sel -t -v /appliance/vserver_master/vserver/@distribution < <(dog --no-header $meta))"
case "$method" in
etch|lenny)
method="debootstrap -- -d $method -m http://ftp.fr.debian.org/debian "
;;
skeleton)
method=skeleton
;;
esac
iface=$(xmlstarlet sel -t -m /appliance/vserver_master/vserver -v ../@iface < <(dog --no-header $meta))
#ip=$(getent hosts $name.$domain | head -1 | cut -f1 -d' ')
addr=$(expr $ip : '.*\.\([0-9]*\)')
test "$addr"
net=$(expr $ip : '\(.*\)\.')
test "$net"
eval vserver $name build --hostname $fqdn --interface a$addr=$iface:$net.$addr/24 --context 2$addr -m $method
echo default > /etc/vservers/$name/apps/init/mark
hg addremove /etc/vservers
hg commit -u $author -m "create $name vserver" /etc/vservers
cat > /var/lib/vservers/$name/etc/resolv.conf <<EOF
search $domain
nameserver $net.1
EOF
case "$method" in
etch|lenny)
if ! grep APT::Cache-Limit /etc/apt/apt.conf.d/70debconf > /dev/null ; then
echo 'APT::Cache-Limit 100000000;' >> /etc/apt/apt.conf.d/70debconf
fi
;;
esac
mkdir -p /var/lib/vservers/$name/proc /var/lib/vservers/$name/sys
ln -s /proc/self/fd /var/lib/vservers/$name/dev/fd
chroot /var/lib/vservers/$name apt-get remove --yes klogd || /bin/true
chroot /var/lib/vservers/$name update-rc.d cron defaults
env -i TERM=vt100 /usr/sbin/vserver $name start
echo DONE
should be converted to use the programable API of bind9 at some point
* The named.conf file //must// include views only. That's the only tricky bit : the top level configuration file may not contain any stanza. When views are used, all must be views. Note that match-clients is on the same line as {{{view}}} so that scripts can easily manipulate it.
{{{
include "/etc/bind/named.conf.options";
view "pokersource.info" { match-clients { 192.168.50.10; };
zone "conf.tld" {
type master;
file "/etc/bind/pokersource.info.view";
};
include "/etc/bind/named.conf.zones";
include "/etc/bind/named.conf.common";
};
view "default" {
include "/etc/bind/named.conf.zones";
include "/etc/bind/named.conf.common";
};
include "/etc/bind/named.conf.local";
}}}
* The //named.conf.common// that's included in each view holds what you'd like to include outside the views if bind9 allowed this. It's typically what you find in a named.conf bind9 file when not using views:
{{{
// prime the server with knowledge of the root servers
zone "." {
type hint;
file "/etc/bind/db.root";
};
// be authoritative for the localhost forward and reverse zones, and for
// broadcast zones as per RFC 1912
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
file "/etc/bind/db.255";
};
}}}
* The {{{/etc/bind/named.conf.zones}}} file included in the {{{/etc/bind/named.conf}}} contains the list of supported zones (master, slave and forwarded). Forwarded zones are used to make sure DNS requests for domains under your control refer only to the master server, to [[avoid propagation delays|avoid DNS delays]].
{{{
zone "my" {
type master;
file "/etc/bind/db.my";
};
zone "pokersource.info."{
type forward ;
forward only ;
forwarders {
88.191.250.41 ;
} ;
};
}}}
In the above file, the //my// zone is used to define the .my top level domain that points to the IP of the appliances running on the local machine and unknown to the outside world.
# cmd meta
set -e
meta="$1"
name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
author="$(xmlstarlet sel -t -v /appliance/@author < <(dog --no-header $meta))"
cname="$(xmlstarlet sel -t -v /appliance/public_ns/@cname < <(dog --no-header $meta))"
dns="$(xmlstarlet sel -t -v /appliance/public_ns/@public_ns_ip < <(dog --no-header $meta))"
cd /etc/bind
if ! grep $domain db.$domain > /dev/null
then
echo "the /etc/bind/db.$domain file must exist and contain the $domain string"
exit 1
fi
if ! grep "^$name" db.$domain > /dev/null
then
echo "$name IN CNAME $cname." >> db.$domain
echo "hg.$name IN CNAME $cname." >> db.$domain
perl -ni -e 'if(/(\d+).*; serial/) { $s = $1; $s++; print "\t\t\t$s\t; serial\n"; } else { print; }' db.$domain
/etc/init.d/bind9 reload
sleep 2
fi
dig @$dns $name.$domain | grep "CNAME.*$cname"
dig @$dns hg.$name.$domain | grep "CNAME.*$cname"
hg commit -u $author -m "define $name.$domain" /etc/bind/db.$domain
echo DONE
# cmd markerclock 192.168.50 call dachary dachary.org loic@dachary.org
set -e
meta="$1"
name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
author="$(xmlstarlet sel -t -v /appliance/@author < <(dog --no-header $meta))"
realm="$(xmlstarlet sel -t -v /appliance/@realm < <(dog --no-header $meta))"
net="$(xmlstarlet sel -t -m /appliance//ns -v ../@net < <(dog --no-header $meta))"
vserver_realm="$(xmlstarlet sel -t -m /appliance//ns -v ../@realm < <(dog --no-header $meta))"
reverse=$(echo $net | perl -p -e 's/(\d+).(\d+).(\d+)/$3.$2.$1/')
cd /etc/bind
db_file=db.$net
if ! test -f $db_file
then
db_file=db.$(expr $net : '\(.*\)\.')
fi
if ! dig @$net.1 $name.$realm.$vserver_realm.tld. | grep "^$name.$realm.$vserver_realm.tld.*IN.*A" > /dev/null
then
perl -ni -e 'if(/(\d+).*; serial/) { $s = $1; $s++; print "\t\t\t$s\t; serial\n"; } else { print; }' \
$db_file db.$vserver_realm views/$domain.view
ip=$(expr "$(grep available $db_file | tail -1)" : '.*available-\([0-9][0-9]*\)')
if test -z "$ip"
then
echo "NO IP"
exit 1
fi
for file in $db_file db.$vserver_realm
do
if ! grep "^$name.$realm" $file > /dev/null
then
perl -pi -e "s/available-$ip/$name.$realm/" $file
fi
done
vserver_proxy="$(xmlstarlet sel -t -m /appliance//http_proxy -v ../@host < <(dog --no-header $meta))"
domain_proxy="$(xmlstarlet sel -t -m /appliance//http_proxy/@domain < <(dog --no-header $meta))"
vserver_ns="$(xmlstarlet sel -t -m /appliance//ns -v ../@host < <(dog --no-header $meta))"
if [ "$domain_proxy" -a "$vserver_proxy" = "$vserver_ns" -a "$domain" != "$domain_proxy" ] ; then
if ! grep "^$name" views/$domain_proxy.view > /dev/null
then
echo -e "$name\t\tIN\tCNAME\t$name.$realm.$vserver_realm.tld." >> views/$domain_proxy.view
fi
fi
if ! grep "^$name" views/$domain.view > /dev/null
then
echo -e "$name\t\tIN\tCNAME\t$name.$realm.$vserver_realm.tld." >> views/$domain.view
fi
/etc/init.d/bind9 reload
sleep 2
dig @$net.1 $name.$realm.$vserver_realm.tld. | grep $ip
dig @$net.1 -x $net.$ip | grep $name.$realm.$vserver_realm.tld
else
ip=$(expr "$(dig @$net.1 $name.$realm.$vserver_realm.tld | grep \^$name.$realm)" : ".*$net.\([0-9]*\)")
fi
# ??? how to test that a resolution within a view works ???
perl -pi -e 's/};$/'$net.$ip'; };/ if(/^view "'$realm'/ && !/'$net.$ip'/)' named.conf
grep "$realm.*$net.$ip" named.conf
/etc/init.d/bind9 reload
hg commit -u $author -m "define $name local names in $realm" /etc/bind
echo DONE
ns2:~# meta=http://garden.conf.tld/packaging-farm.xml
ns2:~# name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
ns2:~# author="$(xmlstarlet sel -t -v /appliance/@author < <(dog --no-header $meta))"
ns2:~# domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
ns2:~#
ns2:~# cd /etc/bind
ns2:/etc/bind# echo $domain
dachary.org
ns2:/etc/bind# #perl -pi -e '$_ = '' if(/^'$name'/ || /^hg.'$name'/)' db.$domain
ns2:/etc/bind# grep $name db.$domain
packaging-farm IN CNAME dachary.org.
hg.packaging-farm IN CNAME dachary.org.
ns2:/etc/bind# perl -pi -e '$_ = '' if(/^'$name'/ || /^hg.'$name'/)' db.$domain
syntax error at -e line 1, near "= if"
Execution of -e aborted due to compilation errors.
ns2:/etc/bind# perl -pi -e '$_ = "" if(/^'$name'/ || /^hg.'$name'/)' db.$domain
ns2:/etc/bind# grep $name db.$domain
ns2:/etc/bind# dns="$(xmlstarlet sel -t -v /appliance/public_ns/@public_ns_ip < <(dog --no-header $meta))"
ns2:/etc/bind# echo $dns
192.168.50.16
ns2:/etc/bind# perl -ni -e 'if(/(\d+).*; serial/) { $s = $1; $s++; print "\t\t\t$s\t; serial\n"; } else { print; }' db.$domain
ns2:/etc/bind# hg diff db.$domain
*** output flushed ***
ns2:/etc/bind# /etc/init.d/bind9 reload
Reloading domain name service...: bind.
ns2:/etc/bind#
ns2:/etc/bind# ! dig @$dns $name.$domain | grep "CNAME.*$cname"
ns2:/etc/bind# #hg commit -u $author -m "undefine $name.$domain" /etc/bind/db.$domain
ns2:/etc/bind# echo $author
loic@dachary.org
ns2:/etc/bind# hg commit -u $author -m "undefine $name.$domain" /etc/bind/db.$domain
ns2:/etc/bind#
pecho:~# meta=http://garden.conf.tld/packaging-farm.xml
pecho:~# name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
author="$(xmlstarlet sel -t -v /appliance/@author < <(dog --no-header $meta))"
realm="$(xmlstarlet sel -t -v /appliance/@realm < <(dog --no-header $meta))"
net="$(xmlstarlet sel -t -m /appliance//ns -v ../@net < <(dog --no-header $meta))"
vserver_realm="$(xmlstarlet sel -t -m /appliance//ns -v ../@realm < <(dog --no-header $meta))"
pecho:~# pecho:~# pecho:~# pecho:~# pecho:~# pecho:~#
pecho:~# echo $realm
dachary
pecho:~# cd /etc/bind
pecho:/etc/bind# reverse=$(echo $net | perl -p -e 's/(\d+).(\d+).(\d+)/$3.$2.$1/')
pecho:/etc/bind# db_file=db.$net
if ! test -f $db_file
then
db_file=db.$(expr $net : '\(.*\)\.')
fi
pecho:/etc/bind# > > > pecho:/etc/bind#
pecho:/etc/bind# echo $db_file
db.192.168
pecho:/etc/bind# dig @$net.1 $name.$realm.$vserver_realm.tld | grep "^$name.$realm.$vserver_realm.tld.*IN.*A"
pecho:/etc/bind# echo dig @$net.1 $name.$realm.$vserver_realm.tld
dig @192.168.50.1 packaging-farm.dachary.fsf.tld
pecho:/etc/bind# ifconfig
*** output flushed ***
pecho:/etc/bind# dig @$net.1 $name.$realm.$vserver_realm.tld. | grep "^$name.$realm.$vserver_realm.tld.*IN.*A"
pecho:/etc/bind# dig @$net.1 $name.$realm.$vserver_realm.tld.
; <<>> DiG 9.3.2-P1 <<>> @192.168.50.1 packaging-farm.dachary.fsf.tld.
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 23377
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;packaging-farm.dachary.fsf.tld. IN A
;; AUTHORITY SECTION:
fsf.tld. 1800 IN SOA ns.fsf.tld. hostmaster.fsf.tld. 2007072308 3600 1800 1209600 1800
;; Query time: 0 msec
;; SERVER: 192.168.50.1#53(192.168.50.1)
;; WHEN: Thu Sep 27 00:06:12 2007
;; MSG SIZE rcvd: 98
pecho:/etc/bind# dig @$net.1 $name.$realm.$vserver_realm.tld.
; <<>> DiG 9.3.2-P1 <<>> @192.168.50.1 packaging-farm.dachary.fsf.tld.
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12598
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; QUESTION SECTION:
;packaging-farm.dachary.fsf.tld. IN A
;; ANSWER SECTION:
packaging-farm.dachary.fsf.tld. 3600 IN A 192.168.50.20
;; AUTHORITY SECTION:
fsf.tld. 3600 IN NS ns.fsf.tld.
;; ADDITIONAL SECTION:
ns.fsf.tld. 3600 IN A 192.168.50.1
;; Query time: 0 msec
;; SERVER: 192.168.50.1#53(192.168.50.1)
;; WHEN: Thu Sep 27 00:09:55 2007
;; MSG SIZE rcvd: 97
pecho:/etc/bind# dig @$net.1 $name.$realm.$vserver_realm.tld. | grep "^$name.$realm.$vserver_realm.tld.*IN.*A"
packaging-farm.dachary.fsf.tld. 3600 IN A 192.168.50.20
pecho:/etc/bind# perl -ni -e 'if(/(\d+).*; serial/) { $s = $1; $s++; print "\t\t\t$s\t; serial\n"; } else { print; }' \
$db_file db.$vserver_realm views/$domain.view
> pecho:/etc/bind#
pecho:/etc/bind# hg diff .
diff -r b01accd3be91 etc/bind/db.192.168
--- a/etc/bind/db.192.168 Thu Sep 27 00:09:42 2007 +0200
+++ b/etc/bind/db.192.168 Thu Sep 27 00:11:01 2007 +0200
@@ -4,7 +4,7 @@
;
$TTL 604800
@ IN SOA localhost. root.localhost. (
- 2007092700 ; serial
+ 2007092701 ; serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
diff -r b01accd3be91 etc/bind/db.fsf
--- a/etc/bind/db.fsf Thu Sep 27 00:09:42 2007 +0200
+++ b/etc/bind/db.fsf Thu Sep 27 00:11:01 2007 +0200
@@ -4,7 +4,7 @@
$ORIGIN fsf.tld.
@ IN SOA ns hostmaster (
- 2007092700 ; serial
+ 2007092701 ; serial
1h ; refresh - time when the slave will try to refresh the zone from the master (8h)
30m ; update retry - time between retries if the slave (secondary) (2h)
; fails to contact the master when refresh (above) has expired.
diff -r b01accd3be91 etc/bind/views/dachary.org.view
--- a/etc/bind/views/dachary.org.view Thu Sep 27 00:09:42 2007 +0200
+++ b/etc/bind/views/dachary.org.view Thu Sep 27 00:11:01 2007 +0200
@@ -4,7 +4,7 @@
$ORIGIN conf.tld.
@ IN SOA ns hostmaster (
- 2007092700 ; serial
+ 2007092701 ; serial
1h ; refresh - time when the slave will try to refresh the zone from the master (8h)
30m ; update retry - time between retries if the slave (secondary) (2h)
; fails to contact the master when refresh (above) has expired.
pecho:/etc/bind# echo $db_file
db.192.168
pecho:/etc/bind# grep $name $db_file
20.50 IN PTR packaging-farm.dachary.fsf.tld.
pecho:/etc/bind# getent hosts $name.$realm.$vserver_realm.tld.
192.168.50.20 packaging-farm.dachary.fsf.tld
pecho:/etc/bind# expr "$(getent hosts $name.$realm.$vserver_realm.tld.)" : ".*\.\([0-9][0-9]*\)"
20
pecho:/etc/bind# ip=(expr "$(getent hosts $name.$realm.$vserver_realm.tld.)" : ".*\.\([0-9][0-9]*\)")
pecho:/etc/bind# echo $ip
expr
pecho:/etc/bind# ip=$(expr "$(getent hosts $name.$realm.$vserver_realm.tld.)" : ".*\.\([0-9][0-9]*\)")
pecho:/etc/bind# echo $ip
20
pecho:/etc/bind# perl -pi -e "s/$name.$realm/available-$ip/" $db_file
pecho:/etc/bind# perl -pi -e "s/$name.$realm/available-$ip/" db.$vserver_realm
pecho:/etc/bind# perl -pi -e '$_ = "" if(/^'$name'/)' views/$domain.view
pecho:/etc/bind# /etc/init.d/bind9 reload
Reloading domain name service...: bind.
pecho:/etc/bind# dig @$net.1 $name.$realm.$vserver_realm.tld. | grep $ip
fsf.tld. 1800 IN SOA ns.fsf.tld. hostmaster.fsf.tld. 2007092702 3600 1800 1209600 1800
;; WHEN: Thu Sep 27 00:34:10 2007
pecho:/etc/bind# dig @$net.1 $name.$realm.$vserver_realm.tld. | grep $name.$realm.$vserver_realm.tld
; <<>> DiG 9.3.2-P1 <<>> @192.168.50.1 packaging-farm.dachary.fsf.tld.
;packaging-farm.dachary.fsf.tld. IN A
pecho:/etc/bind# dig @$net.1 $name.$realm.$vserver_realm.tld. | grep "^$name.$realm.$vserver_realm.tld"
pecho:/etc/bind# ! dig @$net.1 $name.$realm.$vserver_realm.tld. | grep "^$name.$realm.$vserver_realm.tld"
pecho:/etc/bind# echo $net.$ip
192.168.50.20
pecho:/etc/bind# grep $net.$ip named.conf
view "dachary.org" { match-clients { 192.168.50.13; 192.168.50.14; 192.168.50.17; 192.168.50.19; 192.168.50.20; 192.168.50.22; 192.168.50.23; 192.168.50.27; 192.168.50.28; 192.168.50.33; 192.168.50.35; 192.168.50.38; 192.168.50.40; 192.168.50.41; 192.168.50.43; 192.168.50.44; 88.191.250.36; 192.168.50.254; 192.168.50.253; 192.168.50.251; 192.168.50.250; 192.168.50.249; 192.168.50.248; };
pecho:/etc/bind# perl -pi -e "s/$net.$ip; //" named.conf
pecho:/etc/bind# hg status .
M db.192.168
M db.fsf
M named.conf
M views/dachary.org.view
pecho:/etc/bind# grep $net.$ip named.conf
pecho:/etc/bind# /etc/init.d/bind9 reload
Reloading domain name service...: bind.
pecho:/etc/bind# hg commit -u $author -m "undefine $name local names in $realm" /etc/bind
pecho:/etc/bind# echo DONE
DONE
pecho:/etc/bind#
[[Summary]]
[[Rationale]]
[[Use Cases]]
[[Scope]]
[[Design]]
[[Implementation]]
[[Unresolved Issues]]
set -e
meta="$1"
echo $meta
name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
echo $name
domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
author="$(xmlstarlet sel -t -v /appliance/@author < <(dog --no-header $meta))"
http_host="$(xmlstarlet sel -t -v /appliance//http_proxy/@http_host < <(dog --no-header $meta))"
hg_host="$(xmlstarlet sel -t -v /appliance//http_proxy/@hg_host < <(dog --no-header $meta))"
cd /etc/apache2/mods-available/
if ! a2enmod proxy_http | grep already ; then
patch <<'EOF'
diff -r 8177988b2d1d etc/apache2/mods-available/proxy.conf
--- a/etc/apache2/mods-available/proxy.conf Fri Mar 30 12:18:19 2007 +0200
+++ b/etc/apache2/mods-available/proxy.conf Fri Aug 03 18:40:24 2007 +0200
@@ -7,7 +7,8 @@
<Proxy *>
Order deny,allow
- Deny from all
+ Allow from all
+ #Deny from all
#Allow from .your_domain.com
</Proxy>
EOF
fi
cd /etc/apache2/sites-available/
if [ ! -f template.$domain ] ; then
cat > template.$domain <<EOF
<VirtualHost *>
ServerName template.$domain
ServerAlias template.conf.tld
ProxyPass / http://http_host/
ProxyPassReverse / http://http_host/
ServerAdmin root@$domain
ErrorLog /var/log/apache2/http_host-error.log
CustomLog /var/log/apache2/http_host-access.log common
</VirtualHost>
<VirtualHost *>
ServerName hg.template.$domain
ServerAlias hg.template.conf.tld
ProxyPass / http://hg_host/
ProxyPassReverse / http://hg_host/
ServerAdmin root@$domain
ErrorLog /var/log/apache2/http_host-error.log
CustomLog /var/log/apache2/http_host-access.log common
</VirtualHost>
EOF
fi
sed -e "s/template/$name/g" -e "s/hg_host/$hg_host/g" -e "s/http_host/$http_host/g" < template.$domain > $name.$domain
a2ensite $name.$domain
/etc/init.d/apache2 reload
sleep 2
if [ ! -f /var/log/apache2/$http_host-error.log ] ; then
echo "/var/log/apache2/$http_host-error.log does not exist"
exit 1
fi
hg add $name.$domain
hg commit -u $author -m "define proxy for $name.$domain" $name.$domain
echo DONE
Write no code. The actual implementation must consist of configuration lines for each software involved. The implementation must be a set of configuration actions described to fit one or more use case.
Use configuration generators that are designed to create a variety of configuration tweaks (files or patches) based on a centralized description.
/***
|''Name:''|GenerateRssByTagPlugin|
|''Description:''|Only tiddlers with a specific tag are inluded in the RSSFeed. If no tiddlers are selected then works as before. (see ticket #270: http://trac.tiddlywiki.org/tiddlywiki/ticket/270). <br>RssTag: <<option txtRssTag>>|
|''Version:''|1.0.3|
|''Date:''|May 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#GenerateRssByTagPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.GenerateRssByTagPlugin = {
major: 1, minor: 0, revision: 3,
date: new Date("May 17, 2007"),
source: 'http://tiddlywiki.bidix.info/#GenerateRssByTagPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0 (Beta 5)'
};
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.generateRssByTag = function()
{
var s = [];
var d = new Date();
var u = store.getTiddlerText("SiteUrl");
// Assemble the header
s.push("<" + "?xml version=\"1.0\"" + " encoding='UTF-8' " + "?" + ">");
s.push("<rss version=\"2.0\">");
s.push("<channel>");
s.push("<title" + ">" + wikifyPlain("SiteTitle").htmlEncode() + "</title" + ">");
if(u)
s.push("<link>" + u.htmlEncode() + "</link>");
s.push("<description>" + wikifyPlain("SiteSubtitle").htmlEncode() + "</description>");
s.push("<language>en-us</language>");
s.push("<copyright>Copyright " + d.getFullYear() + " " + config.options.txtUserName.htmlEncode() + "</copyright>");
s.push("<pubDate>" + d.toGMTString() + "</pubDate>");
s.push("<lastBuildDate>" + d.toGMTString() + "</lastBuildDate>");
s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");
s.push("<generator>TiddlyWiki " + version.major + "." + version.minor + "." + version.revision + "</generator>");
// The body
var tiddlers;
if (config.options.txtRssTag && store.getTaggedTiddlers(config.options.txtRssTag).length > 0)
tiddlers = store.getTaggedTiddlers(config.options.txtRssTag,"modified");
else
tiddlers = store.getTiddlers("modified","excludeLists");
var n = config.numRssItems > tiddlers.length ? 0 : tiddlers.length-config.numRssItems;
for (var t=tiddlers.length-1; t>=n; t--)
s.push(tiddlers[t].saveToRss(u));
// And footer
s.push("</channel>");
s.push("</rss>");
// Save it all
return s.join("\n");
};
//
// Initializations
//
bidix.generateRss = generateRss; // backup core version
generateRss = bidix.generateRssByTag; // install new one
config.options.txtRssTag = "toRSS"; // default RssTag. use <<option txtRssTag>> to overwritte
merge(config.optionsDesc,{txtRssTag: "Only tiddlers with this tag will be included in the RSS Feed."});
//}}}
/***
| Name|HideWhenPlugin|
| Description|Allows conditional inclusion/exclusion in templates|
| Version|3.0 ($Rev: 1845 $)|
| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|
| Source|http://mptw.tiddlyspot.com/#HideWhenPlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{
window.removeElementWhen = function(test,place) {
if (test) {
removeChildren(place);
place.parentNode.removeChild(place);
}
};
merge(config.macros,{
hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( eval(paramString), place);
}},
showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !eval(paramString), place);
}},
hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place);
}},
showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place);
}},
hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAny(params), place);
}},
showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAny(params), place);
}},
hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place);
}},
showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place);
}},
hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);
}},
showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);
}}
});
//}}}
The context is a Debian etch GNU/Linux distribution.
[[Summary]]
[[Rationale]]
[[Use Cases]]
[[Scope]]
[[Design]]
[[Implementation]]
[[Unresolved Issues]]
[img[Cedre du barouk|images/small/Cedre du barouk.jpg][images/large/Cedre du barouk.jpg]]<<imagebox>>
# cmd openalpp osgal dachary.org /etc/bind
set -e
name="$1"
newname="$2"
domain="$3"
file="$4"
if grep -rl $name $file ; then
grep -rl $name $file | xargs perl -ni -e 'if(/(\d+).*; serial/) { $s = $1; $s++; print "\t\t\t$s\t; serial\n"; } else { print; }'
grep -rl $name $file | xargs perl -pi -e "s/\b$name\b/$newname/g"
! grep -rl $name $file
/etc/init.d/bind9 reload
sleep 1
! getent hosts $name.$domain
getent hosts $newname.$domain
fi
set -e
meta="$1"
name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
author="$(xmlstarlet sel -t -v /appliance/@author < <(dog --no-header $meta))"
parent="$(xmlstarlet sel -t -v /appliance//nagios/@parent < <(dog --no-header $meta))"
address="$(xmlstarlet sel -t -v /appliance//nagios/@address < <(dog --no-header $meta))"
cd /etc/nagios2/conf.d
cat >> $domain.cfg <<EOF
define host {
host_name $name
parents $parent
alias $name mercurial
address $address
hostgroups http-servers, debian-servers
use http-host
}
EOF
/etc/init.d/nagios2 stop ; sleep 2; /etc/init.d/nagios2 start
hg commit -u $author -m "monitor $name" $domain.cfg
echo DONE
# cmd openalpp osgal dachary.org loic@dachary.org
set -e
name="$1"
newname="$2"
domain="$3"
author="$4"
cd /etc/nagios2/conf.d
grep -l $name $domain.cfg
perl -pi -e "s/\b$name\b/$newname/ if(/host_name.*$name/ .. /\}/)" $domain.cfg
! grep -l $name $domain.cfg
/etc/init.d/nagios2 stop
sleep 1
/etc/init.d/nagios2 start
hg commit -u $author -m "nagios rename $name into $newname" /etc/nagios2
** Proppy wants the apache appliance to access the ~MySQL appliance.
** Both appliances are on the same LAN.
** Proppy creates a view in the ~BIND9 DNS serving the apache appliance.
** The view is only active for the 192.168.50.0/24 addresses.
** Within this view a new top level domain name is availble : .conf.
** Proppy defines mysql.conf to be the IP address of the mysql software appliance.
** Proppy configures the phpmyadmin available on the apache appliance to use the ~MySQL database from the mysql.conf host.
** When the apache appliance is moved on another LAN, the DNS of this new LAN must bind mysql.conf to the appropriate IP address.
** Proppy will not have to make changes within the software appliance as long as all references to resources on the LAN are named within the .conf top level domain name.
After {{{NameVirtualHost *}}} add the following so that it catches all unknown hostnames instead of being delivered to the first virtual host.
{{{
<VirtualHost _default_>
ServerName fake
</VirtualHost>
}}}
{{{
(03:08:09 PM) dachary: yo
(03:08:50 PM) dachary: un petit tip apache2 ?
(03:10:23 PM) gryzor: y a qu'a demander, mon bon Loic :)
(03:11:52 PM) dachary: alors alors
(03:11:54 PM) dachary: hum
(03:12:02 PM) dachary: mais qui tu me connais toi que je te connais ?
(03:12:43 PM) gryzor: de vue seulement
(03:12:56 PM) dachary: question: apache2 + virtual host : comment faire pour qu'un host qui n'est pas explicitement liste donne une erreur ?
(03:13:07 PM) dachary: ma question est pas hyper claire
(03:13:14 PM) gryzor: il suffit de faire donner une erreur par le 1er virtualhost
(03:13:22 PM) dachary: mais comment ?
(03:13:24 PM) gryzor: (donc, de le dedier a cela)
(03:13:27 PM) dachary: ah
(03:13:28 PM) dachary: ah
(03:13:31 PM) dachary: hum
(03:13:33 PM) dachary: ok
(03:13:40 PM) dachary: j'essaye
(03:13:41 PM) dachary: smart
(03:13:41 PM) fajita: smart is not enabled
(03:13:50 PM) gryzor: ou alors de definir un virtualhost qui s'appelle "_default_"
(03:14:53 PM) dachary: <VirtualHost _default_>
(03:14:57 PM) dachary: genre ca ?
(03:18:01 PM) dachary: hum
(03:18:13 PM) dachary: alors bon ca marche mais ca a des effets zarb
(03:19:52 PM) gryzor: faq1
(03:19:52 PM) fajita: The value of a NameVirtualHost directive has to match the content of <VirtualHost> exactly. For example, NameVirtualHost *:80 must be used with <VirtualHost *:80>
(03:20:47 PM) dachary: ...
(03:20:50 PM) dachary: ok
(03:20:57 PM) dachary: faq0 : url de la faq ?
(03:21:01 PM) dachary: nan j'abuse ;-)
(03:21:37 PM) dachary: <VirtualHost *>
(03:21:42 PM) dachary: ServerName pokersource.info
(03:21:48 PM) dachary: ServerAlias www.pokersource.info
(03:21:56 PM) dachary: et avant j'ai
(03:22:12 PM) dachary: <VirtualHost _default_>
(03:22:27 PM) dachary: et avant j'ai
(03:22:33 PM) dachary: NameVirtualHost *
(03:22:33 PM) fajita: NameVirtualHost * is 6usually what you want, if you only have one ip address
(03:22:43 PM) dachary: j'ai une seule IP
(03:22:58 PM) dachary: j'ai lu la faq mais la logique m'echape
(03:23:03 PM) dachary: *:80 ce n'est pas *exact*
(03:23:10 PM) dachary: pisque y'a un wildcard
(03:23:28 PM) dachary: donc je comprends pas ce que veut dire "exactly" dans ce contexte
(03:23:46 PM) dachary: ou alors il faut que je mette
(03:23:56 PM) dachary: NameVirtualHost pokersource.info:80
(03:23:58 PM) dachary: avant
(03:24:08 PM) dachary: <VirtualHost pokersource.info:80>
(03:24:21 PM) dachary: je vais essayer ca
(03:24:32 PM) gryzor: non surtout pas
(03:24:41 PM) dachary: y'a un truc qui m'echape
(03:24:47 PM) dachary: ca doit etre enorme
(03:24:54 PM) gryzor: jamais de nom comme parametre a VirtualHost
(03:24:59 PM) gryzor: toujours une IP, ou une *
(03:25:07 PM) gryzor: ou _defaultÃ_
(03:25:32 PM) gryzor: donc la conf avec * et _default_ est bonne
(03:25:36 PM) gryzor: tu as quoi comme effet de bord ?
(03:25:41 PM) dachary: ok
(03:26:01 PM) dachary: http://pokersource.info/ -> not found
(03:26:09 PM) dachary: http://www.pokersource.info/ -> ok
(03:26:16 PM) gryzor: ServerAlias
(03:26:16 PM) fajita: ServerAlias is http://httpd.apache.org/docs/2.2/mod/core.html#serveralias or http://httpd.apache.org/docs/1.3/mod/core.html#serveralias
(03:26:17 PM) dachary: j'ajoute le :80
(03:26:31 PM) dachary: je regarde
(03:26:43 PM) dachary: ServerAlias www.pokersource.info
(03:26:49 PM) gryzor: voila
(03:26:54 PM) dachary: j'ai ca deja
(03:26:59 PM) gryzor: et en ServerName
(03:27:03 PM) gryzor: ?
(03:27:52 PM) gryzor: dns www.pokersource.info
(03:27:53 PM) fajita: gryzor: www.pokersource.info is 88.191.250.37
(03:27:55 PM) dachary: ServerName pokersource.info
(03:27:55 PM) gryzor: dns pokersource.info
(03:27:55 PM) fajita: gryzor: pokersource.info is 88.191.250.37
(03:27:59 PM) dachary: voila
(03:28:20 PM) gryzor: aucun des 2 ne fonctionne
(03:28:26 PM) dachary: NameVirtualHost *
(03:28:26 PM) dachary: <VirtualHost _default_>
(03:28:26 PM) dachary: </VirtualHost>
(03:28:26 PM) dachary: <VirtualHost *>
(03:28:26 PM) dachary: ServerName pokersource.info
(03:28:26 PM) dachary: ServerAlias www.pokersource.info
(03:28:26 PM) dachary:
(03:28:27 PM) fajita: NameVirtualHost * is 6usually what you want, if you only have one ip address
(03:28:29 PM) gryzor: The requested URL / was not found on this server.
(03:28:40 PM) gryzor: apc
(03:28:40 PM) fajita: Try using http://apache.pastebin.ca - It's a good pastebin, and is even set up to highlight Apache 'stuff'.
(03:28:44 PM) dachary: www.pokersource.info ne marche pas ??
(03:28:47 PM) gryzor: non
(03:28:52 PM) gryzor: vide ton cache
(03:29:00 PM) dachary: putain de firefox de mes couilles !!!!
(03:29:22 PM) dachary: :-)
(03:29:58 PM) dachary: hum
(03:30:10 PM) dachary: wget http://www.pokersource.info/ ca marche chez moi
(03:30:20 PM) dachary: je regarde les logs
(03:31:25 PM) gryzor: ok, maintenant oui
(03:32:04 PM) dachary: uof
(03:32:04 PM) dachary: ouf
(03:32:06 PM) dachary: :-)
(03:32:18 PM) dachary: par contre wget http://pokersource.info/ marche pas
(03:32:26 PM) dachary: avec la config ci dessus
(03:32:38 PM) gryzor: que dit le journal d'erreurs
(03:32:39 PM) gryzor: ?
(03:33:58 PM) dachary: file does not exist /htdocs
(03:34:10 PM) gryzor: paste config
(03:34:28 PM) gryzor: fajita: paste config
(03:34:28 PM) fajita: gryzor: i'm not following you...
(03:34:37 PM) gryzor: bon,
(03:34:39 PM) gryzor: stupid bot
(03:34:39 PM) fajita: Dumb human.
(03:34:47 PM) dachary: http://hg.pokersource.info/file/7cde5a08ed7f/etc/apache2/sites-available/default
(03:34:54 PM) dachary: :-)
(03:35:01 PM) dachary: j'ai juste change le debut
(03:35:04 PM) dachary: de la config
(03:35:15 PM) dachary: comme montre ci dessus
(03:36:16 PM) gryzor: tout VirtualHost devrait avoir un ServerName
(03:36:50 PM) dachary: oh
(03:36:56 PM) dachary: y compris le premier _default_ ?
(03:37:07 PM) gryzor: oui
(03:37:14 PM) gryzor: meme si le nom est bidon
(03:37:16 PM) dachary: ah
(03:37:19 PM) dachary: je fais
(03:38:37 PM) dachary: http://hg.pokersource.info/file/a61226fbf24e/etc/apache2/sites-available/default
(03:38:39 PM) dachary: marche mieux
(03:38:41 PM) dachary: :-)
(03:38:52 PM) dachary: j'aurais JAMAIS trouve cette subtilite
(03:39:27 PM) gryzor: disons que c a ca que le support sert :)
(03:39:28 PM) dachary: c'est genial
(03:39:39 PM) dachary: ben bravo les gars
}}}
PasswordOptionPlugin is not compatible TiddlyWiki version 2.1.
See http://tiddlylab.bidix.info/#PasswordOptionPlugin
** Proppy wants to add a forum to the apache appliance.
** Using //hg incoming//, proppy checks if pending modifications from the publicly available apache appliance need to be transfererd to the copy running on his laptop.
** After applying the changes, proppy installs the forum.
** Proppy tests the forum and asks his friends to give it a try using the 37080 port that is being forwarded to his laptop.
** Turns out that the forum is a really bad software that requires too much work.
** Proppy stops the apache appliance and revert to the state it was before trying the forum software using the //hg revert// command.
** When proppy is satisfied with the forum software installed, he creates a changeset and publishes it to the publicly available appliance.
set -e
app=dog ; apt-get install -y --force-yes $app
app=xmlstarlet ; apt-get install -y --force-yes $app
meta="$1"
name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
url="$(xmlstarlet sel -t -v /appliance//garden/@url < <(dog --no-header $meta))"
seed="$(xmlstarlet sel -t -v /appliance//garden/@seed < <(dog --no-header $meta))"
mkdir -p /home/www
cd /home/www
wget -q "$url"
wget -q "$seed"
echo DONE
** Proppy wants to publish sensitive information as part of the software appliance
** The information is not essential for the appliance to work
** It's not extremely sensitive either, otherwise proppy would not publish it at all
** Proppy installs seahorse, the gnome cryptographic assistant
** Proppy uses nautilus to select the files or directories that he want to encrypt
** When asked by seahorse, proppy crypts the selected files for decryption by himself and a few others
** Proppy creates a skeleton vserver on the OS where a public IP was dedicated to the apache appliance.
** The skeleton vserver has a LAN IP that will receive incoming connections from the public IP.
** Proppy edits the DNS to define the .conf names required by the apache appliance.
** Proppy creates a mercurial repository at the root of the apache appliance.
** Proppy stops the apache appliance on his laptop.
** The apache appliance is rsync'ed from the laptop to the remote OS.
** Proppy starts the appliance on the remote OS and accesses it from the public IP.
When running a networked service there is a need to experiment with a clone while the original is still available to the public. Virtual machines are easy to setup based on a backup of an existing virtual server. Switches, cables and firewalls are less intuitives to replicate.
dachary:~# meta=http://garden.conf.tld/packaging-farm.xml
dachary:~# echo $name.$domain
.
dachary:~# name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
dachary:~# domain="$(xmlstarlet sel -t -v /appliance/@domain < <(dog --no-header $meta))"
dachary:~# author="$(xmlstarlet sel -t -v /appliance/@author < <(dog --no-header $meta))"
dachary:~# a2dissite $name.$domain
Site packaging-farm.dachary.org disabled; run /etc/init.d/apache2 reload to fully disable.
dachary:~# hg addremove /etc/apache2/
removing ../etc/apache2/sites-enabled/packaging-farm.dachary.org
dachary:~# rm -f /etc/apache2/sites-available/packaging-farm.dachary.org
dachary:~# hg addremove /etc/apache2/
removing ../etc/apache2/sites-available/packaging-farm.dachary.org
dachary:~# #hg commit -u $author -m "remove proxy for $name.$domain" /etc/apache2
dachary:~# hg status /etc/apache2
R ../etc/apache2/sites-available/packaging-farm.dachary.org
R ../etc/apache2/sites-enabled/packaging-farm.dachary.org
dachary:~# hg commit -u $author -m "remove proxy for $name.$domain" /etc/apache2
# rm /var/log/apache/*$name*
dachary:~# echo DONE
DONE
dachary:~#
pecho:~# meta=http://garden.conf.tld/packaging-farm.xml
pecho:~# name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
pecho:~# echo $name
packaging-farm
pecho:~# vserver $name stop
*** output flushed ***
pecho:~# vserver $name status
*** output flushed ***
pecho:~# vserver $name status | grep stop
Vserver 'packaging-farm' is stopped
pecho:~#
dachary:/etc# meta=http://garden.conf.tld/packaging-farm.xml
dachary:/etc# name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header "$meta"))"
dachary:/etc# rss="$(xmlstarlet sel -t -v /appliance/rss/@url < <(dog --no-header "$meta"))"
dachary:/etc# echo $name
packaging-farm
dachary:/etc# #perl -pi -e '$_ = "" if(/\['$rss'/)' /etc/planet.conf
dachary:/etc# grep $rss /etc/planet.conf
http://packaging-farm.conf.tld:8000/rss-log
dachary:/etc# #perl -pi -e '$_ = "" if(/\['$rss'/)' /etc/planet.conf
dachary:/etc# grep $rss /etc/planet.conf
[http://packaging-farm.conf.tld:8000/rss-log]
dachary:/etc# perl -pi -e '$_ = "" if(/\['$rss'/)' /etc/planet.conf
Warning: Use of "log" without parentheses is ambiguous at -e line 1.
syntax error at -e line 1, near "tld:"
Search pattern not terminated at -e line 1.
dachary:/etc# perl -pi -e '$_ = "" if(|\['$rss'|)' /etc/planet.conf
Bareword found where operator expected at -e line 1, near "//packaging"
(Missing operator before packaging?)
syntax error at -e line 1, near "(|"
Missing right curly or square bracket at -e line 1, at end of line
Execution of -e aborted due to compilation errors.
dachary:/etc# perl -pi -e '$_ = "" if(m|\['$rss'|)' /etc/planet.conf
dachary:/etc# grep $rss /etc/planet.conf
dachary:/etc# #perl -pi -e '$_ = "" if(m|^name = '$name'|)' /etc/planet.conf
dachary:/etc# grep '^name = '$name /etc/planet.conf
dachary:/etc# grep '^name = '$name /etc/planet.conf
name = packaging-farm
dachary:/etc# perl -pi -e '$_ = "" if(m|^name = '$name'|)' /etc/planet.conf
dachary:/etc# grep '^name = '$name /etc/planet.conf
dachary:/etc#
[[Rename a software appliance (script)]]
# [[Modify a DNS entry to change a host name]] on the DNS hosting the public name
# [[Modify a DNS entry to change a host name]] on the DNS hosting the vserver
# [[Rename a vserver]] with the new name
# [[Apache proxy name change]] with the new name
# [[Nagios monitored vserver name change]] with the new name
# [[Rename planet aggregated feed]] with the new name
# [[Rename shorewall port redirections]] with the new name
mkdir app
cd app
mkdir universe
ruby /usr/bin/tiddlywiki_cp -a http://garden.dachary.org/universe.html universe
author=loic@dachary.org
name=feed-reader
newname=yocto-reader
domain=dachary.org
file=/etc/bind
public_ns=ns2.fsffrance.org
scp universe/Modify\ a\ DNS\ entry\ to\ change\ a\ host\ name.tiddler root@$public_ns:/tmp/step1
ssh root@$public_ns sh -x /tmp/step1 $name $newname $domain $file $author
vserver_realm=fsf
realm=dachary
vserver_host=pecho.fsffrance.org
scp universe/Modify\ a\ DNS\ entry\ to\ change\ a\ host\ name.tiddler root@$vserver_host:/tmp/step2
ssh root@$vserver_host sh -x /tmp/step2 $name $newname $realm.$vserver_realm.tld $file $author
scp universe/Rename\ a\ vserver.tiddler root@$vserver_host:/tmp/step3
ssh root@$vserver_host sh -x /tmp/step3 $name $newname $author
proxy_vserver_host=pecho.fsffrance.org
proxy_name=dachary
scp universe/Apache\ proxy\ name\ change.tiddler root@$proxy_vserver_host:/var/lib/vservers/$proxy_name/tmp/step4
ssh root@$proxy_vserver_host vserver $proxy_name exec "sh -x /tmp/step4 $name $newname $domain $author"
nagios_vserver_host=mango.pokersource.info
nagios_name=nagiosfsf
scp universe/Nagios\ monitored\ vserver\ name\ change.tiddler root@$nagios_vserver_host:/var/lib/vservers/$nagios_name/tmp/step5
ssh root@$nagios_vserver_host vserver $nagios_name exec "sh -x /tmp/step5 $name $newname $domain $author"
rss_host=dachary.org
scp universe/Rename\ planet\ aggregated\ feed.tiddler root@$rss_host:/tmp/step6
ssh root@$rss_host sh -x /tmp/step6 $name $newname $author
# cmd openalpp osgal
set -e
name="$1"
newname="$2"
vserver $name stop
#http://oldwiki.linux-vserver.org/TweakingTheConfig
mv /etc/vservers/$name /etc/vservers/$newname
mv /var/lib/vservers/$name /var/lib/vservers/$newname
cd /etc/vservers/$newname
rm cache run vdir
ln -s /etc/vservers/.defaults/cachebase/$newname cache
ln -s /var/run/vservers/$newname run
ln -s /etc/vservers/.defaults/vdirbase/$newname vdir
xid=$(cat context)
rm /var/run/vservers.rev/$xid
ln -s /etc/vservers/$newname /var/run/vservers.rev/$xid
echo $newname > name
perl -pi -e "s/\b$name\b/$newname/" uts/nodename
grep -rl $name /var/lib/vservers/$newname/var/cache/mercurial/rss | xargs perl -pi -e "s/\b$name\b/$newname/"
grep -rl $name /var/lib/vservers/$newname/etc/default /var/lib/vservers/$newname/etc/hosts | xargs perl -pi -e "s/\b$name\b/$newname/"
vserver $newname start
# cmd openalpp osgal dachary.org loic@dachary.org
set -e
name="$1"
newname="$2"
author="$3"
cd /etc/
grep -l $name planet.conf
perl -pi -e "s/\b$name\b/$newname/" planet.conf
! grep -l $name planet.conf
for file in /var/cache/planet/*$name* ; do
newfile=$(echo $file | perl -p -e "s/\b$name\b/$newname/g")
mv $file $newfile
done
hg commit -u $author -m "planet rename $name into $newname" /etc/planet.conf
something like /etc/shorewall/$ip/$name /etc/shorewall/$ip/$newname
/***
| Name:|RenameTagsPlugin|
| Description:|Allows you to easily rename or delete tags across multiple tiddlers|
| Version:|3.0 ($Rev: 1845 $)|
| Date:|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|
| Source:|http://mptw.tiddlyspot.com/#RenameTagsPlugin|
| Author:|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
Rename a tag and you will be prompted to rename it in all its tagged tiddlers.
***/
//{{{
config.renameTags = {
prompts: {
rename: "Rename the tag '%0' to '%1' in %2 tidder%3?",
remove: "Remove the tag '%0' from %1 tidder%2?"
},
removeTag: function(tag,tiddlers) {
store.suspendNotifications();
for (var i=0;i<tiddlers.length;i++) {
store.setTiddlerTag(tiddlers[i].title,false,tag);
}
store.resumeNotifications();
store.notifyAll();
},
renameTag: function(oldTag,newTag,tiddlers) {
store.suspendNotifications();
for (var i=0;i<tiddlers.length;i++) {
store.setTiddlerTag(tiddlers[i].title,false,oldTag); // remove old
store.setTiddlerTag(tiddlers[i].title,true,newTag); // add new
}
store.resumeNotifications();
store.notifyAll();
},
storeMethods: {
saveTiddler_orig_renameTags: TiddlyWiki.prototype.saveTiddler,
saveTiddler: function(title,newTitle,newBody,modifier,modified,tags,fields) {
if (title != newTitle) {
var tagged = this.getTaggedTiddlers(title);
if (tagged.length > 0) {
// then we are renaming a tag
if (confirm(config.renameTags.prompts.rename.format([title,newTitle,tagged.length,tagged.length>1?"s":""])))
config.renameTags.renameTag(title,newTitle,tagged);
if (!this.tiddlerExists(title) && newBody == "")
// dont create unwanted tiddler
return null;
}
}
return this.saveTiddler_orig_renameTags(title,newTitle,newBody,modifier,modified,tags,fields);
},
removeTiddler_orig_renameTags: TiddlyWiki.prototype.removeTiddler,
removeTiddler: function(title) {
var tagged = this.getTaggedTiddlers(title);
if (tagged.length > 0)
if (confirm(config.renameTags.prompts.remove.format([title,tagged.length,tagged.length>1?"s":""])))
config.renameTags.removeTag(title,tagged);
return this.removeTiddler_orig_renameTags(title);
}
},
init: function() {
merge(TiddlyWiki.prototype,this.storeMethods);
}
}
config.renameTags.init();
//}}}
** Proppy wants to use his ssh private key from withing the vserver to gain write access to a SVN repository
** Proppy adds the following lines to /etc/vservers/pokerdev/fstab
{{{
/home/proppy /home/proppy none bind 0 0
}}}
** Proppy mkdir /home/proppy within the vserver
** Proppy adds the following line in /etc/ssh/sshd_config
{{{
X11UseLocalhost no
}}}
** Proppy installs xauth so that X11 forwarding works
{{{
apt-get install xbase-clients
}}}
** Proppy creates the file /etc/hosts with the following content where pokerdev.pokersource.info is the hostname of the vserver and 192.168.70.18 is its IP
{{{
192.168.70.18 pokerdev.pokersource.info
}}}
** Proppy creates the user proppy making sure the uid matches his local machine uid (1000) in this case. He also inserts himself in the users group (100) so that other users of the same appliance can group with him.
{{{
adduser --gecos 'Proppy Aminche' --disabled-password --uid 1000 --gid 100 proppy
}}}
** Proppy logs in the server using
{{{
ssh -X proppy@pokerdev
}}}
** Proppy apt-get install ssh-askpass or another package providing X11 based passphrase challenge
** Proppy sets the following environment variables when he wants to work as root. Although he prefers to work as himself, his home is not always available when in a remote location.
{{{
export SVN_SSH='ssh -i /home/proppy/.ssh/id_rsa'
export SSH_ASKPASS=/usr/lib/ssh/x11-ssh-askpass
}}}
** Proppy extracts a svn tree in /usr/src, making sure the directory have the setgid bit set to allow editing by other members of the users group
** Proppy installs emacs-snapshot because emacs does not have the svn-status command
** Proppy runs emacs, edit files, run svn-status and when commiting with svn-status gives his passphrase to write the repository
Vritual machines are meant to be used in the context of an online service. Average GNU/Linux system administration skills are required.
No software must be implemented. If a new ~BIND9 feature or a vserver feature is to be implemented, another specification has to be written.
including OS, cables, switches and firewalls
http://garden.dachary.org/universe.html
Virtual machines such as vmware, xen instances, vserver or even chroot can be connected using virtual cables and switches and their access controled by virtual firewalls.
set -e
meta="$1"
name="$(xmlstarlet sel -t -v /appliance/@name < <(dog --no-header $meta))"
rss="$(xmlstarlet sel -t -v /appliance/rss/@url < <(dog --no-header $meta))"
echo "[$rss]" >> /etc/planet.conf
echo "name = $name" >> /etc/planet.conf
su www-data -c 'planetplanet -v /etc/planet.conf'
echo DONE
/***
| Name|TagglyTaggingPlugin|
| Description|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|
| Version|3.1 ($Rev: 2341 $)|
| Date|$Date: 2007-07-05 10:02:27 +1000 (Thu, 05 Jul 2007) $|
| Source|http://mptw.tiddlyspot.com/#TagglyTaggingPlugin|
| Author|Simon Baird <simon.baird@gmail.com>|
| License|http://mptw.tiddlyspot.com/#TheBSDLicense|
!Notes
See http://mptw.tiddlyspot.com/#TagglyTagging
***/
//{{{
config.taggly = {
// for translations
lingo: {
labels: {
asc: "\u2191", // down arrow
desc: "\u2193", // up arrow
title: "title",
modified: "modified",
created: "created",
show: "+",
hide: "-",
normal: "normal",
group: "group",
commas: "commas",
sitemap: "sitemap",
numCols: "cols\u00b1", // plus minus sign
label: "Tagged as '%0':",
excerpts: "excerpts",
contents: "contents",
sliders: "sliders",
noexcerpts: "title only"
},
tooltips: {
title: "Click to sort by title",
modified: "Click to sort by modified date",
created: "Click to sort by created date",
show: "Click to show tagging list",
hide: "Click to hide tagging list",
normal: "Click to show a normal ungrouped list",
group: "Click to show list grouped by tag",
sitemap: "Click to show a sitemap style list",
commas: "Click to show a comma separated list",
numCols: "Click to change number of columns",
excerpts: "Click to show excerpts",
contents: "Click to show entire tiddler contents",
sliders: "Click to show tiddler contents in sliders",
noexcerpts: "Click to show entire title only"
}
},
config: {
showTaggingCounts: true,
listOpts: {
// the first one will be the default
sortBy: ["title","modified","created"],
sortOrder: ["asc","desc"],
hideState: ["show","hide"],
listMode: ["normal","group","sitemap","commas"],
numCols: ["1","2","3","4","5","6"],
excerpts: ["noexcerpts","excerpts","contents","sliders"]
},
valuePrefix: "taggly.",
excludeTags: ["excludeLists","excludeTagging"],
excerptSize: 50,
excerptMarker: "/%"+"%/"
},
getTagglyOpt: function(title,opt) {
var val = store.getValue(title,this.config.valuePrefix+opt);
return val ? val : this.config.listOpts[opt][0];
},
setTagglyOpt: function(title,opt,value) {
if (!store.tiddlerExists(title))
// create it silently
store.saveTiddler(title,title,config.views.editor.defaultText.format([title]),config.options.txtUserName,new Date(),null);
// if value is default then remove it to save space
return store.setValue(title,
this.config.valuePrefix+opt,
value == this.config.listOpts[opt][0] ? null : value);
},
getNextValue: function(title,opt) {
var current = this.getTagglyOpt(title,opt);
var pos = this.config.listOpts[opt].indexOf(current);
// a little usability enhancement. actually it doesn't work right for grouped or sitemap
var limit = (opt == "numCols" ? store.getTaggedTiddlers(title).length : this.config.listOpts[opt].length);
var newPos = (pos + 1) % limit;
return this.config.listOpts[opt][newPos];
},
toggleTagglyOpt: function(title,opt) {
var newVal = this.getNextValue(title,opt);
this.setTagglyOpt(title,opt,newVal);
},
createListControl: function(place,title,type) {
var lingo = config.taggly.lingo;
var label;
var tooltip;
var onclick;
if ((type == "title" || type == "modified" || type == "created")) {
// "special" controls. a little tricky. derived from sortOrder and sortBy
label = lingo.labels[type];
tooltip = lingo.tooltips[type];
if (this.getTagglyOpt(title,"sortBy") == type) {
label += lingo.labels[this.getTagglyOpt(title,"sortOrder")];
onclick = function() {
config.taggly.toggleTagglyOpt(title,"sortOrder");
return false;
}
}
else {
onclick = function() {
config.taggly.setTagglyOpt(title,"sortBy",type);
config.taggly.setTagglyOpt(title,"sortOrder",config.taggly.config.listOpts.sortOrder[0]);
return false;
}
}
}
else {
// "regular" controls, nice and simple
label = lingo.labels[type == "numCols" ? type : this.getNextValue(title,type)];
tooltip = lingo.tooltips[type == "numCols" ? type : this.getNextValue(title,type)];
onclick = function() {
config.taggly.toggleTagglyOpt(title,type);
return false;
}
}
// hide button because commas don't have columns
if (!(this.getTagglyOpt(title,"listMode") == "commas" && type == "numCols"))
createTiddlyButton(place,label,tooltip,onclick,type == "hideState" ? "hidebutton" : "button");
},
makeColumns: function(orig,numCols) {
var listSize = orig.length;
var colSize = listSize/numCols;
var remainder = listSize % numCols;
var upperColsize = colSize;
var lowerColsize = colSize;
if (colSize != Math.floor(colSize)) {
// it's not an exact fit so..
upperColsize = Math.floor(colSize) + 1;
lowerColsize = Math.floor(colSize);
}
var output = [];
var c = 0;
for (var j=0;j<numCols;j++) {
var singleCol = [];
var thisSize = j < remainder ? upperColsize : lowerColsize;
for (var i=0;i<thisSize;i++)
singleCol.push(orig[c++]);
output.push(singleCol);
}
return output;
},
drawTable: function(place,columns,theClass) {
var newTable = createTiddlyElement(place,"table",null,theClass);
var newTbody = createTiddlyElement(newTable,"tbody");
var newTr = createTiddlyElement(newTbody,"tr");
for (var j=0;j<columns.length;j++) {
var colOutput = "";
for (var i=0;i<columns[j].length;i++)
colOutput += columns[j][i];
var newTd = createTiddlyElement(newTr,"td",null,"tagglyTagging"); // todo should not need this class
wikify(colOutput,newTd);
}
return newTable;
},
createTagglyList: function(place,title) {
switch(this.getTagglyOpt(title,"listMode")) {
case "group": return this.createTagglyListGrouped(place,title); break;
case "normal": return this.createTagglyListNormal(place,title,false); break;
case "commas": return this.createTagglyListNormal(place,title,true); break;
case "sitemap":return this.createTagglyListSiteMap(place,title); break;
}
},
getTaggingCount: function(title) {
// thanks to Doug Edmunds
if (this.config.showTaggingCounts) {
var tagCount = store.getTaggedTiddlers(title).length;
if (tagCount > 0)
return " ("+tagCount+")";
}
return "";
},
getExcerpt: function(inTiddlerTitle,title,indent) {
if (!indent)
indent = 1;
if (this.getTagglyOpt(inTiddlerTitle,"excerpts") == "excerpts") {
var t = store.getTiddler(title);
if (t) {
var text = t.text.replace(/\n/," ");
var marker = text.indexOf(this.config.excerptMarker);
if (marker != -1) {
return " {{excerpt{<nowiki>" + text.substr(0,marker) + "</nowiki>}}}";
}
else if (text.length < this.config.excerptSize) {
return " {{excerpt{<nowiki>" + t.text + "</nowiki>}}}";
}
else {
return " {{excerpt{<nowiki>" + t.text.substr(0,this.config.excerptSize) + "..." + "</nowiki>}}}";
}
}
}
else if (this.getTagglyOpt(inTiddlerTitle,"excerpts") == "contents") {
var t = store.getTiddler(title);
if (t) {
return "\n{{contents indent"+indent+"{\n" + t.text + "\n}}}";
}
}
else if (this.getTagglyOpt(inTiddlerTitle,"excerpts") == "sliders") {
var t = store.getTiddler(title);
if (t) {
return "<slider slide>\n{{contents{\n" + t.text + "\n}}}\n</slider>";
}
}
return "";
},
notHidden: function(t,inTiddler) {
if (typeof t == "string")
t = store.getTiddler(t);
return (!t || !t.tags.containsAny(this.config.excludeTags) ||
(inTiddler && this.config.excludeTags.contains(inTiddler)));
},
// this is for normal and commas mode
createTagglyListNormal: function(place,title,useCommas) {
var list = store.getTaggedTiddlers(title,this.getTagglyOpt(title,"sortBy"));
if (this.getTagglyOpt(title,"sortOrder") == "desc")
list = list.reverse();
var output = [];
var first = true;
for (var i=0;i<list.length;i++) {
if (this.notHidden(list[i],title)) {
var countString = this.getTaggingCount(list[i].title);
var excerpt = this.getExcerpt(title,list[i].title);
if (useCommas)
output.push((first ? "" : ", ") + "[[" + list[i].title + "]]" + countString + excerpt);
else
output.push("*[[" + list[i].title + "]]" + countString + excerpt + "\n");
first = false;
}
}
return this.drawTable(place,
this.makeColumns(output,useCommas ? 1 : parseInt(this.getTagglyOpt(title,"numCols"))),
useCommas ? "commas" : "normal");
},
// this is for the "grouped" mode
createTagglyListGrouped: function(place,title) {
var sortBy = this.getTagglyOpt(title,"sortBy");
var sortOrder = this.getTagglyOpt(title,"sortOrder");
var list = store.getTaggedTiddlers(title,sortBy);
if (sortOrder == "desc")
list = list.reverse();
var leftOvers = []
for (var i=0;i<list.length;i++)
leftOvers.push(list[i].title);
var allTagsHolder = {};
for (var i=0;i<list.length;i++) {
for (var j=0;j<list[i].tags.length;j++) {
if (list[i].tags[j] != title) { // not this tiddler
if (this.notHidden(list[i].tags[j],title)) {
if (!allTagsHolder[list[i].tags[j]])
allTagsHolder[list[i].tags[j]] = "";
if (this.notHidden(list[i],title)) {
allTagsHolder[list[i].tags[j]] += "**[["+list[i].title+"]]"
+ this.getTaggingCount(list[i].title) + this.getExcerpt(title,list[i].title) + "\n";
leftOvers.setItem(list[i].title,-1); // remove from leftovers. at the end it will contain the leftovers
}
}
}
}
}
var allTags = [];
for (var t in allTagsHolder)
allTags.push(t);
var sortHelper = function(a,b) {
if (a == b) return 0;
if (a < b) return -1;
return 1;
};
allTags.sort(function(a,b) {
var tidA = store.getTiddler(a);
var tidB = store.getTiddler(b);
if (sortBy == "title") return sortHelper(a,b);
else if (!tidA && !tidB) return 0;
else if (!tidA) return -1;
else if (!tidB) return +1;
else return sortHelper(tidA[sortBy],tidB[sortBy]);
});
var leftOverOutput = "";
for (var i=0;i<leftOvers.length;i++)
if (this.notHidden(leftOvers[i],title))
leftOverOutput += "*[["+leftOvers[i]+"]]" + this.getTaggingCount(leftOvers[i]) + this.getExcerpt(title,leftOvers[i]) + "\n";
var output = [];
if (sortOrder == "desc")
allTags.reverse();
else if (leftOverOutput != "")
// leftovers first...
output.push(leftOverOutput);
for (var i=0;i<allTags.length;i++)
if (allTagsHolder[allTags[i]] != "")
output.push("*[["+allTags[i]+"]]" + this.getTaggingCount(allTags[i]) + this.getExcerpt(title,allTags[i]) + "\n" + allTagsHolder[allTags[i]]);
if (sortOrder == "desc" && leftOverOutput != "")
// leftovers last...
output.push(leftOverOutput);
return this.drawTable(place,
this.makeColumns(output,parseInt(this.getTagglyOpt(title,"numCols"))),
"grouped");
},
// used to build site map
treeTraverse: function(title,depth,sortBy,sortOrder) {
var list = store.getTaggedTiddlers(title,sortBy);
if (sortOrder == "desc")
list.reverse();
var indent = "";
for (var j=0;j<depth;j++)
indent += "*"
var childOutput = "";
for (var i=0;i<list.length;i++)
if (list[i].title != title)
if (this.notHidden(list[i].title,this.config.inTiddler))
childOutput += this.treeTraverse(list[i].title,depth+1,sortBy,sortOrder);
if (depth == 0)
return childOutput;
else
return indent + "[["+title+"]]" + this.getTaggingCount(title) + this.getExcerpt(this.config.inTiddler,title,depth) + "\n" + childOutput;
},
// this if for the site map mode
createTagglyListSiteMap: function(place,title) {
this.config.inTiddler = title; // nasty. should pass it in to traverse probably
var output = this.treeTraverse(title,0,this.getTagglyOpt(title,"sortBy"),this.getTagglyOpt(title,"sortOrder"));
return this.drawTable(place,
this.makeColumns(output.split(/(?=^\*\[)/m),parseInt(this.getTagglyOpt(title,"numCols"))), // regexp magic
"sitemap"
);
},
macros: {
tagglyTagging: {
handler: function (place,macroName,params,wikifier,paramString,tiddler) {
var refreshContainer = createTiddlyElement(place,"div");
// do some refresh magic to make it keep the list fresh - thanks Saq
refreshContainer.setAttribute("refresh","macro");
refreshContainer.setAttribute("macroName",macroName);
refreshContainer.setAttribute("title",tiddler.title);
this.refresh(refreshContainer);
},
refresh: function(place) {
var title = place.getAttribute("title");
removeChildren(place);
if (store.getTaggedTiddlers(title).length > 0) {
var lingo = config.taggly.lingo;
config.taggly.createListControl(place,title,"hideState");
if (config.taggly.getTagglyOpt(title,"hideState") == "show") {
createTiddlyElement(place,"span",null,"tagglyLabel",lingo.labels.label.format([title]));
config.taggly.createListControl(place,title,"title");
config.taggly.createListControl(place,title,"modified");
config.taggly.createListControl(place,title,"created");
config.taggly.createListControl(place,title,"listMode");
config.taggly.createListControl(place,title,"excerpts");
config.taggly.createListControl(place,title,"numCols");
config.taggly.createTagglyList(place,title);
}
}
}
}
},
// todo fix these up a bit
styles: [
"/*{{{*/",
"/* created by TagglyTaggingPlugin */",
".tagglyTagging { padding-top:0.5em; }",
".tagglyTagging li.listTitle { display:none; }",
".tagglyTagging ul {",
" margin-top:0px; padding-top:0.5em; padding-left:2em;",
" margin-bottom:0px; padding-bottom:0px;",
"}",
".tagglyTagging { vertical-align: top; margin:0px; padding:0px; }",
".tagglyTagging table { margin:0px; padding:0px; }",
".tagglyTagging .button { visibility:hidden; margin-left:3px; margin-right:3px; }",
".tagglyTagging .button, .tagglyTagging .hidebutton {",
" color:[[ColorPalette::TertiaryLight]]; font-size:90%;",
" border:0px; padding-left:0.3em;padding-right:0.3em;",
"}",
".tagglyTagging .button:hover, .hidebutton:hover, ",
".tagglyTagging .button:active, .hidebutton:active {",
" border:0px; background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];",
"}",
".selected .tagglyTagging .button { visibility:visible; }",
".tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }",
".selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }",
".tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }",
".tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }",
".tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}",
".tagglyTagging ul ul li {margin-left:0.5em; }",
".editLabel { font-size:90%; padding-top:0.5em; }",
".tagglyTagging .commas { padding-left:1.8em; }",
"/* not technically tagglytagging but will put them here anyway */",
".tagglyTagged li.listTitle { display:none; }",
".tagglyTagged li { display: inline; font-size:90%; }",
".tagglyTagged ul { margin:0px; padding:0px; }",
".excerpt { color:[[ColorPalette::TertiaryDark]]; }",
"div.tagglyTagging table,",
"div.tagglyTagging table tr,",
"td.tagglyTagging",
" {border-style:none!important; }",
".tagglyTagging .contents { border-bottom:2px solid [[ColorPalette::TertiaryPale]]; padding:0 1em 1em 0.5em;",
" margin-bottom:0.5em; }",
".tagglyTagging .indent1 { margin-left:3em; }",
".tagglyTagging .indent2 { margin-left:4em; }",
".tagglyTagging .indent3 { margin-left:5em; }",
".tagglyTagging .indent4 { margin-left:6em; }",
".tagglyTagging .indent5 { margin-left:7em; }",
".tagglyTagging .indent6 { margin-left:8em; }",
".tagglyTagging .indent7 { margin-left:9em; }",
".tagglyTagging .indent8 { margin-left:10em; }",
".tagglyTagging .indent9 { margin-left:11em; }",
".tagglyTagging .indent10 { margin-left:12em; }",
"/*}}}*/",
""].join("\n"),
init: function() {
merge(config.macros,this.macros);
config.shadowTiddlers["TagglyTaggingStyles"] = this.styles;
store.addNotification("TagglyTaggingStyles",refreshStyles);
}
};
config.taggly.init();
//}}}
/***
InlineSlidersPlugin
By Saq Imtiaz
http://tw.lewcid.org/sandbox/#InlineSlidersPlugin
// syntax adjusted to not clash with NestedSlidersPlugin
***/
//{{{
config.formatters.unshift( {
name: "inlinesliders",
// match: "\\+\\+\\+\\+|\\<slider",
match: "\\<slider",
// lookaheadRegExp: /(?:\+\+\+\+|<slider) (.*?)(?:>?)\n((?:.|\n)*?)\n(?:====|<\/slider>)/mg,
lookaheadRegExp: /(?:<slider) (.*?)(?:>)\n((?:.|\n)*?)\n(?:<\/slider>)/mg,
handler: function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart ) {
var btn = createTiddlyButton(w.output,lookaheadMatch[1] + " "+"\u00BB",lookaheadMatch[1],this.onClickSlider,"button sliderButton");
var panel = createTiddlyElement(w.output,"div",null,"sliderPanel");
panel.style.display = "none";
wikify(lookaheadMatch[2],panel);
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
},
onClickSlider : function(e) {
if(!e) var e = window.event;
var n = this.nextSibling;
n.style.display = (n.style.display=="none") ? "block" : "none";
return false;
}
});
//}}}
/***
|''Name:''|TiddlyLightBox|
|''Date:''|Jan 1, 2006|
|''Version:''|1.0 beta|
|''Author:''|Saq Imtiaz|
|''Location:''|http://tw.lewcid.org/#TiddlyLightBoxPlugin|
|''Documentation:''|http://tw.lewcid.org/#TiddlyLightBoxDocs|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''Based on:''|DC3.LightBox<br>Light Box Gone Wild <br>Ibox|
!!Code
***/
//{{{
config.macros.imagebox ={};
config.macros.imagebox.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
var e = place.lastChild;
e.onclick = function(){TiddlyLightBox.initBox('image',this,params[1],params[2],params[0]);return false;};
}
config.macros.divbox ={};
config.macros.divbox.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
if (params[0]!=".")
createTiddlyButton(place,params[0],params[0],function(){TiddlyLightBox.initBox('html',params[1],params[3],params[4],params[2]);return false;});
else
{
var e = place.lastChild;
e.onclick = function(){TiddlyLightBox.initBox('html',params[1],params[3],params[4],params[2]);return false;};
}
}
config.macros.tiddlerbox ={}
config.macros.tiddlerbox.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
config.macros.divbox.handler(place,macroName,[params[0],"tiddler:"+params[1],params[2],params[3],params[4]]);
return false;
}
store.addNotification("TiddlyLightBoxStyles",refreshStyles);
if (!window.TiddlyLightBox)
window.TiddlyLightBox = {};
var loadingImage = "indicator.gif";
window.TiddlyLightBox =
{
_curBox: null, // [sentinel]
lightBoxHtml : '<div id="lightBoxOverlay" onclick="TiddlyLightBox.hideBox()" style="display:none"></div><div id="lightboxprogress" style="display:none;"><img src=\''+loadingImage+'\' alt=\'loading\' style="width:128px;height:128px;"></div><div class="lightBox" id="lightBox" style="display:none"><div id="lightBoxContent"></div><div id="lightBoxTitle">This is a title</div><div id="lightBoxClose"><a href:"#" onclick="TiddlyLightBox.hideBox();return false;">Click to close</a></div></div>',
createBoxWrapper : function()
{
var wrapper = createTiddlyElement(document.getElementsByTagName("body")[0],"div","tiddlyLightBoxWrapper");
wrapper.innerHTML = this.lightBoxHtml;
},
initBox : function(contentType,url,w,h,text)
{
if (this._curBox)
return;
this.showProgress();
this.hideSelects("hidden");
this.showBg();
this._curBox = true;
this.sizeTheBox(contentType,w,h);
if (contentType == 'image')
this.showImage(url,text);
else if (contentType == 'html')
this.showHtml(url,text);
return false;
},
sizeTheBox : function(contentType,w,h)
{
var box = document.getElementById("lightBoxContent");
if (w && isNaN(parseInt(w)))
{
addClass(box,w);
}
else if (w ||h || contentType == 'html')
{
box.style.width = w? w+ "px" : "450px";
box.style.height = h? h+ "px" : "280px";
if (contentType=='image')
setStylesheet("#lightBoxContent img{height:100%;width:100%;}","lightBoxImageSizeHack");
}
},
showProgress : function()
{
var progress = document.getElementById("lightboxprogress");
progress.style.display='';
this._center(progress);
},
hideProgress: function()
{
var progress = document.getElementById("lightboxprogress");
progress.style.display='none';
},
//this function lifted from Lightbox Gone Wild
hideSelects: function(visibility)
{
var selects = document.getElementsByTagName('select');
for(i = 0; i < selects.length; i++)
{
selects[i].style.visibility = visibility;
}
},
showBg: function()
{
var overlay = document.getElementById('lightBoxOverlay');
if (config.browser.isIE)
{
overlay.style.height = Math.max(document.documentElement.scrollHeight,document.documentElement.offsetHeight);
overlay.style.width = document.documentElement.scrollWidth;
}
overlay.style.display = 'block';
},
showImage: function (url,text)
{
imgPreloader = new Image();
imgPreloader.onload = function ()
{
var lb = document.getElementById("lightBoxContent");
lb.innerHTML = "<img src="+url+">";
lb.onclick = function(){TiddlyLightBox.hideBox();return false;};
TiddlyLightBox.posBox(text);
};
imgPreloader.src = url;
},
showHtml : function(theID,text)
{
var lb = document.getElementById("lightBoxContent");
if (theID.indexOf("tiddler:")==-1)
lb.innerHTML = document.getElementById(theID).innerHTML;
else
{
wikify(store.getTiddlerText(theID.replace("tiddler:","")),lb);
lb.className='tiddler';
}
lb.style.overflow = "auto";
this.posBox(text);
},
posBox: function(text)
{
this.setTitle(text);
this.hideProgress();
var lb = document.getElementById("lightBox");
lb.style.display = "";
lb.style.visibilty = "hidden";
lb.style.position = "absolute";
this._center(lb);
if(!TiddlyLightBox._curBox) return;
lb.style.visibility = "visible";
lb.style.display = "block";
},
setTitle: function(text)
{
document.getElementById("lightBoxTitle").innerHTML= (text==undefined)? '': text;
},
_center: function(lb)
{
var lbSize = new TiddlyLightBox.getElementSize(lb);
lb.style.left = (Math.round(findWindowWidth()/2) - (lbSize.width /2) + findScrollX())+'px';
lb.style.top = (Math.round(findWindowHeight()/2) - (lbSize.height /2) + findScrollY())+'px';
},
//this function lifted from Ibox
getElementSize : function(elem)
{
this.width = elem.offsetWidth || elem.style.pixelWidth;
this.height = elem.offsetHeight || elem.style.pixelHeight;
},
hideBox: function()
{
if(!this._curBox)
return;
document.getElementById("tiddlyLightBoxWrapper").innerHTML= this.lightBoxHtml;
setStylesheet("","lightBoxImageSizeHack");
this._curBox = null;
return false;
}
}
TiddlyLightBox.createBoxWrapper();
Story.prototype.findContainingTiddler = function(e)
{
while(e && (!hasClass(e,"tiddler") || !e.getAttribute("tiddler")))
e = e.parentNode;
return(e);
}
config.shadowTiddlers.TiddlyLightBoxStyles="/*{{{*/\n#lightBoxOverlay {\n position:absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 90; \n background-color: #000;\n -moz-opacity: 0.75;\n opacity: .75;\n filter: alpha(opacity=75);\n}\n#lightBoxOverlay[id]{ \n position: fixed;\n}\n\n#lightboxprogress { \n margin:0;padding:0;\n position: absolute;\n z-index:95;\n}\n\ndiv.lightBox {\n background: #fff;\n color: #fff;\n border: 4px solid #525252;\npadding:20px 20px 25px 20px; position:absolute; z-index:99;\n}\n\n#lightBoxClose {text-align:right; color:#000; font-size:1.0em; position:absolute; bottom:6px; right:20px;}\n#lightBoxClose a{color:#666; border-bottom:1px solid #666;cursor:pointer;}\n#lightBoxClose a:hover {color:#111; border-bottom:1px solid #666; cursor:pointer; background:transparent;}\n\n#lightBoxContent {border:1px solid #525252;color:#000; background:#fff;}\n#lightBox .tiddler {background:#fff;}\n\n#lightBoxContent img {border:0;margin:0;padding:0;display:block;cursor:pointer;}\n\n#lightBoxTitle {padding:0px; font-weight:bold; position:absolute; left:20px;bottom:6px; font-size:1.1em; color:#000;}\n\n/*}}}*/";
//}}}
* When a package installation spans more than one software appliance (forum installation implying database configuration) the result can't be published with mercurial.
* The content of a database is usualy stored in binary form and text based tools can't be used for backups.
* mercurial does not handle symbolic links or empty directories (0.9.3)
* ''X11 forwarding depends on a match between the IP and the hostname (either from the DNS or from hosts)''
* /etc/resolv.conf must list an IP that depends on the DNS address available on a given vserver host. There is maybe a way to update this globaly from /etc/vserver
* //hg pull// can't be used in [[Patching the apache appliance]] because the hg protocol transmits too many information and it lasts for ages. This is not going to change any time soon.
<<<
With a //linux-2.6// kernel, creating a virtual ethernet interface is made easy.
{{{
apt-get install vlan
}}}
provides the extensions needed for ///etc/network/interfaces//. To create the //eth0.2// interface add the following lines to ///etc/network/interfaces//.
//sources.list// and //resolv.conf// are to be modified when moving the appliance because they are geographicaly dependent.
{{{
auto eth0.2
iface eth0.2 inet static
address 192.168.50.1
netmask 255.255.255.0
pre-up modprobe 8021q
# up iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
# up iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
up echo 0 > /proc/sys/net/ipv4/conf/eth0.2/rp_filter
}}}
Note that once this is done, packets originating from the 192.168.50.0/24 subnet won't be routed because the MASQUERADE lines are commented out. Routing is being dealt with by shorewall. However, if you don't have or don't want shorewall, the MASQUERADE lines will do the work.
<<<
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class="tagglyTagging" macro="tagglyTagging"></div>
<div class='tagged' macro='tags'></div>
<div macro="hideWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">
<div class='viewer' macro='view text wikified'></div>
</div>
<div macro="showWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">
<div class='viewer'><pre macro='view text'></pre></div>
</div>
<div class='tagClear'></div>
<!--}}}-->
/***
|''Name:''|WebDavPlugin|
|''Description:''|Allows a TiddlyWiki to be saved to a WebDav server|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Co-author:''|Loic Dachary|
|''Source:''|http://tw.lewcid.org/#WebDavPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|1.0|
|''Date:''|17/11/2007|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
***/
// /%
//!BEGIN-PLUGIN-CODE
DAV = {
run : function(type,u,data,cb,params,headers){
var callback = function(status,params,responseText,url,xhr) {
url = url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1);
if(params.length){
params.shift().apply(this,[status,params,responseText,url,xhr]);
}
};
params = params||[];
params.unshift(cb);
var r = doHttp.apply(this,[type,u,data,null,null,null,callback,params,headers]);
if (typeof r == "string")
alert(r);
return r;
},
get : function(url,cb,params){
return DAV.run("GET",url,null,cb,params,null);
},
put : function(url,cb,params,data) {
return DAV.run("PUT",url,data,cb,params,null);
},
move : function(url,cb,params,destination) {
return DAV.run("MOVE",url,null,cb,params,{"Destination":destination,"Overwrite":"T"});
},
copy : function(url,cb,params,destination) {
return DAV.run("COPY",url,null,cb,params,{"Destination":destination,"Overwrite":"T","Depth":0});
},
propfind : function(url,cb,params,prop,depth){ // !!!
var xml = '<?xml version="1.0" encoding="UTF-8" ?>' +
'<D:propfind xmlns:D="DAV:">' +
'<D:prop>'+
'<D:'+prop+'/>'+
'</D:prop>'+
'</D:propfind>';
return DAV.run("PROPFIND",url,xml,cb,params,{"Content-type":"text/xml","Depth":depth?depth:0});
},
makeDir : function(url,cb,params){
return DAV.run("MKCOL",url,null,cb,params,null);
},
options : function(url,cb,params){
return DAV.run("OPTIONS",url,null,cb,params,null);
},
safeput : function(url,cb,params,data){
firstcb = function(status,p,responseText,u,xhr){
if(status)
DAV.move(u,cb,p,u.replace("-davsavingtemp",""));
else
cb.apply(firstcb,arguments);
};
return DAV.put(url+"-davsavingtemp",firstcb,params,data);
}
};
config.DavSaver = {
defaultFileName : 'index.html',
messages : {
startSaveMessage : 'saving to server...',
endSaveMessage : 'TiddlyWiki successfuly saved to server',
overwriteNewerPrompt : 'The remote file has changed since you last loaded or saved it.\nDo you wish to overwrite it?',
getModDateError : "Could not get last modified date",
raceError: "Save failed because the remote file is newer than the one you are trying to save"
},
errors:{
raceconflict : 'The save failed because your file is out of date',
getlastmodified : 'The save was aborted because the last modified date of the file could not be retrieved',
davenabled : 'The server does not support WebDav',
saverss : 'There was an error saving the rss file, the save was aborted',
saveempty: 'There was an error saving the empty file, the save was aborted',
savemain : 'Save failed! There was an error saving the main TW file',
savebackup: 'Save failed! There was an error creating a backup file',
makebackupdir: 'Save failed! The backup directory could not be created'
},
timestamp: new Date().toGMTString(),
orig_saveChanges: saveChanges,
saver : null
};
DavSaver = function(){
this.Q = [];
this.reset = function(){
config.DavSaver.saver = null;
};
this.runQ = function(){
if(this.Q.length){
this.Q.shift().apply(this,arguments);
}
else
this.reset();
};
this.posDiv = null;
this.original = null;
this.getOriginalPath = function(){
var p = document.location.toString();
p = convertUriToUTF8(p,config.options.txtFileSystemCharSet);
var argPos = p.indexOf("?");
if(argPos != -1)
p = p.substr(0,argPos);
var hashPos = p.indexOf("#");
if(hashPos != -1)
p = p.substr(0,hashPos);
if (p.charAt(p.length-1) == "/")
p = p + config.DavSaver.defaultFileName;
return p;
};
this.originalPath = this.getOriginalPath();
this.backupPath = null;
this.emptyPath = null;
this.rssPath = null;
this.throwError = function(er){
clearMessage();
this.reset();
alert(config.DavSaver.errors[er]); //cl