Esempio n. 1
0
def _reconcile_vios(db_vios, server_vios, context, db_session, dom_factory):
    """
    Will reconcile the database VioServer object to match that of the Server
    VioServer object.

    :param db_vios: The VioServer object in the database.
    :param server_vios: The VioServer object that represents the current state
                        on the server system.
    :param context: The context for the operations
    :param db_session: The database session to use for this transaction
    :param dom_factory: The factory to use to convert the DOM objects.
    """

    msg = (ras.vif_get_msg('info', 'RECONCILE_VIOS_START') %
           {'host': server_vios.get_host_name(),
            'vios': server_vios.lpar_id})
    ras.trace(LOG, __name__, ras.TRACE_DEBUG, msg)

    db_veas = db_vios.get_all_virtual_ethernet_adapters()
    db_seas = db_vios.get_shared_ethernet_adapters()

    srv_veas = server_vios.get_all_virtual_ethernet_adapters()
    srv_seas = server_vios.get_shared_ethernet_adapters()

    # Have to 'load' these objects due to an issue found in 3749.  By calling
    # these, the attributes are loaded into memory.  If we don't do this
    # then when the VEAs change, they may remove themselves from the SEA.
    for db_sea in db_seas:
        db_sea.primary_vea
        db_sea.control_channel
        db_sea.additional_veas

    # Save the rmc_state of the vios.  This may or may not be different than
    # what's already in the db.
    db_vios.rmc_state = server_vios.rmc_state
    ras.trace(LOG, __name__, ras.TRACE_DEBUG,
              'RMC state for lpar %d (%s): %s, ' % (server_vios.lpar_id,
                                                    server_vios.lpar_name,
                                                    server_vios.rmc_state))

    # If the RMC connection is down, then we'll just update the VIOS's
    # rmc_state in the db, no other reconciliation will occur.  Since rmc_state
    # is taken into account when checking whether an adapter is available, we
    # don't need to update all the adapters.
    if server_vios.rmc_state.lower() == 'active':
        # RMC is up, proceed as normal.

        # The first step to reconciliation is the VEAs, as they are input into
        # the SEAs.
        #
        # We start with the idea that all of the VEAs on the VIOS should be
        # removed.  Then the code will parse out from that delete list and
        # create lists of adapters to add and merge.
        db_veas_to_del = dom.shallow_copy_as_ordinary_list(db_veas)
        srv_veas_to_add = []
        srv_veas_to_modify = []

        for srv_vea in srv_veas:
            db_vea = _find_adapter(db_veas, srv_vea.name)
            if db_vea:
                srv_veas_to_modify.append(srv_vea)
                db_veas_to_del.remove(db_vea)
            else:
                srv_veas_to_add.append(srv_vea)

        # We have sorted how each object should be handled.  Handle these
        # before moving on to the SEAs.
        for db_vea in db_veas_to_del:
            _remove_vea(db_vea, db_vios, context, db_session)
        for server_vea in srv_veas_to_modify:
            _reconcile_vea(_find_adapter(db_veas, server_vea.name),
                           server_vea, db_vios, context, db_session)
        for server_vea in srv_veas_to_add:
            _add_vea(server_vea, db_vios, context, db_session, dom_factory)

        # At this point, we have reconciled the VirtualEthernetAdapters.  Next
        # up is the SharedEthernetAdapters, that contain the
        # VirtualEthernetAdapters.
        db_seas_to_del = dom.shallow_copy_as_ordinary_list(db_seas)
        srv_seas_to_add = []
        srv_seas_to_modify = []

        for srv_sea in srv_seas:
            db_sea = _find_adapter(db_seas, srv_sea.name)
            if db_sea:
                srv_seas_to_modify.append(srv_sea)
                db_seas_to_del.remove(db_sea)
            else:
                srv_seas_to_add.append(srv_sea)

        # Now that we have sorted how each object should be handle (Create,
        # Update, or Delete), execute those actions...
        for db_sea in db_seas_to_del:
            _remove_sea(db_sea, db_vios, context, db_session)
        for server_sea in srv_seas_to_modify:
            _reconcile_sea(_find_adapter(db_seas, server_sea.name),
                           server_sea, db_vios, context, db_session)
        for server_sea in srv_seas_to_add:
            _add_sea(server_sea, db_vios, context, db_session, dom_factory)
    else:
        ras.trace(LOG, __name__, ras.TRACE_WARNING,
                  _('RMC state for lpar %(lpar)d (%(lpar_name)s): %(state)s' %
                    {'lpar': server_vios.lpar_id,
                     'lpar_name': server_vios.lpar_name,
                     'state': server_vios.rmc_state}))

    # Whether reconciled or just set rmc_state, we need to save back to the DB.
    _cascade_save(db_vios, context, db_session)

    msg = (ras.vif_get_msg('info', 'RECONCILE_VIOS_END') %
           {'host': server_vios.get_host_name(),
            'vios': server_vios.lpar_id})
    ras.trace(LOG, __name__, ras.TRACE_DEBUG, msg)
Esempio n. 2
0
def _reconcile_host(context, host_data, dom_factory=dom.DOM_Factory(),
                    db_session=None):
    """
    Performs the actual reconciliation at the host level

    :param context: The database context.
    :param host_data: A dictionary of data that represents the latest inventory
                      information on the server.  The data should be in the
                      network DOM format.
    :param dom_factory: Optional factory used to create the DOM objects.  Not
                        required to be set.
    :param db_session: The database session.  Should be started and finalized
                       outside this class.
    """
    if not db_session:
        db_session = session.get_session()

    # Parse the inventory data into a DOM object.  Use the no_db DOM factory
    # as we want to parse into non-DB backed elements to start...
    non_db_fact = dom.No_DB_DOM_Factory()
    server_dom = dom.parse_to_host(host_data, non_db_fact)

    msg = (ras.vif_get_msg('info', 'RECONCILE_HOST_START') %
           {'host': server_dom.host_name})
    ras.trace(LOG, __name__, ras.TRACE_DEBUG, msg)

    # Get the inventory data from the database.
    db_vio_servers = db.vio_server_find_all(context, server_dom.host_name,
                                            db_session)

    # If there are no VIO Servers, the system may be turned off.  It is very
    # unlikely that they are actually removed (all of them at least).
    # Therefore, we flip the SEAs in each VioServer to a state of unavailable
    # and they do not show up in the UI...but are not deleted.
    if len(server_dom.vio_servers) == 0:
        LOG.info(_("Flipping host %s to unavailable due to lack of VioServers"
                   % server_dom.host_name))
        _make_system_unavailable(db_vio_servers, context, db_session)
        return

    # The first step is to find VIO Servers do add/remove/modify.  Those are
    # the three passes that need to be made.
    #
    # We start with the idea that all of the data base items should be removed.
    # From there, we parse down which are still on the system (therefore need
    # to be modified) and then the new adds.
    db_vios_to_del = dom.shallow_copy_as_ordinary_list(db_vio_servers)
    srv_vios_to_add = []
    srv_vios_to_modify = []

    for vio_server in server_dom.vio_servers:
        db_vios = _find_vios(db_vio_servers, vio_server.lpar_id)
        if db_vios:
            srv_vios_to_modify.append(vio_server)
            db_vios_to_del.remove(db_vios)
        else:
            srv_vios_to_add.append(vio_server)

    # Now that we know what to modify/create/delete...loop through each and
    # execute the commands to reconcile
    db_host_dom = dom.Host(server_dom.host_name, db_vio_servers)

    # Save off the network associations first so we can recreate any that
    # need to be later on.
    net_assns = _build_net_assn_dict(
        db.network_association_find_all(context,
                                        db_host_dom.host_name,
                                        db_session))

    for db_vios in db_vios_to_del:
        _remove_vios(db_vios, db_host_dom, context, db_session)
    for server_vios in srv_vios_to_modify:
        _reconcile_vios(_find_vios(db_vio_servers, server_vios.lpar_id),
                        server_vios, context, db_session, dom_factory)
    for server_vios in srv_vios_to_add:
        _add_vios(server_vios, db_host_dom, context, db_session, dom_factory)

    msg = (ras.vif_get_msg('info', 'RECONCILE_HOST_END') %
           {'host': server_dom.host_name})
    ras.trace(LOG, __name__, ras.TRACE_DEBUG, msg)

    # Cleanup NetworkAssociations in case any VIOSes went away or came back.
    _cleanup_network_associations(db_host_dom, net_assns, context, db_session)