PageRenderTime 138ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/galaxy/config.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 642 lines | 602 code | 16 blank | 24 comment | 13 complexity | fb7715049af349b884a267a2ca285e61 MD5 | raw file
  1. """
  2. Universe configuration builder.
  3. """
  4. # absolute_import needed for tool_shed package.
  5. from __future__ import absolute_import
  6. import sys, os, tempfile, re
  7. import logging, logging.config
  8. import ConfigParser
  9. from datetime import timedelta
  10. from galaxy.web.formatting import expand_pretty_datetime_format
  11. from galaxy.util import string_as_bool
  12. from galaxy.util import listify
  13. from galaxy.util import parse_xml
  14. from galaxy import eggs
  15. import pkg_resources
  16. log = logging.getLogger( __name__ )
  17. def resolve_path( path, root ):
  18. """If 'path' is relative make absolute by prepending 'root'"""
  19. if not( os.path.isabs( path ) ):
  20. path = os.path.join( root, path )
  21. return path
  22. class ConfigurationError( Exception ):
  23. pass
  24. class Configuration( object ):
  25. deprecated_options = ( 'database_file', )
  26. def __init__( self, **kwargs ):
  27. self.config_dict = kwargs
  28. self.root = kwargs.get( 'root_dir', '.' )
  29. # Collect the umask and primary gid from the environment
  30. self.umask = os.umask( 077 ) # get the current umask
  31. os.umask( self.umask ) # can't get w/o set, so set it back
  32. self.gid = os.getgid() # if running under newgrp(1) we'll need to fix the group of data created on the cluster
  33. # Database related configuration
  34. self.database = resolve_path( kwargs.get( "database_file", "database/universe.sqlite" ), self.root )
  35. self.database_connection = kwargs.get( "database_connection", False )
  36. self.database_engine_options = get_database_engine_options( kwargs )
  37. self.database_create_tables = string_as_bool( kwargs.get( "database_create_tables", "True" ) )
  38. self.database_query_profiling_proxy = string_as_bool( kwargs.get( "database_query_profiling_proxy", "False" ) )
  39. # Don't set this to true for production databases, but probably should
  40. # default to True for sqlite databases.
  41. self.database_auto_migrate = string_as_bool( kwargs.get( "database_auto_migrate", "False" ) )
  42. # Install database related configuration (if different).
  43. self.install_database_connection = kwargs.get( "install_database_connection", None )
  44. self.install_database_engine_options = get_database_engine_options( kwargs, model_prefix="install_" )
  45. # Where dataset files are stored
  46. self.file_path = resolve_path( kwargs.get( "file_path", "database/files" ), self.root )
  47. self.new_file_path = resolve_path( kwargs.get( "new_file_path", "database/tmp" ), self.root )
  48. tempfile.tempdir = self.new_file_path
  49. self.openid_consumer_cache_path = resolve_path( kwargs.get( "openid_consumer_cache_path", "database/openid_consumer_cache" ), self.root )
  50. self.cookie_path = kwargs.get( "cookie_path", "/" )
  51. self.genome_data_path = kwargs.get( "genome_data_path", "tool-data/genome" )
  52. self.rsync_url = kwargs.get( "rsync_url", "rsync://datacache.galaxyproject.org/indexes" )
  53. # Galaxy OpenID settings
  54. self.enable_openid = string_as_bool( kwargs.get( 'enable_openid', False ) )
  55. self.openid_config = kwargs.get( 'openid_config_file', 'openid_conf.xml' )
  56. self.enable_quotas = string_as_bool( kwargs.get( 'enable_quotas', False ) )
  57. self.tool_sheds_config = kwargs.get( 'tool_sheds_config_file', 'tool_sheds_conf.xml' )
  58. self.enable_unique_workflow_defaults = string_as_bool( kwargs.get( 'enable_unique_workflow_defaults', False ) )
  59. self.tool_path = resolve_path( kwargs.get( "tool_path", "tools" ), self.root )
  60. self.tool_data_path = resolve_path( kwargs.get( "tool_data_path", "tool-data" ), os.getcwd() )
  61. self.len_file_path = resolve_path( kwargs.get( "len_file_path", os.path.join( self.tool_data_path, 'shared','ucsc','chrom') ), self.root )
  62. self.test_conf = resolve_path( kwargs.get( "test_conf", "" ), self.root )
  63. # The value of migrated_tools_config is the file reserved for containing only those tools that have been eliminated from the distribution
  64. # and moved to the tool shed.
  65. self.migrated_tools_config = resolve_path( kwargs.get( 'migrated_tools_config', 'migrated_tools_conf.xml' ), self.root )
  66. if 'tool_config_file' in kwargs:
  67. tcf = kwargs[ 'tool_config_file' ]
  68. elif 'tool_config_files' in kwargs:
  69. tcf = kwargs[ 'tool_config_files' ]
  70. else:
  71. tcf = 'tool_conf.xml,shed_tool_conf.xml'
  72. self.tool_filters = listify( kwargs.get( "tool_filters", [] ), do_strip=True )
  73. self.tool_label_filters = listify( kwargs.get( "tool_label_filters", [] ), do_strip=True )
  74. self.tool_section_filters = listify( kwargs.get( "tool_section_filters", [] ), do_strip=True )
  75. self.user_tool_filters = listify( kwargs.get( "user_tool_filters", [] ), do_strip=True )
  76. self.user_label_filters = listify( kwargs.get( "user_tool_label_filters", [] ), do_strip=True )
  77. self.user_section_filters = listify( kwargs.get( "user_tool_section_filters", [] ), do_strip=True )
  78. self.tool_configs = [ resolve_path( p, self.root ) for p in listify( tcf ) ]
  79. self.shed_tool_data_path = kwargs.get( "shed_tool_data_path", None )
  80. if self.shed_tool_data_path:
  81. self.shed_tool_data_path = resolve_path( self.shed_tool_data_path, self.root )
  82. else:
  83. self.shed_tool_data_path = self.tool_data_path
  84. self.tool_data_table_config_path = resolve_path( kwargs.get( 'tool_data_table_config_path', 'tool_data_table_conf.xml' ), self.root )
  85. self.shed_tool_data_table_config = resolve_path( kwargs.get( 'shed_tool_data_table_config', 'shed_tool_data_table_conf.xml' ), self.root )
  86. self.enable_tool_shed_check = string_as_bool( kwargs.get( 'enable_tool_shed_check', False ) )
  87. self.manage_dependency_relationships = string_as_bool( kwargs.get( 'manage_dependency_relationships', False ) )
  88. self.running_functional_tests = string_as_bool( kwargs.get( 'running_functional_tests', False ) )
  89. self.hours_between_check = kwargs.get( 'hours_between_check', 12 )
  90. try:
  91. if isinstance( self.hours_between_check, int ):
  92. if self.hours_between_check < 1 or self.hours_between_check > 24:
  93. self.hours_between_check = 12
  94. elif isinstance( self.hours_between_check, float ):
  95. # If we're running functional tests, the minimum hours between check should be reduced to 0.001, or 3.6 seconds.
  96. if self.running_functional_tests:
  97. if self.hours_between_check < 0.001 or self.hours_between_check > 24.0:
  98. self.hours_between_check = 12.0
  99. else:
  100. if self.hours_between_check < 1.0 or self.hours_between_check > 24.0:
  101. self.hours_between_check = 12.0
  102. else:
  103. self.hours_between_check = 12
  104. except:
  105. self.hours_between_check = 12
  106. self.update_integrated_tool_panel = kwargs.get( "update_integrated_tool_panel", True )
  107. self.enable_data_manager_user_view = string_as_bool( kwargs.get( "enable_data_manager_user_view", "False" ) )
  108. self.data_manager_config_file = resolve_path( kwargs.get('data_manager_config_file', 'data_manager_conf.xml' ), self.root )
  109. self.shed_data_manager_config_file = resolve_path( kwargs.get('shed_data_manager_config_file', 'shed_data_manager_conf.xml' ), self.root )
  110. self.galaxy_data_manager_data_path = kwargs.get( 'galaxy_data_manager_data_path', self.tool_data_path )
  111. self.tool_secret = kwargs.get( "tool_secret", "" )
  112. self.id_secret = kwargs.get( "id_secret", "USING THE DEFAULT IS NOT SECURE!" )
  113. self.retry_metadata_internally = string_as_bool( kwargs.get( "retry_metadata_internally", "True" ) )
  114. self.use_remote_user = string_as_bool( kwargs.get( "use_remote_user", "False" ) )
  115. self.normalize_remote_user_email = string_as_bool( kwargs.get( "normalize_remote_user_email", "False" ) )
  116. self.remote_user_maildomain = kwargs.get( "remote_user_maildomain", None )
  117. self.remote_user_header = kwargs.get( "remote_user_header", 'HTTP_REMOTE_USER' )
  118. self.remote_user_logout_href = kwargs.get( "remote_user_logout_href", None )
  119. self.require_login = string_as_bool( kwargs.get( "require_login", "False" ) )
  120. self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) )
  121. self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) )
  122. self.allow_user_dataset_purge = string_as_bool( kwargs.get( "allow_user_dataset_purge", "False" ) )
  123. self.allow_user_impersonation = string_as_bool( kwargs.get( "allow_user_impersonation", "False" ) )
  124. self.new_user_dataset_access_role_default_private = string_as_bool( kwargs.get( "new_user_dataset_access_role_default_private", "False" ) )
  125. self.collect_outputs_from = [ x.strip() for x in kwargs.get( 'collect_outputs_from', 'new_file_path,job_working_directory' ).lower().split(',') ]
  126. self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root )
  127. self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates" ), self.root )
  128. self.dependency_resolvers_config_file = resolve_path( kwargs.get( 'dependency_resolvers_config_file', 'dependency_resolvers_conf.xml' ), self.root )
  129. self.job_config_file = resolve_path( kwargs.get( 'job_config_file', 'job_conf.xml' ), self.root )
  130. self.local_job_queue_workers = int( kwargs.get( "local_job_queue_workers", "5" ) )
  131. self.cluster_job_queue_workers = int( kwargs.get( "cluster_job_queue_workers", "3" ) )
  132. self.job_queue_cleanup_interval = int( kwargs.get("job_queue_cleanup_interval", "5") )
  133. self.cluster_files_directory = os.path.abspath( kwargs.get( "cluster_files_directory", "database/pbs" ) )
  134. self.job_working_directory = resolve_path( kwargs.get( "job_working_directory", "database/job_working_directory" ), self.root )
  135. self.cleanup_job = kwargs.get( "cleanup_job", "always" )
  136. self.outputs_to_working_directory = string_as_bool( kwargs.get( 'outputs_to_working_directory', False ) )
  137. self.output_size_limit = int( kwargs.get( 'output_size_limit', 0 ) )
  138. self.retry_job_output_collection = int( kwargs.get( 'retry_job_output_collection', 0 ) )
  139. self.job_walltime = kwargs.get( 'job_walltime', None )
  140. self.job_walltime_delta = None
  141. if self.job_walltime is not None:
  142. h, m, s = [ int( v ) for v in self.job_walltime.split( ':' ) ]
  143. self.job_walltime_delta = timedelta( 0, s, 0, 0, m, h )
  144. self.admin_users = kwargs.get( "admin_users", "" )
  145. self.reset_password_length = int( kwargs.get('reset_password_length', '15') )
  146. self.mailing_join_addr = kwargs.get('mailing_join_addr',"galaxy-announce-join@bx.psu.edu")
  147. self.error_email_to = kwargs.get( 'error_email_to', None )
  148. self.activation_email = kwargs.get( 'activation_email', None )
  149. self.user_activation_on = string_as_bool( kwargs.get( 'user_activation_on', False ) )
  150. self.activation_grace_period = kwargs.get( 'activation_grace_period', None )
  151. self.inactivity_box_content = kwargs.get( 'inactivity_box_content', None )
  152. self.terms_url = kwargs.get( 'terms_url', None )
  153. self.instance_resource_url = kwargs.get( 'instance_resource_url', None )
  154. self.registration_warning_message = kwargs.get( 'registration_warning_message', None )
  155. # Get the disposable email domains blacklist file and its contents
  156. self.blacklist_location = kwargs.get( 'blacklist_file', None )
  157. self.blacklist_content = None
  158. if self.blacklist_location is not None:
  159. self.blacklist_file = resolve_path( kwargs.get( 'blacklist_file', None ), self.root )
  160. try:
  161. with open( self.blacklist_file ) as blacklist:
  162. self.blacklist_content = [ line.rstrip() for line in blacklist.readlines() ]
  163. except IOError:
  164. print ( "CONFIGURATION ERROR: Can't open supplied blacklist file from path: " + str( self.blacklist_file ) )
  165. self.smtp_server = kwargs.get( 'smtp_server', None )
  166. self.smtp_username = kwargs.get( 'smtp_username', None )
  167. self.smtp_password = kwargs.get( 'smtp_password', None )
  168. self.smtp_ssl = kwargs.get( 'smtp_ssl', None )
  169. self.track_jobs_in_database = kwargs.get( 'track_jobs_in_database', 'None' )
  170. self.start_job_runners = listify(kwargs.get( 'start_job_runners', '' ))
  171. self.expose_dataset_path = string_as_bool( kwargs.get( 'expose_dataset_path', 'False' ) )
  172. # External Service types used in sample tracking
  173. self.external_service_type_config_file = resolve_path( kwargs.get( 'external_service_type_config_file', 'external_service_types_conf.xml' ), self.root )
  174. self.external_service_type_path = resolve_path( kwargs.get( 'external_service_type_path', 'external_service_types' ), self.root )
  175. # Tasked job runner.
  176. self.use_tasked_jobs = string_as_bool( kwargs.get( 'use_tasked_jobs', False ) )
  177. self.local_task_queue_workers = int(kwargs.get("local_task_queue_workers", 2))
  178. # The transfer manager and deferred job queue
  179. self.enable_beta_job_managers = string_as_bool( kwargs.get( 'enable_beta_job_managers', 'False' ) )
  180. # Per-user Job concurrency limitations
  181. self.cache_user_job_count = string_as_bool( kwargs.get( 'cache_user_job_count', False ) )
  182. self.user_job_limit = int( kwargs.get( 'user_job_limit', 0 ) )
  183. self.registered_user_job_limit = int( kwargs.get( 'registered_user_job_limit', self.user_job_limit ) )
  184. self.anonymous_user_job_limit = int( kwargs.get( 'anonymous_user_job_limit', self.user_job_limit ) )
  185. self.default_cluster_job_runner = kwargs.get( 'default_cluster_job_runner', 'local:///' )
  186. self.pbs_application_server = kwargs.get('pbs_application_server', "" )
  187. self.pbs_dataset_server = kwargs.get('pbs_dataset_server', "" )
  188. self.pbs_dataset_path = kwargs.get('pbs_dataset_path', "" )
  189. self.pbs_stage_path = kwargs.get('pbs_stage_path', "" )
  190. self.drmaa_external_runjob_script = kwargs.get('drmaa_external_runjob_script', None )
  191. self.drmaa_external_killjob_script = kwargs.get('drmaa_external_killjob_script', None)
  192. self.external_chown_script = kwargs.get('external_chown_script', None)
  193. self.environment_setup_file = kwargs.get( 'environment_setup_file', None )
  194. self.use_heartbeat = string_as_bool( kwargs.get( 'use_heartbeat', 'False' ) )
  195. self.use_memdump = string_as_bool( kwargs.get( 'use_memdump', 'False' ) )
  196. self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) )
  197. self.log_events = string_as_bool( kwargs.get( 'log_events', 'False' ) )
  198. self.sanitize_all_html = string_as_bool( kwargs.get( 'sanitize_all_html', True ) )
  199. self.serve_xss_vulnerable_mimetypes = string_as_bool( kwargs.get( 'serve_xss_vulnerable_mimetypes', False ) )
  200. self.enable_old_display_applications = string_as_bool( kwargs.get( "enable_old_display_applications", "True" ) )
  201. self.ucsc_display_sites = kwargs.get( 'ucsc_display_sites', "main,test,archaea,ucla" ).lower().split(",")
  202. self.gbrowse_display_sites = kwargs.get( 'gbrowse_display_sites', "modencode,sgd_yeast,tair,wormbase,wormbase_ws120,wormbase_ws140,wormbase_ws170,wormbase_ws180,wormbase_ws190,wormbase_ws200,wormbase_ws204,wormbase_ws210,wormbase_ws220,wormbase_ws225" ).lower().split(",")
  203. self.brand = kwargs.get( 'brand', None )
  204. self.welcome_url = kwargs.get( 'welcome_url', '/static/welcome.html' )
  205. # Configuration for the message box directly below the masthead.
  206. self.message_box_visible = kwargs.get( 'message_box_visible', False )
  207. self.message_box_content = kwargs.get( 'message_box_content', None )
  208. self.message_box_class = kwargs.get( 'message_box_class', 'info' )
  209. self.support_url = kwargs.get( 'support_url', 'http://wiki.g2.bx.psu.edu/Support' )
  210. self.wiki_url = kwargs.get( 'wiki_url', 'http://wiki.galaxyproject.org/' )
  211. self.blog_url = kwargs.get( 'blog_url', None )
  212. self.screencasts_url = kwargs.get( 'screencasts_url', None )
  213. self.library_import_dir = kwargs.get( 'library_import_dir', None )
  214. self.user_library_import_dir = kwargs.get( 'user_library_import_dir', None )
  215. # Searching data libraries
  216. self.enable_lucene_library_search = string_as_bool( kwargs.get( 'enable_lucene_library_search', False ) )
  217. self.enable_whoosh_library_search = string_as_bool( kwargs.get( 'enable_whoosh_library_search', False ) )
  218. self.whoosh_index_dir = resolve_path( kwargs.get( "whoosh_index_dir", "database/whoosh_indexes" ), self.root )
  219. self.ftp_upload_dir = kwargs.get( 'ftp_upload_dir', None )
  220. self.ftp_upload_dir_identifier = kwargs.get( 'ftp_upload_dir_identifier', 'email' ) # attribute on user - email, username, id, etc...
  221. self.ftp_upload_site = kwargs.get( 'ftp_upload_site', None )
  222. self.allow_library_path_paste = kwargs.get( 'allow_library_path_paste', False )
  223. self.disable_library_comptypes = kwargs.get( 'disable_library_comptypes', '' ).lower().split( ',' )
  224. # Cistrome Static libraries
  225. # added by TL
  226. self.cistrome_static_library_path = resolve_path( kwargs.get( "cistrome_static_library_path", "tool-data/" ), self.root )
  227. # end
  228. # Location for dependencies
  229. if 'tool_dependency_dir' in kwargs:
  230. self.tool_dependency_dir = resolve_path( kwargs.get( "tool_dependency_dir" ), self.root )
  231. # Setting the following flag to true will ultimately cause tool dependencies
  232. # to be located in the shell environment and used by the job that is executing
  233. # the tool.
  234. self.use_tool_dependencies = True
  235. else:
  236. self.tool_dependency_dir = None
  237. self.use_tool_dependencies = False
  238. # Configuration options for taking advantage of nginx features
  239. self.upstream_gzip = string_as_bool( kwargs.get( 'upstream_gzip', False ) )
  240. self.apache_xsendfile = string_as_bool( kwargs.get( 'apache_xsendfile', False ) )
  241. self.nginx_x_accel_redirect_base = kwargs.get( 'nginx_x_accel_redirect_base', False )
  242. self.nginx_x_archive_files_base = kwargs.get( 'nginx_x_archive_files_base', False )
  243. self.nginx_upload_store = kwargs.get( 'nginx_upload_store', False )
  244. self.nginx_upload_path = kwargs.get( 'nginx_upload_path', False )
  245. if self.nginx_upload_store:
  246. self.nginx_upload_store = os.path.abspath( self.nginx_upload_store )
  247. self.object_store = kwargs.get( 'object_store', 'disk' )
  248. self.object_store_check_old_style = string_as_bool( kwargs.get( 'object_store_check_old_style', False ) )
  249. self.object_store_cache_path = resolve_path( kwargs.get( "object_store_cache_path", "database/object_store_cache" ), self.root )
  250. # Handle AWS-specific config options for backward compatibility
  251. if kwargs.get( 'aws_access_key', None) is not None:
  252. self.os_access_key= kwargs.get( 'aws_access_key', None )
  253. self.os_secret_key= kwargs.get( 'aws_secret_key', None )
  254. self.os_bucket_name= kwargs.get( 's3_bucket', None )
  255. self.os_use_reduced_redundancy = kwargs.get( 'use_reduced_redundancy', False )
  256. else:
  257. self.os_access_key = kwargs.get( 'os_access_key', None )
  258. self.os_secret_key = kwargs.get( 'os_secret_key', None )
  259. self.os_bucket_name = kwargs.get( 'os_bucket_name', None )
  260. self.os_use_reduced_redundancy = kwargs.get( 'os_use_reduced_redundancy', False )
  261. self.os_host = kwargs.get( 'os_host', None )
  262. self.os_port = kwargs.get( 'os_port', None )
  263. self.os_is_secure = string_as_bool( kwargs.get( 'os_is_secure', True ) )
  264. self.os_conn_path = kwargs.get( 'os_conn_path', '/' )
  265. self.object_store_cache_size = float(kwargs.get( 'object_store_cache_size', -1 ))
  266. self.object_store_config_file = kwargs.get( 'object_store_config_file', None )
  267. if self.object_store_config_file is not None:
  268. self.object_store_config_file = resolve_path( self.object_store_config_file, self.root )
  269. self.distributed_object_store_config_file = kwargs.get( 'distributed_object_store_config_file', None )
  270. if self.distributed_object_store_config_file is not None:
  271. self.distributed_object_store_config_file = resolve_path( self.distributed_object_store_config_file, self.root )
  272. self.irods_root_collection_path = kwargs.get( 'irods_root_collection_path', None )
  273. self.irods_default_resource = kwargs.get( 'irods_default_resource', None )
  274. # Parse global_conf and save the parser
  275. global_conf = kwargs.get( 'global_conf', None )
  276. global_conf_parser = ConfigParser.ConfigParser()
  277. self.config_file = None
  278. self.global_conf_parser = global_conf_parser
  279. if global_conf and "__file__" in global_conf:
  280. self.config_file = global_conf['__file__']
  281. global_conf_parser.read(global_conf['__file__'])
  282. # Heartbeat log file name override
  283. if global_conf is not None:
  284. self.heartbeat_log = global_conf.get( 'heartbeat_log', 'heartbeat.log' )
  285. # Determine which 'server:' this is
  286. self.server_name = 'main'
  287. for arg in sys.argv:
  288. # Crummy, but PasteScript does not give you a way to determine this
  289. if arg.lower().startswith('--server-name='):
  290. self.server_name = arg.split('=', 1)[-1]
  291. # Store all configured server names
  292. self.server_names = []
  293. for section in global_conf_parser.sections():
  294. if section.startswith('server:'):
  295. self.server_names.append(section.replace('server:', '', 1))
  296. # Store advanced job management config
  297. self.job_manager = kwargs.get('job_manager', self.server_name).strip()
  298. self.job_handlers = [ x.strip() for x in kwargs.get('job_handlers', self.server_name).split(',') ]
  299. self.default_job_handlers = [ x.strip() for x in kwargs.get('default_job_handlers', ','.join( self.job_handlers ) ).split(',') ]
  300. # Use database for job running IPC unless this is a standalone server or explicitly set in the config
  301. if self.track_jobs_in_database == 'None':
  302. self.track_jobs_in_database = False
  303. if len(self.server_names) > 1:
  304. self.track_jobs_in_database = True
  305. else:
  306. self.track_jobs_in_database = string_as_bool( self.track_jobs_in_database )
  307. # Store per-tool runner configs
  308. self.tool_handlers = self.__read_tool_job_config( global_conf_parser, 'galaxy:tool_handlers', 'name' )
  309. self.tool_runners = self.__read_tool_job_config( global_conf_parser, 'galaxy:tool_runners', 'url' )
  310. self.datatypes_config = kwargs.get( 'datatypes_config_file', 'datatypes_conf.xml' )
  311. # Cloud configuration options
  312. self.enable_cloud_launch = string_as_bool( kwargs.get( 'enable_cloud_launch', False ) )
  313. self.cloudlaunch_default_ami = kwargs.get( 'cloudlaunch_default_ami', 'ami-a7dbf6ce' )
  314. # Galaxy messaging (AMQP) configuration options
  315. self.amqp = {}
  316. try:
  317. amqp_config = global_conf_parser.items("galaxy_amqp")
  318. except ConfigParser.NoSectionError:
  319. amqp_config = {}
  320. for k, v in amqp_config:
  321. self.amqp[k] = v
  322. self.biostar_url = kwargs.get( 'biostar_url', None )
  323. self.biostar_key_name = kwargs.get( 'biostar_key_name', None )
  324. self.biostar_key = kwargs.get( 'biostar_key', None )
  325. self.biostar_enable_bug_reports = string_as_bool( kwargs.get( 'biostar_enable_bug_reports', True ) )
  326. self.biostar_never_authenticate = string_as_bool( kwargs.get( 'biostar_never_authenticate', False ) )
  327. self.pretty_datetime_format = expand_pretty_datetime_format( kwargs.get( 'pretty_datetime_format', '$locale (UTC)' ) )
  328. self.master_api_key = kwargs.get( 'master_api_key', None )
  329. if self.master_api_key == "changethis": # default in sample config file
  330. raise Exception("Insecure configuration, please change master_api_key to something other than default (changethis)")
  331. # Experimental: This will not be enabled by default and will hide
  332. # nonproduction code.
  333. # The api_folders refers to whether the API exposes the /folders section.
  334. self.api_folders = string_as_bool( kwargs.get( 'api_folders', False ) )
  335. # This is for testing new library browsing capabilities.
  336. self.new_lib_browse = string_as_bool( kwargs.get( 'new_lib_browse', False ) )
  337. # Error logging with sentry
  338. self.sentry_dsn = kwargs.get( 'sentry_dsn', None )
  339. # Logging with fluentd
  340. self.fluent_log = string_as_bool( kwargs.get( 'fluent_log', False ) )
  341. self.fluent_host = kwargs.get( 'fluent_host', 'localhost' )
  342. self.fluent_port = int( kwargs.get( 'fluent_port', 24224 ) )
  343. # visualization plugin framework
  344. self.visualization_plugins_directory = kwargs.get( 'visualization_plugins_directory', None )
  345. @property
  346. def sentry_dsn_public( self ):
  347. """
  348. Sentry URL with private key removed for use in client side scripts,
  349. sentry server will need to be configured to accept events
  350. """
  351. if self.sentry_dsn:
  352. return re.sub( r"^([^:/?#]+:)?//(\w+):(\w+)", r"\1//\2", self.sentry_dsn )
  353. else:
  354. return None
  355. def __read_tool_job_config( self, global_conf_parser, section, key ):
  356. try:
  357. tool_runners_config = global_conf_parser.items( section )
  358. # Process config to group multiple configs for the same tool.
  359. rval = {}
  360. for entry in tool_runners_config:
  361. tool_config, val = entry
  362. tool = None
  363. runner_dict = {}
  364. if tool_config.find("[") != -1:
  365. # Found tool with additional params; put params in dict.
  366. tool, params = tool_config[:-1].split( "[" )
  367. param_dict = {}
  368. for param in params.split( "," ):
  369. name, value = param.split( "@" )
  370. param_dict[ name ] = value
  371. runner_dict[ 'params' ] = param_dict
  372. else:
  373. tool = tool_config
  374. # Add runner URL.
  375. runner_dict[ key ] = val
  376. # Create tool entry if necessary.
  377. if tool not in rval:
  378. rval[ tool ] = []
  379. # Add entry to runners.
  380. rval[ tool ].append( runner_dict )
  381. return rval
  382. except ConfigParser.NoSectionError:
  383. return {}
  384. def get( self, key, default ):
  385. return self.config_dict.get( key, default )
  386. def get_bool( self, key, default ):
  387. if key in self.config_dict:
  388. return string_as_bool( self.config_dict[key] )
  389. else:
  390. return default
  391. def check( self ):
  392. paths_to_check = [ self.root, self.tool_path, self.tool_data_path, self.template_path ]
  393. # Check that required directories exist
  394. for path in paths_to_check:
  395. if path not in [ None, False ] and not os.path.isdir( path ):
  396. try:
  397. os.makedirs( path )
  398. except Exception, e:
  399. raise ConfigurationError( "Unable to create missing directory: %s\n%s" % ( path, e ) )
  400. # Create the directories that it makes sense to create
  401. for path in self.file_path, \
  402. self.new_file_path, \
  403. self.job_working_directory, \
  404. self.cluster_files_directory, \
  405. self.template_cache, \
  406. self.ftp_upload_dir, \
  407. self.library_import_dir, \
  408. self.user_library_import_dir, \
  409. self.nginx_upload_store, \
  410. './static/genetrack/plots', \
  411. self.whoosh_index_dir, \
  412. self.object_store_cache_path, \
  413. os.path.join( self.tool_data_path, 'shared', 'jars' ):
  414. if path not in [ None, False ] and not os.path.isdir( path ):
  415. try:
  416. os.makedirs( path )
  417. except Exception, e:
  418. raise ConfigurationError( "Unable to create missing directory: %s\n%s" % ( path, e ) )
  419. # Check that required files exist
  420. tool_configs = self.tool_configs
  421. if self.migrated_tools_config not in tool_configs:
  422. tool_configs.append( self.migrated_tools_config )
  423. for path in tool_configs:
  424. if not os.path.exists( path ):
  425. raise ConfigurationError("File not found: %s" % path )
  426. if not os.path.isfile( self.datatypes_config ):
  427. raise ConfigurationError("File not found: %s" % self.datatypes_config )
  428. # Check for deprecated options.
  429. for key in self.config_dict.keys():
  430. if key in self.deprecated_options:
  431. log.warning( "Config option '%s' is deprecated and will be removed in a future release. Please consult the latest version of the sample configuration file." % key )
  432. def is_admin_user( self,user ):
  433. """
  434. Determine if the provided user is listed in `admin_users`.
  435. NOTE: This is temporary, admin users will likely be specified in the
  436. database in the future.
  437. """
  438. admin_users = [ x.strip() for x in self.get( "admin_users", "" ).split( "," ) ]
  439. return ( user is not None and user.email in admin_users )
  440. def get_database_engine_options( kwargs, model_prefix='' ):
  441. """
  442. Allow options for the SQLAlchemy database engine to be passed by using
  443. the prefix "database_engine_option".
  444. """
  445. conversions = {
  446. 'convert_unicode': string_as_bool,
  447. 'pool_timeout': int,
  448. 'echo': string_as_bool,
  449. 'echo_pool': string_as_bool,
  450. 'pool_recycle': int,
  451. 'pool_size': int,
  452. 'max_overflow': int,
  453. 'pool_threadlocal': string_as_bool,
  454. 'server_side_cursors': string_as_bool
  455. }
  456. prefix = "%sdatabase_engine_option_" % model_prefix
  457. prefix_len = len( prefix )
  458. rval = {}
  459. for key, value in kwargs.iteritems():
  460. if key.startswith( prefix ):
  461. key = key[prefix_len:]
  462. if key in conversions:
  463. value = conversions[key](value)
  464. rval[ key ] = value
  465. return rval
  466. def configure_logging( config ):
  467. """
  468. Allow some basic logging configuration to be read from ini file.
  469. """
  470. # Get root logger
  471. root = logging.getLogger()
  472. # PasteScript will have already configured the logger if the
  473. # 'loggers' section was found in the config file, otherwise we do
  474. # some simple setup using the 'log_*' values from the config.
  475. if not config.global_conf_parser.has_section( "loggers" ):
  476. format = config.get( "log_format", "%(name)s %(levelname)s %(asctime)s %(message)s" )
  477. level = logging._levelNames[ config.get( "log_level", "DEBUG" ) ]
  478. destination = config.get( "log_destination", "stdout" )
  479. log.info( "Logging at '%s' level to '%s'" % ( level, destination ) )
  480. # Set level
  481. root.setLevel( level )
  482. # Turn down paste httpserver logging
  483. if level <= logging.DEBUG:
  484. logging.getLogger( "paste.httpserver.ThreadPool" ).setLevel( logging.WARN )
  485. # Remove old handlers
  486. for h in root.handlers[:]:
  487. root.removeHandler(h)
  488. # Create handler
  489. if destination == "stdout":
  490. handler = logging.StreamHandler( sys.stdout )
  491. else:
  492. handler = logging.FileHandler( destination )
  493. # Create formatter
  494. formatter = logging.Formatter( format )
  495. # Hook everything up
  496. handler.setFormatter( formatter )
  497. root.addHandler( handler )
  498. # If sentry is configured, also log to it
  499. if config.sentry_dsn:
  500. pkg_resources.require( "raven" )
  501. from raven.handlers.logging import SentryHandler
  502. sentry_handler = SentryHandler( config.sentry_dsn )
  503. sentry_handler.setLevel( logging.WARN )
  504. root.addHandler( sentry_handler )
  505. class ConfiguresGalaxyMixin:
  506. """ Shared code for configuring Galaxy-like app objects.
  507. """
  508. def _configure_toolbox( self ):
  509. # Initialize the tools, making sure the list of tool configs includes the reserved migrated_tools_conf.xml file.
  510. tool_configs = self.config.tool_configs
  511. if self.config.migrated_tools_config not in tool_configs:
  512. tool_configs.append( self.config.migrated_tools_config )
  513. from galaxy import tools
  514. self.toolbox = tools.ToolBox( tool_configs, self.config.tool_path, self )
  515. # Search support for tools
  516. import galaxy.tools.search
  517. self.toolbox_search = galaxy.tools.search.ToolBoxSearch( self.toolbox )
  518. def _configure_tool_data_tables( self, from_shed_config ):
  519. from galaxy.tools.data import ToolDataTableManager
  520. # Initialize tool data tables using the config defined by self.config.tool_data_table_config_path.
  521. self.tool_data_tables = ToolDataTableManager( tool_data_path=self.config.tool_data_path,
  522. config_filename=self.config.tool_data_table_config_path )
  523. # Load additional entries defined by self.config.shed_tool_data_table_config into tool data tables.
  524. self.tool_data_tables.load_from_config_file( config_filename=self.config.shed_tool_data_table_config,
  525. tool_data_path=self.tool_data_tables.tool_data_path,
  526. from_shed_config=from_shed_config )
  527. def _configure_datatypes_registry( self, installed_repository_manager=None ):
  528. from galaxy.datatypes import registry
  529. # Create an empty datatypes registry.
  530. self.datatypes_registry = registry.Registry()
  531. if installed_repository_manager:
  532. # Load proprietary datatypes defined in datatypes_conf.xml files in all installed tool shed repositories. We
  533. # load proprietary datatypes before datatypes in the distribution because Galaxy's default sniffers include some
  534. # generic sniffers (eg text,xml) which catch anything, so it's impossible for proprietary sniffers to be used.
  535. # However, if there is a conflict (2 datatypes with the same extension) between a proprietary datatype and a datatype
  536. # in the Galaxy distribution, the datatype in the Galaxy distribution will take precedence. If there is a conflict
  537. # between 2 proprietary datatypes, the datatype from the repository that was installed earliest will take precedence.
  538. installed_repository_manager.load_proprietary_datatypes()
  539. # Load the data types in the Galaxy distribution, which are defined in self.config.datatypes_config.
  540. self.datatypes_registry.load_datatypes( self.config.root, self.config.datatypes_config )
  541. def _configure_object_store( self, **kwds ):
  542. from galaxy.objectstore import build_object_store_from_config
  543. self.object_store = build_object_store_from_config( self.config, **kwds )
  544. def _configure_security( self ):
  545. from galaxy.web import security
  546. self.security = security.SecurityHelper( id_secret=self.config.id_secret )
  547. def _configure_tool_shed_registry( self ):
  548. import tool_shed.tool_shed_registry
  549. # Set up the tool sheds registry
  550. if os.path.isfile( self.config.tool_sheds_config ):
  551. self.tool_shed_registry = tool_shed.tool_shed_registry.Registry( self.config.root, self.config.tool_sheds_config )
  552. else:
  553. self.tool_shed_registry = None
  554. def _configure_models( self, check_migrate_databases=False, check_migrate_tools=False, config_file=None ):
  555. """
  556. Preconditions: object_store must be set on self.
  557. """
  558. if self.config.database_connection:
  559. db_url = self.config.database_connection
  560. else:
  561. db_url = "sqlite:///%s?isolation_level=IMMEDIATE" % self.config.database
  562. install_db_url = self.config.install_database_connection
  563. # TODO: Consider more aggressive check here that this is not the same
  564. # database file under the hood.
  565. combined_install_database = not( install_db_url and install_db_url != db_url )
  566. install_db_url = install_db_url or db_url
  567. if check_migrate_databases:
  568. # Initialize database / check for appropriate schema version. # If this
  569. # is a new installation, we'll restrict the tool migration messaging.
  570. from galaxy.model.migrate.check import create_or_verify_database
  571. create_or_verify_database( db_url, config_file, self.config.database_engine_options, app=self )
  572. if not combined_install_database:
  573. from galaxy.model.tool_shed_install.migrate.check import create_or_verify_database as tsi_create_or_verify_database
  574. tsi_create_or_verify_database( install_db_url, self.config.install_database_engine_options, app=self )
  575. if check_migrate_tools:
  576. # Alert the Galaxy admin to tools that have been moved from the distribution to the tool shed.
  577. from tool_shed.galaxy_install.migrate.check import verify_tools
  578. if combined_install_database:
  579. install_database_options = self.config.database_engine_options
  580. else:
  581. install_database_options = self.config.install_database_engine_options
  582. verify_tools( self, install_db_url, config_file, install_database_options )
  583. from galaxy.model import mapping
  584. self.model = mapping.init( self.config.file_path,
  585. db_url,
  586. self.config.database_engine_options,
  587. map_install_models=combined_install_database,
  588. database_query_profiling_proxy=self.config.database_query_profiling_proxy,
  589. object_store=self.object_store,
  590. trace_logger=getattr(self, "trace_logger", None),
  591. use_pbkdf2=self.config.get_bool( 'use_pbkdf2', True ) )
  592. if combined_install_database:
  593. log.info("Install database targetting Galaxy's database configuration.")
  594. self.install_model = self.model
  595. else:
  596. from galaxy.model.tool_shed_install import mapping as install_mapping
  597. install_db_url = self.config.install_database_connection
  598. log.info("Install database using its own connection %s" % install_db_url)
  599. install_db_engine_options = self.config.install_database_engine_options
  600. self.install_model = install_mapping.init( install_db_url,
  601. install_db_engine_options )