From 6e06d156a90babd796a3714ef7180634c4c70d37 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Posp=C3=AD=C5=A1il?= Date: Thu, 6 Dec 2007 14:58:38 +0000 Subject: [PATCH] import of old LBUG --- org.glite.lb.doc/src/LBUG.tex | 188 +++++++ org.glite.lb.doc/src/arch.tex | 114 ++++ org.glite.lb.doc/src/cmdln_interface.tex | 54 ++ org.glite.lb.doc/src/consumer_api.tex | 801 ++++++++++++++++++++++++++++ org.glite.lb.doc/src/copyright.tex | 24 + org.glite.lb.doc/src/log_usertag.tex | 54 ++ org.glite.lb.doc/src/logging-arch-notif.pdf | Bin 0 -> 67535 bytes org.glite.lb.doc/src/security.tex | 56 ++ 8 files changed, 1291 insertions(+) create mode 100644 org.glite.lb.doc/src/LBUG.tex create mode 100644 org.glite.lb.doc/src/arch.tex create mode 100644 org.glite.lb.doc/src/cmdln_interface.tex create mode 100644 org.glite.lb.doc/src/consumer_api.tex create mode 100644 org.glite.lb.doc/src/copyright.tex create mode 100644 org.glite.lb.doc/src/log_usertag.tex create mode 100644 org.glite.lb.doc/src/logging-arch-notif.pdf create mode 100644 org.glite.lb.doc/src/security.tex diff --git a/org.glite.lb.doc/src/LBUG.tex b/org.glite.lb.doc/src/LBUG.tex new file mode 100644 index 0000000..7f87bcf --- /dev/null +++ b/org.glite.lb.doc/src/LBUG.tex @@ -0,0 +1,188 @@ +\documentclass{egee} +\usepackage{doxygen} +\usepackage{tabularx} + +\def\LB{L\&B} +\def\eg{e.\,g.} +\def\ie{i.\,e.} +\def\Dash{\,---\,\penalty-1000} +\def\todo#1{\par\textbf{TODO:} #1\par} + +\title{Logging and Bookkeeping} +\Subtitle{User's Guide} +\author{CESNET EGEE II JRA1 team} +\DocIdentifier{EGEE-II....} +\Date{\today} +\Activity{JRA1: Middleware Engineering and Integration} +\DocStatus{DRAFT} +\Dissemination{PUBLIC} +\DocumentLink{http://...} + +\Abstract{ +This user's guide explains how to use the Logging and Bookkeeping (\LB) service. +The service architecture is described briefly. +Examples on using \LB\ event logging command to log a~user tag and change job ACL are given, +as well as \LB\ query and notification API use cases. +% The reference section contains complete description of both the logging command and the API's. +} + +\begin{document} + +\input{frontmatter} +\newpage +\tableofcontents +\newpage + +\section{Introduction} +%This Section should give a brief summary of what the service described +%is supposed to achieve and how it fits into the overall +%architecture. It should contain subsections on the service internal +%architecture and its relations to other services. + +The Logging and Bookkeeping (\LB) service tracks jobs managed by +the gLite WMS (workload management system). +It gathers events from various WMS components in a~reliable way +and processes them in order to give a~higher level view, the +\emph{status of job}. + +Virtually all the important +data are fed to \LB\ internally from various gLite middleware +components, transparently from the user's point of view. +On the contrary, \LB\ provides public interfaces for querying the job +information synchronously as well as registering for asynchronous +notifications. +API's for this functionality are described in this document in detail. + + +\subsection{Service Architecture} +\input{arch} + + +\subsection{Security and Access Control} +\input{security} + + +\subsection{Interactions with other Services} +\input{interaction} + + +\newpage +\section{Quickstart Guide} +% The quickstart guide should explain in simple terms and with examples +% how a user is supposed to achieve the most common usecases. E.g. how +% to submit and cancel a job, how to receive a job's output. How to +% create a grid file, move it around, locate it, and delete it. How to +% monitor the progress on an application etc. + +\subsection{Command-Line Tools} +This section describes usage of event-logging \LB\ command in the two +cases which are ment for the end-user: adding a~user description (tag) +to a~job, and changing a~job access control list. + +\subsubsection{Logging a UserTag event} +\label{log_usertag} +\input{log_usertag} + +\subsubsection{Changing Job Access Control List} +\label{change_acl} +\input{change_acl} + + +%% \subsection{\LB Producer API} +%% \todo{honik} +%% This API is not public at the moment, it may change later. +%% \input{producer_api} + + +\subsection{\LB\ Querying API} +%\todo{valtri} +\input{consumer_api} + + +\subsection{\LB\ Notification API} +\input{notification_api} + + +\newpage +\section{Reference Guide} + +%The reference guide should contain detailed descriptions of all +%provided CLIs and APIs. There should be two subsections for those. + +\subsection{Command-Line Interfaces} +\label{cmdln_interface} +\input{cmdln_interface} + + +\newpage + +\subsection{\LB\ Web Service Interface} + +The \LB\ web service interface currently reflects the functionality of legacy +\LB\ query API (Sect.~\ref{query-C}). + +The following sections describe the operations defined in the \LB\ WSDL +file as well as its custom types. + +For the sake of readability this documentation does not follow the structure +of WSDL strictly, avoiding to duplicate information which is already present +here. +Conseqently, the SOAP messages are not documented, for example, as they +are derived from operation inputs and outputs mechanically. +The same holds for types: \eg\ we do not document defined elements +which correspond 1:1 to types but are required due to the literal SOAP +encoding. + +For exact definition of the operations and types see the WSDL file. + + +{ +\def\chapter#1{} +\def\section#1{\subsubsection{#1}} +\def\subsection#1{\par\textbf{#1}\par} + +\let\odesc=\description +\let\oedesc=\enddescription +\renewenvironment{description}{\odesc\itemindent=1em +\listparindent=2em +}{\oedesc} +%\renewenvironment{description}{\list{}{\labelwidth 5cm\leftmargin 5cm}} +%{\endlist} + +\let\null=\relax +%\input LB-ug +} + + +\newpage +\section{Known Problems and Caveats} +\input{caveats} + + +\begin{thebibliography}1 +\bibitem[R1]{lbapi}\emph{\LB\ API Reference}, DataGrid-01-TED-0139. +\bibitem[R2]{lbarch}\emph{\LB\ Architecture release 2}, DataGrid-01-TED-0141. +\bibitem[R3]{WMS} G.Avellino at al., \emph{The DataGrid Workload Management System: Challenges and Results}, Journal of Grid Computing, ISSN: 1570-7873, 2005, accepted. +\end{thebibliography} + +\clearpage + +\appendix + +\section{Component and Interaction Diagrams} +% \todo{nekdy priste} +% To help understanding the service a set of component and interaction +% diagrams might help. This section is not mandatory. + + +\begin{figure}[h] +\centering +\includegraphics[width=.8\hsize]{logging-arch-notif} +\caption{Overview of the \LB\ architecture} +\label{fig-arch} +\end{figure} + + + + +\end{document} diff --git a/org.glite.lb.doc/src/arch.tex b/org.glite.lb.doc/src/arch.tex new file mode 100644 index 0000000..afd752d --- /dev/null +++ b/org.glite.lb.doc/src/arch.tex @@ -0,0 +1,114 @@ +Within the gLite WMS, upon creation + each job is assigned a~unique, virtually non-recyclable +\emph{job identifier} (JobId) in an~URL form. +The server part of the URL designates the \emph{bookkeeping server} which +gathers and provides information on the job for its whole life. + +High level view on the \LB\ architecture is shown in Fig.~\ref{fig-arch} +on page~\pageref{fig-arch}. + +\LB\ tracks jobs in terms of \emph{events} (\eg\ \emph{Transfer} from a~WMS +component to another one, \emph{Run} and \emph{Done} when the jobs starts +and stops execution, \dots). +Each event type carries its specific attributes. +The entire architecture is specialized for this purpose and is job-centric\Dash +any event is assigned to a~unique Grid job. + +\subsubsection{Event delivery and storage} +The events are gathered from various WMS components by the +\emph{\LB\ producer library} +and passed on to the \emph{locallogger} daemon, +running physically close to avoid +any sort of network problems. +The locallogger's task is storing the accepted event in a~local disk file. +Once it's done, confirmation is sent back and the logging library call +returns, reporting success. +Consequently, logging calls have local, virtually non-blocking semantics. + +Further on, event delivery is managed by the \emph{interlogger} daemon. +It takes the events from the locallogger (or the disk files on crash recovery), +and repeatedly tries to deliver them to the destination +bookkeeping server (known from the JobId) until it succeeds finally. +Therefore the entire event delivery is highly reliable. +However, in the standard mode described so far it is asynchronous +(there is a~synchronous mode for special usage not discussed here) +there is no direct way for the caller to see whether an event has been +already delivered. +Our experience shows that the semantics is suitable in the prevailing number +of cases while being the most efficient in the erratic Grid environment. + +The bookkeeping server processes the incoming events +to give a~higher level view +on the job states (\eg\ \emph{Submitted, Running, Done}), +each having an appropriate set of attributes again. +\LB\ provides a~public interface (Sect.~\ref{query-C}) +to retrieve them via synchronous queries. + +Further on, upon each event delivery to the \LB\ server the new computed +job state is matched against the set of registered requests for notification. +If some of them match, special events\Dash\emph{notifications} are generated +and passed to a~modified +\emph{notification interlogger}. +It takes over the notification from LB server, stores it into file and +periodically tries to deliver it to the address where the corresponding +notification client is listening. +If the user changes this address (IP or port) +\LB\ server instructs the notification interlogger to change +the destination of possible pending notifications. + +\subsubsection{Queries} +\label{arch-queries} +One part of the \LB\ interface is the query API (Sect.~\ref{query-C}). +Two types of queries are supported\Dash\emph{job queries} which return +one or more jobs, including a~detailed description of their states, +and \emph{event queries} returning the raw \LB\ events. +In general, job queries are used to track normal life of jobs, +event queries are used mostly for tracing abnormal behaviour. + +Each query is formed of several conditions (\eg\ concrete jobid's, +owner of jobs, particular job state etc.). +The \LB\ library formats the conditions into a~query message, passes it to +the server, and waits for the response which is passed to the user +synchronously. + +\subsubsection{Notifications} +\label{notification} +On the contrary, the notification API (Sect.~\ref{notify-C}) allows +the user to +register for notifications. These are delivered to the listening +client asynchronously, when the particular event (a~change of job status +typically) occurs. +The main purpose of this \LB\ functionality is avoiding unnecessary load +on the \LB\ server serving many repeated queries (polling) with the same +result most of the time. + +Using a~notification client (program that uses LB client +API to handle notifications) the user registers with a~\LB\ server +to receive notifications. +She must specify conditions under which the +notification is sent. These conditions are a~subset of the conditions +available for synchronous queries (Sect.~\ref{arch-queries}). +Currently due to implementation constraints, one +or more jobid's are required among the conditions and only +a~single occurrence of a~specific attribute is allowed. The registration is +sent to the \LB\ server in the same way as synchronous queries, +and stored there. +In response, the server generates a~unique notification ID which is used +by the user to refer to this notification further on. +The user may +change conditions which trigger notification, prolong validity of +the registration, remove the registration from LB server, +or even change the destination of notifications, \ie\ the address where +a~client listens for notifications. + +The registration is soft-state; it exists only for limited amount of time. The +validity is returned by LB server together with notification ID. + +While the registration is valid, +the user may stop the notification client and launch another, even +on a~different machine. +Notifications generated during the time when there was no client listening +for them are kept by the notification interlogger. +Once a~new listening address is announced to the +server, the pending notifications are delivered. + diff --git a/org.glite.lb.doc/src/cmdln_interface.tex b/org.glite.lb.doc/src/cmdln_interface.tex new file mode 100644 index 0000000..ddf2a55 --- /dev/null +++ b/org.glite.lb.doc/src/cmdln_interface.tex @@ -0,0 +1,54 @@ +Besides the API's \LB\ offers its users a simple command-line interface for +logging events. The command glite-lb-logevent is used for this purpose. However, it +is intended for internal WMS debugging tests in the first place and should not +be used for common event logging because of possibility of confusing \LB\ +server job state automaton. + +The only legal user usage is for logging \verb'UserTag' and \verb'ChangeACL' events. The following description is therefore concentrating only on options dealing with these two events. + +Command usage is: + +\begin{verbatim} + glite-lb-logevent [-h] [-p] [-c seq_code] \ + -j -s Application -e [key=value ...] +\end{verbatim} + +where + +\begin{tabularx}{\textwidth}{lX} +\texttt{ -h -{}-help} & this help message\\ +\texttt{ -p -{}-priority} & send a priority event\\ +\texttt{ -c -{}-sequence} & event sequence code\\ +\texttt{ -j -{}-jobid} & JobId\\ +\texttt{ -e -{}-event} & select event type (see -e help)\\ +\end{tabularx} + +\medskip + +Each event specified after \verb'-e' option has different sub-options enabling to set event specific values. + +Sub-options usable with \verb'UserTag' event are: + + +\begin{tabularx}{\textwidth}{lX} +\texttt{ -{}-name} & tag name\\ +\texttt{ -{}-value} & tag value\\ +\end{tabularx} + +\medskip + +Sub-options usable with \verb'ChangeACL' event are: + +\begin{tabularx}{\textwidth}{lX} +\texttt{ -{}-operation} & operation requested to perform with ACL (add, remove)\\ +\texttt{ -{}-permission} & ACL permission to change (currently only READ)\\ +\texttt{ -{}-permission\_type} & type of permission requested (0 = 'allow', 1 = 'deny')\\ +\texttt{ -{}-user\_id} & DN or VOMS parameter (in format VO:group)\\ +\texttt{ -{}-user\_id\_type} & type of information given in \verb'user_id' (DN or VOMS)\\ +\end{tabularx} + +\bigskip + +To be able to use this command several environmental variables must be set properly. User must specify where the event should be sent. This is address and port of glite-lb-logd daemon. It is done using environmental variable \verb'EDG_WL_LOG_DESTINATION' in a form \verb'address:port'. + +Because user is allowed to change ACL or add user tags only for her jobs, paths to valid X509 user credentials has to be set to authorise her. This is done using two environmental variables \verb'EDG_WL_X509_KEY' and \verb'EDG_WL_X509_CERT' in a form \verb'path_to_cred'. diff --git a/org.glite.lb.doc/src/consumer_api.tex b/org.glite.lb.doc/src/consumer_api.tex new file mode 100644 index 0000000..e1d7034 --- /dev/null +++ b/org.glite.lb.doc/src/consumer_api.tex @@ -0,0 +1,801 @@ +\def\partitle#1{\par{\textbf{#1}}\par} + +\label{ConsOview} +This section describes the aspects of principal use of the \LB\ consumer API. +It begins with the simplest examples how to query the bookkeeping +service, continues with various selection criteria and their combinations, and +through queries on user tags and timestamps it concludes with the discussion of +application specific queries. + +The document is intended for users interested in the \LB\ +consumer API or those interested in better understanding of the \LB\ service +capabilities. + +In the presented examples only the C \LB\ API (Sect.~\ref{query-C}) is considered. +The C++ API (Sect.~\ref{query-CPP}) covers the same functionality. + +\subsubsection{Returned results} + +\LB\ server returns errors which are classified as hard and soft errors. +The main difference between these categories is that in the case of soft +errors results may still be returned. +The authentication errors belong to +``soft error'' sort. Hard errors are typically all unrecoverable errors like ENOMEM. + +When the item count returned by \LB\ server exceeds the defined limits, the E2BIG error occur. +There are two limits\,---\,the server and the user limit. The user defined limit may be set in +the context at the client side in the following way: +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + + edg_wll_InitContext(&ctx); + edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_JOBS_LIMIT, 10); + edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_EVENTS_LIMIT, 20); + edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_RESULTS, 30); + ... + edg_wll_FreeContext(ctx); +\end{verbatim} +This code sets the user query limits to the given maximal count of items. + +The E2BIG error may fall into both categories depending on the setting of +another context parameter, EDG\_WLL\_PARAM\_QUERY\_RESULTS. +It may take the following values: + +%The E2BIG error can be classified as hard or soft error too because this error can be affected +%by one more parameter which can make this error hard or soft. This parameter can be set like this:\\ +%\texttt{edg\_wll\_SetParam(ctx, EDG\_WLL\_PARAM\_QUERY\_RESULTS, EDG\_WLL\_QUERYRES\_ALL);} +%and possible values follows: +\begin{itemize} + \item{EDG\_WLL\_QUERYRES\_NONE}\,---\,No results are returned. + In this case an E2BIG error acts like a hard error. + \item{EDG\_WLL\_QUERYRES\_LIMITED}\,---\,A result contains at most ``limit'' item count. + In this case an E2BIG error acts like a soft error. + \item{EDG\_WLL\_QUERYRES\_ALL}\,---\,All results are returned and limits has no effect. + This option is available only in special cases such as ``user jobs query'' and + the ``job status query''. Otherwise the EINVAL error is returned. +\end{itemize} +Default value is EDG\_WLL\_QUERYRES\_NONE. + + +\subsubsection{Job queries} + +\partitle{Job status} +\label{JS} + +The simplest case corresponds to the situation when an exact job ID +is known and the only information requested is the job status. The job ID +format is described in~\cite{lbapi}. +The following example shows +all the relevant structures and API calls to retrieve status information +about a job with the ID\\ +\texttt{https://lhun.ics.muni.cz:9000/OirOgeWh\_F9sfMZjnIPYhQ}. + +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_JobStat *statesOut = NULL; + edg_wll_QueryRec jc[2]; + ... + edg_wll_InitContext(&ctx); + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_JOBID; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + if ( edg_wlc_JobIdParse( + "https://lhun.ics.muni.cz:9000/OirOgeWh_F9sfMZjnIPYhQ", + &jc[0].value.j) ) + { + edg_wll_FreeContext(ctx); + exit(1); + } + jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + if (edg_wll_QueryJobs(ctx, jc, 0, NULL, &statesOut)) { + char *err_text,*err_desc; + + edg_wll_Error(ctx,&err_text,&err_desc); + fprintf(stderr,"QueryJobs: %s (%s)\n",err_text,err_desc); + free(err_text); + free(err_desc); + } + else { + ... /* process the returned data */ + edg_wll_FreeStatus(statesOut); + free(statesOut); + } + edg_wlc_JobIdFree(jc[0].value.j); + edg_wll_FreeContext(ctx); +\end{verbatim} + +The first function call in this example initializes the \LB\ context\,---\,variable +\texttt{ctx}\,---\,which is necessary for later use. The most important part +of this code fragment is the \texttt{jc} variable setting. +Variable \texttt{jc} is a list of conditions terminated with the +\texttt{EDG\_WLL\_QUERY\_ATTR\_UNDEF} item. +In this example it contains the only data item\,---\,the job ID +(in its parsed form). + +If \texttt{edg\_wll\_QueryJobs()} is successful, returned results are available +in the \texttt{statesOut} variable. This variable contains an array of job states\,---\, +in this example state of a given job. + +The code also shows a~complete handling of returned errors as well as memory +management\,---\,deallocation of data that are not needed anymore. +\emph{For the sake of simplicity such code is not included in the examples +in the rest of this document.} + +\partitle{All user's jobs} +\label{JQ-auj} + +The simple query example is a request for all user's jobs. Another +condition type, \\ +\texttt{EDG\_WLL\_QUERY\_ATTR\_OWNER}, is used in this case, with the +value field filled with a user name. You can found this example in client module, file \texttt{job\_status.c}. + +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc[2]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].value.c = NULL; + jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); + ... +\end{verbatim} + +The value of the \texttt{attr} field which specifies job owner +could be set to \texttt{NULL} meaning the authenticated user. +Obtained results may differ according to the security level, e.g. with strong security +context only information about jobs of the specified user are returned +(in general info about all jobs a user is authorized to retrieve should be +returned). + +The query may return either a~list of job ID's or a~list of job states or both, +depending on the parameters \texttt{jobsOut} and \texttt{statesOut}. +If either is NULL the corresponding list is not retrieved. + +\par + +The following examples demonstrates how \texttt{edg\_wll\_QueryJobs()} combines +the given conditions in a logical conjugation. + +\partitle{Running jobs} +\label{JQ-rj} + +If all (user's) running jobs are to be retrieved the following code can +be used. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc[3]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].value.c = NULL; + jc[1].attr = EDG_WLL_QUERY_ATTR_STATUS; + jc[1].op = EDG_WLL_QUERY_OP_EQUAL; + jc[1].value.i = EDG_WLL_JOB_RUNNING; + jc[2].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); + ... +\end{verbatim} + +This example combines previous example with a new criteria. There are used two different attributes + - \texttt{EDG\_WLL\_QUERY\_ATTR\_OWNER} and \texttt{EDG\_WLL\_QUERY\_ATTR\_STATE}. +\texttt{edg\_wll\_QueryJobs()} connects them in the logical conjunction. +Examples using logical conjunction and logical disjunction are shown in the Sect.~\ref{JQ-AO}. + +\partitle{Jobs running at a given CE} +The following example gives description of all (user's) jobs running at CE XYZ. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc[4]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].value.c = NULL; + jc[1].attr = EDG_WLL_QUERY_ATTR_STATUS; + jc[1].op = EDG_WLL_QUERY_OP_EQUAL; + jc[1].value.i = EDG_WLL_JOB_RUNNING; + jc[2].attr = EDG_WLL_QUERY_ATTR_DESTINATION; + jc[2].op = EDG_WLL_QUERY_OP_EQUAL; + jc[2].value.c = "XYZ"; + jc[3].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); + ... +\end{verbatim} + +In a case the job is not running the destination (attribute \texttt{EDG\_WLL\_QUERY\_ATTR\_DESTINATION}) +saves a CE name the job will be routed to. If location is needed use the \texttt{EDG\_WLL\_QUERY\_ATTR\_LOCATION} attribute. + + +\partitle{The WITHIN operator} +The \texttt{EDG\_WLL\_QUERY\_OP\_WITHIN} operator can be used in any condition with numeric values. +The following example shows a query on all user's jobs that have returned +an exit code from 2 to 7. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc[4]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].value.c = NULL; + jc[1].attr = EDG_WLL_QUERY_ATTR_STATUS; + jc[1].op = EDG_WLL_QUERY_OP_EQUAL; + jc[1].value.i = EDG_WLL_JOB_DONE; + jc[2].attr = EDG_WLL_QUERY_ATTR_EXITCODE; + jc[2].op = EDG_WLL_QUERY_OP_WITHIN; + jc[2].value.i = 2; + jc[2].value2.i = 7; + jc[3].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); + ... +\end{verbatim} + +The second attribute type (``state'') selects jobs in state ``done'' because it doesn't +make sense to query running jobs on their return code. +The last attribute (``exit code'') uses the WITHIN operator. The WITHIN operator accepts an +interval\,---\,the lower bound of the interval is stored in the \texttt{value} union and the +upper bound is stored in the \texttt{value2} union. + +\partitle{Using AND, OR in query clauses} +\label{JQ-AO} +In many cases the basic logic using only conjunctions is not sufficient. +For example, if you need all your jobs running at the destination XXX or at +the destination YYY, the only way to do this with the \texttt{edg\_wll\_QueryJobs()} +call is to call it twice. The \texttt{edg\_wll\_QueryJobsExt()} call allows to make +such a~query in a single step. +The function accepts an array of condition lists. Conditions within a~single list are +OR-ed and the lists themselves are AND-ed. +%It is allowed to use only identical attributes in every standalone condition list. +%This is forced by an ``indexing'' definition, look at Sect.~\ref{ConsIndx} +%for further details. + +The next query example describes how to get all user's jobs running at +CE XXX or YYY. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec *jc[4]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0] = (edg_wll_QueryRec *) malloc(2*sizeof(edg_wll_QueryRec)); + jc[0][0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc[0][0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0][0].value.c = NULL; + jc[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + + jc[1] = (edg_wll_QueryRec *) malloc(2*sizeof(edg_wll_QueryRec)); + jc[1][0].attr = EDG_WLL_QUERY_ATTR_STATUS; + jc[1][0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[1][0].value.i = EDG_WLL_JOB_RUNNING; + jc[1][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + + jc[2] = (edg_wll_QueryRec *) malloc(3*sizeof(edg_wll_QueryRec)); + jc[2][0].attr = EDG_WLL_QUERY_ATTR_DESTINATION; + jc[2][0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[2][0].value.c = "XXX"; + jc[2][1].attr = EDG_WLL_QUERY_ATTR_DESTINATION; + jc[2][1].op = EDG_WLL_QUERY_OP_EQUAL; + jc[2][1].value.c = "YYY"; + jc[2][2].attr = EDG_WLL_QUERY_ATTR_UNDEF; + + jc[3] = NULL; + edg_wll_QueryJobsExt(ctx, (const edg_wll_QueryRec **)jc, 0, &jobsOut, &statesOut); + free(jc[0]); free(jc[1]); free(jc[2]); + ... +\end{verbatim} + +As clearly seen, there are three lists supplied to +\texttt{edg\_wll\_QueryJobsExt()}. The first list specifies the owner of the +job, the second list provides the required status (\texttt{Running}) and +the last list specifies the two destinations. +The list of lists is terminated with \texttt{NULL}. +This query equals to the formula +\begin{quote} +\texttt{(user=NULL) and (state=Running) and (dest='XXX' or dest='YYY')}. +\end{quote} + +\partitle{User tags} +\label{JQ_ut} +User tags can be used for marking (labelling) jobs. A user tag is +a pair of user defined \texttt{name} and \texttt{value}. + +\label{JQ_RedJobs} +For example, if all jobs marked with the user tag \texttt{color} and with its +value \texttt{red} should be retrieved, the following code can be used: +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc[2]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].attr_id.tag = "color"; + jc[0].value.c = "red"; + jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); + ... +\end{verbatim} +The condition \texttt{EDG\_WLL\_QUERY\_ATTR\_USER\_TAG} in \texttt{jc[0]} +specifies that a user tag is set. Tag name is given in +\texttt{jc[0].attr\_id.tag} and the appropriate tag +value is given in \texttt{jc[0].value}. + + +Another example\,---\,jobs marked with red or green color: +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc[1][3]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0][0].attr = EDG_WLL_QUERY_ATTR_USERTAG; + jc[0][0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0][0].attr_id.tag = "color"; + jc[0][0].value.c = "red"; + jc[0][1].attr = EDG_WLL_QUERY_ATTR_USERTAG; + jc[0][1].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0][1].attr_id.tag = "color"; + jc[0][1].value.c = "green"; + jc[0][2].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryJobsExt(ctx, (const edg_wll_QueryRec **)jc, 0, &jobsOut, &statesOut); + ... +\end{verbatim} + +And the last one (with two user tags)\,---\,jobs marked with red color and using the 'xyz' algorithm: +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc[2]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].attr_id.tag = "color"; + jc[0].value.c = "red"; + jc[1].attr = EDG_WLL_QUERY_ATTR_USERTAG; + jc[1].op = EDG_WLL_QUERY_OP_EQUAL; + jc[1].attr_id.tag = "algorithm"; + jc[1].value.c = "xyz"; + jc[2].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); + ... +\end{verbatim} + +Due to performance reasons +it is not possible to make query with two tags of different type in one +or-clause. +% fakt nevim, co tahle veta znamena. ljocha +%That means that user tags are composed of two variable components +%and user tag indices depend on tag names. + +\partitle{Time attributes} + +%A time interval in which a particular state appears is attached to every job +%state. +Besides details on the job's current state the job status also carries +information when the job entered each of the distinguished states +(if ever). +This information is also queriable. + + +The following example shows how to get all jobs that were submitted in +the last 24 hours. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc[2]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_TIME; + jc[0].op = EDG_WLL_QUERY_OP_GREATER; + jc[0].attr_id.state = EDG_WLL_JOB_SUBMITTED; + jc[0].value.t.tv_sec = time_now - (24 * 60 * 60); + jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); + ... +\end{verbatim} + +In this case, a record representing the necessary condition is quite +different. The \LB\ API allows to ask for jobs with a particular status at a +given time. When \LB\ server gets \texttt{EDG\_WLL\_QUERY\_ATTR\_TIME} +as a job condition, it checks \texttt{jc[0].attr\_id.state} for job state. +Note that \texttt{timenow} is a variable which contains current time in +seconds. + +It is easy to modify previous example and add another time boundary. It is then +possible to ask for all jobs with a specified state within a particular time +interval. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc[3]; + edg_wll_JobStat *statesOut = NULL; + edg_wlc_JobId *jobsOut = NULL; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].value.c = NULL; + jc[1].attr = EDG_WLL_QUERY_ATTR_TIME; + jc[1].op = EDG_WLL_QUERY_OP_WITHIN; + jc[1].attr_id.state = EDG_WLL_JOB_SUBMITTED; + jc[1].value.t.tv_sec = time_now - (48 * 60 * 60); + jc[1].value2.t.tv_sec = time_now - (24 * 60 * 60); + jc[2].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); + ... +\end{verbatim} + + +\subsubsection{Event queries and application specific queries} +\label{ASQ} +Event queries and job queries are similar. +Obviously, the return type is different\Dash the \LB\ raw events. +There is one more input parameter +representing specific conditions on events (possibly empty) +in addition to conditions on jobs. +Some examples showing event queries +are considered in the following paragraph. + + +\partitle{All jobs marked as red} +\label{ASQ_allred} +This example shows how to select all user's jobs which were (at some time) +marked with the value red of user tag color. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_Event *eventsOut; + edg_wll_QueryRec jc[2]; + edg_wll_QueryRec ec[2]; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].value.c = NULL; + jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + ec[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; + ec[0].op = EDG_WLL_QUERY_OP_EQUAL; + ec[0].attr_id.tag = "color"; + ec[0].value.c = "red"; + ec[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryEvents(ctx, jc, ec, &eventsOut); + ... +\end{verbatim} + +This example uses \texttt{edg\_wll\_QueryEvents()} call. Two condition lists are +given to \texttt{edg\_wll\_QueryEvents()} call. One represents job conditions and +the second represents event conditions. These two lists are joined together with +logical and (both condition lists have to be satisfied). This is necessary as +events represent a state of a job in a particular moment and this changes in time. + +The \texttt{edg\_wll\_QueryEvents()} returns matched events and save them in the +\texttt{eventsOut} variable. Required job IDs are stored in the edg\_wll\_Event +structure. + +Due to the need of ``historic'' information it's impossible to address +this type of query with calling the function \texttt{edg\_wll\_QueryJobs()}, raw events has to +be retrieved instead. The example above retrieves all events marking +any user's job as ``red''. By gathering the jobid's from those events one +gets a~list of such jobs, not regarding whether their ``color'' was +changed afterwards or not (unlike straightforward \texttt{edg\_wll\_QueryJobs()} +which considers the ``current color'' only). The same applies on all +subsequent examples using the user's marking. + +\partitle{All red jobs at some time marked as green} +The next example shows how to select all jobs which are just now marked with +user tag color red, but at some time in the past they were marked as green. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_Event *eventsOut; + edg_wll_QueryRec jc[2]; + edg_wll_QueryRec ec[2]; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].attr_id.tag = "color"; + jc[0].value.c = "red"; + jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + ec[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; + ec[0].op = EDG_WLL_QUERY_OP_EQUAL; + ec[0].attr_id.tag = "color"; + ec[0].value.c = "green"; + ec[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryEvents(ctx, jc, ec, &eventsOut); + ... +\end{verbatim} + +Jobs conditions selects all jobs with tag ``color = red'' (See example in paragraph +\ref{JQ_RedJobs}). Event conditions selects all jobs which were sometimes marked +as green\,---\,this is described in previous example \ref{ASQ_allred}. + +\partitle{All resubmitted jobs} +The next example shows how to get all (your) resubmitted jobs. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_Event *eventsOut; + edg_wll_QueryRec jc[2]; + edg_wll_QueryRec ec[2]; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].value.c = NULL; + jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + ec[0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; + ec[0].op = EDG_WLL_QUERY_OP_EQUAL; + ec[0].value.i = EDG_WLL_EVENT_RESUBMISSION; + ec[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryEvents(ctx, jc, ec, &eventsOut); + ... +\end{verbatim} + +\partitle{Jobs resubmitted in the last two hours} +The next example shows how to get all user's jobs which were resubmitted in the last +2 hours. +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_Event *eventsOut; + edg_wll_QueryRec jc[2]; + edg_wll_QueryRec ec[3]; + ... + jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0].value.c = NULL; + jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + ec[0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; + ec[0].op = EDG_WLL_QUERY_OP_EQUAL; + ec[0].value.i = EDG_WLL_EVENT_RESUBMISSION; + ec[1].attr = EDG_WLL_QUERY_ATTR_TIME; + ec[1].op = EDG_WLL_QUERY_OP_GREATER; + ec[1].value.t.tv_sec = time_now - (2 * 60 * 60); + ec[2].attr = EDG_WLL_QUERY_ATTR_UNDEF; + edg_wll_QueryEvents(ctx, jc, ec, &eventsOut); + ... +\end{verbatim} + + +\partitle{Complex query} +The last example illustrates the API usage on + a~meaningful but rather complex query ``which of my red jobs are heading +to a~destination that already encountered problems executing red jobs''. + +First we retrieve the information of red jobs failures. +This cannot be accomplished with a~job query because the job may +get resubmitted automatically to another computing element and terminate +successfully. Therefore we need to search for the ``historic'' +information\,---\,`Done' events with their minor status +equal to `Failed'. + +\begin{verbatim} + #include + ... + edg_wll_Context ctx; + edg_wll_QueryRec jc1[3],ec1[3]; + edg_wll_Event *failures; + + jc1[0].attr = EDG_WLL_QUERY_ATTR_OWNER; + jc1[0].op = EDG_WLL_QUERY_OP_EQUAL; + jc1[0].value.c = NULL; + jc1[1].attr = EDG_WLL_QUERY_ATTR_USERTAG; + jc1[1].attr_id.tag = "color"; + jc1[1].op = EDG_WLL_QUERY_OP_EQUAL; + jc1[1].value.c = "red"; + jc1[2].attr = EDG_WLL_QUERY_ATTR_DONECODE; + jc1[2].op = EDG_WLL_QUERY_OP_EQUAL; + jc1[2].value.i = EDG_WLL_DONE_FAILED; + jc1[3].attr = EDG_WLL_QUERY_ATTR_UNDEF; + + ec1[0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; + ec1[0].op = EDG_WLL_QUERY_OP_EQUAL; + ec1[0].value.i = EDG_WLL_EVENT_DONE; + ec1[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + + edg_wll_QueryEvents(ctx,jc1,ec1,&failures); + ... +\end{verbatim} + +Unfortunately, the `Done' event itself does not contain a~complete +identification of the queue where the job was running. +This information is contained in the `Match' events. +Moreover, there may be more than one such events in the job's life cycle +as the job may have been resubmitted. +Therefore we loop over the job ID's extracted from the events returned +in the previous step, and retrieve their `Match' and `Done' events. +The \LB\ API returns sorted results therefore we can assume that `Done' +events immediately following a~`Match' belong to the same attempt to submit +the job\footnote{In reality events may get lost or delayed. +Therefore strict checking the Match-Done pairing would require analysis +of the hierarchical event sequence codes. +However, this falls beyond the scope of this document.}. + +Due to job resubmissions again +a~job may be represented several times in \verb'failures'. +Because of obvious performance reasons +it is desirable to avoid repeated queries on the same job. +On the other hand, we may rely on \LB\ queries returning data grouped +according to jobs. Therefore checking duplicities is easy. + +\begin{verbatim} + ... + edg_wll_QueryRec *jc2[2],*ec2[2]; + char *last_job = strdup(""),*this_job,**failed_sites = NULL; + edg_wll_Event *match_done; + char **failed_sites; + int n, i, j; + ... + jc2[0][0].attr = EDG_WLL_QUERY_ATTR_JOBID; + jc2[0][0].op = EDG_WLL_QUERY_OP_EQUAL; + jc2[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + jc2[1] = NULL; + ec2[0][0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; + ec2[0][0].op = EDG_WLL_QUERY_OP_EQUAL; + ec2[0][0].value.i = EDG_WLL_EVENT_MATCH; + ec2[0][1].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; + ec2[0][1].op = EDG_WLL_QUERY_OP_EQUAL; + ec2[0][1].value.i = EDG_WLL_EVENT_DONE; + ec2[0][2].attr = EDG_WLL_QUERY_ATTR_UNDEF; + ec2[1] = NULL; + + n = 0; + for (i=0; failures[i].type; i++) { + this_job = edg_wlc_JobIdUnparse(failures[i].any.jobId); + if (strcmp(last_job,this_job)) { + free(last_job); + last_job = this_job; + jc2[0][0].value.j = failures[i].any.jobId; + edg_wll_QueryEventsExt(ctx,(const edg_wll_QueryRec **)jc2, + (const edg_wll_QueryRec **)ec2,&match_done); + for (j=0; match_done[j].type; j++) { + if (match_done[j].type == EDG_WLL_EVENT_MATCH && + match_done[j+1].type == EDG_WLL_EVENT_DONE && + match_done[j+1].done.status_code == EDG_WLL_DONE_FAILED) + { + failed_sites = realloc(failed_sites,(n+1)*sizeof *failed_sites); + failed_sites[n++] = strdup(match_done[j].match.dest_id); + } + edg_wll_FreeEvent(&match_done[j]); + } + } + else free(this_job); + edg_wll_FreeEvent(&failures[i]); + } + free(failures); + ... +\end{verbatim} + +The API would allow to perform a~single query instead of the loop, +putting all the job ID's into a~list of OR-ed conditions. +However, as the query conditions are directly converted to a~SQL statement +we don't recommend more than approx. 10--20 atomic conditions per query. +This number can be easily exceeded in the case of this example. +On the other hand, queries containing a~``jobid equals'' clause are very +effective and the overhead of repeating them is not very high. + +Finally we can query the server for the jobs heading to one of the failing +sites. +A~job's destination is known starting from the `Ready' state, +and the query makes sense also in the `Scheduled' state (\ie\ the job reached +the LRMS queue but has not been started yet). + +\begin{verbatim} + ... + edg_wll_QueryRec *jc3[3]; + edg_wlc_JobId *unlucky_jobs; + ... /* remove duplicates from failed_sites */ + + for (i=0; i + ... + edg_wll_Context ctx; + edg_wll_Event *eventsOut; + edg_wll_JobStat *statesOut; + edg_wlc_JobId *jobsOut; + edg_wll_QueryRec **jc; + edg_wll_QueryRec **ec; + ... + jc[0][0].attr = EDG_WLL_QUERY_ATTR_USERTAG; + jc[0][0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[0][0].attr_id.tag = "color"; + jc[0][0].value.c = "red"; + jc[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + jc[2][0].attr = EDG_WLL_QUERY_ATTR_STATUS; + jc[2][0].op = EDG_WLL_QUERY_OP_EQUAL; + jc[2][0].value.i = EDG_WLL_JOB_SUBMITTED; + jc[2][1].attr = EDG_WLL_QUERY_ATTR_STATUS; + jc[2][1].op = EDG_WLL_QUERY_OP_EQUAL; + jc[2][1].value.i = EDG_WLL_JOB_WAITING; + jc[2][2].attr = EDG_WLL_QUERY_ATTR_STATUS; + jc[2][2].op = EDG_WLL_QUERY_OP_EQUAL; + jc[2][2].value.i = EDG_WLL_JOB_READY; + jc[2][3].attr = EDG_WLL_QUERY_ATTR_STATUS; + jc[2][3].op = EDG_WLL_QUERY_OP_EQUAL; + jc[2][3].value.i = EDG_WLL_JOB_SCHEDULED; + jc[2][4].attr = EDG_WLL_QUERY_ATTR_UNDEF; + jc[3] = NULL; + edg_wll_QueryJobsExt(ctx, (const edg_wll_QueryRec **)jc, 0, &jobsOut, &statesOut); + + ec[0][0].attr = EDG_WLL_QUERY_ATTR_USERTAG; + ec[0][0].op = EDG_WLL_QUERY_OP_EQUAL; + ec[0][0].attr_id.tag = "color"; + ec[0][0].value.c = "red"; + ec[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + ec[1][0].attr = EDG_WLL_QUERY_ATTR_USERTAG; + ec[1][0].op = EDG_WLL_QUERY_OP_EQUAL; + ec[1][0].attr_id.tag = "color"; + ec[1][0].value.c = "red"; + ec[1][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + ec[2][0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; + ec[2][0].op = EDG_WLL_QUERY_OP_EQUAL; + ec[2][0].value.i = EDG_WLL_EVENT_DONE; + ec[2][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; + ec[3] = NULL; + edg_wll_QueryEventsExt(ctx, (const edg_wll_QueryRec **)jc, (const edg_wll_QueryRec **)ec, &eventsOut); + ... +\end{verbatim} +\fi diff --git a/org.glite.lb.doc/src/copyright.tex b/org.glite.lb.doc/src/copyright.tex new file mode 100644 index 0000000..3c17886 --- /dev/null +++ b/org.glite.lb.doc/src/copyright.tex @@ -0,0 +1,24 @@ +% Taken from: +% https://twiki.cern.ch/twiki/bin/view/EGEE/EGEEgLiteSoftwareLicense +% +\vfill{} + +{\bf +Copyright \copyright Members of the EGEE Collaboration. 2004. See +\href{http://www.eu-egee.org/partners/}{http://www.eu-egee.org/partners/} for +details on the copyright holders. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + +\begin{center} +\href{http://www.apache.org/licenses/LICENSE-2.0}{http://www.apache.org/licenses/LICENSE-2.0} +\end{center} + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +} + diff --git a/org.glite.lb.doc/src/log_usertag.tex b/org.glite.lb.doc/src/log_usertag.tex new file mode 100644 index 0000000..629b34e --- /dev/null +++ b/org.glite.lb.doc/src/log_usertag.tex @@ -0,0 +1,54 @@ + + +User tag is an arbitrary ``name=value'' pair with which the user can +assign additional information to a job. Further on, LB can be queried +based also on values of user tags. +% (see Sect.~\ref{tag-query}). + +In order to add user tag for a job a special event \verb+UserTag+ is used. This +event can be logged by the job owner using the glite-lb-logevent command (see also +sec.\ref{cmdln_interface}). Here we suppose the command is used from user's running + application because a correct setting of environment variables needed by +the command is assured. + +General template for adding user tag is as follows: + +\begin{verbatim} +glite-lb-logevent -s Application -e UserTag \ + -j \ + -c \ + --name \ + --value +\end{verbatim} + +where + +\begin{tabularx}{\textwidth}{lX} +\verb'' & specifies the job to change \\ +\verb'' & specifies the sequence code returned by previous call + of verb 'glite-lb-logevent'\\ +\verb'' & specifies the name of user tag\\ +\verb'' & specifies the value of user tag\\ +\end{tabularx} + +The user application is always executed from within a JobWrapper script (part of Workload Management System \cite{WMS}). The wrapper sets the appropriate \verb'JobId' in the environment variable \verb'GLITE_WMS_JOBID'. The user should pass this value to the -j option of glite-lb-logevent. Similarly, the wrapper sets an initial value of the event sequence code in the environment variable \verb'GLITE_WMS_SEQUENCE_CODE'. + +If the user application calls glite-lb-logevent just once, it is sufficient to pass this value to the -c option. However, if there are more subsequent calls, the user is responsible for capturing an updated sequence code from the stdout of glite-lb-logevent and using it in subsequent calls. The \LB\ design requires the sequence codes in order to be able to sort events correctly while not relying on strictly synchronized clocks. + +The example bellow is a job consisting of 100 phases. A user tag phase is used to log the phase currently being executed. Subsequently, the user may monitor execution of the job phases as a part of the job status returned by \LB. + +\begin{verbatim} + #!/bin/sh + + for p in `seq 1 100`; do + + # log the UserTag event + GLITE_WMS_SEQUENCE_CODE=`glite-lb-logevent -s Application + -e UserTag + -j $GLITE_WMS_JOBID -c $GLITE_WMS_SEQUENCE_CODE + --name=phase --value=$p` + + # do the actual computation here + done +\end{verbatim} + diff --git a/org.glite.lb.doc/src/logging-arch-notif.pdf b/org.glite.lb.doc/src/logging-arch-notif.pdf new file mode 100644 index 0000000000000000000000000000000000000000..09a39200ae0d94b69ed3853b7251c414195b432c GIT binary patch literal 67535 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

YIN5& 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 + + VOCE/VOCE + + + + /O=CESNET/O=Masaryk University/CN=Daniel Kouril + + + +\end{verbatim} + +This ACL allows access to all people in the VOMS group /VOCE in virtual +organization VOCE, but denies access to user Daniel Kouril (even if he was a +member of the /VOCE group). + +The job owner herself is not specified in the ACL as she is always allowed to +access the information regardless the content of the job ACL. + +An ACL for a job can be changed using the \verb'glite-lb-logevent' command-line +program, see section~\ref{change_acl}. + +%provided in the example subdirectory. In order to use change\_acl, the \LB\ +%daemons locallogger and interlogger must be running. The usage of the command +%is as follows: +% +%\LB\ server configuration +%In order to support the VOMS groups in the ACL's, +%glite_lb_bkserverd must be able to verify client's VOMS proxy certificate using +%a trusted VOMS service certificate stored on a local disk. Default directory +%with trusted VOMS certificates is /etc/grid-security/vomsdir, another location +%can be specified using by either the -V option to glite_lb_bkserverd or setting +%the VOMS_CERT_DIR environment variable. + -- 1.8.2.3