chore: format all code (#2632)
This commit is contained in:
@@ -7,8 +7,9 @@ import { debug } from './utils'
|
||||
|
||||
export default class DensityPlan extends Plan {
|
||||
_checkRessourcesThresholds (objects, averages) {
|
||||
return filter(objects, object =>
|
||||
averages[object.id].memoryFree > this._thresholds.memoryFree.low
|
||||
return filter(
|
||||
objects,
|
||||
object => averages[object.id].memoryFree > this._thresholds.memoryFree.low
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,27 +20,17 @@ export default class DensityPlan extends Plan {
|
||||
return
|
||||
}
|
||||
|
||||
const {
|
||||
hosts,
|
||||
toOptimize,
|
||||
} = results
|
||||
const { hosts, toOptimize } = results
|
||||
|
||||
let {
|
||||
averages: hostsAverages,
|
||||
} = results
|
||||
let { averages: hostsAverages } = results
|
||||
|
||||
const pools = await this._getPlanPools()
|
||||
let optimizationsCount = 0
|
||||
|
||||
for (const hostToOptimize of toOptimize) {
|
||||
const {
|
||||
id: hostId,
|
||||
$poolId: poolId,
|
||||
} = hostToOptimize
|
||||
const { id: hostId, $poolId: poolId } = hostToOptimize
|
||||
|
||||
const {
|
||||
master: masterId,
|
||||
} = pools[poolId]
|
||||
const { master: masterId } = pools[poolId]
|
||||
|
||||
// Avoid master optimization.
|
||||
if (masterId === hostId) {
|
||||
@@ -58,10 +49,7 @@ export default class DensityPlan extends Plan {
|
||||
const otherHosts = []
|
||||
|
||||
for (const dest of hosts) {
|
||||
const {
|
||||
id: destId,
|
||||
$poolId: destPoolId,
|
||||
} = dest
|
||||
const { id: destId, $poolId: destPoolId } = dest
|
||||
|
||||
// Destination host != Host to optimize!
|
||||
if (destId === hostId) {
|
||||
@@ -83,12 +71,7 @@ export default class DensityPlan extends Plan {
|
||||
|
||||
const simulResults = await this._simulate({
|
||||
host: hostToOptimize,
|
||||
destinations: [
|
||||
[ poolMaster ],
|
||||
poolHosts,
|
||||
masters,
|
||||
otherHosts,
|
||||
],
|
||||
destinations: [[poolMaster], poolHosts, masters, otherHosts],
|
||||
hostsAverages: clone(hostsAverages),
|
||||
})
|
||||
|
||||
@@ -115,15 +98,15 @@ export default class DensityPlan extends Plan {
|
||||
|
||||
for (const vm of vms) {
|
||||
if (!vm.xenTools) {
|
||||
debug(`VM (${vm.id}) of Host (${hostId}) does not support pool migration.`)
|
||||
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
|
||||
)
|
||||
vms.sort((a, b) => vmsAverages[b.id].memory - vmsAverages[a.id].memory)
|
||||
|
||||
const simulResults = {
|
||||
hostsAverages,
|
||||
@@ -162,15 +145,11 @@ export default class DensityPlan extends Plan {
|
||||
|
||||
// Test if a VM migration on a destination (of a destinations set) is possible.
|
||||
_testMigration ({ vm, destinations, hostsAverages, vmsAverages }) {
|
||||
const {
|
||||
_thresholds: {
|
||||
critical: criticalThreshold,
|
||||
},
|
||||
} = this
|
||||
const { _thresholds: { critical: criticalThreshold } } = this
|
||||
|
||||
// Sort the destinations by available memory. (- -> +)
|
||||
destinations.sort((a, b) =>
|
||||
hostsAverages[a.id].memoryFree - hostsAverages[b.id].memoryFree
|
||||
destinations.sort(
|
||||
(a, b) => hostsAverages[a.id].memoryFree - hostsAverages[b.id].memoryFree
|
||||
)
|
||||
|
||||
for (const destination of destinations) {
|
||||
@@ -204,13 +183,18 @@ export default class DensityPlan extends Plan {
|
||||
|
||||
await Promise.all(
|
||||
mapToArray(moves, move => {
|
||||
const {
|
||||
vm,
|
||||
destination,
|
||||
} = move
|
||||
const { vm, destination } = move
|
||||
const xapiDest = this.xo.getXapi(destination)
|
||||
debug(`Migrate VM (${vm.id}) to Host (${destination.id}) from Host (${vm.$container}).`)
|
||||
return xapiDest.migrateVm(vm._xapiId, this.xo.getXapi(destination), destination._xapiId)
|
||||
debug(
|
||||
`Migrate VM (${vm.id}) to Host (${destination.id}) from Host (${
|
||||
vm.$container
|
||||
}).`
|
||||
)
|
||||
return xapiDest.migrateVm(
|
||||
vm._xapiId,
|
||||
this.xo.getXapi(destination),
|
||||
destination._xapiId
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@@ -9,10 +9,7 @@ import {
|
||||
DEFAULT_CRITICAL_THRESHOLD_CPU,
|
||||
DEFAULT_CRITICAL_THRESHOLD_MEMORY_FREE,
|
||||
} from './plan'
|
||||
import {
|
||||
EXECUTION_DELAY,
|
||||
debug,
|
||||
} from './utils'
|
||||
import { EXECUTION_DELAY, debug } from './utils'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
@@ -41,7 +38,7 @@ export const configurationSchema = {
|
||||
},
|
||||
|
||||
mode: {
|
||||
enum: [ 'Performance mode', 'Density mode' ],
|
||||
enum: ['Performance mode', 'Density mode'],
|
||||
title: 'Mode',
|
||||
},
|
||||
|
||||
@@ -85,7 +82,7 @@ export const configurationSchema = {
|
||||
},
|
||||
},
|
||||
|
||||
required: [ 'name', 'mode', 'pools' ],
|
||||
required: ['name', 'mode', 'pools'],
|
||||
},
|
||||
|
||||
minItems: 1,
|
||||
@@ -115,7 +112,10 @@ const makeJob = (cronPattern, fn) => {
|
||||
try {
|
||||
await fn()
|
||||
} catch (error) {
|
||||
console.error('[WARN] scheduled function:', (error && error.stack) || error)
|
||||
console.error(
|
||||
'[WARN] scheduled function:',
|
||||
(error && error.stack) || error
|
||||
)
|
||||
} finally {
|
||||
job.running = false
|
||||
job.emitter.emit('finish')
|
||||
@@ -133,7 +133,10 @@ const makeJob = (cronPattern, fn) => {
|
||||
class LoadBalancerPlugin {
|
||||
constructor (xo) {
|
||||
this.xo = xo
|
||||
this._job = makeJob(`*/${EXECUTION_DELAY} * * * *`, this._executePlans.bind(this))
|
||||
this._job = makeJob(
|
||||
`*/${EXECUTION_DELAY} * * * *`,
|
||||
this._executePlans.bind(this)
|
||||
)
|
||||
}
|
||||
|
||||
async configure ({ plans }) {
|
||||
@@ -154,7 +157,10 @@ class LoadBalancerPlugin {
|
||||
|
||||
if (plans) {
|
||||
for (const plan of plans) {
|
||||
this._addPlan(plan.mode === 'Performance mode' ? PERFORMANCE_MODE : DENSITY_MODE, plan)
|
||||
this._addPlan(
|
||||
plan.mode === 'Performance mode' ? PERFORMANCE_MODE : DENSITY_MODE,
|
||||
plan
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,18 +186,17 @@ class LoadBalancerPlugin {
|
||||
}
|
||||
|
||||
this._poolIds = this._poolIds.concat(pools)
|
||||
this._plans.push(mode === PERFORMANCE_MODE
|
||||
? new PerformancePlan(this.xo, name, pools, options)
|
||||
: new DensityPlan(this.xo, name, pools, options)
|
||||
this._plans.push(
|
||||
mode === PERFORMANCE_MODE
|
||||
? new PerformancePlan(this.xo, name, pools, options)
|
||||
: new DensityPlan(this.xo, name, pools, options)
|
||||
)
|
||||
}
|
||||
|
||||
_executePlans () {
|
||||
debug('Execute plans!')
|
||||
|
||||
return Promise.all(
|
||||
mapToArray(this._plans, plan => plan.execute())
|
||||
)
|
||||
return Promise.all(mapToArray(this._plans, plan => plan.execute()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,10 @@ export default class PerformancePlan extends Plan {
|
||||
try {
|
||||
await Promise.all(
|
||||
mapToArray(
|
||||
filter(this._getHosts({ powerState: 'Halted' }), host => host.powerOnMode !== ''),
|
||||
filter(
|
||||
this._getHosts({ powerState: 'Halted' }),
|
||||
host => host.powerOnMode !== ''
|
||||
),
|
||||
host => {
|
||||
const { id } = host
|
||||
return this.xo.getXapi(id).powerOnHost(id)
|
||||
@@ -52,17 +55,14 @@ export default class PerformancePlan extends Plan {
|
||||
return
|
||||
}
|
||||
|
||||
const {
|
||||
averages,
|
||||
toOptimize,
|
||||
} = results
|
||||
const { averages, toOptimize } = results
|
||||
let { hosts } = results
|
||||
|
||||
toOptimize.sort((a, b) => {
|
||||
a = averages[a.id]
|
||||
b = averages[b.id]
|
||||
|
||||
return (b.cpu - a.cpu) || (a.memoryFree - b.memoryFree)
|
||||
return b.cpu - a.cpu || a.memoryFree - b.memoryFree
|
||||
})
|
||||
|
||||
for (const exceededHost of toOptimize) {
|
||||
@@ -85,9 +85,7 @@ export default class PerformancePlan extends Plan {
|
||||
const vmsAverages = await this._getVmsAverages(vms, exceededHost)
|
||||
|
||||
// Sort vms by cpu usage. (lower to higher)
|
||||
vms.sort((a, b) =>
|
||||
vmsAverages[b.id].cpu - vmsAverages[a.id].cpu
|
||||
)
|
||||
vms.sort((a, b) => vmsAverages[b.id].cpu - vmsAverages[a.id].cpu)
|
||||
|
||||
const exceededAverages = hostsAverages[exceededHost.id]
|
||||
const promises = []
|
||||
@@ -95,11 +93,15 @@ export default class PerformancePlan extends Plan {
|
||||
const xapiSrc = this.xo.getXapi(exceededHost)
|
||||
let optimizationsCount = 0
|
||||
|
||||
const searchFunction = (a, b) => hostsAverages[b.id].cpu - hostsAverages[a.id].cpu
|
||||
const searchFunction = (a, b) =>
|
||||
hostsAverages[b.id].cpu - hostsAverages[a.id].cpu
|
||||
|
||||
for (const vm of vms) {
|
||||
// Search host with lower cpu usage in the same pool first. In other pool if necessary.
|
||||
let destination = searchBestObject(find(hosts, host => host.$poolId === vm.$poolId), searchFunction)
|
||||
let destination = searchBestObject(
|
||||
find(hosts, host => host.$poolId === vm.$poolId),
|
||||
searchFunction
|
||||
)
|
||||
|
||||
if (!destination) {
|
||||
destination = searchBestObject(hosts, searchFunction)
|
||||
@@ -110,7 +112,8 @@ export default class PerformancePlan extends Plan {
|
||||
|
||||
// Unable to move the vm.
|
||||
if (
|
||||
exceededAverages.cpu - vmAverages.cpu < destinationAverages.cpu + vmAverages.cpu ||
|
||||
exceededAverages.cpu - vmAverages.cpu <
|
||||
destinationAverages.cpu + vmAverages.cpu ||
|
||||
destinationAverages.memoryFree > vmAverages.memory
|
||||
) {
|
||||
continue
|
||||
@@ -122,15 +125,27 @@ export default class PerformancePlan extends Plan {
|
||||
exceededAverages.memoryFree += vmAverages.memory
|
||||
destinationAverages.memoryFree -= vmAverages.memory
|
||||
|
||||
debug(`Migrate VM (${vm.id}) to Host (${destination.id}) from Host (${exceededHost.id}).`)
|
||||
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)
|
||||
xapiSrc.migrateVm(
|
||||
vm._xapiId,
|
||||
this.xo.getXapi(destination),
|
||||
destination._xapiId
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
await Promise.all(promises)
|
||||
debug(`Performance mode: ${optimizationsCount} optimizations for Host (${exceededHost.id}).`)
|
||||
debug(
|
||||
`Performance mode: ${optimizationsCount} optimizations for Host (${
|
||||
exceededHost.id
|
||||
}).`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { filter, includes, map as mapToArray } from 'lodash'
|
||||
|
||||
import {
|
||||
EXECUTION_DELAY,
|
||||
debug,
|
||||
} from './utils'
|
||||
import { EXECUTION_DELAY, debug } from './utils'
|
||||
|
||||
const MINUTES_OF_HISTORICAL_DATA = 30
|
||||
|
||||
@@ -20,7 +17,7 @@ const LOW_THRESHOLD_FACTOR = 0.25
|
||||
const HIGH_THRESHOLD_MEMORY_FREE_FACTOR = 1.25
|
||||
const LOW_THRESHOLD_MEMORY_FREE_FACTOR = 20.0
|
||||
|
||||
const numberOrDefault = (value, def) => (value >= 0) ? value : def
|
||||
const numberOrDefault = (value, def) => (value >= 0 ? value : def)
|
||||
|
||||
// ===================================================================
|
||||
// Averages.
|
||||
@@ -69,10 +66,12 @@ function computeRessourcesAverageWithWeight (averages1, averages2, ratio) {
|
||||
const averages = {}
|
||||
|
||||
for (const id in averages1) {
|
||||
const objectAverages = averages[id] = {}
|
||||
const objectAverages = (averages[id] = {})
|
||||
|
||||
for (const averageName in averages1[id]) {
|
||||
objectAverages[averageName] = averages1[id][averageName] * ratio + averages2[id][averageName] * (1 - ratio)
|
||||
objectAverages[averageName] =
|
||||
averages1[id][averageName] * ratio +
|
||||
averages2[id][averageName] * (1 - ratio)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,20 +88,24 @@ function setRealCpuAverageOfVms (vms, vmsAverages, nCpus) {
|
||||
// ===================================================================
|
||||
|
||||
export default class Plan {
|
||||
constructor (xo, name, poolIds, {
|
||||
excludedHosts,
|
||||
thresholds,
|
||||
} = {}) {
|
||||
constructor (xo, name, poolIds, { excludedHosts, thresholds } = {}) {
|
||||
this.xo = xo
|
||||
this._name = name
|
||||
this._poolIds = poolIds
|
||||
this._excludedHosts = excludedHosts
|
||||
this._thresholds = {
|
||||
cpu: {
|
||||
critical: numberOrDefault(thresholds && thresholds.cpu, DEFAULT_CRITICAL_THRESHOLD_CPU),
|
||||
critical: numberOrDefault(
|
||||
thresholds && thresholds.cpu,
|
||||
DEFAULT_CRITICAL_THRESHOLD_CPU
|
||||
),
|
||||
},
|
||||
memoryFree: {
|
||||
critical: numberOrDefault(thresholds && thresholds.memoryFree, DEFAULT_CRITICAL_THRESHOLD_MEMORY_FREE) * 1024,
|
||||
critical:
|
||||
numberOrDefault(
|
||||
thresholds && thresholds.memoryFree,
|
||||
DEFAULT_CRITICAL_THRESHOLD_MEMORY_FREE
|
||||
) * 1024,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -143,8 +146,16 @@ export default class Plan {
|
||||
}
|
||||
|
||||
// Check in the last 30 min interval with ratio.
|
||||
const avgBefore = computeRessourcesAverage(hosts, hostsStats, MINUTES_OF_HISTORICAL_DATA)
|
||||
const avgWithRatio = computeRessourcesAverageWithWeight(avgNow, avgBefore, 0.75)
|
||||
const avgBefore = computeRessourcesAverage(
|
||||
hosts,
|
||||
hostsStats,
|
||||
MINUTES_OF_HISTORICAL_DATA
|
||||
)
|
||||
const avgWithRatio = computeRessourcesAverageWithWeight(
|
||||
avgNow,
|
||||
avgBefore,
|
||||
0.75
|
||||
)
|
||||
|
||||
toOptimize = this._checkRessourcesThresholds(toOptimize, avgWithRatio)
|
||||
|
||||
@@ -185,19 +196,23 @@ export default class Plan {
|
||||
|
||||
// Compute hosts for each pool. They can change over time.
|
||||
_getHosts ({ powerState = 'Running' } = {}) {
|
||||
return filter(this.xo.getObjects(), object => (
|
||||
object.type === 'host' &&
|
||||
includes(this._poolIds, object.$poolId) &&
|
||||
object.power_state === powerState &&
|
||||
!includes(this._excludedHosts, object.id)
|
||||
))
|
||||
return filter(
|
||||
this.xo.getObjects(),
|
||||
object =>
|
||||
object.type === 'host' &&
|
||||
includes(this._poolIds, object.$poolId) &&
|
||||
object.power_state === powerState &&
|
||||
!includes(this._excludedHosts, object.id)
|
||||
)
|
||||
}
|
||||
|
||||
async _getVms (hostId) {
|
||||
return filter(this.xo.getObjects(), object =>
|
||||
object.type === 'VM' &&
|
||||
object.power_state === 'Running' &&
|
||||
object.$container === hostId
|
||||
return filter(
|
||||
this.xo.getObjects(),
|
||||
object =>
|
||||
object.type === 'VM' &&
|
||||
object.power_state === 'Running' &&
|
||||
object.$container === hostId
|
||||
)
|
||||
}
|
||||
|
||||
@@ -208,15 +223,17 @@ export default class Plan {
|
||||
async _getHostsStats (hosts, granularity) {
|
||||
const hostsStats = {}
|
||||
|
||||
await Promise.all(mapToArray(hosts, host =>
|
||||
this.xo.getXapiHostStats(host, granularity).then(hostStats => {
|
||||
hostsStats[host.id] = {
|
||||
nPoints: hostStats.stats.cpus[0].length,
|
||||
stats: hostStats.stats,
|
||||
averages: {},
|
||||
}
|
||||
})
|
||||
))
|
||||
await Promise.all(
|
||||
mapToArray(hosts, host =>
|
||||
this.xo.getXapiHostStats(host, granularity).then(hostStats => {
|
||||
hostsStats[host.id] = {
|
||||
nPoints: hostStats.stats.cpus[0].length,
|
||||
stats: hostStats.stats,
|
||||
averages: {},
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
return hostsStats
|
||||
}
|
||||
@@ -224,15 +241,17 @@ export default class Plan {
|
||||
async _getVmsStats (vms, granularity) {
|
||||
const vmsStats = {}
|
||||
|
||||
await Promise.all(mapToArray(vms, vm =>
|
||||
this.xo.getXapiVmStats(vm, granularity).then(vmStats => {
|
||||
vmsStats[vm.id] = {
|
||||
nPoints: vmStats.stats.cpus[0].length,
|
||||
stats: vmStats.stats,
|
||||
averages: {},
|
||||
}
|
||||
})
|
||||
))
|
||||
await Promise.all(
|
||||
mapToArray(vms, vm =>
|
||||
this.xo.getXapiVmStats(vm, granularity).then(vmStats => {
|
||||
vmsStats[vm.id] = {
|
||||
nPoints: vmStats.stats.cpus[0].length,
|
||||
stats: vmStats.stats,
|
||||
averages: {},
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
return vmsStats
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user