def create(cinder_client,
           args={},
           status_timeout=15,
           status_attempts=20,
           **kwargs):

    external_volume = use_external_resource(
        ctx, cinder_client, VOLUME_OPENSTACK_TYPE, VOLUME_OPENSTACK_ID_KEY)

    if external_volume:
        _set_volume_runtime_properties(external_volume)
        return

    volume_dict = create_object_dict(ctx, VOLUME_OPENSTACK_TYPE, args, {})
    handle_image_from_relationship(volume_dict, 'imageRef', ctx)

    v = cinder_client.volumes.create(**volume_dict)

    ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = v.id
    ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \
        VOLUME_OPENSTACK_TYPE
    ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = \
        volume_dict[VOLUME_OPENSTACK_ID_KEY]
    wait_until_status(cinder_client=cinder_client,
                      volume_id=v.id,
                      status=VOLUME_STATUS_AVAILABLE,
                      num_tries=status_attempts,
                      timeout=status_timeout,
                      )
    _set_volume_runtime_properties(v)
예제 #2
0
    def validate_server_property_value_exists(server_props, property_name):
        ctx.logger.debug(
            'checking whether {0} exists...'.format(property_name))

        serv_props_copy = server_props.copy()
        try:
            handle_image_from_relationship(serv_props_copy, 'image', ctx)
            _handle_image_or_flavor(serv_props_copy, nova_client,
                                    property_name)
        except (NonRecoverableError, nova_exceptions.NotFound) as e:
            # temporary error - once image/flavor_name get removed, these
            # errors won't be relevant anymore
            err = str(e)
            ctx.logger.error('VALIDATION ERROR: ' + err)
            raise NonRecoverableError(err)

        prop_value_id = str(serv_props_copy[property_name])
        prop_values = list(nova_client.cosmo_list(property_name))
        for f in prop_values:
            if prop_value_id == f.id:
                ctx.logger.debug('OK: {0} exists'.format(property_name))
                return
        err = '{0} {1} does not exist'.format(property_name, prop_value_id)
        ctx.logger.error('VALIDATION ERROR: ' + err)
        if prop_values:
            ctx.logger.info('list of available {0}s:'.format(property_name))
            for f in prop_values:
                ctx.logger.info('    {0:>10} - {1}'.format(f.id, f.name))
        else:
            ctx.logger.info('there are no available {0}s'.format(
                property_name))
        raise NonRecoverableError(err)
예제 #3
0
def create(cinder_client, status_attempts, status_timeout, args, **kwargs):

    if use_external_resource(ctx, cinder_client, VOLUME_OPENSTACK_TYPE,
                             'name'):
        return

    name = get_resource_id(ctx, VOLUME_OPENSTACK_TYPE)
    volume_dict = {'name': name}
    volume_dict.update(ctx.node.properties['volume'], **args)
    handle_image_from_relationship(volume_dict, 'imageRef', ctx)
    volume_dict['name'] = transform_resource_name(ctx, volume_dict['name'])

    v = cinder_client.volumes.create(**volume_dict)

    ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = v.id
    ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \
        VOLUME_OPENSTACK_TYPE
    ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = \
        volume_dict['name']
    wait_until_status(
        cinder_client=cinder_client,
        volume_id=v.id,
        status=VOLUME_STATUS_AVAILABLE,
        num_tries=status_attempts,
        timeout=status_timeout,
    )
    ctx.instance.runtime_properties[OPENSTACK_AZ_PROPERTY] = \
        v.availability_zone
예제 #4
0
def create(cinder_client, status_attempts, status_timeout, args, **kwargs):

    if use_external_resource(ctx, cinder_client, VOLUME_OPENSTACK_TYPE,
                             'name'):
        return

    name = get_resource_id(ctx, VOLUME_OPENSTACK_TYPE)
    volume_dict = {'name': name}
    volume_dict.update(ctx.node.properties['volume'], **args)
    handle_image_from_relationship(volume_dict, 'imageRef', ctx)
    volume_dict['name'] = transform_resource_name(
        ctx, volume_dict['name'])

    v = cinder_client.volumes.create(**volume_dict)

    ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = v.id
    ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \
        VOLUME_OPENSTACK_TYPE
    ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = \
        volume_dict['name']
    wait_until_status(cinder_client=cinder_client,
                      volume_id=v.id,
                      status=VOLUME_STATUS_AVAILABLE,
                      num_tries=status_attempts,
                      timeout=status_timeout,
                      )
    ctx.instance.runtime_properties[OPENSTACK_AZ_PROPERTY] = \
        v.availability_zone
예제 #5
0
    def validate_server_property_value_exists(server_props, property_name):
        ctx.logger.debug(
            'checking whether {0} exists...'.format(property_name))

        serv_props_copy = server_props.copy()
        try:
            handle_image_from_relationship(serv_props_copy, 'image', ctx)
            _handle_image_or_flavor(serv_props_copy, nova_client,
                                    property_name)
        except (NonRecoverableError, nova_exceptions.NotFound) as e:
            # temporary error - once image/flavor_name get removed, these
            # errors won't be relevant anymore
            err = str(e)
            ctx.logger.error('VALIDATION ERROR: ' + err)
            raise NonRecoverableError(err)

        prop_value_id = str(serv_props_copy[property_name])
        prop_values = list(nova_client.cosmo_list(property_name))
        for f in prop_values:
            if prop_value_id == f.id:
                ctx.logger.debug('OK: {0} exists'.format(property_name))
                return
        err = '{0} {1} does not exist'.format(property_name, prop_value_id)
        ctx.logger.error('VALIDATION ERROR: ' + err)
        if prop_values:
            ctx.logger.info('list of available {0}s:'.format(property_name))
            for f in prop_values:
                ctx.logger.info('    {0:>10} - {1}'.format(f.id, f.name))
        else:
            ctx.logger.info('there are no available {0}s'.format(
                property_name))
        raise NonRecoverableError(err)
예제 #6
0
def create(nova_client, neutron_client, args, **kwargs):
    """
    Creates a server. Exposes the parameters mentioned in
    http://docs.openstack.org/developer/python-novaclient/api/novaclient.v1_1
    .servers.html#novaclient.v1_1.servers.ServerManager.create
    """

    external_server = use_external_resource(ctx, nova_client,
                                            SERVER_OPENSTACK_TYPE)

    if external_server:
        _set_network_and_ip_runtime_properties(external_server)
        if ctx._local:
            return
        else:
            network_ids = \
                get_openstack_ids_of_connected_nodes_by_openstack_type(
                    ctx, NETWORK_OPENSTACK_TYPE)
            port_ids = get_openstack_ids_of_connected_nodes_by_openstack_type(
                ctx, PORT_OPENSTACK_TYPE)
            try:
                _validate_external_server_nics(
                    neutron_client,
                    network_ids,
                    port_ids
                )
                _validate_external_server_keypair(nova_client)
                return
            except Exception:
                delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS)
                raise

    provider_context = provider(ctx)

    def rename(name):
        return transform_resource_name(ctx, name)

    server = {
        'name': get_resource_id(ctx, SERVER_OPENSTACK_TYPE),
    }
    server.update(copy.deepcopy(ctx.node.properties['server']))
    server.update(copy.deepcopy(args))

    _handle_boot_volume(server, ctx)
    handle_image_from_relationship(server, 'image', ctx)

    if 'meta' not in server:
        server['meta'] = dict()

    transform_resource_name(ctx, server)

    ctx.logger.debug(
        "server.create() server before transformations: {0}".format(server))

    if ('block_device_mapping' in server or
            'block_device_mapping_v2' in server) \
            and 'image' not in server:
        # python-novaclient requires an image field even if BDM is used.
        server['image'] = ctx.node.properties.get('image')
    else:
        _handle_image_or_flavor(server, nova_client, 'image')
    _handle_image_or_flavor(server, nova_client, 'flavor')

    if provider_context.agents_security_group:
        security_groups = server.get('security_groups', [])
        asg = provider_context.agents_security_group['name']
        if asg not in security_groups:
            security_groups.append(asg)
        server['security_groups'] = security_groups
    elif not server.get('security_groups', []):
        # Make sure that if the server is connected to a security group
        # from CREATE time so that there the user can control
        # that there is never a time that a running server is not protected.
        security_group_names = \
            get_openstack_names_of_connected_nodes_by_openstack_type(
                ctx,
                SECURITY_GROUP_OPENSTACK_TYPE)
        server['security_groups'] = security_group_names

    # server keypair handling
    keypair_id = get_openstack_id_of_single_connected_node_by_openstack_type(
        ctx, KEYPAIR_OPENSTACK_TYPE, True)

    if 'key_name' in server:
        if keypair_id:
            raise NonRecoverableError("server can't both have the "
                                      '"key_name" nested property and be '
                                      'connected to a keypair via a '
                                      'relationship at the same time')
        server['key_name'] = rename(server['key_name'])
    elif keypair_id:
        server['key_name'] = _get_keypair_name_by_id(nova_client, keypair_id)
    elif provider_context.agents_keypair:
        server['key_name'] = provider_context.agents_keypair['name']
    else:
        server['key_name'] = None
        ctx.logger.info(
            'server must have a keypair, yet no keypair was connected to the '
            'server node, the "key_name" nested property '
            "wasn't used, and there is no agent keypair in the provider "
            "context. Agent installation can have issues.")

    _fail_on_missing_required_parameters(
        server,
        ('name', 'flavor'),
        'server')

    _prepare_server_nics(neutron_client, ctx, server)

    # server group handling
    server_group_id = \
        get_openstack_id_of_single_connected_node_by_openstack_type(
            ctx, SERVER_GROUP_OPENSTACK_TYPE, True)
    if server_group_id:
        scheduler_hints = server.get('scheduler_hints', {})
        scheduler_hints['group'] = server_group_id
        server['scheduler_hints'] = scheduler_hints

    ctx.logger.debug(
        "server.create() server after transformations: {0}".format(server))

    userdata.handle_userdata(server)

    ctx.logger.info("Creating VM with parameters: {0}".format(str(server)))
    # Store the server dictionary contents in runtime properties
    assign_payload_as_runtime_properties(ctx, SERVER_OPENSTACK_TYPE, server)
    ctx.logger.debug(
        "Asking Nova to create server. All possible parameters are: [{0}]"
        .format(','.join(server.keys())))

    try:
        s = nova_client.servers.create(**server)
    except nova_exceptions.BadRequest as e:
        if 'Block Device Mapping is Invalid' in str(e):
            return ctx.operation.retry(
                message='Block Device Mapping is not created yet',
                retry_after=30)
        raise
    ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s.id
    ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \
        SERVER_OPENSTACK_TYPE
    ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server['name']
예제 #7
0
def create(nova_client, neutron_client, args, **kwargs):
    """
    Creates a server. Exposes the parameters mentioned in
    http://docs.openstack.org/developer/python-novaclient/api/novaclient.v1_1
    .servers.html#novaclient.v1_1.servers.ServerManager.create
    """

    external_server = use_external_resource(ctx, nova_client,
                                            SERVER_OPENSTACK_TYPE)

    if external_server:
        _set_network_and_ip_runtime_properties(external_server)
        if ctx._local:
            return
        else:
            network_ids = \
                get_openstack_ids_of_connected_nodes_by_openstack_type(
                    ctx, NETWORK_OPENSTACK_TYPE)
            port_ids = get_openstack_ids_of_connected_nodes_by_openstack_type(
                ctx, PORT_OPENSTACK_TYPE)
            try:
                _validate_external_server_nics(
                    neutron_client,
                    network_ids,
                    port_ids
                )
                _validate_external_server_keypair(nova_client)
                return
            except Exception:
                delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS)
                raise

    provider_context = provider(ctx)

    def rename(name):
        return transform_resource_name(ctx, name)

    server = {
        'name': get_resource_id(ctx, SERVER_OPENSTACK_TYPE),
    }
    server.update(copy.deepcopy(ctx.node.properties['server']))
    server.update(copy.deepcopy(args))

    _handle_boot_volume(server, ctx)
    handle_image_from_relationship(server, 'image', ctx)

    if 'meta' not in server:
        server['meta'] = dict()

    transform_resource_name(ctx, server)

    ctx.logger.debug(
        "server.create() server before transformations: {0}".format(server))

    if ('block_device_mapping' in server or
            'block_device_mapping_v2' in server) \
            and 'image' not in server:
        # python-novaclient requires an image field even if BDM is used.
        server['image'] = ctx.node.properties.get('image')
    else:
        _handle_image_or_flavor(server, nova_client, 'image')
    _handle_image_or_flavor(server, nova_client, 'flavor')

    if provider_context.agents_security_group:
        security_groups = server.get('security_groups', [])
        asg = provider_context.agents_security_group['name']
        if asg not in security_groups:
            security_groups.append(asg)
        server['security_groups'] = security_groups
    elif not server.get('security_groups', []):
        # Make sure that if the server is connected to a security group
        # from CREATE time so that there the user can control
        # that there is never a time that a running server is not protected.
        security_group_names = \
            get_openstack_names_of_connected_nodes_by_openstack_type(
                ctx,
                SECURITY_GROUP_OPENSTACK_TYPE)
        server['security_groups'] = security_group_names

    # server keypair handling
    keypair_id = get_openstack_id_of_single_connected_node_by_openstack_type(
        ctx, KEYPAIR_OPENSTACK_TYPE, True)

    if 'key_name' in server:
        if keypair_id:
            raise NonRecoverableError("server can't both have the "
                                      '"key_name" nested property and be '
                                      'connected to a keypair via a '
                                      'relationship at the same time')
        server['key_name'] = rename(server['key_name'])
    elif keypair_id:
        server['key_name'] = _get_keypair_name_by_id(nova_client, keypair_id)
    elif provider_context.agents_keypair:
        server['key_name'] = provider_context.agents_keypair['name']
    else:
        server['key_name'] = None
        ctx.logger.info(
            'server must have a keypair, yet no keypair was connected to the '
            'server node, the "key_name" nested property '
            "wasn't used, and there is no agent keypair in the provider "
            "context. Agent installation can have issues.")

    _fail_on_missing_required_parameters(
        server,
        ('name', 'flavor'),
        'server')

    _prepare_server_nics(neutron_client, ctx, server)

    # server group handling
    server_group_id = \
        get_openstack_id_of_single_connected_node_by_openstack_type(
            ctx, SERVER_GROUP_OPENSTACK_TYPE, True)
    if server_group_id:
        scheduler_hints = server.get('scheduler_hints', {})
        scheduler_hints['group'] = server_group_id
        server['scheduler_hints'] = scheduler_hints

    ctx.logger.debug(
        "server.create() server after transformations: {0}".format(server))

    userdata.handle_userdata(server)

    ctx.logger.info("Creating VM with parameters: {0}".format(str(server)))
    # Store the server dictionary contents in runtime properties
    assign_payload_as_runtime_properties(ctx, SERVER_OPENSTACK_TYPE, server)
    ctx.logger.debug(
        "Asking Nova to create server. All possible parameters are: {0})"
        .format(','.join(server.keys())))

    try:
        s = nova_client.servers.create(**server)
    except nova_exceptions.BadRequest as e:
        if 'Block Device Mapping is Invalid' in str(e):
            return ctx.operation.retry(
                message='Block Device Mapping is not created yet',
                retry_after=30)
        raise
    ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s.id
    ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \
        SERVER_OPENSTACK_TYPE
    ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server['name']
def create(nova_client, neutron_client, args, **kwargs):
    """
    Creates a server. Exposes the parameters mentioned in
    http://docs.openstack.org/developer/python-novaclient/api/novaclient.v1_1
    .servers.html#novaclient.v1_1.servers.ServerManager.create
    """

    external_server = use_external_resource(ctx, nova_client,
                                            SERVER_OPENSTACK_TYPE)

    if external_server:
        _set_network_and_ip_runtime_properties(external_server)
        if ctx._local:
            return
        else:
            network_ids = \
                get_openstack_ids_of_connected_nodes_by_openstack_type(
                    ctx, NETWORK_OPENSTACK_TYPE)
            port_ids = get_openstack_ids_of_connected_nodes_by_openstack_type(
                ctx, PORT_OPENSTACK_TYPE)
            try:
                _validate_external_server_nics(
                    neutron_client,
                    network_ids,
                    port_ids
                )
                _validate_external_server_keypair(nova_client)
                return
            except Exception:
                delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS)
                raise

    provider_context = provider(ctx)

    def rename(name):
        return transform_resource_name(ctx, name)

    server = {
        'name': get_resource_id(ctx, SERVER_OPENSTACK_TYPE),
    }
    server.update(copy.deepcopy(ctx.node.properties['server']))
    server.update(copy.deepcopy(args))

    _handle_boot_volume(server, ctx)
    handle_image_from_relationship(server, 'image', ctx)

    if 'meta' not in server:
        server['meta'] = dict()

    transform_resource_name(ctx, server)

    ctx.logger.debug(
        "server.create() server before transformations: {0}".format(server))

    for key in 'block_device_mapping', 'block_device_mapping_v2':
        if key in server:
            # if there is a connected boot volume, don't require the `image`
            # property.
            # However, python-novaclient requires an `image` input anyway, and
            # checks it for truthiness when deciding whether to pass it along
            # to the API
            if 'image' not in server:
                server['image'] = ctx.node.properties.get('image')
            break
    else:
        _handle_image_or_flavor(server, nova_client, 'image')
    _handle_image_or_flavor(server, nova_client, 'flavor')

    if provider_context.agents_security_group:
        security_groups = server.get('security_groups', [])
        asg = provider_context.agents_security_group['name']
        if asg not in security_groups:
            security_groups.append(asg)
        server['security_groups'] = security_groups

    # server keypair handling
    keypair_id = get_openstack_id_of_single_connected_node_by_openstack_type(
        ctx, KEYPAIR_OPENSTACK_TYPE, True)

    if 'key_name' in server:
        if keypair_id:
            raise NonRecoverableError("server can't both have the "
                                      '"key_name" nested property and be '
                                      'connected to a keypair via a '
                                      'relationship at the same time')
        server['key_name'] = rename(server['key_name'])
    elif keypair_id:
        server['key_name'] = _get_keypair_name_by_id(nova_client, keypair_id)
    elif provider_context.agents_keypair:
        server['key_name'] = provider_context.agents_keypair['name']
    else:
        raise NonRecoverableError(
            'server must have a keypair, yet no keypair was connected to the '
            'server node, the "key_name" nested property '
            "wasn't used, and there is no agent keypair in the provider "
            "context")

    _fail_on_missing_required_parameters(
        server,
        ('name', 'flavor', 'key_name'),
        'server')

    _prepare_server_nics(neutron_client, ctx, server)

    ctx.logger.debug(
        "server.create() server after transformations: {0}".format(server))

    userdata.handle_userdata(server)

    ctx.logger.info("Creating VM with parameters: {0}".format(str(server)))
    ctx.logger.debug(
        "Asking Nova to create server. All possible parameters are: {0})"
        .format(','.join(server.keys())))

    try:
        s = nova_client.servers.create(**server)
    except nova_exceptions.BadRequest as e:
        if 'Block Device Mapping is Invalid' in str(e):
            return ctx.operation.retry(
                message='Block Device Mapping is not created yet',
                retry_after=30)
        if str(e).startswith(MUST_SPECIFY_NETWORK_EXCEPTION_TEXT):
            raise NonRecoverableError(
                "Can not provision server: management_network_name or id"
                " is not specified but there are several networks that the "
                "server can be connected to.")
        raise
    ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s.id
    ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \
        SERVER_OPENSTACK_TYPE
    ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server['name']
예제 #9
0
def create(nova_client, neutron_client, args, **kwargs):
    """
    Creates a server. Exposes the parameters mentioned in
    http://docs.openstack.org/developer/python-novaclient/api/novaclient.v1_1
    .servers.html#novaclient.v1_1.servers.ServerManager.create
    """

    external_server = use_external_resource(ctx, nova_client,
                                            SERVER_OPENSTACK_TYPE)

    if external_server:
        _set_network_and_ip_runtime_properties(external_server)
        if ctx._local:
            return
        else:
            network_ids = \
                get_openstack_ids_of_connected_nodes_by_openstack_type(
                    ctx, NETWORK_OPENSTACK_TYPE)
            port_ids = get_openstack_ids_of_connected_nodes_by_openstack_type(
                ctx, PORT_OPENSTACK_TYPE)
            try:
                _validate_external_server_nics(neutron_client, network_ids,
                                               port_ids)
                _validate_external_server_keypair(nova_client)
                return
            except Exception:
                delete_runtime_properties(ctx, RUNTIME_PROPERTIES_KEYS)
                raise

    provider_context = provider(ctx)

    def rename(name):
        return transform_resource_name(ctx, name)

    server = {
        'name': get_resource_id(ctx, SERVER_OPENSTACK_TYPE),
    }
    server.update(copy.deepcopy(ctx.node.properties['server']))
    server.update(copy.deepcopy(args))

    _handle_boot_volume(server, ctx)
    handle_image_from_relationship(server, 'image', ctx)

    if 'meta' not in server:
        server['meta'] = dict()

    transform_resource_name(ctx, server)

    ctx.logger.debug(
        "server.create() server before transformations: {0}".format(server))

    for key in 'block_device_mapping', 'block_device_mapping_v2':
        if key in server:
            # if there is a connected boot volume, don't require the `image`
            # property.
            # However, python-novaclient requires an `image` input anyway, and
            # checks it for truthiness when deciding whether to pass it along
            # to the API
            if 'image' not in server:
                server['image'] = ctx.node.properties.get('image')
            break
    else:
        _handle_image_or_flavor(server, nova_client, 'image')
    _handle_image_or_flavor(server, nova_client, 'flavor')

    if provider_context.agents_security_group:
        security_groups = server.get('security_groups', [])
        asg = provider_context.agents_security_group['name']
        if asg not in security_groups:
            security_groups.append(asg)
        server['security_groups'] = security_groups

    # server keypair handling
    keypair_id = get_openstack_id_of_single_connected_node_by_openstack_type(
        ctx, KEYPAIR_OPENSTACK_TYPE, True)

    if 'key_name' in server:
        if keypair_id:
            raise NonRecoverableError("server can't both have the "
                                      '"key_name" nested property and be '
                                      'connected to a keypair via a '
                                      'relationship at the same time')
        server['key_name'] = rename(server['key_name'])
    elif keypair_id:
        server['key_name'] = _get_keypair_name_by_id(nova_client, keypair_id)
    elif provider_context.agents_keypair:
        server['key_name'] = provider_context.agents_keypair['name']
    else:
        raise NonRecoverableError(
            'server must have a keypair, yet no keypair was connected to the '
            'server node, the "key_name" nested property '
            "wasn't used, and there is no agent keypair in the provider "
            "context")

    _fail_on_missing_required_parameters(server,
                                         ('name', 'flavor', 'key_name'),
                                         'server')

    _prepare_server_nics(neutron_client, ctx, server)

    ctx.logger.debug(
        "server.create() server after transformations: {0}".format(server))

    userdata.handle_userdata(server)

    ctx.logger.info("Creating VM with parameters: {0}".format(str(server)))
    ctx.logger.debug(
        "Asking Nova to create server. All possible parameters are: {0})".
        format(','.join(server.keys())))

    try:
        s = nova_client.servers.create(**server)
    except nova_exceptions.BadRequest as e:
        if 'Block Device Mapping is Invalid' in str(e):
            return ctx.operation.retry(
                message='Block Device Mapping is not created yet',
                retry_after=30)
        if str(e).startswith(MUST_SPECIFY_NETWORK_EXCEPTION_TEXT):
            raise NonRecoverableError(
                "Can not provision server: management_network_name or id"
                " is not specified but there are several networks that the "
                "server can be connected to.")
        raise
    ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = s.id
    ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \
        SERVER_OPENSTACK_TYPE
    ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = server['name']