class TermProtocol(protocol.ProcessProtocol): logger = log.Logger() def __init__(self): self.out = [] self.err = [] def connectionMade(self): self.transport.closeStdin() def outReceived(self, data): self.out.append(data) def errReceived(self, data): self.err.append(data) def processEnded(self, status): if isinstance(status.value, error.ProcessTerminated): self.logger.error(console_terminated, status=status.value, out=lambda: "".join(self.out), err=lambda: "".join(self.err)) else: self.logger.info(console_done, status=status.value)
class Plug: sock = None _antiloop = False mode = "vde" logger = log.Logger() model = "" mac = "" def __init__(self, brick): self.brick = brick def configured(self): return self.sock is not None def connected(self): if self._antiloop: if settings.get("erroronloop"): self.logger.error(link_loop) self._antiloop = False return defer.fail(errors.LinkLoopError()) self._antiloop = True if self.sock is None or self.sock.brick is None: self._antiloop = False return defer.fail(errors.NotConnectedError()) # special case where a brick (vm) is plugged to itself: # brick -> plug -> sock <- brick if self.sock.brick is self.brick: self._antiloop = False return defer.succeed(self.brick) def clear_antiloop(passthru): self._antiloop = False return passthru d = self.sock.brick.poweron() d.addBoth(clear_antiloop) return d def connect(self, sock): assert sock is not None, "Cannot connect a plug to nothing" sock.plugs.append(self) self.sock = sock def disconnect(self): assert self.sock is not None, "Plug not connected" assert self in self.sock.plugs, \ "sock %r has not reference to %r" % (self.sock, self) self.sock.plugs.remove(self) self.sock = None def save_to(self, fileobj): tmp = "link|{0.brick.name}|{1}|{0.model}|{0.mac}\n" fileobj.write(tmp.format(self, self.sock.nickname if self.configured() else ""))
class Process(protocol.ProcessProtocol): logger = ProcessLogger(log.Logger()) debug = True debug_child = True def __init__(self, brick): self.brick = brick def connectionMade(self): self.logger.info(process_started) self.brick.process_started(self) def processEnded(self, status): if status.check(error.ProcessTerminated): self.logger.error(process_terminated, status=lambda: " ".join(status.value.args)) else: assert status.check(error.ProcessDone) self.logger.info(process_terminated, status=lambda: "") self.brick.process_ended(self, status) def outReceived(self, data): self.logger.info(data) def errReceived(self, data): self.logger.error(data, hide_to_user=True) # new interface @property def pid(self): return self.transport.pid def signal_process(self, signalID): self.transport.signalProcess(signalID) def write(self, data): self.transport.write(data)
import os import sys import errno from pathlib import Path import random import re import functools import tempfile import struct from virtualbricks import log from twisted.internet import utils from twisted.python import constants logger = log.Logger() ksm_error = log.Event("Can not change ksm state. (failed command: {cmd})") def random_mac(): random.seed() return "00:aa:{0:02x}:{1:02x}:{2:02x}:{3:02x}".format( random.getrandbits(8), random.getrandbits(8), random.getrandbits(8), random.getrandbits(8)) RandMac = random_mac MAC_RE = re.compile(r"^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$") def mac_is_valid(mac): return bool(MAC_RE.match(mac))
class Base(object): _restore = False # type = None # if not set in a subclass will raise an AttributeError _name = None config_factory = Config logger = log.Logger() def get_name(self): return self._name getname = get_name def set_name(self, name): self._name = name self.notify_changed() name = property(get_name, set_name) def __init__(self, factory, name): self._observable = observable.Observable("changed") self.changed = observable.Event(self._observable, "changed") self.factory = factory self._name = name self.config = self.config_factory() def get_type(self): return self.type def needsudo(self): return False def set(self, attrs): iterFixItemAttrs(self, attrs) def get(self, name): try: return self.config[name] except KeyError: raise KeyError( _("%s config has no %s option.") % (self.name, name)) def _getvalue(self, name, value): try: return self.config.parameters[name].from_string_brick(value, self) except KeyError: logger.error(param_not_found, param=name, brick=self, value=value) raise def load_from(self, section): self.set(dict((n, self._getvalue(n, v)) for n, v in section)) def save_to(self, fileobj): iterFixSave(self, fileobj) def rename(self, name): self.set_name(self.factory.normalize_name(name)) def set_restore(self, restore): self._restore = restore def notify_changed(self): if not self._restore: self._observable.notify("changed", self) def __format__(self, format_string): if format_string == "": return repr(self) elif format_string == "s": return self.get_state() elif format_string == "t": return self.get_type() elif format_string == "n": return self.name elif format_string == "p": return self.get_parameters() raise ValueError("Invalid format string %r" % (format_string, ))
from virtualbricks import base, errors, settings, log, interfaces from virtualbricks.base import (Config as _Config, Parameter, String, Integer, SpinInt, Float, SpinFloat, Boolean, Object, ListOf) from virtualbricks._spawn import abspath_vde __all__ = [ "Brick", "Config", "Parameter", "String", "Integer", "SpinInt", "Float", "SpinFloat", "Boolean", "Object", "ListOf" ] if False: # pyflakes _ = str logger = log.Logger(__name__) process_started = log.Event("Process started") process_terminated = log.Event("Process terminated. {status()}") process_done = log.Event("Process terminated") event_unavailable = log.Event("Warning. The Event {name} attached to Brick " "{brick} is not available. Skipping execution.") shutdown_brick = log.Event("Shutting down {name} (pid: {pid})") start_brick = log.Event("Starting: {args()}") open_console = log.Event("Opening console for {name}\n%{args()}\n") console_done = log.Event("Console terminated\n{status}") console_terminated = log.Event("Console terminated\n{status}\nProcess stdout:" "\n{out()}\nProcess stderr:\n{err()}\n") invalid_ack = log.Event("ACK received but no command sent.") class ProcessLogger(object):
class Base(object): _restore = False # type = None # if not set in a subclass will raise an AttributeError _name = None config_factory = Config logger = log.Logger() def get_name(self): return self._name getname = get_name def set_name(self, name): self._name = name self.notify_changed() name = property(get_name, set_name) def __init__(self, factory, name): self._observable = observable.Observable("changed") self.changed = observable.Event(self._observable, "changed") self.factory = factory self._name = name self.config = self.config_factory() def get_type(self): return self.type def needsudo(self): return False def set(self, attrs): for name, value in attrs.iteritems(): if value != self.config[name]: logger.info(attribute_set, attr=name, brick=self, value=value) self.config[name] = value setter = getattr(self, "cbset_" + name, None) if setter: setter(value) self.notify_changed() def get(self, name): try: return self.config[name] except KeyError: raise KeyError( _("%s config has no %s option.") % (self.name, name)) def _getvalue(self, name, value): try: return self.config.parameters[name].from_string_brick(value, self) except KeyError: logger.error(param_not_found, param=name, brick=self, value=value) raise def load_from(self, section): self.set(dict((n, self._getvalue(n, v)) for n, v in section)) def save_to(self, fileobj): opt_tmp = "{0}={1}" l = [] for name, param in sorted(self.config.parameters.iteritems()): if self.config[name] != param.default: value = param.to_string_brick(self.config[name], self) l.append(opt_tmp.format(name, value)) if l: l.append("") tmp = "[{0}:{1}]\n{2}\n" fileobj.write(tmp.format(self.get_type(), self.name, "\n".join(l))) def rename(self, name): self.set_name(self.factory.normalize_name(name)) def set_restore(self, restore): self._restore = restore def notify_changed(self): if not self._restore: self._observable.notify("changed", self) def __format__(self, format_string): if format_string == "": return repr(self) elif format_string == "s": return self.get_state() elif format_string == "t": return self.get_type() elif format_string == "n": return self.name elif format_string == "p": return self.get_parameters() raise ValueError("Invalid format string %r" % (format_string, ))