Merge pull request #247 from vatesfr/too-many-storage-migrates

Xapi#migrateVm(): handle TOO_MANY_STORAGE_MIGRATES (fix vatesfr/xo-we…
This commit is contained in:
Julien Fontanet 2016-03-02 12:47:00 +01:00
commit cfb49f9136
4 changed files with 25 additions and 16 deletions

View File

@ -113,7 +113,7 @@
"partial-stream": "0.0.0",
"passport": "^0.3.0",
"passport-local": "^1.0.0",
"promise-toolbox": "^0.1.0",
"promise-toolbox": "^0.2.0",
"proxy-agent": "^2.0.0",
"proxy-http-request": "0.1.0",
"redis": "^2.0.1",

View File

@ -50,7 +50,7 @@ export default class Redis extends Collection {
const models = []
return Promise.all(mapToArray(ids, id => {
return redis.hgetallAsync(prefix + id).then(model => {
return redis.hgetall(prefix + id).then(model => {
// If empty, consider it a no match.
if (isEmpty(model)) {
return
@ -73,10 +73,10 @@ export default class Redis extends Collection {
return Promise.all(mapToArray(models, async model => {
// Generate a new identifier if necessary.
if (model.id === undefined) {
model.id = idPrefix + String(await redis.incrAsync(prefix + '_id'))
model.id = idPrefix + String(await redis.incr(prefix + '_id'))
}
const success = await redis.saddAsync(prefix + '_ids', model.id)
const success = await redis.sadd(prefix + '_ids', model.id)
// The entry already exists an we are not in replace mode.
if (!success && !replace) {
@ -97,8 +97,8 @@ export default class Redis extends Collection {
const key = `${prefix}:${model.id}`
const promises = [
redis.delAsync(key),
redis.hmsetAsync(key, ...params)
redis.del(key),
redis.hmset(key, ...params)
]
// Update indexes.
@ -109,7 +109,7 @@ export default class Redis extends Collection {
}
const key = prefix + '_' + index + ':' + value
promises.push(redis.saddAsync(key, model.id))
promises.push(redis.sadd(key, model.id))
})
await Promise.all(promises)
@ -122,7 +122,7 @@ export default class Redis extends Collection {
const {prefix, redis} = this
if (isEmpty(properties)) {
return redis.smembersAsync(prefix + '_ids').then(ids => this._extract(ids))
return redis.smembers(prefix + '_ids').then(ids => this._extract(ids))
}
// Special treatment for the identifier.
@ -145,7 +145,7 @@ export default class Redis extends Collection {
}
const keys = mapToArray(properties, (value, index) => `${prefix}_${index}:${value}`)
return redis.sinterAsync(...keys).then(ids => this._extract(ids))
return redis.sinter(...keys).then(ids => this._extract(ids))
}
_remove (ids) {
@ -155,10 +155,10 @@ export default class Redis extends Collection {
return Promise.all([
// Remove the identifiers from the main index.
redis.sremAsync(prefix + '_ids', ...ids),
redis.srem(prefix + '_ids', ...ids),
// Remove the models.
redis.delAsync(mapToArray(ids, id => `${prefix}:${id}`))
redis.del(mapToArray(ids, id => `${prefix}:${id}`))
])
}

View File

@ -308,6 +308,8 @@ export function pSettle (promises) {
export {
all as pAll,
catchPlus as pCatch,
delay as pDelay,
fromCallback as pFromCallback,
isPromise,
lastly as pFinally,

View File

@ -38,6 +38,8 @@ import {
noop,
pAll,
parseXml,
pCatch,
pDelay,
pFinally,
promisifyAll,
pSettle
@ -1561,7 +1563,7 @@ export default class Xapi extends XapiBase {
{}
)
await this.call(
const loop = () => this.call(
'VM.migrate_send',
vm.$ref,
token,
@ -1571,7 +1573,12 @@ export default class Xapi extends XapiBase {
{
force: 'true'
}
)::pCatch(
{ code: 'TOO_MANY_STORAGE_MIGRATES' },
() => pDelay(1e4).then(loop)
)
return loop()
}
async _importVm (stream, sr, onlyMetadata = false, onVmCreation = undefined) {
@ -2286,12 +2293,12 @@ export default class Xapi extends XapiBase {
// Then, generate a FAT fs
const fs = fatfs.createFileSystem(fatfsBuffer(buffer))::promisifyAll()
// Create Cloud config folders
await fs.mkdirAsync('openstack')
await fs.mkdirAsync('openstack/latest')
await fs.mkdir('openstack')
await fs.mkdir('openstack/latest')
// Create the meta_data file
await fs.writeFileAsync('openstack/latest/meta_data.json', '{\n "uuid": "' + vm.uuid + '"\n}\n')
await fs.writeFile('openstack/latest/meta_data.json', '{\n "uuid": "' + vm.uuid + '"\n}\n')
// Create the user_data file
await fs.writeFileAsync('openstack/latest/user_data', config)
await fs.writeFile('openstack/latest/user_data', config)
// Transform the buffer into a stream
const stream = bufferToStream(buffer)