Skip to content

Commit

Permalink
feat(xo-web/self): ability to share VMs by default (#6838)
Browse files Browse the repository at this point in the history
See xoa-support#7420
  • Loading branch information
MathieuRA authored May 25, 2023
1 parent 9f3b020 commit f4bf56f
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- [Home/Host] Displays a warning for hosts with HVM disabled [#6823](https://github.com/vatesfr/xen-orchestra/issues/6823) (PR [#6834](https://github.com/vatesfr/xen-orchestra/pull/6834))
- [OVA import] Workaround for OVA generated by Oracle VM with faulty size in metadata [#6824](https://github.com/vatesfr/xen-orchestra/issues/6824)
- [REST API] _Rolling Pool Update_ action available `pools/<uuid>/actions/rolling_update`
- [Self Service] Ability to set a default value for the "Share VM" feature for Self Service users during creation/edition (PR [#6838](https://github.com/vatesfr/xen-orchestra/pull/6838))

### Bug fixes

Expand Down
15 changes: 12 additions & 3 deletions packages/xo-server/src/api/resource-set.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export function create({ name, subjects, objects, limits }) {
return this.createResourceSet(name, subjects, objects, limits)
export function create({ name, shareByDefault, subjects, objects, limits }) {
return this.createResourceSet(name, subjects, objects, limits, shareByDefault)
}

create.permission = 'admin'
Expand All @@ -26,6 +26,10 @@ create.params = {
type: 'object',
optional: true,
},
shareByDefault: {
type: 'boolean',
optional: true,
},
}

// -------------------------------------------------------------------
Expand All @@ -45,12 +49,13 @@ delete_.params = {

// -------------------------------------------------------------------

export function set({ id, name, subjects, objects, ipPools, limits }) {
export function set({ id, name, shareByDefault, subjects, objects, ipPools, limits }) {
return this.updateResourceSet(id, {
limits,
name,
objects,
ipPools,
shareByDefault,
subjects,
})
}
Expand All @@ -65,6 +70,10 @@ set.params = {
type: 'string',
optional: true,
},
shareByDefault: {
type: 'boolean',
optional: true
},
subjects: {
type: 'array',
items: {
Expand Down
17 changes: 15 additions & 2 deletions packages/xo-server/src/xo-mixins/resource-sets.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const normalize = set => ({
name: set.name || '',
objects: set.objects || [],
subjects: set.subjects || [],
shareByDefault: set.shareByDefault || false,
})

// ===================================================================
Expand Down Expand Up @@ -133,14 +134,15 @@ export default class {
return vm.type === 'VM-snapshot' ? this.computeVmSnapshotResourcesUsage(vm) : this.computeVmResourcesUsage(vm)
}

async createResourceSet(name, subjects = undefined, objects = undefined, limits = undefined) {
async createResourceSet(name, subjects = undefined, objects = undefined, limits = undefined, shareByDefault = false) {
const id = await this._generateId()
const set = normalize({
id,
name,
objects,
subjects,
limits,
shareByDefault,
})

await this._store.put(id, set)
Expand All @@ -167,7 +169,14 @@ export default class {
async updateResourceSet(
$defer,
id,
{ name = undefined, subjects = undefined, objects = undefined, limits = undefined, ipPools = undefined }
{
name = undefined,
shareByDefault = undefined,
subjects = undefined,
objects = undefined,
limits = undefined,
ipPools = undefined,
}
) {
const set = await this.getResourceSet(id)
if (name) {
Expand Down Expand Up @@ -223,6 +232,10 @@ export default class {
set.ipPools = ipPools
}

if (shareByDefault !== undefined && shareByDefault !== set.shareByDefault) {
set.shareByDefault = shareByDefault
}

await this._save(set)
}

Expand Down
1 change: 1 addition & 0 deletions packages/xo-web/src/common/intl/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -1633,6 +1633,7 @@ const messages = {
availableResourceLabel: 'Available',
resourceSetQuota: 'Used: {usage} (Total: {total})',
resourceSetNew: 'New',
shareVmsByDefault: 'Share VMs by default',

// ---- VM import ---
fileType: 'File type:',
Expand Down
7 changes: 4 additions & 3 deletions packages/xo-web/src/common/xo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2513,13 +2513,14 @@ export const sendUsageReport = () => _call('plugin.usageReport.send')

// Resource set ------------------------------------------------------

export const createResourceSet = (name, { subjects, objects, limits } = {}) =>
_call('resourceSet.create', { name, subjects, objects, limits })::tap(subscribeResourceSets.forceRefresh)
export const createResourceSet = (name, { shareByDefault, subjects, objects, limits } = {}) =>
_call('resourceSet.create', { name, shareByDefault, subjects, objects, limits })::tap(subscribeResourceSets.forceRefresh)

export const editResourceSet = (id, { name, subjects, objects, limits, ipPools } = {}) =>
export const editResourceSet = (id, { name, shareByDefault, subjects, objects, limits, ipPools } = {}) =>
_call('resourceSet.set', {
id,
name,
shareByDefault,
subjects,
objects,
limits,
Expand Down
28 changes: 26 additions & 2 deletions packages/xo-web/src/xo-app/new-vm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,22 @@ import {
} from 'cloud-config'
import { Input as DebounceInput, Textarea as DebounceTextarea } from 'debounce-input-decorator'
import { Limits } from 'usage'
import { clamp, every, filter, find, forEach, includes, isEmpty, join, map, size, slice, sum, sumBy } from 'lodash'
import {
clamp,
every,
filter,
find,
forEach,
includes,
isEmpty,
isEqual,
join,
map,
size,
slice,
sum,
sumBy,
} from 'lodash'
import {
addSshKey,
createVm,
Expand Down Expand Up @@ -255,6 +270,15 @@ export default class NewVm extends BaseComponent {
if (get(() => prevProps.template.id) !== get(() => this.props.template.id)) {
this._initTemplate(this.props.template)
}

if (
!isEqual(prevProps.resourceSets, this.props.resourceSets) ||
prevProps.location.query.resourceSet !== this.props.location.query.resourceSet
) {
this._setState({
share: this._getResourceSet()?.shareByDefault ?? false,
})
}
}

_getResourceSet = createFinder(
Expand Down Expand Up @@ -320,7 +344,7 @@ export default class NewVm extends BaseComponent {
VIFs: [],
secureBoot: false,
seqStart: 1,
share: false,
share: this._getResourceSet()?.shareByDefault ?? false,
tags: [],
},
callback
Expand Down
13 changes: 12 additions & 1 deletion packages/xo-web/src/xo-app/self/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export class Edit extends Component {
name: '',
networks: [],
pools: [],
shareByDefault: false,
srs: [],
subjects: [],
templates: [],
Expand Down Expand Up @@ -175,14 +176,15 @@ export class Edit extends Component {
ipPools,
memory: get(limits, 'memory.total', null),
name: resourceSet.name,
shareByDefault: resourceSet.shareByDefault || false,
subjects: resourceSet.subjects,
templates: objectsByType['VM-template'] || [],
})
}
}

_save = async () => {
const { cpus, disk, ipPools, memory, name, networks, srs, subjects, templates } = this.state
const { cpus, disk, ipPools, memory, name, networks, shareByDefault, srs, subjects, templates } = this.state

const set = this.props.resourceSet || (await createResourceSet(name))
const objects = [...templates, ...srs, ...networks]
Expand All @@ -203,6 +205,7 @@ export class Edit extends Component {
...ipPoolsLimits,
},
objects: resolveIds(objects),
shareByDefault,
subjects: resolveIds(subjects),
ipPools: resolveIds(ipPools),
})
Expand All @@ -220,6 +223,7 @@ export class Edit extends Component {
memory: null,
newIpPool: undefined,
newIpPoolQuantity: '',
shareByDefault: false,
subjects: [],
})
}
Expand Down Expand Up @@ -494,6 +498,13 @@ export class Edit extends Component {
</Col>
</Row>
</div>
<div className='mt-1'>
<label>
<input checked={state.shareByDefault} type='checkbox' onChange={this.toggleState('shareByDefault')} />
&nbsp;
<strong>{_('shareVmsByDefault')}</strong>
</label>
</div>
<hr />
<Hosts excludedHosts={state.excludedHosts} eligibleHosts={state.eligibleHosts} />
</form>
Expand Down

0 comments on commit f4bf56f

Please sign in to comment.