configurationengine/source/scripts/conesub_export.py
changeset 3 e7e0ae78773e
parent 0 2e8eeb919028
child 5 d2c80f5cab53
equal deleted inserted replaced
2:87cfa131b535 3:e7e0ae78773e
    16 
    16 
    17 import os
    17 import os
    18 import fnmatch
    18 import fnmatch
    19 import logging
    19 import logging
    20 from optparse import OptionParser, OptionGroup
    20 from optparse import OptionParser, OptionGroup
    21 
       
    22 import cone_common
    21 import cone_common
    23 from cone.public import api, plugin, utils, exceptions
    22 from cone.public import api, plugin, utils, exceptions
    24 
    23 
    25 
    24 
    26 VERSION     = '1.0'
    25 VERSION     = '1.0'
    27 DEFAULT_EXT = '.cpf'
    26 DEFAULT_EXT = '.cpf'
       
    27 CONE_SCRIPT_PATTERN = 'conesub_*.py'
       
    28 ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
    28 
    29 
    29 logger    = logging.getLogger('cone')
    30 logger    = logging.getLogger('cone')
    30 DATA_NAME = 'confml/data.confml'
    31 DATA_NAME = 'confml/data.confml'
    31 
    32 
       
    33 class  ExportFailedException(Exception):
       
    34     pass    
       
    35 
    32 def main():
    36 def main():
       
    37     """ Export configurations. """
    33     parser = OptionParser(version="%%prog %s" % VERSION)
    38     parser = OptionParser(version="%%prog %s" % VERSION)
    34     
    39     
    35     parser.add_options(cone_common.COMMON_OPTIONS)
    40     parser.add_options(cone_common.COMMON_OPTIONS)
    36     
    41     
    37     parser.add_option("-c", "--configuration",
    42     parser.add_option("-c", "--configuration",
   106                         "can create even an empty layer. "\
   111                         "can create even an empty layer. "\
   107                         "Example --add foo/root.confml --add bar/root-confml.",
   112                         "Example --add foo/root.confml --add bar/root-confml.",
   108                    metavar="CONFIG",
   113                    metavar="CONFIG",
   109                    default=None)
   114                    default=None)
   110 
   115 
       
   116     group.add_option("--run-action",
       
   117                    dest="action",
       
   118                    action="append",
       
   119                    type="string",
       
   120                    help="Adds a execution of extra step that can manipulate the configuration before it is exported to external storage. "\
       
   121                         "The --run-action operation can be used several times in a single command and it "\
       
   122                         "will execute the actions in given order."\
       
   123                         "Example --run-action=fix, which would execute fix action during export.",
       
   124                    metavar="PLUGIN",
       
   125                    default=None)
       
   126 
   111     group.add_option("--exclude-folders",
   127     group.add_option("--exclude-folders",
   112                         dest="exclude_empty_folders",
   128                         dest="exclude_empty_folders",
   113                         action="store_true",
   129                         action="store_true",
   114                         help="Excludes empty folders from export",
   130                         help="Excludes empty folders from export",
   115                         default=False)
   131                         default=False)
       
   132 
       
   133     group.add_option("--exclude-content-filter",
       
   134                         dest="exclude_content_filter",
       
   135                         help="Filters out files and folders from content folder which matches with "\
       
   136                              "the given regular expression. Matching is case-insensitive. "\
       
   137                              "Example --exclude-content-filter=\".*\.sisx|.*\.sis|.*\.wgz|.*wgt\" "\
       
   138                              "Filters out all files with extension sis, sisx, wgz or wgt.",
       
   139                         default=None)
       
   140 
   116     
   141     
   117     parser.add_option_group(group)
   142     parser.add_option_group(group)
   118     (options, args) = parser.parse_args()
   143     (options, args) = parser.parse_args()
   119     
   144     
   120     cone_common.handle_common_options(options)
   145     cone_common.handle_common_options(options)
   129     if options.export_dir and not (options.configs or options.config_wildcards or options.config_regexes):
   154     if options.export_dir and not (options.configs or options.config_wildcards or options.config_regexes):
   130         parser.error("Use of --export-dir requires at least one configuration to be specified")
   155         parser.error("Use of --export-dir requires at least one configuration to be specified")
   131     if options.export_dir and os.path.isfile(options.export_dir):
   156     if options.export_dir and os.path.isfile(options.export_dir):
   132         parser.error("Given export directory '%s' is a file")
   157         parser.error("Given export directory '%s' is a file")
   133     
   158     
       
   159     try:
       
   160         run_export(options)
       
   161     except ExportFailedException, e:
       
   162         parser.error(str(e))
       
   163 
       
   164     
       
   165     
       
   166 def run_export(options):
   134     # Open the project and find out the active configuration
   167     # Open the project and find out the active configuration
   135     project = api.Project(api.Storage.open(options.project, "r"))
   168     storage = api.Storage.open(options.project, "r", username=options.username, password=options.password)
       
   169     project = api.Project(storage)
   136     try:
   170     try:
   137         active_root = project.get_storage().get_active_configuration()
   171         active_root = project.get_storage().get_active_configuration()
   138     except AttributeError:
   172     except AttributeError:
   139         active_root = None
   173         active_root = None
   140     
   174     
   146                 project          = project,
   180                 project          = project,
   147                 configs          = options.configs,
   181                 configs          = options.configs,
   148                 config_wildcards = options.config_wildcards,
   182                 config_wildcards = options.config_wildcards,
   149                 config_regexes   = options.config_regexes)
   183                 config_regexes   = options.config_regexes)
   150         except cone_common.ConfigurationNotFoundError, e:
   184         except cone_common.ConfigurationNotFoundError, e:
   151             parser.error(str(e))
   185             raise ExportFailedException(str(e))
   152     
   186     
   153     # Use the active configuration if no configurations are specifically given
   187     # Use the active configuration if no configurations are specifically given
   154     if len(config_list) == 0:
   188     if len(config_list) == 0:
   155         if active_root is None:
   189         if active_root is None:
   156             parser.error("No configurations given and the project does not have an active root")
   190             raise ExportFailedException("No configurations given and the project does not have an active root")
   157         else:
   191         else:
   158             logger.info('No configurations given! Using active root configuration %s' % active_root)
   192             logger.info('No configurations given! Using active root configuration %s' % active_root)
   159             config_list = [active_root]
   193             config_list = [active_root]
   160     
   194     
   161     # Perform the export
   195     # Perform the export
   163         _export_to_dir(project       = project,
   197         _export_to_dir(project       = project,
   164                        export_dir    = options.export_dir,
   198                        export_dir    = options.export_dir,
   165                        export_format = options.export_format or 'cpf',
   199                        export_format = options.export_format or 'cpf',
   166                        configs       = config_list,
   200                        configs       = config_list,
   167                        added_layers  = options.added,
   201                        added_layers  = options.added,
   168                        empty_folders = not options.exclude_empty_folders)
   202                        empty_folders = not options.exclude_empty_folders,
       
   203                        exclude_filters       = {"content": options.exclude_content_filter},
       
   204                        options               = options)
   169     else:
   205     else:
   170         _export_to_storage(project                 = project,
   206         _export_to_storage(project                 = project,
   171                            remote_project_location = options.remote,
   207                            remote_project_location = options.remote,
   172                            configs                 = config_list,
   208                            configs                 = config_list,
   173                            added_layers            = options.added,
   209                            added_layers            = options.added,
   174                            empty_folders           = not options.exclude_empty_folders)
   210                            empty_folders           = not options.exclude_empty_folders,
   175     
   211                            exclude_filters         = {"content": options.exclude_content_filter},
   176 
   212                            options                 = options)
   177 def _export_to_storage(project, remote_project_location, configs, added_layers, empty_folders):
   213     
       
   214 
       
   215 def _export_to_storage(project, remote_project_location, configs, added_layers, empty_folders, exclude_filters, options):
   178     assert len(configs) > 0
   216     assert len(configs) > 0
   179     
   217     
   180     # If the remote storage is not given, determine it automatically based
   218     # If the remote storage is not given, determine it automatically based
   181     # on the first specified configuration name
   219     # on the first specified configuration name
   182     if not remote_project_location:
   220     if not remote_project_location:
   183         remotename, ext = os.path.splitext(os.path.basename(configs[0]))
   221         remotename, ext = os.path.splitext(os.path.basename(configs[0]))
   184         remotename += DEFAULT_EXT
   222         remotename += DEFAULT_EXT
   185         logger.info('No remote storage given! Using source configuration name %s' % remotename)
   223         logger.info('No remote storage given! Using source configuration name %s' % remotename)
   186         remote_project_location = remotename
   224         remote_project_location = remotename
   187     
   225     
   188     remote_project = api.Project(api.Storage.open(remote_project_location, "w"))
   226     remote_project = api.Project(api.Storage.open(remote_project_location, "w", username=options.username, password=options.password))
   189     for config_path in configs:
   227     for config_path in configs:
   190         config = project.get_configuration(config_path)
   228         config = project.get_configuration(config_path)
       
   229         # immediate solution to run fixes during export
       
   230         if options.action:
       
   231             from cone.action import loader
       
   232             for action_name in options.action:
       
   233                 try:
       
   234                     action_class = loader.get_class(action_name)
       
   235                     action = action_class(configuration=config,
       
   236                                           project=project)
       
   237                     action.run()
       
   238                 except Exception,e:
       
   239                     logger.warning('Running plugin %s threw an exception: %s' % (action_name, e))
   191         project.export_configuration(config,
   240         project.export_configuration(config,
   192                                      remote_project.storage,
   241                                      remote_project.storage,
   193                                      empty_folders = empty_folders)
   242                                      empty_folders = empty_folders,
       
   243                                      exclude_filters = exclude_filters)
   194         print "Export %s to %s done!" % (config_path, remote_project_location)
   244         print "Export %s to %s done!" % (config_path, remote_project_location)
   195     
   245     
   196     # Setting first as active configuration if there are more than one configuration defined.
   246     # Setting first as active configuration if there are more than one configuration defined.
   197     configs = remote_project.list_configurations()
   247     configs = remote_project.list_configurations()
   198     if len(configs):
   248     if len(configs):
   202             pass
   252             pass
   203     
   253     
   204     remote_project.save()
   254     remote_project.save()
   205     remote_project.close()
   255     remote_project.close()
   206     
   256     
   207     _add_layers(project, remote_project_location, added_layers, empty_folders)
   257     _add_layers(project, remote_project_location, added_layers, empty_folders, exclude_filters, options)
   208     
   258     
   209 def _add_layers(source_project, remote_project_location, added_configs, empty_folders):
   259 def _add_layers(source_project, remote_project_location, added_configs, empty_folders, exclude_filters, options):
   210     """
   260     """
   211     Add new configuration layers from source_project into 
   261     Add new configuration layers from source_project into 
   212     """
   262     """
   213     if not added_configs:
   263     if not added_configs:
   214         return
   264         return
   225                 if source_project.storage.is_resource(added_config_name):
   275                 if source_project.storage.is_resource(added_config_name):
   226                     # The configuration exists in the source project, export it from there
   276                     # The configuration exists in the source project, export it from there
   227                     existing_config = source_project.get_configuration(added_config_name)
   277                     existing_config = source_project.get_configuration(added_config_name)
   228                     source_project.export_configuration(existing_config,
   278                     source_project.export_configuration(existing_config,
   229                                                         target_project.storage,
   279                                                         target_project.storage,
   230                                                         empty_folders = empty_folders)
   280                                                         empty_folders = empty_folders,
       
   281                                                         exclude_filters = exclude_filters)
   231                 else:
   282                 else:
   232                     # The given configuration does not exist in the source project,
   283                     # The given configuration does not exist in the source project,
   233                     # create a new empty layer
   284                     # create a new empty layer
   234                     logger.info("Creating new layer %s." % added_config_name)
   285                     logger.info("Creating new layer %s." % added_config_name)
   235                     new_config = target_project.create_configuration(added_config_name)
   286                     new_config = target_project.create_configuration(added_config_name)
   239             target_config.include_configuration(utils.resourceref.norm(added_config_name))
   290             target_config.include_configuration(utils.resourceref.norm(added_config_name))
   240     
   291     
   241     target_project.save()
   292     target_project.save()
   242     target_project.close()
   293     target_project.close()
   243 
   294 
   244 def _export_to_dir(project, export_dir, export_format, configs, added_layers, empty_folders):
   295 def _export_to_dir(project, export_dir, export_format, configs, added_layers, empty_folders, exclude_filters, options):
   245     if not os.path.exists(export_dir):
   296     if not os.path.exists(export_dir):
   246         os.makedirs(export_dir)
   297         os.makedirs(export_dir)
   247     
   298     
   248     for config in configs:
   299     for config in configs:
   249         remote_name, _ = os.path.splitext(os.path.basename(config))
   300         remote_name, _ = os.path.splitext(os.path.basename(config))
   251             remote_name += '.cpf'
   302             remote_name += '.cpf'
   252         elif export_format.lower() == 'dir':
   303         elif export_format.lower() == 'dir':
   253             remote_name += '/'
   304             remote_name += '/'
   254         
   305         
   255         remote_name = os.path.join(export_dir, remote_name)
   306         remote_name = os.path.join(export_dir, remote_name)
   256         _export_to_storage(project, remote_name, [config], added_layers, empty_folders)
   307         _export_to_storage(project, remote_name, [config], added_layers, empty_folders, exclude_filters, options)
   257 
   308 
   258 if __name__ == "__main__":
   309 if __name__ == "__main__":
   259     main()
   310     main()