Avoid duplicate runner names
This commit is contained in:
parent
88cde4392a
commit
d959b763f0
|
@ -27,7 +27,7 @@ import { CONFIG, registerConfigChangedHandler } from './config'
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const LAST_MIGRATION_VERSION = 790
|
const LAST_MIGRATION_VERSION = 795
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import * as Sequelize from 'sequelize'
|
||||||
|
|
||||||
|
async function up (utils: {
|
||||||
|
transaction: Sequelize.Transaction
|
||||||
|
queryInterface: Sequelize.QueryInterface
|
||||||
|
sequelize: Sequelize.Sequelize
|
||||||
|
}): Promise<void> {
|
||||||
|
const { transaction } = utils
|
||||||
|
|
||||||
|
const query = 'DELETE FROM "runner" r1 ' +
|
||||||
|
'USING (SELECT MIN(id) as id, "name" FROM "runner" GROUP BY "name" HAVING COUNT(*) > 1) r2 ' +
|
||||||
|
'WHERE r1."name" = r2."name" AND r1.id <> r2.id'
|
||||||
|
|
||||||
|
await utils.sequelize.query(query, { transaction })
|
||||||
|
}
|
||||||
|
|
||||||
|
function down (options) {
|
||||||
|
throw new Error('Not implemented.')
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
up,
|
||||||
|
down
|
||||||
|
}
|
|
@ -35,6 +35,15 @@ const registerRunnerValidator = [
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const existing = await RunnerModel.loadByName(body.name)
|
||||||
|
if (existing) {
|
||||||
|
return res.fail({
|
||||||
|
status: HttpStatusCode.BAD_REQUEST_400,
|
||||||
|
message: 'This runner name already exists on this instance',
|
||||||
|
tags
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
res.locals.runnerRegistrationToken = runnerRegistrationToken
|
res.locals.runnerRegistrationToken = runnerRegistrationToken
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
|
|
|
@ -16,6 +16,10 @@ import { CONSTRAINTS_FIELDS } from '@server/initializers/constants'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fields: [ 'runnerRegistrationTokenId' ]
|
fields: [ 'runnerRegistrationTokenId' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'name' ],
|
||||||
|
unique: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -74,6 +78,14 @@ export class RunnerModel extends Model<Partial<AttributesOnly<RunnerModel>>> {
|
||||||
return RunnerModel.findOne(query)
|
return RunnerModel.findOne(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static loadByName (name: string) {
|
||||||
|
const query = {
|
||||||
|
where: { name }
|
||||||
|
}
|
||||||
|
|
||||||
|
return RunnerModel.findOne(query)
|
||||||
|
}
|
||||||
|
|
||||||
static listForApi (options: {
|
static listForApi (options: {
|
||||||
start: number
|
start: number
|
||||||
count: number
|
count: number
|
||||||
|
|
|
@ -177,6 +177,15 @@ describe('Test managing runners', function () {
|
||||||
|
|
||||||
toDeleteId = id
|
toDeleteId = id
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should fail with the same runner name', async function () {
|
||||||
|
await server.runners.register({
|
||||||
|
name,
|
||||||
|
description: 'super description',
|
||||||
|
registrationToken,
|
||||||
|
expectedStatus: HttpStatusCode.BAD_REQUEST_400
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Delete', function () {
|
describe('Delete', function () {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { pick } from '@shared/core-utils'
|
import { pick } from '@shared/core-utils'
|
||||||
|
import { buildUUID } from '@shared/extra-utils'
|
||||||
import { HttpStatusCode, RegisterRunnerBody, RegisterRunnerResult, ResultList, Runner, UnregisterRunnerBody } from '@shared/models'
|
import { HttpStatusCode, RegisterRunnerBody, RegisterRunnerResult, ResultList, Runner, UnregisterRunnerBody } from '@shared/models'
|
||||||
import { unwrapBody } from '../requests'
|
import { unwrapBody } from '../requests'
|
||||||
import { AbstractCommand, OverrideCommandOptions } from '../shared'
|
import { AbstractCommand, OverrideCommandOptions } from '../shared'
|
||||||
|
@ -68,7 +69,7 @@ export class RunnersCommand extends AbstractCommand {
|
||||||
const { data } = await this.server.runnerRegistrationTokens.list({ sort: 'createdAt' })
|
const { data } = await this.server.runnerRegistrationTokens.list({ sort: 'createdAt' })
|
||||||
|
|
||||||
const { runnerToken } = await this.register({
|
const { runnerToken } = await this.register({
|
||||||
name: 'runner',
|
name: 'runner ' + buildUUID(),
|
||||||
registrationToken: data[0].registrationToken
|
registrationToken: data[0].registrationToken
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue