示例#1
0
    def upgrade( self ):
        warnings = OrderedDict()
        do_warn = False
        for vn, upgs in self.upgrades.items():
            warnings[vn] = []

            for u in upgs:
                try:
                    exp = self.expand(u)
                except:
                    continue

                for upg in exp:
                    try:
                        old = self.get_item( upg['old'] )
                    except:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        warnings[vn].append( msg )
                        do_warn = True
                        self.del_item( upg['old'] )
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item( upg['new'], upg['cvt'].convert(old) )
        if do_warn and cylc.flags.verbose:
            print >> sys.stderr, "WARNING: deprecated items were automatically upgraded in '" + self.descr + "':"
            for vn,msgs in warnings.items():
                for m in msgs:
                    print >> sys.stderr, " * (" + vn + ")", m
示例#2
0
    def upgrade(self):
        warnings = OrderedDict()
        for vn, upgs in self.upgrades.items():
            for u in upgs:
                try:
                    exp = self.expand(u)
                except (KeyError, UpgradeError):
                    continue

                for upg in exp:
                    try:
                        old = self.get_item(upg['old'])
                    except KeyError:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        if not upg['silent']:
                            warnings.setdefault(vn, [])
                            warnings[vn].append(msg)
                        self.del_item(upg['old'])
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item(upg['new'], upg['cvt'].convert(old))
        if warnings:
            level = WARNING
            if self.descr == self.SITE_CONFIG:
                # Site level configuration, user cannot easily fix.
                # Only log at debug level.
                level = DEBUG
            else:
                # User level configuration, user should be able to fix.
                # Log at warning level.
                level = WARNING
            LOG.log(
                level,
                "deprecated items were automatically upgraded in '%s':",
                self.descr)
            for vn, msgs in warnings.items():
                for msg in msgs:
                    LOG.log(level, ' * (%s) %s', vn, msg)
示例#3
0
    def upgrade(self):
        warnings = OrderedDict()
        for vn, upgs in self.upgrades.items():
            for u in upgs:
                try:
                    exp = self.expand(u)
                except (KeyError, UpgradeError):
                    continue

                for upg in exp:
                    try:
                        old = self.get_item(upg['old'])
                    except KeyError:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        if not upg['silent']:
                            warnings.setdefault(vn, [])
                            warnings[vn].append(msg)
                        self.del_item(upg['old'])
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item(upg['new'], upg['cvt'].convert(old))
        if warnings:
            level = WARNING
            if self.descr == self.SITE_CONFIG:
                # Site level configuration, user cannot easily fix.
                # Only log at debug level.
                level = DEBUG
            else:
                # User level configuration, user should be able to fix.
                # Log at warning level.
                level = WARNING
            LOG.log(
                level,
                "deprecated items were automatically upgraded in '%s':",
                self.descr)
            for vn, msgs in warnings.items():
                for msg in msgs:
                    LOG.log(level, ' * (%s) %s', vn, msg)
示例#4
0
 def get_summary_str(self):
     """Return the poll context as a summary string delimited by "|"."""
     ret = OrderedDict()
     for key in self.CONTEXT_ATTRIBUTES:
         value = getattr(self, key)
         if key == 'job_log_dir' or value is None:
             continue
         ret[key] = value
     return '%s|%s' % (self.job_log_dir, json.dumps(ret))
示例#5
0
    def upgrade(self):
        warnings = OrderedDict()
        do_warn = False
        for vn, upgs in self.upgrades.items():
            warnings[vn] = []

            for u in upgs:
                try:
                    exp = self.expand(u)
                except (KeyError, UpgradeError):
                    continue

                for upg in exp:
                    try:
                        old = self.get_item(upg['old'])
                    except KeyError:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        if not upg['silent']:
                            warnings[vn].append(msg)
                            do_warn = True
                        self.del_item(upg['old'])
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item(upg['new'], upg['cvt'].convert(old))
        if do_warn and cylc.flags.verbose:
            sys.stderr.write(
                'WARNING: deprecated items were automatically upgraded in' +
                " '%s':\n" % self.descr)
            for vn, msgs in warnings.items():
                for m in msgs:
                    sys.stderr.write(' * (%s) %s\n' % (vn, m))
示例#6
0
    def upgrade(self):
        warnings = OrderedDict()
        do_warn = False
        for vn, upgs in self.upgrades.items():
            warnings[vn] = []

            for u in upgs:
                try:
                    exp = self.expand(u)
                except:
                    continue

                for upg in exp:
                    try:
                        old = self.get_item(upg['old'])
                    except:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        if not upg['silent']:
                            warnings[vn].append(msg)
                            do_warn = True
                        self.del_item(upg['old'])
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item(upg['new'], upg['cvt'].convert(old))
        if do_warn and cylc.flags.verbose:
            print >> sys.stderr, (
                "WARNING: deprecated items were automatically upgraded in '" +
                self.descr + "':")
            for vn, msgs in warnings.items():
                for m in msgs:
                    print >> sys.stderr, " * (" + vn + ")", m
示例#7
0
文件: upgrade.py 项目: arjclark/cylc
    def upgrade(self):
        warnings = OrderedDict()
        do_warn = False
        for vn, upgs in self.upgrades.items():
            warnings[vn] = []

            for u in upgs:
                try:
                    exp = self.expand(u)
                except (KeyError, UpgradeError):
                    continue

                for upg in exp:
                    try:
                        old = self.get_item(upg['old'])
                    except KeyError:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        if not upg['silent']:
                            warnings[vn].append(msg)
                            do_warn = True
                        self.del_item(upg['old'])
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item(upg['new'], upg['cvt'].convert(old))
        if do_warn and cylc.flags.verbose:
            sys.stderr.write(
                'WARNING: deprecated items were automatically upgraded in' +
                " '%s':\n" % self.descr)
            for vn, msgs in warnings.items():
                for m in msgs:
                    sys.stderr.write(' * (%s) %s\n' % (vn, m))
示例#8
0
 def __init__(self, task_id, filenames, cmd_tmpls, init_active_index):
     self.filenames = OrderedDict()
     name_str, point_str = TaskID.split(task_id)
     for filename in filenames:
         try:
             f_point_str, f_name_str, f_submit_num_str, f_base_name = (
                 filename.rsplit(os.sep, 4)[1:])
             if (f_point_str == point_str and f_name_str == name_str
                     and int(f_submit_num_str) and f_base_name):
                 name = f_submit_num_str + os.sep + f_base_name
             if ":" in filename:
                 name += " (%s)" % (filename.split(":", 1)[0])
         except ValueError:
             name = filename
         self.filenames[name] = filename
     self.init_active_index = init_active_index
     self.cmd_tmpls = cmd_tmpls
     logviewer.__init__(self, task_id, None,
                        filenames[self.init_active_index])
示例#9
0
 def __init__(self, cfg, descr):
     """Store the config dict to be upgraded if necessary."""
     self.cfg = cfg
     self.descr = descr
     # upgrades must be ordered in case several act on the same item
     self.upgrades = OrderedDict()
示例#10
0
class upgrader(object):
    """Handles upgrading of deprecated config values."""
    def __init__(self, cfg, descr):
        """Store the config dict to be upgraded if necessary."""
        self.cfg = cfg
        self.descr = descr
        # upgrades must be ordered in case several act on the same item
        self.upgrades = OrderedDict()

    def deprecate(self, vn, oldkeys, newkeys=None, cvtr=None, silent=False):
        if vn not in self.upgrades:
            self.upgrades[vn] = []
        if cvtr is None:
            cvtr = converter(lambda x: x, "value unchanged")  # identity
        self.upgrades[vn].append({
            'old': oldkeys,
            'new': newkeys,
            'cvt': cvtr,
            'silent': silent
        })

    def obsolete(self, vn, oldkeys, newkeys=None, silent=False):
        if vn not in self.upgrades:
            self.upgrades[vn] = []
        cvtr = converter(lambda x: x, "DELETED (OBSOLETE)")  # identity
        self.upgrades[vn].append({
            'old': oldkeys,
            'new': newkeys,
            'cvt': cvtr,
            'silent': silent
        })

    def get_item(self, keys):
        item = self.cfg
        for key in keys:
            item = item[key]
        return item

    def put_item(self, keys, val):
        item = self.cfg
        for key in keys[:-1]:
            if key not in item:
                item[key] = {}
            item = item[key]
        item[keys[-1]] = val

    def del_item(self, keys):
        item = self.cfg
        for key in keys[:-1]:
            item = item[key]
        del item[keys[-1]]

    @staticmethod
    def show_keys(keys):
        return '[' + ']['.join(keys) + ']'

    def expand(self, upg):
        """Expands __MANY__ items."""
        if '__MANY__' not in upg['old']:
            return [upg]
        if upg['old'].count('__MANY__') > 1:
            sys.stderr.write('%s\n' % upg['old'])
            raise UpgradeError("Multiple simultaneous __MANY__ not supported")
        exp_upgs = []
        pre = []
        post = []
        many = []
        i = -1
        okeys = upg['old']
        for k in okeys:
            i += 1
            if k == "__MANY__":
                pre = okeys[:i]
                post = okeys[i + 1:]
                tmp = self.cfg
                for j in pre:
                    tmp = tmp[j]
                many = tmp.keys()
                break
        if not many:
            exp_upgs.append(upg)
        else:
            i = -1
            nkeys = upg['new']
            if nkeys is None:  # No new keys defined.
                for m in many:
                    exp_upgs.append({
                        'old': pre + [m] + post,
                        'new': None,
                        'cvt': upg['cvt'],
                        'silent': upg['silent'],
                    })
                return exp_upgs
            npre = []
            npost = []
            for k in nkeys:
                i += 1
                if k == "__MANY__":
                    npre = nkeys[:i]
                    npost = nkeys[i + 1:]
            if not npre or not npost:
                raise UpgradeError('ERROR: __MANY__ mismatch')
            for m in many:
                exp_upgs.append({
                    'old': pre + [m] + post,
                    'new': npre + [m] + npost,
                    'cvt': upg['cvt'],
                    'silent': upg['silent'],
                })
        return exp_upgs

    def upgrade(self):
        warnings = OrderedDict()
        do_warn = False
        for vn, upgs in self.upgrades.items():
            warnings[vn] = []

            for u in upgs:
                try:
                    exp = self.expand(u)
                except (KeyError, UpgradeError):
                    continue

                for upg in exp:
                    try:
                        old = self.get_item(upg['old'])
                    except KeyError:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        if not upg['silent']:
                            warnings[vn].append(msg)
                            do_warn = True
                        self.del_item(upg['old'])
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item(upg['new'], upg['cvt'].convert(old))
        if do_warn and cylc.flags.verbose:
            sys.stderr.write(
                'WARNING: deprecated items were automatically upgraded in' +
                " '%s':\n" % self.descr)
            for vn, msgs in warnings.items():
                for m in msgs:
                    sys.stderr.write(' * (%s) %s\n' % (vn, m))
示例#11
0
    def get_task_class(self):
        # return a task proxy class definition, to be used for
        # instantiating objects of this particular task class.
        base_types = []
        for foo in self.modifiers + ['cycling']:
            mod = __import__('cylc.task_types.' + foo, fromlist=[foo])
            base_types.append(getattr(mod, foo))

        tclass = type(self.name, tuple(base_types), dict())

        # set class variables here
        tclass.title = self.rtconfig['title']
        tclass.description = self.rtconfig['description']

        # For any instance-specific environment variables (note that
        # [runtime][TASK][enviroment] is now held in a class variable).
        tclass.env_vars = OrderedDict()

        tclass.name = self.name

        tclass.rtconfig = self.rtconfig
        tclass.run_mode = self.run_mode

        tclass.elapsed_times = []
        tclass.mean_total_elapsed_time = None

        tclass.intercycle = self.intercycle
        tclass.max_future_prereq_offset = None
        tclass.follow_on = self.follow_on_task

        tclass.namespace_hierarchy = self.namespace_hierarchy

        def tclass_add_prerequisites(sself, point):
            # NOTE: Task objects hold all triggers defined for the task
            # in all cycling graph sections in this data structure:
            #     self.triggers[sequence] = [list of triggers for this
            #     sequence]
            # The list of triggers associated with sequenceX will only be
            # used by a particular task if the task's cycle point is a
            # valid member of sequenceX's sequence of cycle points.

            # 1) non-conditional triggers
            pp = plain_prerequisites(sself.id, self.start_point)
            sp = plain_prerequisites(sself.id, self.start_point)

            if self.sequential:
                # For tasks declared 'sequential' we automatically add a
                # previous-instance inter-cycle trigger, and adjust the
                # cleanup cutoff (determined by inter-cycle triggers)
                # accordingly.
                p_next = None
                adjusted = []
                for seq in self.sequences:
                    nxt = seq.get_next_point(sself.point)
                    if nxt:
                        # may be None if beyond the sequence bounds
                        adjusted.append(nxt)
                if adjusted:
                    p_next = min(adjusted)
                    if (sself.cleanup_cutoff is not None
                            and sself.cleanup_cutoff < p_next):
                        sself.cleanup_cutoff = p_next

                p_prev = None
                adjusted = []
                for seq in self.sequences:
                    prv = seq.get_nearest_prev_point(sself.point)
                    if prv:
                        # may be None if out of sequence bounds
                        adjusted.append(prv)
                if adjusted:
                    p_prev = max(adjusted)
                    pp.add(TaskID.get(sself.name, str(p_prev)) + ' succeeded')

            for sequence in self.triggers:
                for trig in self.triggers[sequence]:
                    if not sequence.is_valid(sself.point):
                        # This trigger is not used in current cycle
                        continue
                    if (trig.graph_offset_string is None or
                        (get_point_relative(trig.graph_offset_string, point) >=
                         self.start_point)):
                        # i.c.t. can be None after a restart, if one
                        # is not specified in the suite definition.

                        message, prereq_point = trig.get(point)
                        prereq_offset = prereq_point - point
                        if (prereq_offset > get_interval_cls().get_null() and
                            (sself.max_future_prereq_offset is None or
                             prereq_offset > sself.max_future_prereq_offset)):
                            sself.max_future_prereq_offset = prereq_offset

                        if trig.suicide:
                            sp.add(message)
                        else:
                            pp.add(message)

            sself.prerequisites.add_requisites(pp)
            sself.suicide_prerequisites.add_requisites(sp)

            # 2) conditional triggers
            for sequence in self.cond_triggers.keys():
                for ctrig, exp in self.cond_triggers[sequence]:
                    foo = ctrig.keys()[0]
                    if not sequence.is_valid(sself.point):
                        # This trigger is not valid for current cycle (see NOTE just above)
                        continue
                    cp = conditional_prerequisites(sself.id, self.start_point)
                    for label in ctrig:
                        trig = ctrig[label]
                        if trig.graph_offset_string is not None:
                            is_less_than_start = (get_point_relative(
                                trig.graph_offset_string, point) <
                                                  self.start_point)
                            cp.add(
                                trig.get(point)[0], label, is_less_than_start)
                        else:
                            cp.add(trig.get(point)[0], label)
                    cp.set_condition(exp)
                    if ctrig[foo].suicide:
                        sself.suicide_prerequisites.add_requisites(cp)
                    else:
                        sself.prerequisites.add_requisites(cp)

        tclass.add_prerequisites = tclass_add_prerequisites

        # class init function
        def tclass_init(sself,
                        start_point,
                        initial_state,
                        stop_point=None,
                        startup=False,
                        validate=False,
                        submit_num=0,
                        exists=False):

            sself.__class__.sequences = self.sequences
            sself.__class__.implicit_sequences = self.implicit_sequences
            sself.startup = startup
            sself.submit_num = submit_num
            sself.exists = exists
            sself.intercycle_offsets = self.intercycle_offsets

            if startup:
                # adjust up to the first on-sequence cycle point
                adjusted = []
                for seq in sself.__class__.sequences:
                    adj = seq.get_first_point(start_point)
                    if adj:
                        # may be None if out of sequence bounds
                        adjusted.append(adj)
                if adjusted:
                    sself.point = min(adjusted)
                    sself.cleanup_cutoff = self.get_cleanup_cutoff_point(
                        sself.point, self.intercycle_offsets)
                    sself.id = TaskID.get(sself.name, str(sself.point))
                else:
                    sself.point = None
                    # this task is out of sequence bounds (caller must
                    # check for a point of None)
                    return
            else:
                sself.point = start_point
                sself.cleanup_cutoff = self.get_cleanup_cutoff_point(
                    sself.point, self.intercycle_offsets)
                sself.id = TaskID.get(sself.name, str(sself.point))

            if 'clocktriggered' in self.modifiers:
                sself.clocktrigger_offset = self.clocktrigger_offset

            # prerequisites
            sself.prerequisites = prerequisites(self.start_point)
            sself.suicide_prerequisites = prerequisites(self.start_point)
            sself.add_prerequisites(sself.point)

            sself.logfiles = logfiles()
            for lfile in self.rtconfig['extra log files']:
                sself.logfiles.add_path(lfile)

            # outputs
            sself.outputs = outputs(sself.id)
            for outp in self.outputs:
                msg = outp.get(sself.point)
                if not sself.outputs.exists(msg):
                    sself.outputs.add(msg)
            sself.outputs.register()

            if stop_point:
                # Manually inserted tasks may have a final cycle point set.
                super(sself.__class__, sself).__init__(initial_state,
                                                       stop_point,
                                                       validate=validate)
            else:
                sself.stop_point = None
                super(sself.__class__, sself).__init__(initial_state,
                                                       validate=validate)

            sself.suite_polling_cfg = self.suite_polling_cfg
            sself.reconfigure_me = False
            sself.is_coldstart = self.is_coldstart
            sself.set_from_rtconfig()

        tclass.__init__ = tclass_init

        return tclass
示例#12
0
#!/usr/bin/env python
"""
An empty config file should successfully yield an empty sparse config dict.
"""

import os, sys

fpath = os.path.dirname(os.path.abspath(__file__))
# parsec
sys.path.append(fpath + '/../../..')

from parsec.config import config
from parsec.validate import validator as vdr
from parsec.OrderedDict import OrderedDict

SPEC = {'meta': {'title': vdr(vtype="string")}}
cfg = config(SPEC)
cfg.loadcfg("empty.rc")

if cfg.get(sparse=True) != OrderedDict():
    sys.exit(1)
示例#13
0
 def __init__( self, cfg, descr ):
     """Store the config dict to be upgraded if necessary."""
     self.cfg = cfg
     self.descr = descr
     # upgrades must be ordered in case several act on the same item
     self.upgrades = OrderedDict()
示例#14
0
class upgrader( object ):
    """Handles upgrading of deprecated config values."""

    def __init__( self, cfg, descr ):
        """Store the config dict to be upgraded if necessary."""
        self.cfg = cfg
        self.descr = descr
        # upgrades must be ordered in case several act on the same item
        self.upgrades = OrderedDict()

    def deprecate(self, vn, oldkeys, newkeys=None, cvtr=None, silent=False):
        if vn not in self.upgrades:
            self.upgrades[vn] = []
        if cvtr is None:
            cvtr = converter(lambda x: x, "value unchanged") # identity
        self.upgrades[vn].append(
            {
                'old': oldkeys,
                'new': newkeys,
                'cvt': cvtr,
                'silent': silent
            }
        )

    def obsolete(self, vn, oldkeys, newkeys=None, silent=False):
        if vn not in self.upgrades:
            self.upgrades[vn] = []
        cvtr = converter(lambda x: x, "DELETED (OBSOLETE)") # identity
        self.upgrades[vn].append(
            {
                'old' : oldkeys,
                'new' : newkeys,
                'cvt' : cvtr,
                'silent': silent 
            }
        )

    def get_item( self, keys ):
        item = self.cfg
        for key in keys:
            item = item[key]
        return item

    def put_item( self, keys, val ):
        item = self.cfg
        for key in keys[:-1]:
            if key not in item:
                item[key] = {}
            item = item[key]
        item[keys[-1]] = val

    def del_item( self, keys ):
        item = self.cfg
        for key in keys[:-1]:
            item = item[key]
        del item[keys[-1]]

    def show_keys( self, keys ):
        return '[' + ']['.join(keys) + ']'

    def expand( self, upg ):
        """Expands __MANY__ items."""
        if '__MANY__' not in upg['old']:
            return [upg]
        if upg['old'].count( '__MANY__' ) > 1:
            print >> sys.stderr, upg['old']
            raise UpgradeError( "Multiple simultaneous __MANY__ not supported" )
        exp_upgs = []
        pre = []
        post = []
        many = []
        i = -1
        okeys = upg['old']
        for k in okeys:
            i += 1
            if k == "__MANY__":
                pre = okeys[:i]
                post = okeys[i+1:]
                tmp = self.cfg
                for j in pre:
                    tmp = tmp[j]
                many = tmp.keys()
                break
        if not many:
            exp_upgs.append( upg )
        else:
            i = -1
            nkeys = upg['new']
            npre = []
            npost = []
            for k in nkeys:
                i += 1
                if k == "__MANY__":
                    npre = nkeys[:i]
                    npost = nkeys[i+1:]
            if not npre or not npost:
                raise UpgradeError('ERROR: __MANY__ mismatch')
            for m in many:
                exp_upgs.append( {
                    'old': pre + [m] + post,
                    'new': npre + [m] + npost,
                    'cvt': upg['cvt'],
                    'silent': upg['silent']
                    })
        return exp_upgs

    def upgrade( self ):
        warnings = OrderedDict()
        do_warn = False
        for vn, upgs in self.upgrades.items():
            warnings[vn] = []

            for u in upgs:
                try:
                    exp = self.expand(u)
                except:
                    continue

                for upg in exp:
                    try:
                        old = self.get_item( upg['old'] )
                    except:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        if not upg['silent']:
                            warnings[vn].append( msg )
                            do_warn = True
                        self.del_item( upg['old'] )
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item( upg['new'], upg['cvt'].convert(old) )
        if do_warn and cylc.flags.verbose:
            print >> sys.stderr, "WARNING: deprecated items were automatically upgraded in '" + self.descr + "':"
            for vn,msgs in warnings.items():
                for m in msgs:
                    print >> sys.stderr, " * (" + vn + ")", m
示例#15
0
class upgrader(object):
    """Handles upgrading of deprecated config values."""

    SITE_CONFIG = 'site config'
    USER_CONFIG = 'user config'

    def __init__(self, cfg, descr):
        """Store the config dict to be upgraded if necessary."""
        self.cfg = cfg
        self.descr = descr
        # upgrades must be ordered in case several act on the same item
        self.upgrades = OrderedDict()

    def deprecate(self, vn, oldkeys, newkeys=None, cvtr=None, silent=False):
        if vn not in self.upgrades:
            self.upgrades[vn] = []
        if cvtr is None:
            cvtr = converter(lambda x: x, "value unchanged")  # identity
        self.upgrades[vn].append(
            {'old': oldkeys, 'new': newkeys, 'cvt': cvtr, 'silent': silent})

    def obsolete(self, vn, oldkeys, newkeys=None, silent=False):
        if vn not in self.upgrades:
            self.upgrades[vn] = []
        cvtr = converter(lambda x: x, "DELETED (OBSOLETE)")  # identity
        self.upgrades[vn].append(
            {'old': oldkeys, 'new': newkeys, 'cvt': cvtr, 'silent': silent})

    def get_item(self, keys):
        item = self.cfg
        for key in keys:
            item = item[key]
        return item

    def put_item(self, keys, val):
        item = self.cfg
        for key in keys[:-1]:
            if key not in item:
                item[key] = {}
            item = item[key]
        item[keys[-1]] = val

    def del_item(self, keys):
        item = self.cfg
        for key in keys[:-1]:
            item = item[key]
        del item[keys[-1]]

    @staticmethod
    def show_keys(keys):
        return '[' + ']['.join(keys) + ']'

    def expand(self, upg):
        """Expands __MANY__ items."""
        if '__MANY__' not in upg['old']:
            return [upg]
        if upg['old'].count('__MANY__') > 1:
            raise UpgradeError(
                'Multiple simultaneous __MANY__ not supported: %s' %
                upg['old'])
        exp_upgs = []
        pre = []
        post = []
        many = []
        i = -1
        okeys = upg['old']
        for k in okeys:
            i += 1
            if k == "__MANY__":
                pre = okeys[:i]
                post = okeys[i + 1:]
                tmp = self.cfg
                for j in pre:
                    tmp = tmp[j]
                many = list(tmp.keys())
                break
        if not many:
            exp_upgs.append(upg)
        else:
            i = -1
            nkeys = upg['new']
            if nkeys is None:  # No new keys defined.
                for m in many:
                    exp_upgs.append({
                        'old': pre + [m] + post,
                        'new': None,
                        'cvt': upg['cvt'],
                        'silent': upg['silent'],
                    })
                return exp_upgs
            npre = []
            npost = []
            for k in nkeys:
                i += 1
                if k == "__MANY__":
                    npre = nkeys[:i]
                    npost = nkeys[i + 1:]
            if not npre or not npost:
                raise UpgradeError('__MANY__ mismatch')
            for m in many:
                exp_upgs.append({
                    'old': pre + [m] + post,
                    'new': npre + [m] + npost,
                    'cvt': upg['cvt'],
                    'silent': upg['silent'],
                })
        return exp_upgs

    def upgrade(self):
        warnings = OrderedDict()
        for vn, upgs in self.upgrades.items():
            for u in upgs:
                try:
                    exp = self.expand(u)
                except (KeyError, UpgradeError):
                    continue

                for upg in exp:
                    try:
                        old = self.get_item(upg['old'])
                    except KeyError:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        if not upg['silent']:
                            warnings.setdefault(vn, [])
                            warnings[vn].append(msg)
                        self.del_item(upg['old'])
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item(upg['new'], upg['cvt'].convert(old))
        if warnings:
            level = WARNING
            if self.descr == self.SITE_CONFIG:
                # Site level configuration, user cannot easily fix.
                # Only log at debug level.
                level = DEBUG
            else:
                # User level configuration, user should be able to fix.
                # Log at warning level.
                level = WARNING
            LOG.log(
                level,
                "deprecated items were automatically upgraded in '%s':",
                self.descr)
            for vn, msgs in warnings.items():
                for msg in msgs:
                    LOG.log(level, ' * (%s) %s', vn, msg)
示例#16
0
class upgrader(object):
    """Handles upgrading of deprecated config values."""

    SITE_CONFIG = 'site config'
    USER_CONFIG = 'user config'

    def __init__(self, cfg, descr):
        """Store the config dict to be upgraded if necessary."""
        self.cfg = cfg
        self.descr = descr
        # upgrades must be ordered in case several act on the same item
        self.upgrades = OrderedDict()

    def deprecate(self, vn, oldkeys, newkeys=None, cvtr=None, silent=False):
        if vn not in self.upgrades:
            self.upgrades[vn] = []
        if cvtr is None:
            cvtr = converter(lambda x: x, "value unchanged")  # identity
        self.upgrades[vn].append({
            'old': oldkeys,
            'new': newkeys,
            'cvt': cvtr,
            'silent': silent
        })

    def obsolete(self, vn, oldkeys, newkeys=None, silent=False):
        if vn not in self.upgrades:
            self.upgrades[vn] = []
        cvtr = converter(lambda x: x, "DELETED (OBSOLETE)")  # identity
        self.upgrades[vn].append({
            'old': oldkeys,
            'new': newkeys,
            'cvt': cvtr,
            'silent': silent
        })

    def get_item(self, keys):
        item = self.cfg
        for key in keys:
            item = item[key]
        return item

    def put_item(self, keys, val):
        item = self.cfg
        for key in keys[:-1]:
            if key not in item:
                item[key] = {}
            item = item[key]
        item[keys[-1]] = val

    def del_item(self, keys):
        item = self.cfg
        for key in keys[:-1]:
            item = item[key]
        del item[keys[-1]]

    @staticmethod
    def show_keys(keys):
        return '[' + ']['.join(keys) + ']'

    def expand(self, upg):
        """Expands __MANY__ items."""
        if '__MANY__' not in upg['old']:
            return [upg]
        if upg['old'].count('__MANY__') > 1:
            raise UpgradeError(
                'Multiple simultaneous __MANY__ not supported: %s' %
                upg['old'])
        exp_upgs = []
        pre = []
        post = []
        many = []
        i = -1
        okeys = upg['old']
        for k in okeys:
            i += 1
            if k == "__MANY__":
                pre = okeys[:i]
                post = okeys[i + 1:]
                tmp = self.cfg
                for j in pre:
                    tmp = tmp[j]
                many = list(tmp.keys())
                break
        if not many:
            exp_upgs.append(upg)
        else:
            i = -1
            nkeys = upg['new']
            if nkeys is None:  # No new keys defined.
                for m in many:
                    exp_upgs.append({
                        'old': pre + [m] + post,
                        'new': None,
                        'cvt': upg['cvt'],
                        'silent': upg['silent'],
                    })
                return exp_upgs
            npre = []
            npost = []
            for k in nkeys:
                i += 1
                if k == "__MANY__":
                    npre = nkeys[:i]
                    npost = nkeys[i + 1:]
            if not npre or not npost:
                raise UpgradeError('ERROR: __MANY__ mismatch')
            for m in many:
                exp_upgs.append({
                    'old': pre + [m] + post,
                    'new': npre + [m] + npost,
                    'cvt': upg['cvt'],
                    'silent': upg['silent'],
                })
        return exp_upgs

    def upgrade(self):
        warnings = OrderedDict()
        for vn, upgs in self.upgrades.items():
            for u in upgs:
                try:
                    exp = self.expand(u)
                except (KeyError, UpgradeError):
                    continue

                for upg in exp:
                    try:
                        old = self.get_item(upg['old'])
                    except KeyError:
                        # OK: deprecated item not found
                        pass
                    else:
                        msg = self.show_keys(upg['old'])
                        if upg['new']:
                            msg += ' -> ' + self.show_keys(upg['new'])
                        else:
                            upg['new'] = upg['old']
                        msg += " - " + upg['cvt'].describe()
                        if not upg['silent']:
                            warnings.setdefault(vn, [])
                            warnings[vn].append(msg)
                        self.del_item(upg['old'])
                        if upg['cvt'].describe() != "DELETED (OBSOLETE)":
                            self.put_item(upg['new'], upg['cvt'].convert(old))
        if warnings:
            level = WARNING
            if self.descr == self.SITE_CONFIG:
                # Site level configuration, user cannot easily fix.
                # Only log at debug level.
                level = DEBUG
            else:
                # User level configuration, user should be able to fix.
                # Log at warning level.
                level = WARNING
            LOG.log(level,
                    "deprecated items were automatically upgraded in '%s':",
                    self.descr)
            for vn, msgs in warnings.items():
                for msg in msgs:
                    LOG.log(level, ' * (%s) %s', vn, msg)