<s> """<STR_LIT>""" <EOL> from uuid import UUID <EOL> from warnings import warn <EOL> from hashlib import md5 <EOL> from datetime import datetime , timedelta <EOL> from characteristic import attributes <EOL> from twisted . python . filepath import FilePath <EOL> from pyrsistent import ( <EOL> pmap , PClass , PRecord , field , PMap , CheckedPSet , CheckedPMap , discard , <EOL> optional as optional_type , CheckedPVector <EOL> ) <EOL> from zope . interface import Interface , implementer <EOL> def _sequence_field ( checked_class , suffix , item_type , optional , initial ) : <EOL> """<STR_LIT>""" <EOL> class TheType ( checked_class ) : <EOL> __type__ = item_type <EOL> TheType . __name__ = item_type . __name__ . capitalize ( ) + suffix <EOL> if optional : <EOL> def factory ( argument ) : <EOL> if argument is None : <EOL> return None <EOL> else : <EOL> return TheType ( argument ) <EOL> else : <EOL> factory = TheType <EOL> return field ( type = optional_type ( TheType ) if optional else TheType , <EOL> factory = factory , mandatory = True , <EOL> initial = factory ( initial ) ) <EOL> def pset_field ( item_type , optional = False , initial = ( ) ) : <EOL> """<STR_LIT>""" <EOL> return _sequence_field ( CheckedPSet , "<STR_LIT>" , item_type , optional , <EOL> initial ) <EOL> def pvector_field ( item_type , optional = False , initial = ( ) ) : <EOL> """<STR_LIT>""" <EOL> return _sequence_field ( CheckedPVector , "<STR_LIT>" , item_type , optional , <EOL> initial ) <EOL> def _valid ( item ) : <EOL> return ( True , "<STR_LIT>" ) <EOL> _UNDEFINED = object ( ) <EOL> def pmap_field ( <EOL> key_type , value_type , optional = False , invariant = _valid , <EOL> initial = _UNDEFINED <EOL> ) : <EOL> """<STR_LIT>""" <EOL> class TheMap ( CheckedPMap ) : <EOL> __key_type__ = key_type <EOL> __value_type__ = value_type <EOL> TheMap . __name__ = ( key_type . __name__ . capitalize ( ) + <EOL> value_type . __name__ . capitalize ( ) + "<STR_LIT>" ) <EOL> if optional : <EOL> def factory ( argument ) : <EOL> if argument is None : <EOL> return None <EOL> else : <EOL> return TheMap ( argument ) <EOL> else : <EOL> factory = TheMap <EOL> if initial is _UNDEFINED : <EOL> initial = TheMap ( ) <EOL> else : <EOL> initial = factory ( initial ) <EOL> return field ( mandatory = True , initial = initial , <EOL> type = optional_type ( TheMap ) if optional else TheMap , <EOL> factory = factory , invariant = invariant ) <EOL> class DockerImage ( PClass ) : <EOL> """<STR_LIT>""" <EOL> repository = field ( mandatory = True ) <EOL> tag = field ( mandatory = True , initial = u"<STR_LIT>" ) <EOL> @ property <EOL> def full_name ( self ) : <EOL> return u"<STR_LIT>" . format ( <EOL> repository = self . repository , tag = self . tag ) <EOL> @ classmethod <EOL> def from_string ( cls , input_name ) : <EOL> """<STR_LIT>""" <EOL> kwargs = { } <EOL> parts = input_name . rsplit ( u'<STR_LIT::>' , <NUM_LIT:1> ) <EOL> repository = parts [ <NUM_LIT:0> ] <EOL> if not repository : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> . format ( image_name = input_name ) ) <EOL> kwargs [ '<STR_LIT>' ] = repository <EOL> if len ( parts ) == <NUM_LIT:2> : <EOL> kwargs [ '<STR_LIT>' ] = parts [ <NUM_LIT:1> ] <EOL> return cls ( ** kwargs ) <EOL> class Port ( PClass ) : <EOL> """<STR_LIT>""" <EOL> internal_port = field ( mandatory = True , type = int ) <EOL> external_port = field ( mandatory = True , type = int ) <EOL> class Link ( PClass ) : <EOL> """<STR_LIT>""" <EOL> local_port = field ( mandatory = True , type = int ) <EOL> remote_port = field ( mandatory = True , type = int ) <EOL> alias = field ( <EOL> mandatory = True , factory = lambda s : s . lower ( ) , <EOL> invariant = lambda s : ( <EOL> s . isalnum ( ) , "<STR_LIT>" <EOL> ) <EOL> ) <EOL> class IRestartPolicy ( Interface ) : <EOL> """<STR_LIT>""" <EOL> @ implementer ( IRestartPolicy ) <EOL> class RestartNever ( PClass ) : <EOL> """<STR_LIT>""" <EOL> @ implementer ( IRestartPolicy ) <EOL> class RestartAlways ( PClass ) : <EOL> """<STR_LIT>""" <EOL> @ implementer ( IRestartPolicy ) <EOL> class RestartOnFailure ( PClass ) : <EOL> """<STR_LIT>""" <EOL> maximum_retry_count = field ( mandatory = True , initial = None ) <EOL> def __invariant__ ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . maximum_retry_count is not None : <EOL> if not isinstance ( self . maximum_retry_count , int ) : <EOL> return ( False , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( self . maximum_retry_count , ) ) <EOL> if self . maximum_retry_count < <NUM_LIT:1> : <EOL> return ( False , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( self . maximum_retry_count , ) ) <EOL> return ( True , "<STR_LIT>" ) <EOL> class Application ( PClass ) : <EOL> """<STR_LIT>""" <EOL> name = field ( mandatory = True ) <EOL> image = field ( mandatory = True , type = DockerImage ) <EOL> ports = pset_field ( Port ) <EOL> volume = field ( mandatory = True , initial = None ) <EOL> links = pset_field ( Link ) <EOL> memory_limit = field ( mandatory = True , initial = None ) <EOL> cpu_shares = field ( mandatory = True , initial = None ) <EOL> restart_policy = field ( mandatory = True , initial = RestartNever ( ) ) <EOL> environment = field ( mandatory = True , initial = pmap ( ) , factory = pmap , <EOL> type = PMap ) <EOL> running = field ( mandatory = True , initial = True , type = bool ) <EOL> command_line = pvector_field ( unicode , optional = True , initial = None ) <EOL> class Dataset ( PClass ) : <EOL> """<STR_LIT>""" <EOL> dataset_id = field ( mandatory = True , type = unicode , factory = unicode ) <EOL> deleted = field ( mandatory = True , initial = False , type = bool ) <EOL> maximum_size = field ( mandatory = True , initial = None ) <EOL> metadata = field ( mandatory = True , type = PMap , factory = pmap , initial = pmap ( ) , <EOL> serializer = lambda f , d : dict ( d ) ) <EOL> class Manifestation ( PClass ) : <EOL> """<STR_LIT>""" <EOL> dataset = field ( mandatory = True , type = Dataset ) <EOL> primary = field ( mandatory = True , type = bool ) <EOL> @ property <EOL> def dataset_id ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . dataset . dataset_id <EOL> class AttachedVolume ( PClass ) : <EOL> """<STR_LIT>""" <EOL> manifestation = field ( mandatory = True , type = Manifestation ) <EOL> mountpoint = field ( mandatory = True , type = FilePath ) <EOL> @ property <EOL> def dataset ( self ) : <EOL> return self . manifestation . dataset <EOL> def _keys_match ( attribute ) : <EOL> """<STR_LIT>""" <EOL> def key_match_invariant ( pmap ) : <EOL> if pmap is None : <EOL> return ( True , "<STR_LIT>" ) <EOL> for ( key , value ) in pmap . items ( ) : <EOL> if key != getattr ( value , attribute ) : <EOL> return ( <EOL> False , "<STR_LIT>" . format ( key , value ) <EOL> ) <EOL> return ( True , "<STR_LIT>" ) <EOL> return key_match_invariant <EOL> _keys_match_dataset_id = _keys_match ( "<STR_LIT>" ) <EOL> class Node ( PClass ) : <EOL> """<STR_LIT>""" <EOL> def __invariant__ ( self ) : <EOL> manifestations = self . manifestations . values ( ) <EOL> for app in self . applications : <EOL> if app . volume is not None : <EOL> if app . volume . manifestation not in manifestations : <EOL> return ( False , '<STR_LIT>' % ( app , ) ) <EOL> return ( True , "<STR_LIT>" ) <EOL> def __new__ ( cls , hostname = None , ** kwargs ) : <EOL> if "<STR_LIT>" not in kwargs : <EOL> warn ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , DeprecationWarning , stacklevel = <NUM_LIT:2> ) <EOL> kwargs [ "<STR_LIT>" ] = ip_to_uuid ( hostname ) <EOL> return PClass . __new__ ( cls , ** kwargs ) <EOL> uuid = field ( type = UUID , mandatory = True ) <EOL> applications = pset_field ( Application ) <EOL> manifestations = pmap_field ( <EOL> unicode , Manifestation , invariant = _keys_match_dataset_id <EOL> ) <EOL> def same_node ( node1 , node2 ) : <EOL> """<STR_LIT>""" <EOL> return node1 . uuid == node2 . uuid <EOL> def _get_node ( default_factory ) : <EOL> """<STR_LIT>""" <EOL> def get_node ( deployment , uuid , ** defaults ) : <EOL> nodes = list ( <EOL> node for node in deployment . nodes if node . uuid == uuid <EOL> ) <EOL> if len ( nodes ) == <NUM_LIT:0> : <EOL> return default_factory ( uuid = uuid , ** defaults ) <EOL> return nodes [ <NUM_LIT:0> ] <EOL> return get_node <EOL> LEASE_ACTION_ACQUIRE = u"<STR_LIT>" <EOL> LEASE_ACTION_RELEASE = u"<STR_LIT>" <EOL> class LeaseError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , dataset_id , node_id , action ) : <EOL> """<STR_LIT>""" <EOL> message = ( <EOL> u"<STR_LIT>" <EOL> u"<STR_LIT>" . format ( <EOL> action , unicode ( dataset_id ) , unicode ( node_id ) <EOL> ) <EOL> ) <EOL> return super ( LeaseError , self ) . __init__ ( message ) <EOL> class Lease ( PClass ) : <EOL> """<STR_LIT>""" <EOL> dataset_id = field ( type = UUID ) <EOL> node_id = field ( type = UUID ) <EOL> expiration = field ( <EOL> type = ( datetime , type ( None ) ) , mandatory = True , initial = None <EOL> ) <EOL> class Leases ( CheckedPMap ) : <EOL> """<STR_LIT>""" <EOL> __key_type__ = UUID <EOL> __value_type__ = Lease <EOL> def __invariant__ ( dataset_id , lease ) : <EOL> """<STR_LIT>""" <EOL> if dataset_id != lease . dataset_id : <EOL> return ( False , "<STR_LIT>" . format ( <EOL> dataset_id , lease . dataset_id <EOL> ) ) <EOL> return ( True , "<STR_LIT>" ) <EOL> def _check_lease ( self , dataset_id , node_id , action ) : <EOL> """<STR_LIT>""" <EOL> if dataset_id in self and self [ dataset_id ] . node_id != node_id : <EOL> raise LeaseError ( dataset_id , node_id , action ) <EOL> def acquire ( self , now , dataset_id , node_id , expires = None ) : <EOL> """<STR_LIT>""" <EOL> self . _check_lease ( dataset_id , node_id , LEASE_ACTION_ACQUIRE ) <EOL> if expires is None : <EOL> expiration = None <EOL> else : <EOL> expiration = now + timedelta ( seconds = expires ) <EOL> lease = Lease ( dataset_id = dataset_id , node_id = node_id , <EOL> expiration = expiration ) <EOL> return self . set ( dataset_id , lease ) <EOL> def release ( self , dataset_id , node_id ) : <EOL> """<STR_LIT>""" <EOL> self . _check_lease ( dataset_id , node_id , LEASE_ACTION_RELEASE ) <EOL> return self . remove ( dataset_id ) <EOL> def expire ( self , now ) : <EOL> """<STR_LIT>""" <EOL> updated = self <EOL> for lease in self . values ( ) : <EOL> if lease . expiration is not None and lease . expiration < now : <EOL> updated = updated . release ( lease . dataset_id , lease . node_id ) <EOL> return updated <EOL> class DatasetAlreadyOwned ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class BlockDeviceOwnership ( CheckedPMap ) : <EOL> """<STR_LIT>""" <EOL> __key_type__ = UUID <EOL> __value_type__ = unicode <EOL> def record_ownership ( self , dataset_id , blockdevice_id ) : <EOL> """<STR_LIT>""" <EOL> current_blockdevice_id = self . get ( dataset_id ) <EOL> if current_blockdevice_id not in ( None , blockdevice_id ) : <EOL> raise DatasetAlreadyOwned ( ) <EOL> return self . set ( dataset_id , blockdevice_id ) <EOL> class PersistentState ( PClass ) : <EOL> """<STR_LIT>""" <EOL> blockdevice_ownership = field ( type = BlockDeviceOwnership , mandatory = True , <EOL> initial = BlockDeviceOwnership ( ) ) <EOL> class Deployment ( PClass ) : <EOL> """<STR_LIT>""" <EOL> nodes = pset_field ( Node ) <EOL> leases = field ( type = Leases , mandatory = True , initial = Leases ( ) ) <EOL> persistent_state = field ( type = PersistentState , initial = PersistentState ( ) ) <EOL> get_node = _get_node ( Node ) <EOL> def applications ( self ) : <EOL> """<STR_LIT>""" <EOL> for node in self . nodes : <EOL> for application in node . applications : <EOL> yield application <EOL> def update_node ( self , node ) : <EOL> """<STR_LIT>""" <EOL> return self . set ( <EOL> '<STR_LIT>' , <EOL> [ n for n in self . nodes if not same_node ( n , node ) ] + [ node ] <EOL> ) <EOL> def move_application ( self , application , target_node ) : <EOL> """<STR_LIT>""" <EOL> deployment = self <EOL> for node in deployment . nodes : <EOL> for container in node . applications : <EOL> if container . name == application . name : <EOL> if not same_node ( node , target_node ) : <EOL> if application . volume is not None : <EOL> dataset_id = application . volume . dataset . dataset_id <EOL> target_node = target_node . transform ( <EOL> ( "<STR_LIT>" , dataset_id ) , <EOL> application . volume . manifestation <EOL> ) <EOL> target_node = target_node . transform ( <EOL> [ "<STR_LIT>" ] , lambda s : s . add ( application ) ) <EOL> node = node . transform ( <EOL> [ "<STR_LIT>" ] , lambda s : s . remove ( application ) ) <EOL> if application . volume is not None : <EOL> dataset_id = application . volume . dataset . dataset_id <EOL> node = node . transform ( <EOL> ( "<STR_LIT>" , dataset_id ) , discard <EOL> ) <EOL> deployment = deployment . update_node ( node ) <EOL> deployment = deployment . update_node ( target_node ) <EOL> return deployment <EOL> class Configuration ( PClass ) : <EOL> """<STR_LIT>""" <EOL> version = field ( mandatory = True , type = int ) <EOL> deployment = field ( mandatory = True , type = Deployment ) <EOL> @ attributes ( [ "<STR_LIT>" , "<STR_LIT>" ] ) <EOL> class DatasetHandoff ( object ) : <EOL> """<STR_LIT>""" <EOL> @ attributes ( [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] ) <EOL> class DatasetChanges ( object ) : <EOL> """<STR_LIT>""" <EOL> class IClusterStateChange ( Interface ) : <EOL> """<STR_LIT>""" <EOL> def update_cluster_state ( cluster_state ) : <EOL> """<STR_LIT>""" <EOL> def get_information_wipe ( ) : <EOL> """<STR_LIT>""" <EOL> class IClusterStateWipe ( Interface ) : <EOL> """<STR_LIT>""" <EOL> def update_cluster_state ( cluster_state ) : <EOL> """<STR_LIT>""" <EOL> def key ( ) : <EOL> """<STR_LIT>""" <EOL> @ implementer ( IClusterStateWipe ) <EOL> class NoWipe ( object ) : <EOL> """<STR_LIT>""" <EOL> def key ( self ) : <EOL> """<STR_LIT>""" <EOL> return None <EOL> def update_cluster_state ( self , cluster_state ) : <EOL> """<STR_LIT>""" <EOL> return cluster_state <EOL> class IClusterStateSource ( Interface ) : <EOL> """<STR_LIT>""" <EOL> def last_activity ( ) : <EOL> """<STR_LIT>""" <EOL> @ implementer ( IClusterStateSource ) <EOL> class ChangeSource ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . set_last_activity ( <NUM_LIT:0> ) <EOL> def set_last_activity ( self , since_epoch ) : <EOL> """<STR_LIT>""" <EOL> self . _last_activity = since_epoch <EOL> def last_activity ( self ) : <EOL> return datetime . utcfromtimestamp ( self . _last_activity ) <EOL> def ip_to_uuid ( ip ) : <EOL> """<STR_LIT>""" <EOL> return UUID ( bytes = md5 ( ip . encode ( "<STR_LIT:utf-8>" ) ) . digest ( ) ) <EOL> @ implementer ( IClusterStateChange ) <EOL> class NodeState ( PRecord ) : <EOL> """<STR_LIT>""" <EOL> _POTENTIALLY_IGNORANT_ATTRIBUTES = [ "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> _DATASET_ATTRIBUTES = { "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" } <EOL> def __invariant__ ( self ) : <EOL> def _field_missing ( fields ) : <EOL> num_known_attributes = sum ( getattr ( self , name ) is None <EOL> for name in fields ) <EOL> return num_known_attributes not in ( <NUM_LIT:0> , len ( fields ) ) <EOL> if _field_missing ( self . _DATASET_ATTRIBUTES ) : <EOL> return ( False , <EOL> "<STR_LIT>" . format ( <EOL> self . _DATASET_ATTRIBUTES ) ) <EOL> return ( True , "<STR_LIT>" ) <EOL> def __new__ ( cls , ** kwargs ) : <EOL> if "<STR_LIT>" not in kwargs : <EOL> if "<STR_LIT>" not in kwargs : <EOL> warn ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , DeprecationWarning , stacklevel = <NUM_LIT:2> ) <EOL> kwargs [ "<STR_LIT>" ] = ip_to_uuid ( kwargs [ "<STR_LIT>" ] ) <EOL> return PRecord . __new__ ( cls , ** kwargs ) <EOL> uuid = field ( type = UUID , mandatory = True ) <EOL> hostname = field ( type = unicode , factory = unicode , mandatory = True ) <EOL> applications = pset_field ( Application , optional = True , initial = None ) <EOL> manifestations = pmap_field ( unicode , Manifestation , optional = True , <EOL> initial = None , invariant = _keys_match_dataset_id ) <EOL> paths = pmap_field ( unicode , FilePath , optional = True , initial = None ) <EOL> devices = pmap_field ( UUID , FilePath , optional = True , initial = None ) <EOL> def update_cluster_state ( self , cluster_state ) : <EOL> return cluster_state . update_node ( self ) <EOL> def _provides_information ( self ) : <EOL> """<STR_LIT>""" <EOL> return any ( getattr ( self , attr ) is not None <EOL> for attr in self . _POTENTIALLY_IGNORANT_ATTRIBUTES ) <EOL> def get_information_wipe ( self ) : <EOL> """<STR_LIT>""" <EOL> attributes = [ attr for attr in <EOL> self . _POTENTIALLY_IGNORANT_ATTRIBUTES <EOL> if getattr ( self , attr ) is not None ] <EOL> return _WipeNodeState ( node_uuid = self . uuid , attributes = attributes ) <EOL> @ implementer ( IClusterStateChange ) <EOL> class UpdateNodeStateEra ( PClass ) : <EOL> """<STR_LIT>""" <EOL> uuid = field ( type = UUID , mandatory = True ) <EOL> era = field ( type = UUID , mandatory = True ) <EOL> def update_cluster_state ( self , cluster_state ) : <EOL> """<STR_LIT>""" <EOL> if cluster_state . node_uuid_to_era . get ( self . uuid ) != self . era : <EOL> cluster_state = cluster_state . remove_node ( self . uuid ) <EOL> cluster_state = cluster_state . transform ( <EOL> [ "<STR_LIT>" , self . uuid ] , self . era ) <EOL> return cluster_state <EOL> def get_information_wipe ( self ) : <EOL> """<STR_LIT>""" <EOL> return NoWipe ( ) <EOL> @ implementer ( IClusterStateWipe ) <EOL> class _WipeNodeState ( PClass ) : <EOL> """<STR_LIT>""" <EOL> node_uuid = field ( mandatory = True , type = UUID ) <EOL> attributes = pset_field ( str ) <EOL> def update_cluster_state ( self , cluster_state ) : <EOL> nodes = { n for n in cluster_state . nodes <EOL> if n . uuid == self . node_uuid } <EOL> if not nodes : <EOL> return cluster_state <EOL> [ original_node ] = nodes <EOL> updated_node = original_node . evolver ( ) <EOL> for attribute in self . attributes : <EOL> updated_node = updated_node . set ( attribute , None ) <EOL> updated_node = updated_node . persistent ( ) <EOL> final_nodes = cluster_state . nodes . discard ( original_node ) <EOL> if updated_node . _provides_information ( ) : <EOL> final_nodes = final_nodes . add ( updated_node ) <EOL> return cluster_state . set ( "<STR_LIT>" , final_nodes ) <EOL> def key ( self ) : <EOL> return ( self . node_uuid , self . attributes ) <EOL> class DeploymentState ( PClass ) : <EOL> """<STR_LIT>""" <EOL> nodes = pset_field ( NodeState ) <EOL> node_uuid_to_era = pmap_field ( UUID , UUID ) <EOL> nonmanifest_datasets = pmap_field ( <EOL> unicode , Dataset , invariant = _keys_match_dataset_id <EOL> ) <EOL> get_node = _get_node ( NodeState ) <EOL> def update_node ( self , node_state ) : <EOL> """<STR_LIT>""" <EOL> nodes = { n for n in self . nodes if same_node ( n , node_state ) } <EOL> if not nodes : <EOL> return self . transform ( [ "<STR_LIT>" ] , lambda s : s . add ( node_state ) ) <EOL> [ original_node ] = nodes <EOL> updated_node = original_node . evolver ( ) <EOL> for key , value in node_state . items ( ) : <EOL> if value is not None and value != updated_node [ key ] : <EOL> updated_node = updated_node . set ( key , value ) <EOL> updated_node = updated_node . persistent ( ) <EOL> if updated_node != original_node : <EOL> return self . set ( <EOL> "<STR_LIT>" , self . nodes . discard ( original_node ) . add ( <EOL> updated_node ) ) <EOL> else : <EOL> return self <EOL> def remove_node ( self , node_uuid ) : <EOL> """<STR_LIT>""" <EOL> return self . set ( nodes = { node for node in self . nodes <EOL> if node . uuid != node_uuid } ) <EOL> def all_datasets ( self ) : <EOL> """<STR_LIT>""" <EOL> for node in self . nodes : <EOL> if node . manifestations is None : <EOL> continue <EOL> for manifestation in node . manifestations . values ( ) : <EOL> if manifestation . primary : <EOL> yield manifestation . dataset , node <EOL> for dataset in self . nonmanifest_datasets . values ( ) : <EOL> yield dataset , None <EOL> @ implementer ( IClusterStateChange ) <EOL> class NonManifestDatasets ( PClass ) : <EOL> """<STR_LIT>""" <EOL> datasets = pmap_field ( unicode , Dataset , invariant = _keys_match_dataset_id ) <EOL> def update_cluster_state ( self , cluster_state ) : <EOL> return cluster_state . set ( nonmanifest_datasets = self . datasets ) <EOL> def get_information_wipe ( self ) : <EOL> """<STR_LIT>""" <EOL> return NoWipe ( ) <EOL> SERIALIZABLE_CLASSES = [ <EOL> Deployment , Node , DockerImage , Port , Link , RestartNever , RestartAlways , <EOL> RestartOnFailure , Application , Dataset , Manifestation , AttachedVolume , <EOL> NodeState , DeploymentState , NonManifestDatasets , Configuration , <EOL> Lease , Leases , PersistentState , <EOL> ] </s>
