# Copyright 2017 Cloudbase Solutions, SRL. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import functools from oslo_concurrency import lockutils from oslo_log import log as logging from vdibroker.applications.pool import manager as pool_manager from vdibroker.db import api as db_api from vdibroker.db.sqlalchemy import models from vdibroker import constants from vdibroker import exception VERSION = "1.0" LOG = logging.getLogger(__name__) def application_synchronized(func): @functools.wraps(func) def wrapper(self, ctxt, application_id, *args, **kwargs): @lockutils.synchronized(application_id) def inner(): return func(self, ctxt, application_id, *args, **kwargs) return inner() return wrapper def remote_session_synchronized(func): @functools.wraps(func) def wrapper(self, ctxt, session_id, *args, **kwargs): @lockutils.synchronized(session_id) def inner(): return func(self, ctxt, session_id, *args, **kwargs) return inner() return wrapper class ConductorServerEndpoint(object): def create_application(self, ctxt, name, description, application_type, image_data, pool_size): application = models.Application() application.name = name application.description = description application.type = application_type application.image_data = image_data application.instances_data = [] application.pool_size = pool_size db_api.add_application(ctxt, application) LOG.info("Application created: %s", application.id) pool_manager.start_pool_manager(ctxt, application.id) return self.get_application(ctxt, application.id) def get_applications(self, ctxt): return db_api.get_applications(ctxt) @application_synchronized def get_application(self, ctxt, application_id): return self._get_application(ctxt, application_id) def _get_application(self, ctxt, application_id): application = db_api.get_application(ctxt, application_id) if not application: raise exception.NotFound("Application not found") return application @application_synchronized def delete_application(self, ctxt, application_id): pool_manager.stop_pool_manager(ctxt, application_id) db_api.delete_application(ctxt, application_id) @application_synchronized def add_application_instances_data(self, ctxt, application_id, instances_data): application = self._get_application(ctxt, application_id) application.instances_data.extend(instances_data) db_api.update_application(ctxt, application) @application_synchronized def create_remote_session(self, ctxt, application_id): application = self._get_application(ctxt, application_id) if not application.instances_data: raise exception.ApplicationInstanceUnavailable() instance_id, floating_ip = application.instances_data.pop(0) remote_session = models.RemoteSession() remote_session.application_id = application_id remote_session.instance_id = instance_id remote_session.connection_data = { "host": floating_ip, "port": constants.RDP_PORT} db_api.add_remote_session(ctxt, remote_session) LOG.info("Remote session created: %s", remote_session.id) db_api.update_application(ctxt, application) return self.get_remote_session(ctxt, remote_session.id) def get_remote_sessions(self, ctxt, application_id): return db_api.get_remote_sessions(ctxt, application_id) @remote_session_synchronized def get_remote_session(self, ctxt, session_id): session = db_api.get_remote_session(ctxt, session_id) if not session: raise exception.NotFound("Remote session not found") return session @remote_session_synchronized def delete_remote_session(self, ctxt, session_id): db_api.delete_remote_session(ctxt, session_id)