parent
8b05486945
commit
8971d218bb
@ -500,7 +500,6 @@ export async function set (params) {
|
|||||||
const vmId = VM._xapiId
|
const vmId = VM._xapiId
|
||||||
|
|
||||||
const resourceSetId = extract(params, 'resourceSet')
|
const resourceSetId = extract(params, 'resourceSet')
|
||||||
|
|
||||||
if (resourceSetId !== undefined) {
|
if (resourceSetId !== undefined) {
|
||||||
if (this.user.permission !== 'admin') {
|
if (this.user.permission !== 'admin') {
|
||||||
throw unauthorized()
|
throw unauthorized()
|
||||||
@ -509,6 +508,11 @@ export async function set (params) {
|
|||||||
await this.setVmResourceSet(vmId, resourceSetId)
|
await this.setVmResourceSet(vmId, resourceSetId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const share = extract(params, 'share')
|
||||||
|
if (share) {
|
||||||
|
await this.shareVmResourceSet(vmId)
|
||||||
|
}
|
||||||
|
|
||||||
return xapi.editVm(vmId, params, async (limits, vm) => {
|
return xapi.editVm(vmId, params, async (limits, vm) => {
|
||||||
const resourceSet = xapi.xo.getData(vm, 'resourceSet')
|
const resourceSet = xapi.xo.getData(vm, 'resourceSet')
|
||||||
|
|
||||||
@ -580,6 +584,8 @@ set.params = {
|
|||||||
|
|
||||||
// Move the vm In to/Out of Self Service
|
// Move the vm In to/Out of Self Service
|
||||||
resourceSet: { type: ['string', 'null'], optional: true },
|
resourceSet: { type: ['string', 'null'], optional: true },
|
||||||
|
|
||||||
|
share: { type: 'boolean', optional: true },
|
||||||
}
|
}
|
||||||
|
|
||||||
set.resolve = {
|
set.resolve = {
|
||||||
|
@ -391,10 +391,18 @@ export default class {
|
|||||||
await this._xo.removeAclsForObject(vmId)
|
await this._xo.removeAclsForObject(vmId)
|
||||||
}
|
}
|
||||||
if (resourceSetId != null) {
|
if (resourceSetId != null) {
|
||||||
const { subjects } = await this.getResourceSet(resourceSetId)
|
await this.shareVmResourceSet(vmId)
|
||||||
await asyncMap(subjects, subject =>
|
|
||||||
this._xo.addAcl(subject, vmId, 'admin')
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async shareVmResourceSet (vmId) {
|
||||||
|
const xapi = this._xo.getXapi(vmId)
|
||||||
|
const resourceSetId = xapi.xo.getData(vmId, 'resourceSet')
|
||||||
|
if (resourceSetId === undefined) {
|
||||||
|
throw new Error('the vm is not in a resource set')
|
||||||
|
}
|
||||||
|
|
||||||
|
const { subjects } = await this.getResourceSet(resourceSetId)
|
||||||
|
await asyncMap(subjects, subject => this._xo.addAcl(subject, vmId, 'admin'))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -844,6 +844,7 @@ const messages = {
|
|||||||
// ----- VM advanced tab -----
|
// ----- VM advanced tab -----
|
||||||
vmRemoveButton: 'Remove',
|
vmRemoveButton: 'Remove',
|
||||||
vmConvertButton: 'Convert',
|
vmConvertButton: 'Convert',
|
||||||
|
vmShareButton: 'Share',
|
||||||
xenSettingsLabel: 'Xen settings',
|
xenSettingsLabel: 'Xen settings',
|
||||||
guestOsLabel: 'Guest OS',
|
guestOsLabel: 'Guest OS',
|
||||||
miscLabel: 'Misc',
|
miscLabel: 'Misc',
|
||||||
@ -1252,6 +1253,9 @@ const messages = {
|
|||||||
deleteRemotesModalMessage:
|
deleteRemotesModalMessage:
|
||||||
'Are you sure you want to delete {nRemotes, number} remote{nRemotes, plural, one {} other {s}}?',
|
'Are you sure you want to delete {nRemotes, number} remote{nRemotes, plural, one {} other {s}}?',
|
||||||
revertVmModalTitle: 'Revert your VM',
|
revertVmModalTitle: 'Revert your VM',
|
||||||
|
shareVmInResourceSetModalTitle: 'Share your VM',
|
||||||
|
shareVmInResourceSetModalMessage:
|
||||||
|
'This VM will be shared with all the members of the self-service {self}. Are you sure?',
|
||||||
deleteVifsModalTitle: 'Delete VIF{nVifs, plural, one {} other {s}}',
|
deleteVifsModalTitle: 'Delete VIF{nVifs, plural, one {} other {s}}',
|
||||||
deleteVifsModalMessage:
|
deleteVifsModalMessage:
|
||||||
'Are you sure you want to delete {nVifs, number} VIF{nVifs, plural, one {} other {s}}?',
|
'Are you sure you want to delete {nVifs, number} VIF{nVifs, plural, one {} other {s}}?',
|
||||||
|
@ -24,6 +24,7 @@ import { forbiddenOperation, noHostsAvailable } from 'xo-common/api-errors'
|
|||||||
import _ from '../intl'
|
import _ from '../intl'
|
||||||
import invoke from '../invoke'
|
import invoke from '../invoke'
|
||||||
import logError from '../log-error'
|
import logError from '../log-error'
|
||||||
|
import renderXoItem from '../render-xo-item'
|
||||||
import store from 'store'
|
import store from 'store'
|
||||||
import { alert, chooseAction, confirm } from '../modal'
|
import { alert, chooseAction, confirm } from '../modal'
|
||||||
import { error, info, success } from '../notification'
|
import { error, info, success } from '../notification'
|
||||||
@ -1171,6 +1172,14 @@ export const createVgpu = (vm, { gpuGroup, vgpuType }) =>
|
|||||||
|
|
||||||
export const deleteVgpu = vgpu => _call('vm.deleteVgpu', resolveIds({ vgpu }))
|
export const deleteVgpu = vgpu => _call('vm.deleteVgpu', resolveIds({ vgpu }))
|
||||||
|
|
||||||
|
export const shareVm = (vm, resourceSet) =>
|
||||||
|
confirm({
|
||||||
|
title: _('shareVmInResourceSetModalTitle'),
|
||||||
|
body: _('shareVmInResourceSetModalMessage', {
|
||||||
|
self: renderXoItem(resourceSet),
|
||||||
|
}),
|
||||||
|
}).then(() => editVm(vm, { share: true }), noop)
|
||||||
|
|
||||||
// DISK ---------------------------------------------------------------
|
// DISK ---------------------------------------------------------------
|
||||||
|
|
||||||
export const createDisk = (name, size, sr, { vm, bootable, mode, position }) =>
|
export const createDisk = (name, size, sr, { vm, bootable, mode, position }) =>
|
||||||
|
@ -356,6 +356,10 @@
|
|||||||
@extend .text-primary;
|
@extend .text-primary;
|
||||||
@extend .fa-ship;
|
@extend .fa-ship;
|
||||||
}
|
}
|
||||||
|
&-share {
|
||||||
|
@extend .fa;
|
||||||
|
@extend .fa-list-alt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic states
|
// Generic states
|
||||||
|
@ -24,9 +24,9 @@ import {
|
|||||||
osFamily,
|
osFamily,
|
||||||
} from 'utils'
|
} from 'utils'
|
||||||
import {
|
import {
|
||||||
createVgpu,
|
|
||||||
cloneVm,
|
cloneVm,
|
||||||
convertVmToTemplate,
|
convertVmToTemplate,
|
||||||
|
createVgpu,
|
||||||
deleteVgpu,
|
deleteVgpu,
|
||||||
deleteVm,
|
deleteVm,
|
||||||
editVm,
|
editVm,
|
||||||
@ -34,6 +34,7 @@ import {
|
|||||||
recoveryStartVm,
|
recoveryStartVm,
|
||||||
restartVm,
|
restartVm,
|
||||||
resumeVm,
|
resumeVm,
|
||||||
|
shareVm,
|
||||||
stopVm,
|
stopVm,
|
||||||
subscribeResourceSets,
|
subscribeResourceSets,
|
||||||
suspendVm,
|
suspendVm,
|
||||||
@ -41,7 +42,12 @@ import {
|
|||||||
XEN_DEFAULT_CPU_WEIGHT,
|
XEN_DEFAULT_CPU_WEIGHT,
|
||||||
XEN_VIDEORAM_VALUES,
|
XEN_VIDEORAM_VALUES,
|
||||||
} from 'xo'
|
} from 'xo'
|
||||||
import { createGetObjectsOfType, createSelector, isAdmin } from 'selectors'
|
import {
|
||||||
|
createGetObjectsOfType,
|
||||||
|
createSelector,
|
||||||
|
getCheckPermissions,
|
||||||
|
isAdmin,
|
||||||
|
} from 'selectors'
|
||||||
|
|
||||||
const forceReboot = vm => restartVm(vm, true)
|
const forceReboot = vm => restartVm(vm, true)
|
||||||
const forceShutdown = vm => stopVm(vm, true)
|
const forceShutdown = vm => stopVm(vm, true)
|
||||||
@ -122,6 +128,31 @@ class ResourceSetItem extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@addSubscriptions({
|
||||||
|
resourceSets: subscribeResourceSets,
|
||||||
|
})
|
||||||
|
class ShareVmButton extends Component {
|
||||||
|
_shareVm = () => {
|
||||||
|
const { resourceSets, vm } = this.props
|
||||||
|
|
||||||
|
return shareVm(vm, {
|
||||||
|
...find(resourceSets, { id: vm.resourceSet }),
|
||||||
|
type: 'resourceSet',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<TabButton
|
||||||
|
btnStyle='primary'
|
||||||
|
handler={this._shareVm}
|
||||||
|
icon='vm-share'
|
||||||
|
labelId='vmShareButton'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class NewVgpu extends Component {
|
class NewVgpu extends Component {
|
||||||
get value () {
|
get value () {
|
||||||
return this.state
|
return this.state
|
||||||
@ -284,340 +315,352 @@ export default connectStore(() => {
|
|||||||
createSelector(getVgpus, vgpus => map(vgpus, 'gpuGroup'))
|
createSelector(getVgpus, vgpus => map(vgpus, 'gpuGroup'))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const getCanAdministrate = createSelector(
|
||||||
|
getCheckPermissions,
|
||||||
|
(_, props) => props.vm.id,
|
||||||
|
(check, id) => check(id, 'administrate')
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
canAdministrate: getCanAdministrate,
|
||||||
gpuGroup: getGpuGroup,
|
gpuGroup: getGpuGroup,
|
||||||
isAdmin,
|
isAdmin,
|
||||||
vgpus: getVgpus,
|
vgpus: getVgpus,
|
||||||
vgpuTypes: getVgpuTypes,
|
vgpuTypes: getVgpuTypes,
|
||||||
}
|
}
|
||||||
})(({ container, gpuGroup, isAdmin, vgpus, vgpuTypes, vm }) => (
|
})(
|
||||||
<Container>
|
({ canAdministrate, container, gpuGroup, isAdmin, vgpus, vgpuTypes, vm }) => (
|
||||||
<Row>
|
<Container>
|
||||||
<Col className='text-xs-right'>
|
<Row>
|
||||||
{vm.power_state === 'Running' && (
|
<Col className='text-xs-right'>
|
||||||
<span>
|
{(isAdmin || canAdministrate) &&
|
||||||
<TabButton
|
vm.resourceSet != null && <ShareVmButton vm={vm} />}
|
||||||
btnStyle='primary'
|
{vm.power_state === 'Running' && (
|
||||||
handler={suspendVm}
|
<span>
|
||||||
handlerParam={vm}
|
<TabButton
|
||||||
icon='vm-suspend'
|
btnStyle='primary'
|
||||||
labelId='suspendVmLabel'
|
handler={suspendVm}
|
||||||
/>
|
handlerParam={vm}
|
||||||
<TabButton
|
icon='vm-suspend'
|
||||||
btnStyle='warning'
|
labelId='suspendVmLabel'
|
||||||
handler={forceReboot}
|
/>
|
||||||
handlerParam={vm}
|
<TabButton
|
||||||
icon='vm-force-reboot'
|
btnStyle='warning'
|
||||||
labelId='forceRebootVmLabel'
|
handler={forceReboot}
|
||||||
/>
|
handlerParam={vm}
|
||||||
<TabButton
|
icon='vm-force-reboot'
|
||||||
btnStyle='warning'
|
labelId='forceRebootVmLabel'
|
||||||
handler={forceShutdown}
|
/>
|
||||||
handlerParam={vm}
|
<TabButton
|
||||||
icon='vm-force-shutdown'
|
btnStyle='warning'
|
||||||
labelId='forceShutdownVmLabel'
|
handler={forceShutdown}
|
||||||
/>
|
handlerParam={vm}
|
||||||
</span>
|
icon='vm-force-shutdown'
|
||||||
)}
|
labelId='forceShutdownVmLabel'
|
||||||
{vm.power_state === 'Halted' && (
|
/>
|
||||||
<span>
|
</span>
|
||||||
<TabButton
|
)}
|
||||||
btnStyle='primary'
|
{vm.power_state === 'Halted' && (
|
||||||
handler={recoveryStartVm}
|
<span>
|
||||||
handlerParam={vm}
|
<TabButton
|
||||||
icon='vm-recovery-mode'
|
btnStyle='primary'
|
||||||
labelId='recoveryModeLabel'
|
handler={recoveryStartVm}
|
||||||
/>
|
handlerParam={vm}
|
||||||
<TabButton
|
icon='vm-recovery-mode'
|
||||||
btnStyle='primary'
|
labelId='recoveryModeLabel'
|
||||||
handler={fullCopy}
|
/>
|
||||||
handlerParam={vm}
|
<TabButton
|
||||||
icon='vm-clone'
|
btnStyle='primary'
|
||||||
labelId='cloneVmLabel'
|
handler={fullCopy}
|
||||||
/>
|
handlerParam={vm}
|
||||||
<TabButton
|
icon='vm-clone'
|
||||||
btnStyle='danger'
|
labelId='cloneVmLabel'
|
||||||
handler={convertVmToTemplate}
|
/>
|
||||||
handlerParam={vm}
|
<TabButton
|
||||||
icon='vm-create-template'
|
btnStyle='danger'
|
||||||
labelId='vmConvertButton'
|
handler={convertVmToTemplate}
|
||||||
redirectOnSuccess='/'
|
handlerParam={vm}
|
||||||
/>
|
icon='vm-create-template'
|
||||||
</span>
|
labelId='vmConvertButton'
|
||||||
)}
|
redirectOnSuccess='/'
|
||||||
{vm.power_state === 'Suspended' && (
|
/>
|
||||||
<span>
|
</span>
|
||||||
<TabButton
|
)}
|
||||||
btnStyle='primary'
|
{vm.power_state === 'Suspended' && (
|
||||||
handler={resumeVm}
|
<span>
|
||||||
handlerParam={vm}
|
<TabButton
|
||||||
icon='vm-start'
|
btnStyle='primary'
|
||||||
labelId='resumeVmLabel'
|
handler={resumeVm}
|
||||||
/>
|
handlerParam={vm}
|
||||||
<TabButton
|
icon='vm-start'
|
||||||
btnStyle='warning'
|
labelId='resumeVmLabel'
|
||||||
handler={forceShutdown}
|
/>
|
||||||
handlerParam={vm}
|
<TabButton
|
||||||
icon='vm-force-shutdown'
|
btnStyle='warning'
|
||||||
labelId='forceShutdownVmLabel'
|
handler={forceShutdown}
|
||||||
/>
|
handlerParam={vm}
|
||||||
</span>
|
icon='vm-force-shutdown'
|
||||||
)}
|
labelId='forceShutdownVmLabel'
|
||||||
<TabButton
|
/>
|
||||||
btnStyle='danger'
|
</span>
|
||||||
handler={deleteVm}
|
)}
|
||||||
handlerParam={vm}
|
<TabButton
|
||||||
icon='vm-delete'
|
btnStyle='danger'
|
||||||
labelId='vmRemoveButton'
|
handler={deleteVm}
|
||||||
/>
|
handlerParam={vm}
|
||||||
</Col>
|
icon='vm-delete'
|
||||||
</Row>
|
labelId='vmRemoveButton'
|
||||||
<Row>
|
/>
|
||||||
<Col>
|
</Col>
|
||||||
<h3>{_('xenSettingsLabel')}</h3>
|
</Row>
|
||||||
<table className='table'>
|
<Row>
|
||||||
<tbody>
|
<Col>
|
||||||
<tr>
|
<h3>{_('xenSettingsLabel')}</h3>
|
||||||
<th>{_('uuid')}</th>
|
<table className='table'>
|
||||||
<Copiable tagName='td'>{vm.uuid}</Copiable>
|
<tbody>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>{_('virtualizationMode')}</th>
|
|
||||||
<td>
|
|
||||||
{vm.virtualizationMode === 'pv'
|
|
||||||
? _('paraVirtualizedMode')
|
|
||||||
: _('hardwareVirtualizedMode')}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{vm.virtualizationMode === 'pv' && (
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>{_('pvArgsLabel')}</th>
|
<th>{_('uuid')}</th>
|
||||||
|
<Copiable tagName='td'>{vm.uuid}</Copiable>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{_('virtualizationMode')}</th>
|
||||||
<td>
|
<td>
|
||||||
<Text
|
{vm.virtualizationMode === 'pv'
|
||||||
value={vm.PV_args}
|
? _('paraVirtualizedMode')
|
||||||
onChange={value => editVm(vm, { PV_args: value })}
|
: _('hardwareVirtualizedMode')}
|
||||||
/>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
{vm.virtualizationMode === 'pv' && (
|
||||||
<tr>
|
<tr>
|
||||||
<th>{_('cpuWeightLabel')}</th>
|
<th>{_('pvArgsLabel')}</th>
|
||||||
<td>
|
<td>
|
||||||
<Number
|
<Text
|
||||||
value={vm.cpuWeight == null ? null : vm.cpuWeight}
|
value={vm.PV_args}
|
||||||
onChange={value => editVm(vm, { cpuWeight: value })}
|
onChange={value => editVm(vm, { PV_args: value })}
|
||||||
nullable
|
/>
|
||||||
>
|
</td>
|
||||||
{vm.cpuWeight == null
|
</tr>
|
||||||
? _('defaultCpuWeight', { value: XEN_DEFAULT_CPU_WEIGHT })
|
)}
|
||||||
: vm.cpuWeight}
|
|
||||||
</Number>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>{_('cpuCapLabel')}</th>
|
|
||||||
<td>
|
|
||||||
<Number
|
|
||||||
value={vm.cpuCap == null ? null : vm.cpuCap}
|
|
||||||
onChange={value => editVm(vm, { cpuCap: value })}
|
|
||||||
nullable
|
|
||||||
>
|
|
||||||
{vm.cpuCap == null
|
|
||||||
? _('defaultCpuCap', { value: XEN_DEFAULT_CPU_CAP })
|
|
||||||
: vm.cpuCap}
|
|
||||||
</Number>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>{_('autoPowerOn')}</th>
|
|
||||||
<td>
|
|
||||||
<Toggle
|
|
||||||
value={Boolean(vm.auto_poweron)}
|
|
||||||
onChange={value => editVm(vm, { auto_poweron: value })}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>{_('ha')}</th>
|
|
||||||
<td>
|
|
||||||
<Toggle
|
|
||||||
value={vm.high_availability}
|
|
||||||
onChange={value => editVm(vm, { high_availability: value })}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>{_('vmAffinityHost')}</th>
|
|
||||||
<td>
|
|
||||||
<AffinityHost vm={vm} />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{vm.virtualizationMode === 'hvm' && (
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>{_('vmVgpus')}</th>
|
<th>{_('cpuWeightLabel')}</th>
|
||||||
<td>
|
<td>
|
||||||
<Vgpus vgpus={vgpus} vm={vm} />
|
<Number
|
||||||
|
value={vm.cpuWeight == null ? null : vm.cpuWeight}
|
||||||
|
onChange={value => editVm(vm, { cpuWeight: value })}
|
||||||
|
nullable
|
||||||
|
>
|
||||||
|
{vm.cpuWeight == null
|
||||||
|
? _('defaultCpuWeight', { value: XEN_DEFAULT_CPU_WEIGHT })
|
||||||
|
: vm.cpuWeight}
|
||||||
|
</Number>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
|
||||||
{vm.virtualizationMode === 'hvm' && (
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>{_('vmVga')}</th>
|
<th>{_('cpuCapLabel')}</th>
|
||||||
|
<td>
|
||||||
|
<Number
|
||||||
|
value={vm.cpuCap == null ? null : vm.cpuCap}
|
||||||
|
onChange={value => editVm(vm, { cpuCap: value })}
|
||||||
|
nullable
|
||||||
|
>
|
||||||
|
{vm.cpuCap == null
|
||||||
|
? _('defaultCpuCap', { value: XEN_DEFAULT_CPU_CAP })
|
||||||
|
: vm.cpuCap}
|
||||||
|
</Number>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{_('autoPowerOn')}</th>
|
||||||
<td>
|
<td>
|
||||||
<Toggle
|
<Toggle
|
||||||
value={vm.vga === 'std'}
|
value={Boolean(vm.auto_poweron)}
|
||||||
onChange={value =>
|
onChange={value => editVm(vm, { auto_poweron: value })}
|
||||||
editVm(vm, { vga: value ? 'std' : 'cirrus' })
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
|
||||||
{vm.vga === 'std' && (
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>{_('vmVideoram')}</th>
|
<th>{_('ha')}</th>
|
||||||
<td>
|
<td>
|
||||||
<select
|
<Toggle
|
||||||
className='form-control'
|
value={vm.high_availability}
|
||||||
onChange={event =>
|
onChange={value => editVm(vm, { high_availability: value })}
|
||||||
editVm(vm, { videoram: +getEventValue(event) })
|
/>
|
||||||
}
|
|
||||||
value={vm.videoram}
|
|
||||||
>
|
|
||||||
{map(XEN_VIDEORAM_VALUES, val => (
|
|
||||||
<option key={val} value={val}>
|
|
||||||
{formatSize(val * 1048576)}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
<tr>
|
||||||
</tbody>
|
<th>{_('vmAffinityHost')}</th>
|
||||||
</table>
|
<td>
|
||||||
<br />
|
<AffinityHost vm={vm} />
|
||||||
<h3>{_('vmLimitsLabel')}</h3>
|
</td>
|
||||||
<table className='table table-hover'>
|
</tr>
|
||||||
<tbody>
|
{vm.virtualizationMode === 'hvm' && (
|
||||||
<tr>
|
<tr>
|
||||||
<th>{_('vmCpuLimitsLabel')}</th>
|
<th>{_('vmVgpus')}</th>
|
||||||
<td>
|
<td>
|
||||||
<Number
|
<Vgpus vgpus={vgpus} vm={vm} />
|
||||||
value={vm.CPUs.number}
|
</td>
|
||||||
onChange={cpus => editVm(vm, { cpus })}
|
</tr>
|
||||||
/>
|
)}
|
||||||
/
|
{vm.virtualizationMode === 'hvm' && (
|
||||||
{vm.power_state === 'Running' ? (
|
<tr>
|
||||||
vm.CPUs.max
|
<th>{_('vmVga')}</th>
|
||||||
) : (
|
<td>
|
||||||
|
<Toggle
|
||||||
|
value={vm.vga === 'std'}
|
||||||
|
onChange={value =>
|
||||||
|
editVm(vm, { vga: value ? 'std' : 'cirrus' })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{vm.vga === 'std' && (
|
||||||
|
<tr>
|
||||||
|
<th>{_('vmVideoram')}</th>
|
||||||
|
<td>
|
||||||
|
<select
|
||||||
|
className='form-control'
|
||||||
|
onChange={event =>
|
||||||
|
editVm(vm, { videoram: +getEventValue(event) })
|
||||||
|
}
|
||||||
|
value={vm.videoram}
|
||||||
|
>
|
||||||
|
{map(XEN_VIDEORAM_VALUES, val => (
|
||||||
|
<option key={val} value={val}>
|
||||||
|
{formatSize(val * 1048576)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br />
|
||||||
|
<h3>{_('vmLimitsLabel')}</h3>
|
||||||
|
<table className='table table-hover'>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>{_('vmCpuLimitsLabel')}</th>
|
||||||
|
<td>
|
||||||
<Number
|
<Number
|
||||||
value={vm.CPUs.max}
|
value={vm.CPUs.number}
|
||||||
onChange={cpusStaticMax => editVm(vm, { cpusStaticMax })}
|
onChange={cpus => editVm(vm, { cpus })}
|
||||||
/>
|
/>
|
||||||
)}
|
/
|
||||||
</td>
|
{vm.power_state === 'Running' ? (
|
||||||
</tr>
|
vm.CPUs.max
|
||||||
<tr>
|
) : (
|
||||||
<th>{_('vmCpuTopology')}</th>
|
<Number
|
||||||
<td>
|
value={vm.CPUs.max}
|
||||||
<CoresPerSocket container={container} vm={vm} />
|
onChange={cpusStaticMax => editVm(vm, { cpusStaticMax })}
|
||||||
</td>
|
/>
|
||||||
</tr>
|
)}
|
||||||
<tr>
|
</td>
|
||||||
<th>{_('vmMemoryLimitsLabel')}</th>
|
</tr>
|
||||||
<td>
|
<tr>
|
||||||
<p>
|
<th>{_('vmCpuTopology')}</th>
|
||||||
Static: {formatSize(vm.memory.static[0])}/<Size
|
<td>
|
||||||
value={defined(vm.memory.static[1], null)}
|
<CoresPerSocket container={container} vm={vm} />
|
||||||
onChange={memoryStaticMax =>
|
</td>
|
||||||
editVm(vm, { memoryStaticMax })
|
</tr>
|
||||||
}
|
<tr>
|
||||||
/>
|
<th>{_('vmMemoryLimitsLabel')}</th>
|
||||||
</p>
|
<td>
|
||||||
<p>
|
<p>
|
||||||
Dynamic:{' '}
|
Static: {formatSize(vm.memory.static[0])}/<Size
|
||||||
<Size
|
value={defined(vm.memory.static[1], null)}
|
||||||
value={defined(vm.memory.dynamic[0], null)}
|
onChange={memoryStaticMax =>
|
||||||
onChange={memoryMin => editVm(vm, { memoryMin })}
|
editVm(vm, { memoryStaticMax })
|
||||||
/>/<Size
|
}
|
||||||
value={defined(vm.memory.dynamic[1], null)}
|
/>
|
||||||
onChange={memoryMax => editVm(vm, { memoryMax })}
|
</p>
|
||||||
/>
|
<p>
|
||||||
</p>
|
Dynamic:{' '}
|
||||||
</td>
|
<Size
|
||||||
</tr>
|
value={defined(vm.memory.dynamic[0], null)}
|
||||||
</tbody>
|
onChange={memoryMin => editVm(vm, { memoryMin })}
|
||||||
</table>
|
/>/<Size
|
||||||
<br />
|
value={defined(vm.memory.dynamic[1], null)}
|
||||||
<h3>{_('guestOsLabel')}</h3>
|
onChange={memoryMax => editVm(vm, { memoryMax })}
|
||||||
<table className='table table-hover'>
|
/>
|
||||||
<tbody>
|
</p>
|
||||||
<tr>
|
</td>
|
||||||
<th>{_('xenToolsStatus')}</th>
|
</tr>
|
||||||
<td>
|
</tbody>
|
||||||
{_('xenToolsStatusValue', {
|
</table>
|
||||||
status: normalizeXenToolsStatus(vm.xenTools),
|
<br />
|
||||||
})}
|
<h3>{_('guestOsLabel')}</h3>
|
||||||
</td>
|
<table className='table table-hover'>
|
||||||
</tr>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{_('osName')}</th>
|
<th>{_('xenToolsStatus')}</th>
|
||||||
<td>
|
<td>
|
||||||
{isEmpty(vm.os_version) ? (
|
{_('xenToolsStatusValue', {
|
||||||
_('unknownOsName')
|
status: normalizeXenToolsStatus(vm.xenTools),
|
||||||
) : (
|
})}
|
||||||
<span>
|
</td>
|
||||||
<Icon
|
</tr>
|
||||||
className='text-info'
|
<tr>
|
||||||
icon={osFamily(vm.os_version.distro)}
|
<th>{_('osName')}</th>
|
||||||
/> {vm.os_version.name}
|
<td>
|
||||||
</span>
|
{isEmpty(vm.os_version) ? (
|
||||||
)}
|
_('unknownOsName')
|
||||||
</td>
|
) : (
|
||||||
</tr>
|
<span>
|
||||||
<tr>
|
<Icon
|
||||||
<th>{_('osKernel')}</th>
|
className='text-info'
|
||||||
<td>
|
icon={osFamily(vm.os_version.distro)}
|
||||||
{(vm.os_version && vm.os_version.uname) || _('unknownOsKernel')}
|
/> {vm.os_version.name}
|
||||||
</td>
|
</span>
|
||||||
</tr>
|
)}
|
||||||
</tbody>
|
</td>
|
||||||
</table>
|
</tr>
|
||||||
<br />
|
<tr>
|
||||||
<h3>{_('miscLabel')}</h3>
|
<th>{_('osKernel')}</th>
|
||||||
<table className='table table-hover'>
|
<td>
|
||||||
<tbody>
|
{(vm.os_version && vm.os_version.uname) ||
|
||||||
<tr>
|
_('unknownOsKernel')}
|
||||||
<th>{_('originalTemplate')}</th>
|
</td>
|
||||||
<td>
|
</tr>
|
||||||
{vm.other.base_template_name
|
</tbody>
|
||||||
? vm.other.base_template_name
|
</table>
|
||||||
: _('unknownOriginalTemplate')}
|
<br />
|
||||||
</td>
|
<h3>{_('miscLabel')}</h3>
|
||||||
</tr>
|
<table className='table table-hover'>
|
||||||
<tr>
|
<tbody>
|
||||||
<th>{_('resourceSet')}</th>
|
<tr>
|
||||||
<td>
|
<th>{_('originalTemplate')}</th>
|
||||||
{isAdmin ? (
|
<td>
|
||||||
<SelectResourceSet
|
{vm.other.base_template_name
|
||||||
onChange={resourceSet =>
|
? vm.other.base_template_name
|
||||||
editVm(vm, {
|
: _('unknownOriginalTemplate')}
|
||||||
resourceSet:
|
</td>
|
||||||
resourceSet != null ? resourceSet.id : resourceSet,
|
</tr>
|
||||||
})
|
<tr>
|
||||||
}
|
<th>{_('resourceSet')}</th>
|
||||||
value={vm.resourceSet}
|
<td>
|
||||||
/>
|
{isAdmin ? (
|
||||||
) : vm.resourceSet !== undefined ? (
|
<SelectResourceSet
|
||||||
<ResourceSetItem id={vm.resourceSet} />
|
onChange={resourceSet =>
|
||||||
) : (
|
editVm(vm, {
|
||||||
_('resourceSetNone')
|
resourceSet:
|
||||||
)}
|
resourceSet != null ? resourceSet.id : resourceSet,
|
||||||
</td>
|
})
|
||||||
</tr>
|
}
|
||||||
</tbody>
|
value={vm.resourceSet}
|
||||||
</table>
|
/>
|
||||||
</Col>
|
) : vm.resourceSet !== undefined ? (
|
||||||
</Row>
|
<ResourceSetItem id={vm.resourceSet} />
|
||||||
</Container>
|
) : (
|
||||||
))
|
_('resourceSetNone')
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user