diff --git a/packages/xo-server-load-balancer/src/density-plan.js b/packages/xo-server-load-balancer/src/density-plan.js index 068d01202..25019c1c0 100644 --- a/packages/xo-server-load-balancer/src/density-plan.js +++ b/packages/xo-server-load-balancer/src/density-plan.js @@ -54,6 +54,12 @@ export default class DensityPlan extends Plan { continue } + // A host to optimize needs the ability to be restarted. + if (hostToOptimize.powerOnMode === '') { + debug(`Host (${hostId}) does not have a power on mode.`) + continue + } + let poolMaster // Pool master. const poolHosts = [] // Without master. const masters = [] // Without the master of this loop. @@ -99,7 +105,7 @@ export default class DensityPlan extends Plan { hostsAverages = simulResults.hostsAverages // Migrate. - await this._migrate(simulResults.moves) + await this._migrate(hostId, simulResults.moves) optimizationsCount++ } } @@ -115,6 +121,13 @@ export default class DensityPlan extends Plan { const vms = await this._getVms(hostId) const vmsAverages = await this._getVmsAverages(vms, host) + for (const vm of vms) { + if (!vm.xenTools) { + debug(`VM (${vm.id}) of Host (${hostId}) does not support pool migration.`) + return + } + } + // Sort vms by amount of memory. (+ -> -) vms.sort((a, b) => vmsAverages[b.id].memory - vmsAverages[a.id].memory @@ -180,6 +193,7 @@ export default class DensityPlan extends Plan { continue } + // Move ok. Update stats. destinationAverages.cpu += vmAverages.cpu destinationAverages.memoryFree -= vmAverages.memory @@ -191,17 +205,29 @@ export default class DensityPlan extends Plan { } } - async _migrate (moves) { + // Migrate the VMs of one host. + // Try to shutdown the VMs host. + async _migrate (hostId, moves) { + const xapiSrc = this.xo.getXapi(hostId) + await Promise.all( mapToArray(moves, move => { const { vm, destination } = move - const xapiSrc = this.xo.getXapi(destination) + const xapiDest = this.xo.getXapi(destination) debug(`Migrate VM (${vm.id}) to Host (${destination.id}) from Host (${vm.$container}).`) - // xapiSrc.migrateVm(vm._xapiId, this.xo.getXapi(destination), destination._xapiId) + return xapiDest.migrateVm(vm._xapiId, this.xo.getXapi(destination), destination._xapiId) }) ) + + debug(`Shutdown Host (${hostId}).`) + + try { + await xapiSrc.shutdownHost(hostId) + } catch (error) { + debug(`Unable to shutdown Host (${hostId}).`, error) + } } } diff --git a/packages/xo-server-load-balancer/src/performance-plan.js b/packages/xo-server-load-balancer/src/performance-plan.js index 18d3eef11..bbf4103b5 100644 --- a/packages/xo-server-load-balancer/src/performance-plan.js +++ b/packages/xo-server-load-balancer/src/performance-plan.js @@ -99,9 +99,9 @@ export default class PerformancePlan extends Plan { debug(`Migrate VM (${vm.id}) to Host (${destination.id}) from Host (${exceededHost.id}).`) optimizationsCount++ - // promises.push( - // xapiSrc.migrateVm(vm._xapiId, this.xo.getXapi(destination), destination._xapiId) - // ) + promises.push( + xapiSrc.migrateVm(vm._xapiId, this.xo.getXapi(destination), destination._xapiId) + ) } await Promise.all(promises) diff --git a/packages/xo-server-load-balancer/src/plan.js b/packages/xo-server-load-balancer/src/plan.js index 96c9cf52d..d4b240fe1 100644 --- a/packages/xo-server-load-balancer/src/plan.js +++ b/packages/xo-server-load-balancer/src/plan.js @@ -189,9 +189,11 @@ export default class Plan { // Compute hosts for each pool. They can change over time. _getHosts () { return differenceBy( - filter(this.xo.getObjects(), object => - object.type === 'host' && includes(this._poolIds, object.$poolId) - ), + filter(this.xo.getObjects(), object => { + object.type === 'host' && + includes(this._poolIds, object.$poolId) && + object.power_state !== 'Halted' + }), this._excludedHosts, val => val.id || val )