Adding constraints to cache and advancing so we can make use efficiently a predefined pool with uds & uds actor

This commit is contained in:
Adolfo Gómez García 2017-01-12 03:27:42 +01:00
parent 4e972e0aff
commit 4401985f3c
12 changed files with 70 additions and 32 deletions

View File

@ -76,7 +76,7 @@ class OsManagerError(RESTError):
# Disable warnings log messages
try:
import urllib3 # @UnusedImport
import urllib3 # @UnusedImport @UnresolvedImport
except Exception:
from requests.packages import urllib3 # @Reimport
@ -84,7 +84,7 @@ try:
urllib3.disable_warnings() # @UndefinedVariable
warnings.simplefilter("ignore")
except Exception:
pass # In fact, isn't too important, but wil log warns to logging file
pass # In fact, isn't too important, but will log warns to logging file
def ensureResultIsOk(result):
@ -221,9 +221,13 @@ class Api(object):
logger.debug('Requesting information'.format())
return self.postMessage('information', '')
def setReady(self, ipsInfo):
def setReady(self, ipsInfo, hostName=None):
logger.debug('Notifying readyness: {}'.format(ipsInfo))
data = ','.join(['{}={}'.format(v[0], v[1]) for v in ipsInfo])
# data = ','.join(['{}={}'.format(v[0], v[1]) for v in ipsInfo])
data = {
'ips': ipsInfo,
'hostname': hostName
}
return self.postMessage('ready', data)
def notifyIpChanges(self, ipsInfo):

View File

@ -34,7 +34,7 @@ from __future__ import unicode_literals
# On centos, old six release does not includes byte2int, nor six.PY2
import six
VERSION = '2.1.0'
VERSION = '2.5.0'
__title__ = 'udsactor'
__version__ = VERSION

View File

@ -174,6 +174,11 @@ class HTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
# TODO: Return something useful? :)
return 'Up and running'
def get_refresh(self, params):
'''
Requests a refresh of own information offered from UDS Server
'''
def get_uuid(self, params):
return self.service.api.uuid

View File

@ -85,8 +85,8 @@ class CommonService(object):
def reboot(self):
self.rebootRequested = True
def setReady(self):
self.api.setReady([(v.mac, v.ip) for v in operations.getNetworkInfo()])
def setReady(self, hostName=None):
self.api.setReady([(v.mac, v.ip) for v in operations.getNetworkInfo()], hostName)
def interactWithBroker(self):
'''
@ -171,6 +171,9 @@ class CommonService(object):
return False # Stop running service
self.joinDomain(params[0], params[1], params[2], params[3], params[4])
break
elif data[0] == 'notify': # Broker is just requesting local information, no rename nor domain is requested
self.notifyLocalInfo()
break
else:
logger.error('Unrecognized action sent from broker: {}'.format(data[0]))
return False # Stop running service
@ -310,6 +313,9 @@ class CommonService(object):
# ****************************************
# Methods that CAN BE overriden by actors
# ****************************************
def notifyLocal(self):
self.setReady(operations.getComputerName())
def doWait(self, miliseconds):
'''
Invoked to wait a bit

View File

@ -66,7 +66,7 @@ class Services(DetailHandler): # pylint: disable=too-many-public-methods
'icon': info.icon().replace('\n', ''),
'needs_publication': info.publicationType is not None,
'max_deployed': info.maxDeployed,
'uses_cache': info.usesCache,
'uses_cache': info.usesCache and info.cacheConstains == None,
'uses_cache_l2': info.usesCache_L2,
'cache_tooltip': _(info.cacheTooltip),
'cache_tooltip_l2': _(info.cacheTooltip_L2),

View File

@ -239,7 +239,7 @@ class ServicesPools(ModelHandler):
raise RequestError(ugettext('Base service does not exist anymore'))
try:
serviceType = service.getType()
serviceType = service.getInstance()
if serviceType.publicationType is None:
self._params['publish_on_save'] = False
@ -250,6 +250,15 @@ class ServicesPools(ModelHandler):
else:
del fields['osmanager_id']
if serviceType.cacheConstains is not None:
for k, v in serviceType.cacheConstains.iteritems():
fields[k] = v
if serviceType.maxDeployed != -1:
fields['max_srvs'] = min((int(fields['max_srvs']), serviceType.maxDeployed))
fields['initial_srvs'] = min(int(fields['initial_srvs']), serviceType.maxDeployed)
fields['cache_l1_srvs'] = min(int(fields['cache_l1_srvs']), serviceType.maxDeployed)
if serviceType.usesCache is False:
for k in ('initial_srvs', 'cache_l1_srvs', 'cache_l2_srvs', 'max_srvs'):
fields[k] = 0
@ -257,6 +266,7 @@ class ServicesPools(ModelHandler):
except Exception:
raise RequestError(ugettext('This service requires an OS Manager'))
# If max < initial or cache_1 or cache_l2
fields['max_srvs'] = max((int(fields['initial_srvs']), int(fields['cache_l1_srvs']), int(fields['max_srvs'])))
@ -288,7 +298,10 @@ class ServicesPools(ModelHandler):
def afterSave(self, item):
if self._params.get('publish_on_save', False) is True:
item.publish()
try:
item.publish()
except Exception:
pass
def deleteItem(self, item):
item.remove() # This will mark it for deletion, but in fact will not delete it directly

View File

@ -35,7 +35,7 @@ from __future__ import unicode_literals
from uds.core import Environmentable
from uds.core import Serializable
__updated__ = '2016-02-26'
__updated__ = '2017-01-12'
class Publication(Environmentable, Serializable):
@ -89,6 +89,7 @@ class Publication(Environmentable, Serializable):
self._osManager = kwargs.get('osManager', None)
self._service = kwargs['service'] # Raises an exception if service is not included
self._revision = kwargs.get('revision', -1)
self._dbPublication = kwargs.get('dbPublication')
self._dsName = kwargs.get('dsName', 'Unknown')
self.initialize()

View File

@ -37,7 +37,7 @@ from uds.core import Module
from uds.core.transports import protocols
from . import types
__updated__ = '2016-03-09'
__updated__ = '2017-01-12'
class Service(Module):
@ -112,6 +112,9 @@ class Service(Module):
# : modified at instance level, core will access always to it using an instance object.
maxDeployed = UNLIMITED # : If the service provides more than 1 "provided service" (-1 = no limit, 0 = ???? (do not use it!!!), N = max number to deploy
# : If this item "has constains", on deployed service edition, defined keys will overwrite defined ones
cacheConstains = None
# : If this class uses cache or not. If uses cache is true, means that the
# : service can "prepare" some user deployments to allow quicker user access
# : to services if he already do not have one.

View File

@ -47,7 +47,7 @@ from uds.models.UUIDModel import UUIDModel
import logging
__updated__ = '2016-03-29'
__updated__ = '2017-01-12'
logger = logging.getLogger(__name__)
@ -134,7 +134,7 @@ class DeployedServicePublication(UUIDModel):
if serviceInstance.publicationType is None:
raise Exception('Class {0} do not have defined publicationType but needs to be published!!!'.format(serviceInstance.__class__))
dpl = serviceInstance.publicationType(self.getEnvironment(), service=serviceInstance, osManager=osManagerInstance, revision=self.revision, dsName=self.deployed_service.name)
dpl = serviceInstance.publicationType(self.getEnvironment(), service=serviceInstance, osManager=osManagerInstance, revision=self.revision, dsName=self.deployed_service.name, dbPublication=self)
# Only invokes deserialization if data has something. '' is nothing
if self.data != '' and self.data is not None:
dpl.unserialize(self.data)

View File

@ -57,7 +57,7 @@ import six
import pickle
import logging
__updated__ = '2016-09-21'
__updated__ = '2017-01-12'
logger = logging.getLogger(__name__)
@ -415,7 +415,7 @@ class UserService(UUIDModel):
def release(self):
'''
A much more convenient method that "remove"
A much more convenient method that "remove" for some situations..
'''
self.remove()

View File

@ -105,15 +105,13 @@ class LinuxOsManager(osmanagers.OSManager):
def notifyIp(self, uid, service, data):
si = service.getInstance()
ip = ''
# Notifies IP to deployed
pairs = data.split(',')
for p in pairs:
key, val = p.split('=')
if key.lower() == uid.lower():
si.setIp(val)
ip = val
for p in data['ips']:
if p[0].lower() == uid.lower():
si.setIp(p[1])
ip = p[1]
break
self.logKnownIp(service, ip)
@ -168,6 +166,11 @@ class LinuxOsManager(osmanagers.OSManager):
doRemove = True
elif msg == "ip":
# This ocurss on main loop inside machine, so userService is usable
if not isinstance(data, dict): # Old actors, previous to 2.5, convert it information..
data = {
'ips': [v.split('=') for v in data.split(',')],
'hostname': userService.friendly_name
}
state = State.USABLE
self.notifyIp(userService.unique_id, userService, data)
elif msg == "ready":
@ -195,7 +198,7 @@ class LinuxOsManager(osmanagers.OSManager):
This function can update userService values. Normal operation will be remove machines if this state is not valid
'''
if self._onLogout == 'remove':
userService.remove()
userService.release()
def checkState(self, service):
logger.debug('Checking state for service {0}'.format(service))

View File

@ -112,15 +112,13 @@ class WindowsOsManager(osmanagers.OSManager):
def notifyIp(self, uid, service, data):
si = service.getInstance()
ip = ''
# Notifies IP to deployed
pairs = data.split(',')
for p in pairs:
key, val = p.split('=')
if key.lower() == uid.lower():
si.setIp(val)
ip = val
for p in data['ips']:
if p[0].lower() == uid.lower():
si.setIp(p[1])
ip = p[1]
break
self.logKnownIp(service, ip)
@ -181,6 +179,11 @@ class WindowsOsManager(osmanagers.OSManager):
doRemove = True
elif msg == "ip":
# This ocurss on main loop inside machine, so userService is usable
if not isinstance(data, dict): # Old actors, previous to 2.5
data = {
'ips': [v.split('=') for v in data.split(',')],
'hostname': userService.friendly_name
}
state = State.USABLE
self.notifyIp(userService.unique_id, userService, data)
elif msg == "ready":
@ -230,7 +233,7 @@ class WindowsOsManager(osmanagers.OSManager):
This function can update userService values. Normal operation will be remove machines if this state is not valid
'''
if self._onLogout == 'remove':
userService.remove()
userService.release()
def checkState(self, service):
logger.debug('Checking state for service {0}'.format(service))