Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Commit

Permalink
Introduce VNC console access
Browse files Browse the repository at this point in the history
Based on implementation in kubevirt-web-ui.

Suuport for VNC console type is added.
The user can switch between console types via a dropdown.
  • Loading branch information
mareklibra authored and rawagner committed Nov 27, 2018
1 parent c42fb16 commit b65754c
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 67 deletions.
4 changes: 4 additions & 0 deletions frontend/public/kubevirt/components/_vmconsoles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@
padding: 0;
}
}

.console-terminal-pf {
padding-top: 15px; // fix OKD core vs pf-react styling difference
}
35 changes: 26 additions & 9 deletions frontend/public/kubevirt/components/utils/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,39 @@ export const getFlattenForKind = (kind) => {
return resources => _.get(resources, kind, {}).data;
};

// TODO: move following to web-ui-components
export const isVmiRunning = (vmi) => _.get(vmi, 'status.phase') === 'Running';
export const isVmStarting = (vm, vmi) => _.get(vm, 'spec.running') && !isVmiRunning(vmi);
export const getVmStatus = vm => _.get(vm, 'spec.running', false) ? 'Running' : 'Stopped';

export const getVncConnectionDetails = vmi => {
// Example: ws://localhost:9000/api/kubernetes/apis/subresources.kubevirt.io/v1alpha2/namespaces/kube-system/virtualmachineinstances/vm-cirros1/vnc
const getApiConsoleApiBase = () => {
let base = k8sBasePath;
base = base[0] === '/' ? base.substring(1) : base; // avpid the extra slash when compose the URL by VncConsole
const context = `${base}/apis/subresources.${VirtualMachineInstanceModel.apiGroup}`;
const apiPath = `${VirtualMachineInstanceModel.apiVersion}/namespaces/${vmi.metadata.namespace}/${VirtualMachineInstanceModel.path}/${vmi.metadata.name}`;
const query = `?x-csrf-token=${encodeURIComponent(getCSRFToken())}`;
const encrypt = window.location.protocol === 'https:';
base = base[0] === '/' ? base.substring(1) : base; // avoid the extra slash when compose the URL by VncConsole
return base;
};

const getConsoleApiContext = () => `${getApiConsoleApiBase()}/apis/subresources.${VirtualMachineInstanceModel.apiGroup}`;
const getConsoleApiPath = vmi => `${VirtualMachineInstanceModel.apiVersion}/namespaces/${vmi.metadata.namespace}/${VirtualMachineInstanceModel.path}/${vmi.metadata.name}`;
const getConsoleApiQuery = () => `?x-csrf-token=${encodeURIComponent(getCSRFToken())}`;
const isEncrypted = () => window.location.protocol === 'https:';

export const getVncConnectionDetails = vmi => {
// the novnc library requires protocol to be specified so the URL must be absolute - including host:port
return {
encrypt: isEncrypted(), // whether ws or wss to be used
host: window.location.hostname,
port: window.location.port || (encrypt ? '443' : '80'),
path: `${context}/${apiPath}/vnc${query}`,
port: window.location.port || (isEncrypted() ? '443' : '80'),

// Example: ws://localhost:9000/api/kubernetes/apis/subresources.kubevirt.io/v1alpha2/namespaces/kube-system/virtualmachineinstances/vm-cirros1/vnc
path: `${getConsoleApiContext()}/${getConsoleApiPath(vmi)}/vnc${getConsoleApiQuery()}`,
};
};

export const getSerialConsoleConnectionDetails = vmi => {
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
return {
vmi,
host: `${protocol}://${window.location.hostname}:${window.location.port || (isEncrypted() ? '443' : '80')}`,
path: `/${getConsoleApiContext()}/${getConsoleApiPath(vmi)}/console`, // CSRF Token will be added in WSFactory
};
};
70 changes: 12 additions & 58 deletions frontend/public/kubevirt/components/vmconsoles.jsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,15 @@
import React from 'react';
import { VncConsole } from '@patternfly/react-console';
import { Button } from 'patternfly-react';

import { getLabelMatcher, getResourceKind, getVncConnectionDetails, getFlattenForKind, findVMI, isVmiRunning, isVmStarting } from './utils/resources';
import { getLabelMatcher, getResourceKind, getVncConnectionDetails, getSerialConsoleConnectionDetails, getFlattenForKind, findVMI } from './utils/resources';

import { Firehose } from './utils/okdutils';
import { LoadingInline } from './okdcomponents';
import { WSFactory } from '../module/okdk8s';

import { VirtualMachineInstanceModel, VirtualMachineModel } from '../models';
import { startStopVmModal } from './modals/start-stop-vm-modal';

const VmIsDown = ({ vm }) => {
const action = (
<Button bsStyle="link" onClick={() => startStopVmModal({
kind: VirtualMachineModel,
resource: vm,
start: true,
})}>
start
</Button>);

return (
<div className="co-m-pane__body">
<div className="vm-consoles-loading">
This Virtual Machine is down. Please {action} it to access its console.
</div>
</div>

);
};

const VmIsStarting = () => (
<div className="co-m-pane__body">
<div className="vm-consoles-loading">
<LoadingInline />
This Virtual Machine is still starting up. The console will be available soon.
</div>
</div>
);

/**
* Once design is stabilized, this will go to pf-react's VncConsole.
*/
const ConsoleType = ({ type }) => (
<div className="vmconsoles-type">
<b>Console</b> {type}
</div>
);

/**
* Actual component for consoles.
*/
const VmConsoles = ({ vm, vmi }) => {
if (!isVmiRunning(vmi)) {
return isVmStarting(vm, vmi) ? <VmIsStarting /> : <VmIsDown vm={vm} />;
}

const vncConDetails = getVncConnectionDetails(vmi);
return (
<div className="co-m-pane__body">
<ConsoleType type="VNC" />
<VncConsole {...vncConDetails} />
</div>
);
};
import { VmConsoles } from 'kubevirt-web-ui-components';

/**
* Helper component to keep VmConsoles dependent on VMI only.
Expand All @@ -71,7 +18,14 @@ const FirehoseVmConsoles = props => {
const data = props.flatten(props.resources);
const vmi = props.filter(data);
const vm = props.vm;
return <VmConsoles vm={vm} vmi={vmi} />;

const onStartVm = () => startStopVmModal({
kind: VirtualMachineModel,
resource: vm,
start: true,
});

return <VmConsoles vm={vm} vmi={vmi} onStartVm={onStartVm} getVncConnectionDetails={getVncConnectionDetails} getSerialConsoleConnectionDetails={getSerialConsoleConnectionDetails} LoadingComponent={LoadingInline} WSFactory={WSFactory} />;
};

/**
Expand Down
1 change: 1 addition & 0 deletions frontend/public/kubevirt/module/okdk8s.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// kubevirt uses indirect references to OKD-core
export * from '../../module/k8s';
export { default as actions } from '../../module/k8s/k8s-actions';
export { WSFactory as WSFactory } from '../../module/ws-factory';

0 comments on commit b65754c

Please sign in to comment.