Compare commits
4 Commits
vhd_hashes
...
restApi-cr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42cc6d4dd6 | ||
|
|
b5d9d9a9e1 | ||
|
|
3a4e9b8f8e | ||
|
|
92efd28b33 |
@@ -399,6 +399,16 @@ class Vm {
|
||||
return ref
|
||||
}
|
||||
|
||||
async createFull($defer, { clone = true, boot = false, name_label, name_description, template: templateRef }) {
|
||||
// Clones the template.
|
||||
const vmRef = await (
|
||||
clone
|
||||
? this.callAsync('VM.clone', templateRef, name_label)
|
||||
: this.callAsync('VM.copy', templateRef, name_label, '')
|
||||
).then(extractOpaqueRef)
|
||||
$defer.onFailure(() => this.VM_destroy(vmRef))
|
||||
}
|
||||
|
||||
async destroy(
|
||||
vmRef,
|
||||
{ deleteDisks = true, force = false, bypassBlockedOperation = force, forceDeleteDefaultTemplate = force } = {}
|
||||
@@ -699,6 +709,7 @@ export default Vm
|
||||
decorateClass(Vm, {
|
||||
checkpoint: defer,
|
||||
create: defer,
|
||||
createFull: defer,
|
||||
export: defer,
|
||||
snapshot: defer,
|
||||
})
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
> Users must be able to say: “I had this issue, happy to know it's fixed”
|
||||
|
||||
- [Settings/XO Config] Sort backups from newest to oldest
|
||||
- [Plugins/audit] Don't log `tag.getAllConfigured` calls
|
||||
|
||||
### Packages to release
|
||||
|
||||
> When modifying a package, add it here with its release type.
|
||||
@@ -30,5 +33,7 @@
|
||||
<!--packages-start-->
|
||||
|
||||
- xo-server patch
|
||||
- xo-server-audit patch
|
||||
- xo-web patch
|
||||
|
||||
<!--packages-end-->
|
||||
|
||||
@@ -72,6 +72,7 @@ const DEFAULT_BLOCKED_LIST = {
|
||||
'system.getServerTimezone': true,
|
||||
'system.getServerVersion': true,
|
||||
'system.getVersion': true,
|
||||
'tag.getAllConfigured': true,
|
||||
'test.getPermissionsForUser': true,
|
||||
'user.getAll': true,
|
||||
'user.getAuthenticationTokens': true,
|
||||
|
||||
@@ -32,6 +32,9 @@ const methods = {
|
||||
name_label, // eslint-disable-line camelcase
|
||||
nameLabel = name_label, // eslint-disable-line camelcase
|
||||
|
||||
cloudConfig,
|
||||
networkConfig,
|
||||
|
||||
clone = true,
|
||||
installRepository = undefined,
|
||||
vdis = undefined,
|
||||
@@ -217,6 +220,35 @@ const methods = {
|
||||
await this.createVgpu(vm, gpuGroup, vgpuType)
|
||||
}
|
||||
|
||||
// create cloud config drive
|
||||
let cloudConfigVdiUuid
|
||||
if (params.cloudConfig != null) {
|
||||
// Find the SR of the first VDI.
|
||||
let srId
|
||||
forEach(vm.$VBDs, vbdId => {
|
||||
const vbd = this.getObject(vbdId)
|
||||
const vdiId = vbd.VDI
|
||||
if (!vbd.is_cd_drive && vdiId !== undefined) {
|
||||
srId = this.getObject(vdiId).$SR
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
try {
|
||||
cloudConfigVdiUuid = params.coreOs
|
||||
? await xapi.createCoreOsCloudInitConfigDrive(vm.id, srId, params.cloudConfig)
|
||||
: await xapi.createCloudInitConfigDrive(vm.id, srId, params.cloudConfig, params.networkConfig)
|
||||
} catch (error) {
|
||||
log.warn('vm.create', { vmId: vm.id, srId, error })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
if (params.createVtpm) {
|
||||
const vtpmRef = await xapi.VTPM_create({ VM: xapiVm.$ref })
|
||||
$defer.onFailure(() => xapi.call('VTPM.destroy', vtpmRef))
|
||||
}
|
||||
|
||||
// wait for the record with all the VBDs and VIFs
|
||||
return this.barrier(vm.$ref)
|
||||
},
|
||||
|
||||
@@ -297,6 +297,15 @@ export default class RestApi {
|
||||
auto_poweron: { type: 'boolean', optional: true },
|
||||
boot: { type: 'boolean', default: false },
|
||||
clone: { type: 'boolean', default: true },
|
||||
cloud_init: {
|
||||
type: 'object',
|
||||
default: {},
|
||||
properties: {
|
||||
cloud_config: { type: 'string', optional: true },
|
||||
destroy_after_boot: { type: 'boolean', default: false },
|
||||
network_config: { type: 'string', optional: true },
|
||||
},
|
||||
},
|
||||
install: {
|
||||
type: 'object',
|
||||
optional: true,
|
||||
|
||||
@@ -1099,7 +1099,9 @@ export const SelectXoCloudConfig = makeSubscriptionSelect(
|
||||
subscriber =>
|
||||
subscribeCloudXoConfigBackups(configs => {
|
||||
const xoObjects = groupBy(
|
||||
map(configs, config => ({ ...config, type: 'xoConfig' })),
|
||||
map(configs, config => ({ ...config, type: 'xoConfig' }))
|
||||
// from newest to oldest
|
||||
.sort((a, b) => b.createdAt - a.createdAt),
|
||||
'xoaId'
|
||||
)
|
||||
subscriber({
|
||||
|
||||
@@ -5,10 +5,9 @@ import decorate from 'apply-decorators'
|
||||
import Icon from 'icon'
|
||||
import React from 'react'
|
||||
import { confirm } from 'modal'
|
||||
import { getApiApplianceInfo, subscribeCloudXoConfig, subscribeCloudXoConfigBackups } from 'xo'
|
||||
import { groupBy, sortBy } from 'lodash'
|
||||
import { injectState, provideState } from 'reaclette'
|
||||
import { SelectXoCloudConfig } from 'select-objects'
|
||||
import { subscribeCloudXoConfig, subscribeCloudXoConfigBackups } from 'xo'
|
||||
|
||||
import BackupXoConfigModal from './backup-xo-config-modal'
|
||||
import RestoreXoConfigModal from './restore-xo-config-modal'
|
||||
@@ -88,15 +87,7 @@ const CloudConfig = decorate([
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
applianceId: async () => {
|
||||
const { id } = await getApiApplianceInfo()
|
||||
return id
|
||||
},
|
||||
groupedConfigs: ({ applianceId, sortedConfigs }) =>
|
||||
sortBy(groupBy(sortedConfigs, 'xoaId'), config => (config[0].xoaId === applianceId ? -1 : 1)),
|
||||
isConfigDefined: ({ config }) => config != null,
|
||||
sortedConfigs: (_, { cloudXoConfigBackups }) =>
|
||||
cloudXoConfigBackups?.sort((config, nextConfig) => config.createdAt - nextConfig.createdAt),
|
||||
},
|
||||
}),
|
||||
injectState,
|
||||
|
||||
Reference in New Issue
Block a user