# # Copyright (c) Members of the EGEE Collaboration. 2004. # See http://eu-egee.org/partners/ for details on the copyright holders. # For license conditions see the license file or http://eu-egee.org/license.html # # README file for the Config Service module # # Authors: Paolo Badino # Version info: $Id: README,v 1.18 2006/03/09 11:39:08 badino Exp $ # Release: $Name: glite-data-config-service_R_1_2_7 $ # # GLite Config Service Module ReadMe ================================== Module ------------- org.glite.data.config-service Library Names ------------- libglite_data_configserviceconfiguration.so libglite_data_config.so Application Name ---------------- glite-data-config-service glite-data-config-generator Introduction -------------- This package provides a library (glite_data_config) for configuring an application following the Component Configuration pattern. It also provides an application (glite-data-config-service) that could be used to start and stop daemons: the composition of service is done at run-time reading a configuration file GLite Data Config Service ------------------------- Glite Data Config Service is an application that could be useful to create any Glite C++ daemons/service. It is an implementation of the ComponentConfigurator pattern, that suggest to move away from the traditional approach, where each library is coupled statically with a process, and to introduce an infrastructure where all the libraries are loaded and configured dynamically into the process, by implementing a common interface. The advantages of such approach are mainly: - All the common administrative tasks (such as configuring, initializing and controlling components and processes) could be performed in a component-indipendent way - Developers should not care at development time of most effective way to collocate components into services - Developers should not rewrite the code to handle the control signals for each service - Changes on the configuration schema or backend will be hidden by this infrastructure and will not affect the rest of the system To provide such infrastructure, the GLite Data Config Service module exports a library (libglite_data_config_serviceconfigurator.so), that define the ComponentConfiguration common interface and the ServiceConfigurator class, used to get the configuration parameter and submit them to the right component. The same module also provide an application (glite_data_config_server) that could be used as a daemon launcher. To plug a component into that architecture, a developer has just to code a class that inherits from the ComponentConfiguration class, implementing all the declared abstract methods, and export two C methods to allow the ServiceConfigurator to get a pointer to an instance of that class. The ComponentConfiguration pattern is not related just to services, but could also be used to configure the libraries of a console application. At that purpose, the GLite Data Config Service module export a library (libglite_data_config.so) that could be used by C/C++ application to initialize the ServiceConfigurator. The configuration will then be executed exactly in the same way as using the glite_data_config_server daemon launcher, but the developer has the flexibility to manage the control of the application * Configuration Namespaces The flexibility to define the composition of a service just at integration-time requires that the same components could be installated in different services with different configuration parameters. That rules applies also to the scenario where two copies of the same services should run on the same host with differenet configuration values. To support that, the GLite Data Config Service introduce the concept of Configuration Namespace: the fact of using different names for such services allow the user to have completed distincted repositories where to store the configuration parameters. Moreover, in case of console applications, you may even think to get the value of that configuration namespace dynamically (i.e. based on some policies or user input), allowing the application to support a predefined set of behaviours or giving the user a certains customization ability, without affecting the default one. In case of services, the configuration namespace could be seen as the service application name. Starting form version 1.2.0, glite-data-config-service supports the concept of configuration directories and configuration instance names: the idea is that a set of applications, that provides a similar functionality but that requires different configuration, could be logically grouped into directories and then and unique instance name is used to identify each application. The purpose of this feature is to improve the way the configuration is stored and managed, by providing a mapping of this logical division a into phisical one. The configuration namespace in case configuration directories are use is generated depending on the option used to pass the configuration directory: if it's considered as a prefix, glite-data-config-service will concatenate the directory and the instance name following the rule -; otherwise it will be just The usage of configuration directories is optional and has been added to help integrators and system administrators in the organization of the gLite configuration files. * GLite Data Config Service - Configuration File The current implementation of the GLite Data ServiceConfiguration requires that the configuration values are stored on a file named .properties.xml where is the configuration namespace, (usually the name of the service). The structure of that XML files should be: ------------------------------------------------------------------------------- service: Root Node. It requires the "name" attribute specifying the service name | @-name: [mandatory] attribute containing the service name | |-components: Container Node for all the components | |-component: Component Root Node | @-name: [mandatory] attribute containing the component name | |-lib: Contains a text value with the name of the Shared library that should | be used to load the component. This node is mandatory for all the | components that should be loaded dynamically | |-dependencies: Container Node for the dependencies. The child nodes should | | be used to specify non-glite component dependencies, since some | | platforms don't load those libraries automaticallly when a shared | | library is loaded. All the child nodes should be: | | | |-lib: Contains a text value with the name of the library that shoudl be | loaded before the component library is loaded | |-init: Container node for the Initailization parameters. If the component | | has no initialization parameters, thise node could be skipped. | | The child nodes shoudl use the following syntax | | | |-param: Container Node for the Parameter. It has the mandatory attribute | | name and the mandatory child value | | | @-name: [mandatory] contains the parameter's name | | | |-value: [mandatory] contains a text node with the value of the | parameter's value | |-config: Container node for the Configuration parameters. If the component | has no configuration parameters, thise node could be skipped. | The child nodes shoudl use the following syntax | |-param: same as above (init/param[name,value) ------------------------------------------------------------------------------- A simple example will look like: ------------------------------------------------------------------------------- the library that should be loaded at run time a library that should be dynamically loaded before the component library another library that should be dynamically loaded before the component library init_param_1 value init_param_n value config_param_1 value config_param_m value ------------------------------------------------------------------------------- ServiceConfiguration also initialize some Log4Cpp Appenders looking at the file .log-properties. The format of that file should follow the convention of the Log4j PropertyConfigurator ServiceConfigurator expect that those files are store in some directories. The applied rule is that it start serching in: GLITE_LOCATION_USER/etc then GLITE_LOCATION_VAR/etc then GLITE_LOCATION/etc then the current working directory In the case where configuration directories are used, the configuration namespace is not used to localize the configuration files, instead the these files should be stored in .d/.properties.xml .d/.log-properties this then implies that all configuration files of the services providing a similar functionality can be grouped into a directory structure. in order to look up these files ServiceConfigurator uses the same rule describe above. For the definition of the GLITE_LOCATION, GLITE_LOCATION_VAR, GLITE_LOCATION_USER variables, ServiceConfiguration first look at the environment variables $GLITE_LOCATION, $GLITE_LOCATION_VAR and $GLITE_LOCATION_USER then the content of the file $HOME/.glite.conf then the content fo the file /etc/glite.conf If those values are not set, ServiceConfigurator will assign the default values: GLITE_LOCATION = /opt/glite GLITE_LOCATION_VAR = /var/glite GLITE_LOCATION_USER = ~/.glite More detailes can be found at the GLite Developers Guide. * GLite Data Config Service - Configutration phases As illustrated above, configuration parameters belong to two different categories, that correspond to two phases, named "Initializazion" and "Configuration". In fact, when the GLite Data ServiceConfiguration is initialized, it performs the following actions: 1. Read the configuration file for the service 2. For each component, loads dynamically the dependencies (if any), then loads the component library and get a pointer to the implementation of the ComponentConfiguration interface 3. For each component, invokes the "init" method of the ComponentConfiguration interface, passing the value of all the parameters registered for the initialization phase 4. For each component, invokes the "config" method of the ComponentConfiguration interface, passing the value of all the parameters registered for the configuration phase 5. For each component, invokes the "start" method of the ComponentConfiguration interface, to notify the component tho start its business logic (e.g. accept request from a client) The need of those two phases come from two practical issues: - It's quite useful to have "static" parameters, i.e. parameter that the service should not expect changing during the execution (like resource reservation), and parameters that could be changed at run-time without restarting the process. In GLite Data ServiceConfiguration, all the Initialization parameters are intended as static, when Configuration parameters could be changed by editing the configuration file and perform a ServiceConfiguration reconfiguration action. - In case components need to resolve dependencies at run-time, as for plug-ins, it's a good practice to get pointer to instances that have been initialized at least for their critical part.In the current implementation, instances should then be created during Initialization phase when run-time dependencies should be resolved during Configuration. * GLite Data Config Service - Configure Logging In addition to the configuration file, the GLite ServiceConfiguration requires another file to properly configure the logging filters and destinations. That file should be named .log-properties, where is the name of the service (or configuration namespace). The content of that file should be a Log4Cpp configuration file that will be passed to the log4cpp::PropertyConfigurator. Check the Log4Cpp or the Log4J documentation for more details. How to use glite-data-config-service ------------------------------------ glite-data-config-service is a command line application that accept the following syntax: glite-data-config-service [--quiet|-Q] [[--directory|-d ] | [--prefix|-p ]] where is the Configuration name used by the ServiceConfigurator. In case the --directory or --prefix is used, is the value of the configuration directory and config_name is the configuration instance name. should one of the following values: - start: start a service in a separate process. This new process will have a new session id and the name reported on the process table will be - stop: stop the service running in a separate process. - kill: kill the service running in a separate process. Not safe: some resources will not be released - restart: restart a service. This action is the same thing as running stop and then start - reconfig: reconfigure a service without stopping it. The sevrice process will not be killed. Only changes on the log and configuration parameters will be taken into account, initialization one will not be affected - status: print the service status on the standard output - debug: run the service in the current process. This mode is useful for debugging purposes, since the process could be easily attached to a debugger the "--quiet" option disable the messages on the standard output/error The only difference between the --directory and --prefix options is that the service name will be in the first case the value of the parameter, while in the latter will be - Example: Supposing the have a service named "glite-test-foo", whith the configuration files "glite-test-foo.properties.xml" and "glite-test-foo.log-properties" should be located in one of the path (GLITE_LOCATION_USER/etc, GLITE_LOCATION_VAR/etc, GLITE_LOCATION/etc). The command required to start the service is glite-data-config-sevrice glite-test-foo start After it's started, this daemon will assume the name "glite-test-foo" In case you need to run different instances of this "foo" service, supposing one for each VO, you need to create as many config file pairs as the number of VO you have. All of these files should be stored, with a different name, in one of the path (GLITE_LOCATION_USER/etc, GLITE_LOCATION_VAR/etc, GLITE_LOCATION/etc). You'll end up having something like this: $(GLITE_LOCATION)/etc/glite-test-foo-VO_1.properties.xml $(GLITE_LOCATION)/etc/glite-test-foo-VO_1.log-properties $(GLITE_LOCATION)/etc/glite-test-foo-VO_2.properties.xml $(GLITE_LOCATION)/etc/glite-test-foo-VO_2.log-properties ... $(GLITE_LOCATION)/etc/glite-test-foo-VO_n.properties.xml $(GLITE_LOCATION)/etc/glite-test-foo-VO_n.log-properties in order to start these services, the commands are the same as the one described above, just use a differnet configuration name glite-data-config-sevrice glite-test-foo-VO_1 start glite-data-config-sevrice glite-test-foo-VO_2 start ... glite-data-config-sevrice glite-test-foo-VO_n start In order to better organize the configuration, an administrator may want to define a configuration directory and then name each instance with the VO name. The layout of the configuration would then be: $(GLITE_LOCATION)/etc/glite-test-foo.d/VO_1.properties.xml $(GLITE_LOCATION)/etc/glite-test-foo.d/VO_1.log-properties $(GLITE_LOCATION)/etc/glite-test-foo.d/VO_2.properties.xml $(GLITE_LOCATION)/etc/glite-test-foo.d/VO_2.log-properties ... $(GLITE_LOCATION)/etc/glite-test-foo.d/VO_n.properties.xml $(GLITE_LOCATION)/etc/glite-test-foo.d/VO_n.log-properties and in order to start these services, the commands required would be glite-data-config-sevrice -d glite-test-foo VO_1 start glite-data-config-sevrice -d glite-test-foo VO_2 start ... glite-data-config-sevrice -d glite-test-foo VO_n start Please note that the name of the process related to the daemon is set to glite-test-foo-VO_1, exactly the same value as if the configuration directory wasn't used. The usage of the configuration directory is optional, and depends on the taste of the system administator installing and configuring the service. Config Generator ---------------- glite-data-config-generator is an application that could be used to generate a configuration file. It requires as input a configuration template file that contains the configuration details for a given service and then either prompt the user for the values to be assigned to each configuration parameter or use a property file to get those values. The command line for that application is: glite-data-config-generator -f [-o ] [-l ] [-p | -O =][*] [-i] [-L ] where: -f config-template: specify the template file to be used to create the configuration -o output_file : the name of the configuration file to create -l log_file : the name of the log configuration file to create -p property_file : use the property file as input. If a mandatory property is missing, the generation fails, unless the interactive mode is enabled. Multiple files can be specified by repeating the -p option -O property=value : Set a property from the command line. Multiple properties can be specified by repeating the -O option and can be mixed with the -p option -i : Run the interacting mode, asking for unset properties, depending on the chosen level -L level : the detail level that shoudl be used. Allowed values are: low - only mandatory parameters normal - increase the level by adding some parameters that usually you want to set advanced - increase the level by adding parameters that has a reasonable default expert - include all the parameters Accordingly to the selected level, the user would be asked only for unset parameters glite-data-config-generator may accept multiple property files as input by specifying multiple -p options. In case a property is repeated in more the one file, the value is taken from the last one: glite-data-config-generator -f template.config.xml -o service_1.properties.xml -l service_1.log-properties -p property_1.properties -p property_2.properties -p property_3.properties It would be possible to specify properties direclty on the command line, via the -O option: glite-data-config-generator -f template.config.xml -o service_1.properties.xml -l service_1.log-properties -O component_1.property_1=value_1 -O component_1.property_2=value_2 -O component_2.property_1=value_1 The -p and -O options could be combinated together, so some properties could be defined in the properties file (e.g. default values) and others passed as parameters on the command line. In case of redefined property values, the rule is always that the last wins (in fact, the original meaning of the -O optin was override). In case the -p/-O option is used and one or more mandatory parameters are not set, the glite-data-config-generator returns an error, unless you specify the -i option: in that case the generator would ask the user to provide the missing parameters, depending from the chosen expert level (this value can also be set using the -L option). Config Template --------------- The structure of the template file is the following: ------------------------------------------------------------------------------- service: Root Node. It requires the "name" attibute specifying the service name | @-name: [mandatory] attribute containing the service name | |-components: Container Node for all the components | |-component: Component Root Node | @-name: [mandatory] attribute containing the component name | |-config-template: root for the component configuration template.It contains | the following child nodes: | |-lib: Contains a text value with the name of the Shared library | that shouls be used to load the component. This node is mandatory | for all the Components that should be loaded dynamically | |-description: Contains a text value with a description of the component's | purpose and functionalities | |-dependencies: Container Node for the dependencies. The child nodes should | | be used to specify non-glite component dependencies, since some | | platforms don't load those libraries automaticallly when a shared | | library is loaded. All the child nodes should have the format: | | | |-lib: Contains a text value with the name of the library that shoudl be | loaded before the component library is loaded | |-init: Container node for the Initailization parameters. If the component | | has no initialization parameters, thise node could be skipped. | | The child nodes shoudl use the following syntax | | | |-param: Container Node for the Parameter. It has the mandatory attribute | | "name" and the mandatory child node "value". It alse has the optional | | attributes "mandatory", "type" and "advanced" | @-name: [mandatory] contains the parameter's name | @-mandatory: contains a flag that specifies of the parameter is mandatory | | (mandatory="true"), optional(mandatory="false") or fixed | | (mandatory="fixed"). A fixed value is set on the configuration | | template and shoudn't be changed. Default vaue is "false" | @-type: contains the parameter's type, useful to perform input validation. | | Default is "string" | @-advanced(deprecated): flag used to specify that the given parameter | | should be used only in advanced configuration, so normally users | | don't have to configure it. A parameter couldn't be mandatory and | | advanced at the same time. Default is "false" | @-level: The level of the parameter. Can be either normal, advanced or | | expert. This attrbute replace the deprecated advanced attribute: | | level=normal is equal to advanced=false and level=advanced to | | advanced=true; level=expert has been added in order to identify | | an property as one that should be changed only by expert system | | administrator. Default is "false" | | | |-description: contains a text value with a description of the parameter | | purpose, specifying also allowed values and restrictions | | | |-value: [mandatory] contains a text node with the value of the | initailization parameter's value | |-config: Container node for the Configuration parameters. If the component | has no configuration parameters, thise node could be skipped. | The child nodes shoudl use the following syntax | |-param: same as described above (init/param[name,value]) -------------------------------------------------------------------------------