Commit 6a66e120 authored by Karl Chen's avatar Karl Chen

python overhaul

svn path=/trunk/boinc/; revision=2246
parent 306e9d33
......@@ -6073,3 +6073,6 @@ David Sept 3 2003
testbase.py
tools/
create_work.C
quarl 2003/09/03
- restructured python scripts
......@@ -49,8 +49,9 @@ AC_SUBST(MINOR_VERSION, `echo AC_PACKAGE_VERSION | sed 's/.*\.0*//'`)
AC_DEFINE_UNQUOTED(MAJOR_VERSION, $MAJOR_VERSION, [Major part of version number])
AC_DEFINE_UNQUOTED(MINOR_VERSION, $MINOR_VERSION, [Minor part of version number])
AC_DEFINE_UNQUOTED(HOSTTYPE, "$host", [Host for this compilation])
AC_SUBST(BUILD_TOP_DIR, `pwd`)
AC_SUBST(CLIENT_BIN_FILENAME,[boinc_]AC_PACKAGE_VERSION[_$host${EXEEXT}])
AC_SUBST(TOP_BUILD_DIR, [`pwd`])
AC_SUBST(TOP_SOURCE_DIR, [`(cd \`dirname "$0"\` && pwd)`])
AM_MAINTAINER_MODE
......@@ -119,8 +120,6 @@ AC_TYPE_SIZE_T
AC_STRUCT_TM
AC_STRUCT_TIMEZONE
AC_SUBST(CLIENT_BIN_FILENAME,[boinc_]AC_PACKAGE_VERSION[_$host${EXEEXT}])
# by default, create static binaries on linux.
[if [ "$target_os" = "linux-gnu" ]; then
STATIC_FLAGS="-static"
......@@ -128,7 +127,8 @@ fi
echo "checking static flags... ${STATIC_FLAGS:-(none)}"]
AC_SUBST(STATIC_FLAGS)
AC_CONFIG_FILES([RSAEuro/source/Makefile
AC_CONFIG_FILES([Makefile
RSAEuro/source/Makefile
RSAEuro/Makefile
api/Makefile
apps/Makefile
......@@ -138,14 +138,22 @@ AC_CONFIG_FILES([RSAEuro/source/Makefile
sched/Makefile
tools/Makefile
test/Makefile
py/Makefile
test/version.inc
py/version.py
Makefile
py/Makefile
py/Boinc/Makefile
py/Boinc/version.py
py/Boinc/boinc_path_config.py:py/Boinc/boinc_path_config.py.in
py/boinc_path_config.py:py/Boinc/boinc_path_config.py.in
sched/boinc_path_config.py:py/Boinc/boinc_path_config.py.in
tools/boinc_path_config.py:py/Boinc/boinc_path_config.py.in
test/boinc_path_config.py:py/Boinc/boinc_path_config.py.in
])
AC_CONFIG_HEADER([config.h])
AC_OUTPUT
(cd test && ./test_sanity.py)
echo "--- Configured BOINC AC_PACKAGE_VERSION ---"
test/test_sanity.py
## $Id$
include $(top_srcdir)/Makefile.incl
EXTRA_DIST = boinc.py boinc_db.py version.py.in db_def_to_py
$(srcdir)/boinc_db.py: $(top_srcdir)/db/boinc_db.h $(top_srcdir)/lib/result_state.h
cat $^ | $(srcdir)/db_def_to_py > $@
# all: $(srcdir)/boinc_db.py
# $Id$
# this file is necessary to let Python know this directory is a module.
# $Id$
# This module prepends boinc/py/ to the python system path
# configure generates boinc/*/boinc_path_config.py from
# boinc/py/Boinc/boinc_path_config.py.in (in all directories that contain
# python scripts, so that they can directly import path_config.py)
import sys, os
TOP_BUILD_DIR = "@TOP_BUILD_DIR@"
TOP_SOURCE_DIR = "@TOP_SOURCE_DIR@"
sys.path.insert(0, os.path.join(TOP_SOURCE_DIR, 'py'))
if TOP_BUILD_DIR != TOP_SOURCE_DIR:
sys.path.insert(0, os.path.join(TOP_BUILD_DIR, 'py'))
try:
from Boinc import version
except ImportError:
sys_path = sys.path
raise SystemExit("""
FATAL configuration error
=========================
boinc_path_config.py: Couldn't find version.py.
boinc/py/Boinc/version.py should have been built from boinc/py/version.py.in
by configure.
TOP_SOURCE_DIR = %(TOP_SOURCE_DIR)s
TOP_BUILD_DIR = %(TOP_BUILD_DIR)s
sys.path = %(sys_path)s
""" %locals())
#!/usr/bin/env python
# $Id$
# configxml.py - module to read and parse config.xml, run_state.xml
'''
SYNOPSIS: parses and writes config.xml and run_state.xml
USAGE: from Boinc import configxml
config = configxml.ConfigFile().read()
run_state = configxml.RunStateFile().read()
print config.config.db_name
print config.tasks[4].cmd
run_state.enabled = True
new_task = newConfigDict()
new_task.cmd = "echo hi | mail quarl"
config.tasks.append(new_task)
config.write()
run_state.write()
'''
import sys
import xml.dom.minidom
import boinc_project_path
def _append_new_element(parent_node, name):
new_element = xml.dom.minidom.Element(name)
if isinstance(parent_node,xml.dom.minidom.Document):
new_element.ownerDocument = parent_node
else:
assert(parent_node.ownerDocument)
new_element.ownerDocument = parent_node.ownerDocument
parent_node.appendChild(new_element)
return new_element
def _get_elements(node, name):
return node.getElementsByTagName(name)
def _get_element(node, name, optional=True):
try:
return _get_elements(node,name)[0]
except IndexError:
if optional:
return _append_new_element(node, name)
raise SystemExit("ERROR: Couldn't find xml node <%s>"% name)
def _None2Str(object):
if object == None:
return ''
else:
return object
def _get_element_data(node):
return node and _None2Str(node.firstChild and node.firstChild.data)
def _get_element_int(node, default=0):
try:
return int(_get_element_data(node))
except:
return default
def _get_child_elements(node):
return filter(lambda node: node.nodeType == node.ELEMENT_NODE, node.childNodes)
def _set_element(node, new_data):
if node.firstChild and node.firstChild.data:
node.firstChild.data = str(new_data)
else:
new_data_node = xml.dom.minidom.Text()
new_data_node.data = str(new_data)
new_data_node.ownerDocument = node.ownerDocument
node.appendChild(new_data_node)
class ConfigDict:
def __init__(self, dom_node):
self._node = dom_node
self._name = self._node.nodeName
for node in _get_child_elements(self._node):
self.__dict__[node.nodeName] = _get_element_data(node)
def save(self):
for key in self.__dict__:
if key.startswith('_'): continue
_set_element( _get_element(self._node,key,1), str(self.__dict__[key]) )
def debug_print(self):
for key in self.__dict__.keys():
print key.rjust(15), '=', self.__dict__[key]
class ConfigDictList(list):
def __init__(self, dom_node, item_class=ConfigDict):
self._node = dom_node
list.__init__(self, map(item_class, _get_child_elements(self._node)))
def save(self):
map(ConfigDict.save, self)
def make_node_and_append(self, name):
'''Make a new ConfigDict and append it. Returns new ConfigDict.'''
new_element = _append_new_element(self._node, name)
new_cd = ConfigDict(new_element)
self.append(new_cd)
return new_cd
class XMLConfig:
'''Base class for xml config files'''
def __init__(self, filename = None):
# default_filename should be defined by children
self.filename = filename or self.default_filename
def read(self, failopen_ok=False):
"""Read the XML object's file source and return self."""
try:
self.xml = xml.dom.minidom.parse(self.filename)
except IOError, e:
if not failopen_ok:
# raise
raise SystemExit("%s: Couldn't parse XML config\n%s: %s"%(sys.argv[0],sys.argv[0],e))
print >>sys.stderr, "Warning:", e
# self.xml = xml.dom.minidom.Document()
self.xml = xml.dom.minidom.parseString(self.default_xml)
self._get_elements()
return self
def _get_elements(self):
pass
def write(self, output=None):
"""Write XML data to filename, or other stream."""
self._set_elements()
if not output:
output = open(self.filename,'w')
self.xml.writexml(output)
print >>output
return self
def _set_elements(self):
pass
class ConfigFile(XMLConfig):
'''
embodies config.xml
Public attributes:
config - ConfigDict
tasks - list of ConfigDict elements
daemons -
'''
default_filename = boinc_project_path.config_xml_filename
def _get_elements(self):
self.xml_boinc = _get_element(self.xml, 'boinc', optional=False)
self.xml_config = _get_element(self.xml_boinc, 'config', optional=False)
self.xml_tasks = _get_element(self.xml_boinc, 'tasks')
self.xml_daemons = _get_element(self.xml_boinc, 'daemons')
self.config = ConfigDict(self.xml_config)
self.daemons = ConfigDictList(self.xml_daemons)
self.tasks = ConfigDictList(self.xml_tasks)
def _set_elements(self):
self.config.save()
self.daemons.save()
self.tasks.save()
def debug_print_all(self):
'''print everything to stdout.'''
print 'Debug dump of', self.filename
print '-- parsed xml -------------------------------------------------------'
self.xml.writexml(sys.stdout)
print
print '-- Config -----------------------------------------------------------'
self.config.debug_print()
print
print '-- Daemons ------------------------------------------------------------'
for daemon in self.daemons:
daemon.debug_print()
print
print
print '-- Tasks ------------------------------------------------------------'
for task in self.tasks:
task.debug_print()
print
default_xml = '<boinc><config></config></boinc>'
# keeps BoincCron's timestamp status file
class RunStateFile(XMLConfig):
'''
embodies run_state.xml
Public attributes:
tasks - list of ConfigDict elements
enabled - boolean
'''
default_filename = boinc_project_path.run_state_xml_filename
def _get_elements(self):
self.xml_boinc = _get_element(self.xml, 'boinc', optional=False)
self.xml_tasks = _get_element(self.xml_boinc, 'tasks')
self.xml_enabled = _get_element(self.xml_boinc, 'enabled')
self.tasks = ConfigDictList(self.xml_tasks)
self.enabled = _get_element_int(self.xml_enabled)
def _set_elements(self):
_set_element( self.xml_enabled, self.enabled )
self.tasks.save()
default_xml = '<boinc></boinc>'
if __name__ == '__main__':
config = ConfigFile().read()
# print "setting config.enabled = True"
# config.enabled = True
config.debug_print_all()
print " -- saving xml and rewriting -----------------------------------------------"
config.write(sys.stdout)
## $Id$
# the module MySQLdb can be installed on debian with "apt-get install python2.2-mysqldb"
# TODO: make things work if build_dir != src_dir
from version import *
import version
from boinc_db import *
import os, sys, glob, time, shutil, re, random
import MySQLdb
......@@ -20,7 +18,7 @@ options.have_init = False
options.install_method = None
options.echo_verbose = 1
options.is_test = False
options.client_bin_filename = CLIENT_BIN_FILENAME
options.client_bin_filename = version.CLIENT_BIN_FILENAME
options.drop_db_first = False
def init():
......@@ -146,7 +144,7 @@ Executable not found: %s
Did you `make' yet?
""" % prog)
def check_core_client_executable():
check_program_exists(builddir('client', CLIENT_BIN_FILENAME))
check_program_exists(builddir('client', version.CLIENT_BIN_FILENAME))
def check_app_executable(app):
check_program_exists(builddir('apps', app))
......@@ -172,7 +170,7 @@ def _url_to_filename(url):
if (c.isalnum()):
s += c
else:
s += '_'
s += '_'
return _remove_trail(s,'_')
def account_file_name(url):
......
## $Id$
import os
import sys
# define version numbers using autoconf
MAJOR_VERSION = @MAJOR_VERSION@
MINOR_VERSION = @MINOR_VERSION@
VERSION_STRING = "@VERSION@"
CLIENT_BIN_FILENAME = "@CLIENT_BIN_FILENAME@"
PLATFORM = "@host@"
_BUILD_TOP_DIR = "@BUILD_TOP_DIR@"
_REL_TOP_SRC_DIR = "@top_srcdir@"
_REL_SRC_DIR = "@srcdir@"
TOP_BUILD_DIR = os.path.realpath(_BUILD_TOP_DIR)
TOP_SRC_DIR = os.path.realpath(os.path.join(_BUILD_TOP_DIR, 'py', _REL_TOP_SRC_DIR))
if _REL_SRC_DIR != ".":
sys.path.insert(0, _REL_SRC_DIR)
## $Id$
include $(top_srcdir)/Makefile.incl
EXTRA_DIST = boinc.py boinc_db.py version.py.in db_def_to_py
$(srcdir)/boinc_db.py: ../db/boinc_db.h ../lib/result_state.h
cat $^ | $(srcdir)/db_def_to_py > $@
# all: $(srcdir)/boinc_db.py
SUBDIRS = Boinc
......@@ -79,8 +79,9 @@ Start/stop:
The main script is "start"; sym-link or hard-link "start" to "stop".
'''
import boinc_path_config
from Boinc import configxml
import sys, os, getopt, time, glob, fcntl, signal
from boinc_config import *
verbose = os.isatty(sys.stdout.fileno())
verbose_daemon_run = 0
......@@ -557,8 +558,8 @@ for opt,v in opts:
if not command:
raise SystemExit('No command specified and script name is not "start", "stop", or "status"')
config = BoincConfig(config_filename).read()
run_state = BoincRunState(run_state_filename).read(failopen_ok = True)
config = configxml.ConfigFile(config_filename).read()
run_state = configxml.RunStateFile(run_state_filename).read(failopen_ok = True)
project_dir = os.path.realpath(config.config.__dict__.get('project_dir') or
os.path.join(program_path, '../'))
......
......@@ -33,11 +33,11 @@ def read_url(url, quiet=False):
if __name__ == '__main__':
test_msg("framework sanity")
verbose_echo(1, "Checking executables")
check_core_client_executable()
check_app_executable("upper_case")
check_app_executable("concat")
check_app_executable("1sec")
# verbose_echo(1, "Checking executables")
# check_core_client_executable()
# check_app_executable("upper_case")
# check_app_executable("concat")
# check_app_executable("1sec")
verbose_echo(1, "Checking directories")
for d in ['projects_dir',
......
......@@ -7,25 +7,13 @@
# applications and work units, run the system, and verify that the results are
# correct.
#
# See doc/test.html for details
# See doc/test.php for details
# the module MySQLdb can be installed on debian with "apt-get install python2.2-mysqldb"
# TODO: make sure things work if build_dir != src_dir
# TODO: make things work if build_dir != src_dir
import sys
sys.path.append('../py')
try:
from version import *
except ImportError:
raise SystemExit("""testbase.py: Couldn't import version.py
This file is built from py/version.py.in by configure.
Perhaps you did not run configure, or you configured in a different directory,
or you are running from the wrong directory.""")
from boinc import *
import boinc_path_config
from Boinc import version
from Boinc.setup_project import *
import atexit, traceback, signal
import cgiserver
......@@ -37,7 +25,7 @@ def test_init():
options.have_init_t = True
if not os.path.exists('test_uc.py'):
os.chdir(os.path.join(TOP_SRC_DIR,'test'))
os.chdir(os.path.join(boinc_path_config.TOP_SOURCE_DIR,'test'))
if not os.path.exists('test_uc.py'):
raise SystemExit('Could not find boinc_db.py anywhere')
......
......@@ -2,25 +2,6 @@
# $Id$
# The contents of this file are subject to the BOINC Public License
# Version 1.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://boinc.berkeley.edu/license_1.0.txt
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the Berkeley Open Infrastructure for Network Computing.
#
# The Initial Developer of the Original Code is the SETI@home project.
# Portions created by the SETI@home project are Copyright (C) 2002
# University of California at Berkeley. All Rights Reserved.
#
# Contributor(s):
#
'''
add items to the BOINC database.
......@@ -51,11 +32,9 @@ add.py workunit (TODO)
add.py result (TODO) '''
import boinc_path_config
from Boinc import database, db_mid, configxml, util
import sys, os, getopt, md5, time
sys.path.append('../py/')
sys.path.append('../sched')
import database, db_mid, boinc_config
from util import *
config = boinc_config.BoincConfig('../../projects/client_test/config.xml').read()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment