Source code for pyfarm.models.core.functions

# No shebang line, this module is meant to be imported
#
# Copyright 2013 Oliver Palmer
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


"""
Functions
=========

Contains core functions and data for use by :mod:`pyfarm.models`
"""

from uuid import UUID
from datetime import datetime
from textwrap import dedent

from pyfarm.core.enums import STRING_TYPES
from pyfarm.master.application import db
from pyfarm.master.config import config
from pyfarm.models.core.types import (
    id_column, IDTypeWork, IPAddress, WorkStateEnum)

DEFAULT_PRIORITY = config.get("queue_default_priority")


[docs]def modelfor(model, table): """ Returns True if the given `model` object is for the expected `table`. >>> from pyfarm.master.config import config >>> from pyfarm.models.agent import Agent >>> modelfor(Agent("foo", "10.56.0.0", "255.0.0.0"), config.get("table_agent")) True """ try: return model.__tablename__ == table except AttributeError: return False
[docs]def getuuid(value, table, table_attrib, error_tail): """ Returns the proper value for the given input. Depending on the type being provided this will return one of the following: * None * the value from an attribute * string from a UUID * the original value (after validating it's a UUID) :arg string value: the value to validate and returning data from :arg string table: the table which the provided `value` belongs to :arg string table_attrib: the attribute to use when attempting to pull data off of a model object :arg string error_tail: added to the end of error messages :arg str error_text: error text to render in the event of problems :exception ValueError: raised when the provided input is invalid, blank, or otherwise unexpected """ if value is None: return value elif modelfor(value, table): value = getattr(value, table_attrib, None) if value is None: raise ValueError("null id provided for %s" % error_tail) return value # if a string was provided then we should # try to convert it into a uuid first to # be sure it's valid elif isinstance(value, STRING_TYPES): UUID(value) return value elif isinstance(value, UUID): return str(value) else: raise ValueError("failed to determine %s" % error_tail)
[docs]def work_columns(state_default, priority_default): """ Produces some default columns which are used by models which produce work. """ return ( # id id_column(IDTypeWork), # state db.Column(WorkStateEnum, default=state_default, doc=dedent(""" The state of the job with a value provided by :class:`.WorkState`""")), # priority db.Column(db.Integer, default=DEFAULT_PRIORITY, doc=dedent(""" The priority of the job relative to others in the queue. This is not the same as task priority. **configured by**: `%s`""" % priority_default)), # time_submitted db.Column(db.DateTime, default=datetime.utcnow, doc=dedent(""" The time the job was submitted. By default this defaults to using :meth:`datetime.datetime.utcnow` as the source of submission time. This value will not be set more than once and will not change even after a job is requeued.""")), # time_started db.Column(db.DateTime, doc=dedent(""" The time this job was started. By default this value is set when :attr:`state` is changed to an appropriate value or when a job is requeued.""")), # time_finished db.Column(db.DateTime, doc=dedent(""" Time the job was finished. This will be set when the last task finishes and reset if a job is requeued.""")) )
[docs]def split_and_extend(items): """ Takes a list of input elements and splits them before producing an extended set. **Example** >>> split_and_extend(["root.admin", "admin"]) set(['admin', 'root.admin', 'root']) """ if not items: return items output = set() for item in items: current = [] for split_item in item.split("."): current = current + [split_item] output.add(".".join(current)) return output
[docs]def repr_ip(value): """properly formats an :class:`.IPAddress` object""" if isinstance(value, IPAddress): value = value.format() return repr(value)
[docs]def repr_enum(value, enum=None): """produces the string representation of an enum value""" assert enum is not None, "`enum` required" for key, value in enum._asdict().iteritems(): if value == value: return repr(key) raise KeyError( "%s does not map to a key in %s" % (repr(value), enum.__class__))