Beispiel #1
0
 def _get_server_ip(self, server, net_name):
     """Returns service IP address of service instance."""
     net_ips = self._get_addresses_by_network_name(net_name, server)
     if not net_ips:
         msg = _("Failed to get service instance IP address. "
                 "Service network name is '%(net_name)s' "
                 "and provided data are '%(data)s'.")
         msg = msg % {'net_name': net_name, 'data': six.text_type(server)}
         raise exception.ServiceInstanceException(msg)
     return net_ips[0]
Beispiel #2
0
 def _get_private_router(self, neutron_net_id, neutron_subnet_id):
     """Returns router attached to private subnet gateway."""
     private_subnet = self.neutron_api.get_subnet(neutron_subnet_id)
     if not private_subnet['gateway_ip']:
         raise exception.ServiceInstanceException(
             _('Subnet must have gateway.'))
     private_network_ports = [p for p in self.neutron_api.list_ports(
                              network_id=neutron_net_id)]
     for p in private_network_ports:
         fixed_ip = p['fixed_ips'][0]
         if (fixed_ip['subnet_id'] == private_subnet['id'] and
                 fixed_ip['ip_address'] == private_subnet['gateway_ip']):
             private_subnet_gateway_port = p
             break
     else:
         raise exception.ServiceInstanceException(
             _('Subnet gateway is not attached the router.'))
     private_subnet_router = self.neutron_api.show_router(
         private_subnet_gateway_port['device_id'])
     return private_subnet_router
Beispiel #3
0
 def _check_auth_mode(self):
     if self._use_cert_auth:
         if not (os.path.exists(self._cert_pem_path) and
                 os.path.exists(self._cert_key_pem_path)):
             msg = _("Certificate based authentication was configured "
                     "but one or more certificates are missing.")
             raise exception.ServiceInstanceException(msg)
         LOG.debug("Using certificate based authentication for "
                   "service instances.")
     else:
         instance_password = self.get_config_option(
             "service_instance_password")
         if not self._check_password_complexity(instance_password):
             msg = _("The configured service instance password does not "
                     "match the minimum complexity requirements. "
                     "The password must contain at least %s characters. "
                     "Also, it must contain at least one digit, "
                     "one lower case and one upper case character.")
             raise exception.ServiceInstanceException(
                 msg % self._DEFAULT_MINIMUM_PASS_LENGTH)
         LOG.debug("Using password based authentication for "
                   "service instances.")
Beispiel #4
0
 def __init__(self, db, _helpers, *args, **kwargs):
     """Do initialization."""
     super(ServiceInstanceManager, self).__init__()
     self.driver_config = None
     if "driver_config" in kwargs:
         self.driver_config = kwargs["driver_config"]
     if not self.get_config_option("service_instance_user"):
         raise exception.ServiceInstanceException(
             _('Service instance user '
               'is not specified'))
     self.admin_context = context.get_admin_context()
     self._execute = utils.execute
     self.compute_api = compute.API()
     self.neutron_api = neutron.API()
     self._helpers = _helpers
     self.db = db
     attempts = 5
     while attempts:
         try:
             self.service_tenant_id = self.neutron_api.admin_tenant_id
             break
         except exception.NetworkException:
             LOG.debug('Connection to neutron failed.')
             attempts -= 1
             time.sleep(3)
     else:
         raise exception.ServiceInstanceException(
             _('Can not receive '
               'service tenant id.'))
     self.share_networks_servers = {}
     self.service_network_id = self._get_service_network()
     self.vif_driver = importutils.import_class(
         self.get_config_option("interface_driver"))()
     self._setup_connectivity_with_service_instances()
     self.max_time_to_build_instance = self.get_config_option(
         "max_time_to_build_instance")
     self.path_to_private_key = self.get_config_option(
         "path_to_private_key")
     self.path_to_public_key = self.get_config_option("path_to_public_key")
Beispiel #5
0
 def _get_cidr_for_subnet(self):
     """Returns not used cidr for service subnet creating."""
     subnets = self._get_all_service_subnets()
     used_cidrs = set(subnet['cidr'] for subnet in subnets)
     serv_cidr = netaddr.IPNetwork(
         self.get_config_option("service_network_cidr"))
     division_mask = self.get_config_option("service_network_division_mask")
     for subnet in serv_cidr.subnet(division_mask):
         cidr = six.text_type(subnet.cidr)
         if cidr not in used_cidrs:
             return cidr
     else:
         raise exception.ServiceInstanceException(_('No available cidrs.'))
Beispiel #6
0
 def _get_service_network(self):
     """Finds existing or creates new service network."""
     service_network_name = self.get_config_option("service_network_name")
     networks = [network for network in self.neutron_api.
                 get_all_tenant_networks(self.service_tenant_id)
                 if network['name'] == service_network_name]
     if len(networks) > 1:
         raise exception.ServiceInstanceException(_('Ambiguous service '
                                                    'networks.'))
     elif not networks:
         return self.neutron_api.network_create(self.service_tenant_id,
                                                service_network_name)['id']
     else:
         return networks[0]['id']
Beispiel #7
0
    def _join_domain(self, server, domain, admin_username, admin_password):
        # As the WinRM configuration may be altered and existing connections
        # closed, we may not be able to retrieve the result of this operation.
        # Instead, we'll ensure that the instance actually joined the domain
        # after the reboot.
        try:
            self._windows_utils.join_domain(server, domain, admin_username,
                                            admin_password)
        except processutils.ProcessExecutionError:
            raise
        except Exception as exc:
            LOG.debug(
                "Unexpected error while attempting to join domain "
                "%(domain)s. Verifying the result of the operation "
                "after instance reboot. Exception: %(exc)s",
                dict(domain=domain, exc=exc))
        # We reboot the service instance using the Compute API so that
        # we can wait for it to become active.
        self.reboot_server(server, soft_reboot=True)
        self.wait_for_instance_to_be_active(
            server['instance_id'], timeout=self.max_time_to_build_instance)
        if not self._check_server_availability(server):
            raise exception.ServiceInstanceException(
                _('%(conn_proto)s connection has not been '
                  'established to %(server)s in %(time)ss. Giving up.') % {
                      'conn_proto': self._INSTANCE_CONNECTION_PROTO,
                      'server': server['ip'],
                      'time': self.max_time_to_build_instance
                  })

        current_domain = self._windows_utils.get_current_domain(server)
        if current_domain != domain:
            err_msg = _("Failed to join domain %(requested_domain)s. "
                        "Current domain: %(current_domain)s")
            raise exception.ServiceInstanceException(
                err_msg %
                dict(requested_domain=domain, current_domain=current_domain))
Beispiel #8
0
 def _get_server_ip(self, server):
     """Returns service vms ip address."""
     net_name = self.get_config_option("service_network_name")
     net_ips = []
     if 'networks' in server and net_name in server['networks']:
         net_ips = server['networks'][net_name]
     elif 'addresses' in server and net_name in server['addresses']:
         net_ips = [addr['addr'] for addr in server['addresses'][net_name]]
     if not net_ips:
         msg = _("Failed to get service instance ip address. "
                 "Service network name is '%(net_name)s' "
                 "and provided data are '%(data)s'.")
         msg = msg % {'net_name': net_name, 'data': six.text_type(server)}
         raise exception.ServiceInstanceException(msg)
     return net_ips[0]
Beispiel #9
0
 def _get_service_network_id(self):
     """Finds existing or creates new service network."""
     service_network_name = self.get_config_option("service_network_name")
     networks = []
     for network in self.neutron_api.get_all_admin_project_networks():
         if network['name'] == service_network_name:
             networks.append(network)
     if len(networks) > 1:
         raise exception.ServiceInstanceException(
             _('Ambiguous service networks.'))
     elif not networks:
         return self.neutron_api.network_create(self.admin_project_id,
                                                service_network_name)['id']
     else:
         return networks[0]['id']
Beispiel #10
0
 def _delete_server(self, context, server_id):
     """Deletes the server."""
     self.compute_api.server_delete(context, server_id)
     t = time.time()
     while time.time() - t < self.max_time_to_build_instance:
         try:
             self.compute_api.server_get(context, server_id)
         except exception.InstanceNotFound:
             LOG.debug('Service instance was deleted succesfully.')
             break
         time.sleep(1)
     else:
         raise exception.ServiceInstanceException(
             _('Instance have not '
               'been deleted in %ss. Giving up.') %
             self.max_time_to_build_instance)
Beispiel #11
0
    def _get_or_create_security_group(self,
                                      context,
                                      name=None,
                                      description=None):
        """Get or create security group for service_instance.

        :param context: context, that should be used
        :param name: this is used for selection/creation of sec.group
        :param description: this is used on sec.group creation step only
        :returns: SecurityGroup -- security group instance from Nova
        :raises: exception.ServiceInstanceException.
        """
        name = name or self.get_config_option(
            "service_instance_security_group")
        if not name:
            LOG.warning(
                _LW("Name for service instance security group is not "
                    "provided. Skipping security group step."))
            return None
        s_groups = [
            s for s in self.compute_api.security_group_list(context)
            if s.name == name
        ]
        if not s_groups:
            # Creating security group
            if not description:
                description = "This security group is intended "\
                              "to be used by share service."
            LOG.debug("Creating security group with name '%s'.", name)
            sg = self.compute_api.security_group_create(
                context, name, description)
            for protocol, ports in const.SERVICE_INSTANCE_SECGROUP_DATA:
                self.compute_api.security_group_rule_create(
                    context,
                    parent_group_id=sg.id,
                    ip_protocol=protocol,
                    from_port=ports[0],
                    to_port=ports[1],
                    cidr="0.0.0.0/0",
                )
        elif len(s_groups) > 1:
            msg = _("Ambiguous security_groups.")
            raise exception.ServiceInstanceException(msg)
        else:
            sg = s_groups[0]
        return sg
Beispiel #12
0
 def _get_service_subnet(self, subnet_name):
     all_service_subnets = self._get_all_service_subnets()
     service_subnets = [subnet for subnet in all_service_subnets
                        if subnet['name'] == subnet_name]
     if len(service_subnets) == 1:
         return service_subnets[0]
     elif not service_subnets:
         unused_service_subnets = [subnet for subnet in all_service_subnets
                                   if subnet['name'] == '']
         if unused_service_subnets:
             service_subnet = unused_service_subnets[0]
             self.neutron_api.update_subnet(service_subnet['id'],
                                            subnet_name)
             return service_subnet
         return None
     else:
         raise exception.ServiceInstanceException(_('Ambiguous service '
                                                    'subnets.'))
    def _get_service_port(self):
        """Find or creates service neutron port.

        This port will be used for connectivity with service instances.
        """
        ports = [port for port in self.neutron_api.
                 list_ports(device_id='manila-share')]
        if len(ports) > 1:
            raise exception.ServiceInstanceException(
                _('Error. Ambiguous service ports.'))
        elif not ports:
            host = socket.gethostname()
            port = self.neutron_api.create_port(
                self.admin_project_id, self.service_network_id,
                device_id='manila-share', device_owner='manila:share',
                host_id=host)
        else:
            port = ports[0]
        return port
Beispiel #14
0
    def _get_cbs_init_reg_section(self, server):
        base_path = 'hklm:\\SOFTWARE'
        cbs_section = 'Cloudbase Solutions\\Cloudbase-Init'

        for upper_section in ('', 'Wow6432Node'):
            cbs_init_section = self._windows_utils.normalize_path(
                os.path.join(base_path, upper_section, cbs_section))
            try:
                self._windows_utils.get_win_reg_value(
                    server, path=cbs_init_section)
                return cbs_init_section
            except processutils.ProcessExecutionError as ex:
                # The exit code will always be '1' in case of errors, so the
                # only way to determine the error type is checking stderr.
                if 'Cannot find path' in ex.stderr:
                    continue
                else:
                    raise
        raise exception.ServiceInstanceException(
            _("Could not retrieve Cloudbase Init registry section"))
Beispiel #15
0
    def _get_service_port(self, network_id, subnet_id, device_id):
        """Find or creates service neutron port.

        This port will be used for connectivity with service instances.
        """
        host = socket.gethostname()
        search_opts = {'device_id': device_id,
                       'binding:host_id': host}
        ports = [port for port in self.neutron_api.
                 list_ports(**search_opts)]
        if len(ports) > 1:
            raise exception.ServiceInstanceException(
                _('Error. Ambiguous service ports.'))
        elif not ports:
            port = self.neutron_api.create_port(
                self.admin_project_id, network_id, subnet_id=subnet_id,
                device_id=device_id, device_owner='manila:share', host_id=host)
        else:
            port = ports[0]
        return port
Beispiel #16
0
    def __init__(self, driver_config=None):

        super(ServiceInstanceManager, self).__init__()
        self.driver_config = driver_config

        if self.driver_config:
            self.driver_config.append_config_values(common_opts)
            if self.get_config_option("driver_handles_share_servers"):
                self.driver_config.append_config_values(
                    share_servers_handling_mode_opts)
            else:
                self.driver_config.append_config_values(
                    no_share_servers_handling_mode_opts)
        else:
            CONF.register_opts(common_opts)
            if self.get_config_option("driver_handles_share_servers"):
                CONF.register_opts(share_servers_handling_mode_opts)
            else:
                CONF.register_opts(no_share_servers_handling_mode_opts)

        if not self.get_config_option("service_instance_user"):
            raise exception.ServiceInstanceException(
                _('Service instance user is not specified.'))
        self.admin_context = context.get_admin_context()
        self._execute = utils.execute

        self.image_api = image.API()
        self.compute_api = compute.API()

        self.path_to_private_key = self.get_config_option(
            "path_to_private_key")
        self.max_time_to_build_instance = self.get_config_option(
            "max_time_to_build_instance")

        self.availability_zone = self.get_config_option(
            'backend_availability_zone') or CONF.storage_availability_zone

        if self.get_config_option("driver_handles_share_servers"):
            self.path_to_public_key = self.get_config_option(
                "path_to_public_key")
            self._network_helper = None
    def set_up_service_instance(self, context, network_info):
        """Finds or creates and sets up service vm.

        :param context: defines context, that should be used
        :param network_info: network info for getting allocations
        :returns: dict with service instance details
        :raises: exception.ServiceInstanceException
        """
        instance_name = network_info['server_id']
        server = self._create_service_instance(
            context, instance_name, network_info)
        instance_details = self._get_new_instance_details(server)

        if not self._check_server_availability(instance_details):
            raise exception.ServiceInstanceException(
                _('%(conn_proto)s connection has not been '
                  'established to %(server)s in %(time)ss. Giving up.') % {
                      'conn_proto': self._INSTANCE_CONNECTION_PROTO,
                      'server': server['ip'],
                      'time': self.max_time_to_build_instance})

        return instance_details
Beispiel #18
0
    def _create_service_instance(self, context, instance_name, network_info):
        """Creates service vm and sets up networking for it."""
        service_image_id = self._get_service_image(context)
        key_name, key_path = self._get_key(context)
        if not (self.get_config_option("service_instance_password")
                or key_name):
            raise exception.ServiceInstanceException(
                _('Neither service instance password nor key are available.'))
        if not key_path:
            LOG.warning(
                'No key path is available. May be non-existent key path is '
                'provided. Check path_to_private_key (current value '
                '%(private_path)s) and path_to_public_key (current value '
                '%(public_path)s) in manila configuration file.',
                dict(private_path=self.path_to_private_key,
                     public_path=self.path_to_public_key))
        network_data = self.network_helper.setup_network(network_info)
        fail_safe_data = dict(router_id=network_data.get('router_id'),
                              subnet_id=network_data.get('subnet_id'))
        if network_data.get('service_port'):
            fail_safe_data['service_port_id'] = (
                network_data['service_port']['id'])
        if network_data.get('public_port'):
            fail_safe_data['public_port_id'] = (
                network_data['public_port']['id'])
        if network_data.get('admin_port'):
            fail_safe_data['admin_port_id'] = (
                network_data['admin_port']['id'])
        try:
            create_kwargs = self._get_service_instance_create_kwargs()
            service_instance = self.compute_api.server_create(
                context,
                name=instance_name,
                image=service_image_id,
                flavor=self.get_config_option("service_instance_flavor_id"),
                key_name=key_name,
                nics=network_data['nics'],
                availability_zone=self.availability_zone,
                **create_kwargs)

            fail_safe_data['instance_id'] = service_instance['id']

            service_instance = self.wait_for_instance_to_be_active(
                service_instance['id'], self.max_time_to_build_instance)

            if self.get_config_option("limit_ssh_access"):
                try:
                    service_subnet = network_data['service_subnet']
                except KeyError:
                    LOG.error(
                        "Unable to limit ssh access to instance id: '%s'!",
                        fail_safe_data['instance_id'])
                    raise exception.ManilaException(
                        "Unable to limit SSH access - "
                        "invalid service subnet details provided")
            else:
                service_subnet = False

            sec_groups = self._get_or_create_security_groups(
                context, allow_ssh_subnet=service_subnet)

            for sg in sec_groups:
                sg_id = sg['id']
                LOG.debug("Adding security group '%(sg)s' to server '%(si)s'.",
                          dict(sg=sg_id, si=service_instance["id"]))
                self.compute_api.add_security_group_to_server(
                    context, service_instance["id"], sg_id)

            ip = (network_data.get(
                'service_port', network_data.get('admin_port'))['fixed_ips'])
            service_instance['ip'] = ip[0]['ip_address']
            public_ip = (network_data.get(
                'public_port', network_data.get('service_port'))['fixed_ips'])
            service_instance['public_address'] = public_ip[0]['ip_address']

        except Exception as e:
            e.detail_data = {'server_details': fail_safe_data}
            raise

        service_instance.update(fail_safe_data)
        service_instance['pk_path'] = key_path
        for pair in [('router', 'router_id'), ('service_subnet', 'subnet_id')]:
            if pair[0] in network_data and 'id' in network_data[pair[0]]:
                service_instance[pair[1]] = network_data[pair[0]]['id']

        admin_port = network_data.get('admin_port')
        if admin_port:
            try:
                service_instance['admin_ip'] = (
                    admin_port['fixed_ips'][0]['ip_address'])
            except Exception:
                msg = _("Admin port is being used but Admin IP was not found.")
                LOG.exception(msg)
                raise exception.AdminIPNotFound(reason=msg)

        return service_instance
Beispiel #19
0
    def _create_service_instance(self, context, instance_name, network_info):
        """Creates service vm and sets up networking for it."""
        service_image_id = self._get_service_image(context)
        key_name, key_path = self._get_key(context)
        if not (self.get_config_option("service_instance_password")
                or key_name):
            raise exception.ServiceInstanceException(
                _('Neither service instance password nor key are available.'))
        if not key_path:
            LOG.warning(
                _LW('No key path is available. May be non-existent key path is '
                    'provided. Check path_to_private_key (current value '
                    '%(private_path)s) and path_to_public_key (current value '
                    '%(public_path)s) in manila configuration file.'),
                dict(private_path=self.path_to_private_key,
                     public_path=self.path_to_public_key))
        network_data = self.network_helper.setup_network(network_info)
        fail_safe_data = dict(router_id=network_data.get('router_id'),
                              subnet_id=network_data.get('subnet_id'))
        if network_data.get('service_port'):
            fail_safe_data['service_port_id'] = (
                network_data['service_port']['id'])
        if network_data.get('public_port'):
            fail_safe_data['public_port_id'] = (
                network_data['public_port']['id'])
        if network_data.get('admin_port'):
            fail_safe_data['admin_port_id'] = (
                network_data['admin_port']['id'])
        try:
            create_kwargs = self._get_service_instance_create_kwargs()
            service_instance = self.compute_api.server_create(
                context,
                name=instance_name,
                image=service_image_id,
                flavor=self.get_config_option("service_instance_flavor_id"),
                key_name=key_name,
                nics=network_data['nics'],
                availability_zone=CONF.storage_availability_zone,
                **create_kwargs)

            fail_safe_data['instance_id'] = service_instance['id']

            service_instance = self.wait_for_instance_to_be_active(
                service_instance['id'], self.max_time_to_build_instance)

            security_group = self._get_or_create_security_group(context)
            if security_group:
                if self.network_helper.NAME == NOVA_NAME:
                    # NOTE(vponomaryov): Nova-network allows to assign
                    #                    secgroups only by names.
                    sg_id = security_group.name
                else:
                    sg_id = security_group.id
                LOG.debug("Adding security group '%(sg)s' to server '%(si)s'.",
                          dict(sg=sg_id, si=service_instance["id"]))
                self.compute_api.add_security_group_to_server(
                    context, service_instance["id"], sg_id)

            if self.network_helper.NAME == NEUTRON_NAME:
                ip = (network_data.get(
                    'service_port',
                    network_data.get('admin_port'))['fixed_ips'])
                service_instance['ip'] = ip[0]['ip_address']
                public_ip = (network_data.get(
                    'public_port',
                    network_data.get('service_port'))['fixed_ips'])
                service_instance['public_address'] = public_ip[0]['ip_address']
            else:
                net_name = self.network_helper.get_network_name(network_info)
                service_instance['ip'] = self._get_server_ip(
                    service_instance, net_name)
                service_instance['public_address'] = service_instance['ip']

        except Exception as e:
            e.detail_data = {'server_details': fail_safe_data}
            raise

        service_instance.update(fail_safe_data)
        service_instance['pk_path'] = key_path
        for pair in [('router', 'router_id'), ('service_subnet', 'subnet_id')]:
            if pair[0] in network_data and 'id' in network_data[pair[0]]:
                service_instance[pair[1]] = network_data[pair[0]]['id']

        admin_port = network_data.get('admin_port')
        if admin_port:
            try:
                service_instance['admin_ip'] = (
                    admin_port['fixed_ips'][0]['ip_address'])
            except Exception:
                msg = _("Admin port is being used but Admin IP was not found.")
                LOG.exception(msg)
                raise exception.AdminIPNotFound(reason=msg)

        return service_instance
Beispiel #20
0
    def _create_service_instance(self, context, instance_name, neutron_net_id,
                                 neutron_subnet_id):
        """Creates service vm and sets up networking for it."""
        service_image_id = self._get_service_image(context)

        with lock:
            key_name, key_path = self._get_key(context)
            if not (self.get_config_option("service_instance_password")
                    or key_name):
                raise exception.ServiceInstanceException(
                    _('Neither service '
                      'instance password nor key are available.'))

            security_group = self._get_or_create_security_group(context)
            subnet_id, router_id, port_id = \
                self._setup_network_for_instance(neutron_net_id,
                                                 neutron_subnet_id)
            try:
                self._setup_connectivity_with_service_instances()
            except Exception as e:
                LOG.debug(e)
                self.neutron_api.delete_port(port_id)
                raise

        service_instance = self.compute_api.server_create(
            context,
            name=instance_name,
            image=service_image_id,
            flavor=self.get_config_option("service_instance_flavor_id"),
            key_name=key_name,
            nics=[{
                'port-id': port_id
            }])

        t = time.time()
        while time.time() - t < self.max_time_to_build_instance:
            if service_instance['status'] == 'ACTIVE':
                break
            if service_instance['status'] == 'ERROR':
                raise exception.ServiceInstanceException(
                    _('Failed to build service instance.'))
            time.sleep(1)
            try:
                service_instance = self.compute_api.server_get(
                    context, service_instance['id'])
            except exception.InstanceNotFound as e:
                LOG.debug(e)
        else:
            raise exception.ServiceInstanceException(
                _('Instance have not been spawned in %ss. Giving up.') %
                self.max_time_to_build_instance)

        if security_group:
            LOG.debug("Adding security group "
                      "'%s' to server '%s'." %
                      (security_group.id, service_instance["id"]))
            self.compute_api.add_security_group_to_server(
                context, service_instance["id"], security_group.id)

        service_instance['ip'] = self._get_server_ip(service_instance)
        service_instance['pk_path'] = key_path
        service_instance['router_id'] = router_id
        service_instance['subnet_id'] = subnet_id
        service_instance['port_id'] = port_id

        if not self._check_server_availability(service_instance):
            raise exception.ServiceInstanceException(
                _('SSH connection have not been '
                  'established in %ss. Giving up.') %
                self.max_time_to_build_instance)
        return service_instance
Beispiel #21
0
    def _create_service_instance(self, context, instance_name, neutron_net_id,
                                 neutron_subnet_id):
        """Creates service vm and sets up networking for it."""
        service_image_id = self._get_service_image(context)

        with lock:
            key_name, key_path = self._get_key(context)
            if not (self.get_config_option("service_instance_password") or
                    key_name):
                raise exception.ServiceInstanceException(
                    _('Neither service '
                      'instance password nor key are available.'))

            security_group = self._get_or_create_security_group(context)
            network_data = self._setup_network_for_instance(neutron_net_id,
                                                            neutron_subnet_id)
            try:
                self._setup_connectivity_with_service_instances()
            except Exception as e:
                LOG.debug(e)
                for port in network_data['ports']:
                    self.neutron_api.delete_port(port['id'])
                raise

        service_instance = self.compute_api.server_create(
            context,
            name=instance_name,
            image=service_image_id,
            flavor=self.get_config_option("service_instance_flavor_id"),
            key_name=key_name,
            nics=[{'port-id': port['id']} for port in network_data['ports']])

        t = time.time()
        while time.time() - t < self.max_time_to_build_instance:
            # NOTE(vponomaryov): emptiness of 'networks' field is checked as
            #                    workaround for nova/neutron bug #1210483.
            if (service_instance['status'] == 'ACTIVE' and
                    service_instance.get('networks', {})):
                break
            if service_instance['status'] == 'ERROR':
                raise exception.ServiceInstanceException(
                    _('Failed to build service instance.'))
            time.sleep(1)
            try:
                service_instance = self.compute_api.server_get(
                    context,
                    service_instance['id'])
            except exception.InstanceNotFound as e:
                LOG.debug(e)
        else:
            raise exception.ServiceInstanceException(
                _('Instance have not been spawned in %ss. Giving up.') %
                self.max_time_to_build_instance)

        if security_group:
            LOG.debug("Adding security group "
                      "'%s' to server '%s'." % (security_group.id,
                                                service_instance["id"]))
            self.compute_api.add_security_group_to_server(
                context,
                service_instance["id"], security_group.id)

        router, service_subnet, service_port = (
            network_data['router'], network_data['service_subnet'],
            network_data['service_port']
        )

        service_instance['ip'] = self._get_server_ip(service_instance)
        service_instance['pk_path'] = key_path
        service_instance['router_id'] = router['id']
        service_instance['subnet_id'] = service_subnet['id']
        service_instance['port_id'] = service_port['id']

        try:
            public_ip = network_data['public_port']
        except KeyError:
            public_ip = network_data['service_port']
        public_ip = public_ip['fixed_ips']
        public_ip = public_ip[0]
        public_ip = public_ip['ip_address']

        service_instance['public_address'] = public_ip

        if not self._check_server_availability(service_instance):
            raise exception.ServiceInstanceException(
                _('SSH connection have not been '
                  'established in %ss. Giving up.') %
                self.max_time_to_build_instance)

        return service_instance
Beispiel #22
0
    def _create_service_instance(self, context, instance_name, network_info):
        """Creates service vm and sets up networking for it."""
        service_image_id = self._get_service_image(context)
        key_name, key_path = self._get_key(context)
        if not (self.get_config_option("service_instance_password")
                or key_name):
            raise exception.ServiceInstanceException(
                _('Neither service instance password nor key are available.'))
        if not key_path:
            LOG.warning(
                _LW('No key path is available. May be non-existent key path is '
                    'provided. Check path_to_private_key (current value '
                    '%(private_path)s) and path_to_public_key (current value '
                    '%(public_path)s) in manila configuration file.'),
                dict(private_path=self.path_to_private_key,
                     public_path=self.path_to_public_key))
        network_data = self.network_helper.setup_network(network_info)
        fail_safe_data = dict(router_id=network_data.get('router_id'),
                              subnet_id=network_data.get('subnet_id'))
        try:
            service_instance = self.compute_api.server_create(
                context,
                name=instance_name,
                image=service_image_id,
                flavor=self.get_config_option("service_instance_flavor_id"),
                key_name=key_name,
                nics=network_data['nics'])

            fail_safe_data['instance_id'] = service_instance['id']

            t = time.time()
            while time.time() - t < self.max_time_to_build_instance:
                # NOTE(vponomaryov): emptiness of 'networks' field checked as
                #                    workaround for nova/neutron bug #1210483.
                if (service_instance['status'] == 'ACTIVE'
                        and service_instance.get('networks', {})):
                    break
                if service_instance['status'] == 'ERROR':
                    raise exception.ServiceInstanceException(
                        _("Failed to build service instance '%s'.") %
                        service_instance['id'])
                time.sleep(1)
                try:
                    service_instance = self.compute_api.server_get(
                        context, service_instance['id'])
                except exception.InstanceNotFound as e:
                    LOG.debug(e)
            else:
                raise exception.ServiceInstanceException(
                    _("Instance '%(ins)s' has not been spawned in %(timeout)s "
                      "seconds. Giving up.") %
                    dict(ins=service_instance['id'],
                         timeout=self.max_time_to_build_instance))

            security_group = self._get_or_create_security_group(context)
            if security_group:
                if self.network_helper.NAME == NOVA_NAME:
                    # NOTE(vponomaryov): Nova-network allows to assign
                    #                    secgroups only by names.
                    sg_id = security_group.name
                else:
                    sg_id = security_group.id
                LOG.debug("Adding security group '%(sg)s' to server '%(si)s'.",
                          dict(sg=sg_id, si=service_instance["id"]))
                self.compute_api.add_security_group_to_server(
                    context, service_instance["id"], sg_id)

            if self.network_helper.NAME == NEUTRON_NAME:
                service_instance['ip'] = self._get_server_ip(
                    service_instance,
                    self.get_config_option("service_network_name"))
                public_ip = network_data.get(
                    'public_port', network_data['service_port'])['fixed_ips']
                service_instance['public_address'] = public_ip[0]['ip_address']
            else:
                net_name = self.network_helper.get_network_name(network_info)
                service_instance['ip'] = self._get_server_ip(
                    service_instance, net_name)
                service_instance['public_address'] = service_instance['ip']

        except Exception as e:
            e.detail_data = {'server_details': fail_safe_data}
            raise

        service_instance['pk_path'] = key_path
        for pair in [('router', 'router_id'), ('service_subnet', 'subnet_id')]:
            if pair[0] in network_data and 'id' in network_data[pair[0]]:
                service_instance[pair[1]] = network_data[pair[0]]['id']

        return service_instance