diff --git a/doc/projects.inc b/doc/projects.inc index e7b0df51e6..7007511539 100644 --- a/doc/projects.inc +++ b/doc/projects.inc @@ -379,7 +379,7 @@ $astro_phys_chem = array( // ), array( "LHC@home", - "http://lhcathomeclassic.cern.ch/sixtrack/", + "http://lhcathome.cern.ch/", tra("CERN (European Organization for Nuclear Research)"), tra("Physics"), tra("The Large Hadron Collider (LHC) is a particle accelerator at CERN, the European Organization for Nuclear Research, the world's largest particle physics laboratory. It is the most powerful instrument ever built to investigate on particles proprieties. LHC@home runs simulations to improve the design of LHC and its detectors."), diff --git a/gl.py b/gl.py new file mode 100644 index 0000000000..d9eb531a39 --- /dev/null +++ b/gl.py @@ -0,0 +1,16 @@ +# This file is part of BOINC. +# http://boinc.berkeley.edu +# Copyright (C) 2016 University of California +# +# BOINC is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# +# BOINC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with BOINC. If not, see . diff --git a/lib/submit_api.py b/lib/submit_api.py new file mode 100644 index 0000000000..884e6df084 --- /dev/null +++ b/lib/submit_api.py @@ -0,0 +1,183 @@ +# Python bindings of remote job submission and file management APIs + +import urllib +import copy +import xml.etree.ElementTree as ET + +# represents an input file +# +class FILE_DESC: + def __init__(self): + return + def to_xml(self): + xml = ('\n' + '%s\n' + ) %(self.mode) + if self.mode == 'remote': + xml += ('%s\n' + '%f\n' + '%s\n' + ) %(self.url, self.nbytes, self.md5) + else: + xml += '%s\n' %(self.source) + xml += '\n' + return xml + +# represents a job +# +class JOB_DESC: + def __init__(self): + return + def to_xml(self): + xml = ('\n' + '%f\n' + '%s\n' + ) %(self.rsc_fpops_est, self.command_line) + for file in self.files: + xml += file.to_xml() + xml += '\n'; + return xml + +# represents a batch description for submit() or estimate() +# +class BATCH_DESC: + def __init__(self): + return + + # convert to XML + # + def to_xml(self, op): + xml = ('<%s>\n' + '%s\n' + '\n' + '%s\n' + '%s\n' + ) %(op, self.authenticator, self.app_name, self.batch_name) + for job in self.jobs: + xml += job.to_xml() + xml += '\n\n' %(op) + return xml + +# a generic request +# +class REQUEST: + def __init__(self): + return + +def do_http_post(req, project_url): + url = project_url + 'submit_rpc_handler.php' + params = urllib.urlencode({'request': req}) + f = urllib.urlopen(url, params) + reply = f.read() + print reply + r = ET.fromstring(reply) + return r[0] + +def estimate_batch(req): + return do_http_post(req.to_xml('estimate_batch'), req.project) + +def submit_batch(req): + return do_http_post(req.to_xml('submit_batch'), req.project) + +def query_batches(req): + req_xml = ('\n' + '%s\n' + '%d\n' + '\n' + ) %(req.authenticator, 1 if req.get_cpu_time else 0) + return do_http_post(req_xml, req.project) + +def query_batch(req): + req_xml = ('\n' + '%s\n' + '%s\n' + '%d\n' + '\n' + ) %(req.authenticator, req.batch_id, 1 if req.get_cpu_time else 0) + return do_http_post(req_xml, req.project) + +def query_job(req): + req_xml = ('\n' + '%s\n' + '%s\n' + '\n' + ) %(req.authenticator, req.job_id) + return do_http_post(req_xml, req.project) + +def abort_batch(req): + req_xml = ('\n' + '%s\n' + '%s\n' + '\n' + ) %(req.authenticator, req.batch_id) + return do_http_post(req_xml, req.project) + +def get_output_file(req): + auth_str = md5.new(req.authenticator+req.instance_name).digest() + name = req.instance_name + file_num = req.file_num + return project_url+"/get_output.php?cmd=result_file&result_name=%s&file_num=%s&auth_str=%s"%(name, file_num, auth_str); + +def get_output_files(req): + auth_str = md5.new(req.authenticator+req.batch_id).digest() + return project_url+"/get_output.php?cmd=batch_files&batch_id=%s&auth_str=%s"%(req.batch_id, auth_str) + + +def retire_batch(req): + req_xml = ('\n' + '%s\n' + '%s\n' + '\n' + ) %(req.authenticator, req.batch_id) + return do_http_post(req_xml, project_url) + +def query_files(req): + return do_http_post(req_xml, project_url) + +def upload_files(req): + return do_http_post(req_xml, project_url) + +def test_estimate(): + file = FILE_DESC() + file.mode = 'remote' + file.url = 'http://isaac.ssl.berkeley.edu/validate_logic.txt' + file.md5 = "eec5a142cea5202c9ab2e4575a8aaaa7" + file.nbytes = 4250; + + job = JOB_DESC() + job.files = [file] + + batch = BATCH_DESC() + batch.project = 'http://isaac.ssl.berkeley.edu/test/' + batch.authenticator = "157f96a018b0b2f2b466e2ce3c7f54db" + batch.app_name = "uppercase" + batch.batch_name = "blah" + batch.jobs = [] + + for i in range(3): + job.rsc_fpops_est = i*1e9 + job.command_line = '-i %s' %(i) + batch.jobs.append(copy.copy(job)) + + #print batch.to_xml("submit") + r = estimate_batch(batch) + print ET.tostring(r) + +def test_query_batches(): + req = REQUEST() + req.project = 'http://isaac.ssl.berkeley.edu/test/' + req.authenticator = "157f96a018b0b2f2b466e2ce3c7f54db" + req.get_cpu_time = True + r = query_batches(req) + print ET.tostring(r) + +def test_query_batch(): + req = REQUEST() + req.project = 'http://isaac.ssl.berkeley.edu/test/' + req.authenticator = "157f96a018b0b2f2b466e2ce3c7f54db" + req.batch_id = 101 + req.get_cpu_time = True + r = query_batch(req) + print ET.tostring(r) + +test_query_batch() diff --git a/tools/submit_api_test.py b/tools/submit_api_test.py new file mode 100644 index 0000000000..755e0f1407 --- /dev/null +++ b/tools/submit_api_test.py @@ -0,0 +1,79 @@ +# This file is part of BOINC. +# http://boinc.berkeley.edu +# Copyright (C) 2016 University of California +# +# BOINC is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# +# BOINC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with BOINC. If not, see . + +# test code for submit_api.py + +from submit_api import * + +# read auth from a file so we don't have to including it here +# +def get_auth(): + with open("test_auth", "r") as f: + return (f.readline()).strip() + +def make_batch(): + file = FILE_DESC() + file.mode = 'remote' + file.url = 'http://isaac.ssl.berkeley.edu/validate_logic.txt' + file.md5 = "eec5a142cea5202c9ab2e4575a8aaaa7" + file.nbytes = 4250 + + job = JOB_DESC() + job.files = [file] + + batch = BATCH_DESC() + batch.project = 'http://isaac.ssl.berkeley.edu/test/' + batch.authenticator = get_auth() + batch.app_name = "uppercase" + batch.batch_name = "blah" + batch.jobs = [] + + for i in range(3): + job.rsc_fpops_est = i*1e9 + job.command_line = '-i %s' %(i) + batch.jobs.append(copy.copy(job)) + + return batch + +def test_estimate(): + batch = make_batch() + #print batch.to_xml("submit") + r = estimate_batch(batch) + #print ET.tostring(r) + if r.tag == 'error': + print 'error: ', r.find('error_msg').text + else: + print 'estimated time: ', r.text, ' seconds' + +def test_query_batches(): + req = REQUEST() + req.project = 'http://isaac.ssl.berkeley.edu/test/' + req.authenticator = get_auth() + req.get_cpu_time = True + r = query_batches(req) + print ET.tostring(r) + +def test_query_batch(): + req = REQUEST() + req.project = 'http://isaac.ssl.berkeley.edu/test/' + req.authenticator = get_auth() + req.batch_id = 101 + req.get_cpu_time = True + r = query_batch(req) + print ET.tostring(r) + +test_estimate()