class _EnvironmentVariable(CFObject): """ An environment variable to set when running a component. """ name = CFField('name').name_field() value = CFField('value').value_field() def __init__(self): super(_EnvironmentVariable, self).__init__('Environment Variable')
class _RestartPolicy(CFObject): """ A restart policy for how a container should or should not be restarted on exit. """ name = CFField('name').name_field().default('') max_retry_count = CFField('max_retry_count').kind(int).default(0) def __init__(self): super(_RestartPolicy, self).__init__('Restart Policy')
class _RequiredComponentLink(CFObject): """ A network link required by a component. """ name = CFField('name').name_field() alias = CFField('alias').value_field() def __init__(self): super(_RequiredComponentLink, self).__init__('Required Component Link')
class _VolumeBinding(CFObject): """ A port mapping of an internal container port to the outside world. """ external = CFField('external').name_field() volume = CFField('volume').value_field() def __init__(self): super(_VolumeBinding, self).__init__('Volume Binding')
class _PortMapping(CFObject): """ A port mapping of an internal container port to the outside world. """ external = CFField('external').kind(int).name_field() container = CFField('container').kind(int).value_field() kind = CFField('kind').default('tcp') def __init__(self): super(_PortMapping, self).__init__('Port Mapping')
class _HealthCheck(CFObject): """ A single check to perform to verify that a component is ready to be pushed or is running properly. """ id = CFField('id').default('').name_field() kind = CFField('kind').value_field() timeout = CFField('timeout').kind(int).default(3) def __init__(self): super(_HealthCheck, self).__init__('Health Check') def getTitle(self): """ Returns a descriptive title for the check. """ if self.id != '': return self.id return self.kind
class _TerminationSignal(CFObject): """ A single signal that is sent to a component when the component should shut itself down. """ id = CFField('id').default('').name_field() kind = CFField('kind').value_field() timeout = CFField('timeout').kind(int).default(3) def __init__(self): super(_TerminationSignal, self).__init__('Termination Signal') def getTitle(self): """ Returns a descriptive title for the check. """ if self.id != '': return self.id return self.kind
class _DefinedComponentLink(CFObject): """ A network link exported by a component. """ name = CFField('name').name_field() port = CFField('port').kind(int).value_field() kind = CFField('kind').default('tcp') def __init__(self): super(_DefinedComponentLink, self).__init__('Component Link') def getHostPort(self): """ Returns the port used by the component link on the host. """ key = 'link-' + self.name + '-port' port = getComponentField(self.parent.name, key, 0) if not port: port = pickUnusedPort() setComponentField(self.parent.name, key, port) return port
class Configuration(CFObject): """ The overall gantry configuration. """ components = CFField('components').list_of(_Component) def __init__(self): super(Configuration, self).__init__('Configuration') def lookupComponent(self, name): """ Looks up the component with the given name under this config. """ for component in self.components: if component.name == name: return component return None
class _Component(CFObject): """ A single gantry component. """ name = CFField('name') repo = CFField('repo') tag = CFField('tag').default('latest') command = CFField('command').list_of(str).default([]) user = CFField('user').default('') ports = CFField('ports').list_of(_PortMapping).default([]) bindings = CFField('bindings').list_of(_VolumeBinding).default([]) volumes_from = CFField('volumesFrom').list_of(str).default([]) ready_checks = CFField('readyChecks').list_of(_HealthCheck).default([]) health_checks = CFField('healthChecks').list_of(_HealthCheck).default([]) ready_timeout = CFField('readyTimeout').kind(int).default(10000) termination_signals = CFField('terminationSignals').list_of( _TerminationSignal).default([]) privileged = CFField('privileged').kind(bool).default(False) defined_component_links = CFField('defineComponentLinks').list_of( _DefinedComponentLink).default([]) required_component_links = CFField('requireComponentLinks').list_of( _RequiredComponentLink).default([]) environment_variables = CFField('environmentVariables').list_of( _EnvironmentVariable).default([]) connection_check = _HealthCheck().build({'kind': 'connection'}) termination_checks = CFField('terminationChecks').list_of( _HealthCheck).default([connection_check]) def __init__(self): super(_Component, self).__init__('Component') def getFullImage(self): """ Returns the full image ID for this component, of the form 'repo:tag' """ return self.repo + ':' + self.tag def getUser(self): """ Returns the user under which to run the container or None if none. """ if not self.user: return None return self.user def getCommand(self): """ Returns the command string to run on component startup or None if none. """ if not self.command: return None return ' '.join(self.command) def getContainerPorts(self): """ Returns the full set of ports exposed by this component. """ return set([p.container for p in self.ports] + [l.port for l in self.defined_component_links]) def getReadyCheckTimeout(self): """ Returns the maximum amount of time, in seconds, before ready checks time out. """ return self.ready_timeout / 1000 def getVolumes(self): """ Returns the volumes exposed by this component. """ return [binding.volume for binding in self.bindings] def getBindings(self, container_id): """ Returns the volumes exposed by this component. """ def substitute_id(external_dir): return external_dir.format(container_id=container_id[:12]) return { substitute_id(binding.external): binding.volume for binding in self.bindings } def getDefinedComponentLinks(self): """ Returns the dict of defined components links. """ return {l.name: l for l in self.defined_component_links} def getComponentLinks(self): """ Returns a dict of aliases for component links required, with the values being the links' names. """ return {l.alias: l.name for l in self.required_component_links} def getEnvironmentVariables(self): """ Returns a dict of the defined environments variables and their values. """ return {v.name: v.value for v in self.environment_variables}