mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-03-13 15:56:38 +00:00
157 lines
4.4 KiB
JavaScript
157 lines
4.4 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'));
|
|
};
|