def attach_list(func): @wraps(func) def inner_decorator(*args, **kwargs): return func(*args, **kwargs) _values = values # Allow for single iterable argument as well as *args if len(_values) == 1 and not isinstance(_values[0], basestring): _values = _values[0] setattr(inner_decorator, attribute, list(_values)) # Don't replace @task new-style task objects with inner_decorator by # itself -- wrap in a new Task object first. inner_decorator = _wrap_as_new(func, inner_decorator) return inner_decorator
def notify(func): '''Notification decorator. To use, simply apply @notify to the fabric task method. ''' # Argument formatting copied from: http://wordaligned.org/articles/echo code = func.func_code # Func's code obj in bytecode arg_count = code.co_argcount # Number of arguments arg_names = code.co_varnames[:arg_count] # Name of each argument fn_defaults = func.func_defaults or list() # Default value of keyword argument # Groups default arguments name and its value arg_defs = dict(zip(arg_names[-len(fn_defaults):], fn_defaults)) # The implementation pattern here is based off the @runs_once decorator implementation @wraps(func) def wrapped(*v, **k): # Only send notificationonce per host if not hasattr(notify, 'notified_hosts'): notify.notified_hosts = set([]) # Define set # If env.host is not in notify.notified_hosts, we send notifications send_notification = env.host not in notify.notified_hosts # Add host into notified_hosts notify.notified_hosts.add(env.host) if send_notification: positional = map(_format_arg_value, zip(arg_names, v)) defaulted = [_format_arg_value((a, arg_defs[a])) for a in arg_names[len(v):] if a not in k] nameless = map(repr, v[arg_count:]) keyword = map(_format_arg_value, k.items()) args = positional + defaulted + nameless + keyword # The prefix used for notifications: easter_msg = easter() prefix = '[{}] - {} [{}] {}.{}({})'.format( easter_msg, datetime.strftime(datetime.now(), '%Y.%m.%d %H:%M:%S'), None if env.host is None else env.host.replace('.lixu.ca', ''), func.__module__.replace('fabfile.', ''), func.func_name, ','.join(args) ) send_notifications('{}'.format(prefix)) try: # Now actually invoke it return func(*v, **k) except BaseException as e: if send_notification: send_notifications("{}\nFAILED! {} {}".format(prefix, e.__class__.__name__, e)) raise return _wrap_as_new(func, wrapped)
def attach_list(func): @wraps(func) def inner_decorator(*args, **kwargs): return func(*args, **kwargs) _values = values # Allow for single iterable argument as well as *args if len(_values) == 1 and not isinstance(_values[0], str): _values = _values[0] setattr(inner_decorator, attribute, list(_values)) # Don't replace @task new-style task objects with inner_decorator by # itself -- wrap in a new Task object first. inner_decorator = _wrap_as_new(func, inner_decorator) return inner_decorator
def outer(func): @wraps(func) def inner(*args, **kwargs): if instanceid: instancewrapper = Ec2InstanceWrapper.get_by_instanceid(instanceid) elif nametag: instancewrapper = Ec2InstanceWrapper.get_by_nametag(nametag) else: raise ValueError('nametag or instanceid must be supplied.') state_name = instancewrapper['state'] if not state_name == 'running': prettyname = instancewrapper.prettyname() abort('Instance, {prettyname}, is not running. (Current state={state_name})'.format(**vars())) ssh_uri = instancewrapper.get_ssh_uri() key_filename = instancewrapper.get_ssh_key_filename() with settings(key_filename=key_filename, host_string=ssh_uri): return func(*args, **kwargs) return _wrap_as_new(func, inner)