From 690ca819de8b6f114a8c52ef69efceaa94efd787 Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Wed, 10 Aug 2005 07:36:28 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'GLITE_RELEASE_1_3'. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Sprout from master 2004-12-10 13:01:20 UTC Aleš Křenek 'imported statistics counting' Cherrypick from master 2005-06-10 09:43:14 UTC Andrew McNab 'Tidy up for tag': org.glite.deployment.lb/build.xml org.glite.deployment.lb/doc/release_notes/release_notes.doc org.glite.deployment.lb/doc/release_notes/release_notes.html org.glite.deployment.lb/doc/release_notes/release_notes.pdf org.glite.deployment.lb/project/lxscript-rpm.xsl org.glite.security.gsoap-plugin/LICENSE org.glite.security.gsoap-plugin/examples/calc.h.S org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c org.glite.security.gsoap-plugin/interface/glite_gsplugin.h org.glite.security.gsoap-plugin/interface/glite_gss.h org.glite.security.gsoap-plugin/project/build.properties org.glite.security.gsoap-plugin/project/properties.xml org.glite.security.gsoap-plugin/project/tar_exclude org.glite.security.gsoap-plugin/src/glite_gss.c org.gridsite.core/CHANGES org.gridsite.core/VERSION org.gridsite.core/build.xml org.gridsite.core/doc/config.html org.gridsite.core/doc/gsexec.8 org.gridsite.core/doc/httpd-fileserver.conf org.gridsite.core/doc/httpd-webserver.conf org.gridsite.core/interface/gridsite.h org.gridsite.core/project/build.number org.gridsite.core/project/configure.properties.xml org.gridsite.core/project/version.properties org.gridsite.core/src/Makefile org.gridsite.core/src/gridsite.spec org.gridsite.core/src/grst-delegation.c org.gridsite.core/src/grst_admin_file.c org.gridsite.core/src/grst_admin_gacl.c org.gridsite.core/src/grst_admin_main.c org.gridsite.core/src/grst_asn1.c org.gridsite.core/src/grst_gacl.c org.gridsite.core/src/grst_x509.c org.gridsite.core/src/grst_xacml.c org.gridsite.core/src/gsexec.c org.gridsite.core/src/gsexec.h org.gridsite.core/src/htcp org.gridsite.core/src/mod_gridsite.c org.gridsite.core/src/showx509exts.c org.gridsite.core/src/xacmlexample.c Cherrypick from master 2005-07-08 13:18:40 UTC Alberto Di Meglio 'Merged from branch 1.2.2': org.glite.deployment.lb/LICENSE org.glite.deployment.lb/project/properties.xml Cherrypick from master 2005-02-15 09:29:04 UTC Jiří Škrábal '- files lb_gss.* renamed to glite_gss.*': org.glite.security.gsoap-plugin/test/test_gss.cpp Cherrypick from glite-lb-client-interface_branch_1_0_0 2005-04-13 11:41:09 UTC Jiří Škrábal '- do not distribute fake library header files': org.glite.lb.client-interface/Makefile org.glite.lb.client-interface/build.xml org.glite.lb.client-interface/interface/CountRef.h org.glite.lb.client-interface/interface/Event.h.T org.glite.lb.client-interface/interface/Job.h org.glite.lb.client-interface/interface/JobStatus.h.T org.glite.lb.client-interface/interface/LoggingExceptions.h org.glite.lb.client-interface/interface/Notification.h org.glite.lb.client-interface/interface/ServerConnection.h org.glite.lb.client-interface/interface/consumer.h org.glite.lb.client-interface/interface/context.h org.glite.lb.client-interface/interface/events.h.T org.glite.lb.client-interface/interface/jobstat.h.T org.glite.lb.client-interface/interface/notification.h org.glite.lb.client-interface/interface/notifid.h org.glite.lb.client-interface/interface/producer.h.T org.glite.lb.client-interface/interface/statistics.h org.glite.lb.client-interface/project/build.number org.glite.lb.client-interface/project/configure.properties.xml org.glite.lb.client-interface/project/version.properties Cherrypick from glite-lb-client_branch_1_0_0 2005-07-07 17:22:40 UTC Aleš Křenek 'fix for double connection close crash': org.glite.lb.client/Makefile org.glite.lb.client/build.xml org.glite.lb.client/doc/README-acl org.glite.lb.client/doc/README-fake org.glite.lb.client/doc/README-notify org.glite.lb.client/examples/abort_job.c org.glite.lb.client/examples/change_acl.c org.glite.lb.client/examples/job_log.c org.glite.lb.client/examples/job_log_fake.cpp org.glite.lb.client/examples/job_status.c org.glite.lb.client/examples/producer_fake.c org.glite.lb.client/examples/purge_test org.glite.lb.client/project/build.number org.glite.lb.client/project/version.properties org.glite.lb.client/src/ServerConnection.cpp org.glite.lb.client/src/connection.c org.glite.lb.client/src/logevent.c.T org.glite.lb.client/src/producer.c org.glite.lb.client/src/uiwrap.c.T Cherrypick from glite-security-proxyrenewal_branch_1_0_0_RC1 2005-04-08 02:14:05 UTC Master Builder 'Incremented build number [GLBUILDER]': org.glite.security.proxyrenewal/Makefile org.glite.security.proxyrenewal/build.xml org.glite.security.proxyrenewal/config/startup org.glite.security.proxyrenewal/interface/renewal.h org.glite.security.proxyrenewal/project/build.number org.glite.security.proxyrenewal/project/version.properties org.glite.security.proxyrenewal/src/acstack.h org.glite.security.proxyrenewal/src/api.c org.glite.security.proxyrenewal/src/commands.c org.glite.security.proxyrenewal/src/common.c org.glite.security.proxyrenewal/src/newformat.h org.glite.security.proxyrenewal/src/renew.c org.glite.security.proxyrenewal/src/renewal_locl.h org.glite.security.proxyrenewal/src/renewd.c org.glite.security.proxyrenewal/src/renewd_locl.h org.glite.security.proxyrenewal/src/voms.c Cherrypick from glite-lb-common_branch_1_1_0 2005-07-07 17:20:50 UTC Aleš Křenek 'fix for double connection close crash': org.glite.lb.common/Makefile org.glite.lb.common/build.xml org.glite.lb.common/interface/lb_gss.h org.glite.lb.common/project/build.number org.glite.lb.common/project/version.properties org.glite.lb.common/src/context.c org.glite.lb.common/src/events.c.T org.glite.lb.common/src/il_log.c org.glite.lb.common/src/lb_gss.c org.glite.lb.common/src/param.c Cherrypick from glite-lb-server_branch_1_0_0 2005-06-08 05:24:47 UTC Master Builder 'Incremented build number [GLBUILDER]': org.glite.lb.server/Makefile org.glite.lb.server/build.xml org.glite.lb.server/project/build.number org.glite.lb.server/project/configure.properties.xml org.glite.lb.server/project/version.properties org.glite.lb.server/src/dump.c org.glite.lb.server/src/notification.c org.glite.lb.server/src/server_state.c org.glite.lb.server/src/srv_purge.c org.glite.lb.server/src/store.c.T Cherrypick from glite-lb-logger_branch_1_0_0 2005-07-07 06:30:51 UTC Master Builder 'Incremented build number [GLBUILDER]': org.glite.lb.logger/build.xml org.glite.lb.logger/project/build.number org.glite.lb.logger/project/version.properties org.glite.lb.logger/src/event_queue.c org.glite.lb.logger/src/event_store.c org.glite.lb.logger/src/il_master.c org.glite.lb.logger/src/interlogd.h org.glite.lb.logger/src/logd_proto.c org.glite.lb.logger/src/queue_thread.c Cherrypick from glite-security-gsoap-plugin_branch_1_1_0 2005-06-02 11:00:51 UTC Jiří Škrábal '- clean connection on unsuccessfull connect': org.glite.security.gsoap-plugin/Makefile org.glite.security.gsoap-plugin/build.xml org.glite.security.gsoap-plugin/project/build.number org.glite.security.gsoap-plugin/project/configure.properties.xml org.glite.security.gsoap-plugin/project/version.properties org.glite.security.gsoap-plugin/src/glite_gsplugin.c org.glite.security.gsoap-plugin/src/stdsoap2_2.6.2.c Cherrypick from glite-deployment-lb_branch_2_0_0 2005-07-22 09:14:26 UTC Master Builder 'Incremented build number [GLBUILDER]': org.glite.deployment.lb/CHANGELOG org.glite.deployment.lb/config/scripts/glite-lb-config.py org.glite.deployment.lb/config/templates/glite-lb.cfg.xml org.glite.deployment.lb/project/build.number org.glite.deployment.lb/project/version.properties Cherrypick from glite-deployment-lb_branch_2_0_0 2005-08-10 07:36:27 UTC Robert Harakaly 'fixed myproxy and gpt tokens to be correctly replaced': org.glite.deployment.lb/project/glite-lb.sdf.xml.template Cherrypick from glite-lb-ws-interface_branch_1_0_0 2005-04-03 16:29:31 UTC Alberto Di Meglio 'Increased revision number': org.glite.lb.ws-interface/Makefile org.glite.lb.ws-interface/build.xml org.glite.lb.ws-interface/project/build.number org.glite.lb.ws-interface/project/version.properties org.glite.lb.ws-interface/src/LB.xml.T org.glite.lb.ws-interface/src/puke-ug.xsl Cherrypick from glite-lb_branch_1_0_0_RC1 2005-07-07 17:31:17 UTC Aleš Křenek 'Tagged dependencies properties file [GLBUILDER]': org.glite.lb/build.xml org.glite.lb/project/build.number org.glite.lb/project/dependencies.properties org.glite.lb/project/events.T org.glite.lb/project/types.T org.glite.lb/project/version.properties Cherrypick from glite-wms-utils-exception_branch_1_0_0 2005-07-28 13:55:08 UTC Giuseppe Avellino 'updating version': org.glite.wms-utils.exception/build.xml org.glite.wms-utils.exception/configure.ac org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h org.glite.wms-utils.exception/project/build.number org.glite.wms-utils.exception/project/version.properties org.glite.wms-utils.exception/src/Exception.cpp Cherrypick from glite-lb-server-bones_branch_1_0_0 2005-04-14 14:02:40 UTC Aleš Křenek 'do not distribute srvbones.h (Makefile rev. 1.5.2.1)': org.glite.lb.server-bones/Makefile org.glite.lb.server-bones/build.xml org.glite.lb.server-bones/project/build.number org.glite.lb.server-bones/project/version.properties Cherrypick from glite-wms-utils-jobid_branch_1_0_0 2005-04-03 01:12:39 UTC Master Builder 'Incremented build number [GLBUILDER]': org.glite.wms-utils.jobid/build.xml org.glite.wms-utils.jobid/project/build.number org.glite.wms-utils.jobid/project/version.properties Delete: org.glite.deployment.lb/project/glite-lb.spec org.glite.jp.common/.cvsignore org.glite.jp.common/Makefile org.glite.jp.common/build.xml org.glite.jp.common/interface/context.h org.glite.jp.common/interface/strmd5.h org.glite.jp.common/interface/types.h org.glite.jp.common/project/build.properties org.glite.jp.common/project/configure.properties.xml org.glite.jp.common/project/properties.xml org.glite.jp.common/project/tar_exclude org.glite.jp.common/project/version.properties org.glite.jp.common/src/context.c org.glite.jp.common/src/strmd5.c org.glite.jp.index/.cvsignore org.glite.jp.index/Makefile org.glite.jp.index/build.xml org.glite.jp.index/project/JobProvenanceIS.wsdl org.glite.jp.index/project/build.properties org.glite.jp.index/project/configure.properties.xml org.glite.jp.index/project/properties.xml org.glite.jp.index/project/tar_exclude org.glite.jp.index/project/version.properties org.glite.jp.index/src/simple_server.c org.glite.jp.index/src/soap_ops.c org.glite.jp.index/src/typemap.dat org.glite.jp.primary/.cvsignore org.glite.jp.primary/Makefile org.glite.jp.primary/build.xml org.glite.jp.primary/examples/jpps-test.c org.glite.jp.primary/project/build.properties org.glite.jp.primary/project/configure.properties.xml org.glite.jp.primary/project/properties.xml org.glite.jp.primary/project/tar_exclude org.glite.jp.primary/project/version.properties org.glite.jp.primary/src/backend.h org.glite.jp.primary/src/feed.c org.glite.jp.primary/src/feed.h org.glite.jp.primary/src/ftp_backend.c org.glite.jp.primary/src/is_client.c org.glite.jp.primary/src/jptype_map.h org.glite.jp.primary/src/simple_server.c org.glite.jp.primary/src/soap_ops.c org.glite.jp.primary/src/tags.c org.glite.jp.primary/src/tags.h org.glite.jp.primary/src/typemap.dat org.glite.jp.ws-interface/.cvsignore org.glite.jp.ws-interface/LICENSE org.glite.jp.ws-interface/Makefile org.glite.jp.ws-interface/build.xml org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl org.glite.jp.ws-interface/interface/JobProvenancePS.wsdl org.glite.jp.ws-interface/interface/JobProvenanceTypes.wsdl org.glite.jp.ws-interface/project/build.properties org.glite.jp.ws-interface/project/configure.properties.xml org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec org.glite.jp.ws-interface/project/properties.xml org.glite.jp.ws-interface/project/tar_exclude org.glite.jp.ws-interface/project/version.properties org.glite.jp/.cvsignore org.glite.jp/build.xml org.glite.jp/project/build.properties org.glite.jp/project/dependencies.properties org.glite.jp/project/glite.jp.csf.xml org.glite.jp/project/properties.xml org.glite.jp/project/run-workspace org.glite.jp/project/taskdefs.xml org.glite.jp/project/version.properties org.glite.lb.client/examples/log_usertag_proxy.c org.gridsite.core/src/real-gridsite-admin.cgi --- org.glite.deployment.lb/CHANGELOG | 29 + .../LICENSE | 138 +- org.glite.deployment.lb/build.xml | 6 + .../config/scripts/glite-lb-config.py | 407 +- .../config/templates/glite-lb.cfg.xml | 117 +- .../doc/release_notes/release_notes.doc | Bin 172032 -> 267264 bytes .../doc/release_notes/release_notes.html | 2316 ++-- .../doc/release_notes/release_notes.pdf | Bin 34870 -> 217944 bytes org.glite.deployment.lb/project/build.number | 2 + .../project/glite-lb.sdf.xml.template | 137 +- org.glite.deployment.lb/project/glite-lb.spec | 46 - org.glite.deployment.lb/project/lxscript-rpm.xsl | 94 +- org.glite.deployment.lb/project/properties.xml | 13 + org.glite.deployment.lb/project/version.properties | 8 +- org.glite.jp.common/.cvsignore | 1 - org.glite.jp.common/Makefile | 85 - org.glite.jp.common/build.xml | 93 - org.glite.jp.common/interface/context.h | 17 - org.glite.jp.common/interface/strmd5.h | 28 - org.glite.jp.common/interface/types.h | 83 - .../project/configure.properties.xml | 52 - org.glite.jp.common/project/version.properties | 4 - org.glite.jp.common/src/context.c | 164 - org.glite.jp.common/src/strmd5.c | 115 - org.glite.jp.index/.cvsignore | 1 - org.glite.jp.index/Makefile | 129 - org.glite.jp.index/build.xml | 93 - org.glite.jp.index/project/JobProvenanceIS.wsdl | 531 - org.glite.jp.index/project/build.properties | 0 .../project/configure.properties.xml | 53 - org.glite.jp.index/project/properties.xml | 52 - org.glite.jp.index/project/tar_exclude | 10 - org.glite.jp.index/project/version.properties | 4 - org.glite.jp.index/src/simple_server.c | 39 - org.glite.jp.index/src/soap_ops.c | 81 - org.glite.jp.index/src/typemap.dat | 2 - org.glite.jp.primary/.cvsignore | 1 - org.glite.jp.primary/Makefile | 148 - org.glite.jp.primary/build.xml | 97 - org.glite.jp.primary/examples/jpps-test.c | 194 - org.glite.jp.primary/project/build.properties | 0 org.glite.jp.primary/project/properties.xml | 51 - org.glite.jp.primary/project/tar_exclude | 10 - org.glite.jp.primary/project/version.properties | 4 - org.glite.jp.primary/src/backend.h | 105 - org.glite.jp.primary/src/feed.c | 264 - org.glite.jp.primary/src/feed.h | 21 - org.glite.jp.primary/src/ftp_backend.c | 1701 --- org.glite.jp.primary/src/is_client.c | 33 - org.glite.jp.primary/src/jptype_map.h | 16 - org.glite.jp.primary/src/simple_server.c | 59 - org.glite.jp.primary/src/soap_ops.c | 374 - org.glite.jp.primary/src/tags.c | 233 - org.glite.jp.primary/src/tags.h | 1 - org.glite.jp.primary/src/typemap.dat | 2 - org.glite.jp.ws-interface/.cvsignore | 2 - org.glite.jp.ws-interface/Makefile | 48 - .../interface/JobProvenanceIS.wsdl | 110 - .../interface/JobProvenancePS.wsdl | 307 - .../interface/JobProvenanceTypes.wsdl | 162 - org.glite.jp.ws-interface/project/build.properties | 0 .../project/configure.properties.xml | 54 - .../project/glite-jp-ws-interface.spec | 42 - org.glite.jp.ws-interface/project/properties.xml | 73 - org.glite.jp.ws-interface/project/tar_exclude | 0 .../project/version.properties | 3 - org.glite.jp/.cvsignore | 1 - org.glite.jp/build.xml | 262 - org.glite.jp/project/build.properties | 0 org.glite.jp/project/dependencies.properties | 12 - org.glite.jp/project/glite.jp.csf.xml | 271 - org.glite.jp/project/properties.xml | 47 - org.glite.jp/project/run-workspace | 10 - org.glite.jp/project/taskdefs.xml | 24 - org.glite.jp/project/version.properties | 4 - org.glite.lb.client-interface/Makefile | 12 +- org.glite.lb.client-interface/build.xml | 4 + org.glite.lb.client-interface/interface/CountRef.h | 42 +- org.glite.lb.client-interface/interface/Event.h.T | 153 +- org.glite.lb.client-interface/interface/Job.h | 198 +- .../interface/JobStatus.h.T | 216 +- .../interface/LoggingExceptions.h | 138 +- .../interface/Notification.h | 29 +- .../interface/ServerConnection.h | 677 +- org.glite.lb.client-interface/interface/consumer.h | 209 +- org.glite.lb.client-interface/interface/context.h | 66 +- org.glite.lb.client-interface/interface/events.h.T | 60 +- .../interface/jobstat.h.T | 14 +- .../interface/notification.h | 61 +- org.glite.lb.client-interface/interface/notifid.h | 74 +- .../interface/producer.h.T | 146 +- .../interface/statistics.h | 12 +- org.glite.lb.client-interface/project/build.number | 2 + .../project/configure.properties.xml | 56 +- .../project/version.properties | 8 +- org.glite.lb.client/Makefile | 12 +- org.glite.lb.client/build.xml | 4 + org.glite.lb.client/doc/README-acl | 66 + org.glite.lb.client/doc/README-fake | 4 - org.glite.lb.client/doc/README-notify | 72 + org.glite.lb.client/examples/abort_job.c | 128 + org.glite.lb.client/examples/change_acl.c | 78 + org.glite.lb.client/examples/job_log.c | 7 +- org.glite.lb.client/examples/job_log_fake.cpp | 71 + org.glite.lb.client/examples/job_status.c | 231 + org.glite.lb.client/examples/log_usertag_proxy.c | 103 - org.glite.lb.client/examples/producer_fake.c | 24 - org.glite.lb.client/examples/purge_test | 189 + org.glite.lb.client/project/build.number | 2 + org.glite.lb.client/project/version.properties | 8 +- org.glite.lb.client/src/ServerConnection.cpp | 61 +- org.glite.lb.client/src/connection.c | 40 +- org.glite.lb.client/src/logevent.c.T | 23 +- org.glite.lb.client/src/producer.c | 343 - org.glite.lb.client/src/uiwrap.c.T | 38 +- org.glite.lb.common/Makefile | 2 +- org.glite.lb.common/build.xml | 4 + org.glite.lb.common/interface/lb_gss.h | 2 +- org.glite.lb.common/project/build.number | 2 + org.glite.lb.common/project/version.properties | 8 +- org.glite.lb.common/src/context.c | 1 + org.glite.lb.common/src/events.c.T | 22 +- org.glite.lb.common/src/il_log.c | 7 +- org.glite.lb.common/src/lb_gss.c | 39 +- org.glite.lb.common/src/param.c | 78 +- org.glite.lb.logger/build.xml | 4 + org.glite.lb.logger/project/build.number | 2 + org.glite.lb.logger/project/version.properties | 10 +- org.glite.lb.logger/src/event_queue.c | 14 +- org.glite.lb.logger/src/event_store.c | 119 +- org.glite.lb.logger/src/il_master.c | 8 +- org.glite.lb.logger/src/interlogd.h | 2 +- org.glite.lb.logger/src/logd_proto.c | 9 +- org.glite.lb.logger/src/queue_thread.c | 17 +- org.glite.lb.server-bones/Makefile | 8 +- org.glite.lb.server-bones/build.xml | 4 + org.glite.lb.server-bones/project/build.number | 2 + .../project/version.properties | 8 +- org.glite.lb.server/Makefile | 30 +- org.glite.lb.server/build.xml | 4 + org.glite.lb.server/project/build.number | 2 + .../project/configure.properties.xml | 4 + org.glite.lb.server/project/version.properties | 8 +- org.glite.lb.server/src/dump.c | 29 +- org.glite.lb.server/src/notification.c | 13 +- org.glite.lb.server/src/server_state.c | 2 +- org.glite.lb.server/src/srv_purge.c | 3 +- org.glite.lb.server/src/store.c.T | 2 +- org.glite.lb.ws-interface/Makefile | 20 +- org.glite.lb.ws-interface/build.xml | 26 +- org.glite.lb.ws-interface/project/build.number | 2 + .../project/version.properties | 8 +- org.glite.lb.ws-interface/src/LB.xml.T | 209 + org.glite.lb.ws-interface/src/puke-ug.xsl | 139 + org.glite.lb/build.xml | 4 + org.glite.lb/project/build.number | 2 + org.glite.lb/project/dependencies.properties | 32 +- org.glite.lb/project/events.T | 264 +- org.glite.lb/project/types.T | 16 + org.glite.lb/project/version.properties | 8 +- org.glite.security.gsoap-plugin/LICENSE | 69 + org.glite.security.gsoap-plugin/Makefile | 224 + .../build.xml | 73 +- org.glite.security.gsoap-plugin/examples/calc.h.S | 13 + .../examples/wscalc_clt_ex.c | 47 + .../examples/wscalc_srv_ex.c | 102 + .../examples/wscalc_srv_ex2.c | 130 + .../interface/glite_gsplugin.h | 37 + .../interface/glite_gss.h | 117 + .../project/build.number | 2 + .../project/build.properties | 0 .../project/configure.properties.xml | 37 +- .../project/properties.xml | 33 +- .../project/tar_exclude | 2 +- .../project/version.properties | 2 + .../src/glite_gsplugin.c | 416 + org.glite.security.gsoap-plugin/src/glite_gss.c | 998 ++ .../src/stdsoap2_2.6.2.c | 11020 +++++++++++++++++++ org.glite.security.gsoap-plugin/test/test_gss.cpp | 149 + org.glite.security.proxyrenewal/Makefile | 12 +- org.glite.security.proxyrenewal/build.xml | 5 + org.glite.security.proxyrenewal/config/startup | 52 +- .../interface/renewal.h | 2 + .../project/build.number | 2 + .../project/version.properties | 8 +- org.glite.security.proxyrenewal/src/acstack.h | 79 + org.glite.security.proxyrenewal/src/api.c | 71 +- org.glite.security.proxyrenewal/src/commands.c | 127 +- org.glite.security.proxyrenewal/src/common.c | 126 +- org.glite.security.proxyrenewal/src/newformat.h | 195 + org.glite.security.proxyrenewal/src/renew.c | 884 +- org.glite.security.proxyrenewal/src/renewal_locl.h | 14 +- org.glite.security.proxyrenewal/src/renewd.c | 231 +- org.glite.security.proxyrenewal/src/renewd_locl.h | 20 +- org.glite.security.proxyrenewal/src/voms.c | 318 + org.glite.wms-utils.exception/build.xml | 5 + org.glite.wms-utils.exception/configure.ac | 8 +- .../interface/glite/wmsutils/exception/Exception.h | 15 +- org.glite.wms-utils.exception/project/build.number | 2 + .../project/version.properties | 8 +- org.glite.wms-utils.exception/src/Exception.cpp | 62 +- org.glite.wms-utils.jobid/build.xml | 5 + org.glite.wms-utils.jobid/project/build.number | 2 + .../project/version.properties | 8 +- org.gridsite.core/CHANGES | 58 + org.gridsite.core/VERSION | 2 +- org.gridsite.core/build.xml | 61 +- org.gridsite.core/doc/config.html | 4 + org.gridsite.core/doc/gsexec.8 | 56 + org.gridsite.core/doc/httpd-fileserver.conf | 5 +- org.gridsite.core/doc/httpd-webserver.conf | 5 +- org.gridsite.core/interface/gridsite.h | 32 +- org.gridsite.core/project/build.number | 2 + org.gridsite.core/project/configure.properties.xml | 2 +- org.gridsite.core/project/version.properties | 6 +- org.gridsite.core/src/Makefile | 155 +- org.gridsite.core/src/gridsite.spec | 31 +- org.gridsite.core/src/grst-delegation.c | 2 + org.gridsite.core/src/grst_admin_file.c | 18 +- org.gridsite.core/src/grst_admin_gacl.c | 16 +- org.gridsite.core/src/grst_admin_main.c | 2 +- org.gridsite.core/src/grst_asn1.c | 506 + org.gridsite.core/src/grst_gacl.c | 84 +- org.gridsite.core/src/grst_x509.c | 761 +- org.gridsite.core/src/grst_xacml.c | 577 + org.gridsite.core/src/gsexec.c | 1056 ++ org.gridsite.core/src/gsexec.h | 126 + org.gridsite.core/src/htcp | Bin 29747 -> 22680 bytes org.gridsite.core/src/mod_gridsite.c | 313 +- org.gridsite.core/src/real-gridsite-admin.cgi | Bin 96256 -> 0 bytes org.gridsite.core/src/showx509exts.c | 117 + org.gridsite.core/src/xacmlexample.c | 148 + 232 files changed, 24026 insertions(+), 10427 deletions(-) create mode 100644 org.glite.deployment.lb/CHANGELOG rename {org.glite.jp.ws-interface => org.glite.deployment.lb}/LICENSE (98%) mode change 100755 => 100644 create mode 100644 org.glite.deployment.lb/project/build.number delete mode 100644 org.glite.deployment.lb/project/glite-lb.spec delete mode 100644 org.glite.jp.common/.cvsignore delete mode 100644 org.glite.jp.common/Makefile delete mode 100755 org.glite.jp.common/build.xml delete mode 100644 org.glite.jp.common/interface/context.h delete mode 100755 org.glite.jp.common/interface/strmd5.h delete mode 100644 org.glite.jp.common/interface/types.h delete mode 100644 org.glite.jp.common/project/configure.properties.xml delete mode 100644 org.glite.jp.common/project/version.properties delete mode 100644 org.glite.jp.common/src/context.c delete mode 100755 org.glite.jp.common/src/strmd5.c delete mode 100644 org.glite.jp.index/.cvsignore delete mode 100644 org.glite.jp.index/Makefile delete mode 100755 org.glite.jp.index/build.xml delete mode 100644 org.glite.jp.index/project/JobProvenanceIS.wsdl delete mode 100644 org.glite.jp.index/project/build.properties delete mode 100644 org.glite.jp.index/project/configure.properties.xml delete mode 100755 org.glite.jp.index/project/properties.xml delete mode 100644 org.glite.jp.index/project/tar_exclude delete mode 100644 org.glite.jp.index/project/version.properties delete mode 100644 org.glite.jp.index/src/simple_server.c delete mode 100644 org.glite.jp.index/src/soap_ops.c delete mode 100644 org.glite.jp.index/src/typemap.dat delete mode 100644 org.glite.jp.primary/.cvsignore delete mode 100644 org.glite.jp.primary/Makefile delete mode 100755 org.glite.jp.primary/build.xml delete mode 100644 org.glite.jp.primary/examples/jpps-test.c delete mode 100644 org.glite.jp.primary/project/build.properties delete mode 100755 org.glite.jp.primary/project/properties.xml delete mode 100644 org.glite.jp.primary/project/tar_exclude delete mode 100644 org.glite.jp.primary/project/version.properties delete mode 100644 org.glite.jp.primary/src/backend.h delete mode 100644 org.glite.jp.primary/src/feed.c delete mode 100644 org.glite.jp.primary/src/feed.h delete mode 100644 org.glite.jp.primary/src/ftp_backend.c delete mode 100644 org.glite.jp.primary/src/is_client.c delete mode 100644 org.glite.jp.primary/src/jptype_map.h delete mode 100644 org.glite.jp.primary/src/simple_server.c delete mode 100644 org.glite.jp.primary/src/soap_ops.c delete mode 100644 org.glite.jp.primary/src/tags.c delete mode 100644 org.glite.jp.primary/src/tags.h delete mode 100644 org.glite.jp.primary/src/typemap.dat delete mode 100755 org.glite.jp.ws-interface/.cvsignore delete mode 100644 org.glite.jp.ws-interface/Makefile delete mode 100644 org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl delete mode 100644 org.glite.jp.ws-interface/interface/JobProvenancePS.wsdl delete mode 100644 org.glite.jp.ws-interface/interface/JobProvenanceTypes.wsdl delete mode 100755 org.glite.jp.ws-interface/project/build.properties delete mode 100644 org.glite.jp.ws-interface/project/configure.properties.xml delete mode 100644 org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec delete mode 100644 org.glite.jp.ws-interface/project/properties.xml delete mode 100644 org.glite.jp.ws-interface/project/tar_exclude delete mode 100755 org.glite.jp.ws-interface/project/version.properties delete mode 100644 org.glite.jp/.cvsignore delete mode 100644 org.glite.jp/build.xml delete mode 100644 org.glite.jp/project/build.properties delete mode 100644 org.glite.jp/project/dependencies.properties delete mode 100644 org.glite.jp/project/glite.jp.csf.xml delete mode 100755 org.glite.jp/project/properties.xml delete mode 100644 org.glite.jp/project/run-workspace delete mode 100755 org.glite.jp/project/taskdefs.xml delete mode 100644 org.glite.jp/project/version.properties create mode 100644 org.glite.lb.client-interface/project/build.number create mode 100644 org.glite.lb.client/doc/README-acl create mode 100644 org.glite.lb.client/doc/README-notify create mode 100644 org.glite.lb.client/examples/abort_job.c create mode 100644 org.glite.lb.client/examples/change_acl.c create mode 100644 org.glite.lb.client/examples/job_log_fake.cpp create mode 100644 org.glite.lb.client/examples/job_status.c delete mode 100644 org.glite.lb.client/examples/log_usertag_proxy.c create mode 100644 org.glite.lb.client/examples/purge_test create mode 100644 org.glite.lb.client/project/build.number create mode 100644 org.glite.lb.common/project/build.number create mode 100644 org.glite.lb.logger/project/build.number create mode 100644 org.glite.lb.server-bones/project/build.number create mode 100644 org.glite.lb.server/project/build.number create mode 100644 org.glite.lb.ws-interface/project/build.number create mode 100644 org.glite.lb.ws-interface/src/LB.xml.T create mode 100644 org.glite.lb.ws-interface/src/puke-ug.xsl create mode 100644 org.glite.lb/project/build.number create mode 100644 org.glite.security.gsoap-plugin/LICENSE create mode 100644 org.glite.security.gsoap-plugin/Makefile rename {org.glite.jp.ws-interface => org.glite.security.gsoap-plugin}/build.xml (64%) mode change 100644 => 100755 create mode 100644 org.glite.security.gsoap-plugin/examples/calc.h.S create mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c create mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c create mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c create mode 100644 org.glite.security.gsoap-plugin/interface/glite_gsplugin.h create mode 100644 org.glite.security.gsoap-plugin/interface/glite_gss.h create mode 100644 org.glite.security.gsoap-plugin/project/build.number rename {org.glite.jp.common => org.glite.security.gsoap-plugin}/project/build.properties (100%) rename {org.glite.jp.primary => org.glite.security.gsoap-plugin}/project/configure.properties.xml (52%) rename {org.glite.jp.common => org.glite.security.gsoap-plugin}/project/properties.xml (52%) rename {org.glite.jp.common => org.glite.security.gsoap-plugin}/project/tar_exclude (79%) create mode 100644 org.glite.security.gsoap-plugin/project/version.properties create mode 100644 org.glite.security.gsoap-plugin/src/glite_gsplugin.c create mode 100644 org.glite.security.gsoap-plugin/src/glite_gss.c create mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.6.2.c create mode 100644 org.glite.security.gsoap-plugin/test/test_gss.cpp create mode 100644 org.glite.security.proxyrenewal/project/build.number create mode 100755 org.glite.security.proxyrenewal/src/acstack.h create mode 100755 org.glite.security.proxyrenewal/src/newformat.h create mode 100644 org.glite.security.proxyrenewal/src/voms.c create mode 100644 org.glite.wms-utils.exception/project/build.number create mode 100644 org.glite.wms-utils.jobid/project/build.number create mode 100644 org.gridsite.core/doc/gsexec.8 create mode 100644 org.gridsite.core/project/build.number create mode 100644 org.gridsite.core/src/grst_asn1.c create mode 100644 org.gridsite.core/src/grst_xacml.c create mode 100644 org.gridsite.core/src/gsexec.c create mode 100644 org.gridsite.core/src/gsexec.h delete mode 100644 org.gridsite.core/src/real-gridsite-admin.cgi create mode 100644 org.gridsite.core/src/showx509exts.c create mode 100644 org.gridsite.core/src/xacmlexample.c diff --git a/org.glite.deployment.lb/CHANGELOG b/org.glite.deployment.lb/CHANGELOG new file mode 100644 index 0000000..9a4d20d --- /dev/null +++ b/org.glite.deployment.lb/CHANGELOG @@ -0,0 +1,29 @@ +DATE: 08-07-2005 15:20 +[dimeglio] Increased major version because of interface changes in the config scripts + +DATE: 08-07-2005 15:20 +[dimeglio] Merged from branch 1.2.2 + +DATE: 25-05-2005 20:00 +[dimeglio] Merged from branch 1.2.2 + +DATE: 21-03-2005 17:21 +[dimeglio] Implemented status method + +DATE: 21-03-2005 00:32 +[dimeglio] Added PERL5LIB env var + +DATE: 17-03-2005 17:33 +[gdiez] Stopping and starting the database before the index creation (just after the database is created and the user granted) + +DATE: 09-03-2005 23:05 +[dimeglio] Moved creation of indices inside database creation (if database + exists indices are not recreated) + +DATE: 02-03-2005 11:05 +[dimeglio] Started CHANGELOG +[dimeglio] Fixed formatting, improved display of message using glib.printXxxMessage functions +[dimeglio] Fixed some problems when starting/stopping services +[dimeglio] GLITE_USER parameter not exposed anymore in config file, use same user parameters + as WMS to allow installation on same node +[dimeglio] Increased module version number to 1.2.0 \ No newline at end of file diff --git a/org.glite.jp.ws-interface/LICENSE b/org.glite.deployment.lb/LICENSE old mode 100755 new mode 100644 similarity index 98% rename from org.glite.jp.ws-interface/LICENSE rename to org.glite.deployment.lb/LICENSE index 01b973b..259a91f --- a/org.glite.jp.ws-interface/LICENSE +++ b/org.glite.deployment.lb/LICENSE @@ -1,69 +1,69 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - +LICENSE file for EGEE Middleware +================================ + +Copyright (c) 2004 on behalf of the EU EGEE Project: +The European Organization for Nuclear Research (CERN), +Istituto Nazionale di Fisica Nucleare (INFN), Italy +Datamat Spa, Italy +Centre National de la Recherche Scientifique (CNRS), France +CS Systeme d'Information (CSSI), France +Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden +Universiteit van Amsterdam (UvA), Netherlands +University of Helsinki (UH.HIP), Finlan +University of Bergen (UiB), Norway +Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. The end-user documentation included with the redistribution, if +any, must include the following acknowledgment: "This product includes +software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." +Alternatively, this acknowledgment may appear in the software itself, if +and wherever such third-party acknowledgments normally appear. + +4. The names EGEE and the EU EGEE Project must not be +used to endorse or promote products derived from this software without +prior written permission. For written permission, please contact +. + +5. You are under no obligation whatsoever to provide anyone with any +bug fixes, patches, or upgrades to the features, functionality or +performance of the Software ("Enhancements") that you may develop over +time; however, if you choose to provide your Enhancements to The EU +EGEE Project, or if you choose to otherwise publish or distribute your +Enhancements, in source code form without contemporaneously requiring +end users of The EU EGEE Proejct to enter into a separate written license +agreement for such Enhancements, then you hereby grant The EU EGEE Project +a non-exclusive, royalty-free perpetual license to install, use, copy, +modify, prepare derivative works, incorporate into the EGEE Middleware +or any other computer software, distribute, and sublicense your +Enhancements or derivative works thereof, in binary and source code +form (if any), whether developed by The EU EGEE Project or third parties. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +This software consists of voluntary contributions made by many +individuals on behalf of the EU EGEE Prject. For more information on The +EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on +EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ + + diff --git a/org.glite.deployment.lb/build.xml b/org.glite.deployment.lb/build.xml index 0ceaee9..874c661 100644 --- a/org.glite.deployment.lb/build.xml +++ b/org.glite.deployment.lb/build.xml @@ -13,6 +13,11 @@ Revision history: $Log$ + Revision 1.5 2004/10/17 22:34:39 dimeglio + Use new installer script format + Use global filters + Use RH standard expat rpm in sdf template + Revision 1.4 2004/10/14 16:07:53 dimeglio Removed wms.thirdparty-globus-ssl-utils @@ -84,6 +89,7 @@ Load version file ========================================= --> + - + + + + + + + + + + @@ -15,32 +30,100 @@ description="Enable check of host certificates" value="true"/> - - - - - - + + + + owner + location + destination + + - - - + - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.doc b/org.glite.deployment.lb/doc/release_notes/release_notes.doc index 5fc59f7ed7fd784df377df43e569a4d21cefc8b3..ae9fd1814da46c1ba144a0202e5185f6fe1069cf 100644 GIT binary patch literal 267264 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 z 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 diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.html b/org.glite.deployment.lb/doc/release_notes/release_notes.html index 1db7585..ecba765 100644 --- a/org.glite.deployment.lb/doc/release_notes/release_notes.html +++ b/org.glite.deployment.lb/doc/release_notes/release_notes.html @@ -20,8 +20,7 @@ {font-family:Times; panose-1:2 2 6 3 5 4 5 2 3 4;} @font-face - {font-family:"Univers \(W1\)"; - panose-1:0 0 0 0 0 0 0 0 0 0;} + {font-family:"Univers \(W1\)";} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {margin-top:2.0pt; @@ -492,429 +491,522 @@ text-transform:uppercase'>gLite Logging & Bookkeeping Server

1. Release Description

This release contains the gLite Logging & Bookkeeping -Server module v. 0.2.0. The following sections provide additional information about +Server module v. 1.2.3. The following sections provide additional information about the release content, the module dependencies, the know bugs and issues and a list of bugs closed since the previous release. For information about installing and using the gLite Logging & Bookkeeping Server, please refer to the gLite Installation and User Guides.

-

2. Release contents

+

2. Changes in this Release

-

The gLite Logging & Bookkeeping Server v. 0.2.0 is +

This release introduces the following changes:

+ +

 

+ +
    +
  • All R-GMA service publishing + instances in the configuration template now have default values
  • +
  • Bug fixes (see below for the complete lists)
  • +
+ +

3. Release contents

+ +

The gLite Logging & Bookkeeping Server v. 1.2.3 is composed of the following gLite components:

 

- +
- - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - -
-

Component name

+

Component name

-

Version

+

Version

-

File

+

File

-

org.glite.deployment.lb

+

org.glite.deployment.lb

-

0.2.0

+

1.2.3

-

http://glite.web.cern.ch/glite/packages/I20041210/installers/glite-lb_installer.sh +

http://glite.web.cern.ch/glite/packages/R1.1/R20050430/installers/glite-lb_installer.sh

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/noarch/RPMS/glite-lb-config-0.2.0-1.noarch.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/noarch/RPMS/glite-lb-config-1.2.3-1.noarch.rpm

+

apt-get install + glite-lb-config

-

org.glite.deployment.config

+

org.glite.deployment.config

-

0.3.0

+

1.1.1

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/noarch/RPMS/glite- - config-0.3.0-1.noarch.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/noarch/RPMS/glite-config-1.1.1-3.noarch.rpm

-

glite-lb-client-interface

+

org.glite.lb.client-interface

-

0.3.1

+

1.0.3

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-client-interface-0.3.1-2.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-client-interface-1.0.3-1.i386.rpm

-

glite-lb-common

+

org.glite.lb.common

-

0.4.1

+

1.1.4

-

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-common-0.4.1-2.i386.rpm

+

http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-common-1.1.4-1.i386.rpm

-

glite-lb-logger

+

org.glite.lb.logger

-

0.4.1

+

1.0.1

-

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-logger-0.4.1-3.i386.rpm

+

http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-logger-1.0.1-1.i386.rpm

-

glite-lb-server

+

org.glite.lb.server

-

0.6.2

+

1.0.1

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-server-0.6.2-4.i386.rpm

+ 8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-server-1.0.1-1.i386.rpm

+
+

org.glite.lb.server-bones

+
+

1.0.0

+
+

http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-server-bones-1.0.0-1.i386.rpm

+
+

org.glite.lb.ws-interface

+
+

1.0.1

+
+

http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-lb-ws-interface-1.0.1-1.i386.rpm

-

glite-lb-server-bones

+

org.glite.security.proxyrenewal

-

0.1.0

+

1.0.13

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-server-bones-0.1.0-1.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-1.0.13-1.i386.rpm

-

glite-lb-ws-interface

+

org.glite.wms-utils.exception

-

0.1.0

+

1.0.1

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-lb-ws-interface-0.1.0-0.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.1-1.i386.rpm

-

glite-security-proxyrenewal

+

org.glite.wms-utils.jobid

-

0.1.1

+

1.0.0

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-0.1.1-1.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.0-1.i386.rpm

-

glite-wms-utils-exception

+

org.glite.security.voms

-

0.1.2

+

1.2.32

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-wms-utils-exception-0.1.2-1.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/glite-security-voms-1.2.32-1.i386.rpm

-

glite-wms-utils-jobid

+

org.gridsite.core

-

0.1.2

+

1.1.5

http://glite.web.cern.ch/glite/packages/I20041210/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-0.1.2-1.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/bin/rhel30/i386/RPMS/gridsite-1.1.5-1.i386.rpm

 

-

3. Dependencies

+

4. Dependencies

-

The gLite Logging & Bookkeeping Server module has the -following dependencies:

+

The gLite Logging & Bookkeeping Server v. 1.2.2 module +has the following dependencies:

 

- +
- - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + +

Component name

+ 8.0pt'>Component name

-

Version

+

Version

-

RPM file name

+

RPM file name

+
+

gLite Security Utilities

+
+

1.0.1

+
+

http://glite.web.cern.ch/glite/packages/R1.1/R20050430/installers/glite-security-utils_installer.sh

gLite Security Utilities

+ style='font-size:8.0pt'>gLite R-GMA Service Publisher

-

0.2.0

+

4.2.0

http://glite.web.cern.ch/glite/packages/I20041210/installers/glite-security-utils_installer.sh

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.1/R20050430/installers/glite-rgma-servicetool_installer.sh

GPT

+ 8.0pt'>GPT

-

VDT 1.2.0

+

VDT 1.2.2

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.0rh9-1.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.2rh9-1.i386.rpm

VDT Globus Essentials

+ 8.0pt'>VDT Globus Essentials

-

VDT 1.2.0

+

VDT 1.2.2

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.0rh9-1.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.2rh9-1.i386.rpm

MySQL-server

+ 8.0pt'>MySQL-server

-

4.0.20

+

4.0.20

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.0.20-0.i386.rpm

MySQL-client

+ 8.0pt'>MySQL-client

-

4.0.20

+

4.0.20

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.0.20-0.i386.rpm

ares

+ 8.0pt'>ares

-

1.1.1

+

1.1.1

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-1.1.1-EGEE.i386.rpm

myproxy

+ 8.0pt'>myproxy

-

1.14

+

1.14

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm

perl-Expect.pm

+ 8.0pt'>perl-Expect.pm

-

1.01

+

1.01

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-1.01-9.i386.rpm

+

Java SDK/JRE

+
+

1.4.2

+
+

http://java.sun.com/j2se/1.4.2/download.html

+

 

-

4. Known bugs and issues

+

5. Known bugs and issues

This release has the following bugs and issues. Bug numbers refer to the gLite Bug Tracking system @@ -924,787 +1016,1707 @@ href="https://savannah.cern.ch/bugs/?group=jra1mdw">https://savannah.cern.ch/bug

 

+
    +
  • If the mysql root password is set + and it is not specified in the mysql.conf file, the configuration script + fails. This bug will be fixed in the next release
  • +
  • No removal procedure is provided + with this release apart from the removal of the RPMS. Any account, group + or other resource created during the module configuration must be manually + cleaned.
  • +
+ +

 

+ +

Known open bugs:

+ +

 

+ - - + - - + - - - - - - - - - - - + - + - + - +

Bug number

Description

+

 

+
+

 #5125

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7053"> #7053

glite-lb-bkserverd - start/stop/status displays usage options 

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7053">LB configuration fails if the + mysql root pwd is set 

+
+

 

 #5202

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7237"> #7237

-

no RPM provides the - lb-local-logger daemon -  

-
+

 #5248

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7237">Intermittent errors with job + submission 

-

When running - "glite-lb-bkserverd start", glite-lb-bkserverd doesn't start in - background 

+

 

 #5833

-
-

all jobs in SUBMITTED after a - job storm 

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7300"> #7300

 #5903

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7300">update of the lb instructions + at the end of the installer script  

-

glite-lb-bkserverd script gives - bash: /root/.bashrc: Permission denied error  

+
+

 

 #5904

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7305"> #7305

+

glite-lb-bkserverd does not - check default location for credentials 

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7305">lb.database.username paramenter + in config file 

+
+

 

 #5926

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7307"> #7307

+

Default user should not be used - in the init.d scripts 

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7307">lb config script does _not_ + fail if mysql root password is set 

+
+

 

 #5932

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7324"> #7324

+

credential file created in - /var/tmp is unnecessary 

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7324">lb-bkserver is running with no + pid 

+
+

 

 #5934

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7389"> #7389

+

service start and stop notifications - are inconsistent for glite-lb-bkserverd init,d script 

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7389">LB server and WMS local logger + related issues 

+
+

 

-

 

- -

No removal procedure is -provided with this release apart from the removal of the RPMS. Any account, -group or other resource created during the module configuration must be -manually cleaned.

- -

 

- -

5. Bugs closed since last release

+

 

-
+

Bugs fixed in this or previous releases, but not yet officially +tested:

-

 

+

 

- - + - - - - - - - + - - -

Bug number

Description

+

 

+
+

 #4627

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6412"> #6412

no licence found in lb packages 

-
-

 #5236

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6412">--start and --stop options not + documented in glite-ce-config.py, glite-lb-config.py 

-

LB install/config documentation - has some errors 

+

 

 #5912

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6722"> #6722

+

glite-lb-bkserver daemon looks - hangs is /tmp/mysql.sock is not present 

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=6722">glite-job-status -all doesn't + work 

+
+

 

 #5930

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7151"> #7151

+

running start on started - service is not an error.  

+ href="https://savannah.cern.ch/bugs/?func=detailitem&item_id=7151">There are conflicts when + installing WMS and LB on the same node 

- -

 

- -

6. Previous Releases

- -

6.1. Release 0.1.0

- -

6.1.1. Release Description

- -

This release contains the gLite Logging & Bookkeeping -Server module v. 0.1.0. The following sections provide additional information -about the release content, the module dependencies, the know bugs and issues -and a list of bugs closed since the previous release. For information about -installing and using the gLite Logging & Bookkeeping Server, please refer -to the gLite Installation and User Guides.

- -

6.1.2. Release contents

- -

The gLite Logging & Bookkeeping Server v. 0.1.0 is -composed of the following gLite components:

- -

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
-

Component name

-
-

Version

-
-

File

+

 

-

org.glite.deployment.lb

-
-

0.1.0

+

 #7180

-

http://glite.web.cern.ch/glite/packages/I20041126/installers/glite-lb_installer.sh -

-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/noarch/RPMS/glite-lb-config-0.1.0-1.noarch.rpm

-
-

org.glite.deployment.config

-
-

0.1.0

+

Logging & Bookkeping UI  

-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/noarch/RPMS/glite- - config-0.1.0-1.noarch.rpm

+

 

-

glite-lb-client-interface

-
-

0.3.0

+

 #7321

-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-client-interface-0.3.0-2.i386.rpm

-
-

glite-lb-logger

-
-

0.3.0

+

creation of indices fails + randomly 

-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-logger-0.3.0-3.i386.rpm

+

 

-

glite-lb-common

-
-

0.3.0

+

 #7884

-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-common-0.3.0-2.i386.rpm

-
-

glite-lb-server

-
-

0.5.2

+

local header files distributed + in RPMs.  

-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-server-0.5.2-4.i386.rpm

+

 

-

glite-lb-server-bones

-
-

0.1.0

+

 #7910

-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-lb-server-bones-0.1.0-1.i386.rpm

-
-

glite-wms-utils-jobid

-
-

0.1.2

+

Duplicate apostroph in MySQL + calls 

-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-0.1.2-1.i386.rpm

+

 

+ +

 

+ +

6. Bugs closed since last release

+ +

This release fixes the +following bugs and issues. Bug numbers refer to the gLite Bug Tracking system +database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw

+ +

 

+ + - + - + - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-

glite-wms-utils-exception

+
+

Bug number

+
+

Description

-

0.1.2

+

 #5850

+
+

glite-lb-config.py has + glite.location and globus.location not set in params[] 

+

 #5901

+
-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-wms-utils-exception-0.1.2-1.i386.rpm

+

mysqlaccess command fails with + Broken pipe if mysql socket file is in /tmp  

-

glite-security-proxyrenewal

+
+

 #5908

+
+

Environment variables set via + the configuration script are not passed to daemon startup scripts 

-

0.1.0

+

 #6057

+

glite-lb configuration scripts + has missing dependency (CGI.pm) 

+
-

http://glite.web.cern.ch/glite/packages/I20041126/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-0.1.0-1.i386.rpm

+

 #6075

+
+

glite-lb-config.py crashes with + KeyError: GLITE_CERT_DIR 

+
+

 #6190

+
+

LB local logger doesn't start + on the CE node 

+
+

 #6366

+
+

LB install script:: Fails but + no error reported 

+
+

 #6415

+
+

glite-lb-bkserver does not + start and blocks execution of glite-lb-config.py 

+
+

 #7296

+
+

glite-lb-config.py crashes with + a TypeError exception 

+
+

 #7753

+
+

glite-lb-config.py fails with + an indentation error 

+
+

 #7976

+
+

edg-job-status not working with + voms proxies 

+
+

 #8094

+
+

interlogd on the WMS doesn't + restart 

-

 

+

 

+ +
+
+ +

7. Previous Releases

+ +

7.1. Release 1.2.2

+ +

7.1.1. Release Description

+ +

This release contains the gLite Logging & Bookkeeping +Server module v. 1.2.2. The following sections provide additional information +about the release content, the module dependencies, the know bugs and issues +and a list of bugs closed since the previous release. For information about +installing and using the gLite Logging & Bookkeeping Server, please refer +to the gLite Installation and User Guides.

+ +

7.1.2. Changes in this Release

+ +

This release introduces the following changes:

+ +

 

+ +
    +
  • Implemented status method
  • +
  • Added definition of PERL5LIB env var
  • +
  • Stopping and starting the database before the index + creation (just after the database is created and the user granted) to fix + access denied error
  • +
  • Moved creation of indices inside database creation (if + database exists indices must not be recreated)
  • +
  • GLITE_USER parameter is not exposed anymore in the + configuration file; instead the module uses the same user parameters as + WMS to allow installation on same node
  • +
  • LB admin tools are now installed in sbin, not in bin
  • +
  • Bug fixes (see below for the complete lists)
  • +
-

6.1.3. Dependencies

+

7.1.3. Release contents

-

The gLite Logging & Bookkeeping Server module has the -following dependencies:

+

The gLite Logging & Bookkeeping Server v. 1.2.2 is +composed of the following gLite components:

 

- +
- - - - - - - - - - - - - - - - + + + + + - + + + + + - - - - - - - - - - -
-

Component name

+

Component name

-

Version

+

Version

-

RPM file name

+

File

-

gLite Security Utilities

+

org.glite.deployment.lb

-

0.2.0

+

1.2.2

+

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-lb_installer.sh +

http://glite.web.cern.ch/glite/packages/I20041126/installers/glite-security-utils_installer.sh

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/noarch/RPMS/glite-lb-config-1.2.2-1.noarch.rpm

-

GPT

+

org.glite.deployment.config

-

VDT 1.2.0

+

1.0.0

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.0rh9-1.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/noarch/RPMS/glite-config-1.0.0-1.noarch.rpm

-

VDT Globus Essentials

+

org.glite.lb.client-interface

-

VDT 1.2.0

+

1.0.2

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.0rh9-1.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-client-interface-1.0.2-1.i386.rpm

-

MySQL-server

+

org.glite.lb.common

-

4.0.20

+

1.1.4

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.0.20-0.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-common-1.1.4-1.i386.rpm

-

MySQL-client

+

org.glite.lb.logger

+
+

1.0.1

+
+

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-logger-1.0.1-1.i386.rpm

+
+

org.glite.lb.server

+

1.0.1

+
+

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-1.0.1-1.i386.rpm

+
+

org.glite.lb.server-bones

+
-

4.0.20

+

1.0.0

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.0.20-0.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-server-bones-1.0.0-1.i386.rpm

-

ares

+

org.glite.lb.ws-interface

-

1.1.1

+

1.0.1

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-1.1.1-EGEE.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-lb-ws-interface-1.0.1-1.i386.rpm

-

myproxy

+

org.glite.security.proxyrenewal

-

1.14

+

1.0.11

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-security-proxyrenewal-1.0.11-1.i386.rpm

-

perl-Expect.pm

+

org.glite.wms-utils.exception

-

1.01

+

1.0.1

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-1.01-9.i386.rpm

+ style='font-size:8.0pt'>http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-exception-1.0.1-1.i386.rpm

- -

 

- -

6.1.4. Known bugs and issues

- -

This release has the -following bugs and issues. Bug numbers refer to the gLite Bug Tracking system -database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw -.

- -

 

- - - + - - - + - - +
+

org.glite.wms-utils.jobid

+
-

Bug number

+

1.0.0

-

Description

+
+

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-wms-utils-jobid-1.0.0-1.i386.rpm

-

 #5125

+

org.glite.security.voms

-

glite-lb-bkserverd - start/stop/status displays usage options 

+

1.2.32

+
+

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/glite-security-voms-1.2.32-1.i386.rpm

-

 #5248

+

org.gridsite.core

-

When running - "glite-lb-bkserverd start", glite-lb-bkserverd doesn't start in - background 

+

1.1.5

+
+

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/bin/rhel30/i386/RPMS/gridsite-1.1.5-1.i386.rpm

-

 

- -

No removal procedure is -provided with this release apart from the removal of the RPMS. Any account, -group or other resource created during the module configuration must be -manually cleaned.

- -

 

+

 

-

6.1.5. Bugs closed since last release

+

7.1.4. Dependencies

-

This release fixes the -following bugs and issues. Since there are no previous public releases, this -list refers to the previous development release. Bug numbers refer to the gLite -Bug Tracking system database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw

+

The gLite Logging & Bookkeeping Server v. 1.2.2 module +has the following dependencies:

-

 

+

 

- +
- + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + +
-

Bug number

+

Component name

+
+

Version

-

Description

+

RPM file name

-

 #4627

+

gLite Security Utilities

-

no licence found in lb packages 

+

1.0.0

+
+

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-security-utils_installer.sh

+
+

gLite R-GMA Service Publisher

+
+

4.1.5

+
+

http://glite.web.cern.ch/glite/packages/R1.0/R20050331/installers/glite-rgma-servicetool_installer.sh

+
+

GPT

+
+

VDT 1.2.2

+
+

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/gpt-VDT1.2.2rh9-1.i386.rpm

+
+

VDT Globus Essentials

+
+

VDT 1.2.2

+
+

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/vdt_globus_essentials-VDT1.2.2rh9-1.i386.rpm

+
+

MySQL-server

+
+

4.0.20

+
+

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-server-4.0.20-0.i386.rpm

+
+

MySQL-client

+
+

4.0.20

+
+

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/MySQL-client-4.0.20-0.i386.rpm

+
+

ares

+
+

1.1.1

+
+

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/ares-1.1.1-EGEE.i386.rpm

+
+

myproxy

+
+

1.14

+
+

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/myproxy-1.14-EGEE.i386.rpm

-

 #5236

+

perl-Expect.pm

+
+

1.01

+
+

http://glite.web.cern.ch/glite/packages/externals/bin/rhel30/RPMS/per-Expect.pm-1.01-9.i386.rpm

+
+

Java SDK/JRE

+
+

1.4.2

+
+

http://java.sun.com/j2se/1.4.2/download.html

+
+ +

 

+ +

7.1.5. Known bugs and issues

+ +

This release has the +following bugs and issues. Bug numbers refer to the gLite Bug Tracking system +database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw +.

+ +

 

+ +
    +
  • No removal procedure is provided + with this release apart from the removal of the RPMS. Any account, group + or other resource created during the module configuration must be manually + cleaned.
  • +
+ +

 

+ +

Known open bugs:

+ +

 

+ + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Bug number

+
+

Description

+
+

 

+
+

 #6412

+
+

--start and --stop options not + documented in glite-ce-config.py, glite-lb-config.py 

+
+

 

+
+

 #7053

+
+

LB configuration fails if the + mysql root pwd is set 

+
+

 

+
+

 #7180

+
+

Logging & Bookkeping UI  

+
+

 

+
+

 #7237

+
+

Intermittent errors with job + submission 

-

LB install/config documentation - has some errors 

+

 

+
+

 #7300

+
+

update of the lb instructions + at the end of the installer script  

+
+

 

+
+

 #7305

+
+

lb.database.username + paramenter in config file 

+
+

 

+
+

 #7307

+
+

lb config script does _not_ + fail if mysql root password is set 

+
+

 

+
+

 #7321

+
+

creation of indices fails + randomly 

+
+

 

+
+

 #7324

+
+

lb-bkserver is running with no + pid 

+
+

 

+
+

 #7389

+
+

LB server and WMS local logger + related issues 

+
+

 

+
+ +

 

+ +

Bugs fixed in this or previous releases, but not yet +officially tested:

+ +

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Bug number

+
+

Description

+
+

 

+
+

 #5850

+
+

glite-lb-config.py has + glite.location and globus.location not set in params[] 

+
+

 

+
+

 #5908

+
+

Environment variables set via + the configuration script are not passed to daemon startup scripts 

+
+

 

+
+

 #6075

+
+

glite-lb-config.py crashes with + KeyError: GLITE_CERT_DIR 

+
+

 

+
+

 #6366

+
+

LB install script:: Fails but + no error reported 

+
+

 

+
+

 #6415

+
+

glite-lb-bkserver does not + start and blocks execution of glite-lb-config.py 

+
+

 

+
+

 #6689

+
+

glite-proxy-renewd starts the + daemon glite-proxy-renewd as GLITE_USER which is glite-lb i.e. wrong 

+
+

 

+
+

 #6722

+
+

glite-job-status -all doesn't + work 

+
+

 

+
+

 #7296

+
+

glite-lb-config.py crashes with + a TypeError exception 

+
+

 

+
+ +

 

+ +

7.1.6. Bugs closed since last release

+ +

This release fixes the +following bugs and issues. Bug numbers refer to the gLite Bug Tracking system +database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw

+ +

 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Bug number

+
+

Description

+
+

 #5833

+
+

all jobs in SUBMITTED after a + job storm 

+
+

 #5897

+
+

I20041203 LB installation + script has a missing dependency  

+
+

 #5910

+
+

glite-lb configuration scripts + don't set GLITE_USER environment 

+
+

 #5925

+
+

Running glite-lb script removes + mysql.sock file  

+
+

 #6416

+
+

the BKserver on the LB machine + needs a symlink and the script doesn't check for it 

+
+

 #7032

+
+

The LB installer fails with an + RPM not found message 

+
+

 #7152

+
+

The LB installer tries to + install gridsite with a wrong rpm name 

+
+

 #7351

+
+

Star/restart of LB services  

+
+

 #7401

+
+

The first time the LB config + script is run it fails creating the db indices 

+
+

 #7423

+
+

'/etc/rc.d/init.d/gLite status' + not working correctly in LB 

diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.pdf b/org.glite.deployment.lb/doc/release_notes/release_notes.pdf index 353c3a28a37959364d92fe9221a4253f160322af..cfd9fe519216527d0ea4f925092783b9790ab87e 100644 GIT binary patch literal 217944 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

xgU9WWw_)riR~GH^?ZY>7C=G8~UTkFVWw2 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 delta 21374 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 diff --git a/org.glite.deployment.lb/project/build.number b/org.glite.deployment.lb/project/build.number new file mode 100644 index 0000000..74c1cb4 --- /dev/null +++ b/org.glite.deployment.lb/project/build.number @@ -0,0 +1,2 @@ +#Fri Jul 22 11:14:22 CEST 2005 +module.build=246 diff --git a/org.glite.deployment.lb/project/glite-lb.sdf.xml.template b/org.glite.deployment.lb/project/glite-lb.sdf.xml.template index 9fd493f..1e48ca9 100644 --- a/org.glite.deployment.lb/project/glite-lb.sdf.xml.template +++ b/org.glite.deployment.lb/project/glite-lb.sdf.xml.template @@ -10,9 +10,9 @@ - - + + + - - - - - - - + + + + + + + + + + + + + + + + - diff --git a/org.glite.deployment.lb/project/glite-lb.spec b/org.glite.deployment.lb/project/glite-lb.spec deleted file mode 100644 index cf7c650..0000000 --- a/org.glite.deployment.lb/project/glite-lb.spec +++ /dev/null @@ -1,46 +0,0 @@ -Summary:gLite LB node installation package -Name:glite-lb-config -Version:@MODULE.VERSION@ -Release:@MODULE.BUILD@ -Copyright:Open Source EGEE License -Vendor:EU EGEE project -Group:System/Application -Prefix:/opt/glite -BuildArch:noarch -BuildRoot:%{_builddir}/%{name}-%{version} -Requires: glite-lb-common, glite-lb-logger, glite-lb-server, glite-security-proxyrenewal, glite-lb-client-interface, MySQL-server, MySQL-client, expat, ares,vdt_globus_essentials, glite-wms-utils-jobid, glite-wms-utils-exception, myproxy, perl-Expect.pm - -AutoReqProv:no -Source:glite-lb.tar.gz -%define debug_package %{nil} - -%description -gLite Logging and Bookkeeping node installation package - -%prep - - -%setup -c - -%build - - -%install - - -%clean - -%pre -%post -#echo "post install script" -%preun -%postun -%files -%attr(755,root,root) %{prefix}/etc/config/scripts/glite-lb-config.py -%attr(644,root,root) %{prefix}/etc/config/templates/glite-lb.cfg.xml -%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.doc -%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.pdf -%attr(644,root,root) %{prefix}/share/doc/glite-lb/release_notes/release_notes.html - -%changelog - diff --git a/org.glite.deployment.lb/project/lxscript-rpm.xsl b/org.glite.deployment.lb/project/lxscript-rpm.xsl index 79eb3dc..e20f297 100644 --- a/org.glite.deployment.lb/project/lxscript-rpm.xsl +++ b/org.glite.deployment.lb/project/lxscript-rpm.xsl @@ -9,6 +9,7 @@ omit-xml-declaration="yes"/> + @@ -52,10 +53,24 @@ function parseRPMList() RPMLIST=$newRPMLIST } +#Parse the SCRIPTLIST to execute all scripts +function parseScriptList() +{ + for i in $SCRIPTLIST + do + if [ "$INSTALL" = "true" ]; then + $i + else + $i -u + fi + done +} #Downloads and install the module RPMS function install() { + + INSTALL=true version echo echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -75,6 +90,14 @@ function install() + # Download scripts from repository + + + true + + + + # Download dependencies RPMS from repository @@ -90,6 +113,10 @@ function install() + + # Download and install subservices + parseScriptList + # Install all RPMS echo @@ -98,12 +125,35 @@ function install() echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx echo parseRPMList - rpm -Uvh $RPMLIST - echo - echo Done! + if [ ! -z "$RPMLIST" ]; then + rpm -Uvh $RPMLIST + rpm_return=$? + else + echo All required RPMS are already installed + rpm_return=0 + fi + if [ "$rpm_return" == "0" ]; then + echo + echo Done! + echo + echo Before using the gLite LB, please create or update the configuration + echo file /opt/glite/etc/config/glite-lb.cfg.xml + echo and run the configuration script + echo /opt/glite/etc/config/scripts/glite-lb-config.py. + echo A template is provided in + echo /opt/glite/etc/config/templates/glite-lb.cfg.xml + else + echo + echo An error occurred while installing the LB RPMS. + echo Most likely one or more of the RPMS to be installed require + echo additional dependencies or are older than already installed packages. + echo Please refer to the rpm error message above for more details. + fi echo - echo For more information refer to the gLite Installation and User Guides or to the gLite web site \(http:\/\/www.glite.org\) - echo Please report problems and comments to the gLite Team at project-eu-egee-middleware-integration-support@cern.ch + echo For more information refer to the gLite Installation and User Guides + echo or to the gLite web site \(http:\/\/www.glite.org\) + echo Please report problems and comments to the gLite Team at + echo project-eu-egee-glite-bugs@cern.ch cd .. } @@ -144,8 +194,16 @@ function uninstall() echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx echo rpm -ev $RPMLIST - echo - echo Done! + if [ "$?" == "0" ]; then + echo + echo Done! + else + echo + echo An error occurred while removing the LB RPMS. + echo Most likely one or more of the RPMS to be removed have + echo dependent packages. + echo Please refer to the rpm error message above for more details. + fi } ############################################################################### @@ -209,6 +267,28 @@ install exit 0 + + + _installer.sh + + +wget -N --non-verbose +if [ ! -f "" ] +then + echo + echo ERROR: could not be downloaded! + exit 1 +fi +chmod u+x +SCRIPTLIST="$SCRIPTLIST ./" + + +SCRIPTLISTUn="$SCRIPTLISTUn ./ -u " + + + + + --..rpm diff --git a/org.glite.deployment.lb/project/properties.xml b/org.glite.deployment.lb/project/properties.xml index 638f02b..c7ef835 100644 --- a/org.glite.deployment.lb/project/properties.xml +++ b/org.glite.deployment.lb/project/properties.xml @@ -12,6 +12,9 @@ Revision history: $Log$ + Revision 1.1 2004/10/06 09:19:24 dimeglio + First version of this file + --> @@ -47,4 +50,14 @@ Define extra properties here ... ====================================================== --> + + + + diff --git a/org.glite.deployment.lb/project/version.properties b/org.glite.deployment.lb/project/version.properties index 61f3e64..08bf106 100644 --- a/org.glite.deployment.lb/project/version.properties +++ b/org.glite.deployment.lb/project/version.properties @@ -1,4 +1,4 @@ -#Thu Dec 09 08:14:11 CET 2004 -module.version=0.2.0 -module.build=68 -module.age=1 + +module.version = 2.0.0 +module.age = 1 + \ No newline at end of file diff --git a/org.glite.jp.common/.cvsignore b/org.glite.jp.common/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.common/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.common/Makefile b/org.glite.jp.common/Makefile deleted file mode 100644 index 8626261..0000000 --- a/org.glite.jp.common/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -# defaults -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -lbprefix=lb -package=glite-jp-common -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -expat_prefix=/opt/expat -ares_prefix=/opt/ares -gsoap_prefix=/software/gsoap-2.6 - -CC=gcc - --include Makefile.inc - - -VPATH=${top_srcdir}/src:${top_srcdir}/test:${top_srcdir}/project:${jpproject} - -GLOBUSINC:= -I${globus_prefix}/include/${nothrflavour} - - -DEBUG:=-g -O0 -CFLAGS:=${DEBUG} -I. -I${top_srcdir}/interface -I${stagedir}/include \ - ${GLOBUSINC} - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -rpath ${stagedir}/lib -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} - -HDRS:=types.h context.h strmd5.h - -SRCS:=context.c strmd5.c -OBJS:=${SRCS:.c=.lo} - -commonlib:= libglite_jp_common.la - -default all: compile - -compile: ${commonlib} - -${commonlib}: ${OBJS} - ${LINK} -o $@ ${OBJS} - -check: - -echo nothing yet - -doc: - -stage: compile - $(MAKE) install PREFIX=${stagedir} - -install: - -mkdir -p ${PREFIX}/include/${globalprefix}/${jpprefix} - cd ${top_srcdir}/interface && install -m 644 ${HDRS} ${PREFIX}/include/${globalprefix}/${jpprefix} - -mkdir -p ${PREFIX}/lib - ${INSTALL} -m 755 ${commonlib} ${PREFIX}/lib - -dist: distsrc distbin - -# FIXME: just copied from LB -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -clean: - -%.lo: %.c - ${COMPILE} -o $@ -c $< diff --git a/org.glite.jp.common/build.xml b/org.glite.jp.common/build.xml deleted file mode 100755 index f20263f..0000000 --- a/org.glite.jp.common/build.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.common/interface/context.h b/org.glite.jp.common/interface/context.h deleted file mode 100644 index 20effb2..0000000 --- a/org.glite.jp.common/interface/context.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __GLITE_JP_CONTEXT -#define __GLITE_JP_CONTEXT - -int glite_jp_init_context(glite_jp_context_t *); -void glite_jp_free_query_rec(glite_jp_query_rec_t *); - -char *glite_jp_peer_name(glite_jp_context_t); -char *glite_jp_error_chain(glite_jp_context_t); - -int glite_jp_stack_error(glite_jp_context_t, const glite_jp_error_t *); -int glite_jp_clear_error(glite_jp_context_t); - -int glite_jp_add_deferred(glite_jp_context_t,int (*)(glite_jp_context_t,void *),void *); -int glite_jp_run_deferred(glite_jp_context_t); - - -#endif diff --git a/org.glite.jp.common/interface/strmd5.h b/org.glite.jp.common/interface/strmd5.h deleted file mode 100755 index c5d76b6..0000000 --- a/org.glite.jp.common/interface/strmd5.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _GLITE_STRMD5_H -#define _GLITE_STRMD5_H - -#ident "$Header$" - -/* Compute MD5 sum of the first argument. - * The sum is returned in the 16-byte array pointed to by 2nd argument - * (if not NULL) - * - * Return value: ASCII string of the sum, i.e. 32 characters [0-9a-f] - * (pointer to static area, changed by subsequent calls) - */ - -char *strmd5(const char *src, unsigned char *dst); - -/** - * Returns: allocated 32bytes long ASCII string with md5 sum - * of the first argument - */ -char *str2md5(const char *src); - -/** - * Returns: allocated 22bytes long ASCII string with md5 sum in base64 - * format of the source argument - */ -char *str2md5base64(const char *src); - -#endif /* _GLITE_STRMD5_H */ diff --git a/org.glite.jp.common/interface/types.h b/org.glite.jp.common/interface/types.h deleted file mode 100644 index 70e8482..0000000 --- a/org.glite.jp.common/interface/types.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef __GLITE_JP_TYPES -#define __GLITE_JP_TYPES - -#include - -typedef struct _glite_jp_error_t { - int code; - char *desc; - char *source; - struct _glite_jp_error_t *reason; -} glite_jp_error_t; - -typedef struct _glite_jp_context { - glite_jp_error_t *error; - int (**deferred_func)(struct _glite_jp_context *,void *); - void **deferred_arg; - void *feeds; - struct soap *other_soap; -} *glite_jp_context_t; - -typedef enum { - GLITE_JP_FILECLASS_UNDEF, - GLITE_JP_FILECLASS_INPUT, - GLITE_JP_FILECLASS_OUTPUT, - GLITE_JP_FILECLASS_LBLOG, - GLITE_JP_FILECLASS_TAGS, - GLITE_JP_FILECLASS__LAST -} glite_jp_fileclass_t; - -typedef struct { - char *name; - int sequence; - time_t timestamp; - int binary; - size_t size; - char *value; -} glite_jp_tagval_t; - -typedef enum { - GLITE_JP_ATTR_UNDEF, - GLITE_JP_ATTR_OWNER, - GLITE_JP_ATTR_TIME, - GLITE_JP_ATTR_TAG, - GLITE_JP_ATTR__LAST -} glite_jp_attrtype_t; - -typedef struct { - glite_jp_attrtype_t type; - char *name; -} glite_jp_attr_t; - -typedef struct { - glite_jp_attr_t attr; - union { - char *s; - int i; - struct timeval time; - glite_jp_tagval_t tag; - } value; -} glite_jp_attrval_t; - - -typedef enum { - GLITE_JP_QUERYOP_UNDEF, - GLITE_JP_QUERYOP_EQUAL, - GLITE_JP_QUERYOP_UNEQUAL, - GLITE_JP_QUERYOP_LESS, - GLITE_JP_QUERYOP_GREATER, - GLITE_JP_QUERYOP_WITHIN, - GLITE_JP_QUERYOP__LAST, -} glite_jp_queryop_t; - -typedef struct { - glite_jp_attr_t attr; - glite_jp_queryop_t op; - union _glite_jp_query_rec_val { - char *s; - int i; - struct timeval time; - } value,value2; -} glite_jp_query_rec_t; - -#endif diff --git a/org.glite.jp.common/project/configure.properties.xml b/org.glite.jp.common/project/configure.properties.xml deleted file mode 100644 index 5f0ea37..0000000 --- a/org.glite.jp.common/project/configure.properties.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -jpprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -version=${module.version} -glite_location=${with.glite.location} -globus_prefix=${with.globus.prefix} -expat_prefix=${with.expat.prefix} -gsoap_prefix=${with.gsoap.prefix} -ares_prefix=${with.ares.prefix} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} - - - diff --git a/org.glite.jp.common/project/version.properties b/org.glite.jp.common/project/version.properties deleted file mode 100644 index 999300f..0000000 --- a/org.glite.jp.common/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ -#Fri Dec 10 13:33:53 CET 2004 -module.version=0.1.0 -module.build=3 -module.age=1 diff --git a/org.glite.jp.common/src/context.c b/org.glite.jp.common/src/context.c deleted file mode 100644 index 016bc59..0000000 --- a/org.glite.jp.common/src/context.c +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include - -#include "types.h" -#include "context.h" - -int glite_jp_init_context(glite_jp_context_t *ctx) -{ - *ctx = calloc(1,sizeof **ctx); -} - -char *glite_jp_peer_name(glite_jp_context_t ctx) -{ - return strdup("unknown"); -} - -char *glite_jp_error_chain(glite_jp_context_t ctx) -{ - char *ret = NULL,indent[300] = ""; - int len = 0,add; - char buf[2000]; - - glite_jp_error_t *ep = ctx->error; - - do { - add = snprintf(buf,sizeof buf,"%s%s: %s (%s)\n", - indent, - ep->source, - strerror(ep->code), - ep->desc ? ep->desc : ""); - ret = realloc(ret,len + add + 1); - strncpy(ret + len,buf,add); ret[len += add] = 0; - strcat(indent," "); - } while (ep = ep->reason); - - return ret; -} - -int glite_jp_stack_error(glite_jp_context_t ctx, const glite_jp_error_t *err) -{ - glite_jp_error_t *reason = ctx->error; - - ctx->error = calloc(1,sizeof *ctx->error); - ctx->error->code = err->code; - ctx->error->desc = err->desc ? strdup(err->desc) : NULL; - ctx->error->source = err->source ? strdup(err->source) : NULL; - ctx->error->reason = reason; - - return err->code; -} - -int glite_jp_clear_error(glite_jp_context_t ctx) -{ - glite_jp_error_t *e = ctx->error, *r; - - while (e) { - r = e->reason; - free(e->source); - free(e->desc); - free(e); - e = r; - } - ctx->error = NULL; - return 0; -} - - -void glite_jp_free_query_rec(glite_jp_query_rec_t *q) -{ - free(q->attr.name); q->attr.name = NULL; - switch (q->attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - free(q->value.s); q->value.s = NULL; - if (q->op == GLITE_JP_QUERYOP_WITHIN) { - free(q->value2.s); - q->value2.s = NULL; - } - break; - default: break; - } -} - -int glite_jp_attr_copy(glite_jp_attr_t *dst,const glite_jp_attr_t *src) -{ - dst->name = src->name ? strdup(src->name) : NULL; - dst->type = src->type; - return 0; -} - -int glite_jp_queryrec_copy(glite_jp_query_rec_t *dst, const glite_jp_query_rec_t *src) -{ - glite_jp_attr_copy(&dst->attr,&src->attr); - dst->op = src->op; - switch (src->attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - dst->value.s = strdup(src->value.s); - if (dst->op == GLITE_JP_QUERYOP_WITHIN) - dst->value2.s = strdup(src->value2.s); - break; - case GLITE_JP_ATTR_TIME: - memcpy(&dst->value.time,&src->value.time,sizeof dst->value.time); - if (dst->op == GLITE_JP_QUERYOP_WITHIN) - memcpy(&dst->value2.time,&src->value2.time,sizeof dst->value2.time); - break; - } - return 0; -} - -int glite_jp_run_deferred(glite_jp_context_t ctx) -{ - int i,cnt,ret; - - if (!ctx->deferred_func) return 0; - - glite_jp_clear_error(ctx); - for (cnt=0;ctx->deferred_func[cnt];cnt++); - for (i=0; ideferred_func)(ctx,*ctx->deferred_arg)) { - glite_jp_error_t err; - char desc[100]; - - sprintf(desc,"calling func #%d, %p",i,*ctx->deferred_func); - err.code = ret; - err.desc = desc; - err.source = "glite_jp_run_deferred()"; - - glite_jp_stack_error(ctx,&err); - return ret; - } - else { - memmove(ctx->deferred_func,ctx->deferred_func+1, - (cnt-i) * sizeof *ctx->deferred_func); - memmove(ctx->deferred_arg,ctx->deferred_arg+1, - (cnt-i) * sizeof *ctx->deferred_arg); - } - } - free(ctx->deferred_func); ctx->deferred_func = NULL; - free(ctx->deferred_arg); ctx->deferred_arg = NULL; - return 0; -} - -int glite_jp_add_deferred( - glite_jp_context_t ctx, - int (*func)(glite_jp_context_t, void *), - void *arg -) -{ - int (**v)(glite_jp_context_t, void *) = ctx->deferred_func; - int i; - - for (i=0; v && *v; i++); - - ctx->deferred_func = realloc(ctx->deferred_func, (i+1) * sizeof *ctx->deferred_func); - ctx->deferred_func[i] = func; - ctx->deferred_func[i+1] = NULL; - - ctx->deferred_arg = realloc(ctx->deferred_arg,(i+1) * sizeof *ctx->deferred_arg); - ctx->deferred_arg[i] = arg; - ctx->deferred_arg[i+1] = NULL; - - return 0; -} diff --git a/org.glite.jp.common/src/strmd5.c b/org.glite.jp.common/src/strmd5.c deleted file mode 100755 index 87fd400..0000000 --- a/org.glite.jp.common/src/strmd5.c +++ /dev/null @@ -1,115 +0,0 @@ -#include -#include -#include -#include - -#include "strmd5.h" - -static char mbuf[33]; - -static int base64_encode(const void *enc, int enc_size, char *out, int out_max_size) -{ - static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - - unsigned char* enc_buf = (unsigned char*)enc; - int out_size = 0; - unsigned int bits = 0; - unsigned int shift = 0; - - while ( out_size < out_max_size ) { - if ( enc_size>0 ) { - // Shift in byte - bits <<= 8; - bits |= *enc_buf; - shift += 8; - // Next byte - enc_buf++; - enc_size--; - } else if ( shift>0 ) { - // Pad last bits to 6 bits - will end next loop - bits <<= 6 - shift; - shift = 6; - } else { - // Terminate with Mime style '=' - *out = '='; - out_size++; - - return out_size; - } - - // Encode 6 bit segments - while ( shift>=6 ) { - shift -= 6; - *out = b64[ (bits >> shift) & 0x3F ]; - out++; - out_size++; - } - } - - // Output overflow - return -1; -} - -char *strmd5(const char *s, unsigned char *digest) -{ - MD5_CTX md5; - unsigned char d[16]; - int i; - - MD5_Init(&md5); - MD5_Update(&md5,s,strlen(s)); - MD5_Final(d,&md5); - - if (digest) memcpy(digest,d,sizeof(d)); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - mbuf[32] = 0; - return (char *) mbuf; -} - -char *str2md5(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char* ret = malloc(33); - int i; - - if (!ret) - return NULL; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - ret[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - ret[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - ret[32] = 0; - return ret; -} - -char *str2md5base64(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char buf[50]; - int l; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - l = base64_encode(d, 16, buf, sizeof(buf) - 1); - if (l < 1) - return NULL; - buf[l - 1] = 0; - return strdup(buf); -} diff --git a/org.glite.jp.index/.cvsignore b/org.glite.jp.index/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.index/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.index/Makefile b/org.glite.jp.index/Makefile deleted file mode 100644 index 3b893cd..0000000 --- a/org.glite.jp.index/Makefile +++ /dev/null @@ -1,129 +0,0 @@ -# defaults -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -lbprefix=lb -package=glite-lb-server -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -expat_prefix=/opt/expat -ares_prefix=/opt/ares -gsoap_prefix=/software/gsoap-2.6 - -CC=gcc - --include Makefile.inc - - -VPATH=${top_srcdir}/src:${top_srcdir}/examples:${top_srcdir}/test:${top_srcdir}/project:${jpproject} - -GLOBUS_LIBS:=-L${globus_prefix}/lib \ - -lglobus_common_${nothrflavour} \ - -lglobus_gssapi_gsi_${nothrflavour} - -DEBUG:=-g -O0 -DDEBUG - -CFLAGS:=${DEBUG} -I. -I${gsoap_prefix}/include -I${stagedir}/include -LDFLAGS:=-L${stagedir}/lib - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - - -daemon:=glite-jp-indexd -example:=jpis-test -soap_prefix:=jpis_ - -SRCS:= simple_server.c soap_ops.c \ - ${soap_prefix}C.c \ - ${soap_prefix}Server.c - -EXA_SRCS:=jpis-test.c ${soap_prefix}C.c ${soap_prefix}Client.c - - -OBJS:=${SRCS:.c=.o} stdsoap2.o -EXA_OBJS:=${EXA_SRCS:.c=.o} stdsoap2.o - -COMMONLIB:=-lglite_jp_common - -default all: compile - -compile: ${daemon} ${example} - -${daemon}: ${OBJS} - ${LINK} -o $@ ${OBJS} ${COMMONLIB} ${GLOBUS_LIBS} - -${example}: ${EXA_OBJS} - ${LINK} -o $@ ${EXA_OBJS} - -JobProvenanceIS.xh: JobProvenanceIS.wsdl JobProvenanceTypes.wsdl typemap.dat - cp ${jpproject}/JobProvenanceTypes.wsdl . - ${gsoap_prefix}/bin/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< - rm -f JobProvenanceTypes.wsdl - -${soap_prefix}C.c ${soap_prefix}H.h: JobProvenanceIS.xh - ${gsoap_prefix}/bin/soapcpp2 -w -c -p ${soap_prefix} JobProvenanceIS.xh - -#$(SOAP_PREFIX)H.h $(SOAP_PREFIX)C.c: LB.xh -# $(GSOAP_BIN_PATH)/soapcpp2 -w -c -p $(SOAP_PREFIX) LB.xh -# -#LB.xh: LB.wsdl typemap.dat -# $(GSOAP_BIN_PATH)/wsdl2h -c -o $@ LB.wsdl -# - - -check: - -echo nothing yet - -doc: - -stage: compile - ${INSTALL} -m 755 ${daemon} ${stagedir}/bin - -dist: distsrc distbin - -# FIXME: just copied from LB -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - -mkdir -p ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/etc/init.d - for p in bkserverd bkindex; do \ - ${INSTALL} -m 755 "glite_lb_$$p" "${PREFIX}/bin/glite-lb-$$p"; \ - done - - for f in dbsetup.sql index.conf.template; do \ - ${INSTALL} -m 644 ${top_srcdir}/config/"glite-lb-$$f" ${PREFIX}/etc; \ - done - - ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-lb-bkserverd - -clean: - -soap_ops.o jpis-test.o simple_server.o: ${soap_prefix}H.h - -# we have no real config.h but have to force gSoap not to use -# linux ftime with broken (aka obsolete) DST information - -stdsoap2.o: ${gsoap_prefix}/devel/stdsoap2.c - test -f config.h || touch config.h - @echo 'The following warning "time_t (de)serialization is not MT safe on this platform" is harmless' - ${CC} -o $@ -c -DHAVE_CONFIG_H ${CFLAGS} ${gsoap_prefix}/devel/stdsoap2.c - diff --git a/org.glite.jp.index/build.xml b/org.glite.jp.index/build.xml deleted file mode 100755 index 547659a..0000000 --- a/org.glite.jp.index/build.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.index/project/JobProvenanceIS.wsdl b/org.glite.jp.index/project/JobProvenanceIS.wsdl deleted file mode 100644 index 26f97a4..0000000 --- a/org.glite.jp.index/project/JobProvenanceIS.wsdl +++ /dev/null @@ -1,531 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Register job with JP primary storage. -Job registration in LB is propagated to JP immediately so that JP is aware of the job, -despite no furhter information is available in it. - -Input: JobId - -Output: N/A - -Faults: GenericJPFault - - - - - - - Initiate upload of of sandbox/dump of job life log from LB. -WM component responsible for job sandbox management and LB server call JP to declare -intention to upload intput/output sandbox and job life log. - -Input: - -uclass: type of the upload - INPUT_SANDBOX, OUTPUT_SANDBOX, JOB_LOG - -commitTimeout: upper limit on time for which JP waits for committing this upload transaction - -contentType: MIME type of the uploaded file - -Output: - -destination: URL where the client should upload the file - -commitBefore: acutual time when the upload transaction times out - -Faults: GenericJPFault - - -Initiate upload of of sandbox/dump of job life log from LB. - - - - - - Confirm upload. -Should be called after a file upload initiaded with StartUpload is finished. - -Input: - -destination: Upload destination URL (to match with the original request) - -Output: - -Faults: GenericJPFault - - - - - - - Record a value of user tag. -JP tags are either standalone or override values of their LB counterparts. -However, JP tag values are still distinguishable those inherited from LB. -JP tags may be either strings or blobs. - -Input: - -jobid: - -tag: structure containing name, timestamp, optional sequence number to order tag values -without relying on timestamps, and string or blob value. - -Output: N/A - -Faults: GenericJPFault - - - - - - - Start feeding JP index server. -Called by the index server to start batch feed, and optionally also subscribe for incremental feed. - -JP index server subscribes with JP primary storage using a query -containing conditions on primary metadata and a list of queryable attributes -of the index server (i.e. data which should be sent to the index server). - -When a matching job record is created or modified within the primary storage -the job record data are sent to the subscribed index server. - -The subscription is soft-state, it expires after certain time unless refreshed by the client explicitely. - -In the batch mode the query has the same form -with additional flag asking for all matching records (i.e.\ not only -arriving afterwards). - -Input: - -destination: where to send the job record data - -attributes: which job record attributes should be sent to the requesting index server - -conditions: list of query conditions. Each conditions has the form Attribute Operator Value, -where Attribute is any of job record attributes and Operator is one of EQUAL, UNEQUAL, LESS, GREATER, WITHIN. - -continuous: flag determining that the query is incremental (not batch) - -Output: - -feedId: unique Id of the feed request, to be used in refresh, cancelation etc. - -expires: when the feed times out. Must be refreshed before this time. - -Faults: GenericJPFault - - - - - - - Extend batch feed subscription (used by index server) - -Input: feedId returned previously by FeedIndex - -Output: the same as for FeedIndex - -Faults: GenericJPFault - - - - - - - Retrieve job record URL's when jobid is known -Used either to bypass JP index server query for this specific case, or after the index server query to -retrieve actual job record. - -Input: jobid - -Output: - -jobLog, inputSandbox, outputSandbox, tags: URL's to components of the job record. - -Faults: GenericJPFault - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Job Provenance Primary Storage service - - - - - - - - - - - - - - - - - - - - - - Store or update information on jobs within the JP index server. -Called directly by the primary storage, used for both batch and incremental feed. - -Input: - -data: list of job record updates. Each contains jobid, list of JP attribute values and user tag values. - -feedDone: flag indicating end of batch feed. (In order to avoid potential problems with buffer allocation -the huge dataset of batch feed is split into reasonable chunks and delivered with more UpdateJobs calls.) - -Output: N/A - -Faults: GenericJPFault - - - - - - - - - Retrieve pointers to job records of jobs matching a query. -Input: conditions - list of lists of query conditions. - Elements of the inner lists refer to a single job attribute, the conditions are or-ed. - Elements of the outer list may refer to different job attributes, they are and-ed. - -Output: - -jobs: list of JobId, PSContact (URL of the primary storage which manges this job) pairs - -Faults: GenericJPFault - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Job Provenance Index service - - - - - - - diff --git a/org.glite.jp.index/project/build.properties b/org.glite.jp.index/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.index/project/configure.properties.xml b/org.glite.jp.index/project/configure.properties.xml deleted file mode 100644 index 72af8f4..0000000 --- a/org.glite.jp.index/project/configure.properties.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -version=${module.version} -glite_location=${with.glite.location} -globus_prefix=${with.globus.prefix} -expat_prefix=${with.expat.prefix} -gsoap_prefix=${with.gsoap.prefix} -ares_prefix=${with.ares.prefix} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} - - - diff --git a/org.glite.jp.index/project/properties.xml b/org.glite.jp.index/project/properties.xml deleted file mode 100755 index 5f56392..0000000 --- a/org.glite.jp.index/project/properties.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.index/project/tar_exclude b/org.glite.jp.index/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.index/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.index/project/version.properties b/org.glite.jp.index/project/version.properties deleted file mode 100644 index a0d1638..0000000 --- a/org.glite.jp.index/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ -#Fri Dec 10 13:35:33 CET 2004 -module.version=0.1.0 -module.build=2 -module.age=1 diff --git a/org.glite.jp.index/src/simple_server.c b/org.glite.jp.index/src/simple_server.c deleted file mode 100644 index ccaa5a7..0000000 --- a/org.glite.jp.index/src/simple_server.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "jpis_H.h" - -int main() { - struct soap soap; - int i, m, s; // master and slave sockets - - glite_jp_context_t ctx; - - soap_init(&soap); - glite_jp_init_context(&ctx); - soap.user = (void *) ctx; - - srand48(time(NULL)); /* feed id generation */ - - m = soap_bind(&soap, NULL, 8902, 100); - if (m < 0) - soap_print_fault(&soap, stderr); - else - { - fprintf(stderr, "Socket connection successful: master socket = %d\n", m); - for (i = 1; ; i++) { - s = soap_accept(&soap); - if (s < 0) { - soap_print_fault(&soap, stderr); - break; - } - soap_serve(&soap); // process RPC request - soap_destroy(&soap); // clean up class instances - soap_end(&soap); // clean up everything and close socket - glite_jp_run_deferred(ctx); - } - } - soap_done(&soap); // close master socket - - return 0; -} diff --git a/org.glite.jp.index/src/soap_ops.c b/org.glite.jp.index/src/soap_ops.c deleted file mode 100644 index 5af7352..0000000 --- a/org.glite.jp.index/src/soap_ops.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "jpis_H.h" -#include "JobProvenanceIS.nsmap" - -static struct jptype__GenericJPFaultType *jp2s_error(struct soap *soap, - const glite_jp_error_t *err) -{ - struct jptype__GenericJPFaultType *ret = NULL; - if (err) { - ret = soap_malloc(soap,sizeof *ret); - memset(ret,0,sizeof *ret); - ret->code = err->code; - ret->source = soap_strdup(soap,err->source); - ret->text = soap_strdup(soap,strerror(err->code)); - ret->description = soap_strdup(soap,err->desc); - ret->reason = jp2s_error(soap,err->reason); - } - return ret; -} - -static void err2fault(const glite_jp_context_t ctx,struct soap *soap) -{ - char *et; - struct SOAP_ENV__Detail *detail = soap_malloc(soap,sizeof *detail); - struct _GenericJPFault *f = soap_malloc(soap,sizeof *f); - - - f->jptype__GenericJPFault = jp2s_error(soap,ctx->error); - - detail->__type = SOAP_TYPE__GenericJPFault; - detail->value = f; - detail->__any = NULL; - - soap_receiver_fault(soap,"Oh, shit!",NULL); - if (soap->version == 2) soap->fault->SOAP_ENV__Detail = detail; - else soap->fault->detail = detail; -} - -static void s2jp_tag(const struct jptype__TagValue *stag,glite_jp_tagval_t *jptag) -{ - memset(jptag,0,sizeof *jptag); - jptag->name = strdup(stag->name); - jptag->sequence = stag->sequence ? *stag->sequence : 0; - jptag->timestamp = stag->timestamp ? *stag->timestamp : 0; - if (stag->stringValue) jptag->value = strdup(stag->stringValue); - else if (stag->blobValue) { - jptag->binary = 1; - jptag->size = stag->blobValue->__size; - jptag->value = (char *) stag->blobValue->__ptr; - } -} - -#define CONTEXT_FROM_SOAP(soap,ctx) glite_jp_context_t ctx = (glite_jp_context_t) ((soap)->user) - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__UpdateJobs( - struct soap *soap, - char *feed_id, - struct jptype__UpdateJobsData *jobs, - enum xsd__boolean done -) -{ - printf("%s items %d jobid %s\n",__FUNCTION__,jobs->__sizejob, - jobs->job[0]->jobid); - return SOAP_OK; -} - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__QueryJobs( - struct soap *soap, - struct jptype__IndexQuery *query, - struct jpsrv__QueryJobsResponse *resp -) -{ - puts(__FUNCTION__); - return SOAP_OK; -} - diff --git a/org.glite.jp.index/src/typemap.dat b/org.glite.jp.index/src/typemap.dat deleted file mode 100644 index 7032cb2..0000000 --- a/org.glite.jp.index/src/typemap.dat +++ /dev/null @@ -1,2 +0,0 @@ -jpsrv = http://glite.org/wsdl/services/jp -jptype = http://glite.org/wsdl/types/jp diff --git a/org.glite.jp.primary/.cvsignore b/org.glite.jp.primary/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.primary/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.primary/Makefile b/org.glite.jp.primary/Makefile deleted file mode 100644 index 2e9b3c4..0000000 --- a/org.glite.jp.primary/Makefile +++ /dev/null @@ -1,148 +0,0 @@ -# defaults -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -jpprefix=jp -package=glite-jp-primary -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -expat_prefix=/opt/expat -ares_prefix=/opt/ares -gsoap_prefix=/software/gsoap-2.6 - -CC=gcc - --include Makefile.inc - - -VPATH=${top_srcdir}/src:${top_srcdir}/examples:${top_srcdir}/test:${top_srcdir}/project:${stagedir}/interface - -GLOBUS_LIBS:=-L${globus_prefix}/lib \ - -lglobus_common_${nothrflavour} \ - -lglobus_gssapi_gsi_${nothrflavour} - -DEBUG:=-g -O0 -DDEBUG - -CFLAGS:=${DEBUG} -I. -I${top_srcdir}/src -I${gsoap_prefix}/include -I${stagedir}/include -LDFLAGS:=-L${stagedir}/lib - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - - -daemon:=glite-jp-primarystoraged -example:=jpps-test -ps_prefix:=jpps_ -is_prefix:=jpis_ - -gsoap_version=`${gsoap_prefix}/bin/soapcpp2 -version 2>&1 | cut -d' ' -f4 | perl -F\\\\. -nae '$$F[2] =~ s/\D*$$//; print $$F[2]+100*$$F[1]+10000*$$F[0]'` - -CFLAGS+=-DGSOAP_VERSION=${gsoap_version} - - -SRCS:= simple_server.c soap_ops.c \ - ftp_backend.c \ - feed.c tags.c\ - is_client.c \ - ${ps_prefix}ServerLib.c \ - ${is_prefix}ClientLib.c jpps_C.c -# env_C.c - -EXA_SRCS:=jpps-test.c ${ps_prefix}C.c ${ps_prefix}Client.c - - -OBJS:=${SRCS:.c=.o} -EXA_OBJS:=${EXA_SRCS:.c=.o} - -COMMONLIB:=-lglite_jp_common -GSOAPLIB:=-L${gsoap_prefix}/lib -lgsoap${GSOAP_DEBUG} - -default all: compile - -compile: ${daemon} ${example} - -${daemon}: ${OBJS} - ${LINK} -o $@ ${OBJS} ${COMMONLIB} ${GSOAPLIB} ${GLOBUS_LIBS} - -${example}: ${EXA_OBJS} - ${LINK} -o $@ ${EXA_OBJS} ${GSOAPLIB} - -JobProvenanceIS.xh JobProvenancePS.xh: %.xh: %.wsdl JobProvenanceTypes.wsdl typemap.dat - cp ${stagedir}/interface/JobProvenanceTypes.wsdl . - ${gsoap_prefix}/bin/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< - rm -f JobProvenanceTypes.wsdl - -${ps_prefix}Client.c ${ps_prefix}ClientLib.c \ -${ps_prefix}Server.c ${ps_prefix}ServerLib.c \ -${ps_prefix}C.c ${ps_prefix}H.h: JobProvenancePS.xh - ${gsoap_prefix}/bin/soapcpp2 -n -w -c -p ${ps_prefix} JobProvenancePS.xh - -${is_prefix}ClientLib.c ${is_prefix}Client.c \ -${is_prefix}C.c ${is_prefix}H.h: JobProvenanceIS.xh - ${gsoap_prefix}/bin/soapcpp2 -n -w -c -p ${is_prefix} JobProvenanceIS.xh - -env_C.c env_Server.c: - touch env.xh - cp ${jpproject}/JobProvenanceTypes.wsdl . - ${gsoap_prefix}/bin/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o env.xh JobProvenanceTypes.wsdl - rm -f JobProvenanceTypes.wsdl - ${gsoap_prefix}/bin/soapcpp2 -w -c -p env_ env.xh - -#$(SOAP_PREFIX)H.h $(SOAP_PREFIX)C.c: LB.xh -# $(GSOAP_BIN_PATH)/soapcpp2 -w -c -p $(SOAP_PREFIX) LB.xh -# -#LB.xh: LB.wsdl typemap.dat -# $(GSOAP_BIN_PATH)/wsdl2h -c -o $@ LB.wsdl -# - - -simple_server.o: ${is_prefix}H.h ${ps_prefix}H.h - -check: - -echo nothing yet - -doc: - -stage: compile - ${MAKE} PREFIX=${stagedir} DOSTAGE=yes install - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - -mkdir -p ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/examples ${PREFIX}/etc/init.d - ${INSTALL} -m 755 ${daemon} ${PREFIX}/bin - ${INSTALL} -m 755 jpps-test ${PREFIX}/examples/glite-jp-primary-test - - -clean: - -simple_server.o soap_ops.o jpps-test.o: ${ps_prefix}H.h - -# we have no real config.h but have to force gSoap not to use -# linux ftime with broken (aka obsolete) DST information - -stdsoap2.o: ${gsoap_prefix}/devel/stdsoap2.c - test -f config.h || touch config.h - @echo 'The following warning "time_t (de)serialization is not MT safe on this platform" is harmless' - ${CC} -o $@ -c -DWITH_NONAMESPACES -DHAVE_CONFIG_H ${CFLAGS} ${gsoap_prefix}/devel/stdsoap2.c - diff --git a/org.glite.jp.primary/build.xml b/org.glite.jp.primary/build.xml deleted file mode 100755 index 28c0d13..0000000 --- a/org.glite.jp.primary/build.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.primary/examples/jpps-test.c b/org.glite.jp.primary/examples/jpps-test.c deleted file mode 100644 index 8cf9c6f..0000000 --- a/org.glite.jp.primary/examples/jpps-test.c +++ /dev/null @@ -1,194 +0,0 @@ -#include -#include -#include -#include - -#include "jpps_H.h" -#include "jpps_.nsmap" - -#include "jptype_map.h" - -static void usage(const char *me) -{ - fprintf(stderr,"%s: [-s server-url] operation args \n\n" - " operations are:\n" - " RegisterJob jobid\n" - " StartUpload jobid class(0,1,2) commit_before mimetype\n" - " CommitUpload destination\n" - " RecordTag jobid tagname sequence stringvalue\n" - " GetJob jobid\n" - " FeedIndex destination query_number history continuous\n" - " FeedIndexRefresh feedid\n" - ,me); - - exit (EX_USAGE); -} - -static int check_fault(struct soap *soap,int err) { - struct SOAP_ENV__Detail *detail; - struct jptype__GenericJPFaultType *f; - char *reason,indent[200] = " "; - - switch(err) { - case SOAP_OK: puts("OK"); - break; - case SOAP_FAULT: - case SOAP_SVR_FAULT: - if (soap->version == 2) { - detail = soap->fault->SOAP_ENV__Detail; - reason = soap->fault->SOAP_ENV__Reason; - } - else { - detail = soap->fault->detail; - reason = soap->fault->faultstring; - } - fputs(reason,stderr); - putc('\n',stderr); - assert(detail->__type == SOAP_TYPE__GenericJPFault); -#if GSOAP_VERSION >=20700 - f = ((struct _GenericJPFault *) detail->fault) -#else - f = ((struct _GenericJPFault *) detail->value) -#endif - -> jptype__GenericJPFault; - - while (f) { - fprintf(stderr,"%s%s: %s (%s)\n",indent, - f->source,f->text,f->description); - f = f->reason; - strcat(indent," "); - } - return -1; - - default: soap_print_fault(soap,stderr); - return -1; - } - return 0; -} - -static struct jptype__Attribute sample_attr[] = { - { OWNER, NULL }, - { TIME, "submitted" }, - { TAG, "test" }, -}; - -static struct jptype__PrimaryQueryElement sample_query[][5] = { - { - { sample_attr+OWNER, EQUAL, "unknown", NULL }, - { NULL, 0, NULL, NULL } - }, -}; - -int main(int argc,char *argv[]) -{ - char *server = "http://localhost:8901"; - int opt; - struct soap *soap = soap_new(); - - if (argc < 2) usage(argv[0]); - - soap_init(soap); - soap_set_namespaces(soap, jpps__namespaces); - - while ((opt = getopt(argc,argv,"s:")) >= 0) switch (opt) { - case 's': server = optarg; - argv += 2; - break; - case '?': usage(argv[0]); - } - - if (!strcasecmp(argv[1],"RegisterJob")) { - struct jpsrv__RegisterJobResponse r; - - if (argc != 3) usage(argv[0]); - check_fault(soap, - soap_call_jpsrv__RegisterJob(soap,server,"",argv[2],&r)); - } else if (!strcasecmp(argv[1], "StartUpload")) { - struct jpsrv__StartUploadResponse r; - - if (argc != 6) usage(argv[0]); - if (!check_fault(soap, - soap_call_jpsrv__StartUpload(soap, server, "", - argv[2], atoi(argv[3]), atoi(argv[4]), argv[5], &r))) { - printf("Destination: %s\nCommit before: %s\n", r.destination, ctime(&r.commitBefore)); - } - } else if (!strcasecmp(argv[1], "CommitUpload")) { - struct jpsrv__CommitUploadResponse r; - - if (argc != 3) usage(argv[0]); - if (!check_fault(soap, - soap_call_jpsrv__CommitUpload(soap, server, "", - argv[2], &r))) { - /* OK */ - } - } else if (!strcasecmp(argv[1], "RecordTag")) { - struct jpsrv__RecordTagResponse r; - struct jptype__TagValue tagval; - - if (argc != 6) usage(argv[0]); - - tagval.name = argv[3]; - tagval.sequence = NULL; - tagval.timestamp = NULL; - tagval.stringValue = argv[5]; - tagval.blobValue = NULL; - - if (!check_fault(soap, - soap_call_jpsrv__RecordTag(soap, server, "", - argv[2], &tagval, &r))) { - /* OK */ - } - } else if (!strcasecmp(argv[1],"FeedIndex")) { - struct jpsrv__FeedIndexResponse r; - struct jptype__Attribute *ap[2]; - struct jptype__Attributes attr = { 2, ap }; - struct jptype__PrimaryQueryElement *qp[100]; - struct jptype__PrimaryQuery qry = { 0, qp }; - - int i,j,qi = atoi(argv[3])-1; - - if (argc != 6) usage(argv[0]); - - for (i=0; i - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.primary/project/tar_exclude b/org.glite.jp.primary/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.primary/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.primary/project/version.properties b/org.glite.jp.primary/project/version.properties deleted file mode 100644 index 1343828..0000000 --- a/org.glite.jp.primary/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ -#Fri Dec 10 13:37:05 CET 2004 -module.version=0.1.0 -module.build=3 -module.age=1 diff --git a/org.glite.jp.primary/src/backend.h b/org.glite.jp.primary/src/backend.h deleted file mode 100644 index bb143e9..0000000 --- a/org.glite.jp.primary/src/backend.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef __GLITE_JP_BACKEND -#define __GLITE_JP_BACKEND - -#include -#include - -int glite_jppsbe_init( - glite_jp_context_t ctx, - int *argc, - char *argv[] -); - -int glite_jppsbe_init_slave( - glite_jp_context_t ctx -); - -int glite_jppsbe_register_job( - glite_jp_context_t ctx, - const char *job, - const char *owner -); - -int glite_jppsbe_start_upload( - glite_jp_context_t ctx, - const char *job, - glite_jp_fileclass_t class, - const char *content_type, - char **destination_out, - time_t *commit_before_inout -); - -int glite_jppsbe_commit_upload( - glite_jp_context_t ctx, - const char *destination -); - -int glite_jppsbe_destination_info( - glite_jp_context_t ctx, - const char *destination, - char **job_out, - glite_jp_fileclass_t *class_out -); - -int glite_jppsbe_get_job_url( - glite_jp_context_t ctx, - const char *job, - glite_jp_fileclass_t class, - char **url_out -); - -int glite_jppsbe_open_file( - glite_jp_context_t ctx, - const char *job, - glite_jp_fileclass_t class, - int mode, - void **handle_out -); - -int glite_jppsbe_close_file( - glite_jp_context_t ctx, - void *handle -); - -int glite_jppsbe_pread( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes, - off_t offset, - ssize_t *nbytes_ret -); - -int glite_jppsbe_pwrite( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes, - off_t offset -); - -int glite_jppsbe_append( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes -); - -int glite_jppsbe_get_job_metadata( - glite_jp_context_t ctx, - const char *job, - glite_jp_attrval_t attrs_inout[] -); - -int glite_jppsbe_query( - glite_jp_context_t ctx, - const glite_jp_query_rec_t query[], - const glite_jp_attrval_t metadata[], - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[] - ) -); - -#endif diff --git a/org.glite.jp.primary/src/feed.c b/org.glite.jp.primary/src/feed.c deleted file mode 100644 index 297eb23..0000000 --- a/org.glite.jp.primary/src/feed.c +++ /dev/null @@ -1,264 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/strmd5.h" -#include "feed.h" - - -/* - * seconds before feed expires: should be - * XXX: should be configurable, default for real deployment sort of 1 hour - */ -#define FEED_TTL 120 - -static int check_qry_item( - glite_jp_context_t ctx, - const glite_jp_query_rec_t *qry, - const glite_jp_attrval_t *attr -) -{ - int cmp,cmp2; - long scmp,ucmp; - - switch (qry->attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - cmp = strcmp(attr->value.s,qry->value.s); - break; - case GLITE_JP_ATTR_TIME: - scmp = (ucmp = attr->value.time.tv_usec - qry->value.time.tv_usec) > 0 ? 0 : -1; - ucmp -= 1000000 * scmp; - scmp += attr->value.time.tv_sec - qry->value.time.tv_sec; - cmp = scmp ? scmp : ucmp; - break; - } - switch (qry->op) { - case GLITE_JP_QUERYOP_EQUAL: return !cmp; - case GLITE_JP_QUERYOP_UNEQUAL: return cmp; - case GLITE_JP_QUERYOP_LESS: return cmp < 0; - case GLITE_JP_QUERYOP_GREATER: return cmp > 0; - - case GLITE_JP_QUERYOP_WITHIN: - switch (qry->attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - cmp2 = strcmp(attr->value.s,qry->value2.s); - break; - case GLITE_JP_ATTR_TIME: - scmp = (ucmp = attr->value.time.tv_usec - qry->value2.time.tv_usec) > 0 ? 0 : -1; - ucmp -= 1000000 * scmp; - scmp += attr->value.time.tv_sec - qry->value2.time.tv_sec; - cmp2 = scmp ? scmp : ucmp; - break; - } - return cmp >= 0 && cmp2 <= 0; - } -} - -/* XXX: limit on query size -- I'm lazy to malloc() */ -#define QUERY_MAX 100 - -static int match_feed( - glite_jp_context_t ctx, - const struct jpfeed *feed, - const char *job, - const glite_jp_attrval_t attrs[] /* XXX: not checked for correctness */ -) -{ - int i; - int attri[GLITE_JP_ATTR__LAST]; - int qi[QUERY_MAX]; - - glite_jp_attrval_t *newattr = NULL; - - glite_jp_clear_error(ctx); - - for (i=0; iqry) { - int j,complete = 1; - - memset(qi,0,sizeof qi); - for (i=0; feed->qry[i].attr.type; i++) { - assert(iqry[i].attr.type]) >=0) { - if (check_qry_item(ctx,feed->qry+i,attrs+j)) - qi[i] = 1; /* matched */ - else return 0; /* can't be satisfied */ - } - else complete = 0; - } - - /* not all attributes in query are known from input - * we have to retrieve job metadata from the backend - */ - if (!complete) { - glite_jp_attrval_t meta[GLITE_JP_ATTR__LAST+1]; - int qai[GLITE_JP_ATTR__LAST]; - - memset(meta,0,sizeof meta); - j=0; - for (i=0; feed->qry[i].attr.type; i++) if (!qi[i]) { - meta[j].attr.type = feed->qry[i].attr.type; - meta[j].attr.name = feed->qry[i].attr.name; - qai[feed->qry[i].attr.type] = i; - j++; - } - - if (glite_jppsbe_get_job_metadata(ctx,job,meta)) { - glite_jp_error_t err; - err.code = EIO; - err.source = __FUNCTION__; - err.desc = "complete query"; - return glite_jp_stack_error(ctx,&err); - } - - for (i=0; j=meta[i].attr.type; i++) - if (!check_qry_item(ctx,feed->qry+qai[j],meta+i)) - return 0; - } - } - - /* matched completely */ - return glite_jpps_single_feed(ctx,feed->destination,job,attrs); - return 0; -} - -int glite_jpps_match_attr( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t attrs[] -) -{ - struct jpfeed *f = (struct jpfeed *) ctx->feeds; - int i,j; - int attri[GLITE_JP_ATTR__LAST]; - - glite_jp_clear_error(ctx); - - for (i=0; i= GLITE_JP_ATTR__LAST || - attrs[i].attr.type <= 0) - { - glite_jp_error_t err; - err.code = EINVAL; - err.source = __FUNCTION__; - err.desc = "unknown attribute"; - return glite_jp_stack_error(ctx,&err); - } - if (attri[attrs[i].attr.type] >= 0) { - glite_jp_error_t err; - err.code = EINVAL; - err.source = __FUNCTION__; - err.desc = "double attribute change"; - return glite_jp_stack_error(ctx,&err); - } - - attri[attrs[i].attr.type] = i; - } - - for (;f; f = f->next) { - for (i=0; f->attrs[i].type && attri[f->attrs[i].type] == -1; i++); - /* XXX: ignore any errors */ - if (f->attrs[i].type) match_feed(ctx,f,job,attrs); - } - - return glite_jp_clear_error(ctx); -} - -int glite_jpps_match_file( - glite_jp_context_t ctx, - const char *job, - glite_jp_fileclass_t class -) -{ - fprintf(stderr,"%s: \n",__FUNCTION__); - return 0; -} - -int glite_jpps_match_tag( - glite_jp_context_t ctx, - const char *job, - const glite_jp_tagval_t *tag -) -{ - fprintf(stderr,"%s: \n",__FUNCTION__); - return 0; -} - -static char *generate_feedid(void) -{ - char hname[200],buf[1000]; - - gethostname(hname,sizeof hname); - snprintf(buf,sizeof buf,"%s%d%ld",hname,getpid(),lrand48()); - buf[sizeof buf-1] = 0; - return str2md5base64(buf); -} - - -int glite_jpps_run_feed( - glite_jp_context_t ctx, - const char *destination, - const glite_jp_attr_t *attrs, - const glite_jp_query_rec_t *qry, - char **feed_id) -{ - fprintf(stderr,"%s: \n",__FUNCTION__); - return 0; -} - -static int register_feed_deferred(glite_jp_context_t ctx,void *feed) -{ - struct jpfeed *f = feed; - - f->next = ctx->feeds; - ctx->feeds = f; - return 0; -} - -/* FIXME: - * - volatile implementation: should store the registrations in a file - * and recover after restart - * - should communicate the data among all server slaves - */ -int glite_jpps_register_feed( - glite_jp_context_t ctx, - const char *destination, - const glite_jp_attr_t *attrs, - const glite_jp_query_rec_t *qry, - char **feed_id, - time_t *expires) -{ - int i; - struct jpfeed *f = calloc(1,sizeof *f); - - if (!*feed_id) *feed_id = generate_feedid(); - time(expires); *expires += FEED_TTL; - - f->id = strdup(*feed_id); - f->destination = strdup(destination); - f->expires = *expires; - for (i=0; attrs[i].type; i++) { - f->attrs = realloc(f->attrs,(i+2) * sizeof *f->attrs); - glite_jp_attr_copy(f->attrs+i,attrs+i); - memset(f->attrs+i+1,0,sizeof *f->attrs); - } - for (i=0; qry[i].attr.type; i++) { - f->qry = realloc(f->qry,(i+2) * sizeof *f->qry); - glite_jp_queryrec_copy(f->qry+i,qry+i); - memset(f->qry+i+1,0,sizeof *f->qry); - } - - glite_jp_add_deferred(ctx,register_feed_deferred,f); - - return 0; -} - diff --git a/org.glite.jp.primary/src/feed.h b/org.glite.jp.primary/src/feed.h deleted file mode 100644 index 1551a82..0000000 --- a/org.glite.jp.primary/src/feed.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __GLITE_JP_FEED -#define __GLITE_JP_FEED - - -struct jpfeed { - char *id,*destination; - time_t expires; - glite_jp_attr_t *attrs; - glite_jp_query_rec_t *qry; - struct jpfeed *next; -}; - - -int glite_jpps_match_attr(glite_jp_context_t,const char *,const glite_jp_attrval_t[]); -int glite_jpps_match_file(glite_jp_context_t,const char *,glite_jp_fileclass_t); -int glite_jpps_match_tag(glite_jp_context_t,const char *,const glite_jp_tagval_t *); -int glite_jpps_run_feed(glite_jp_context_t,const char *,const glite_jp_attr_t *,const glite_jp_query_rec_t *,char **); -int glite_jpps_register_feed(glite_jp_context_t,const char *,const glite_jp_attr_t *,const glite_jp_query_rec_t *,char **,time_t *); - -#endif - diff --git a/org.glite.jp.primary/src/ftp_backend.c b/org.glite.jp.primary/src/ftp_backend.c deleted file mode 100644 index b598f0a..0000000 --- a/org.glite.jp.primary/src/ftp_backend.c +++ /dev/null @@ -1,1701 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/strmd5.h" - -#include "tags.h" -#include "backend.h" - -#define UPLOAD_SUFFIX ".upload" -#define LOCK_SUFFIX ".lock" - -struct ftpbe_config { - char *internal_path; - char *external_path; - char *gridmap; - char *logname; -}; - -static struct ftpbe_config *config = NULL; - -struct fhandle_rec { - int fd; - int fd_append; -}; -typedef struct fhandle_rec *fhandle; - -static struct option ftpbe_opts[] = { - { "ftp-internal-path", 1, NULL, 'I' }, - { "ftp-external-path", 1, NULL, 'E' }, - { "ftp-gridmap", 1, NULL, 'G' }, - { NULL, 0, NULL, 0 } -}; - -static struct { - glite_jp_fileclass_t type; - char * fname; - } class_to_fname_tab[] = { - { GLITE_JP_FILECLASS_INPUT, "input" }, - { GLITE_JP_FILECLASS_OUTPUT, "output" }, - { GLITE_JP_FILECLASS_LBLOG, "lblog" }, - { GLITE_JP_FILECLASS_TAGS, "tags" }, - { GLITE_JP_FILECLASS_UNDEF, NULL } - }; - -static char *class_to_fname(glite_jp_fileclass_t type) -{ - int i; - - for (i = 0; class_to_fname_tab[i].type != GLITE_JP_FILECLASS_UNDEF; i++) - if (type == class_to_fname_tab[i].type) - return class_to_fname_tab[i].fname; - - return NULL; -} - -static glite_jp_fileclass_t fname_to_class(char* fname) -{ - int i; - - for (i = 0; class_to_fname_tab[i].type != GLITE_JP_FILECLASS_UNDEF; i++) - if (!strcmp(fname, class_to_fname_tab[i].fname)) - return class_to_fname_tab[i].type; - - return GLITE_JP_FILECLASS_UNDEF; -} - -static int config_check( - glite_jp_context_t ctx, - struct ftpbe_config *config) -{ - return config == NULL || - config->internal_path == NULL || - config->external_path == NULL || - config->gridmap == NULL || - config->logname == NULL; - - /* XXX check reality */ -} - -static int jobid_unique_pathname(glite_jp_context_t ctx, const char *job, - char **unique, char **ju_path, int get_path) -{ - char *p; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - p = strrchr(job, '/'); - if (!p) { - err.code = EINVAL; - err.desc = "Malformed jobid"; - return glite_jp_stack_error(ctx,&err); - } - /* XXX thorough checks */ - if (!(*unique = strdup(p+1))) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - if (get_path) { - if (!(*ju_path = strdup(p+1))) { - free(*unique); - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - *(*ju_path + 10) = '\0'; - } - return 0; -} - -static int mkdirpath(const char* path, int prefixlen) -{ - char *wpath, *p; - int goout, ret; - - wpath = strdup(path); - if (!wpath) { - errno = ENOMEM; - return -1; - } - - p = wpath + prefixlen; - goout = 0; - while (!goout) { - while (*p == '/') p++; - while (*p != '/' && *p != '\0') p++; - goout = (*p == '\0'); - *p = '\0'; - ret = mkdir(wpath, S_IRUSR | S_IWUSR | S_IXUSR); - if (ret < 0 && errno != EEXIST) break; - *p = '/'; - } - free(wpath); - return goout ? 0 : ret; -} - -static long regtime_trunc(long tv_sec) -{ - return tv_sec / (86400*7); -} - -static long regtime_ceil(long tv_sec) -{ - return (tv_sec % (86400*7)) ? tv_sec/(86400*7)+1 : tv_sec/(86400*7) ; -} - -/********************************************************************************/ -int glite_jppsbe_init( - glite_jp_context_t ctx, - int *argc, - char *argv[] -) -{ - glite_jp_error_t err; - int opt; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - config = (struct ftpbe_config *) calloc(1, sizeof *config); - if (!config) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - - config->logname = getlogin(); - - while ((opt = getopt_long(*argc, argv, "I:E:G:", ftpbe_opts, NULL)) != EOF) { - switch (opt) { - case 'I': config->internal_path = optarg; break; - case 'E': config->external_path = optarg; break; - case 'G': config->gridmap = optarg; break; - default: break; - } - } - - if (config_check(ctx, config)) { - err.code = EINVAL; - err.desc = "Invalid FTP backend configuration"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - -int glite_jppsbe_init_slave( - glite_jp_context_t ctx -) -{ - /* Nothing to do */ -} - -int glite_jppsbe_register_job( - glite_jp_context_t ctx, - const char *job, - const char *owner -) -{ - glite_jp_error_t err; - char *int_dir = NULL; - char *int_fname = NULL; - char *data_dir = NULL; - char *data_fname = NULL; - char *ju = NULL; - char *ju_path = NULL; - char *ownerhash = NULL; - FILE *regfile = NULL; - struct timeval reg_tv; - long reg_tv_trunc; - struct stat statbuf; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job != NULL); - assert(owner != NULL); - - gettimeofday(®_tv, NULL); - reg_tv_trunc = regtime_trunc(reg_tv.tv_sec); - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&int_dir, "%s/regs/%s", - config->internal_path, ju_path) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - - if (mkdirpath(int_dir, strlen(config->internal_path)) < 0 && - errno != EEXIST) { - free(int_dir); - err.code = errno; - err.desc = "Cannot mkdir jobs's reg directory"; - return glite_jp_stack_error(ctx,&err); - } - free(int_dir); - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - - if (stat(int_fname, &statbuf) < 0) { - if (errno != ENOENT) { - err.code = errno; - err.desc = "Cannot stat jobs's reg info file"; - goto error_out; - } - } else { - err.code = EEXIST; - err.desc = "Job already registered"; - goto error_out; - } - - regfile = fopen(int_fname, "w"); - if (regfile == NULL) { - err.code = errno; - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - - ownerhash = str2md5(owner); /* static buffer */ - - if (fprintf(regfile, "%d %ld.%06ld %s %s %d %s\n", 1, - (long)reg_tv.tv_sec, (long)reg_tv.tv_usec, job, - ownerhash, strlen(owner), owner) < 1 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot write jobs's reg info file"; - goto error_out; - } - if (fclose(regfile) != 0 ) { - err.code = errno; - err.desc = "Cannot close(write) jobs's reg info file"; - goto error_out; - } - - if (asprintf(&data_dir, "%s/data/%s/%d/%s", - config->internal_path, ownerhash, regtime_trunc(reg_tv.tv_sec), ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - if (asprintf(&data_fname, "%s/_info", data_dir) == -1) { - err.code = ENOMEM; - goto error_out; - } - if (mkdirpath(data_dir, strlen(config->internal_path)) < 0 && - errno != EEXIST) { - err.code = errno; - err.desc = "Cannot mkdir jobs's data directory"; - goto error_out; - } - - if (link(int_fname, data_fname) < 0) { - err.code = errno; - err.desc = "Cannot link job's reg and data info files"; - goto error_out; - } - -error_out: - free(int_fname); - free(data_fname); - if (err.code && data_dir) rmdir(data_dir); - free(data_dir); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -static int add_to_gridmap(glite_jp_context_t ctx, const char *dn) -{ - FILE *gridmap = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - gridmap = fopen(config->gridmap, "a"); - if (!gridmap) { - err.code = errno; - err.desc = "Cannot open gridmap file"; - return glite_jp_stack_error(ctx,&err); - } - if (fprintf(gridmap, "\"%s\" %s\n", dn, config->logname) < 6 || - ferror(gridmap)) { - err.code = EIO; - err.desc = "Cannot write to gridmap file"; - fclose(gridmap); - return glite_jp_stack_error(ctx,&err); - } - fclose(gridmap); - return 0; -} - -static int remove_from_gridmap(glite_jp_context_t ctx, const char *dn) -{ - FILE *gridmap = NULL; - char *temp_name = NULL; - FILE *temp_file = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - /* XXX */ - return 0; -} - -int glite_jppsbe_start_upload( - glite_jp_context_t ctx, - const char *job, - glite_jp_fileclass_t class, - const char *content_type, - char **destination_out, - time_t *commit_before_inout -) -{ - char *int_fname = NULL; - char *lock_fname = NULL; - FILE *lockfile = NULL; - FILE *regfile = NULL; - char *fname = NULL; - char *data_dir = NULL; - char *data_lock = NULL; - char *ju = NULL; - char *ju_path = NULL; - char *peername = NULL; - int info_version; - long reg_time; - char ownerhash[33]; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job!=NULL); - assert(destination_out!=NULL); - - fname = class_to_fname(class); - assert(fname!=NULL); - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - peername = glite_jp_peer_name(ctx); - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - if (errno == ENOENT) - err.desc = "Job not registered"; - else - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%*ld %*s %s ", &info_version, - ®_time, ownerhash) < 3 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - fclose(regfile); - - /* XXX authorization */ - - if (asprintf(&data_dir, "%s/data/%s/%d/%s", - config->internal_path, ownerhash, regtime_trunc(reg_time), ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (asprintf(&lock_fname, "%s/%s" LOCK_SUFFIX, - data_dir, fname) == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (commit_before_inout != NULL) - *commit_before_inout = (time_t) LONG_MAX; /* XXX no timeout enforced */ - - lockfile = fopen(lock_fname, "w"); - if (lockfile == NULL) { - err.code = errno; - err.desc = "Cannot open uploads's lock file"; - goto error_out; - } - - if (fprintf(lockfile, "%ld %d %s\n", (long)*commit_before_inout, - peername ? peername : 0, - peername ? peername : "") < 1 || ferror(regfile)) { - fclose(lockfile); - err.code = errno; - err.desc = "Cannot write upload's lock file"; - goto error_out; - } - if (fclose(lockfile) != 0 ) { - err.code = errno; - err.desc = "Cannot close(write) upload's lock file"; - goto error_out; - } - - if (asprintf(destination_out, "%s/data/%s/%d/%s/%s" UPLOAD_SUFFIX, - config->external_path, ownerhash, regtime_trunc(reg_time), ju, fname) == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (add_to_gridmap(ctx, peername)) { - err.code = EIO; - err.desc = "Cannot add peer DN to ftp server authorization file"; - goto error_out; - } - -error_out: - free(int_fname); - free(data_dir); - if (err.code && data_lock) unlink(data_lock); - free(data_lock); - free(ju); free(ju_path); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_commit_upload( - glite_jp_context_t ctx, - const char *destination -) -{ - size_t dest_len; - size_t suff_len; - size_t extp_len; - long commit_before; - int lockpeerlen; - char *lockpeername = NULL; - char *peername = NULL; - char *dest_rw = NULL; - char *dest_rw_suff = NULL; - char *dest_rw_lock = NULL; - FILE *lockfile = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(destination != NULL); - - suff_len = strlen(UPLOAD_SUFFIX); - dest_len = strlen(destination); - extp_len = strlen(config->external_path); - - if (dest_len < suff_len || - strcmp(UPLOAD_SUFFIX, destination + (dest_len - suff_len)) || - strncmp(destination, config->external_path, extp_len)) { - err.code = EINVAL; - err.desc = "Forged destination path"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&dest_rw_suff, "%s%s", config->internal_path, - destination + extp_len) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - dest_rw = strdup(dest_rw_suff); - if (!dest_rw) { - err.code = ENOMEM; - goto error_out; - } - *(dest_rw + (strlen(dest_rw_suff) - suff_len)) = '\0'; - - if (asprintf(&dest_rw_lock, "%s" LOCK_SUFFIX, dest_rw) == -1) { - err.code = ENOMEM; - goto error_out; - } - - lockfile = fopen(dest_rw_lock, "r"); - if (lockfile == NULL) { - err.code = errno; - err.desc = "Cannot open upload's lock file"; - goto error_out; - } - if (fscanf(lockfile, "%ld %d ", &commit_before, &lockpeerlen) < 2 || ferror(lockfile)) { - fclose(lockfile); - err.code = errno; - err.desc = "Cannot read upload's lock file"; - goto error_out; - } - if (lockpeerlen) { - lockpeername = (char*) calloc(1, lockpeerlen+1); - if (!lockpeername) { - err.code = ENOMEM; - goto error_out; - } - if (fgets(lockpeername, lockpeerlen+1, lockfile) == NULL) { - fclose(lockfile); - err.code = errno; - err.desc = "Cannot read upload's lock file"; - goto error_out; - } - } - fclose(lockfile); - - peername = glite_jp_peer_name(ctx); - if (lockpeername && (!peername || strcmp(lockpeername, peername))) { - err.code = EPERM; - err.desc = "Upload started by client of different identity"; - goto error_out; - } - - if (rename(dest_rw_suff, dest_rw) < 0) { - err.code = errno; - err.desc = "Cannot move upload file to the final place"; - goto error_out; - } - - if (unlink(dest_rw_lock) < 0) { - err.code = errno; - err.desc = "Cannot unlink upload's lock file"; - goto error_out; - } - -error_out: - free(dest_rw); - free(dest_rw_suff); - free(dest_rw_lock); - free(peername); - free(lockpeername); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_destination_info( - glite_jp_context_t ctx, - const char *destination, - char **job, - glite_jp_fileclass_t *class -) -{ - size_t dest_len; - size_t suff_len; - size_t extp_len; - char *dest_rw = NULL; - char *dest_rw_suff = NULL; - char *dest_rw_info = NULL; - FILE *infofile = NULL; - char *classname = NULL; - char jobstr[256+1]; - glite_jp_error_t err; - - assert(destination != NULL); - assert(job != NULL); - assert(class != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - suff_len = strlen(UPLOAD_SUFFIX); - dest_len = strlen(destination); - extp_len = strlen(config->external_path); - - if (dest_len < suff_len || - strcmp(UPLOAD_SUFFIX, destination + (dest_len - suff_len)) || - strncmp(destination, config->external_path, extp_len)) { - err.code = EINVAL; - err.desc = "Forged destination path"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&dest_rw_suff, "%s%s", config->internal_path, - destination + extp_len) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - dest_rw = strdup(dest_rw_suff); - if (!dest_rw) { - err.code = ENOMEM; - goto error_out; - } - *(dest_rw + (strlen(dest_rw_suff) - suff_len)) = '\0'; - - classname = strrchr(dest_rw,'/'); - if (classname == NULL) { - err.code = EINVAL; - err.desc = "Forged destination path"; - goto error_out; - } - *classname++ ='\0'; - *class = fname_to_class(classname); - if (!class == GLITE_JP_FILECLASS_UNDEF) { - err.code = EINVAL; - err.desc = "Forged destination path"; - goto error_out; - } - - if (asprintf(&dest_rw_info, "%s/_info", dest_rw) == -1) { - err.code = ENOMEM; - goto error_out; - } - - infofile = fopen(dest_rw_info, "r"); - if (infofile == NULL) { - err.code = errno; - err.desc = "Cannot open _info file"; - goto error_out; - } - if (fscanf(infofile, "%*d %*ld.%*ld %256s ", jobstr) < 1 || ferror(infofile)) { - fclose(infofile); - err.code = errno; - err.desc = "Cannot read _info file"; - goto error_out; - } - *job = strdup(jobstr); - fclose(infofile); - -error_out: - free(dest_rw); - free(dest_rw_suff); - free(dest_rw_info); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - - -int glite_jppsbe_get_job_url( - glite_jp_context_t ctx, - const char *job, - glite_jp_fileclass_t class, - char **url_out -) -{ - FILE *regfile = NULL; - char *int_fname = NULL; - char *fname = NULL; - char *ju = NULL; - char *ju_path = NULL; - int info_version; - long reg_time; - char ownerhash[33]; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job!=NULL); - assert(class != GLITE_JP_FILECLASS_UNDEF); - assert(url_out != NULL); - - fname = class_to_fname(class); - assert(fname!=NULL); - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - if (errno == ENOENT) - err.desc = "Job not registered"; - else - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%*ld %*s %s", &info_version, - ®_time, ownerhash) < 3 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - fclose(regfile); - - if (asprintf(url_out, "%s/data/%s/%d/%s/%s", - config->external_path, ownerhash, regtime_trunc(reg_time), ju, fname) == -1) { - err.code = ENOMEM; - goto error_out; - } - -error_out: - free(int_fname); - free(ju); free(ju_path); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -static int get_job_fname( - glite_jp_context_t ctx, - const char *job, - glite_jp_fileclass_t class, - char **fname_out -) -{ - FILE *regfile = NULL; - char *fname = NULL; - char *int_fname = NULL; - char *ju = NULL; - char *ju_path = NULL; - int info_version; - long reg_time; - char ownerhash[33]; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job!=NULL); - assert(class != GLITE_JP_FILECLASS_UNDEF); - assert(fname_out != NULL); - - fname = class_to_fname(class); - assert(fname!=NULL); - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - if (errno == ENOENT) - err.desc = "Job not registered"; - else - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%*ld %*s %s", &info_version, - ®_time, ownerhash) < 3 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - fclose(regfile); - - if (asprintf(fname_out, "%s/data/%s/%d/%s/%s", - config->internal_path, ownerhash, regtime_trunc(reg_time), ju, fname) == -1) { - err.code = ENOMEM; - goto error_out; - } - -error_out: - free(int_fname); - free(ju); free(ju_path); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_open_file( - glite_jp_context_t ctx, - const char *job, - glite_jp_fileclass_t class, - int mode, - void **handle_out -) -{ - fhandle handle = NULL; - char* fname = NULL; - glite_jp_error_t err; - - assert(handle_out != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (get_job_fname(ctx, job, class, &fname)) { - err.code = ctx->error->code; - err.desc = "Cannot construct internal filename"; - return glite_jp_stack_error(ctx,&err); - } - - handle = (fhandle) calloc(1,sizeof(*handle)); - if (handle == NULL) { - err.code = ENOMEM; - goto error_out; - } - - handle->fd = open(fname, mode, S_IRUSR | S_IWUSR); - if (handle->fd < 0) { - err.code = errno; - err.desc = "Cannot open requested file"; - free(handle); - goto error_out; - } - handle->fd_append = open(fname, mode | O_APPEND, S_IRUSR | S_IWUSR); - if (handle->fd_append < 0) { - err.code = errno; - err.desc = "Cannot open requested file for append"; - close(handle->fd); - free(handle); - goto error_out; - } - *handle_out = (void*) handle; - -error_out: - free(fname); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_close_file( - glite_jp_context_t ctx, - void *handle -) -{ - glite_jp_error_t err; - - assert(handle != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (close(((fhandle)handle)->fd_append) < 0) { - err.code = errno; - err.desc = "Error closing file descriptor (fd_append)"; - goto error_out; - } - if (close(((fhandle)handle)->fd) < 0) { - err.code = errno; - err.desc = "Error closing file descriptor"; - goto error_out; - } - -error_out: - free(handle); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_pread( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes, - off_t offset, - ssize_t *nbytes_ret -) -{ - ssize_t ret; - glite_jp_error_t err; - - assert(handle != NULL); - assert(buf != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if ((ret = pread(((fhandle)handle)->fd, buf, nbytes, offset)) < 0) { - err.code = errno; - err.desc = "Error in pread()"; - return glite_jp_stack_error(ctx,&err); - } - *nbytes_ret = ret; - - return 0; -} - -int glite_jppsbe_pwrite( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes, - off_t offset -) -{ - glite_jp_error_t err; - - assert(handle != NULL); - assert(buf != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (pwrite(((fhandle)handle)->fd, buf, nbytes, offset) < 0) { - err.code = errno; - err.desc = "Error in pwrite()"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - -int glite_jppsbe_append( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes -) -{ - glite_jp_error_t err; - - assert(handle != NULL); - assert(buf != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (write(((fhandle)handle)->fd_append, buf, nbytes) < 0) { - err.code = errno; - err.desc = "Error in write()"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - -static int get_job_info( - glite_jp_context_t ctx, - const char *job, - char **owner, - struct timeval *tv_reg -) -{ - char *ju = NULL; - char *ju_path = NULL; - FILE *regfile = NULL; - long reg_time_sec; - long reg_time_usec; - int ownerlen = 0; - int info_version; - char *int_fname = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - return glite_jp_stack_error(ctx,&err); - } - - if (asprintf(&int_fname, "%s/regs/%s/%s.info", - config->internal_path, ju_path, ju) == -1) { - err.code = ENOMEM; - goto error_out; - } - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - if (errno == ENOENT) - err.desc = "Job not registered"; - else - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%ld %*s %*s %d ", &info_version, - ®_time_sec, ®_time_usec, &ownerlen) < 4 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - if (ownerlen) { - *owner = (char *) calloc(1, ownerlen+1); - if (!*owner) { - err.code = ENOMEM; - goto error_out; - } - if (fgets(*owner, ownerlen+1, regfile) == NULL) { - fclose(regfile); - free(*owner); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - } - fclose(regfile); - - tv_reg->tv_sec = reg_time_sec; - tv_reg->tv_usec = reg_time_usec; - -error_out: - free(int_fname); - free(ju); - free(ju_path); - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -static int get_job_info_int( - glite_jp_context_t ctx, - const char *int_fname, - char **jobid, - char **owner, - struct timeval *tv_reg -) -{ - FILE *regfile = NULL; - long reg_time_sec; - long reg_time_usec; - int ownerlen = 0; - int info_version; - char jobid_buf[256]; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - regfile = fopen(int_fname, "r"); - if (regfile == NULL) { - err.code = errno; - err.desc = "Cannot open jobs's reg info file"; - goto error_out; - } - if (fscanf(regfile, "%d %ld.%ld %s %*s %d ", &info_version, - ®_time_sec, ®_time_usec, jobid_buf, &ownerlen) < 5 || ferror(regfile)) { - fclose(regfile); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - *jobid = strdup(jobid_buf); - if (ownerlen) { - *owner = (char *) calloc(1, ownerlen+1); - if (!*owner) { - err.code = ENOMEM; - goto error_out; - } - if (fgets(*owner, ownerlen+1, regfile) == NULL) { - fclose(regfile); - free(*owner); - err.code = errno; - err.desc = "Cannot read jobs's reg info file"; - goto error_out; - } - } - fclose(regfile); - - tv_reg->tv_sec = reg_time_sec; - tv_reg->tv_usec = reg_time_usec; - -error_out: - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -int glite_jppsbe_get_job_metadata( - glite_jp_context_t ctx, - const char *job, - glite_jp_attrval_t attrs_inout[] -) -{ - int got_info = 0; - struct timeval tv_reg; - char *owner = NULL; - int got_tags = 0; - void *tags_handle = NULL; - glite_jp_tagval_t* tags = NULL; - int i,j; - glite_jp_error_t err; - - assert(job != NULL); - assert(attrs_inout != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - for (i = 0; attrs_inout[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - switch (attrs_inout[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TIME: - if (!got_info) { - if (get_job_info(ctx, job, &owner, &tv_reg)) { - err.code = ctx->error->code; - err.desc = "Cannot retrieve job info"; - goto error_out; - } - got_info = 1; - } - break; - case GLITE_JP_ATTR_TAG: - if (!got_tags) { - if (glite_jppsbe_open_file(ctx, job, GLITE_JP_FILECLASS_TAGS, - O_RDONLY, &tags_handle)) { - err.code = ctx->error->code; - err.desc = "Cannot open tag file"; - goto error_out; - } - if (glite_jpps_tag_readall(ctx, tags_handle, &tags)) { - err.code = ctx->error->code; - err.desc = "Cannot read tags"; - glite_jppsbe_close_file(ctx, tags_handle); - goto error_out; - } - glite_jppsbe_close_file(ctx, tags_handle); - got_tags = 1; - } - break; - default: - err.code = EINVAL; - err.desc = "Invalid attribute type"; - goto error_out; - break; - } - - switch (attrs_inout[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - attrs_inout[i].value.s = strdup(owner); - if (!attrs_inout[i].value.s) { - err.code = ENOMEM; - err.desc = "Cannot copy owner string"; - goto error_out; - } - break; - case GLITE_JP_ATTR_TIME: - attrs_inout[i].value.time = tv_reg; - break; - case GLITE_JP_ATTR_TAG: - for (j = 0; tags[j].name != NULL; j++) { - if (!strcmp(tags[j].name, attrs_inout[i].attr.name)) { - if (glite_jpps_tagval_copy(ctx, &tags[j], - &attrs_inout[i].value.tag)) { - err.code = ENOMEM; - err.desc = "Cannot copy tag value"; - goto error_out; - } - break; - } - } - if (!tags[j].name) attrs_inout[i].value.tag.name = NULL; - break; - default: - break; - } - } - -error_out: - free(owner); - if (tags) for (j = 0; tags[j].name != NULL; j++) { - free(tags[j].name); - free(tags[j].value); - } - free(tags); - - if (err.code) { - while (i > 0) { - i--; - switch (attrs_inout[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - free(attrs_inout[i].value.s); - break; - case GLITE_JP_ATTR_TAG: - free(attrs_inout[i].value.tag.name); - free(attrs_inout[i].value.tag.value); - default: - break; - } - } - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} -static int compare_timeval(struct timeval a, struct timeval b) -{ - if (a.tv_sec < b.tv_sec) return -1; - if (a.tv_sec > b.tv_sec) return 1; - if (a.tv_usec < b.tv_usec) return -1; - if (a.tv_usec > b.tv_usec) return 1; - return 0; -} - -static int query_phase2( - glite_jp_context_t ctx, - const char *ownerhash, - long regtime_tr, - int q_tags, - int md_tags, - const glite_jp_query_rec_t query[], - glite_jp_attrval_t metadata[], - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[] - ) -); - -static int query_phase2( - glite_jp_context_t ctx, - const char *ownerhash, - long regtime_tr, - int q_tags, - int md_tags, - const glite_jp_query_rec_t query[], - glite_jp_attrval_t metadata[], - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[] - ) -) -{ - char *time_dirname = NULL; - DIR *time_dirp = NULL; - struct dirent *jobent; - char *info_fname = NULL; - char *jobid = NULL; - char *owner = NULL; - struct timeval tv_reg; - void *tags_handle = NULL; - int matching; - int i, j; - glite_jp_tagval_t* tags = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (asprintf(&time_dirname, "%s/data/%s/%d", config->internal_path, - ownerhash, regtime_tr) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - time_dirp = opendir(time_dirname); - if (!time_dirp) { - free(time_dirname); - return 0; /* found nothing */ - } - while ((jobent = readdir(time_dirp)) != NULL) { - if (!strcmp(jobent->d_name, ".")) continue; - if (!strcmp(jobent->d_name, "..")) continue; - if (asprintf(&info_fname, "%s/%s/_info", time_dirname, - jobent->d_name) == -1) { - err.code = ENOMEM; - goto error_out; - } - if (get_job_info_int(ctx, info_fname, &jobid, &owner, &tv_reg)) { - err.code = EIO; - err.desc = "Cannot retrieve job info"; - goto error_out; - } - if (q_tags || md_tags) { - if (glite_jppsbe_open_file(ctx, jobid, GLITE_JP_FILECLASS_TAGS, - O_RDONLY, &tags_handle)) { - err.code = ctx->error->code; - err.desc = "Cannot open tag file"; - goto error_out; - } - if (glite_jpps_tag_readall(ctx, tags_handle, &tags)) { - err.code = ctx->error->code; - err.desc = "Cannot read tags"; - glite_jppsbe_close_file(ctx, tags_handle); - goto error_out; - } - glite_jppsbe_close_file(ctx, tags_handle); - tags_handle = NULL; - } - - matching = 1; - for (i = 0; matching && query[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - switch (query[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - if (query[i].value.s == NULL || - strcmp(query[i].value.s, owner)) matching = 0; - break; - case GLITE_JP_ATTR_TIME: - switch (query[i].op) { - case GLITE_JP_QUERYOP_EQUAL: - matching = !compare_timeval(tv_reg, query[i].value.time); - break; - case GLITE_JP_QUERYOP_UNEQUAL: - matching = compare_timeval(tv_reg, query[i].value.time); - break; - case GLITE_JP_QUERYOP_LESS: - matching = compare_timeval(tv_reg, query[i].value.time) < 0; - break; - case GLITE_JP_QUERYOP_GREATER: - matching = compare_timeval(tv_reg, query[i].value.time) > 0; - break; - case GLITE_JP_QUERYOP_WITHIN: - matching = compare_timeval(tv_reg, query[i].value.time) >= 0 - && compare_timeval(tv_reg, query[i].value2.time) <= 0; - break; - } - break; - case GLITE_JP_ATTR_TAG: - if (!tags) { - matching = 0; - break; - } - for (j = 0; tags[j].name != NULL; j++) { - if (!strcmp(tags[j].name, query[i].attr.name)) { - switch (query[i].op) { - case GLITE_JP_QUERYOP_EQUAL: - matching = !strcmp(tags[j].value, query[i].value.s); - break; - case GLITE_JP_QUERYOP_UNEQUAL: - matching = strcmp(tags[j].value, query[i].value.s); - break; - case GLITE_JP_QUERYOP_LESS: - matching = strcmp(tags[j].value, query[i].value.s) < 0; - break; - case GLITE_JP_QUERYOP_GREATER: - matching = strcmp(tags[j].value, query[i].value.s) > 0; - break; - case GLITE_JP_QUERYOP_WITHIN: - matching = strcmp(tags[j].value, query[i].value.s) >= 0 \ - && strcmp(tags[j].value, query[i].value2.s) <= 0 ; - break; - default: - break; - } - } - } - break; - default: - break; - } - } - if (!matching) { - free(info_fname); info_fname = NULL; - free(jobid); jobid = NULL; - if (tags) for (j = 0; tags[j].name != NULL; j++) { - free(tags[j].name); - free(tags[j].value); - } - free(tags); tags = NULL; - continue; - } - - for (i = 0; metadata[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - switch (metadata[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - metadata[i].value.s = owner; - break; - case GLITE_JP_ATTR_TIME: - metadata[i].value.time = tv_reg; - break; - case GLITE_JP_ATTR_TAG: - for (j = 0; tags[j].name != NULL; j++) { - if (!strcmp(tags[j].name, metadata[i].attr.name)) { - if (glite_jpps_tagval_copy(ctx, &tags[j], - &metadata[i].value.tag)) { - err.code = ENOMEM; - err.desc = "Cannot copy tag value"; - goto error_out; - } - break; - } - } - if (!tags[j].name) { - metadata[i].value.tag.name = NULL; - metadata[i].value.tag.value = NULL; - } - break; - default: - break; - } - } - (*callback)(ctx, jobid, metadata); - free(jobid); jobid = NULL; - while (i > 0) { - i--; - switch (metadata[i].attr.type) { - case GLITE_JP_ATTR_TAG: - free(metadata[i].value.tag.name); - free(metadata[i].value.tag.value); - default: - break; - } - } - } - -error_out: - if (tags) for (j = 0; tags[j].name != NULL; j++) { - free(tags[j].name); - free(tags[j].value); - } - if (tags_handle) glite_jppsbe_close_file(ctx, tags_handle); - free(info_fname); - free(owner); - free(jobid); - closedir(time_dirp); - free(time_dirname); - if (err.code) { - while (i > 0) { - i--; - switch (metadata[i].attr.type) { - case GLITE_JP_ATTR_TAG: - free(metadata[i].value.tag.name); - free(metadata[i].value.tag.value); - default: - break; - } - } - return glite_jp_stack_error(ctx,&err); - } else - return 0; -} - -int glite_jppsbe_query( - glite_jp_context_t ctx, - const glite_jp_query_rec_t query[], - const glite_jp_attrval_t metadata[], - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[] - ) -) -{ - /* XXX clone metadata */ - int i; - char *q_exact_owner = NULL; - char *ownerhash = NULL; - long q_min_time = 0; - long q_max_time = LONG_MAX; - long q_min_time_tr; - long q_max_time_tr; - int q_with_tags = 0; - int md_info = 0; - int md_tags = 0; - char *owner_dirname = NULL; - DIR *owner_dirp = NULL; - struct dirent *ttimeent; - char *data_dirname = NULL; - DIR *data_dirp = NULL; - struct dirent *ownerent; - long ttime = 0; - glite_jp_attrval_t *metadata_templ = NULL; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - for (i = 0; query[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - if (query[i].attr.type == GLITE_JP_ATTR_OWNER && query[i].op == GLITE_JP_QUERYOP_EQUAL) { - q_exact_owner = query[i].value.s; - } - if (query[i].attr.type == GLITE_JP_ATTR_TIME) { - switch (query[i].op) { - case GLITE_JP_QUERYOP_EQUAL: - q_min_time = query[i].value.time.tv_sec; - q_max_time = query[i].value.time.tv_sec + 1; - break; - case GLITE_JP_QUERYOP_LESS: - if (q_max_time > query[i].value.time.tv_sec + 1) - q_max_time = query[i].value.time.tv_sec + 1; - break; - case GLITE_JP_QUERYOP_WITHIN: - if (q_max_time > query[i].value2.time.tv_sec + 1) - q_max_time = query[i].value2.time.tv_sec + 1; - /* fallthrough */ - case GLITE_JP_QUERYOP_GREATER: - if (q_min_time < query[i].value.time.tv_sec) - q_min_time = query[i].value.time.tv_sec; - break; - default: - err.code = EINVAL; - err.desc = "Invalid query op"; - return glite_jp_stack_error(ctx,&err); - break; - } - } - if (query[i].attr.type == GLITE_JP_ATTR_TAG) - q_with_tags = 1; - - } - - for (i = 0; metadata[i].attr.type != GLITE_JP_ATTR_UNDEF; i++) { - switch (metadata[i].attr.type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TIME: - md_info = 1; - break; - case GLITE_JP_ATTR_TAG: - md_tags = 1; - break; - default: - err.code = EINVAL; - err.desc = "Invalid attribute type in metadata parameter"; - return glite_jp_stack_error(ctx,&err); - break; - } - } - metadata_templ = (glite_jp_attrval_t *) calloc(i + 1, sizeof(glite_jp_attrval_t)); - if (!metadata_templ) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - memcpy(metadata_templ, metadata, (i + 1) * sizeof(glite_jp_attrval_t)); - - q_min_time_tr = regtime_trunc(q_min_time); - q_max_time_tr = regtime_ceil(q_max_time); - - if (q_exact_owner) { - ownerhash = str2md5(q_exact_owner); /* static buffer */ - if (asprintf(&owner_dirname, "%s/data/%s", config->internal_path, ownerhash) == -1) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - owner_dirp = opendir(owner_dirname); - free(owner_dirname); - if (!owner_dirp) { - free(metadata_templ); - return 0; /* found nothing */ - } - while ((ttimeent = readdir(owner_dirp)) != NULL) { - if (!strcmp(ttimeent->d_name, ".")) continue; - if (!strcmp(ttimeent->d_name, "..")) continue; - ttime = atol(ttimeent->d_name); - if (ttime >= q_min_time_tr && ttime < q_max_time_tr) { - if (query_phase2(ctx, ownerhash, ttime, q_with_tags, md_tags, - query, metadata_templ, callback)) { - err.code = EIO; - err.desc = "query_phase2() error"; - goto error_out; - } - } - } - } else { /* !q_exact_owner */ - if (asprintf(&data_dirname, "%s/data", config->internal_path) == -1) { - err.code = ENOMEM; - goto error_out; - } - data_dirp = opendir(data_dirname); - if (!data_dirp) { - err.code = EIO; - err.desc = "Cannot open data directory"; - goto error_out; - } - while ((ownerent = readdir(data_dirp)) != NULL) { - if (!strcmp(ownerent->d_name, ".")) continue; - if (!strcmp(ownerent->d_name, "..")) continue; - if (asprintf(&owner_dirname, "%s/data/%s", config->internal_path, - ownerent->d_name) == -1) { - err.code = ENOMEM; - goto error_out; - } - owner_dirp = opendir(owner_dirname); - free(owner_dirname); - if (!owner_dirp) { - err.code = EIO; - err.desc = "Cannot open owner data directory"; - goto error_out; - } - while ((ttimeent = readdir(owner_dirp)) != NULL) { - if (!strcmp(ttimeent->d_name, ".")) continue; - if (!strcmp(ttimeent->d_name, "..")) continue; - ttime = atol(ttimeent->d_name); - if (ttime >= q_min_time_tr && ttime < q_max_time_tr) { - if (query_phase2(ctx, ownerent->d_name, ttime, q_with_tags, md_tags, - query, metadata_templ, callback)) { - err.code = EIO; - err.desc = "query_phase2() error"; - goto error_out; - } - } - } - closedir(owner_dirp); owner_dirp = NULL; - } - closedir(data_dirp); data_dirp = NULL; - } - return 0; - -error_out: - if (owner_dirp) closedir(owner_dirp); - if (data_dirp) closedir(data_dirp); - free(data_dirname); - free(metadata_templ); - return glite_jp_stack_error(ctx,&err); -} - -/* XXX: -- no primary authorization yet -- no concurrency control yet -- partial success in pwrite,append -- "unique" part of jobid is assumed to be unique across bookkeeping servers -- repository versioning not fully implemented yet -*/ diff --git a/org.glite.jp.primary/src/is_client.c b/org.glite.jp.primary/src/is_client.c deleted file mode 100644 index 1d0446a..0000000 --- a/org.glite.jp.primary/src/is_client.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" - -#include "feed.h" -#include "jpis_H.h" -#include "jpis_.nsmap" - -int glite_jpps_single_feed( - glite_jp_context_t ctx, - const char *destination, - const char *job, - const glite_jp_attrval_t attrs[] -) -{ - /* TODO: really call JP Index server (via interlogger) */ - printf("feed to %s, job %s\n",destination,job); - - if (soap_call_jpsrv__UpdateJobs(ctx->other_soap,destination,"", - /* FIXME: feedId */ "", - /* FIXME: UpdateJobsData */ NULL, - 0, - NULL - )) fprintf(stderr,"UpdateJobs: %s %s\n",ctx->other_soap->fault->faultcode, - ctx->other_soap->fault->faultstring); - - return 0; -} diff --git a/org.glite.jp.primary/src/jptype_map.h b/org.glite.jp.primary/src/jptype_map.h deleted file mode 100644 index 6df0828..0000000 --- a/org.glite.jp.primary/src/jptype_map.h +++ /dev/null @@ -1,16 +0,0 @@ -#if GSOAP_VERSION >= 20700 -#define INPUT_SANDBOX jptype__UploadClass__INPUT_SANDBOX -#define OUTPUT_SANDBOX jptype__UploadClass__OUTPUT_SANDBOX -#define JOB_LOG jptype__UploadClass__JOB_LOG - -#define OWNER jptype__AttributeType__OWNER -#define TIME jptype__AttributeType__TIME -#define TAG jptype__AttributeType__TAG - -#define EQUAL jptype__QueryOp__EQUAL -#define UNEQUAL jptype__QueryOp__UNEQUAL -#define LESS jptype__QueryOp__LESS -#define GREATER jptype__QueryOp__GREATER -#define WITHIN jptype__QueryOp__WITHIN -#endif - diff --git a/org.glite.jp.primary/src/simple_server.c b/org.glite.jp.primary/src/simple_server.c deleted file mode 100644 index 3bbb743..0000000 --- a/org.glite.jp.primary/src/simple_server.c +++ /dev/null @@ -1,59 +0,0 @@ -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "jpps_H.h" - -extern SOAP_NMAC struct Namespace jpis__namespaces[],jpps__namespaces[]; - -int main(int argc, char *argv[]) { - struct soap soap; - int i, m, s; // master and slave sockets - - glite_jp_context_t ctx; - - soap_init(&soap); - soap_set_namespaces(&soap, jpps__namespaces); - - glite_jp_init_context(&ctx); - - if (glite_jppsbe_init(ctx, &argc, argv)) { - /* XXX log */ - fputs(glite_jp_error_chain(ctx), stderr); - exit(1); - } - - soap.user = (void *) ctx; - - ctx->other_soap = soap_new(); - soap_init(ctx->other_soap); - soap_set_namespaces(ctx->other_soap,jpis__namespaces); - - srand48(time(NULL)); /* feed id generation */ - - m = soap_bind(&soap, NULL, 8901, 100); - if (m < 0) - soap_print_fault(&soap, stderr); - else - { - fprintf(stderr, "Socket connection successful: master socket = %d\n", m); - for (i = 1; ; i++) { - s = soap_accept(&soap); - if (s < 0) { - soap_print_fault(&soap, stderr); - break; - } - jpps__serve(&soap); // process RPC request - soap_destroy(&soap); // clean up class instances - soap_end(&soap); // clean up everything and close socket - glite_jp_run_deferred(ctx); - } - } - soap_done(&soap); // close master socket - - return 0; -} - -/* XXX: we don't use it */ -SOAP_NMAC struct Namespace namespaces[] = { {NULL,NULL} }; diff --git a/org.glite.jp.primary/src/soap_ops.c b/org.glite.jp.primary/src/soap_ops.c deleted file mode 100644 index 1e5534b..0000000 --- a/org.glite.jp.primary/src/soap_ops.c +++ /dev/null @@ -1,374 +0,0 @@ -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "feed.h" - -#include "jpps_H.h" -/* #include "JobProvenancePS.nsmap" */ -#include "jpps_.nsmap" - -#include "jptype_map.h" - -static struct jptype__GenericJPFaultType *jp2s_error(struct soap *soap, - const glite_jp_error_t *err) -{ - struct jptype__GenericJPFaultType *ret = NULL; - if (err) { - ret = soap_malloc(soap,sizeof *ret); - memset(ret,0,sizeof *ret); - ret->code = err->code; - ret->source = soap_strdup(soap,err->source); - ret->text = soap_strdup(soap,strerror(err->code)); - ret->description = soap_strdup(soap,err->desc); - ret->reason = jp2s_error(soap,err->reason); - } - return ret; -} - -static void err2fault(const glite_jp_context_t ctx,struct soap *soap) -{ - char *et; - struct SOAP_ENV__Detail *detail = soap_malloc(soap,sizeof *detail); - struct _GenericJPFault *f = soap_malloc(soap,sizeof *f); - - - f->jptype__GenericJPFault = jp2s_error(soap,ctx->error); - - detail->__type = SOAP_TYPE__GenericJPFault; -#if GSOAP_VERSION >= 20700 - detail->fault = f; -#else - detail->value = f; -#endif - detail->__any = NULL; - - soap_receiver_fault(soap,"Oh, shit!",NULL); - if (soap->version == 2) soap->fault->SOAP_ENV__Detail = detail; - else soap->fault->detail = detail; -} - -static glite_jp_fileclass_t s2jp_fileclass(enum jptype__UploadClass class) -{ - switch (class) { - case INPUT_SANDBOX: return GLITE_JP_FILECLASS_INPUT; - case OUTPUT_SANDBOX: return GLITE_JP_FILECLASS_OUTPUT; - case JOB_LOG: return GLITE_JP_FILECLASS_LBLOG; - default: return GLITE_JP_FILECLASS_UNDEF; - } -} - -static void s2jp_tag(const struct jptype__TagValue *stag,glite_jp_tagval_t *jptag) -{ - memset(jptag,0,sizeof *jptag); - jptag->name = strdup(stag->name); - jptag->sequence = stag->sequence ? *stag->sequence : 0; - jptag->timestamp = stag->timestamp ? *stag->timestamp : 0; - if (stag->stringValue) jptag->value = strdup(stag->stringValue); - else if (stag->blobValue) { - jptag->binary = 1; - jptag->size = stag->blobValue->__size; - jptag->value = (char *) stag->blobValue->__ptr; - } -} - -#define CONTEXT_FROM_SOAP(soap,ctx) glite_jp_context_t ctx = (glite_jp_context_t) ((soap)->user) - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__RegisterJob( - struct soap *soap, - char *job, - struct jpsrv__RegisterJobResponse *response) -{ - CONTEXT_FROM_SOAP(soap,ctx); - char *owner = glite_jp_peer_name(ctx); - glite_jp_attrval_t owner_val[2]; - - if (glite_jppsbe_register_job(ctx,job,owner)) { - err2fault(ctx,soap); - free(owner); - return SOAP_FAULT; - } - - owner_val[0].attr.type = GLITE_JP_ATTR_OWNER; - owner_val[0].value.s = owner; - owner_val[1].attr.type = GLITE_JP_ATTR_UNDEF; - -/* XXX: errrors should be ingored but not silently */ - glite_jpps_match_attr(ctx,job,owner_val); - free(owner); - - return SOAP_OK; -} - - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__StartUpload( - struct soap *soap, - char *job, - enum jptype__UploadClass class, - time_t commit_before, - char *content_type, - struct jpsrv__StartUploadResponse *response) -{ - CONTEXT_FROM_SOAP(soap,ctx); - glite_jp_fileclass_t jclass = s2jp_fileclass(class); - char *destination; - - if (glite_jppsbe_start_upload(ctx,job,jclass,content_type,&destination,&commit_before)) { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - response->destination = soap_strdup(soap,destination); - free(destination); - response->commitBefore = commit_before; - - return SOAP_OK; -} - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__CommitUpload( - struct soap *soap, - char *destination, - struct jpsrv__CommitUploadResponse *response) -{ - CONTEXT_FROM_SOAP(soap,ctx); - char *job = NULL; - glite_jp_fileclass_t class; - - if (glite_jppsbe_commit_upload(ctx,destination)) { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - /* XXX: should not fail when commit_upload was OK */ - glite_jppsbe_destination_info(ctx,destination,&job,&class); - - /* XXX: ignore errors but don't fail silenty */ - glite_jpps_match_file(ctx,job,class); - - return SOAP_OK; -} - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__RecordTag( - struct soap *soap, - char *job, - struct jptype__TagValue *tag, - struct jpsrv__RecordTagResponse *response) -{ - CONTEXT_FROM_SOAP(soap,ctx); - void *tagfile; - - glite_jp_tagval_t mytag; - - if (glite_jppsbe_open_file(ctx,job,GLITE_JP_FILECLASS_TAGS, - O_WRONLY|O_CREAT,&tagfile)) - { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - if (glite_jpps_tag_append(ctx,tagfile,&mytag)) { - err2fault(ctx,soap); - glite_jppsbe_close_file(ctx,tagfile); - return SOAP_FAULT; - } - - if (glite_jppsbe_close_file(ctx,tagfile)) { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - /* XXX: ignore errors but don't fail silenty */ - - s2jp_tag(tag,&mytag); - glite_jpps_match_tag(ctx,job,&mytag); - - return SOAP_OK; -} - -static void s2jp_attr(const struct jptype__Attribute *in,glite_jp_attr_t *out) -{ - switch (in->type) { - case OWNER: out->type = GLITE_JP_ATTR_OWNER; break; - case TIME: out->type = GLITE_JP_ATTR_TIME; - out->name = strdup(in->name); - break; - case TAG: out->type = GLITE_JP_ATTR_TAG; - out->name = strdup(in->name); - break; - default: break; - } -} - -static void s2jp_queryval( - const char *in, - glite_jp_attrtype_t type, - union _glite_jp_query_rec_val *out) -{ - switch (type) { - case GLITE_JP_ATTR_OWNER: - case GLITE_JP_ATTR_TAG: - out->s = strdup(in); - break; - case GLITE_JP_ATTR_TIME: - out->time.tv_sec = atoi(in); - break; - } -} - -static void s2jp_query(const struct jptype__PrimaryQueryElement *in, glite_jp_query_rec_t *out) -{ - s2jp_attr(in->attr,&out->attr); - - switch (in->op) { - case EQUAL: out->op = GLITE_JP_QUERYOP_EQUAL; break; - case UNEQUAL: out->op = GLITE_JP_QUERYOP_UNEQUAL; break; - case LESS: out->op = GLITE_JP_QUERYOP_LESS; break; - case GREATER: out->op = GLITE_JP_QUERYOP_GREATER; break; - case WITHIN: - out->op = GLITE_JP_QUERYOP_WITHIN; - s2jp_queryval(in->value2,out->attr.type,&out->value2); - break; - } - - s2jp_queryval(in->value,out->attr.type,&out->value); -} - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__FeedIndex( - struct soap *soap, - char *destination, - struct jptype__Attributes *attributes, - struct jptype__PrimaryQuery *query, - enum xsd__boolean history, - enum xsd__boolean continuous, - struct jpsrv__FeedIndexResponse *response) -{ - -/* deferred processing: return feed_id to the index server first, - * start feeding it afterwards -- not before the index server actually - * knows feed_id and is ready to accept the feed. - * - * Has to be done within the same server slave, - * passed through the context */ - - CONTEXT_FROM_SOAP(soap,ctx); - char *feed_id = NULL; - time_t expires = 0; - int ret = SOAP_OK; - - glite_jp_attr_t *attrs = calloc(attributes->__sizeitem+1,sizeof *attrs); - glite_jp_query_rec_t *qry = calloc(query->__sizeitem+1,sizeof *qry); - int i; - - glite_jp_clear_error(ctx); - - for (i = 0; i__sizeitem; i++) s2jp_attr(attributes->item[i],attrs+i); - for (i = 0; i__sizeitem; i++) s2jp_query(query->item[i],qry+i); - - if (history) { - if (glite_jpps_run_feed(ctx,destination,attrs,qry,&feed_id)) { - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - } - - if (continuous) { - if (glite_jpps_register_feed(ctx,destination,attrs,qry,&feed_id,&expires)) { - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - } - - if (!history && !continuous) { - glite_jp_error_t err; - err.code = EINVAL; - err.source = __FUNCTION__; - err.desc = "at least one of and must be true"; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - - response->expires = expires; - response->feedId = soap_strdup(soap,feed_id); - -cleanup: - free(feed_id); - for (i=0; attrs[i].type; i++) free(attrs[i].name); - free(attrs); - for (i=0; qry[i].attr.type; i++) glite_jp_free_query_rec(qry+i); - free(qry); - - return ret; -} - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__FeedIndexRefresh( - struct soap *soap, - char *feed_id, - struct jpsrv__FeedIndexRefreshResponse *response) -{ - fprintf(stderr,"%s: not implemented\n",__FUNCTION__); - abort(); -} - -SOAP_FMAC5 int SOAP_FMAC6 jpsrv__GetJob( - struct soap *soap, - char *job, - struct jpsrv__GetJobResponse *response) -{ - CONTEXT_FROM_SOAP(soap,ctx); - char *url; - - struct { - glite_jp_fileclass_t type; - char **url; - char *name; - } tab[] = { - { GLITE_JP_FILECLASS_INPUT, &response->inputSandbox, "input sandbox" }, - { GLITE_JP_FILECLASS_OUTPUT, &response->outputSandbox, "output sandbox" }, - { GLITE_JP_FILECLASS_LBLOG, &response->jobLog, "L&B log" }, - { GLITE_JP_FILECLASS_TAGS, &response->tags, "JP tags" }, - { GLITE_JP_FILECLASS_UNDEF, NULL, NULL } - }; - - int i,gotone = 0; - glite_jp_error_t err; - - for (i=0; tab[i].type; i++) { - glite_jp_clear_error(ctx); - switch (glite_jppsbe_get_job_url(ctx,job,tab[i].type,&url)) { - case 0: *tab[i].url = soap_strdup(soap,url); - free(url); - gotone = 1; - break; - case ENOENT: - *tab[i].url = NULL; - break; - default: - err.code = ctx->error->code; - err.source = "jpsrv__GetJob()"; - err.desc = tab[i].name; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - glite_jp_clear_error(ctx); - return SOAP_FAULT; - } - } - - if (!gotone) { - glite_jp_clear_error(ctx); - err.code = ENOENT; - err.source = __FUNCTION__; - err.desc = "No file found for this job"; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - glite_jp_clear_error(ctx); - return SOAP_FAULT; - } - return SOAP_OK; -} - diff --git a/org.glite.jp.primary/src/tags.c b/org.glite.jp.primary/src/tags.c deleted file mode 100644 index 1f11b4d..0000000 --- a/org.glite.jp.primary/src/tags.c +++ /dev/null @@ -1,233 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include "tags.h" -#include "backend.h" - -/* magic name_len value_len binary sequence timestamp */ -#define HEADER "JP#TAG# %05u %012lu %c %05u %012lu#" -#define HEADER_SIZE 48 - -int glite_jpps_tag_append( - glite_jp_context_t ctx, - void *handle, - const glite_jp_tagval_t *tag -) -{ - char hdr[HEADER_SIZE+1]; - glite_jp_error_t err; - - unsigned long vlen = tag->binary ? tag->size : - (tag->value ? strlen(tag->value) : 0); - int nlen; - - memset(&err,0,sizeof err); - err.source = "glite_jpps_tag_append()"; - - if (!tag->name) { - err.code = EINVAL; - err.desc = "tag name"; - return glite_jp_stack_error(ctx,&err); - } - - nlen = strlen(tag->name); - - assert(sprintf(hdr,HEADER,nlen,vlen, - tag->binary ? "B" : "S", - tag->sequence, tag->timestamp) == HEADER_SIZE); - - if (glite_jppsbe_append(ctx,handle,hdr,HEADER_SIZE)) { - err.code = EIO; - err.desc = "write tag header"; - return glite_jp_stack_error(ctx,&err); - } - - if (glite_jppsbe_append(ctx,handle,tag->name,nlen)) { - err.code = EIO; - err.desc = "write tag name"; - return glite_jp_stack_error(ctx,&err); - } - - if (glite_jppsbe_append(ctx,handle,tag->value,vlen)) { - err.code = EIO; - err.desc = "write tag value"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - -int glite_jpps_tagval_copy( - glite_jp_context_t ctx, - glite_jp_tagval_t *from, - glite_jp_tagval_t *to -) -{ - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - to->name = strdup(from->name); - if (!to->name) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - to->sequence = from->sequence; - to->timestamp = from->timestamp; - to->binary = from->binary; - to->size = from->size; - to->value = (char *) malloc(to->size); - if (!to->value) { - free(to->name); - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - memcpy(from->value, to->value, to->size); - - return 0; -} - -int glite_jpps_tag_read( - glite_jp_context_t ctx, - void *handle, - off_t offset, - glite_jp_tagval_t *tagvalue, - size_t *shift -) -{ - char hdr[HEADER_SIZE+1]; - unsigned int nlen; - unsigned long vlen; - char binary; - unsigned sequence; - unsigned timestamp; - char * name = NULL; - char * value = NULL; - ssize_t ret; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - hdr[HEADER_SIZE] = '\0'; - if (glite_jppsbe_pread(ctx, handle, hdr, HEADER_SIZE, offset, &ret)) { - err.code = EIO; - err.desc = "Cannot read tag header"; - goto error_out; - } - if (ret == 0) { - err.code = ENOENT; - err.desc = "No more tags in the file"; - goto error_out; - } - /* #define HEADER "JP#TAG# %05u %012lu %c %05u %012lu#" */ - if (sscanf(hdr, HEADER, &nlen, &vlen, &binary, &sequence, ×tamp) < 5) { - err.code = EILSEQ; - err.desc = "Incorrect tag header format"; - goto error_out; - } - name = (char*) malloc(nlen + 1); - if (!name) { - err.code = ENOMEM; - goto error_out; - } - name[nlen] = '\0'; - value = (char*) malloc(vlen + 1); - if (!value) { - err.code = ENOMEM; - goto error_out; - } - value[vlen] = '\0'; - if (glite_jppsbe_pread(ctx, handle, name, nlen, offset + HEADER_SIZE, &ret)) { - err.code = EIO; - err.desc = "Cannot read tag name"; - goto error_out; - } - if (glite_jppsbe_pread(ctx, handle, value, vlen, offset + HEADER_SIZE + nlen, &ret)) { - err.code = EIO; - err.desc = "Cannot read tag value"; - goto error_out; - } - - tagvalue->name = name; - tagvalue->sequence = sequence; - tagvalue->timestamp = timestamp; - tagvalue->binary = (binary == 'B') ? 1 : 0; - tagvalue->size = vlen; - tagvalue->value = value; - - *shift = HEADER_SIZE + nlen + vlen; - - return 0; -error_out: - free(name); - free(value); - return glite_jp_stack_error(ctx,&err); -} - -/* -int glite_jpps_tag_read(glite_jp_context_t, void *, off_t, glite_jp_tagval_t *, size_t); -int glite_jpps_tag_readall(glite_jp_context_t, void *, glite_jp_tagval_t **); -*/ - -int glite_jpps_tag_readall( - glite_jp_context_t ctx, - void *handle, - glite_jp_tagval_t **tags_out -) -{ - glite_jp_tagval_t * tags = NULL; - void * newspace; - int ntags = 0; - int ntagspace = 0; - off_t offset = 0; - int ret; - size_t shift; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - ntagspace = 1; - tags = (glite_jp_tagval_t *) calloc(ntagspace + 1, sizeof(*tags)); - if (!tags) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - while (!(ret = glite_jpps_tag_read(ctx, handle, offset, &tags[ntags], &shift))) { - offset += shift; - ntags++; - if (ntagspace <= ntags) { - ntagspace += 1; - newspace = realloc(tags, (ntagspace + 1) * sizeof(*tags)); - if (!newspace) { - err.code = ENOMEM; - goto error_out; - } - tags = (glite_jp_tagval_t *) newspace; - } - } - if (ret == ENOENT) { - *tags_out = tags; - return 0; - } else { - err.code = EIO; - err.desc = "Error reading tag value"; - } - -error_out: - for (; ntags-- ;) { - free(tags[ntags].name); - free(tags[ntags].value); - } - free(tags); - return glite_jp_stack_error(ctx,&err); -} diff --git a/org.glite.jp.primary/src/tags.h b/org.glite.jp.primary/src/tags.h deleted file mode 100644 index 0d8afa8..0000000 --- a/org.glite.jp.primary/src/tags.h +++ /dev/null @@ -1 +0,0 @@ -int glite_jpps_tag_append(glite_jp_context_t,void *,const glite_jp_tagval_t *); diff --git a/org.glite.jp.primary/src/typemap.dat b/org.glite.jp.primary/src/typemap.dat deleted file mode 100644 index 7032cb2..0000000 --- a/org.glite.jp.primary/src/typemap.dat +++ /dev/null @@ -1,2 +0,0 @@ -jpsrv = http://glite.org/wsdl/services/jp -jptype = http://glite.org/wsdl/types/jp diff --git a/org.glite.jp.ws-interface/.cvsignore b/org.glite.jp.ws-interface/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.jp.ws-interface/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.jp.ws-interface/Makefile b/org.glite.jp.ws-interface/Makefile deleted file mode 100644 index 73cd9ad..0000000 --- a/org.glite.jp.ws-interface/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# Default values -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -package=glite-jp-ws-interface -version=0.0.0 -PREFIX=/opt/glite - --include Makefile.inc - -VPATH=${top_srcdir}/interface -STAGETO=interface - -WSDL=JobProvenancePS.wsdl JobProvenanceTypes.wsdl - -all compile: - -check: - @echo No unit test required for interface-only module. - -stage: - $(MAKE) install PREFIX=${stagedir} - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=${top_srcdir}/tmpbuilddir - cd ${top_srcdir}/tmpbuilddir && tar -czf ${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz * - rm -rf ${top_srcdir}/tmpbuilddir - -install: - -mkdir -p ${PREFIX}/${STAGETO} - -mkdir -p ${PREFIX}/share/doc/${package}-${version} - install -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - cd ${top_srcdir}/interface && install -m 644 ${WSDL} ${PREFIX}/${STAGETO} - -clean: - rm -f *.h - diff --git a/org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl b/org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl deleted file mode 100644 index 84c8844..0000000 --- a/org.glite.jp.ws-interface/interface/JobProvenanceIS.wsdl +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - Store or update information on jobs within the JP index server. -Called directly by the primary storage, used for both batch and incremental feed. - -Input: - -data: list of job record updates. Each contains jobid, list of JP attribute values and user tag values. - -feedDone: flag indicating end of batch feed. (In order to avoid potential problems with buffer allocation -the huge dataset of batch feed is split into reasonable chunks and delivered with more UpdateJobs calls.) - -Output: N/A - -Faults: GenericJPFault - - - - - - - - - Retrieve pointers to job records of jobs matching a query. -Input: conditions - list of lists of query conditions. - Elements of the inner lists refer to a single job attribute, the conditions are or-ed. - Elements of the outer list may refer to different job attributes, they are and-ed. - -Output: - -jobs: list of JobId, PSContact (URL of the primary storage which manges this job) pairs - -Faults: GenericJPFault - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Job Provenance Index service - - - - - - - diff --git a/org.glite.jp.ws-interface/interface/JobProvenancePS.wsdl b/org.glite.jp.ws-interface/interface/JobProvenancePS.wsdl deleted file mode 100644 index 7c777dd..0000000 --- a/org.glite.jp.ws-interface/interface/JobProvenancePS.wsdl +++ /dev/null @@ -1,307 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Register job with JP primary storage. -Job registration in LB is propagated to JP immediately so that JP is aware of the job, -despite no furhter information is available in it. - -Input: JobId - -Output: N/A - -Faults: GenericJPFault - - - - - - - Initiate upload of of sandbox/dump of job life log from LB. -WM component responsible for job sandbox management and LB server call JP to declare -intention to upload intput/output sandbox and job life log. - -Input: - -uclass: type of the upload - INPUT_SANDBOX, OUTPUT_SANDBOX, JOB_LOG - -commitTimeout: upper limit on time for which JP waits for committing this upload transaction - -contentType: MIME type of the uploaded file - -Output: - -destination: URL where the client should upload the file - -commitBefore: acutual time when the upload transaction times out - -Faults: GenericJPFault - - -Initiate upload of of sandbox/dump of job life log from LB. - - - - - - Confirm upload. -Should be called after a file upload initiaded with StartUpload is finished. - -Input: - -destination: Upload destination URL (to match with the original request) - -Output: - -Faults: GenericJPFault - - - - - - - Record a value of user tag. -JP tags are either standalone or override values of their LB counterparts. -However, JP tag values are still distinguishable those inherited from LB. -JP tags may be either strings or blobs. - -Input: - -jobid: - -tag: structure containing name, timestamp, optional sequence number to order tag values -without relying on timestamps, and string or blob value. - -Output: N/A - -Faults: GenericJPFault - - - - - - - Start feeding JP index server. -Called by the index server to start batch feed, and optionally also subscribe for incremental feed. - -JP index server subscribes with JP primary storage using a query -containing conditions on primary metadata and a list of queryable attributes -of the index server (i.e. data which should be sent to the index server). - -When a matching job record is created or modified within the primary storage -the job record data are sent to the subscribed index server. - -The subscription is soft-state, it expires after certain time unless refreshed by the client explicitely. - -In the batch mode the query has the same form -with additional flag asking for all matching records (i.e.\ not only -arriving afterwards). - -Input: - -destination: where to send the job record data - -attributes: which job record attributes should be sent to the requesting index server - -conditions: list of query conditions. Each conditions has the form Attribute Operator Value, -where Attribute is any of job record attributes and Operator is one of EQUAL, UNEQUAL, LESS, GREATER, WITHIN. - -continuous: flag determining that the query is incremental (not batch) - -Output: - -feedId: unique Id of the feed request, to be used in refresh, cancelation etc. - -expires: when the feed times out. Must be refreshed before this time. - -Faults: GenericJPFault - - - - - - - Extend batch feed subscription (used by index server) - -Input: feedId returned previously by FeedIndex - -Output: the same as for FeedIndex - -Faults: GenericJPFault - - - - - - - Retrieve job record URL's when jobid is known -Used either to bypass JP index server query for this specific case, or after the index server query to -retrieve actual job record. - -Input: jobid - -Output: - -jobLog, inputSandbox, outputSandbox, tags: URL's to components of the job record. - -Faults: GenericJPFault - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Job Provenance Primary Storage service - - - - - diff --git a/org.glite.jp.ws-interface/interface/JobProvenanceTypes.wsdl b/org.glite.jp.ws-interface/interface/JobProvenanceTypes.wsdl deleted file mode 100644 index e1a6db4..0000000 --- a/org.glite.jp.ws-interface/interface/JobProvenanceTypes.wsdl +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/project/build.properties b/org.glite.jp.ws-interface/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.jp.ws-interface/project/configure.properties.xml b/org.glite.jp.ws-interface/project/configure.properties.xml deleted file mode 100644 index 4b08208..0000000 --- a/org.glite.jp.ws-interface/project/configure.properties.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -jpprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -version=${module.version} -glite_location=${with.glite.location} - - - diff --git a/org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec b/org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec deleted file mode 100644 index dba6d55..0000000 --- a/org.glite.jp.ws-interface/project/glite-jp-ws-interface.spec +++ /dev/null @@ -1,42 +0,0 @@ -Summary:Change me !!! -Name:glite-jp-ws-interface -Version:0.0.0 -Release:0 -Copyright:Open Source EGEE License -Vendor:EU EGEE project -Group:System/Application -Prefix:/opt/glite -BuildArch:x86_64 -BuildRoot:%{_builddir}/%{name}-%{version} -Source:glite-jp-ws-interface-0.0.0_bin.tar.gz - -%define debug_package %{nil} - -%description -Change me !!! - -%prep - - -%setup -c - -%build - - -%install - - -%clean - -%pre -%post -%preun -%postun -%files -%defattr(-,root,root) -%{prefix}/interface/JobProvenancePS.wsdl -%{prefix}/interface/JobProvenanceTypes.wsdl -%{prefix}/share/doc/glite-jp-ws-interface-0.0.0/LICENSE - -%changelog - diff --git a/org.glite.jp.ws-interface/project/properties.xml b/org.glite.jp.ws-interface/project/properties.xml deleted file mode 100644 index 4ec8018..0000000 --- a/org.glite.jp.ws-interface/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/project/tar_exclude b/org.glite.jp.ws-interface/project/tar_exclude deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.ws-interface/project/version.properties b/org.glite.jp.ws-interface/project/version.properties deleted file mode 100755 index e78612b..0000000 --- a/org.glite.jp.ws-interface/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -module.version = 0.0.0 -module.build = 0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.jp/.cvsignore b/org.glite.jp/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp/build.xml b/org.glite.jp/build.xml deleted file mode 100644 index 7871c14..0000000 --- a/org.glite.jp/build.xml +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - - Ant build file to build the GLite Job Provenance Subsystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Preparing directories ... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <project name="${subsystem.name}" type="post-subsystem" packageName="${global.prefix}-${subsystem.prefix}"/> - - - - diff --git a/org.glite.jp/project/build.properties b/org.glite.jp/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp/project/dependencies.properties b/org.glite.jp/project/dependencies.properties deleted file mode 100644 index ab3b83f..0000000 --- a/org.glite.jp/project/dependencies.properties +++ /dev/null @@ -1,12 +0,0 @@ -################################################################### -# System dependencies -################################################################### - -org.glite.version = HEAD -org.glite.jp.version = HEAD - -# Component dependencies tag = do not remove this line = -org.glite.jp.ws-interface.version = HEAD -org.glite.jp.common.version = HEAD -org.glite.jp.index.version = HEAD -org.glite.jp.primary.version = HEAD diff --git a/org.glite.jp/project/glite.jp.csf.xml b/org.glite.jp/project/glite.jp.csf.xml deleted file mode 100644 index fd68f71..0000000 --- a/org.glite.jp/project/glite.jp.csf.xml +++ /dev/null @@ -1,271 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The org.glite and org.glite.jp modules have been updated, please rerun the configuration file - - - - - The org.glite and org.glite.jp modules have been updated, please rerun the configuration file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp/project/properties.xml b/org.glite.jp/project/properties.xml deleted file mode 100755 index 276cf76..0000000 --- a/org.glite.jp/project/properties.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp/project/run-workspace b/org.glite.jp/project/run-workspace deleted file mode 100644 index a5d1f54..0000000 --- a/org.glite.jp/project/run-workspace +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -cd ../.. - -cvs co org.glite -cvs co org.glite.jp - -cd org.glite.jp/project -ant -f glite.jp.csf.xml - diff --git a/org.glite.jp/project/taskdefs.xml b/org.glite.jp/project/taskdefs.xml deleted file mode 100755 index c4cc889..0000000 --- a/org.glite.jp/project/taskdefs.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/org.glite.jp/project/version.properties b/org.glite.jp/project/version.properties deleted file mode 100644 index 75e32e6..0000000 --- a/org.glite.jp/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ -#Fri Dec 10 13:38:38 CET 2004 -module.version=0.1.0 -module.build=3 -module.age=1 diff --git a/org.glite.lb.client-interface/Makefile b/org.glite.lb.client-interface/Makefile index 39d467d..5a0d350 100644 --- a/org.glite.lb.client-interface/Makefile +++ b/org.glite.lb.client-interface/Makefile @@ -20,7 +20,8 @@ AT3=perl -I${top_srcdir}/project ${top_srcdir}/project/at3 STAGETO=include/${globalprefix}/${lbprefix} STATIC_H=consumer.h context.h dump.h load.h notification.h notifid.h purge.h \ Notification.h CountRef.h Job.h LoggingExceptions.h ServerConnection.h \ - consumer_fake.h producer_fake.h statistics.h + statistics.h +FAKE_H=consumer_fake.h producer_fake.h GEN_H=events.h jobstat.h producer.h Event.h JobStatus.h interface_version.h @@ -39,7 +40,7 @@ check: interface_version.h: ${top_srcdir}/project/version.properties echo "#define GLITE_LB_CLIENT_INTERFACE \"${version}\"" >$@ stage: generate - $(MAKE) install PREFIX=${top_srcdir}/${stagedir} + $(MAKE) install PREFIX=${top_srcdir}/${stagedir} DOSTAGE=yes dist: distsrc distbin @@ -58,12 +59,17 @@ doc: generate doxygen C.dox doxygen CPP.dox -install: +install: generate doc -mkdir -p ${PREFIX}/${STAGETO} -mkdir -p ${PREFIX}/share/doc/${package}-${version} install -m 644 ${GEN_H} ${PREFIX}/${STAGETO} install -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} cd ${top_srcdir}/interface && install -m 644 ${STATIC_H} ${PREFIX}/${STAGETO} + cd ${top_srcdir}/doc && cp -r C CPP ${PREFIX}/share/doc/${package}-${version} + if [ x${DOSTAGE} = xyes ]; then \ + cd ${top_srcdir}/interface && install -m 644 ${FAKE_H} ${PREFIX}/${STAGETO} ; \ + fi + clean: rm -f *.h diff --git a/org.glite.lb.client-interface/build.xml b/org.glite.lb.client-interface/build.xml index f0f6a1a..22ebc3a 100755 --- a/org.glite.lb.client-interface/build.xml +++ b/org.glite.lb.client-interface/build.xml @@ -20,6 +20,9 @@ Revision history: $Log$ + Revision 1.6 2004/10/18 19:16:09 zsalvet + RPM descriptions + Revision 1.5 2004/08/05 15:22:34 dimeglio Changed default target from compile to dist @@ -90,6 +93,7 @@ Load version file ========================================= --> + + + + + + @@ -95,6 +85,7 @@ Load version file ========================================= --> + + + + +LB web service interface currently reflects the functionality of legacy +LB query API. + + + + + Flags determining which fields of job status should be retrieved. + Include also long job descriptions (JDL). + Return list of subjobs of a DAG. + Return state of the subjobs, i.e. apply other flags recursively + + + + Classification of job states. +@@@{ + for my $stat ($status->getTypesOrdered) { + my $u = uc $stat; + my $c = getTypeComment $status $stat; + gen qq{ +! $c +}; + } +@@@} + + +@@@{ + for my $n ($status->getAllFieldsOrdered) { + my $f = selectField $status $n; + if ($f->{codes}) { + my $n = getName $f; + $n = $1.ucfirst $2 while $n =~ /([[:alpha:]]*)_([[:alpha:]]*)/; + gen qq{ +! +! Auxiliary type; values of the jobStatus.$n field. +}; + for (@{$f->{codes}}) { + my $uc = uc $_->{name}; + gen qq{ +! $_->{comment} +}; + } + gen qq{ +! +}; + } + } +@@@} + + + + + Status of a job, possibly including subjobs. + Status name. +@@@{ + for my $n (getAllFieldsOrdered $status) { + selectField $status $n; + my $f = getField $status; + my $name = getName $f; + $name = $1.ucfirst $2 while $name =~ /([[:alpha:]]*)_([[:alpha:]]*)/; + my $type = $f->{type}; + my $list = 'no'; + + if ($main::baseTypes{$type}) { + $type = eval $main::types{wsdl}->{$main::baseTypes{$type}}; + $list = 'yes' + } + elsif ($f->{codes}) { + $type = $name; + } + else { + $type = getType $f; + } + + my $comment = getComment $f; +# XXX: currently nothing is "optional" as we don't know from status.T + gen qq{ +! $comment +}; + } +@@@} + + + + Value of a single user tag. + Tag name + Tag value + + + + UNIX time representation. + Seconds since Jan 1 1970 + Microseconds + + + + + Generic SOAP fault, used to deliver any LB errors. + May be returned by any of the operations. + Source component (module) of the error. + Numeric error code. + Error text corresponding to the code. + Additional description of the error (e.g. filename) + Reason of the error, coming from lower levels. + + + + + + + An element of outer list of query conditions in job queries. + It expresses possibly several conditions (records) on a single job attribute. + These conditions are logically OR-ed. + The job attribute to which the query conditions apply. + Name of the queried user tag if attr is USERTAG. + Name of the job state to which "attr = TIME" condition refers. + The conditions. + + + + Specification of a job attribute in query. + A concrete JobId + Owner of the job (X509 certificate subject). + Status of the job (see statName type). + Where the job is currently handled (hostname). + Where the job is or was scheduled to be executed. + How the job terminated (see doneCode type) + Value of particular user tag. The tag name has to be specified in queryConditions.tagName. + When the job entered a particular state. The state has to be specified in queryCondition.statName. + The job was resubmitted. + JobId of the job parend (DAG). + UNIX exit code of the job. + + + + A single query condition. + Relational operator of the condition. + Value to compare the attribute with. + Another value to compare the attribute with (op = WITHIN only). + + + + Relational operator of query conditions. + Attribute is equal to the specified value + Attribute is less than the specified value or equal + Attribute is greater than the specified value or equal + Attribute is withing a range (queryRecord.value2 must be specified) + Attribute is not equal to the specified value. + + + + A value to compare an attribute with in queries. + Exactly one of the elements must be specified. + Integer. + String. + Timestamp. + + + + + + + + Query state of a single job. + Id of the queried job. + Which data fields to retrieve. + Current state of the job. + Any error. + + + + Retrieve a list of jobs, including their states, based on + query conditions. + The conditions take the form of a list of lists. + Elements of the inner lists refer to a single job attribute, the conditions are or-ed. + Elements of the outer list may refer to different job attributes, they are and-ed. + + The query conditions. + Which data fields to retrieve. + JobId's of jobs matching the query. + States of jobs matching the query. + Any error. + + + + Return version of the service. + Returned version. + Any error. + + + + Simplified query, return all jobs of the authenticated user. + JobId's of jobs matching the query. + States of jobs matching the query. + Any error. + + + diff --git a/org.glite.lb.ws-interface/src/puke-ug.xsl b/org.glite.lb.ws-interface/src/puke-ug.xsl new file mode 100644 index 0000000..2536d40 --- /dev/null +++ b/org.glite.lb.ws-interface/src/puke-ug.xsl @@ -0,0 +1,139 @@ + + + + + + + + + + + <xsl:value-of select="@name"/> + + Operations + + + + + + + Types + + + + + + + + + + + + + + + + + + xsd: + + + + + + + + + + + + + <xsl:value-of select="@name"/> + + + Inputs: + + + + + + + N/A + + + + Outputs: + + + + + + + + + + + + <xsl:value-of select="@name"/> + + + + Structure (sequence complex type in WSDL) + Fields: ( type name description ) + + + Enumeration (restriction of xsd:string in WSDL), + exactly one of the values must be specified. + + Values: + + + Flags (sequence of restricted xsd:string in WSDL), + any number of values can be specified together. + + Values: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (optional) + (multiple occurence) + + + + + + + + + + + + diff --git a/org.glite.lb/build.xml b/org.glite.lb/build.xml index 2ded065..3647e56 100755 --- a/org.glite.lb/build.xml +++ b/org.glite.lb/build.xml @@ -20,6 +20,9 @@ Revision history: $Log$ + Revision 1.28 2004/11/29 15:16:26 zsalvet + Add ws-interface to checkout/build machinery. + Revision 1.27 2004/11/29 13:55:02 akrenek added dependence on ws-interface @@ -152,6 +155,7 @@ Load version file ========================================= --> + - - - + - + + + - - - - + + + + - + - - + - + + - + - + - + + + + + + diff --git a/org.glite.security.gsoap-plugin/examples/calc.h.S b/org.glite.security.gsoap-plugin/examples/calc.h.S new file mode 100644 index 0000000..385e872 --- /dev/null +++ b/org.glite.security.gsoap-plugin/examples/calc.h.S @@ -0,0 +1,13 @@ +//gsoap egeesec schema namespace: urn:calc +// +//gsoap egeesec service name: calc +//gsoap egeesec service port: http://localhost:9999/ +//gsoap egeesec service namespace: urn:calc:wscalc + +//gsoap egeesec service method-style: add rpc +//gsoap egeesec service method-action: add "" +int wscalc__add(double a, double b, double *result); + +//gsoap egeesec service method-style: sub rpc +//gsoap egeesec service method-action: sub "" +int wscalc__sub(double a, double b, double *result); diff --git a/org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c b/org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c new file mode 100644 index 0000000..b96827d --- /dev/null +++ b/org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c @@ -0,0 +1,47 @@ +#include + +#include "GSOAP_H.h" +#include "wscalc.nsmap" + +static const char *server = "http://localhost:9999/"; + +int +main(int argc, char **argv) +{ + struct soap soap; + double a, b, result; + int ret; + + + if (argc < 4) { + fprintf(stderr, "Usage: [add|sub] num num\n"); + exit(1); + } + + soap_init(&soap); + soap_register_plugin(&soap, glite_gsplugin); + + a = strtod(argv[2], NULL); + b = strtod(argv[3], NULL); + switch ( *argv[1] ) { + case 'a': + ret = soap_call_wscalc__add(&soap, server, "", a, b, &result); + break; + case 's': + ret = soap_call_wscalc__sub(&soap, server, "", a, b, &result); + break; + default: + fprintf(stderr, "Unknown command\n"); + exit(2); + } + + if ( ret ) { + fprintf(stderr, "NECO JE V ****\n\n"); + fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); + soap_print_fault(&soap, stderr); + } + else printf("result = %g\n", result); + + + return 0; +} diff --git a/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c new file mode 100644 index 0000000..96d58f4 --- /dev/null +++ b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include + +#include "GSOAP_H.h" +#include "wscalc.nsmap" + + +static struct option long_options[] = { + { "cert", required_argument, NULL, 'c' }, + { "key", required_argument, NULL, 'k' }, + { NULL, 0, NULL, 0 } +}; + +void +usage(const char *me) +{ + fprintf(stderr, + "usage: %s [option]\n" + "\t-c, --cred\t certificate file\n" + "\t-k, --key\t private key file\n", me); +} + + +int +main(int argc, char **argv) +{ + struct soap soap; + glite_gsplugin_Context ctx = NULL; + char *name; + char *cert, *key; + int opt; + + + cert = key = NULL; + name = strrchr(argv[0],'/'); + if ( name ) name++; else name = argv[0]; + + while ((opt = getopt_long(argc, argv, "c:k:", long_options, NULL)) != EOF) { + switch (opt) { + case 'c': cert = optarg; break; + case 'k': key = optarg; break; + case '?': + default : usage(name); exit(1); + } + } + + if ( cert || key ) { + if ( glite_gsplugin_init_context(&ctx) ) { perror("init context"); exit(1); } + ctx->cert_filename = strdup(cert? : key); + ctx->key_filename = strdup(key? : cert); + } + + soap_init(&soap); + + if ( soap_register_plugin_arg(&soap, glite_gsplugin, ctx? : NULL) ) { + fprintf(stderr, "Can't register plugin\n"); + exit(1); + } + + if ( soap_bind(&soap, NULL, 9999, 100) < 0 ) { + soap_print_fault(&soap, stderr); + exit(1); + } + + while ( 1 ) { + printf("accepting connection\n"); + if ( soap_accept(&soap) < 0 ) { + fprintf(stderr, "soap_accept() failed!!!\n"); + soap_print_fault(&soap, stderr); + fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); + break; + } + + printf("serving connection\n"); + if ( soap_serve(&soap) ) { + soap_print_fault(&soap, stderr); + fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); + } + + soap_destroy(&soap); /* clean up class instances */ + soap_end(&soap); /* clean up everything and close socket */ + } + soap_done(&soap); /* close master socket */ + + if ( ctx ) glite_gsplugin_free_context(ctx); + + return 0; +} + +int wscalc__add(struct soap *soap, double a, double b, double *result) +{ + *result = a + b; + return SOAP_OK; +} + +int wscalc__sub(struct soap *soap, double a, double b, double *result) +{ + *result = a - b; + return SOAP_OK; +} diff --git a/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c new file mode 100644 index 0000000..8a7c001 --- /dev/null +++ b/org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include + +#include "GSOAP_H.h" +#include "wscalc.nsmap" + + +static struct option long_options[] = { + { "cert", required_argument, NULL, 'c' }, + { "key", required_argument, NULL, 'k' }, + { "port", required_argument, NULL, 'p' }, + { NULL, 0, NULL, 0 } +}; + +void +usage(const char *me) +{ + fprintf(stderr, + "usage: %s [option]\n" + "\t-p, --port\t listening port\n" + "\t-c, --cred\t certificate file\n" + "\t-k, --key\t private key file\n", me); +} + + +int +main(int argc, char **argv) +{ + struct soap soap; + edg_wll_GssStatus gss_code; + glite_gsplugin_Context ctx; + struct sockaddr_in a; + int alen; + char *name, *msg; + char *subject = NULL; + int opt, + port = 9999; + int sock; + + + name = strrchr(argv[0],'/'); + if ( name ) name++; else name = argv[0]; + + if ( glite_gsplugin_init_context(&ctx) ) { perror("init context"); exit(1); } + + while ((opt = getopt_long(argc, argv, "c:k:p:", long_options, NULL)) != EOF) { + switch (opt) { + case 'p': port = atoi(optarg); break; + case 'c': ctx->cert_filename = strdup(optarg); break; + case 'k': ctx->key_filename = strdup(optarg); break; + case '?': + default : usage(name); exit(1); + } + } + + if ( edg_wll_gss_acquire_cred_gsi(ctx->cert_filename, ctx->key_filename, &ctx->cred, &subject, &gss_code) ) { + edg_wll_gss_get_error(&gss_code, "Failed to read credential", &msg); + fprintf(stderr, "%s\n", msg); + free(msg); + exit(1); + } + if (subject) { + printf("server running with certificate: %s\n", subject); + free(subject); + } + + soap_init(&soap); + + if ( soap_register_plugin_arg(&soap, glite_gsplugin, ctx) ) { + fprintf(stderr, "Can't register plugin\n"); + exit(1); + } + + alen = sizeof(a); + if ( (sock = socket(PF_INET,SOCK_STREAM,0)) < 0 ) { perror("socket()"); exit(1); } + a.sin_family = AF_INET; + a.sin_port = htons(port); + a.sin_addr.s_addr = INADDR_ANY; + if ( bind(sock, (struct sockaddr *)&a, sizeof(a)) ) { perror("bind()"); exit(1); } + if ( listen(sock, 100) ) { perror("listen()"); exit(1); } + if ( !(ctx->connection = malloc(sizeof(*ctx->connection))) ) exit(1); + + bzero((char *) &a, alen); + + while ( 1 ) { + int conn; + + printf("accepting connection\n"); + if ( (conn = accept(sock, (struct sockaddr *) &a, &alen)) < 0 ) { + close(sock); + perror("accept"); + exit(1); + } + if ( edg_wll_gss_accept(ctx->cred,conn,ctx->timeout,ctx->connection,&gss_code) ){ + edg_wll_gss_get_error(&gss_code, "Failed to read credential", &msg); + fprintf(stderr, "%s\n", msg); + free(msg); + exit(1); + } + + printf("serving connection\n"); + if ( soap_serve(&soap) ) { + soap_print_fault(&soap, stderr); + fprintf(stderr, "plugin err: %s", glite_gsplugin_errdesc(&soap)); + } + + soap_destroy(&soap); /* clean up class instances */ + soap_end(&soap); /* clean up everything and close socket */ + } + + soap_done(&soap); /* close master socket */ + + glite_gsplugin_free_context(ctx); + + return 0; +} + +int wscalc__add(struct soap *soap, double a, double b, double *result) +{ + *result = a + b; + return SOAP_OK; +} + +int wscalc__sub(struct soap *soap, double a, double b, double *result) +{ + *result = a - b; + return SOAP_OK; +} diff --git a/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h b/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h new file mode 100644 index 0000000..1272a48 --- /dev/null +++ b/org.glite.security.gsoap-plugin/interface/glite_gsplugin.h @@ -0,0 +1,37 @@ +#ifndef __GLITE_GSOAP_PLUGIN_H__ +#define __GLITE_GSOAP_PLUGIN_H__ + +#include + +#include "glite_gss.h" + +#define PLUGIN_ID "GLITE_GSOAP_PLUGIN" + +struct _glite_gsplugin_ctx { + struct timeval _timeout, *timeout; + + char *error_msg; + + char *key_filename; + char *cert_filename; + + edg_wll_GssConnection *connection; + gss_cred_id_t cred; + + void *user_data; +}; + +typedef struct _glite_gsplugin_ctx *glite_gsplugin_Context; + +extern int glite_gsplugin_init_context(glite_gsplugin_Context *); +extern int glite_gsplugin_free_context(glite_gsplugin_Context); +extern glite_gsplugin_Context glite_gsplugin_get_context(struct soap *); +extern void *glite_gsplugin_get_udata(struct soap *); +extern void glite_gsplugin_set_udata(struct soap *, void *); + +extern void glite_gsplugin_set_timeout(glite_gsplugin_Context, struct timeval const *); + +extern int glite_gsplugin(struct soap *, struct soap_plugin *, void *); +extern char *glite_gsplugin_errdesc(struct soap *); + +#endif diff --git a/org.glite.security.gsoap-plugin/interface/glite_gss.h b/org.glite.security.gsoap-plugin/interface/glite_gss.h new file mode 100644 index 0000000..3dd4903 --- /dev/null +++ b/org.glite.security.gsoap-plugin/interface/glite_gss.h @@ -0,0 +1,117 @@ +#ifndef __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ +#define __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ + +#ident "$Header$" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + EDG_WLL_GSS_OK = 0, /* no GSS errors */ + EDG_WLL_GSS_ERROR_GSS = -1, /* GSS specific error, call edg_wll_get_gss_error() for details */ + EDG_WLL_GSS_ERROR_TIMEOUT = -2, /* Timeout */ + EDG_WLL_GSS_ERROR_EOF = -3, /* EOF occured */ + EDG_WLL_GSS_ERROR_ERRNO = -4, /* System error. See errno */ + EDG_WLL_GSS_ERROR_HERRNO = -5 /* Resolver error. See h_errno */ +}; + +typedef struct _edg_wll_GssConnection { + gss_ctx_id_t context; + int sock; + char *buffer; + size_t bufsize; +} edg_wll_GssConnection; + +typedef struct _edg_wll_GssStatus { + OM_uint32 major_status; + OM_uint32 minor_status; +} edg_wll_GssStatus; + +/* XXX Support anonymous connections. Are we able/required to support + * anonymous servers as well. */ + +int +edg_wll_gss_acquire_cred_gsi(char *cert_file, + char *key_file, + gss_cred_id_t *cred, + char **name, + edg_wll_GssStatus* gss_code); + +int +edg_wll_gss_connect(gss_cred_id_t cred, + char const *hostname, + int port, + struct timeval *timeout, + edg_wll_GssConnection *connection, + edg_wll_GssStatus* gss_code); + +int +edg_wll_gss_accept(gss_cred_id_t cred, + int sock, + struct timeval *timeout, + edg_wll_GssConnection *connection, + edg_wll_GssStatus* gss_code); + +int +edg_wll_gss_read(edg_wll_GssConnection *connection, + void *buf, + size_t bufsize, + struct timeval *timeout, + edg_wll_GssStatus* gss_code); + +int +edg_wll_gss_write(edg_wll_GssConnection *connection, + const void *buf, + size_t bufsize, + struct timeval *timeout, + edg_wll_GssStatus* gss_code); + +int +edg_wll_gss_read_full(edg_wll_GssConnection *connection, + void *buf, + size_t bufsize, + struct timeval *timeout, + size_t *total, + edg_wll_GssStatus* gss_code); + +int +edg_wll_gss_write_full(edg_wll_GssConnection *connection, + const void *buf, + size_t bufsize, + struct timeval *timeout, + size_t *total, + edg_wll_GssStatus* gss_code); + +int +edg_wll_gss_watch_creds(const char * proxy_file, + time_t * proxy_mtime); + +int +edg_wll_gss_get_error(edg_wll_GssStatus* gss_code, + const char *prefix, + char **errmsg); + +int +edg_wll_gss_close(edg_wll_GssConnection *connection, + struct timeval *timeout); + +int +edg_wll_gss_reject(int sock); + +int +edg_wll_gss_oid_equal(const gss_OID a, + const gss_OID b); + +/* +int +edg_wll_gss_get_name(gss_cred_id_t cred, char **name); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __EDG_WORKLOAD_LOGGING_COMMON_LB_GSS_H__ */ diff --git a/org.glite.security.gsoap-plugin/project/build.number b/org.glite.security.gsoap-plugin/project/build.number new file mode 100644 index 0000000..abb62dc --- /dev/null +++ b/org.glite.security.gsoap-plugin/project/build.number @@ -0,0 +1,2 @@ +#Thu Jun 02 03:37:13 CEST 2005 +module.build=21 diff --git a/org.glite.jp.common/project/build.properties b/org.glite.security.gsoap-plugin/project/build.properties similarity index 100% rename from org.glite.jp.common/project/build.properties rename to org.glite.security.gsoap-plugin/project/build.properties diff --git a/org.glite.jp.primary/project/configure.properties.xml b/org.glite.security.gsoap-plugin/project/configure.properties.xml similarity index 52% rename from org.glite.jp.primary/project/configure.properties.xml rename to org.glite.security.gsoap-plugin/project/configure.properties.xml index 3f88fbf..7b9f931 100644 --- a/org.glite.jp.primary/project/configure.properties.xml +++ b/org.glite.security.gsoap-plugin/project/configure.properties.xml @@ -1,29 +1,30 @@ - - + + @@ -38,15 +39,13 @@ package=${module.package.name} PREFIX=${install.dir} version=${module.version} glite_location=${with.glite.location} -globus_prefix=${with.globus.prefix} -expat_prefix=${with.expat.prefix} ares_prefix=${with.ares.prefix} -gsoap_prefix=${with.gsoap.prefix} +globus_prefix=${with.globus.prefix} thrflavour=${with.globus.thr.flavor} nothrflavour=${with.globus.nothr.flavor} cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} +gsoap_prefix=${with.gsoap.prefix} +gsplugin_version_checking=${gsplugin.version.checking} diff --git a/org.glite.jp.common/project/properties.xml b/org.glite.security.gsoap-plugin/project/properties.xml similarity index 52% rename from org.glite.jp.common/project/properties.xml rename to org.glite.security.gsoap-plugin/project/properties.xml index b9d669d..f63ddbd 100755 --- a/org.glite.jp.common/project/properties.xml +++ b/org.glite.security.gsoap-plugin/project/properties.xml @@ -1,42 +1,45 @@ - + - + - + - + - + + + @@ -80,6 +83,8 @@ Load version file ========================================= --> + + >Create HEADER ?? @@ -79,6 +80,7 @@ void Exception::log(const std::string& logfile) pthread_mutex_unlock( &METHOD_MUTEX); // UNLOCK } }; + string Exception::printStackTrace(){ string stack = "" ; for (unsigned int i = 0 ; i < stack_strings.size() ; i++ ){ @@ -86,25 +88,27 @@ string Exception::printStackTrace(){ } return stack +dbgMessage(); }; + vector Exception::getStackTrace(){ // make a copy of the stack vector stack = stack_strings ; - stack.push_back(dbgMessage() ) ; + stack.push_back(dbgMessage()) ; return stack; }; string Exception::dbgMessage(){ string result ; //Adding exception Name - if ( exception_name!="") - result = exception_name ; + result = exception_name; + //Adding error msg - if (error_message!="") - result +=": " + string(what()); - if (result != "") - result+="\n"; + if (error_message!="") result +=": " + string(what()); + + if (result != "") result+="\n"; + //Adding Source result +="\tat " + method_name +"[" +source_file; + //Adding line number if (line!=0){ char buffer [1024] ; diff --git a/org.glite.wms-utils.jobid/build.xml b/org.glite.wms-utils.jobid/build.xml index 220b2a6..009513f 100755 --- a/org.glite.wms-utils.jobid/build.xml +++ b/org.glite.wms-utils.jobid/build.xml @@ -21,6 +21,9 @@ Revision history: $Log$ + Revision 1.4 2004/07/21 17:53:36 eronchie + Moved out org.glite.wms.jobid from org.glite.wms and put in org.glite.wms-utils + --> @@ -80,6 +83,8 @@ Load version file ========================================= --> + + + - - - @@ -154,7 +167,7 @@ - + @@ -209,7 +222,45 @@ Private targets =============================================== --> - + + + + + + + + + New tag is ${cvs.label} + + + + + + + + + + + + + + + + + + New tag is ${cvs.label} + + + + + + + + + diff --git a/org.gridsite.core/doc/config.html b/org.gridsite.core/doc/config.html index 825bf49..2edeb27 100644 --- a/org.gridsite.core/doc/config.html +++ b/org.gridsite.core/doc/config.html @@ -96,6 +96,10 @@ directives in this file. The easiest way to get started is to examine the example httpd.conf files we provide. +

+Please note: this version of GridSite is not compatible with the +SHM SSL session cache - use the DBM or per-process caches instead. + pC17-! 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
c9Yl`Gi%kkVY{ak?XfKH2Vc<6g1xT7 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 diff --git a/org.gridsite.core/src/showx509exts.c b/org.gridsite.core/src/showx509exts.c new file mode 100644 index 0000000..d37dff4 --- /dev/null +++ b/org.gridsite.core/src/showx509exts.c @@ -0,0 +1,117 @@ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "gridsite.h" + +#define MAXTAG 500 + +main() +{ + X509 *cert, *tmpcert; + STACK_OF(X509) *certstack = sk_X509_new_null(); + FILE *fp; + struct vomsdata *vd; + int i, j, vomserror, i1, i2, j1, j2, lastobject; + X509_EXTENSION *ex; + ASN1_OBJECT *asnobject; + char s[80], *t; + ASN1_OCTET_STRING *asndata; + BIO *out; + unsigned char *p, *op, *tot, *p1, *p2, *q, *oq; + long len1, length1, len2, length2; + int tag,xclass,ret=0; + struct GRSTasn1TagList taglist[MAXTAG+1]; + int lasttag=-1, itag; + + + OpenSSL_add_all_algorithms(); + ERR_load_crypto_strings(); +// seed_prng(); + +// fp = fopen("proxy-with-voms", "r"); + fp = fopen("/tmp/x509up_u300", "r"); + + cert = PEM_read_X509(fp, NULL, NULL, NULL); + + fclose(fp); + + out=BIO_new(BIO_s_file()); + BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); + + for (i = 0; i < X509_get_ext_count(cert); ++i) + { + lasttag=-1; + + ex = X509_get_ext(cert, i); + + OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ex), 1); + printf("%d OID=%s\n", i, s); + + asnobject = X509_EXTENSION_get_object(ex); + asndata = X509_EXTENSION_get_data(ex); + + p1 = ASN1_STRING_data(asndata); + p = p1; + length1 = ASN1_STRING_length(asndata); + + GRSTasn1ParseDump(out, p1, length1, taglist, MAXTAG, &lasttag); + +{ + int n, tag, xclass; + unsigned char *q, buf[100]; + const unsigned char *dn, hash[EVP_MAX_MD_SIZE]; + ASN1_OBJECT *obj = NULL; + const EVP_MD *m; + EVP_MD_CTX ctx; + + itag = GRSTasn1SearchTaglist(taglist, &lasttag, + "-1-1-1-1-2-1-1-1-1-1-1-1"); + + X509_NAME *xname; + + q = &p[taglist[itag].start]; + + d2i_ASN1_OBJECT(&obj, &q, taglist[itag].length + + taglist[itag].headerlength); + + n = OBJ_obj2nid(obj); + dn = OBJ_nid2sn(n); + +// dn = X509_NAME_oneline(xname,NULL,0); + + printf("n=%d dn=%s obj2txt=%s\n", n, dn, OBJ_obj2txt(NULL,0,obj,1)); + + GRSTasn1GetX509Name(buf, 99, "-1-1-1-1-2-1-1-1-1-%d-1-%d", p1, taglist, &lasttag); + printf("%s\n", buf); + GRSTasn1GetX509Name(buf, 99, "-1-1-1-1-3-1-1-1-%d-1-%d", p1, taglist, &lasttag); + printf("%s\n", buf); + +/* + m = EVP_md5(); + EVP_DigestInit(&ctx, m); + EVP_DigestUpdate(&ctx, delegation_id, strlen(delegation_id)); + EVP_DigestFinal(&ctx, hash, &delegation_id_len); + */ +} + +/* + itag = GRSTasn1SearchTaglist(taglist, &lasttag, + "1-1-1-1-1-7-1-2-1-2-1"); + + printf("tag=%d %s %d %.*s\n", + itag, taglist[itag].treecoords, taglist[itag].tag, + taglist[itag].length, + &p[taglist[itag].start+taglist[itag].headerlength]); +*/ + } +} diff --git a/org.gridsite.core/src/xacmlexample.c b/org.gridsite.core/src/xacmlexample.c new file mode 100644 index 0000000..af914b9 --- /dev/null +++ b/org.gridsite.core/src/xacmlexample.c @@ -0,0 +1,148 @@ +/* + Copyright (c) 2005, Andrew McNab and Shiv Kaushal, University of Manchester + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + o Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + o Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/*---------------------------------------------------------------* + * For more about GridSite: http://www.gridsite.org/ * + *---------------------------------------------------------------*/ + +/* + Example program using XACML + + Build with: + + gcc -o xacmlexample xacmlexample.c -L. -I. -lgridsite -lxml2 -lz -lm +*/ + +#include +#include +#include +#include + +int main() +{ + GRSTgaclCred *cred, *usercred; + GRSTgaclEntry *entry; + GRSTgaclAcl *acl1, *acl2; + GRSTgaclUser *user; + GRSTgaclPerm perm0, perm1, perm2; + FILE *fp; + + /* must initialise GACL before using XACML functions */ + + GRSTgaclInit(); + + /* build up an ACL, starting with a credential */ + + cred = GRSTgaclCredNew("person"); + + GRSTgaclCredAddValue(cred, "dn", "/O=Grid/CN=Mr Grid Person"); + + /* create an entry to put it in */ + + entry = GRSTgaclEntryNew(); + + /* add the credential to it */ + + GRSTgaclEntryAddCred(entry, cred); + + /* add another credential */ + + cred = GRSTgaclCredNew("dn-list"); + GRSTgaclCredAddValue(cred, "url", "example-dn-list"); + GRSTgaclEntryAddCred(entry, cred); + + fp = fopen("example-dn-list", "w"); + fputs("/O=Grid/CN=Mr Grid Person\n", fp); + fclose(fp); + + /* associate some permissions and denials to the credential */ + + GRSTgaclEntryAllowPerm( entry, GRST_PERM_READ); + GRSTgaclEntryAllowPerm( entry, GRST_PERM_WRITE); + GRSTgaclEntryAllowPerm( entry, GRST_PERM_ADMIN); + GRSTgaclEntryDenyPerm( entry, GRST_PERM_ADMIN); + GRSTgaclEntryDenyPerm( entry, GRST_PERM_LIST); + + perm0 = GRST_PERM_READ | GRST_PERM_WRITE; + + printf("test perm should be %d\n", perm0); + + /* create a new ACL and add the entry to it */ + + acl1 = GRSTgaclAclNew(); + + GRSTgaclAclAddEntry(acl1, entry); + + /* create a GRSTgaclUser to compare with the ACL */ + + usercred = GRSTgaclCredNew("person"); + + GRSTgaclCredAddValue(usercred, "dn", "/O=Grid/CN=Mr Grid Person"); + + user = GRSTgaclUserNew(usercred); + + GRSTgaclUserSetDNlists(user, getcwd(NULL, 0)); + printf("DN Lists dir %s\n", getcwd(NULL, 0)); + +// putenv("GRST_DN_LISTS=."); + + perm1 = GRSTgaclAclTestUser(acl1, user); + + printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm1); + + /* print and save the whole ACL */ + + GRSTgaclAclPrint(acl1, stdout); + + GRSTxacmlAclSave(acl1, "example.xacml"); + + puts("gridacl.out saved"); + + puts(""); + + /* load the ACL back off the disk, print and test it */ + + acl2 = GRSTxacmlAclLoadFile("example.xacml"); + + puts("gridacl.out loaded"); + + if (acl2 != NULL) GRSTgaclAclPrint(acl2, stdout); else puts("acl2 is NULL"); + + perm2 = GRSTgaclAclTestUser(acl2, user); + + printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm2); + + if (perm1 != perm0) return 1; + if (perm2 != perm0) return 2; + + return 0; +} + -- 1.8.2.3

This release fixes the -following bugs and issues. Since there are no previous public releases, this -list refers to the previous development release. Bug numbers refer to the gLite -Bug Tracking system database hosted on the CERN Savannah system at https://savannah.cern.ch/bugs/?group=jra1mdw