balena-supervisor/src/migrations/20171129013519_legacy.js
Pablo Carranza Velez 58b167b43d Various bugfixes and sytlistic improvements
* Use the correct defaults for the delta config variables that have them

* Only mount /lib/firmware and /lib/modules if they exist on the host

* hardcode-migrations.js: Nicer line separation

* APIBinder: switch to using a header for authentication, and keep credentials saved in the API clients

* Fix hrtime measurements in milliseconds

* Do not uses classes for routers

* compose: properly initialize networkMode to the first entry in networks if there is one

* Fix some details regarding defaults in validation and service

Signed-off-by: Pablo Carranza Velez <pablo@resin.io>
2018-03-06 10:32:29 -08:00

137 lines
4.2 KiB
JavaScript

// This migration implements the legacy db schema used in supervisors lower than 7.0.0.
// It's a bit ugly for a migration (it's unusual that migrations check for existence of tables and columns)
// but being the first migration for a legacy system, this is the easiest way to bring the db
// to a known schema to start doing proper migrations afterwards.
// For reference, compare this to db.coffee in old supervisors (e.g. v6.4.2), but consider we've added
// a few dropColumn and dropTable calls to delete things that were removed throughout the supervisor's
// history without actually adding drop statements (mostly just becoming unused, but still there).
exports.up = function (knex, Promise) {
const addColumn = function (table, column, type) {
return knex.schema.hasColumn(table, column)
.then((exists) => {
if (!exists) {
return knex.schema.table(table, (t) => { return t[type](column) })
}
})
}
const dropColumn = function (table, column) {
return knex.schema.hasColumn(table, column)
.then((exists) => {
if (exists) {
return knex.schema.table(table, (t) => { return t.dropColumn(column) })
}
})
}
const createTableOrRun = function (tableName, tableCreator, runIfTableExists) {
return knex.schema.hasTable(tableName)
.then((exists) => {
if (!exists) {
return knex.schema.createTable(tableName, tableCreator)
} else if (runIfTableExists != null) {
return runIfTableExists()
}
})
}
const dropTable = function (tableName) {
return knex.schema.hasTable(tableName)
.then((exists) => {
if (exists) {
return knex.schema.dropTable(tableName)
}
})
}
return Promise.all([
createTableOrRun('config', (t) => {
t.string('key').primary()
t.string('value')
}),
createTableOrRun('deviceConfig', (t) => {
t.json('values')
t.json('targetValues')
}).then(() => {
return knex('deviceConfig').select()
.then((deviceConfigs) => {
if (deviceConfigs.length == 0) {
return knex('deviceConfig').insert({ values: '{}', targetValues: '{}' })
}
})
}),
createTableOrRun('app', (t) => {
t.increments('id').primary()
t.string('name')
t.string('containerName')
t.string('commit')
t.string('imageId')
t.string('appId')
t.boolean('privileged')
t.json('env')
t.json('config')
t.boolean('markedForDeletion')
}, () => {
return Promise.all([
addColumn('app', 'commit', 'string'),
addColumn('app', 'appId', 'string'),
addColumn('app', 'containerName', 'string'),
addColumn('app', 'config', 'json'),
addColumn('app', 'markedForDeletion', 'boolean'),
dropColumn('app', 'containerId')
]).then(() => {
//When updating from older supervisors, config can be null
return knex('app').update({ config: '{}' }).whereNull('config')
.then(() => {
knex('app').update({ markedForDeletion: false }).whereNull('markedForDeletion')
})
})
}),
createTableOrRun('dependentApp', (t) => {
t.increments('id').primary()
t.string('appId')
t.string('parentAppId')
t.string('name')
t.string('commit')
t.string('imageId')
t.json('config')
t.json('environment')
}, () => {
return addColumn('dependentApp', 'environment', 'json')
}),
createTableOrRun('dependentDevice', (t) => {
t.increments('id').primary()
t.string('uuid')
t.string('appId')
t.string('localId')
t.string('device_type')
t.string('logs_channel')
t.string('deviceId')
t.boolean('is_online')
t.string('name')
t.string('status')
t.string('download_progress')
t.string('is_managed_by')
t.dateTime('lock_expiry_date')
t.string('commit')
t.string('targetCommit')
t.json('environment')
t.json('targetEnvironment')
t.json('config')
t.json('targetConfig')
t.boolean('markedForDeletion')
}, () => {
return Promise.all([
addColumn('dependentDevice', 'markedForDeletion', 'boolean'),
addColumn('dependentDevice', 'localId', 'string'),
addColumn('dependentDevice', 'is_managed_by', 'string'),
addColumn('dependentDevice', 'lock_expiry_date', 'dateTime')
])
}),
dropTable('image'),
dropTable('container')
])
}
exports.down = function(knex, Promise) {
return Promise.reject(new Error('Not implemented'))
}