Compare commits
5 Commits
vusb-api
...
xo6/custom
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d71017aec5 | ||
|
|
aefcce45ff | ||
|
|
367fb4d8a6 | ||
|
|
e54a0bfc80 | ||
|
|
9e5541703b |
@@ -15,6 +15,31 @@
|
||||
&.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
--scrollbar-width: 1.4rem;
|
||||
--scrollbar-border: 0.4rem;
|
||||
--scrollbar-thumb-color: var(--color-purple-l40);
|
||||
--scrollbar-track-color: var(--background-color-purple-10);
|
||||
|
||||
/* Firefox/Gecko and Chrome versions >= 121 */
|
||||
scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
|
||||
scrollbar-width: auto;
|
||||
|
||||
/* Chrome/Webkit */
|
||||
::-webkit-scrollbar {
|
||||
width: var(--scrollbar-width);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: var(--scrollbar-track-color);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: var(--scrollbar-thumb-color);
|
||||
border: var(--scrollbar-border) solid transparent;
|
||||
border-radius: 90rem;
|
||||
background-clip: content-box;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
@@ -51,3 +76,15 @@ pre {
|
||||
.link.router-link-active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.scrollbar-small {
|
||||
scrollbar-width: thin;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
--scrollbar-width: 0.7rem;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
--scrollbar-border: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,3 @@ export { default as VDI } from './vdi.mjs'
|
||||
export { default as VIF } from './vif.mjs'
|
||||
export { default as VM } from './vm.mjs'
|
||||
export { default as VTPM } from './vtpm.mjs'
|
||||
export { default as VUSB } from './vusb.mjs'
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import ignoreErrors from 'promise-toolbox/ignoreErrors'
|
||||
|
||||
export default class Vusb {
|
||||
async create(VM, USB_group) {
|
||||
return this.call('VUSB.create', VM, USB_group)
|
||||
}
|
||||
|
||||
async unplug(ref) {
|
||||
await this.call('VUSB.unplug', ref)
|
||||
}
|
||||
|
||||
async destroy(ref) {
|
||||
await ignoreErrors.call(this.VUSB_unplug(ref))
|
||||
await this.call('VUSB.destroy', ref)
|
||||
}
|
||||
}
|
||||
27
packages/xo-server/src/api/pusb.mjs
Normal file
27
packages/xo-server/src/api/pusb.mjs
Normal file
@@ -0,0 +1,27 @@
|
||||
export async function scan({ host }) {
|
||||
await this.getXapi(host).call('PUSB.scan', host._xapiRef)
|
||||
}
|
||||
|
||||
scan.params = {
|
||||
host: { type: 'string' },
|
||||
}
|
||||
scan.resolve = {
|
||||
host: ['host', 'host', 'operate'],
|
||||
}
|
||||
|
||||
export async function set({ pusb, enabled }) {
|
||||
const xapi = this.getXapi(pusb)
|
||||
|
||||
if (enabled !== undefined && enabled !== pusb.passthroughEnabled) {
|
||||
await xapi.call('PUSB.set_passthrough_enabled', pusb._xapiRef, enabled)
|
||||
}
|
||||
}
|
||||
|
||||
set.params = {
|
||||
id: { type: 'string' },
|
||||
enabled: { type: 'boolean', optional: true },
|
||||
}
|
||||
|
||||
set.resolve = {
|
||||
pusb: ['id', 'PUSB', 'administrate'],
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// Creates a VUSB which will be plugged to the VM at its next restart
|
||||
// Only one VUSB can be attached to a given USB_group, and up to six VUSB can be attached to a VM.
|
||||
export async function create({ vm, usbGroup }) {
|
||||
const xapi = this.getXapi(vm)
|
||||
const vusbRef = await xapi.VUSB_create(vm._xapiRef, usbGroup._xapiRef)
|
||||
return xapi.getField('VUSB', vusbRef, 'uuid')
|
||||
}
|
||||
|
||||
create.params = {
|
||||
vmId: { type: 'string' },
|
||||
usbGroupId: { type: 'string' },
|
||||
}
|
||||
|
||||
create.resolve = {
|
||||
vm: ['vmId', 'VM', 'administrate'],
|
||||
usbGroup: ['usbGroupId', 'USB_group', 'administrate'],
|
||||
}
|
||||
|
||||
// Unplug VUSB until next VM restart
|
||||
export async function unplug({ vusb }) {
|
||||
await this.getXapi(vusb).VUSB_unplug(vusb._xapiRef)
|
||||
}
|
||||
|
||||
unplug.params = {
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
unplug.resolve = {
|
||||
vusb: ['id', 'VUSB', 'administrate'],
|
||||
}
|
||||
|
||||
export async function destroy({ vusb }) {
|
||||
await this.getXapi(vusb).VUSB_destroy(vusb._xapiRef)
|
||||
}
|
||||
|
||||
destroy.params = {
|
||||
id: { type: 'string' },
|
||||
}
|
||||
|
||||
destroy.resolve = {
|
||||
vusb: ['id', 'VUSB', 'administrate'],
|
||||
}
|
||||
@@ -882,8 +882,6 @@ const TRANSFORMS = {
|
||||
}
|
||||
},
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
vtpm(obj) {
|
||||
return {
|
||||
type: 'VTPM',
|
||||
@@ -892,31 +890,16 @@ const TRANSFORMS = {
|
||||
}
|
||||
},
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
vusb(obj) {
|
||||
pusb(obj) {
|
||||
return {
|
||||
type: 'VUSB',
|
||||
type: 'PUSB',
|
||||
|
||||
vm: link(obj, 'VM'),
|
||||
currentlyAttached: obj.currently_attached,
|
||||
description: obj.description,
|
||||
host: link(obj, 'host'),
|
||||
passthroughEnabled: obj.passthrough_enabled,
|
||||
usbGroup: link(obj, 'USB_group'),
|
||||
}
|
||||
},
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
usb_group(obj) {
|
||||
return {
|
||||
type: 'USB_group',
|
||||
|
||||
PUSB: link(obj, 'PUSBs'),
|
||||
VUSB: link(obj, 'VUSBs'),
|
||||
nameDescription: obj.name_description,
|
||||
nameLabel: obj.name_label,
|
||||
otherConfig: obj.other_config,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
@@ -54,13 +54,9 @@ export default class IsoDevice extends Component {
|
||||
() => this.props.vm.$pool,
|
||||
() => this.props.vm.$container,
|
||||
(vmPool, vmContainer) => sr => {
|
||||
const vmRunning = vmContainer !== vmPool
|
||||
const sameHost = vmContainer === sr.$container
|
||||
const samePool = vmPool === sr.$pool
|
||||
|
||||
return (
|
||||
samePool &&
|
||||
(vmRunning ? sr.shared || sameHost : true) &&
|
||||
vmPool === sr.$pool &&
|
||||
(sr.shared || vmContainer === sr.$container) &&
|
||||
(sr.SR_type === 'iso' || (sr.SR_type === 'udev' && sr.size))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import _ from 'intl'
|
||||
import Copiable from 'copiable'
|
||||
import decorate from 'apply-decorators'
|
||||
import Icon from 'icon'
|
||||
import map from 'lodash/map'
|
||||
import React from 'react'
|
||||
import store from 'store'
|
||||
import HomeTags from 'home-tags'
|
||||
@@ -24,10 +23,21 @@ export default decorate([
|
||||
provideState({
|
||||
computed: {
|
||||
areHostsVersionsEqual: ({ areHostsVersionsEqualByPool }, { host }) => areHostsVersionsEqualByPool[host.$pool],
|
||||
inMemoryVms: (_, { vms }) => {
|
||||
const result = []
|
||||
for (const key of Object.keys(vms)) {
|
||||
const vm = vms[key]
|
||||
const { power_state } = vm
|
||||
if (power_state === 'Running' || power_state === 'Paused') {
|
||||
result.push(vm)
|
||||
}
|
||||
}
|
||||
return result
|
||||
},
|
||||
},
|
||||
}),
|
||||
injectState,
|
||||
({ statsOverview, host, nVms, vmController, vms, state: { areHostsVersionsEqual } }) => {
|
||||
({ statsOverview, host, nVms, vmController, state: { areHostsVersionsEqual, inMemoryVms } }) => {
|
||||
const pool = getObject(store.getState(), host.$pool)
|
||||
const vmsFilter = encodeURIComponent(new CM.Property('$container', new CM.String(host.id)).toString())
|
||||
return (
|
||||
@@ -120,7 +130,7 @@ export default decorate([
|
||||
tooltip={`${host.productBrand} (${formatSize(vmController.memory.size)})`}
|
||||
value={vmController.memory.size}
|
||||
/>
|
||||
{map(vms, vm => (
|
||||
{inMemoryVms.map(vm => (
|
||||
<UsageElement
|
||||
tooltip={`${vm.name_label} (${formatSize(vm.memory.size)})`}
|
||||
key={vm.id}
|
||||
|
||||
Reference in New Issue
Block a user