diff --git a/checkin_notes b/checkin_notes index a978f009b8..4b8432de11 100644 --- a/checkin_notes +++ b/checkin_notes @@ -7275,3 +7275,15 @@ David 28 Aug 2009 cs_cmdline.cpp lib/ proxy_info.cpp,h + +David 28 Aug 2009 + - add "appmgr" script for managing apps and versions (from Gabor Gombas) + + doc/manpages/ + appmgr.xml + Makefile.xm + py/Boinc/ + setup_project.py + tools/ + appmgr (new) + pymw_setup (removed) diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am index 6af7629880..9349d4ccf4 100644 --- a/doc/manpages/Makefile.am +++ b/doc/manpages/Makefile.am @@ -13,16 +13,19 @@ if ENABLE_MANAGER endif if ENABLE_SERVER - SERVER_MANS = + SERVER_MANS = appmgr.8 endif man_MANS = $(CLIENT_MANS) $(CLIENTGUI_MANS) $(SERVER_MANS) -SUFFIXES = .xml .1 +SUFFIXES = .xml .1 .8 .xml.1: $(DOCBOOK2X_MAN) $< +.xml.8: + $(DOCBOOK2X_MAN) $< + all-local: $(man_MANS) CLEANFILES = $(man_MANS) diff --git a/doc/manpages/appmgr.xml b/doc/manpages/appmgr.xml new file mode 100644 index 0000000000..375d154eff --- /dev/null +++ b/doc/manpages/appmgr.xml @@ -0,0 +1,640 @@ + +appmgr"> +]> + + + + + Gábor + Gombás + gombasg@sztaki.hu + + August 27, 2009 + + + + &appmgr; + 8 + + + + &appmgr; + Tool to manage applications and platforms + + + + + &appmgr; + list + + + + &appmgr; + add + NAME + DESC + + + + + + + + + + + &appmgr; + delete + NAME + + + + + + &appmgr; + update + NAME + + + + + + + + + + + + + + + + + + + + &appmgr; + update_appver + NAME + + + + + + + + + + + + &appmgr; + list_platform + + + + &appmgr; + add_platform + NAME + DESC + + + &appmgr; + delete_platform + NAME + + + + &appmgr; + update_platform + NAME + + + + + + + + &appmgr; + add_standard_platforms + + + &appmgr; + + + + + + + + + DESCRIPTION + + &appmgr; is a tool to manage platforms, applications and application + versions from the command-line. + + + Note: application refers to data in the + app table; application version + refers to data in the app_version table and in the + file system. + + + + + COMMANDS + + The generic syntax is: + + + + &appmgr; + COMMAND + command arguments + + + + Note that command-specific options must came after the command, never before. + Here is a short list of the available commands. The following sections describe + the commands in detail. + + + + list + + + List the installed applications and application versions. + + + + + add + + + Add a new application. + + + + + delete + + + Delete an application or application version. + + + + + update + + + Update the properties of an application. + + + + + update_appver + + + Update the properties of an application version. + + + + + list_platform + + + List the platforms known to the project. + + + + + add_platform + + + Add a new platform. + + + + + delete_platform + + + Delete a platform. + + + + + update_platform + + + Update the properties of a platform. + + + + + add_standard_platforms + + + Add all standard platforms to the project. + + + + + + + LIST + + List the installed applications and application versions, together with + any non-default properties (beta, deprecated, min. core version etc.). If the + option is specified, then the + list of application versions is omitted and just the application definitions + are listed. + + + + + ADD + + Add a new application. NAME is + the short name of the application as used in the file system. + DESC is the user-friendly name that is + displayed to users. + + + The following options can also be specified: + + + + + , + , + + + + + Set the homogeneous redundancy class. no means + all hosts are equivalent, fine means + fine-grained classification of 80 classes, + coarse means coarse classification of 4 + classes. + + + + + + + + + + Indicate that this is application is in beta testing. Users can select + if they are willing to test applications marked as beta in their + preferences; see the wiki section "Beta-test applications" about + how to enable this on the web interface. + + + + + + + + + + Specify the weight of this application if the feeder is run with + the option. NUM + is a floating-point value, the default is 1. + + + + + + + + + + Set the number of replicas when an otherwise unreplicated work + unit is sent to a host that is not trusted. See the wiki section + "Adaptive replication" for details. + + + + + + + + DELETE + + Delete applications or application versions. This command deletes both the + database records and the files under the download and + apps directories, so use with care. + + + The following options can be specified: + + + + + + + + + Select only application versions with the version number + VER. + The version number must be + specified as major.minor. + + + + + + + + + + Select only application versions for the platform + NAME. + + + + + + + + + + Select only application versions having the plan class + NAME. + + + + + + If more than one of the options , + and are + specified, then only application versions matching all the criteria + are deleted. If none of these options are specified, then the + application is also deleted. Note that if one or more of + these options are specified then the application is not + deleted even if there are no more application versions remaining. + + + + + UPDATE + + Update the properties of an application. The following properties can + be modified: + + + + + , + , + + + + + Set the homogeneous redundancy class. no means + all hosts are equivalent, fine means + fine-grained classification of 80 classes, + coarse means coarse classification of 4 + classes. + + + Do not change the homogeneous redundancy class while there are jobs + in progress! + + + + + + + + + + Indicate that this is application is in beta testing. Users can select + if they are willing to test applications marked as beta in their + preferences; see the wiki about how to enable this on the web interface. + + + + + + + + + + Indicate that the application is no more in beta testing. + + + + + + + + + + Specify the weight of this application if the feeder is run with + the option. NUM + is a floating-point value, the default is 1. + + + + + + + + + + Set the number of replicas when an otherwise unreplicated work + unit is sent to a host that is not trusted. See the wiki article + on "Adaptive replication" for details. + + + + + + + + + + Update the user-friendly description of the application. + + + + + + + + + + Set the min. version of the application that the scheduler accepts. + This is checked only if the client uses the anonymous + platform. + The version number must be + specified as major.minor. + + + + + + + + + + Indicate that the application is deprecated. The feeder will then + ignore this application when looking for new work. + + + + + + + + + + Remove the deprecation mark from the application. + + + + + + + + UPDATE_APPVER + + Update the properties of an application version. The version(s) to operate + on can be specified with the , + and options, as described at the DELETE + command. + + + The following properties can be modified: + + + + + + + + + Set the min. version of the core client that is required to run + this application version. + The version number must be specified as + major.minor. The 3rd component (the patch + level) of the core client version is ignored. + + + + + + + + + + Set the max. version of the core client that is allowed to run + this application. Note that the scheduler ignores this setting currently. + + + + + + + + + + Indicate that the application version is deprecated. The feeder will then + ignore this version when looking for new work. + + + + + + + + + + Remove the deprecation mark from the application version. + + + + + + + + LIST_PLATFORM + + List the platforms known to the project. If the option + is specified, then only the short names of the platforms are listed. + + + + + ADD_PLATFORM + + Add a new platform. NAME is the short name + of the platform that is used in the scheduler requests. + DESC is the user-friendly name that is + displayed to users. + + + + + DELETE_PLATFORM + + Delete a platform. If the option is specified, the + command deletes all application versions for this platform. Otherwise, if there + are such application versions, the command will fail. + + + + + UPDATE_PLATFORM + + Update the properties of a platform. The following properties can be modified: + + + + + + + + + Update the user-friendly description of the platform. + + + + + + + + + + Indicate that the platform is deprecated. The feeder will then + ignore this platform when looking for new work. + + + + + + + + + + Remove the deprecation mark from the platform. + + + + + + + + ADD_STANDARD_PLATFORMS + + Add all the standard platform definitions to the database that do not + exist yet. + + + + + diff --git a/py/Boinc/setup_project.py b/py/Boinc/setup_project.py index 83b4943044..68c6d156e2 100644 --- a/py/Boinc/setup_project.py +++ b/py/Boinc/setup_project.py @@ -363,7 +363,7 @@ sys.path.insert(0, os.path.join('%s', 'py')) 'update_stats', 'db_dump', 'db_purge', 'show_shmem', 'census', 'delete_file', 'request_file_list', 'get_file', 'send_file' ]) map(lambda (s): install(srcdir('tools',s), dir('bin',s)), - [ 'create_work', 'xadd', 'dbcheck_files_exist', 'run_in_ops', + [ 'appmgr', 'create_work', 'xadd', 'dbcheck_files_exist', 'run_in_ops', 'update_versions', 'parse_config', 'grep_logs', 'db_query', 'watch_tcp', 'sign_executable', 'dir_hier_move', 'dir_hier_path' ]) diff --git a/tools/appmgr b/tools/appmgr new file mode 100755 index 0000000000..c82f3f5b0a --- /dev/null +++ b/tools/appmgr @@ -0,0 +1,571 @@ +#! /usr/bin/env python +# +# Written by Gabor Gombas +# Licensed under the same terms as the rest of BOINC. + +""" +Manage applications and platforms from the command line. + +Run "appmgr --help" to list the available commands. +Run "appmgr --help" to get the description of a command. +""" + + +import time, os, re, string +from optparse import OptionParser +from xml.dom.minidom import parseString + +import boinc_path_config +from Boinc import database, db_mid, configxml + +# The list of standard platforms +standard_platforms = { + 'windows_intelx86': 'Microsoft Windows (98 or later) running on an Intel x86-compatible CPU', + 'windows_x86_64': 'Microsoft Windows running on an AMD x86_64 or Intel EM64T CPU', + 'i686-pc-linux-gnu': 'Linux running on an Intel x86-compatible CPU', + 'x86_64-pc-linux-gnu': 'Linux running on an AMD x86_64 or Intel EM64T CPU', + 'powerpc-apple-darwin': 'Mac OS X 10.3 or later running on Motorola PowerPC', + 'i686-apple-darwin': 'Mac OS 10.4 or later running on Intel', + 'x86_64-apple-darwin': 'Intel 64-bit Mac OS 10.5 or later', + 'sparc-sun-solaris2.7': 'Solaris 2.7 running on a SPARC-compatible CPU', + 'sparc-sun-solaris': 'Solaris 2.8 or later running on a SPARC-compatible CPU', + 'sparc64-sun-solaris': 'Solaris 2.8 or later running on a SPARC 64-bit CPU', + 'powerpc64-ps3-linux-gnu': 'Sony Playstation 3 running Linux', + 'anonymous': 'anonymous'} + +def remove_directory(dir): + """Remove a directory and all files inside it.""" + + for file in os.listdir(dir): + os.unlink(os.path.join(dir, file)) + os.rmdir(dir) + +def remove_app_directory(appver, config): + """Remove files for an app version under /apps""" + + appdir = os.path.join(config.app_dir, appver.app.name) + for path in map(lambda file: os.path.join(appdir, file), os.listdir(appdir)): + match = re.match('^[^.]+_([0-9]+)[.]([0-9]+)_([^.]+?(?:[0-9][0-9.]*[0-9])?)(?:__([^.])+)?(?:[.][a-zA-Z0-9\_\-]*)?$', os.path.basename(path)) + if not match: + continue + + major, minor, platform_name, plan_class = match.groups() + version_num = int(major) * 100 + int(minor) + if plan_class is None: + plan_class = '' + + if platform_name != appver.platform.name: + continue + if appver.version_num != version_num: + continue + if appver.plan_class != plan_class: + continue + + if os.path.isdir(path): + remove_directory(path) + else: + os.unlink(path) + + # If all versions are gone, remove the parent directory as well + try: + os.rmdir(appdir) + except: + pass + +def do_delete_app_version(appver): + """Delete both the files and the database entry for an app version.""" + + config = configxml.default_config().config + + # Remove files/directories under app_dir + appdir = os.path.join(config.app_dir, appver.app.name) + if os.path.isdir(appdir): + remove_app_directory(appver, config) + + # Remove files under download_dir + # appver.xml_doc does not have a parent node, so we have to add one + xml = parseString('' + appver.xml_doc + '') + for file in xml.getElementsByTagName('file_info'): + name = '' + for node in file.getElementsByTagName('name')[0].childNodes: + if node.nodeType == node.TEXT_NODE: + name += node.data + if not name: + continue + os.unlink(os.path.join(config.download_dir, name)) + + tmp = str(appver) + appver.remove() + print "Removed " + tmp + +def add_platform(args): + usage = """%prog add_platform + +Add a new platform definition to the database.""" + + parser = OptionParser(usage = usage) + options, extra_args = parser.parse_args(args) + if len(extra_args) != 2: + parser.error("Wrong number of arguments") + + platform = database.Platform(create_time = time.time(), + name = extra_args[0], + user_friendly_name = extra_args[1], + deprecated = 0) + platform.commit() + print "Added " + str(platform) + +def del_platform(args): + usage = """%prog delete_platform + +Deletes a platform from the database. If the --force flag is specified, it also +deletes all application versions for this platform. Otherwise, if there is an +application version available for this platform, the command will fail.""" + + parser = OptionParser(usage = usage) + parser.add_option("-f", "--force", + dest = "force", + action = "store_true", + default = False, + help = "remove any app versions that still exist for this platform") + options, extra_args = parser.parse_args(args) + if len(extra_args) != 1: + parser.error("Wrong number of arguments") + + platforms = database.Platforms.find(name = extra_args[0]) + if len(platforms) < 1: + raise SystemExit("Unknown platform name") + platform = platforms[0] + + # If there are still application versions defined for this platform, then + # either bail out, or if --force was given, blow those application versions + # first + for appver in database.AppVersions.find(platform = platform): + if not options.force: + raise SystemExit("There are still application versions for this " + "platform, bailing out") + do_delete_app_version(appver) + + # The id is gone after .remove(), so we have to save the stringified form + tmp = str(platform) + platform.remove() + print "Deleted " + tmp + +def update_platform(args): + usage = """%prog update_platform [options] + +Update platform data.""" + + parser = OptionParser(usage = usage) + parser.add_option("--deprecated", + action = "store_const", + const = 1, + help = "mark the platform as deprecated") + parser.add_option("--no-deprecated", + dest = "deprecated", + action = "store_const", + const = 0, + help = "remove the deprecation mark") + parser.add_option("--user_friendly_name", + metavar = "DESC", + help = "set the user-friendly name of the platform") + options, extra_args = parser.parse_args(args) + if len(extra_args) != 1: + parser.error("Wrong number of arguments") + + platforms = database.Platforms.find(name = extra_args[0]) + if not platforms: + raise SystemExit("Unknown platform name") + platform = platforms[0] + + if options.deprecated is not None: + platform.deprecated = options.deprecated + if options.user_friendly_name: + platform.user_friendly_name = options.user_friendly_name + platform.commit() + print "Updated " + str(platform) + +def list_platform(args): + usage = """%prog list_platform + +List all defined platforms.""" + + parser = OptionParser(usage = usage) + parser.add_option("--short", + action = "store_true", + help = "show the short names only") + options, extra_args = parser.parse_args(args) + if extra_args: + parser.error("Extra arguments on the command line") + + # Ensure consistent ordering + database.Platforms.select_args = 'ORDER BY name' + for platform in database.Platforms.find(): + if options.short: + print platform.name + else: + desc = platform.name + ": " + platform.user_friendly_name + if platform.deprecated: + desc += " (Deprecated)" + print desc + +def add_standard_platforms(args): + usage = """%prog add_standard_platforms + +Add all standard platform definitions to the database. If some of them +already exist they will not be modified.""" + + parser = OptionParser(usage = usage) + options, extra_args = parser.parse_args(args) + if extra_args: + parser.error("Extra arguments on the command line") + + for name in standard_platforms.keys(): + if database.Platforms.find(name = name): + continue + platform = database.Platform(create_time = time.time(), + name = name, + user_friendly_name = standard_platforms[name], + deprecated = 0) + platform.commit() + print "Added " + str(platform) + +def add_app(args): + usage = """%prog add [options] + +Register a new application in the database.""" + + hr_types = { 'no': 0, 'fine': 1, 'coarse': 2} + + parser = OptionParser(usage = usage) + parser.add_option("--hr", + choices = hr_types.keys(), + default = "no", + metavar = "(no|fine|coarse)", + help = "set the homogeneous redundancy type") + parser.add_option("--beta", + action = "store_const", + default = 0, + const = 1, + help = "the application is still in beta testing, and only " + "users participating in the test program will run it") + parser.add_option("--weight", + type = "float", + default = 1, + metavar = "NUM", + help = "set the weight of the application when application " + "interleaving is enabled in the feeder") + parser.add_option("--target_nresults", + type = "int", + default = 0, + metavar = "NUM", + help = "default number of replicas for adaptive replication") + options, extra_args = parser.parse_args(args) + if len(extra_args) != 2: + parser.error("Wrong number of arguments") + + app = database.App(create_time = time.time(), + name = extra_args[0], + min_version = 0, + deprecated = 0, + user_friendly_name = extra_args[1], + homogeneous_redundancy = hr_types[options.hr], + weight = options.weight, + beta = options.beta, + target_nresults = options.target_nresults) + try: + app.commit() + except Exception, e: + print "Failed to add application" + return + + print "Added " + str(app) + +def del_app(args): + usage = """%prog delete [options] + +Delete application versions. This command deletes the matching database +entries and all corresponding files under /apps and +/download. If more than one of the --version, --platform and +--plan_class options are specified, they are AND'ed together. If no +version/platform/plan class options are given, all versions of the application +are deleted and the application is removed from the 'app' table as well.""" + + parser = OptionParser(usage = usage) + parser.add_option("--version", + type = "float", + metavar = "VER", + help = "delete versions with the given version number") + parser.add_option("--platform", + metavar = "NAME", + help = "delete versions for the given platform") + parser.add_option("--plan_class", + metavar = "NAME", + help = "delete versions for the given plan class") + options, extra_args = parser.parse_args(args) + if len(extra_args) != 1: + parser.error("Wrong number of arguments") + + apps = database.Apps.find(name = extra_args[0]) + if not apps: + raise SystemExit("No such application") + app = apps[0] + + kwargs = { 'app': app } + if options.version: + kwargs['version_num'] = int(options.version * 100) + if options.platform: + platforms = database.Platforms.find(name = options.platform) + if not platforms: + raise SystemExit("Unknown platform name") + kwargs['platform'] = platforms[0] + if options.plan_class: + kwargs['plan_class'] = options.plan_class + + for appver in database.AppVersions.find(**kwargs): + do_delete_app_version(appver) + + # If the user requested to remove all versions, then remove the entry + # from the 'app' table as well + if not options.version and not options.platform and not options.plan_class: + tmp = str(app) + app.remove() + print "Removed " + tmp + +def update_app(args): + usage = """%prog update [options] + +Update the properties of the given application.""" + + hr_types = { 'no': 0, 'fine': 1, 'coarse': 2} + + parser = OptionParser(usage = usage) + parser.add_option("--hr", + choices = hr_types.keys(), + default = "no", + metavar = "(no|fine|coarse)", + help = "set the homogeneous redundancy type") + parser.add_option("--beta", + action = "store_const", + const = 1, + help = "the application is still in beta testing, and only " + "users participating in the test program will run it") + parser.add_option("--no-beta", + action = "store_const", + dest = "beta", + const = 0, + help = "the application is no more in beta testing") + parser.add_option("--weight", + type = "float", + metavar = "NUM", + help = "set the weight of the application when application " + "interleaving is enabled in the feeder") + parser.add_option("--target_nresults", + type = "int", + metavar = "NUM", + help = "default number of replicas for adaptive replication") + parser.add_option("--user_friendly_name", + metavar = "DESC", + help = "set the user-friendly description of the application") + parser.add_option("--min_version", + type = "float", + metavar = "VER", + help = "set the minimum app version clients allowed to use") + parser.add_option("--deprecated", + action = "store_const", + const = 1, + help = "mark the application as deprecated") + parser.add_option("--no-deprecated", + dest = "deprecated", + action = "store_const", + const = 0, + help = "remove the deprecation mark") + options, extra_args = parser.parse_args(args) + if len(extra_args) != 1: + parser.error("Wrong number of arguments") + + apps = database.Apps.find(name = extra_args[0]) + if not apps: + raise SystemExit("No such application") + app = apps[0] + + if options.hr is not None: + app.homogeneous_redundancy = hr_types[options.hr] + if options.beta is not None: + app.beta = options.beta + if options.weight is not None: + app.weight = options.weight + if options.target_nresults is not None: + app.target_nresults = options.target_nresults + if options.user_friendly_name: + app.user_friendly_name = options.user_friendly_name + if options.min_version is not None: + app.min_version = int(options.min_version * 100) + if options.deprecated is not None: + app.deprecated = options.deprecated + + app.commit() + print "Updated " + str(app) + +def list_app(args): + usage = """%prog list + +List all applications and application versions.""" + + parser = OptionParser(usage = usage) + parser.add_option("--no-versions", + action = "store_true", + default = False, + help = "do not list application versions") + options, extra_args = parser.parse_args(args) + if extra_args: + parser.error("Extra arguments on the command line") + + # Ensure consistent ordering for the output + database.Apps.select_args = 'ORDER BY name' + # It would be nice to order by platform name... + database.AppVersions.select_args = 'ORDER BY version_num, platformid, plan_class' + + hr_classes = {0: 'No', 1: 'Fine-grained', 2: 'Coarse'} + + for app in database.Apps.find(): + title = app.name + ": " + app.user_friendly_name + print title + print "-" * len(title) + + props = [] + if app.deprecated: + props.append("Deprecated.") + if app.beta: + props.append("Beta.") + if app.min_version: + props.append("Min. version: %.2f." % (float(app.min_version) / 100)) + props.append(hr_classes[app.homogeneous_redundancy] + + ' homogeneous redundancy.') + props.append("Weight %g." % app.weight) + if app.target_nresults: + props.append(str(app.target_nresults) + " adaptive replicas.") + print string.join(props, ' ') + + if options.no_versions: + print + continue + + print "Versions:\n" + for appver in database.AppVersions.find(app = app): + desc = "\t%5.2f" % (float(appver.version_num) / 100) + desc += " " + appver.platform.name + props = [] + if appver.plan_class: + props.append("Plan: " + appver.plan_class + ".") + if appver.deprecated: + props.append("Deprecated.") + if appver.min_core_version: + props.append("Min. core version: %g." % \ + (float(appver.min_core_version) / 100)) + if appver.max_core_version: + props.append("Max. core version: %g." % \ + (float(appver.max_core_version) / 100)) + if props: + desc += " (" + string.join(props, ' ') + ')' + print desc + print + +def update_appver(args): + usage = """%prog update_appver [options] + +Update the properties of the given application version(s). If none +of the --version, --platform, --plan_class options are specified, +then all versions for the given application are updated.""" + + parser = OptionParser(usage = usage) + parser.add_option("--version", + type = "float", + metavar = "VER", + help = "update just the given version number") + parser.add_option("--platform", + metavar = "NAME", + help = "update just the given platform") + parser.add_option("--plan_class", + metavar = "NAME", + help = "update just the given plan class") + parser.add_option("--min_core_version", + type = "float", + metavar = "VER", + help = "set the minimum usable core client version") + parser.add_option("--max_core_version", + type = "float", + metavar = "VER", + help = "set the maximum usable core client version") + parser.add_option("--deprecated", + action = "store_const", + const = 1, + help = "mark this version as deprecated") + parser.add_option("--no-deprecated", + dest = "deprecated", + action = "store_const", + const = 0, + help = "remove the deprecation mark") + options, extra_args = parser.parse_args(args) + if len(extra_args) != 1: + parser.error("Wrong number of arguments") + + apps = database.Apps.find(name = extra_args[0]) + if not apps: + raise SystemExit("No such application") + app = apps[0] + + kwargs = { 'app': app } + if options.version: + kwargs['version_num'] = int(options.version * 100) + if options.platform: + platforms = database.Platforms.find(name = options.platform) + if not platforms: + raise SystemExit("Unknown platform name") + kwargs['platform'] = platforms[0] + if options.plan_class: + kwargs['plan_class'] = options.plan_class + + for appver in database.AppVersions.find(**kwargs): + if options.deprecated is not None: + appver.deprecated = options.deprecated + if options.min_core_version is not None: + appver.min_core_version = int(options.min_core_version * 100) + if options.max_core_version is not None: + appver.max_core_version = int(options.max_core_version * 100) + appver.commit() + print "Updated " + str(appver) + +command_table = { + 'add': add_app, + 'delete': del_app, + 'update': update_app, + 'list': list_app, + 'update_appver': update_appver, + 'add_platform': add_platform, + 'delete_platform': del_platform, + 'update_platform': update_platform, + 'list_platform': list_platform, + 'add_standard_platforms': add_standard_platforms} + +usage = """%%prog [global options] [command arguments] + +Available commands: + +%s + +Use "%%prog --help" to get a description of the command.""" % \ + string.join(map(lambda x: "\t" + x, sorted(command_table.keys())), "\n") + +parser = OptionParser(usage=usage) +parser.disable_interspersed_args() + +global_options, args = parser.parse_args() +if not args: + parser.error("Command is not provided") +if not args[0] in command_table: + parser.error("Unknown command " + args[0]) + +database.connect() + +command_table[args[0]](args[1:]) diff --git a/tools/pymw_setup b/tools/pymw_setup deleted file mode 100644 index f3a7f15d02..0000000000 --- a/tools/pymw_setup +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python -try: - import boinc_path_config - from Boinc import configxml, projectxml -except: - import configxml, projectxml -from optparse import OptionParser -import os, logging, sys, stat - -LINUX_WORKER = """\ -#!/bin/sh -`python $1 $2 $3` -`touch boinc_finish_called` -""" - -WINDOWS_WORKER = """\ -@echo off -set _path=%path% -set _python=%_path:*python=python% -set _python=%_python:~0,6% -if %_python% neq python set PATH=%path%;C:\python25 -python %1 %2 %s3 -type nul > boinc_finish_called -""" - -PYMW_APP = """\ -import sys -import cPickle - -def pymw_get_input(): - infile = open(sys.argv[1], 'r') - obj = cPickle.Unpickler(infile).load() - infile.close() - return obj - -def pymw_return_output(output): - outfile = open(sys.argv[2], 'w') - cPickle.Pickler(outfile).dump(output) - outfile.close() -""" - -FILE_REF = """\ - -""" - -parser = OptionParser(usage="usage: %prog") -parser.add_option("-p", "--pymw_dir", dest="pymw_dir", default="", help="specify the working directory of pymw", metavar="") -options, args = parser.parse_args() - -logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") - -pymw_dir = options.pymw_dir - -if pymw_dir == "": - logging.error("py_mw working directory have to be provided (-p switch)") - sys.exit(0) -elif not os.path.exists(pymw_dir): - logging.error(pymw_dir + " does not exist") - sys.exit(0) - -logging.info("pymw working directory set to " + pymw_dir) - -logging.info("writing pymw_assimilator in config.xml") -config = configxml.ConfigFile().read() - -# Remove old instances of pymw_assimilator -for daemon in config.daemons: - if daemon.cmd[0:16] == 'pymw_assimilator': - config.daemons.remove_node(daemon) - -# Append new instance of pymw_assimilator to config.xml -config.daemons.make_node_and_append("daemon").cmd = "pymw_assimilator -d 3 -app pymw -pymw_dir " + pymw_dir -config.write() - -# Append new instance of pymw worker to project.xml -project = projectxml.ProjectFile().read() -found = False -for element in project.elements: - if element.name == 'pymw': - logging.info("PyMW client applications are already installed") - sys.exit(0) - -project.elements.make_node_and_append("app").name = "pymw" -project.write() -for element in project.elements: - if element.name == "pymw": - element.user_friendly_name = "PyMW - Master Worker Computing in Python" - project.write() - -# Install worker applications -app_dir = os.path.join(config.config.app_dir, "pymw") -print app_dir -if os.path.isdir(app_dir): - logging.info("PyMW client applications are already installed") -else: - os.mkdir(app_dir) - # Linux - logging.info("setting up client application for Linux platform") - linux_dir = os.path.join(app_dir, "pymw_1.00_i686-pc-linux-gnu") - linux_exe = os.path.join(linux_dir, "pymw_1.00_i686-pc-linux-gnu") - os.mkdir(linux_dir) - open(linux_exe, "w").writelines(LINUX_WORKER) - open(os.path.join(linux_dir, "pymw_1.00_i686-pc-linux-gnu.file_ref_info"), "w").writelines(FILE_REF) - open(os.path.join(linux_dir, "pymw_app.py"), "w").writelines(PYMW_APP) - open(os.path.join(linux_dir, "pymw_app.py.file_ref_info"), "w").writelines(FILE_REF) - os.chmod(linux_exe, stat.S_IRWXU) - logging.info("client application for Linux platform set up successfully") - - # Windows - logging.info("setting up client application for Windows platform") - win_dir = os.path.join(app_dir, "pymw_1.00_windows_intelx86") - win_exe = os.path.join(win_dir, "pymw_1.00_windows_intelx86.exe") - os.mkdir(win_dir) - open(win_exe, "w").writelines(WINDOWS_WORKER) - open(os.path.join(win_dir, "pymw_1.00_windows_intelx86.exe.file_ref_info"), "w").writelines(FILE_REF) - open(os.path.join(win_dir, "pymw_app.py"), "w").writelines(PYMW_APP) - open(os.path.join(win_dir, "pymw_app.py.file_ref_info"), "w").writelines(FILE_REF) - os.chmod(win_exe, stat.S_IRWXU) - logging.info("client application for Windows platform set up successfully") - - # Call update_versions - project_home = config.config.app_dir.rpartition('/')[0] - os.chdir(project_home) - os.system("xadd") - os.system("update_versions") -logging.info("---------------------") -logging.info("PyMW setup successful") -logging.info("---------------------")