Ovirt

【Ovirt 笔记】spice 连接虚拟机机制的实现分析

2017-07-20  本文已影响7人  58bc06151329

分析整理的版本为 Ovirt 3.4.5 版本。

连接虚拟机

private void connectToConsoles() {
    StringBuilder errorMessages = null;

    final List<VM> list = getSelectedItems();
    if (list == null || list.isEmpty()) {
        return;
    }

    for (VM vm : list) {
        try {
            consoleModelsCache.getVmConsolesForEntity(vm).connect();
......
public void connect() throws ConsoleConnectException {
    if (!canConnectToConsole()) {
        throw new ConsoleConnectException(connectErrorMessage());
    }

    getConsoleModel(getSelectedProcotol().getBackingClass()).getConnectCommand().execute();
}
protected abstract void connect();
@Override
protected void connect() {
    if (spiceTime == null) {
        spiceTime = new Date();
    } else {
        Date test = new Date();
        long ste = test.getTime() - spiceTime.getTime();
        if (test.getTime() - spiceTime.getTime() < 1000 * 1) {
            getLogger().debug("double click too fast..."); //$NON-NLS-1$
            return;
        }
        spiceTime = test;
    }
    if (getEntity() != null) {
        getLogger().debug("Connecting to Spice console..."); //$NON-NLS-1$
        if (!getspice().getIsInstalled()) {
            getLogger().info("Spice client is not installed."); //$NON-NLS-1$
            getspice().install();
            return;
        }

        // Check a spice version.
        if (getConfigurator().getIsAdmin()
                && getspice().getCurrentVersion().compareTo(getspice().getDesiredVersion()) < 0)
        {
            getLogger().info("Spice client version is not as desired (" + getspice().getDesiredVersion() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
            getspice().install();
            return;
        }

        // Don't connect if there VM is not running on any host.
        if (getEntity().getRunOnVds() == null)
        {
            return;
        }

        // If it is not windows or SPICE guest agent is not installed, make sure the WAN options are disabled.
        if (!AsyncDataProvider.isWindowsOsType(getEntity().getVmOsId()) || !getEntity().getHasSpiceDriver()) {
            getspice().setWanOptionsEnabled(false);
        }

        UICommand setVmTicketCommand = new UICommand("setVmCommand", new BaseCommandTarget() { //$NON-NLS-1$
            @Override
            public void executeCommand(UICommand uiCommand) {
                setVmTicket();
            }
        });
        executeCommandWithConsoleSafenessWarning(setVmTicketCommand);
    }
}
private void setVmTicket() {
    // Create ticket for single sign on.
    Frontend.getInstance().runAction(VdcActionType.SetVmTicket, new SetVmTicketParameters(getEntity().getId(), null, 120),
            new IFrontendActionAsyncCallback() {
                @Override
                public void executed(FrontendActionAsyncResult result) {

                    SpiceConsoleModel spiceConsoleModel = (SpiceConsoleModel) result.getState();
                    spiceConsoleModel.postSendVmTicket(result.getReturnValue());

                }
            }, this);
}
status = getBroker().setVmTicket(mVmId.toString(), mTicket, String.valueOf(mValidTime),connectionAction, params);

构造 vv 文件

private void fillModels() {
    SpiceConsoleModel spiceConsoleModel = new SpiceConsoleModel(vm, parentModel);
    spiceConsoleModel.getErrorEvent().addListener(new ConsoleModelErrorEventListener(parentModel));
    spiceConsoleModel.setForceVmStatusUp(myContext == ConsoleOptionsFrontendPersister.ConsoleContext.UP_BASIC);
    consoleModels.put(ConsoleProtocol.SPICE, spiceConsoleModel);
......
setConsoleClientMode(getDefaultConsoleMode());
protected ClientConsoleMode getDefaultConsoleMode() {
    return ClientConsoleMode.valueOf((String) AsyncDataProvider
            .getConfigValuePreConverted(ConfigurationValues.ClientModeSpiceDefault));
}
public enum ClientConsoleMode { Native, Plugin, Auto, Html5 }
[root@localhost ~]# engine-config -g ClientModeSpiceDefault
ClientModeSpiceDefault: Auto version: general
switch (consoleMode) {
    case Native:
        setspice((ISpice) TypeResolver.getInstance().resolve(ISpiceNative.class));
        break;
    case Plugin:
        setspice((ISpice) TypeResolver.getInstance().resolve(ISpicePlugin.class));
        break;
    case Html5:
        setspice((ISpice) TypeResolver.getInstance().resolve(ISpiceHtml5.class));
        break;
    default:
        ISpicePlugin pluginSpice = (ISpicePlugin) TypeResolver.getInstance().resolve(ISpicePlugin.class);
        setspice(pluginSpice.detectBrowserPlugin() ? pluginSpice
                : (ISpice) TypeResolver.getInstance().resolve(ISpiceNative.class));
    break;
}
} else if (type == ISpiceNative.class) {
    return new SpiceNativeImpl();
SpiceConsoleModel spiceConsoleModel = (SpiceConsoleModel) result.getState();
spiceConsoleModel.postSendVmTicket(result.getReturnValue());
public void postSendVmTicket(VdcReturnValueBase returnValue) {
......
executeQuery(getEntity());
private void executeQuery(final VM vm) {
......
Frontend.getInstance().runMultipleQueries(queryTypeList, parametersList, thisSpiceConsoleModel);
@Override
public void executed(FrontendMultipleQueryAsyncResult result) {
......
if (StringHelper.isNullOrEmpty(getEntity().getDisplayIp()) || StringHelper.stringsEqual(getEntity().getDisplayIp(), "0")) {
    determineIpAndConnect(getEntity().getId());
} else {
    // Try to connect.
    spiceConnect();
}
public void spiceConnect()
{
    try {
        getspice().connect();
    } catch (RuntimeException ex) {
        getLogger().error("Exception on Spice connect", ex); //$NON-NLS-1$
    }
}
@Override
public void connect() {
    StringBuilder configBuilder = new StringBuilder("[virt-viewer]"); //$NON-NLS-1$

    int fullscreen = 0;
    if (isFullScreen()) {
        fullscreen = 1;
    }

    int enableSmartcard = 0;
    if (isSmartcardEnabled()) {
        enableSmartcard = 1;
    }

    int usbAutoShare = 0;
    if (getUsbAutoShare()) {
        usbAutoShare = 1;
    }

    configBuilder.append("\ntype=spice") //$NON-NLS-1$
        .append("\nhost=").append(getHost()) //$NON-NLS-1$
        .append("\nport=").append(Integer.toString(getPort())) //$NON-NLS-1$
        .append("\npassword=").append(getPassword()) //$NON-NLS-1$
        .append("\ntls-port=").append(getSecurePort()) //$NON-NLS-1$
        .append("\nfullscreen=").append(fullscreen) //$NON-NLS-1$
        .append("\ntitle=").append(getTitle()) //$NON-NLS-1$
        .append("\nenable-smartcard=").append(enableSmartcard) //$NON-NLS-1$
        .append("\nenable-usb-autoshare=").append(usbAutoShare) //$NON-NLS-1$
        .append("\ndelete-this-file=1") //$NON-NLS-1$
        .append("\nusb-filter=").append(getUsbFilter()) //$NON-NLS-1$
        .append("\nvideo-qmax=").append(getSpiceVideoQMax()); //$NON-NLS-1$

    if (getCipherSuite() != null) {
        configBuilder.append("\ntls-ciphers=").append(getCipherSuite()); //$NON-NLS-1$
    }

    if (!StringHelper.isNullOrEmpty(getHostSubject())) {
        configBuilder.append("\nhost-subject=").append(getHostSubject()); //$NON-NLS-1$
    }

    if (getTrustStore() != null) {
        //virt-viewer-file doesn't want newlines in ca
        String trustStore= getTrustStore().replace("\n", "\\n");  //$NON-NLS-1$ $NON-NLS-2$
        configBuilder.append("\nca=").append(trustStore); //$NON-NLS-1$
    }

    if (isWanOptionsEnabled()) {
        configBuilder.append("\ncolor-depth=").append(colorDepthAsInt()) //$NON-NLS-1$
            .append("\ndisable-effects=").append(disableEffectsAsString()); //$NON-NLS-1$
    }

    if (!StringHelper.isNullOrEmpty(getToggleFullscreenHotKey())) {
        configBuilder.append("\ntoggle-fullscreen=").append(getToggleFullscreenHotKey()); //$NON-NLS-1$
    }

    if (!StringHelper.isNullOrEmpty(getReleaseCursorHotKey())) {
        configBuilder.append("\nrelease-cursor=").append(getReleaseCursorHotKey()); //$NON-NLS-1$
    }

    if (isRemapCtrlAltDel() && !StringHelper.isNullOrEmpty(getSecureAttentionMapping())) {
        configBuilder.append("\nsecure-attention=").append(getSecureAttentionMapping()); //$NON-NLS-1$
    }

    if (!StringHelper.isNullOrEmpty(getSpiceProxy())) {
        configBuilder.append("\nproxy=").append(getSpiceProxy()); //$NON-NLS-1$
    }

    if (!StringHelper.isNullOrEmpty(getSslChanels())) {
        configBuilder.append("\nsecure-channels=").append(formatSecureChannels(getSslChanels())); //$NON-NLS-1$
    }

    ConsoleModel.makeConsoleConfigRequest("console.vv", "application/x-virt-viewer; charset=UTF-8", configBuilder.toString()); //$NON-NLS-1$ $NON-NLS-2$
}
上一篇 下一篇

猜你喜欢

热点阅读