Exemple #1
0
 def eliot_action(self):
     return ActionType(
         u"flocker:test:broken_action",
         [], [],
         u"An action used by tests for handling of broken IStateChange "
         u"implementations.",
     )()
Exemple #2
0
    def test_cross_process_logging(self, logger):
        """
        Eliot tasks can be traced from the HTTP client to the API server.
        """
        self.patch(rest_api, "_logger", logger)
        my_action = ActionType("my_action", [], [])
        with my_action():
            d = self.client.create_dataset(primary=self.node_1)

        def got_response(_):
            parent = LoggedAction.ofType(logger.messages, my_action)[0]
            child = LoggedAction.ofType(logger.messages, JSON_REQUEST)[0]
            self.assertIn(child, list(parent.descendants()))
        d.addCallback(got_response)
        return d
Exemple #3
0
    def test_serialized_task(self, logger):
        """
        If the ``X-Eliot-Task-Id`` header containers a serialized task level,
        it is used as a parent of the logged actions from the handler.
        """
        parent = ActionType("parent", [], [])
        with parent() as context:
            task_id = context.serialize_task_id()

        app = self.Application()
        app.logger = logger
        request = dummyRequest(
            b"GET", b"/foo/bar", Headers({b"X-Eliot-Task-Id": [task_id]}), b"")
        render(app.app.resource(), request)

        logged_parent = LoggedAction.ofType(logger.messages, parent)[0]
        child = _assertRequestLogged(b"/foo/bar")(self, logger)
        self.assertIn(child, logged_parent.descendants())
Exemple #4
0
            result = run_process([executable] + [b"--help"])
            self.assertIn(executable, result.output)

    return ScriptTests


class CustomException(Exception):
    """
    An exception that will never be raised by real code, useful for
    testing.
    """


TWISTED_CHILD_PROCESS_ACTION = ActionType(
    u'flocker:testtools:logged_run_process',
    fields(command=list),
    [],
    u'A child process is spawned using Twisted',
)

STDOUT_RECEIVED = MessageType(
    u'flocker:testtools:logged_run_process:stdout',
    fields(output=str),
    u'A chunk of stdout received from a child process',
)

STDERR_RECEIVED = MessageType(
    u'flocker:testtools:logged_run_process:stdout',
    fields(output=str),
    u'A chunk of stderr received from a child process',
)
Exemple #5
0
    """
    def is_in_states(units):
        for unit in units:
            if unit.name == unit_name:
                if unit.activation_state in expected_activation_states:
                    return True

    def check_if_in_states():
        responded = docker_client.list()
        responded.addCallback(is_in_states)
        return responded

    return loop_until(reactor, check_if_in_states)


CONTROLLABLE_ACTION_TYPE = ActionType(u"test:controllableaction", [], [])


@implementer(IStateChange)
@attributes(['result'])
class ControllableAction(object):
    """
    ``IStateChange`` whose results can be controlled.
    """
    called = False
    deployer = None
    state_persister = None

    _logger = Logger()

    @property
Exemple #6
0
# storage drivers.

# An OPERATION is a list of:
# IBlockDeviceAPI name, positional arguments, keyword arguments.
OPERATION = Field.for_types(
    u"operation", [list], u"The IBlockDeviceAPI operation being executed,"
    u"along with positional and keyword arguments.")

# End: Common structures used by all storage drivers.

# Begin: Helper datastructures to log IBlockDeviceAPI calls
# from AWS storage driver using Eliot.

# ActionType used by AWS storage driver.
AWS_ACTION = ActionType(
    u"flocker:node:agents:blockdevice:aws", [OPERATION], [],
    u"An IBlockDeviceAPI operation is executing using AWS storage driver.")

# Three fields to gather from EC2 response to Boto.
AWS_CODE = Field.for_types("aws_code", [bytes, unicode],
                           u"The error response code.")
AWS_MESSAGE = Field.for_types(
    "aws_message",
    [unicode],
    u"A human-readable error message given by the response.",
)
AWS_REQUEST_ID = Field.for_types(
    "aws_request_id",
    [bytes, unicode],
    u"The unique identifier assigned by the server for this request.",
)
Exemple #7
0
 def make_action_type(self, action_type):
     """
     Eliot makes it tricky to create ``ActionType`` objects. Here's a
     helper to declutter our tests.
     """
     return ActionType(action_type, [], [])
Exemple #8
0
BLOCK_DEVICE_ID = Field(
    u"block_device_id", lambda id: unicode(id),
    u"The unique identifier if the underlying block device.")

BLOCK_DEVICE_SIZE = Field(u"block_device_size", identity,
                          u"The size of the underlying block device.")

BLOCK_DEVICE_HOST = Field(
    u"block_device_host", identity,
    u"The host to which the underlying block device is attached.")

CREATE_BLOCK_DEVICE_DATASET = ActionType(
    u"agent:blockdevice:create",
    [DATASET, MOUNTPOINT],
    [
        DEVICE_PATH, BLOCK_DEVICE_ID, DATASET_ID, BLOCK_DEVICE_SIZE,
        BLOCK_DEVICE_HOST
    ],
    u"A block-device-backed dataset is being created.",
)

DESTROY_BLOCK_DEVICE_DATASET = ActionType(
    u"agent:blockdevice:destroy",
    [DATASET_ID],
    [],
    u"A block-device-backed dataset is being destroyed.",
)

UNMOUNT_BLOCK_DEVICE = ActionType(
    u"agent:blockdevice:unmount",
    [VOLUME],
Exemple #9
0
        return {
            "function": str(function),
            "file": getfile(function),
            "line": getsourcelines(function)[1]
        }
    except IOError:
        # One debugging method involves changing .py files and is incompatible
        # with inspecting the source.
        return {
            "function": str(function),
        }


LOOP_UNTIL_ACTION = ActionType(
    action_type="flocker:testtools:loop_until",
    startFields=[Field("predicate", function_serializer)],
    successFields=[Field("result", serializer=safe_repr)],
    description="Looping until predicate is true.")

LOOP_UNTIL_ITERATION_MESSAGE = MessageType(
    message_type="flocker:testtools:loop_until:iteration",
    fields=[Field("result", serializer=safe_repr)],
    description="Predicate failed, trying again.")


def loop_until(predicate, reactor=reactor):
    """Call predicate every 0.1 seconds, until it returns something ``Truthy``.

    :param predicate: Callable returning termination condition.
    :type predicate: 0-argument callable returning a Deferred.
Exemple #10
0
# Copyright ClusterHQ Inc.  See LICENSE file for details.
"""
This module defines the Eliot log events emitted by the API implementation.
"""

from eliot import Field, ActionType

__all__ = [
    "REQUEST",
]

LOG_SYSTEM = u"api"

METHOD = Field(u"method", lambda method: method,
               u"The HTTP method of the request.")
REQUEST_PATH = Field(
    u"request_path", lambda path: path,
    u"The absolute path of the resource to which the request was issued.")
JSON = Field.forTypes(u"json", [unicode, bytes, dict, list, None, bool, float],
                      u"The JSON request body.")
RESPONSE_CODE = Field.forTypes(u"code", [int],
                               u"The response code for the request.")

# It would be nice if RESPONSE_CODE was in REQUEST; see FLOC-1586.
REQUEST = ActionType(LOG_SYSTEM + u":request", [REQUEST_PATH, METHOD], [],
                     u"A request was received on the public HTTP interface.")
Exemple #11
0
)
from twisted.internet.utils import getProcessOutput
from twisted.internet.task import deferLater

from treq import json_content, content

from ..ca import treq_with_authentication
from ..control import Leases as LeasesModel, LeaseError, DockerImage
from ..common import retry_failure

from .. import __version__

_LOG_HTTP_REQUEST = ActionType("flocker:apiclient:http_request", [
    Field.forTypes("url", [bytes, unicode], "Request URL."),
    Field.forTypes("method", [bytes, unicode], "Request method."),
    Field("request_body", lambda o: o, "Request JSON body.")
], [
    Field.forTypes("response_code", [int], "Response code."),
    Field("response_body", lambda o: o, "JSON response body.")
], "A HTTP request.")

_LOG_CONDITIONAL_CREATE = ActionType(u"flocker:apiclient:conditional_create",
                                     [], [],
                                     u"Conditionally create a dataset.")

NoneType = type(None)


class ServerResponseMissingElementError(Exception):
    """
    Output the invalid server response if a response does not contain an
    expected JSON object attribute.
Exemple #12
0
PRIVACYPASS_MESSAGE = Field(
    u"message",
    unicode,
    u"The PrivacyPass request-binding data associated with a pass.",
)

PASS_COUNT = Field(
    u"count",
    int,
    u"A number of passes.",
)

GET_PASSES = MessageType(
    u"zkapauthorizer:get-passes",
    [PRIVACYPASS_MESSAGE, PASS_COUNT],
    u"Passes are being spent.",
)

SIGNATURE_CHECK_FAILED = MessageType(
    u"zkapauthorizer:storage-client:signature-check-failed",
    [PASS_COUNT],
    u"Some passes the client tried to use were rejected for having invalid signatures.",
)

CALL_WITH_PASSES = ActionType(
    u"zkapauthorizer:storage-client:call-with-passes",
    [PASS_COUNT],
    [],
    u"A storage operation is being started which may spend some passes.",
)
Exemple #13
0
from pipes import quote as shell_quote

from characteristic import attributes
from eliot import MessageType, ActionType, Field
from eliot.twisted import DeferredContext

from twisted.python.failure import Failure
from twisted.internet.error import ProcessTerminated, ProcessDone
from twisted.internet.defer import Deferred
from twisted.internet.protocol import ProcessProtocol

from twisted.protocols.basic import LineOnlyReceiver

RUN_ACTION = ActionType(
    action_type="flocker.common.runner:run",
    startFields=[Field.for_types(u"command", [list], u"The command.")],
    successFields=[],
    description="Run a command.",
)
RUN_OUTPUT_MESSAGE = MessageType(
    message_type="flocker.common.runner:run:stdout",
    fields=[
        Field.for_types(u"line", [bytes], u"The output."),
    ],
    description=u"A line of command output.",
)
RUN_ERROR_MESSAGE = MessageType(
    message_type="flocker.common.runner:run:stderr",
    fields=[
        Field.for_types(u"line", [bytes], u"The error."),
    ],
    description=u"A line of command stderr.",
Exemple #14
0
        "last_downloaded_timestamp": v.last_downloaded_timestamp,
    },
    u"The local database state of a file.",
    validateInstanceOf((type(None), PathEntry)),
)

_INSERT_OR_UPDATE = Field.for_types(
    u"insert_or_update",
    [unicode],
    u"An indication of whether the record for this upload was new or an update to a previous entry.",
    validateSetMembership({u"insert", u"update"}),
)

UPDATE_ENTRY = ActionType(
    u"magic-folder-db:update-entry",
    [RELPATH, VERSION, LAST_UPLOADED_URI, LAST_DOWNLOADED_URI, LAST_DOWNLOADED_TIMESTAMP, PATHINFO],
    [_INSERT_OR_UPDATE],
    u"Record some metadata about a relative path in the magic-folder.",
)


# magic-folder db schema version 1
SCHEMA_v1 = """
CREATE TABLE version
(
 version INTEGER  -- contains one row, set to 1
);

CREATE TABLE local_files
(
 path                VARCHAR(1024) PRIMARY KEY,   -- UTF-8 filename relative to local magic folder dir
 size                INTEGER,                     -- ST_SIZE, or NULL if the file has been deleted
Exemple #15
0
    service_factory = AgentServiceFactory(
        deployer_factory=deployer_factory).get_service
    agent_script = AgentScript(service_factory=service_factory)

    # Use CPU time instead of wallclock time.
    pr = cProfile.Profile(clock)

    signal.signal(signal.SIGUSR1, partial(enable_profiling, pr))
    signal.signal(signal.SIGUSR2, partial(disable_profiling, pr, 'container'))

    return FlockerScriptRunner(script=agent_script,
                               options=ContainerAgentOptions()).main()


LOG_GET_EXTERNAL_IP = ActionType(u"flocker:node:script:get_external_ip",
                                 fields(host=unicode, port=int),
                                 fields(local_ip=unicode),
                                 "An attempt to discover the local IP.")


def _get_external_ip(host, port):
    """
    Get an external IP address for this node that can in theory connect to
    the given host and port.

    Failures are retried until a successful connect.

    See https://clusterhq.atlassian.net/browse/FLOC-1751 for a possibly
    better solution.

    :param host: A host to connect to.
    :param port: The port to connect to.
Exemple #16
0
    # Schedule timeout for sleep so we don't sleep forever:
    SCHEDULE_WAKEUP = NamedConstant()
    # Clear/cancel the sleep wakeup timeout:
    CLEAR_WAKEUP = NamedConstant()
    # Check if we need to wakeup due to update from AMP client:
    UPDATE_MAYBE_WAKEUP = NamedConstant()


_FIELD_CONNECTION = Field(u"connection", repr,
                          u"The AMP connection to control service")

_FIELD_LOCAL_CHANGES = Field(u"local_changes", to_unserialized_json,
                             u"Changes discovered in local state.")

LOG_SEND_TO_CONTROL_SERVICE = ActionType(
    u"flocker:agent:send_to_control_service",
    [_FIELD_CONNECTION, _FIELD_LOCAL_CHANGES], [],
    u"Send the local state to the control service.")

_FIELD_CLUSTERSTATE = Field(
    u"cluster_state", to_unserialized_json,
    u"The state of the cluster, according to control service.")

_FIELD_CONFIGURATION = Field(
    u"desired_configuration", to_unserialized_json,
    u"The configuration of the cluster according to the control service.")

_FIELD_ACTIONS = Field(
    u"calculated_actions", repr,
    u"The actions we decided to take to converge with configuration.")

LOG_CONVERGE = ActionType(u"flocker:agent:converge",
Exemple #17
0
        elif class_name == u"UUID":
            return UUID(dictionary[u"hex"])
        elif class_name in _CONFIG_CLASS_MAP:
            dictionary = dictionary.copy()
            dictionary.pop(_CLASS_MARKER)
            return _CONFIG_CLASS_MAP[class_name].create(dictionary)
        else:
            return dictionary

    return loads(data, object_hook=decode)


_DEPLOYMENT_FIELD = Field(u"configuration", repr)
_LOG_STARTUP = MessageType(u"flocker-control:persistence:startup",
                           [_DEPLOYMENT_FIELD])
_LOG_SAVE = ActionType(u"flocker-control:persistence:save",
                       [_DEPLOYMENT_FIELD], [])

_UPGRADE_SOURCE_FIELD = Field.for_types(
    u"source_version", [int], u"Configuration version to upgrade from.")
_UPGRADE_TARGET_FIELD = Field.for_types(
    u"target_version", [int], u"Configuration version to upgrade to.")
_LOG_UPGRADE = ActionType(u"flocker-control:persistence:migrate_configuration",
                          [
                              _DEPLOYMENT_FIELD,
                              _UPGRADE_SOURCE_FIELD,
                              _UPGRADE_TARGET_FIELD,
                          ], [])


class LeaseService(Service):
    """
Exemple #18
0
class ConvergenceLoopOutputs(Names):
    """
    Converence loop FSM outputs.
    """
    # Store AMP client, desired configuration and cluster state for later
    # use:
    STORE_INFO = NamedConstant()
    # Start an iteration of the covergence loop:
    CONVERGE = NamedConstant()


_FIELD_CONNECTION = Field(u"connection", lambda client: repr(client),
                          "The AMP connection to control service")

LOG_SEND_TO_CONTROL_SERVICE = ActionType(
    u"flocker:agent:send_to_control_service", [_FIELD_CONNECTION], [],
    "Send the local state to the control service.")


class ConvergenceLoop(object):
    """
    World object for the convergence loop state machine, executing the actions
    indicated by the outputs from the state machine.

    :ivar AMP client: An AMP client connected to the control
        service. Initially ``None``.

    :ivar Deployment configuration: Desired cluster
        configuration. Initially ``None``.

    :ivar DeploymentState cluster_state: Actual cluster state.  Initially
Exemple #19
0
        """
        CREATE TABLE remote_snapshots
        (
            name          TEXT PRIMARY KEY, -- mangled name in UTF-8
            snapshot_cap  TEXT              -- Tahoe-LAFS URI that represents the remote snapshot
        )
        """,
    ]),
])

## XXX "parents_local" should be IDs of other local_snapshots, not
## sure how to do that w/o docs here

DELETE_SNAPSHOTS = ActionType(
    u"config:state-db:delete-local-snapshot-entry",
    [RELPATH],
    [],
    u"Delete the row corresponding to the given path from the local snapshot table.",
)

FETCH_REMOTE_SNAPSHOTS_FROM_DB = ActionType(
    u"config:state-db:get-remote-snapshot-entry",
    [RELPATH],
    [],
    u"Delete the row corresponding to the given path from the local snapshot table.",
)
_INSERT_OR_UPDATE = Field.for_types(
    u"insert_or_update",
    [unicode],
    u"An indication of whether the record for this upload was new or an update to a previous entry.",
    validateSetMembership({u"insert", u"update"}),
)
Exemple #20
0
        "ctime_ns": v.ctime_ns,
    },
    u"The metadata for this version of this file.",
    validateInstanceOf((type(None), PathInfo)),
)

INOTIFY_EVENTS = Field(
    u"inotify_events",
    humanReadableMask,
    u"Details about a filesystem event generating a notification event.",
    validateInstanceOf((int, long)),
)

MAYBE_NOTIFY = ActionType(
    u"filesystem:notification:maybe-notify",
    [],
    [],
    u"A filesystem event is being considered for dispatch to an application handler.",
)

CALLBACK = ActionType(
    u"filesystem:notification:callback", [INOTIFY_EVENTS], [],
    u"A filesystem event is being dispatched to an application callback.")


def eliot_logging_service(reactor, destinations):
    """
    Parse the given Eliot destination descriptions and return an ``IService``
    which will add them when started and remove them when stopped.

    See ``--help-eliot-destinations`` for details about supported
    destinations.
Exemple #21
0
)
from eliot.testing import capture_logging

from twisted.internet.defer import (
    maybeDeferred,
)

_NAME = Field.for_types(
    u"name",
    [unicode],
    u"The name of the test.",
)

RUN_TEST = ActionType(
    u"run-test",
    [_NAME],
    [],
    u"A test is run.",
)


def eliot_logged_test(f):
    """
    Decorate a test method to run in a dedicated Eliot action context.

    The action will finish after the test is done (after the returned Deferred
    fires, if a Deferred is returned).  It will note the name of the test
    being run.

    All messages emitted by the test will be validated.  They will still be
    delivered to the global logger.
    """
Exemple #22
0
METADATA = Field.for_types(
    u"metadata",
    [dict],
    u"Data about a node.",
)

OVERWRITE = Field.for_types(
    u"overwrite",
    [bool],
    u"True to replace an existing file of the same name, "
    u"false to fail with a collision error.",
)

ADD_FILE = ActionType(
    u"dirnode:add-file",
    [NAME, METADATA, OVERWRITE],
    [],
    u"Add a new file as a child of a directory.",
)

def update_metadata(metadata, new_metadata, now):
    """Updates 'metadata' in-place with the information in 'new_metadata'.

    Timestamps are set according to the time 'now'.
    """

    if metadata is None:
        metadata = {}

    old_ctime = None
    if 'ctime' in metadata:
        old_ctime = metadata['ctime']
Exemple #23
0
            The object provides ``IConvergenceAgent``.
            """
            agent = fixture(self)
            self.assertTrue(verifyObject(IConvergenceAgent, agent))

    return IConvergenceAgentTests


class FakeAgentInterfaceTests(
        iconvergence_agent_tests_factory(lambda test: FakeAgent())):
    """
    ``IConvergenceAgent`` tests for ``FakeAgent``.
    """


SEND_REQUEST = ActionType(u'test:send_request', [], [],
                          u'client makes request to server.')

HANDLE_REQUEST = ActionType(u'test:handle_request', [], [],
                            u'server receives request from client.')


class ClusterStatusCommandTests(TestCase):
    """
    Tests for ``ClusterStatusCommand``.
    """
    def test_command_arguments(self):
        """
        ClusterStatusCommand requires the following arguments.
        """
        self.assertItemsEqual(['configuration', 'state', 'eliot_context'],
                              (v[0] for v in ClusterStatusCommand.arguments))
Exemple #24
0
        if class_name == u"FilePath":
            return FilePath(dictionary.get(u"path").encode("utf-8"))
        elif class_name in classes:
            dictionary = dictionary.copy()
            dictionary.pop(_CLASS_MARKER)
            return classes[class_name].create(dictionary)
        else:
            return dictionary

    return loads(data, object_hook=decode_object)


_DEPLOYMENT_FIELD = Field(u"configuration", repr)
_LOG_STARTUP = MessageType(u"flocker-control:persistence:startup",
                           [_DEPLOYMENT_FIELD])
_LOG_SAVE = ActionType(u"flocker-control:persistence:save",
                       [_DEPLOYMENT_FIELD], [])


class ConfigurationPersistenceService(Service):
    """
    Persist configuration to disk, and load it back.

    :ivar Deployment _deployment: The current desired deployment configuration.
    """
    logger = Logger()

    def __init__(self, reactor, path):
        """
        :param reactor: Reactor to use for thread pool.
        :param FilePath path: Directory where desired deployment will be
            persisted.
Exemple #25
0
        }


class LoopExceeded(Exception):
    """
    Raised when ``loop_until`` looped too many times.
    """
    def __init__(self, predicate, last_result):
        super(LoopExceeded,
              self).__init__('%r never True in loop_until, last result: %r' %
                             (predicate, last_result))


LOOP_UNTIL_ACTION = ActionType(
    action_type="flocker:common:loop_until",
    startFields=[Field("predicate", function_serializer)],
    successFields=[Field("result", serializer=safe_repr)],
    description="Looping until predicate is true.")

LOOP_UNTIL_ITERATION_MESSAGE = MessageType(
    message_type="flocker:common:loop_until:iteration",
    fields=[Field("result", serializer=safe_repr)],
    description="Predicate failed, trying again.")


def loop_until(reactor, predicate, steps=None):
    """Repeatedly call ``predicate``, until it returns something ``Truthy``.

    :param reactor: The reactor implementation to use to delay.
    :type reactor: ``IReactorTime``.
Exemple #26
0
    """
    # Store AMP client, desired configuration and cluster state for later
    # use:
    STORE_INFO = NamedConstant()
    # Start an iteration of the covergence loop:
    CONVERGE = NamedConstant()


_FIELD_CONNECTION = Field(u"connection", lambda client: repr(client),
                          "The AMP connection to control service")

_FIELD_LOCAL_CHANGES = Field(u"local_changes", repr,
                             "Changes discovered in local state.")

LOG_SEND_TO_CONTROL_SERVICE = ActionType(
    u"flocker:agent:send_to_control_service",
    [_FIELD_CONNECTION, _FIELD_LOCAL_CHANGES], [],
    "Send the local state to the control service.")

_FIELD_CLUSTERSTATE = Field(
    u"cluster_state", repr,
    "The state of the cluster, according to control service.")

_FIELD_CONFIGURATION = Field(
    u"desired_configuration", repr,
    "The configuration of the cluster according to the control service.")

_FIELD_ACTIONS = Field(
    u"calculated_actions", repr,
    "The actions we decided to take to converge with configuration.")

LOG_CONVERGE = ActionType(u"flocker:agent:converge",
Exemple #27
0
# Copyright Hybrid Logic Ltd.  See LICENSE file for details.
"""
This module defines the Eliot log events emitted by the API implementation.
"""

__all__ = [
    "REQUEST_PATH",
    "REQUEST",
]

from eliot import Field, ActionType

LOG_SYSTEM = u"api"

REQUEST_PATH = Field.forTypes(
    u"request_path", [unicode],
    u"The absolute path of the resource to which the request was issued.")

REQUEST = ActionType(LOG_SYSTEM, [REQUEST_PATH], [],
                     u"A request was received on the public HTTP interface.")
Exemple #28
0
    def connectionLost(self, reason):
        AMP.connectionLost(self, reason)
        self.control_amp_service.disconnected(self)
        self._pinger.stop()


# These two logging fields use caching_wire_encode as the serializer so
# that they can share the encoding cache with the network code related to
# this logging.  This reduces the overhead of logging these (potentially
# quite large) data structures.
DEPLOYMENT_CONFIG = Field(u"configuration", caching_wire_encode,
                          u"The cluster configuration")
CLUSTER_STATE = Field(u"state", caching_wire_encode, u"The cluster state")

LOG_SEND_CLUSTER_STATE = ActionType(
    "flocker:controlservice:send_cluster_state", [],
    [DEPLOYMENT_CONFIG, CLUSTER_STATE],
    "Send the configuration and state of the cluster to all agents.")


def _serialize_agent(controlamp):
    """
    Serialize a connected ``ControlAMP`` to the address of its peer.

    :return: A string representation of the Twisted address object describing
        the remote address of the connection of the given protocol.

    :rtype str:
    """
    return str(controlamp.transport.getPeer())

Exemple #29
0
    :param change: Either an ``IStateChange`` provider or the result of an
        ``in_parallel`` or ``sequentially`` call.
    :param IDeployer deployer: The ``IDeployer`` to use.  Specific
        ``IStateChange`` providers may require specific ``IDeployer`` providers
        that provide relevant functionality for applying the change.

    :return: ``Deferred`` firing when the change is done.
    """
    with change.eliot_action.context():
        context = DeferredContext(maybeDeferred(change.run, deployer))
        context.addActionFinish()
        return context.result


LOG_SEQUENTIALLY = ActionType("flocker:node:sequentially", [], [])
LOG_IN_PARALLEL = ActionType("flocker:node:in_parallel", [], [])


@implementer(IStateChange)
class _InParallel(PClass):
    changes = field(
        type=PVector,
        # Sort the changes for the benefit of comparison.  Stick with a vector
        # (rather than, say, a set) in case someone wants to run the same
        # change multiple times in parallel.
        factory=lambda changes: pvector(sorted(changes, key=id)),
        mandatory=True)

    @property
    def eliot_action(self):
Exemple #30
0
)
from .snapshot import (
    LocalAuthor,
    LocalSnapshot,
    create_snapshot,
    write_snapshot_to_tahoe,
)
from .status import (
    FolderStatus, )
from .config import (
    MagicFolderConfig, )
from .util.file import get_pathinfo

SNAPSHOT_CREATOR_PROCESS_ITEM = ActionType(
    u"magic-folder:local-snapshot-creator:processing-item",
    [RELPATH],
    [],
    u"Local snapshot creator is processing an input.",
)
UPLOADER_SERVICE_UPLOAD_LOCAL_SNAPSHOTS = ActionType(
    u"magic-folder:uploader-service:upload-local-snapshot",
    [RELPATH],
    [],
    u"Uploader service is uploading a local snapshot",
)
SNAPSHOT_COMMIT_FAILURE = MessageType(
    u"magic-folder:uploader-service:snapshot-commit-failure",
    [],
    u"Uploader service is unable to commit the LocalSnapshot.",
)
ADD_FILE_FAILURE = MessageType(
    u"magic-folder:local-snapshot-creator:add-file-failure",