Package lcmc.host.ui

Source Code of lcmc.host.ui.HostBrowser

/*
* This file is part of DRBD Management Console by LINBIT HA-Solutions GmbH
* written by Rasto Levrinc.
*
* Copyright (C) 2009, LINBIT HA-Solutions GmbH.
* Copyright (C) 2011-2012, Rastislav Levrinc.
*
* RBD Management Console is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* DRBD Management Console is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with drbd; see the file COPYING.  If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package lcmc.host.ui;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import lcmc.cluster.ui.ClusterBrowser;
import lcmc.common.domain.AccessMode;
import lcmc.common.domain.Application;
import lcmc.cluster.domain.Cluster;
import lcmc.common.ui.Browser;
import lcmc.common.ui.GUIData;
import lcmc.common.ui.treemenu.TreeMenuController;
import lcmc.drbd.ui.DrbdGraph;
import lcmc.event.BlockDevicesChangedEvent;
import lcmc.event.NetInterfacesChangedEvent;
import lcmc.host.domain.Host;
import lcmc.drbd.domain.BlockDevice;
import lcmc.drbd.domain.NetInterface;
import lcmc.common.ui.CmdLog;
import lcmc.common.ui.CategoryInfo;
import lcmc.cluster.ui.resource.FSInfo;
import lcmc.common.ui.Info;
import lcmc.cluster.ui.resource.NetInfo;
import lcmc.crm.ui.resource.HostInfo;
import lcmc.drbd.ui.resource.BlockDevInfo;
import lcmc.drbd.ui.resource.HostDrbdInfo;
import lcmc.common.domain.EnablePredicate;
import lcmc.common.ui.utils.MenuAction;
import lcmc.common.ui.utils.MenuFactory;
import lcmc.common.ui.utils.MyMenu;
import lcmc.common.ui.utils.MyMenuItem;
import lcmc.common.domain.util.Tools;
import lcmc.cluster.service.ssh.ExecCommandConfig;

/**
* This class holds host resource data in a tree. It shows panels that allow
* to edit data of resources, services etc., hosts and clusters.
* Every resource has its Info object, that accessible through the tree view.
*/
@Named
public class HostBrowser extends Browser {
    public static final ImageIcon HOST_ICON = Tools.createImageIcon(Tools.getDefault("HostBrowser.HostIconSmall"));
    public static final ImageIcon HOST_ON_ICON = Tools.createImageIcon(
            Tools.getDefault("HostBrowser.HostOnIconSmall"));
    public static final ImageIcon HOST_OFF_ICON = Tools.createImageIcon(
            Tools.getDefault("HostBrowser.HostOffIconSmall"));
    public static final ImageIcon HOST_ON_ICON_LARGE = Tools.createImageIcon(
            Tools.getDefault("HostBrowser.HostOnIcon"));
    public static final ImageIcon HOST_OFF_ICON_LARGE = Tools.createImageIcon(
            Tools.getDefault("HostBrowser.HostOffIcon"));
    public static final ImageIcon HOST_ICON_LARGE = Tools.createImageIcon(Tools.getDefault("HostBrowser.HostIcon"));
    public static final ImageIcon HOST_REMOVE_ICON = Tools.createImageIcon(Tools.getDefault("HostBrowser.RemoveIcon"));
    /**
     * Small host in cluster icon (right side).
     */
    public static final ImageIcon HOST_IN_CLUSTER_ICON_RIGHT_SMALL =
            Tools.createImageIcon(Tools.getDefault("HostBrowser.HostInClusterIconRightSmall"));
    private DefaultMutableTreeNode netInterfacesNode;
    private DefaultMutableTreeNode blockDevicesNode;
    private DefaultMutableTreeNode fileSystemsNode;

    /**
     * List of used network interface ports.
     */
    private final Collection<String> usedPorts = new HashSet<String>();
    private final Collection<String> usedProxyPorts = new HashSet<String>();
    public Host host;
    @Inject
    private HostInfo hostInfo;
    /**
     * Host info object of the host in drbd view of this browser.
     */
    @Inject
    private HostDrbdInfo hostDrbdInfo;
    /**
     * Map of block devices and their info objects.
     */
    private final Map<BlockDevice, BlockDevInfo> blockDevInfos = new LinkedHashMap<BlockDevice, BlockDevInfo>();
    private final ReadWriteLock mBlockDevInfosLock = new ReentrantReadWriteLock();
    private final Lock mBlockDevInfosReadLock = mBlockDevInfosLock.readLock();
    private final Lock mBlockDevInfosWriteLock = mBlockDevInfosLock.writeLock();
    private final ReadWriteLock mNetInfosLock = new ReentrantReadWriteLock();
    private final Lock mNetInfosReadLock = mNetInfosLock.readLock();
    private final Lock mNetInfosWriteLock = mNetInfosLock.writeLock();
    private final ReadWriteLock mFileSystemsLock = new ReentrantReadWriteLock();
    private final Lock mFileSystemsReadLock = mFileSystemsLock.readLock();
    private final Lock mFileSystemsWriteLock = mFileSystemsLock.writeLock();
    private DefaultMutableTreeNode treeTop;
    @Inject
    private GUIData guiData;
    @Inject
    private Provider<BlockDevInfo> blockDevInfoFactory;
    @Inject
    private Application application;
    @Inject
    private MenuFactory menuFactory;
    @Inject
    private Provider<CmdLog> cmdLogProvider;
    @Resource(name="categoryInfo")
    private CategoryInfo netInterfacesCategory;
    @Resource(name="categoryInfo")
    private CategoryInfo blockDevicesCategory;
    @Resource(name="categoryInfo")
    private CategoryInfo fileSystemsCategory;

    @Inject @Named("netInfo")
    private Provider<NetInfo> netInfoProvider;
    @Inject
    private Provider<FSInfo> fsInfoProvider;
    @Inject
    private TreeMenuController treeMenuController;
    @Inject
    private EventBus eventBus;

    public void init(final Host host) {
        this.host = host;
        hostInfo.init(host, this);
        hostDrbdInfo.init(host, this);
        treeTop = treeMenuController.createMenuTreeTop(hostInfo);
        application.invokeInEdt(new Runnable() {
            @Override
            public void run() {
                initHostResources();
            }
        });
        eventBus.register(this);
    }

    public HostInfo getHostInfo() {
        return hostInfo;
    }

    public Host getHost() {
        return host;
    }

    public DefaultMutableTreeNode getTreeTop() {
        return treeTop;
    }

    public HostDrbdInfo getHostDrbdInfo() {
        return hostDrbdInfo;
    }

    public void initHostResources() {
        netInterfacesCategory.init(Tools.getString("HostBrowser.NetInterfaces"), this);
        netInterfacesNode = treeMenuController.createMenuItem(treeTop, netInterfacesCategory);

        /* block devices */
        blockDevicesCategory.init(Tools.getString("HostBrowser.BlockDevices"), this);
        blockDevicesNode = treeMenuController.createMenuItem(treeTop, blockDevicesCategory);

        /* file systems */
        fileSystemsCategory.init(Tools.getString("HostBrowser.FileSystems"), this);
        fileSystemsNode = treeMenuController.createMenuItem(treeTop, fileSystemsCategory);
    }

    public ClusterBrowser getClusterBrowser() {
        final Cluster c = host.getCluster();
        if (c == null) {
            return null;
        }
        return c.getBrowser();
    }

    public void updateHWResources(
            final String[] fileSystems) {
        /* file systems */
        final HostBrowser thisClass = this;
        final Map<String, FSInfo> oldFilesystems = getFilesystemsMap();
        mFileSystemsWriteLock.lock();
        try {
            treeMenuController.removeChildren(fileSystemsNode);
            for (final String fs : fileSystems) {
                final FSInfo fsi;
                if (oldFilesystems.containsKey(fs)) {
                    fsi = oldFilesystems.get(fs);
                } else {

                    fsi = fsInfoProvider.get();
                    fsi.init(fs, thisClass);
                }
                treeMenuController.addChild(fileSystemsNode,  treeMenuController.createMenuItem(fsi));
            }
            treeMenuController.reloadNode(fileSystemsNode, false);
        } finally {
            mFileSystemsWriteLock.unlock();
        }
    }

    @Subscribe
    public void updateBlockDevicesNodes(final BlockDevicesChangedEvent event) {
        if (event.getHost() != host) {
            return;
        }
        final Collection<BlockDevice> blockDevices = event.getBlockDevices();
        mBlockDevInfosWriteLock.lock();
        boolean changed = false;
        try {
            final Map<BlockDevice, BlockDevInfo> oldBlockDevices = new HashMap<BlockDevice, BlockDevInfo>(blockDevInfos);
            if (oldBlockDevices.size() != blockDevInfos.size()) {
                changed = true;
            }
            blockDevInfos.clear();
            for (final BlockDevice blockDevice : blockDevices) {
                final BlockDevInfo blockDevInfo;
                if (oldBlockDevices.containsKey(blockDevice)) {
                    blockDevInfo = oldBlockDevices.get(blockDevice);
                    blockDevInfo.updateInfo();
                } else {
                    changed = true;
                    blockDevInfo = blockDevInfoFactory.get();
                    blockDevInfo.init(blockDevice.getName(), blockDevice, this);
                }
                blockDevInfos.put(blockDevice, blockDevInfo);
            }
        } finally {
            mBlockDevInfosWriteLock.unlock();
        }
        if (changed) {
            mBlockDevInfosWriteLock.lock();
            try {
                treeMenuController.removeChildren(blockDevicesNode);
                for (final Map.Entry<BlockDevice, BlockDevInfo> bdEntry : blockDevInfos.entrySet()) {
                    final BlockDevInfo bdi = bdEntry.getValue();
                    final MutableTreeNode resource = treeMenuController.createMenuItem(blockDevicesNode, bdi);
                }
                treeMenuController.reloadNode(blockDevicesNode, false);
            } finally {
                mBlockDevInfosWriteLock.unlock();
            }
        }
    }

    @Subscribe
    public void onNetInterfacesChanged(final NetInterfacesChangedEvent event) {
        if (event.getHost() != host) {
            return;
        }
        final Collection<NetInterface> netInterfaces = event.getNetInterfaces();
        final Map<NetInterface, NetInfo> oldNetInterfaces = getNetInterfacesMap();
        final HostBrowser thisClass = this;
        mNetInfosWriteLock.lock();
        try {
            treeMenuController.removeChildren(netInterfacesNode);
            for (final NetInterface netInterface : netInterfaces) {
                final NetInfo netInfo;
                if (oldNetInterfaces.containsKey(netInterface)) {
                    netInfo = oldNetInterfaces.get(netInterface);
                } else {
                    netInfo = netInfoProvider.get();
                    netInfo.init(netInterface.getName(), netInterface, thisClass);
                }
                final DefaultMutableTreeNode resource = treeMenuController.createMenuItem(netInterfacesNode, netInfo);
            }
            treeMenuController.reloadNode(netInterfacesNode, false);
        } finally {
            mNetInfosWriteLock.unlock();
        }
    }


    public Set<BlockDevInfo> getSortedBlockDevInfos() {
        mBlockDevInfosReadLock.lock();
        try {
            return new TreeSet<BlockDevInfo>(blockDevInfos.values());
        } finally {
            mBlockDevInfosReadLock.unlock();
        }
    }

    Map<NetInterface, NetInfo> getNetInterfacesMap() {
        final Map<NetInterface, NetInfo> netInterfaces = new HashMap<NetInterface, NetInfo>();
        mNetInfosReadLock.lock();
        try {
            for (final Info info : treeMenuController.nodesToInfos(netInterfacesNode.children())) {
                final NetInfo netInfo = (NetInfo) info;
                netInterfaces.put(netInfo.getNetInterface(), netInfo);
            }
        } finally {
            mNetInfosReadLock.unlock();
        }
        return netInterfaces;
    }

    Map<String, FSInfo> getFilesystemsMap() {
        final Map<String, FSInfo> filesystems = new HashMap<String, FSInfo>();
        mFileSystemsReadLock.lock();
        try {
            for (final Info info : treeMenuController.nodesToInfos(fileSystemsNode.children())) {
                final FSInfo fsInfo = (FSInfo) info;
                filesystems.put(fsInfo.getName(), fsInfo);
            }
        } finally {
            mFileSystemsReadLock.unlock();
        }
        return filesystems;
    }

    /**
     * Adds advanced submenu to the host menus in drbd and pacemaker view.
     */
    public void addAdvancedMenu(final MyMenu submenu) {
        if (submenu.getItemCount() > 0) {
            return;
        }
        /* Command log */
        final MyMenuItem cmdLogMenuItem = menuFactory.createMenuItem(
                Tools.getString("HostBrowser.CmdLog"),
                Info.LOGFILE_ICON,
                "",
                new AccessMode(AccessMode.ADMIN, AccessMode.NORMAL),
                new AccessMode(AccessMode.ADMIN, AccessMode.NORMAL))

                .enablePredicate(new EnablePredicate() {
                    @Override
                    public String check() {
                        if (!host.isConnected()) {
                            return Host.NOT_CONNECTED_MENU_TOOLTIP_TEXT;
                        }
                        return null;
                    }
                })

                .addAction(new MenuAction() {
                    @Override
                    public void run(final String text) {
                        final CmdLog cmdLog = cmdLogProvider.get();
                        cmdLog.init(host);
                        cmdLog.showDialog();
                    }
                });
        submenu.add(cmdLogMenuItem);

        /* panic */
        final MyMenuItem panicMenuItem = menuFactory.createMenuItem(
                Tools.getString("HostBrowser.MakeKernelPanic") + host.getName(),
                null,
                new AccessMode(AccessMode.GOD, AccessMode.NORMAL),
                new AccessMode(AccessMode.ADMIN, AccessMode.NORMAL))
                .enablePredicate(new EnablePredicate() {
                    @Override
                    public String check() {
                        if (!host.isConnected()) {
                            return Host.NOT_CONNECTED_MENU_TOOLTIP_TEXT;
                        }
                        return null;
                    }
                })
                .addAction(new MenuAction() {
                    @Override
                    public void run(final String text) {
                        final String hostName = host.getName();
                        final String command = "MakeKernelPanic";
                        guiData.startProgressIndicator(hostName, host.getDistString(command));
                        host.execCommand(new ExecCommandConfig().commandString(command));
                        guiData.stopProgressIndicator(hostName, host.getDistString(command));
                    }
                });
        submenu.add(panicMenuItem);

        /* reboot */
        final MyMenuItem rebootMenuItem = menuFactory.createMenuItem(
                Tools.getString("HostBrowser.MakeKernelReboot") + host.getName(),
                null,
                new AccessMode(AccessMode.GOD, AccessMode.NORMAL),
                new AccessMode(AccessMode.ADMIN, AccessMode.NORMAL))
                .enablePredicate(new EnablePredicate() {
                    @Override
                    public String check() {
                        if (!host.isConnected()) {
                            return Host.NOT_CONNECTED_MENU_TOOLTIP_TEXT;
                        }
                        return null;
                    }
                })

                .addAction(new MenuAction() {
                    @Override
                    public void run(final String text) {
                        final String hostName = host.getName();
                        final String command = "MakeKernelReboot";
                        guiData.startProgressIndicator(hostName, host.getDistString(command));
                        host.execCommand(new ExecCommandConfig().commandString(command));
                        guiData.stopProgressIndicator(hostName, host.getDistString(command));
                    }
                });
        submenu.add(rebootMenuItem);
    }

    /**
     * Returns info string about Pacemaker installation.
     */
    public String getPacemakerInfo() {
        final StringBuilder pacemakerInfo = new StringBuilder(40);
        final String pmV = host.getPacemakerVersion();
        final String hbV = host.getHeartbeatVersion();
        final StringBuilder hbRunning = new StringBuilder(20);
        if (host.isHeartbeatRunning()) {
            hbRunning.append("running");
            if (!host.isHeartbeatInRc()) {
                hbRunning.append("/no rc.d");
            }
        } else {
            hbRunning.append("not running");
        }
        if (host.isHeartbeatInRc()) {
            hbRunning.append("/rc.d");
        }
        if (pmV == null) {
            if (hbV != null) {
                pacemakerInfo.append(" \nHeartbeat ");
                pacemakerInfo.append(hbV);
                pacemakerInfo.append(" (");
                pacemakerInfo.append(hbRunning);
                pacemakerInfo.append(')');
            }
        } else {
            final String pmRunning;
            if (host.isCrmStatusOk()) {
                pmRunning = "running";
            } else {
                pmRunning = "not running";
            }
            pacemakerInfo.append(" \nPacemaker ");
            pacemakerInfo.append(pmV);
            pacemakerInfo.append(" (");
            pacemakerInfo.append(pmRunning);
            pacemakerInfo.append(')');
            String corOrAis = null;
            final String corV = host.getCorosyncVersion();
            final String aisV = host.getOpenaisVersion();
            if (corV != null) {
                corOrAis = "Corosync " + corV;
            } else if (aisV != null) {
                corOrAis = "Openais " + aisV;
            }

            if (hbV != null && host.isHeartbeatRunning()) {
                pacemakerInfo.append(" \nHeartbeat ");
                pacemakerInfo.append(hbV);
                pacemakerInfo.append(" (");
                pacemakerInfo.append(hbRunning);
                pacemakerInfo.append(')');
            }
            if (corOrAis != null) {
                pacemakerInfo.append(" \n");
                pacemakerInfo.append(corOrAis);
                pacemakerInfo.append(" (");
                if (host.isCorosyncRunning()
                        || host.isOpenaisRunning()) {
                    pacemakerInfo.append("running");
                    if (!host.isCorosyncInRc() && !host.isOpenaisInRc()) {
                        pacemakerInfo.append("/no rc.d");
                    }
                } else {
                    pacemakerInfo.append("not running");
                }
                if (host.isCorosyncInRc() || host.isOpenaisInRc()) {
                    pacemakerInfo.append("/rc.d");
                }
                pacemakerInfo.append(')');
            }
            if (hbV != null && !host.isHeartbeatRunning()) {
                pacemakerInfo.append(" \nHeartbeat ");
                pacemakerInfo.append(hbV);
                pacemakerInfo.append(" (");
                pacemakerInfo.append(hbRunning);
                pacemakerInfo.append(')');
            }
        }
        return pacemakerInfo.toString();
    }

    public String getHostToolTip(final Host host) {
        final StringBuilder hostToolTip = new StringBuilder(80);
        hostToolTip.append("<b>").append(host.getName()).append("</b>");
        final ClusterBrowser b = getClusterBrowser();
        if (b != null && b.isRealDcHost(host)) {
            hostToolTip.append(" (designated co-ordinator)");
        }
        if (!host.isConnected()) {
            hostToolTip.append('\n');
            hostToolTip.append(Tools.getString("ClusterBrowser.Host.Disconnected"));
        } else if (!host.isDrbdStatusOk() && !host.isCrmStatusOk()) {
            hostToolTip.append('\n');
            hostToolTip.append(Tools.getString("ClusterBrowser.Host.Offline"));
        }
        hostToolTip.append(host.getDrbdInfoAboutInstallation());
        hostToolTip.append(getPacemakerInfo());
        return hostToolTip.toString();
    }

    public DrbdGraph getDrbdGraph() {
        final ClusterBrowser b = getClusterBrowser();
        if (b == null) {
            return null;
        }
        return b.getDrbdGraph();
    }

    /**
     * Returns a list of used network interface ports.
     */
    public Collection<String> getUsedPorts() {
        return usedPorts;
    }

    public Collection<String> getUsedProxyPorts() {
        return usedProxyPorts;
    }

    public void lockBlockDevInfosRead() {
        mBlockDevInfosReadLock.lock();
    }

    public void unlockBlockDevInfosRead() {
        mBlockDevInfosReadLock.unlock();
    }

    public TreeNode getNetInterfacesNode() {
        return netInterfacesNode;
    }
}
TOP

Related Classes of lcmc.host.ui.HostBrowser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.