def register(): restype = ResourceType('Directory', Directory, id_type={ 'path': AttrType( pytype=str, valid_condition=fileperms.is_valid_path), }, state_type={ 'present': AttrType( default_value=True, pytype=bool, reader=read_present), 'mode': AttrType( default_value='0700', reader=fileperms.read_mode, valid_condition=fileperms.is_valid_mode, pytype=str), 'owner': AttrType( none_allowed=True, reader=fileperms.read_owner, # Commenting due to users created after validation #valid_condition=fileperms.is_valid_username, # XXX Non-realizing references would be nice. # eg by building a ref if a res is passed, and depending on the ref. pytype=str), 'group': AttrType( none_allowed=True, reader=fileperms.read_group, valid_condition=fileperms.is_valid_groupname, pytype=str), }) get_registry().resource_types.register(restype)
def register(): # We should have UNIQUE (location) and UNIQUE (name), # not just a unique-together. restype = ResourceType('Rails', Rails, id_type={ 'name': AttrType( pytype=str), 'location': RefAttrType( rtype='Directory'), }, state_type={ # More privileged 'maint_user': RefAttrType( valid_condition=is_valid_user, rtype='User'), # Less privileged 'run_user': RefAttrType( valid_condition=is_valid_user, rtype='User'), 'hostname': AttrType( default_value='localhost', pytype=str), 'cluster': RefAttrType( rtype='PgCluster'), }) get_registry().resource_types.register(restype)
def register(): restype = ResourceType('SvnWorkingCopy', SvnWorkingCopy, id_type={ 'location': RefAttrType( rtype='Directory'), }, state_type={ 'url': AttrType( pytype=str), }) get_registry().resource_types.register(restype)
def register(): restype = ResourceType('Duplicity', Duplicity, id_type={ 'source': AttrType( rtype='Directory'), 'dest': AttrType( pytype=str), }, state_type={ }) get_registry().resource_types.register(restype)
def register(): restype = ResourceType('Key', Key, id_type={ 'name': AttrType( pytype=str), }, state_type={ 'enabled': AttrType( default_value=True, pytype=bool), }) get_registry().resource_types.register(restype)
def register(cls): cls.__type = TransitionType( "PythonCode", cls, instr_type={ "function": AttrType(pytype=(types.FunctionType, types.MethodType)), # Positional arguments, a sequence "args": AttrType(default_value=[], pytype=list), # Keyword arguments, a map "kargs": AttrType(default_value={}, pytype=dict), }, results_type={"retval": AttrType(none_allowed=True)}, ) get_registry().transition_types.register(cls.__type)
def register(): restype = ResourceType('RubyGem', RubyGem, id_type={ 'name': AttrType( valid_condition=is_valid_arg, pytype=str), 'version': AttrType( valid_condition=is_valid_arg, pytype=str), }, state_type={ 'present': AttrType( default_value=True, reader=read_present, pytype=bool), }) get_registry().resource_types.register(restype)
def register(): restype = ResourceType('DirService', DirService, id_type={ 'location': RefAttrType( rtype='Directory'), }, state_type={ 'status': AttrType( default_value='up', valid_values=('up', 'down', ), pytype=str), 'present': AttrType( default_value=True, pytype=bool), 'target_dir': RefAttrType( rtype='Directory'), }) get_registry().resource_types.register(restype)
def register(cls): cls.__restype = ResourceType('AptitudePackage', cls, id_type={ 'name': AttrType( pytype=str, valid_condition=cls.is_valid_pkgname), }, state_type={ 'version': AttrType( none_allowed=True, pytype=str, valid_condition=cls.is_valid_version), 'state': AttrType( default_value='installed', pytype=str, valid_condition=cls.is_valid_state), }, ) get_registry().resource_types.register(cls.__restype)
def register(cls): cls.__restype = TransitionType('Command', cls, instr_type={ 'cmdline': AttrType( valid_condition=cls.is_valid_cmdline), 'cmdline_input': AttrType( # Node means keyboard input is possible. none_allowed=True, # str so we needn't bother with encodings pytype=str), 'unless': AttrType( none_allowed=True, valid_condition=cls.is_valid_cmdline), 'cwd': AttrType( none_allowed=True, pytype=str), 'username': AttrType( none_allowed=True, # Commented since some users are created after validation. # Passing User deps would be better. #valid_condition=cls.is_valid_username, pytype=str), 'extra_env': AttrType( none_allowed=True, valid_condition=cls.is_valid_extra_env), 'redir_stdout': AttrType( default_value=False, pytype=bool), 'expected_retcodes': AttrType( default_value=(0, ), valid_condition=cls.is_valid_expected_retcodes), }, results_type={ 'retcode': AttrType( pytype=int, ), 'stdout': AttrType( pytype=str, default_value='', ), }) get_registry().transition_types.register(cls.__restype)
def register(): restype = ResourceType('Redmine', Redmine, id_type={ # They must be _separately_ unique. 'path': AttrType( pytype=str), 'name': AttrType( pytype=str), }, state_type={ 'svn_branch': AttrType( default_value='http://redmine.rubyforge.org/svn/branches/0.8-stable/', pytype=str), 'hostname': AttrType( default_value='localhost', pytype=str), 'cluster': RefAttrType( rtype='PgCluster'), }) get_registry().resource_types.register(restype)
def register(): # Considered conninfo strings; problem is createuser doesn't support them. # They do a bit too much (spec the db…) and wouldn't be identifying. # Rejected. restype = ResourceType('PgCluster', PgCluster, id_type={ 'pg_host': AttrType( default_value='/var/run/postgresql', pytype=str), 'pg_port': AttrType( default_value=5432, pytype=int), }, state_type={ 'present': AttrType( default_value=True, pytype=bool), }) get_registry().resource_types.register(restype)
def register(cls): cls.__restype = ResourceType('User', cls, id_type={ 'name': AttrType( valid_condition=cls.is_valid_username), }, state_type={ 'present': AttrType( default_value=True, pytype=bool), 'home': AttrType( none_allowed=True, valid_condition=cls.is_valid_home), 'shell': AttrType( none_allowed=True, valid_condition=cls.is_valid_shell), }, global_reader=read_attrs, ) get_registry().resource_types.register(cls.__restype)
def register(): restype = ResourceType('PgDatabase', PgDatabase, id_type={ 'cluster': RefAttrType( rtype='PgCluster'), 'name': AttrType( valid_condition=is_valid_dbname, pytype=str), }, state_type={ 'present': AttrType( default_value=True, pytype=bool, reader=read_present), 'owner': RefAttrType( rtype='PgUser'), 'enable_backups': AttrType( default_value=True, pytype=bool), }) get_registry().resource_types.register(restype)
def register(): restype = ResourceType('PlainFile', PlainFile, id_type={ 'path': AttrType( pytype=str, valid_condition=fileperms.is_valid_path), }, state_type={ # Not specifying contents means the file will be emptied. 'contents': AttrType( default_value='', reader=read_contents, # A byte string, no encoding pytype=str), # The rest is handled with fileperms 'present': AttrType( default_value=True, pytype=bool, reader=read_present), 'mode': AttrType( default_value='0600', reader=fileperms.read_mode, valid_condition=fileperms.is_valid_mode, pytype=str), 'owner': AttrType( none_allowed=True, reader=fileperms.read_owner, valid_condition=fileperms.is_valid_username, # XXX Non-realizing references would be nice. # eg by building a ref if a res is passed, and depending on the ref. pytype=str), 'group': AttrType( none_allowed=True, reader=fileperms.read_group, valid_condition=fileperms.is_valid_groupname, pytype=str), }) get_registry().resource_types.register(restype)
def _collect(self): # Collects compatible nodes into merged nodes. def can_merge(part0, part1): for n0 in part0: for n1 in part1: if self.__resources.resources_connected(n0, n1): return False return True def possibly_merge(partition): # Merge once if possible. Return true if did merge. e = dict(enumerate(partition)) n = len(partition) # Loop over the triangle of unordered pairs for i in xrange(n): for j in xrange(i + 1, n): part0, part1 = e[i], e[j] if can_merge(part0, part1): partition.add(part0.union(part1)) partition.remove(part0) partition.remove(part1) return True return False reg = get_registry() for collector in reg.collectors: # Pre-partition is made of parts acceptable for the collector. pre_partition = collector.partition( [r for r in self.__resources.iter_uncollected_resources() if collector.filter(r)] ) for part in pre_partition: # Collector parts are split again, the sub-parts are merged # when dependencies allow. # Not a particularly efficient algorithm, just simple. # Gives one solution among many possibilities. partition = set(frozenset((r,)) for r in part for part in pre_partition) while possibly_merge(partition): pass # Let the collector handle the rest for part in partition: if not bool(part): # Test for emptiness. # Aggregate even singletons. continue merged = collector.collect(part) self.__resources.collect_resources(part, merged) assert not bool(list(self.__resources.iter_uncollected_resources()))
def register(): restype = ResourceType('A2Site', A2Site, id_type={ 'name': AttrType( pytype=str), }, state_type={ 'present': AttrType( default_value=True, pytype=bool), 'enabled': AttrType( default_value=True, pytype=bool), 'hostname': AttrType( # I suppose that's secure by default; if not, maybe 127.0.0.1. default_value='localhost', pytype=str), 'port': AttrType( default_value=80, pytype=int), 'contents': AttrType( pytype=str), }) get_registry().resource_types.register(restype)
def register(): restype = ResourceType('PassengerSite', PassengerSite, id_type={ 'name': AttrType( pytype=str), }, state_type={ 'present': AttrType( default_value=True, pytype=bool), 'enabled': AttrType( default_value=True, pytype=bool), 'hostname': AttrType( # I suppose that's secure by default; if not, maybe 127.0.0.1. default_value='localhost', pytype=str), 'port': AttrType( default_value=80, pytype=int), 'rails_dir': RefAttrType( rtype='Directory'), }) get_registry().resource_types.register(restype)
def from_yaml(cls, loader, tag_suffix, node): from systems.registry import get_registry mp = loader.construct_mapping(node) ttype = get_registry().transition_types.lookup(tag_suffix) return ttype.make_instance(instr_valdict=mp['instr'])
def from_yaml(cls, loader, tag_suffix, node): from systems.registry import get_registry mp = loader.construct_mapping(node) rtype = get_registry().resource_types.lookup(tag_suffix) return rtype.make_instance_sep( id_valdict=mp['id'], wanted_valdict=mp['wanted'])
def _rtype(self): from systems.registry import get_registry return get_registry().resource_types.lookup(self.rtypename)
def register(cls): get_registry().collectors \ .register(cls('AptitudePackageCollector'))
def transition_type(typename): return get_registry().transition_types.lookup(typename)
def resource_type(typename): return get_registry().resource_types.lookup(typename)