* configuration works a slightly different way, using plc-config-tty is recommended
* a few new convenience commands
* improved packaging (plcapi doc, yum.conf, sudoers)
* more robust for invoking service plc through ssh
--- /dev/null
+#
+# $Id: Makefile 1078 2007-11-15 13:38:27Z thierry $
+#
+
+BINARIES = plc-config plc-config-tty db-config dns-config refresh-peer.py plc-map.py clean-empty-dirs.py mtail.py
+INIT_SCRIPTS = api bootcd bootmanager crond db dns functions gpg httpd mail network packages postgresql ssh ssl syslog
+
+INITS=$(addprefix plc.d/,$(INIT_SCRIPTS))
+
+########## make sync PLCHOST=hostname
+ifdef PLCHOST
+PLCSSH:=root@$(PLCHOST)
+endif
+
+LOCAL_RSYNC_EXCLUDES := --exclude '*.pyc'
+RSYNC_EXCLUDES := --exclude .svn --exclude CVS --exclude '*~' --exclude TAGS $(LOCAL_RSYNC_EXCLUDES)
+RSYNC_COND_DRY_RUN := $(if $(findstring n,$(MAKEFLAGS)),--dry-run,)
+RSYNC := rsync -a -v $(RSYNC_COND_DRY_RUN) $(RSYNC_EXCLUDES)
+
+sync:
+ifeq (,$(PLCSSH))
+ echo "sync: You must define target host as PLCHOST on the command line"
+ echo " e.g. make sync PLCHOST=private.one-lab.org" ; exit 1
+else
+ +$(RSYNC) host.init $(PLCSSH):/etc/init.d/plc
+ +$(RSYNC) guest.init $(PLCSSH):/plc/root/etc/init.d/plc
+ +$(RSYNC) $(BINARIES) $(PLCSSH):/plc/root/usr/bin
+ +$(RSYNC) $(INITS) $(PLCSSH):/plc/root/etc/plc.d
+ +$(RSYNC) plc_config.py $(PLCSSH):/plc/root/usr/lib/python2.4/site-packages/plc_config.py
+ +$(RSYNC) default_config.xml $(PLCSSH):/plc/data/etc/planetlab/default_config.xml
+ @echo XXXXXXXX You might consider running the following command
+ @echo ssh $(PLCSSH) chroot /plc/root service plc start
+endif
+
+
+tags:
+ find . -type f | egrep -v '.svn/|~$$' | xargs etags
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: build.functions,v 1.10.2.1 2007/08/30 16:39:07 mef Exp $
+# $Id: build.functions 1086 2007-11-15 14:17:45Z thierry $
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin
# Make a basic chroot at the specified location given the specified
# configuration.
-make_chroot() {
+make_chroot_from_lst() {
root=$1
- config=$2
+ lst=$2
- # Get group list
- groups=
- while read group ; do
- groups="$groups -g \"$group\""
- done < <(./plc-config --groups $config)
-
- # Get package list
- packages=
- while read package ; do
- packages="$packages -p \"$package\""
- done < <(./plc-config --packages $config)
+ packages=$(pl_getPackagesOptions $lst)
+ groups=$(pl_getGroupsOptions $lst)
pl_setup_chroot $root $packages $groups
}
# Move specified directories out of the chroot and into a "data"
# directory that will be bind mounted on /data inside the chroot.
-move_datadirs() {
- root=$1
- data=$2
- shift 2
- pl_move_dirs $root $data /data "$@"
-}
+#move_datadirs() {
+# root=$1
+# data=$2
+# shift 2
+# pl_move_dirs $root $data /data "$@"
+#}
# Make loopback filesystem from specified location
-make_image() {
- root=$1
- image=$2
- pl_make_image $root $image 100000000
+#make_image() {
+# root=$1
+# image=$2
+# pl_make_image $root $image 100000000
+#}
+
+function yum_conf_to_build_host () {
+ BUILD_HOST=$(hostname)
+ cat <<EOF
+[main]
+cachedir=/var/cache/yum
+debuglevel=2
+logfile=/var/log/yum.log
+pkgpolicy=newest
+distroverpkg=redhat-release
+tolerant=1
+exactarch=1
+retries=10
+obsoletes=1
+gpgcheck=0
+# Prevent yum-2.4 from loading additional repository definitions
+# (e.g., from /etc/yum.repos.d/)
+reposdir=/dev/null
+
+[base]
+name=Fedora Core 4 - i386 - base
+baseurl=http://${BUILD_HOST}/fedora/linux/core/${PLC_DEVEL_FEDORA_RELEASE}/${PLC_DEVEL_FEDORA_ARCH}/os/
+
+
+[updates]
+name=Fedora Core 4 - i386 - updates
+baseurl=http://${BUILD_HOST}/fedora/linux/core/updates/${PLC_DEVEL_FEDORA_RELEASE}/${PLC_DEVEL_FEDORA_ARCH}/
+
+$(if [ "${PLC_DEVEL_FEDORA_RELEASE}" -le 6 ] ; then cat << EXTRAS
+[extras]
+name=Fedora Core 4 - i386 - extras
+baseurl=http://${BUILD_HOST}/fedora/linux/extras/${PLC_DEVEL_FEDORA_RELEASE}/${PLC_DEVEL_FEDORA_ARCH}/
+EXTRAS
+fi)
+EOF
+
}
+
+function sudoers_bootcustom_apache () {
+ cat <<EOF
+User_Alias WWW = %apache,%root
+Cmnd_Alias BOOTCUSTOM = /usr/share/bootcd/bootcustom.sh
+WWW ALL = NOPASSWD: BOOTCUSTOM
+EOF
+}
+
+# quick and dirty - might break anytime if docbook html output changes
+function docbook_html_to_drupal () {
+ title=$1; shift
+ html=$1; shift
+ php=$1; shift
+
+ mkdir -p $(dirname $php)
+ if [ ! -f $html ] ; then
+ cat << __header_no_doc__ > $php
+<?php
+require_once 'plc_drupal.php';
+drupal_set_title("$title - unavailable");
+?>
+<p class='plc-warning'> Build-time error - could not locate documentation $html</p>
+__header_no_doc__
+ else
+ # insert header, makes sure we have a trailing eol
+ (cat << __header_doc__ ; cat $html ) > $php
+<?php
+require_once 'plc_drupal.php';
+drupal_set_title("$title");
+?>
+__header_doc__
+ # ignore ed return status
+ set +e
+ # cuts off around the <body> </body>
+ # preserves the 4 first lines that we just added as a header
+ ed -s $php << __ed_script__
+/BODY/
+/>/
+s,><,<,
+5,-d
+$
+?/BODY?
+s,><.*,>,
++
+;d
+w
+q
+__ed_script__
+ set -e
+ fi
+}
# Builds MyPLC, either inside the MyPLC development environment in
# devel/root (if PLC_DEVEL_BOOTSTRAP is true), or in the current host
# environment (may be itself a MyPLC development environment or a
-# Fedora environment with the appropriate development packages
+# Fedora Core 4 environment with the appropriate development packages
# installed).
#
# root.img (loopback image)
# data/root (root's homedir)
#
# Mark Huang <mlhuang@cs.princeton.edu>
-# Marc E. Fiuczynski <mef@cs.princeton.edu>
-# Copyright (C) 2006-2007 The Trustees of Princeton University
+# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: build.sh,v 1.41.2.1 2007/08/30 16:39:08 mef Exp $
+# $Id: build.sh 1095 2007-11-16 09:52:30Z thierry $
#
. build.functions
+# pldistro expected as $1 - defaults to planetlab
+pldistro=planetlab
+[ -n "$@" ] && pldistro=$1
+
# These directories are allowed to grow to unspecified size, so they
# are stored as symlinks to the /data partition. mkfedora and yum
# expect some of them to be real directories, however.
echo "* myplc: Installing base filesystem"
mkdir -p root data
-make_chroot root plc_config.xml
+
+lst=${pldistro}-${pl_DISTRO_NAME}-plc.lst
+make_chroot_from_lst root $lst
# Install configuration scripts
echo "* myplc: Installing configuration scripts"
install -D -m 755 plc-config-tty root/usr/bin/plc-config-tty
install -D -m 755 db-config root/usr/bin/db-config
install -D -m 755 dns-config root/usr/bin/dns-config
+install -D -m 755 plc-map.py root/usr/bin/plc-map.py
+install -D -m 755 clean-empty-dirs.py root/usr/bin/clean-empty-dirs.py
+install -D -m 755 mtail.py root/usr/bin/mtail.py
+install -D -m 755 check-ssl-peering.py root/usr/bin/check-ssl-peering.py
# Install initscripts
echo "* myplc: Installing initscripts"
#$srcdir/plc/scripts/gen-static-content.py \
#root/usr/bin/
-# Install web pages
-echo "* myplc: Installing web pages"
-mkdir -p root/var/www/html
-rsync -a $srcdir/WWW/ root/var/www/html/
-
-# Install Drupal rewrite rules
-install -D -m 644 $srcdir/WWW/drupal.conf root/etc/httpd/conf.d/drupal.conf
+### Thierry Parmentelat - april 16 2007
+### from now on we package plcwww separately in the plcwww rpm
+#### Install web pages
+###echo "* myplc: Installing web pages"
+###mkdir -p root/var/www/html
+###rsync -a $srcdir/new_plc_www/ root/var/www/html/
+
+#### Install Drupal rewrite rules
+###install -D -m 644 $srcdir/new_plc_www/drupal.conf root/etc/httpd/conf.d/drupal.conf
+
+### Thierry Parmentelat - april 16 2007
+# fetch the release stamp from the build if any
+# I could not come up with any more sensitive scheme
+if [ -f ../../../SOURCES/myplc-release ] ; then
+ cp ../../../SOURCES/myplc-release myplc-release
+else
+ echo "No build information found in ../.." > myplc-release
+fi
+# install it in /etc/myplc-release
+install -m 444 myplc-release root/etc/myplc-release
+
+### Thierry Parmentelat - april 16 2007
+# fix the yum.conf as produced by mkfedora
+# so we can use the build's fc4 mirror for various installs/upgrades
+# within the chroot jail
+# yum_conf_to_build_host is defined in build.functions
+yum_conf_to_build_host > root/etc/yum.conf
+
+### Thierry Parmentelat - may 16 2007
+# the node-dependent image generation script requires root privilege
+# to perform various mount operations
+sudoers_bootcustom_apache > root/etc/sudoers
+chown root:root root/etc/sudoers
+chmod 400 root/etc/sudoers
+
+### Thierry Parmentelat - july 20 2007
+# we now build the myplc doc
+# beware that making the pdf file somehow overwrites the html
+make -C doc myplc.pdf
+rm -f doc/myplc.html
+make -C doc myplc.html
+
+# install at the same place as plcapi - better ideas ?
+for doc in myplc.html myplc.pdf ; do
+ install -m 644 doc/$doc root/usr/share/plc_api/doc/$doc
+done
+
+# we now build the plcapi doc
+# this generates a drupal php file from a docbook-generated html
+# quick & dirty
+docbook_html_to_drupal "OneLab PLCAPI Documentation" \
+ root/usr/share/plc_api/doc/PLCAPI.html \
+ root/var/www/html/planetlab/doc/plcapi.php
+# pdf just get copied
+install -m 644 root/usr/share/plc_api/doc/PLCAPI.pdf root/var/www/html/planetlab/doc/plcapi.pdf
+
+docbook_html_to_drupal "Myplc User Guide" \
+ root/usr/share/plc_api/doc/myplc.html \
+ root/var/www/html/planetlab/doc/myplc.php
+# pdf just get copied
+install -m 644 root/usr/share/plc_api/doc/myplc.pdf root/var/www/html/planetlab/doc/myplc.pdf
# Install configuration file
echo "* myplc: Installing configuration file"
-install -D -m 444 $config data/etc/planetlab/default_config.xml
+install -D -m 444 default_config.xml data/etc/planetlab/default_config.xml
install -D -m 444 plc_config.dtd data/etc/planetlab/plc_config.dtd
# handle root's homedir and tweak root prompt
# Initialize node RPMs directory. The PlanetLab-Bootstrap.tar.bz2
# tarball already contains all of the node RPMs pre-installed. Only
# updates or optional packages should be placed in this directory.
-install -D -m 644 $pl_YUMGROUPSXML \
+install -D -m 644 $pl_DISTRO_YUMGROUPS \
data/var/www/html/install-rpms/planetlab/yumgroups.xml
# Make image out of directory
# devel/data/root (root's home dir)
#
# Mark Huang <mlhuang@cs.princeton.edu>
-# Marc E. Fiuczynski <mef@cs.princeton.edu>
-# Copyright (C) 2006-2007 The Trustees of Princeton University
+# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: build_devel.sh,v 1.11 2007/08/31 02:33:04 mef Exp $
+# $Id: build_devel.sh 1078 2007-11-15 13:38:27Z thierry $
#
+echo "$0" not supported anymore
+echo "need to figure a way to handle space in group names in .lst files"
+exit 1
+
. build.functions
# These directories are allowed to grow to unspecified size, so they
echo "* myplc-devel: Installing base filesystem"
mkdir -p devel/root
-make_chroot devel/root plc_devel_config.xml
+# xxx need be pldistro & fcdistro dependant
+make_chroot_from_lst devel/root planetlab-devel.lst
# Install configuration file
echo "* myplc-devel: Installing configuration file"
uid=${SUDO_UID:-2000}
gid=${SUDO_GID:-2000}
if ! grep -q "Automated Build" devel/root/etc/passwd ; then
- chroot devel/root sh -c "groupadd -o -g $gid build; \
-useradd -o -c 'Automated Build' -u $uid -g $gid -n -d /data/build -M -s /bin/bash build; \
-exit 0"
+ chroot devel/root <<EOF
+groupadd -o -g $gid build
+useradd -o -c 'Automated Build' -u $uid -g $gid -n -d /data/build -M -s /bin/bash build
+exit 0
+EOF
fi
# Copy build scripts to build home directory
--- /dev/null
+#!/usr/bin/env plcsh
+# checking ssl connection
+# mimicks what PyCurl does
+
+import sys
+import pycurl
+
+class check_ssl:
+
+ def getpeername_post_request (self,local_peername) :
+ methodname="GetPeerName"
+ from PLC.GPG import gpg_sign
+ signature = gpg_sign((),
+ self.options.PLC_ROOT_GPG_KEY,
+ self.options.PLC_ROOT_GPG_KEY_PUB,
+ methodname)
+ post="""<?xml version='1.0'?>
+<methodCall>
+<methodName>GetPeerName</methodName>
+<params>
+<param>
+<value><struct>
+<member>
+<name>AuthMethod</name>
+<value><string>gpg</string></value>
+</member>
+<member>
+<name>name</name>
+<value><string>%s</string></value>
+</member>
+<member>
+<name>signature</name>
+<value><string>%s
+</string></value>
+</member>
+</struct></value>
+</param>
+</params>
+</methodCall>"""%(local_peername,signature)
+ return post
+
+ def check_url (self,url,local_peername,remote_peername,cert,timeout=10,verbose=1):
+ curl=pycurl.Curl()
+ curl.setopt(pycurl.NOSIGNAL, 1)
+
+ # Follow redirections
+ curl.setopt(pycurl.FOLLOWLOCATION, 1)
+ curl.setopt(pycurl.URL, str(url))
+ cert_path = str(cert)
+ curl.setopt(pycurl.CAINFO, cert_path)
+ curl.setopt(pycurl.SSL_VERIFYPEER, 2)
+
+ # Set connection timeout
+ if timeout:
+ curl.setopt(pycurl.CONNECTTIMEOUT, timeout)
+ curl.setopt(pycurl.TIMEOUT, timeout)
+
+ curl.setopt(pycurl.VERBOSE, verbose)
+
+ # Post request
+ curl.setopt(pycurl.POST, 1)
+ curl.setopt(pycurl.POSTFIELDS, self.getpeername_post_request(local_peername))
+
+ import StringIO
+ b = StringIO.StringIO()
+ curl.setopt(pycurl.WRITEFUNCTION, b.write)
+
+ try:
+ curl.perform()
+ errcode = curl.getinfo(pycurl.HTTP_CODE)
+ response = b.getvalue()
+ print 'xmlrpc answer',response
+ if response.find('Failed') >= 0:
+ print 'FAILURE : failed to authenticate ?'
+ return False
+ elif response.find(remote_peername) <0:
+ print 'FAILURE : xmlrpc round trip OK but peername does not match'
+ return False
+ else:
+ print 'SUCCESS'
+ return True
+
+ except pycurl.error, err:
+ (errcode, errmsg) = err
+ if errcode == 60:
+ print 'FAILURE', "SSL certificate validation failed, %r"%(errmsg)
+ elif errcode != 200:
+ print 'FAILURE', "HTTP error %d, errmsg %r" % (errcode,errmsg)
+ return False
+
+ def main (self):
+ from optparse import OptionParser
+ usage="%prog [options] local-peername remote-peername cacert hostname [ .. hostname ]"
+ parser=OptionParser(usage=usage)
+ parser.add_option('-s','--secret',default='/etc/planetlab/secring.gpg',
+ dest='PLC_ROOT_GPG_KEY',
+ help='local GPG secret ring')
+ parser.add_option('-p','--public',default='/etc/planetlab/pubring.gpg',
+ dest='PLC_ROOT_GPG_KEY_PUB',
+ help='local GPG public ring')
+ (self.options, args) = parser.parse_args()
+
+ if len(args) < 4:
+ parser.print_help()
+ sys.exit(2)
+ arg=0
+ local_peername=args[arg] ; arg+=1
+ remote_peername=args[arg] ; arg+=1
+ cacert=args[arg]; arg+=1
+ ok=False
+ for hostname in args[arg:]:
+# this does not seem to make any difference
+# for url_format in [ 'https://%s:443/PLCAPI/' , 'https://%s/PLCAPI/' ]:
+ for url_format in [ 'https://%s/PLCAPI/' ]:
+ url=url_format%hostname
+ print '============================== Checking url=',url
+ if self.check_url(url,local_peername,remote_peername,cacert):
+ ok=True
+ if ok:
+ return 0
+ else:
+ return 1
+
+if __name__ == '__main__':
+ sys.exit(check_ssl().main())
--- /dev/null
+#!/usr/bin/python
+###
+### $Id: clean-empty-dirs.py 495 2007-06-11 07:20:50Z thierry $
+###
+### utility script for cleaning empty directories
+### useful to clean up /var/tmp/bootmedium
+###
+
+"""
+Usage: $0 dir [ .. dir]
+scans all provided directories and prunes any empty directory under
+the arg directories are always preserved
+"""
+
+import os,sys
+
+### cleans up a everything under a given root
+def clean_root (path, cleanRoot = False):
+
+ if not os.path.isdir(path):
+ return
+
+ # scan dir contents
+ files=os.listdir(path)
+
+ for x in files:
+ fullpath=os.path.join(path, x)
+ if os.path.isfile(fullpath):
+ # we do not remove files
+ return
+ elif os.path.isdir(fullpath):
+ clean_root(fullpath,True)
+
+ if (cleanRoot):
+ # rescan, and clean if empty
+ files=os.listdir(path)
+ if not files:
+ os.rmdir(path)
+
+ERROR_STR= """Error removing %(path)s, %(error)s """
+
+def main (dirs):
+
+ for dir in dirs:
+ try:
+ if dir.index("/") != 0:
+ print "%s: args must be absolute paths"%(sys.argv[0])
+ print "%s: %s ignored"%(sys.argv[0],dir)
+ else:
+ clean_root(dir)
+ except OSError, (errno, strerror):
+ print ERROR_STR % {'path' : path, 'error': strerror }
+
+if __name__ == '__main__':
+ main (sys.argv[1:])
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: db-config,v 1.23 2007/07/02 18:44:10 tmack Exp $
+# $Id: db-config 1078 2007-11-15 13:38:27Z thierry $
#
from plc_config import PLCConfiguration
'name': plc['name'] + " Central",
'abbreviated_name': plc['name'],
'login_base': plc['slice_prefix'],
- 'is_public': True,
+ 'is_public': False,
'url': url,
'max_slices': 100 }
Mark Huang <mlhuang@cs.princeton.edu>
Copyright (C) 2006 The Trustees of Princeton University
-$Id: plc_config.xml,v 1.21 2007/08/24 07:19:27 mef Exp $
+$Id: default_config.xml 1078 2007-11-15 13:38:27Z thierry $
-->
<!DOCTYPE configuration PUBLIC "-//PlanetLab Central//DTD PLC configuration//EN" "plc_config.dtd">
</variables>
<comps>
+ <!-- xxx should be deprecated - not used anymore xxx -->
<group>
<id>plc</id>
<name>PlanetLab Central</name>
<!-- Customizable Boot CD and Boot Manager packages -->
<packagereq type="mandatory">bootcd</packagereq>
<packagereq type="mandatory">bootmanager</packagereq>
+
+ <!-- PLCWWW now packaged separately from myplc -->
+ <packagereq type="mandatory">plcwww</packagereq>
+
+ <!-- apache user needs root access for building node-dependent images -->
+ <packagereq type="mandatory">sudo</packagereq>
+
+ <!-- OneLab specifics - for convenience -->
+ <packagereq type="mandatory">vim-minimal</packagereq>
+ <packagereq type="mandatory">python-imaging</packagereq>
+
</packagelist>
</group>
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: dns-config,v 1.1 2006/05/26 19:57:30 mlhuang Exp $
+# $Id: dns-config 129 2007-03-20 12:04:03Z thierry $
#
from plc_config import PLCConfiguration
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: Makefile,v 1.5 2006/07/18 22:41:44 mlhuang Exp $
+# $Id: Makefile 704 2007-07-20 14:15:43Z thierry $
#
vpath GenDoc.xsl ../../plc_www/doc
vpath %_config.xml ..
-all: myplc.pdf myplc.php
+# dont redo php by default, this requires plc_www (see above)
+# that we build separately (has no doc/ subdir anyway)
+# note that the build host (myplc-devel) needs ghostscript
+# that we added only on 20 july 2007
+all: myplc.pdf myplc.html
+
+static: pyplc.php
.PHONY: all
#
# description: Manages all PLC services on this machine
#
-# $Id: guest.init,v 1.20 2006/08/08 23:19:52 mlhuang Exp $
+# $Id: guest.init 635 2007-07-05 11:08:14Z thierry $
#
# Source function library and configuration
# being run. The idea is that when the configuration changes, "service
# plc restart" is called, all dependencies are fixed up, and
# everything just works.
+
+### NOTE.
+# we want the resulting myplc to be able to easily skip
+# some steps. e.g. the packages step takes ages if you install
+# all rpms under the repository.
+# We skip steps whose name contains a dot (.) or a tilde (~)
+# this way the operations would just rename a step name e.g.
+# cd /etc/plc.d
+# mv packages packages.hide
+#
+# The drawback is, this stuff does not survive an rpm update
+# but that's maybe a good thing, that all is done at first start
+###
+
steps=($(
for step in /etc/plc.d/* ; do
- if [ -f $step -a -x $step ] ; then
+ stepname=$(basename $step)
+ plainstepname=$(echo $stepname | sed -e 's,\.,,' -e 's,~,,')
+ if [ -f $step -a -x $step -a "$stepname" = "$plainstepname" ] ; then
priority=$(sed -ne 's/# priority: \(.*\)/\1/p' $step)
- echo $priority $(basename $step)
+ echo $priority $stepname
fi
done | sort -n | cut -d' ' -f2
))
# Regenerate the main configuration file from default values
# overlaid with site-specific and current values.
+ # Thierry -- 2007-07-05 : values in plc_config.xml are *not* taken into account here
files=(
/etc/planetlab/default_config.xml
- /etc/planetlab/configs/*.xml
- /etc/planetlab/plc_config.xml
+ /etc/planetlab/configs/site.xml
)
for file in "${files[@]}" ; do
if [ -n "$force" -o $file -nt /etc/planetlab/plc_config.xml ] ; then
plc-config --xml "${files[@]}" >$tmp
if [ $? -eq 0 ] ; then
mv $tmp /etc/planetlab/plc_config.xml
- chmod 644 /etc/planetlab/plc_config.xml
+ chmod 444 /etc/planetlab/plc_config.xml
else
echo "PLC: Warning: Invalid configuration file(s) detected"
rm -f $tmp
#
# description: Manages all PLC services on this machine
#
-# $Id: host.init,v 1.8 2006/07/06 17:43:52 mlhuang Exp $
+# $Id: host.init 1078 2007-11-15 13:38:27Z thierry $
#
PATH=/sbin:/bin:/usr/bin:/usr/sbin
done
}
+# safestop : tries to stop normally; if that fails, kills processes that are still using /plc
+# needs the lsof rpm in the root context (should be a dependency of the myplc spec)
+function check_command ()
+{
+ command=$1; shift
+ found=$(type -p $command)
+ if [ -z "$found" ] ; then
+ echo "$COMMAND : requires command $command, was not found - exiting"
+ exit 1
+ fi
+}
+
+
+### when process stil use /plc/root, we cannot umount it
+function kill_all ()
+{
+ [ -n "$DEBUG" ] && set -x
+ check_command lsof
+
+ echo -n "Killing processes using $PLC_ROOT and $PLC_DATA: "
+ # initialize process list
+ former_process_list="unlikely"
+
+ # we ignore unknown uids for now, since we run in the chroot jail anyway
+ # not too sure about that though,
+ while true; do
+ # get the list of processes - collapse and remove empty lines
+ process_list=$(lsof -t +D $PLC_ROOT +D $PLC_DATA)
+ if [ -z "$process_list" ] ; then
+ # we are done, let's bail out
+ success "$PLC_ROOT clear" ; echo ; return
+ fi
+ if [ "$process_list" = "$former_process_list" ] ; then
+ # we are stuck, no progress since last time : exit on error
+ failure "$PLC_ROOT locked" ; echo ; return
+ fi
+ # record for next loop
+ former_process_list="$process_list"
+ # kill them
+ kill $process_list
+ sleep 2
+ # check there are dead
+ for pid in $process_list ; do
+ ps -o pid $pid &> /dev/null
+ if [ "$?" = 0 ] ; then
+ [ -n "$DEBUG" ] && echo "$pid survived kill - forcing kill -9"
+ kill -9 $pid
+ fi
+ done
+ done
+}
+
# Get command
shift $(($OPTIND - 1))
command=$1
restart)
stop $*
+ ERRORS=0
start $*
;;
;;
mount|umount|mountstatus)
- ${command}_plc $*
+ ${command}_plc
+ ;;
+
+ kill)
+ kill_all
+ ;;
+
+ safestop)
+ stop
+ ### Checking : we might need to run kill
+ mounted=$(mountstatus_plc)
+ if [ -n "$mounted" ] ; then
+ echo "Umount failed : killing remaining processes and trying again"
+ ERRORS=0
+ kill_all
+ ERRORS=0
+ stop
+ fi
;;
*)
- echo "Usage: $0 {start|stop|restart|reload|mount|umount|mountstatus}"
+ echo "Usage: $0 {start|stop|restart|reload|mount|umount|mountstatus|kill|safestop}"
RETVAL=1
;;
esac
--- /dev/null
+#!/usr/bin/env python
+
+'''
+Does tail -f on log files in a given directory.
+The display is in chronological order of the logged lines,
+given that the first column of log files is timestamp.
+It can be altered to fit other formats too
+'''
+
+import os, sys, time
+from optparse import OptionParser
+
+class mtail:
+
+ subversion_id = "$Id: mtail.py 571 2007-06-22 21:38:07Z thierry $"
+
+ default_time_format = "%H:%M:%S"
+
+ def __init__ (self, args ):
+
+ # internal structure for tracking changes
+ self.files = {}
+ # parse command-line args : will set options and args
+ self.parse_args(args)
+ # initialize
+ self.scan_files()
+
+ def parse_args (self, args):
+ usage = """usage: %prog [options] file-or-dir ...
+example:
+# %prog -e '*access*' /var/log"""
+ parser=OptionParser(usage=usage,version=self.subversion_id)
+ # tail_period
+ parser.add_option("-p","--period", type="int", dest="tail_period", default=1,
+ help="Files check period in seconds")
+ # rescan_period
+ parser.add_option("-d","--dir-period", type="int", dest="rescan_period", default=20,
+ help="Directories rescan period in seconds")
+ # time format
+ parser.add_option("-f","--format", dest="time_format", default=mtail.default_time_format,
+ help="Time format, defaults to " + mtail.default_time_format)
+ # show time
+ parser.add_option("-r","--raw", action="store_true", dest="show_time", default=True,
+ help="Suppresses time display")
+
+ # note for exclusion patterns
+ parser.add_option("-e","--exclude", action="append", dest="excludes", default=[],
+ help="Exclusion pattern -- can be specified multiple times applies on files not explicitly mentioned on the command-line")
+
+ parser.add_option("-u","--usual",action="store_true",dest="plc_mode",default=False,
+ help="Shortcut for watching /var/log with default settings")
+
+ # verbosity
+ parser.add_option("-v","--verbose", action="store_true", dest="verbose", default=False,
+ help="Run in verbose mode")
+
+ (self.options, self.args) = parser.parse_args(args)
+ self.optparse = parser
+
+ ### plc shortcuts
+ if self.options.plc_mode:
+ self.options.excludes.append('*access_log')
+ self.options.excludes.append('*request_log')
+ self.options.excludes.append('*.swp')
+ self.args.append('/var/log')
+
+ if self.options.verbose:
+ print 'Version:',self.subversion_id
+ print 'Options:',self.options
+ print 'Arguments:',self.args
+
+ def file_size (self,filename):
+ return os.stat(filename)[6]
+
+ def number_files (self):
+ return len(self.files)
+
+ # scans given arguments, and updates files accordingly
+ # can be run several times
+ def scan_files (self) :
+
+ if self.options.verbose:
+ print 'entering scan_files, files=',self.files
+
+ # mark entries in files as pre-existing
+ for key in self.files:
+ self.files[key]['old-file']=True
+
+ # refreshes the proper set of filenames
+ filenames = []
+ for arg in self.args:
+ if self.options.verbose:
+ print 'scan_files -- Considering arg',arg
+ if os.path.isfile (arg):
+ filenames += [ arg ]
+ elif os.path.isdir (arg) :
+ filenames += self.walk (arg)
+ else:
+ print "mtail : no such file or directory %s -- ignored"%arg
+
+ # updates files
+ for filename in filenames :
+ # known file
+ if self.files.has_key(filename):
+ size = self.file_size(filename)
+ offset = self.files[filename]['size']
+ if size > offset:
+ self.show_file_end(filename,offset,size)
+ self.files[filename]['size']=size
+ elif size < offset:
+ self.show_file_when_size_decreased(filename,offset,size)
+ del self.files[filename]['old-file']
+ else:
+ # enter file with current size
+ # if we didn't set format yet, it's because we are initializing
+ try:
+ self.format
+ self.show_now()
+ print self.format%filename,"new file"
+ self.show_file_end(filename,0,self.file_size(filename))
+ except:
+ pass
+ self.files[filename]={'size':self.file_size(filename)}
+
+ # cleanup
+ # avoid side-effects on the current loop basis
+ read_filenames = self.files.keys()
+ for filename in read_filenames:
+ if self.files[filename].has_key('old-file'):
+ self.show_now()
+ print self.format%filename,"file has gone"
+ del self.files[filename]
+
+ # compute margin and format
+ if not filenames:
+ print sys.argv[0],": WARNING : no file in scope"
+ self.format="%s"
+ else:
+ self.margin=max(*[len(f) for f in filenames])
+ self.format="%%%ds"%self.margin
+ if self.options.verbose:
+ print 'Current set of files:',filenames
+
+ def tail_files (self):
+
+ if self.options.verbose:
+ print 'tail_files'
+ for filename in self.files:
+ size = self.file_size(filename)
+ offset = self.files[filename]['size']
+ if size != offset:
+ self.show_file_end(filename,offset,size)
+ self.files[filename]['size']=size
+
+ def show_now (self):
+ if self.options.show_time:
+ label=time.strftime(self.options.time_format,time.localtime())
+ print label,
+
+ def show_file_end (self, filename, offset, size):
+ file = open(filename,"r")
+ file.seek(offset)
+ line=file.read(size-offset)
+ self.show_now()
+ print self.format%filename,'----------------------------------------'
+ print line
+ file.close()
+
+ def show_file_when_size_decreased (self, filename, offset, size):
+ print self.format%filename,'---------- file size decreased ---------',
+ if self.options.verbose:
+ print 'size during last check',offset,'current size',size
+ else:
+ print ''
+
+ # get all files under a directory
+ def walk ( self, root ):
+ import fnmatch, os, string
+
+ # initialize
+ result = []
+
+ # must have at least root folder
+ try:
+ names = os.listdir(root)
+ except os.error:
+ return result
+
+ # check each file
+ for name in names:
+ fullname = os.path.normpath(os.path.join(root, name))
+
+ # a file : check for excluded, otherwise append
+ if os.path.isfile(fullname):
+ try:
+ for exclude in self.options.excludes:
+ if fnmatch.fnmatch(name, exclude):
+ raise Exception('excluded')
+ result.append(fullname)
+ except:
+ pass
+ # a dir : let's recurse - avoid symlinks for anti-loop
+ elif os.path.isdir(fullname) and not os.path.islink(fullname):
+ result = result + self.walk( fullname )
+
+ return result
+
+ def run (self):
+
+ if self.number_files() == 0:
+ self.optparse.print_help()
+ sys.exit(1)
+ counter = 0
+
+ while 1:
+ ## hit the period ?
+ # dont do this twice at startup
+ if (counter !=0 and counter % self.options.rescan_period == 0):
+ self.scan_files()
+
+ if (counter % self.options.tail_period == 0):
+ self.tail_files()
+
+ time.sleep(1)
+ counter += 1
+
+###
+if __name__ == '__main__':
+ mtail (sys.argv[1:]).run()
-Vendor: PlanetLab
-Packager: PlanetLab Central <support@planet-lab.org>
-Distribution: PlanetLab 4.0
-URL: http://cvs.planet-lab.org/cvs/myplc
+#
+# $Id: myplc.spec 1087 2007-11-15 14:25:23Z thierry $
+#
+%define url $URL: svn+ssh://thierry@svn.planet-lab.org/svn/PLCAPI/trunk/PLCAPI.spec $
+
+%define name myplc
+%define version 4.0
+%define subversion 15
+
+%define release %{subversion}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
Summary: PlanetLab Central (PLC) Portable Installation
-Name: myplc
-Version: 0.5
-Release: 5%{?pldistro:.%{pldistro}}%{?date:.%{date}}
+Name: %{name}
+Version: %{version}
+Release: %{release}
License: PlanetLab
Group: Applications/Systems
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+Vendor: PlanetLab
+Packager: PlanetLab Central <support@planet-lab.org>
+Distribution: PlanetLab 4.0
+URL: %(echo %{url} | cut -d ' ' -f 2)
+
%define debug_package %{nil}
%description
MyPLC is a complete PlanetLab Central (PLC) portable installation
contained within a chroot jail. The default installation consists of a
web server, an XML-RPC API server, a boot server, and a database
-server: the core components of PLC. The installation may be customized
-through a graphical interface. All PLC services are started up and
+server: the core components of PLC. All PLC services are started up and
shut down through a single System V init script installed in the host
-system.
+system. The related Web Interface is now separately packaged
+in the PLCWWW component.
%prep
%setup -q
%build
pushd MyPLC
-./build.sh
+./build.sh %{pldistro}
popd
%install
%pre
if [ -x %{_sysconfdir}/init.d/plc ] ; then
- %{_sysconfdir}/init.d/plc stop
+ %{_sysconfdir}/init.d/plc safestop
fi
# Old versions of myplc used to ship with a bootstrapped database and
%preun
# 0 = erase, 1 = upgrade
if [ $1 -eq 0 ] ; then
- %{_sysconfdir}/init.d/plc stop
+ %{_sysconfdir}/init.d/plc safestop
if [ -x /sbin/chkconfig ] ; then
/sbin/chkconfig plc off
/sbin/chkconfig --del plc
--- /dev/null
+# first draft, extracted from plc_config.xml with --packages
+# the groups list was 'PlanetLab Central' but turned out to be an unknown group
+package:bzip2
+package:sendmail-cf
+package:tar
+package:less
+package:perl-GD
+package:sudo
+package:openssl
+package:xmlsec1
+package:kernel-vserver
+package:plcwww
+package:gd
+package:expect
+package:php-pgsql
+package:curl
+package:rpm
+package:httpd
+package:rsync
+package:mod_python
+package:mod_ssl
+package:bootmanager
+package:python-devel
+package:SOAPpy
+package:vixie-cron
+package:yum
+package:php-gd
+package:PLCAPI
+package:vim-minimal
+package:PyXML
+package:sendmail
+package:python
+package:createrepo
+package:postgresql-python
+package:cpio
+package:postgresql-server
+package:wget
+package:php
+package:xmlsec1-openssl
+package:postgresql
+package:openssh
+package:cvs
+package:dev
+package:python-imaging
+package:bootcd
+package:dnsmasq
+package:diffutils
+package:gzip
+package:findutils
--- /dev/null
+# first draft, extracted from plc_config.xml with --packages
+# the groups list was 'PlanetLab Central' but turned out to be an unknown group
+package:bzip2
+package:sendmail-cf
+package:tar
+package:less
+package:perl-GD
+package:sudo
+package:openssl
+package:xmlsec1
+package:kernel-vserver
+package:plcwww
+package:gd
+package:expect
+package:php-pgsql
+package:curl
+package:rpm
+package:httpd
+package:rsync
+package:mod_python
+package:mod_ssl
+package:bootmanager
+package:python-devel
+package:SOAPpy
+package:vixie-cron
+package:yum
+package:php-gd
+package:PLCAPI
+package:vim-minimal
+package:PyXML
+package:sendmail
+package:python
+package:createrepo
+package:postgresql-python
+package:cpio
+package:postgresql-server
+package:wget
+package:php
+package:xmlsec1-openssl
+package:postgresql
+package:openssh
+package:cvs
+package:dev
+package:python-imaging
+package:bootcd
+package:dnsmasq
+package:diffutils
+package:gzip
+package:findutils
--- /dev/null
+# first draft, extracted from plc_config.xml with --packages
+# the groups list was 'PlanetLab Central' but turned out to be an unknown group
+package:bzip2
+package:sendmail-cf
+package:tar
+package:less
+package:perl-GD
+package:sudo
+package:openssl
+package:xmlsec1
+package:kernel-vserver
+package:plcwww
+package:gd
+package:expect
+package:php-pgsql
+package:curl
+package:rpm
+package:httpd
+package:rsync
+package:mod_python
+package:mod_ssl
+package:bootmanager
+package:python-devel
+package:SOAPpy
+package:vixie-cron
+package:yum
+package:php-gd
+package:PLCAPI
+package:vim-minimal
+package:PyXML
+package:sendmail
+package:python
+package:createrepo
+package:postgresql-python
+package:cpio
+package:postgresql-server
+package:wget
+package:php
+package:xmlsec1-openssl
+package:postgresql
+package:openssh
+package:cvs
+package:dev
+package:python-imaging
+package:bootcd
+package:dnsmasq
+package:diffutils
+package:gzip
+package:findutils
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: plc-config,v 1.1.1.1 2006/03/27 17:36:46 mlhuang Exp $
+# $Id: plc-config 1078 2007-11-15 13:38:27Z thierry $
#
import sys
sys.exit(1)
+def deprecated (message):
+ print "%s: deprecated usage"%sys.argv[0]
+ print message
+ sys.exit(1)
+
def main():
plc = PLCConfiguration()
fileobjs = []
save = False
# Standard options
- shortopts = "hs"
+ shortopts = "hs:"
longopts = ["shell", "bash", "python",
"php",
"xml",
"category=", "variable=", "value=",
"group=", "package=", "type=",
"help",
- "save"]
+ "save="]
try:
(opts, argv) = getopt.gnu_getopt(sys.argv[1:], shortopts, longopts)
elif opt == "--variables":
output = plc.output_variables
elif opt == "--packages":
- output = plc.output_packages
+# output = plc.output_packages
+ deprecated("option --packages deprecated -- use .lst files instead")
elif opt == "--groups":
- output = plc.output_groups
+# output = plc.output_groups
+ deprecated("option --groups deprecated -- use .lst files instead")
elif opt == "--comps":
- output = plc.output_comps
+# output = plc.output_comps
+ deprecated("option --comps deprecated -- use .lst files instead")
elif opt == "--category":
category['id'] = optval
elif opt == "--variable":
elif opt == "--value":
variable['value'] = optval
elif opt == "--group":
- group['id'] = optval
+# group['id'] = optval
+ deprecated("option --group deprecated -- use .lst files instead")
elif opt == "--package":
- package['name'] = optval
+# package['name'] = optval
+ deprecated("option --package deprecated -- use .lst files instead")
elif opt == "--type":
package['type'] = optval
elif opt == '-s' or opt == "--save":
- save = True
+ if not optval:
+ usage()
+ print 'parsed save option',optval
+ save = optval
elif opt == '-h' or opt == "--help":
usage()
# --save
if save:
- plc.save()
+ # create directory if needed
+ # so that plc.d/{api,postgres} can create configs/site.xml
+ dirname = os.path.dirname (save)
+ if (not os.path.exists (dirname)):
+ os.makedirs(dirname,0755)
+ if (not os.path.exists (dirname)):
+ print "Cannot create dir %s - exiting" % dirname
+ sys.exit(1)
+
+ plc.save(save)
if __name__ == '__main__':
from plc_config import PLCConfiguration
####################
-release_id = "$Id: plc-config-tty,v 1.10 2006/12/12 10:14:44 thierry Exp $"
-release_rev = "$Revision: 1.10 $"
+release_id = "$Id: plc-config-tty 635 2007-07-05 11:08:14Z thierry $"
+release_rev = "$Revision: 635 $"
def init_flavour (flavour):
global service
global mainloop_usage
mainloop_usage= """Available commands:
Uppercase versions give variables comments, when available
--u/U\t\t\tEdit usual variables
--w\t\t\tWrite & consolidate
--r\t\t\tRestart %s service
--q\t\t\tQuit (without saving)
--h/?\t\t\tThis help
+ u/U\t\t\tEdit usual variables
+ w\t\t\tWrite & consolidate
+ r\t\t\tRestart %s service
+ q\t\t\tQuit (without saving)
+ h/?\t\t\tThis help
---
-l/L [<cat>|<var>]\tShow Locally modified variables/values
--s/S [<cat>|<var>]\tShow variables/values (all, in category, single)
--e/E [<cat>|<var>]\tEdit variables (all, in category, single)
+ l/L [<cat>|<var>]\tShow Locally modified variables/values
+ s/S [<cat>|<var>]\tShow variables/values (all, in category, single)
+ e/E [<cat>|<var>]\tEdit variables (all, in category, single)
---
--c\t\t\tList categories
--v/V [<cat>|<var>]List Variables (all, in category, single)
+ c\t\t\tList categories
+ v/V [<cat>|<var>]List Variables (all, in category, single)
---
Typical usage involves: u, [l,] w, r, q
""" % service
return
print ("Merged\n\t%s\nand\t%s\ninto\t%s"%(default_config,site_config,
consolidated_config))
+ os.system("set -x ; service plc reload")
####################
def restart_plc ():
print ("Unknown command >%s< -- use h for help" % answer)
####################
+# creates directory for file if not yet existing
def check_dir (config_file):
dirname = os.path.dirname (config_file)
if (not os.path.exists (dirname)):
- print "Config file %s located under a non-existing directory" % config_file
- answer=raw_input("Want to create %s [y]/n ? " % dirname)
- answer = answer.lower()
- if (answer == 'n'):
- print "Cannot proceed - good bye"
+ os.makedirs(dirname,0755)
+ if (not os.path.exists (dirname)):
+ print "Cannot create dir %s - exiting" % dirname
sys.exit(1)
else:
- os.makedirs(dirname,0755)
- if (not os.path.exists (dirname)):
- print "Cannot create dir %s - exiting" % dirname
- sys.exit(1)
- else:
- print "Created directory %s" % dirname
-
+ print "Created directory %s" % dirname
####################
def main ():
--- /dev/null
+#!/usr/bin/env plcsh
+
+import Image, ImageDraw
+
+####### first - rustic - linear positioning on a map
+def circle (image, percentX, percentY, radiusX, radiusY, colorIn, colorOut):
+
+ imageX, imageY = image.size
+ centerX = int(imageX*percentX)
+ centerY = int(imageY*percentY)
+ x = max (0, min (centerX,imageX))
+ y = max (0, min (centerY,imageY))
+
+ x1 = x - radiusX
+ x2 = x + radiusX
+ y1 = y - radiusY
+ y2 = y + radiusY
+
+ draw = ImageDraw.Draw (image)
+ draw.chord((x1,y1,x2,y2), 0, 360, fill=colorIn, outline=colorOut )
+ del draw
+
+latitude={'top':65.,
+ 'bottom': 35.5}
+longitude={'left':-11.,
+ 'right':58.}
+
+def render_site (site, image, sx, sy, cIn, cOut):
+ if site['longitude'] is not None and site['latitude'] is not None:
+ px=float(longitude['left']-site['longitude'])/float(longitude['left']-longitude['right'])
+ py=float(latitude['top']-site['latitude'])/float(latitude['top']-latitude['bottom'])
+ if (px<0 or py<0 or px>1 or py>1):
+ return
+
+ circle(image,px,py,sx,sy,cIn,cOut)
+
+def make_image():
+ path = '/var/www/html/sites/'
+ original = path + 'map.png'
+ live = path + 'livemap.png'
+
+ # map characteristics, in degrees.
+ # latitude : positive is north
+ # longitude : positive is east
+
+ # circle radius in pixels
+ sxLocal,syLocal=7,7
+ # circle in and out colors
+ cInLocal , cOutLocal = '#566b8a','#bbbbbb'
+
+ # same for federating / foreign sites
+ sxForeign,syForeign=6,6
+ cInForeign , cOutForeign = '#acb3a4', '#444444'
+
+ image = Image.open(original)
+
+ for site in GetSites({'~peer_id':None,'enabled':True}):
+ render_site (site, image, sxForeign, syForeign, cInForeign , cOutForeign)
+ # local sites go last to be more visible
+ for site in GetSites({'peer_id':None,'enabled':True}):
+ render_site (site, image, sxLocal, syLocal, cInLocal , cOutLocal)
+
+ image.save (live)
+
+########## second - way simpler - export sites as a list to javascript for rendering with googlemap
+js_prelude="""
+function Site (lat,lon,site_id,name,peer_id,peername,nb_nodes) {
+ this.lat=lat;
+ this.lon=lon;
+ this.site_id=site_id;
+ this.name=name;
+ this.peer_id=peer_id;
+ this.peername=peername;
+ this.nb_nodes=nb_nodes;
+}
+"""
+
+def locate_peer (peers,peer_id):
+ for peer in peers:
+ if peer['peer_id']==peer_id:
+ return peer
+ return {'peername':'Cannot locate peer'}
+
+def js_site (site,peers):
+ # some sites come with lat or lon being None
+ lat = site['latitude']
+ if not lat:
+ lat=0
+ lon = site['longitude']
+ if not lon:
+ lon=0
+ # build javascript text
+ jstext="new Site("
+ jstext += str(lat) + "," + str(lon) + ","
+ jstext += str(site['site_id']) + ","
+ # needs html encoding for wierd chars
+ jstext += '"' + site['name'].encode("utf-8") + '"' + ','
+ if not site['peer_id']:
+ jstext += '0,""' +','
+ else:
+ peer=locate_peer(peers,site['peer_id'])
+ jstext += str(site['peer_id']) + ',"' + peer['peername'].encode("utf-8") + '"' + ','
+ jstext += str(len(site['node_ids']))
+ jstext += ')\n'
+ return jstext
+
+def make_javascript():
+ outputname="/var/www/html/sites/plc-sites.js"
+ f=open(outputname,"w")
+ f.write(js_prelude)
+ columns=['latitude','longitude','site_id','name','peer_id','node_ids']
+ f.write("allSites=new Array(\n")
+ # writes foreign sites first
+ foreign_sites=GetSites({'~peer_id':None},columns)
+ peers=GetPeers({})
+ local_sites=GetSites({'peer_id':None},columns)
+ f.write(",".join([js_site(site,peers) for site in foreign_sites+local_sites]))
+ f.write(");")
+
+def main ():
+ make_image ()
+ make_javascript ()
+
+if __name__ == '__main__':
+ main ()
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: api,v 1.8 2007/01/19 20:05:05 mlhuang Exp $
+# $Id: api 635 2007-07-05 11:08:14Z thierry $
#
# Source function library and configuration
. /etc/plc.d/functions
. /etc/planetlab/plc_config
+local_config=/etc/planetlab/configs/site.xml
# Be verbose
set -x
# password.
if [ -z "$PLC_API_MAINTENANCE_PASSWORD" ] ; then
PLC_API_MAINTENANCE_PASSWORD=$(uuidgen)
- plc-config --category=plc_api --variable=maintenance_password --value="$PLC_API_MAINTENANCE_PASSWORD" --save
+ plc-config --category=plc_api --variable=maintenance_password --value="$PLC_API_MAINTENANCE_PASSWORD" --save=$local_config $local_config
+ service plc reload
fi
# Make sure that all PLC servers are allowed to access the API
done
) | sort -u))
PLC_API_MAINTENANCE_SOURCES=${PLC_API_MAINTENANCE_SOURCES[*]}
- plc-config --category=plc_api --variable=maintenance_sources --value="$PLC_API_MAINTENANCE_SOURCES" --save
+ plc-config --category=plc_api --variable=maintenance_sources --value="$PLC_API_MAINTENANCE_SOURCES" --save=$local_config $local_config
+ service plc reload
result "$MESSAGE"
;;
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: bootcd,v 1.3 2006/06/23 20:29:22 mlhuang Exp $
+# $Id: bootcd 129 2007-03-20 12:04:03Z thierry $
#
# Source function library and configuration
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: bootmanager,v 1.3 2006/06/23 20:29:22 mlhuang Exp $
+# $Id: bootmanager 129 2007-03-20 12:04:03Z thierry $
#
# Source function library and configuration
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: crond,v 1.9 2007/02/07 23:21:27 mlhuang Exp $
+# $Id: crond 1078 2007-11-15 13:38:27Z thierry $
#
# Source function library and configuration
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=$MAILTO
HOME=/
-
+#
# minute hour day-of-month month day-of-week user command
EOF
# Run all jobs once at startup
- if [ "$PLC_BOOT_ENABLED" = "1" ] ; then
- echo "*/5 * * * * root gen-slices-xml-05.py" >>/etc/cron.d/plc.cron
- gen-slices-xml-05.py
- check
+# if [ "$PLC_BOOT_ENABLED" = "1" ] ; then
+# echo "*/5 * * * * root gen-slices-xml-05.py" >>/etc/cron.d/plc.cron
+# gen-slices-xml-05.py
+# check
fi
if [ "$PLC_WWW_ENABLED" = "1" ] ; then
- echo "*/15 * * * * root gen-static-content.py" >>/etc/cron.d/plc.cron
- echo "*/15 * * * * root gen-sites-xml.py" >>/etc/cron.d/plc.cron
+# echo "*/15 * * * * root gen-static-content.py" >>/etc/cron.d/plc.cron
+# echo "*/15 * * * * root gen-sites-xml.py" >>/etc/cron.d/plc.cron
echo "00 * * * * wget -O - -q http://localhost/cron.php" >>/etc/cron.d/plc.cron
- gen-static-content.py
- check
- gen-sites-xml.py
- check
+# gen-static-content.py
+# check
+# gen-sites-xml.py
+# check
wget -O - -q http://localhost/cron.php
check
fi
check
fi
+ if [ "$PLC_WWW_ENABLED" = "1" ] ; then
+ echo "*/15 * * * * root clean-empty-dirs.py /var/tmp/bootmedium" >> /etc/cron.d/plc.cron
+ clean-empty-dirs.py /var/tmp/bootmedium
+ check
+ fi
+
plc_daemon crond
check
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: db,v 1.7 2007/01/31 19:53:20 mlhuang Exp $
+# $Id: db 316 2007-04-24 17:25:09Z thierry $
#
# Source function library and configuration
extension=${script##*.}
if [ $index -gt $subversion ] ; then
if [ "$extension" = "sql" ] ; then
+ dialog " - $script (dbdumped)"
+ dump_planetlab_db "before-$script"
psql -U $PLC_DB_USER -f $file $PLC_DB_NAME
elif [ -x $file ] ; then
+ dialog " - $script (dbdumped)"
+ dump_planetlab_db "before-$script"
$file
+ else
+ dialog "\nWarning: migration $file not executable"
fi
check
fi
done
}
-# Dumps the database
-function dump_db()
+# Dumps the database - optional argument to specify filename suffix
+function dump_planetlab_db()
{
- dump=/var/lib/pgsql/backups/$(date +"$PLC_DB_NAME.%Y-%m-%d-%H-%M.sql")
+ if [ -n "$1" ] ; then suffix="-$1" ; else suffix="" ; fi
+ dump=/var/lib/pgsql/backups/$(date +"$PLC_DB_NAME.%Y-%m-%d-%H-%M-%S${suffix}.sql")
pg_dump -U $PLC_DB_USER $PLC_DB_NAME > $dump
check
- dump=/var/lib/pgsql/backups/$(date +"drupal.%Y-%m-%d-%H-%M.sql")
+}
+
+function dump_drupal_db()
+{
+ dump=/var/lib/pgsql/backups/$(date +"drupal.%Y-%m-%d-%H-%M-%S.sql")
pg_dump -U $PLC_DB_USER drupal > $dump
check
}
MESSAGE=$"Dumping the databases in /var/lib/pgsql/backups"
dialog "$MESSAGE"
- dump_db
+ dump_planetlab_db
+ dump_drupal_db
result "$MESSAGE"
;;
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: dns,v 1.2 2006/05/26 19:57:30 mlhuang Exp $
+# $Id: dns 129 2007-03-20 12:04:03Z thierry $
#
# Source function library and configuration
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: functions,v 1.7 2007/01/19 17:12:45 mlhuang Exp $
+# $Id: functions 545 2007-06-18 10:56:31Z thierry $
#
export PATH=/sbin:/bin:/usr/bin:/usr/sbin
[ -n "${pid:-}" -a -z "${force:-}" ] && return
# And start it up.
- (exec -a plc_${base} $*)
+ # Thierry -- June 18 2007
+ # when invoking, e.g. service plc start httpd from an ssh connection
+ # ssh stupidly hangs when everything is done
+ # it turns out the forked ssh daemon exhibits the following stack at that point
+ # (gdb) where
+ # #0 0x001d6402 in __kernel_vsyscall ()
+ # #1 0x003c2e7d in ___newselect_nocancel () from /lib/libc.so.6
+ # #2 0x004387b4 in main () from /usr/sbin/sshd
+ # So I figured the various file descriptors used were not properly closed
+ (exec 3>&- 4>&- ; exec -a plc_${base} $*)
ret=$?
if [ -f /var/run/${base}.pid ] ; then
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: gpg,v 1.8 2006/12/15 20:16:16 mlhuang Exp $
+# $Id: gpg 129 2007-03-20 12:04:03Z thierry $
#
# Source function library and configuration
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: httpd,v 1.11 2007/02/06 16:24:13 mlhuang Exp $
+# $Id: httpd 350 2007-05-11 10:58:44Z thierry $
#
# Source function library and configuration
Redirect /index.html http://$PLC_WWW_HOST:$PLC_WWW_PORT/
EOF
fi
+ cat <<EOF
+AddType application/octet-stream .iso
+AddType application/octet-stream .usb
+EOF
) >>$plc_conf
# Make alpina-logs directory writable for bootmanager log upload
?>
EOF
+ ## patch php.ini
+ # memory limit
+ sed -i -e 's,^memory_limit = 8M *;,memory_limit = 24M ; patch myplc -- ,' $php_ini
+ # log_errors : is On by default
+ # error_log
+ if ! grep '^error_log *=' $php_ini > /dev/null ; then
+ echo 'error_log = /var/log/php.log' >> $php_ini
+ touch /var/log/php.log
+ chmod 666 /var/log/php.log
+ fi
+
plc_daemon httpd
check
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: mail,v 1.3 2006/06/23 20:29:22 mlhuang Exp $
+# $Id: mail 554 2007-06-19 15:11:22Z thierry $
#
# Source function library and configuration
# without a warning, so that the API can send out mail.
echo "apache" >/etc/mail/trusted-users
- service sendmail start
+ (exec 3>&- 4>&- ; service sendmail start)
check
result "$MESSAGE"
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: network,v 1.5 2006/06/23 20:29:22 mlhuang Exp $
+# $Id: network 129 2007-03-20 12:04:03Z thierry $
#
# Source function library and configuration
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: packages,v 1.7 2007/02/04 01:05:28 mlhuang Exp $
+# $Id: packages 129 2007-03-20 12:04:03Z thierry $
#
# Source function library and configuration
# Old command is yum-arch
if [ $yum_arch -eq 1 ] ; then
- yum-arch $repository
+ yum-arch $repository | tr '\r' '\n' | grep -v '^ *$'
check
fi
# New command is createrepo
if [ $createrepo -eq 1 ] ; then
if [ -f $repository/yumgroups.xml ] ; then
- createrepo -g yumgroups.xml $repository
+ createrepo -g yumgroups.xml $repository | tr '\r' '\n' | grep -v '^ *$'
else
- createrepo $repository
+ createrepo $repository | tr '\r' '\n' | grep -v '^ *$'
fi
check
fi
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: postgresql,v 1.11 2007/02/05 19:11:06 mlhuang Exp $
+# $Id: postgresql 635 2007-07-05 11:08:14Z thierry $
#
# Source function library and configuration
. /etc/plc.d/functions
. /etc/planetlab/plc_config
+local_config=/etc/planetlab/configs/site.xml
# Be verbose
set -x
postgresql_start ()
{
# start() always returns 0
- service postgresql start
+ (exec 3>&- 4>&- ; service postgresql start)
# status() will still return 0 even while still initializing
if status postmaster && [ -f /var/lock/subsys/postgresql ] ; then
# Create/update the unprivileged database user and password
if [ -z "$PLC_DB_PASSWORD" ] ; then
PLC_DB_PASSWORD=$(uuidgen)
- plc-config --category=plc_db --variable=password --value="$PLC_DB_PASSWORD" --save
+ plc-config --category=plc_db --variable=password --value="$PLC_DB_PASSWORD" --save=$local_config $local_config
+ service plc reload
fi
if ! psql -U $PLC_DB_USER -c "" template1 >/dev/null 2>&1 ; then
psql -U postgres -c "CREATE USER $PLC_DB_USER PASSWORD '$PLC_DB_PASSWORD'" template1
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: ssh,v 1.2 2006/04/25 21:18:19 mlhuang Exp $
+# $Id: ssh 129 2007-03-20 12:04:03Z thierry $
#
# Source function library and configuration
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: ssl,v 1.11 2007/01/18 18:44:18 mlhuang Exp $
+# $Id: ssl 129 2007-03-20 12:04:03Z thierry $
#
# Source function library and configuration
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: syslog,v 1.2 2006/04/25 21:18:19 mlhuang Exp $
+# $Id: syslog 129 2007-03-20 12:04:03Z thierry $
#
# Source function library and configuration
Mark Huang <mlhuang@cs.princeton.edu>
Copyright (C) 2006 The Trustees of Princeton University
-$Id$
+$Id: plc_config.dtd 129 2007-03-20 12:04:03Z thierry $
-->
<!ELEMENT configuration (variables, comps)>
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: plc_config.py,v 1.4 2006/07/17 21:29:15 mlhuang Exp $
+# $Id: plc_config.py 1078 2007-11-15 13:38:27Z thierry $
#
import xml.dom.minidom
Mark Huang <mlhuang@cs.princeton.edu>
Copyright (C) 2006 The Trustees of Princeton University
-$Id: plc_devel_config.xml,v 1.10 2007/08/24 07:19:27 mef Exp $
+$Id: plc_devel_config.xml 1078 2007-11-15 13:38:27Z thierry $
-->
<!DOCTYPE configuration PUBLIC "-//PlanetLab Central//DTD PLC configuration//EN" "plc_config.dtd">
</variables>
<comps>
+ <!-- xxx should be deprecated - not used anymore xxx -->
<group>
<id>development-libs</id>
<name>Development Libraries</name>
<description>Additional tools required to build PlanetLab
software.</description>
<packagelist>
- <!-- Basics -->
- <packagereq type="mandatory">findutils</packagereq>
-
<!-- kernel-vserver is intended for the vserver-reference, but
serves the same useful purpose for MyPLC, namely, to
Provide: kernel without actually installing anything. -->
<packagereq type="mandatory">tetex-latex</packagereq>
<packagereq type="mandatory">gcc-c++</packagereq>
- <!-- vsys -->
- <packagereq type="mandatory">ocaml</packagereq>
- <packagereq type="mandatory">ocaml-ocamldoc</packagereq>
- <packagereq type="mandatory">inotify-tools-devel</packagereq>
-
<!-- ulogd -->
<packagereq type="mandatory">libpcap</packagereq>
<packagereq type="mandatory">libpcap-devel</packagereq>
- <packagereq type="mandatory">mysql</packagereq>
- <packagereq type="mandatory">mysql-devel</packagereq>
- <packagereq type="mandatory">mysql-server</packagereq>
<!-- iptables -->
<packagereq type="mandatory">linuxdoc-tools</packagereq>
<!-- myplc -->
<packagereq type="mandatory">rsync</packagereq>
+ <packagereq type="mandatory">ghostscript</packagereq>
- <!-- PLCAPI -->
+ <!-- new_plc_api -->
<packagereq type="mandatory">docbook-utils-pdf</packagereq>
<packagereq type="mandatory">postgresql-devel</packagereq>
<packagereq type="mandatory">php-devel</packagereq>
<packagereq type="mandatory">SOAPpy</packagereq>
<packagereq type="mandatory">PyXML</packagereq>
- <packagereq type="mandatory">expat-devel</packagereq>
</packagelist>
</group>
--- /dev/null
+#!/usr/bin/env plcsh
+# $Id: refresh-peer.py 154 2007-03-28 14:15:55Z thierry $
+
+import sys,os,time
+
+def Run (peername):
+ timestring=time.strftime("%Y-%m-%d-%H-%M-%S")
+ print 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',peername
+ print 'RefreshPeer on %s - starting on %s'%(peername,timestring)
+ print 'xxxxxxxxxx'
+ sys.stdout.flush()
+ start=time.time()
+ result=RefreshPeer(peername)
+ finish=time.time()
+
+ print 'Total duration',finish-start
+ print 'xxxxxxxxxx timers:'
+ keys=result.keys()
+ keys.sort()
+ for key in keys:
+ print key,result[key]
+ sys.stdout.flush()
+ sys.stderr.flush()
+
+def RunInLog (peername):
+ logname="/var/log/refresh-peer-%s.log"%(peername)
+ sys.stdout=open(logname,'a')
+ sys.stderr=sys.stdout
+ Run(peername)
+ sys.stderr.close()
+ sys.stdout.close()
+
+if __name__ == "__main__":
+
+ for peername in sys.argv[1:]:
+ RunInLog (peername)