Sqlite Tweaks

- Added cypress testing in CI for sqlite
- Cleaned up promises in setup
- Ensure check for settings is strict
This commit is contained in:
Jamie Curnow 2020-08-06 08:58:20 +10:00
parent 04412f3624
commit 492d450d26
5 changed files with 180 additions and 105 deletions

View File

@ -0,0 +1,21 @@
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
},
"pool": {
"min": 0,
"max": 1,
"createTimeoutMillis": 3000,
"acquireTimeoutMillis": 30000,
"idleTimeoutMillis": 30000,
"reapIntervalMillis": 1000,
"createRetryIntervalMillis": 100,
"propagateCreateError": false
}
}
}
}

36
Jenkinsfile vendored
View File

@ -83,11 +83,11 @@ pipeline {
''' '''
} }
} }
stage('Test') { stage('Integration Tests Sqlite') {
steps { steps {
// Bring up a stack // Bring up a stack
sh 'docker-compose up -d fullstack' sh 'docker-compose up -d fullstack-sqlite'
sh './scripts/wait-healthy $(docker-compose ps -q fullstack) 120' sh './scripts/wait-healthy $(docker-compose ps -q fullstack-sqlite) 120'
// Run tests // Run tests
sh 'rm -rf test/results' sh 'rm -rf test/results'
@ -99,8 +99,36 @@ pipeline {
always { always {
// Dumps to analyze later // Dumps to analyze later
sh 'mkdir -p debug' sh 'mkdir -p debug'
sh 'docker-compose logs fullstack | gzip > debug/docker_fullstack.log.gz' sh 'docker-compose logs fullstack-sqlite | gzip > debug/docker_fullstack_sqlite.log.gz'
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz' sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
sh 'docker-compose down'
// Cypress videos and screenshot artifacts
dir(path: 'test/results') {
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
}
junit 'test/results/junit/*'
}
}
}
stage('Integration Tests Mysql') {
steps {
// Bring up a stack
sh 'docker-compose up -d fullstack-mysql'
sh './scripts/wait-healthy $(docker-compose ps -q fullstack-mysql) 120'
// Run tests
sh 'rm -rf test/results'
sh 'docker-compose up cypress'
// Get results
sh 'docker cp -L "$(docker-compose ps -q cypress):/results" test/'
}
post {
always {
// Dumps to analyze later
sh 'mkdir -p debug'
sh 'docker-compose logs fullstack-mysql | gzip > debug/docker_fullstack_mysql.log.gz'
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
sh 'docker-compose down'
// Cypress videos and screenshot artifacts // Cypress videos and screenshot artifacts
dir(path: 'test/results') { dir(path: 'test/results') {
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml' archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'

View File

@ -8,92 +8,101 @@ const authModel = require('./models/auth');
const settingModel = require('./models/setting'); const settingModel = require('./models/setting');
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG; const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
function setupJwt(resolve, reject) { /**
// Now go and check if the jwt gpg keys have been created and if not, create them * Creates a new JWT RSA Keypair if not alread set on the config
if (!config.has('jwt') || !config.has('jwt.key') || !config.has('jwt.pub')) { *
logger.info('Creating a new JWT key pair...'); * @returns {Promise}
*/
const setupJwt = () => {
return new Promise((resolve, reject) => {
// Now go and check if the jwt gpg keys have been created and if not, create them
if (!config.has('jwt') || !config.has('jwt.key') || !config.has('jwt.pub')) {
logger.info('Creating a new JWT key pair...');
// jwt keys are not configured properly // jwt keys are not configured properly
const filename = config.util.getEnv('NODE_CONFIG_DIR') + '/' + (config.util.getEnv('NODE_ENV') || 'default') + '.json'; const filename = config.util.getEnv('NODE_CONFIG_DIR') + '/' + (config.util.getEnv('NODE_ENV') || 'default') + '.json';
let config_data = {}; let config_data = {};
try { try {
config_data = require(filename); config_data = require(filename);
} catch (err) { } catch (err) {
// do nothing // do nothing
if (debug_mode) {
logger.debug(filename + ' config file could not be required');
}
}
// Now create the keys and save them in the config.
let key = new NodeRSA({ b: 2048 });
key.generateKeyPair();
config_data.jwt = {
key: key.exportKey('private').toString(),
pub: key.exportKey('public').toString(),
};
// Write config
fs.writeFile(filename, JSON.stringify(config_data, null, 2), (err) => {
if (err) {
logger.error('Could not write JWT key pair to config file: ' + filename);
reject(err);
} else {
logger.info('Wrote JWT key pair to config file: ' + filename);
logger.warn('Restarting interface to apply new configuration');
process.exit(0);
}
});
} else {
// JWT key pair exists
if (debug_mode) { if (debug_mode) {
logger.debug(filename + ' config file could not be required'); logger.debug('JWT Keypair already exists');
} }
resolve();
} }
});
};
// Now create the keys and save them in the config. /**
let key = new NodeRSA({b: 2048}); * Creates a default admin users if one doesn't already exist in the database
key.generateKeyPair(); *
* @returns {Promise}
config_data.jwt = { */
key: key.exportKey('private').toString(), const setupDefaultUser = () => {
pub: key.exportKey('public').toString() return userModel
};
// Write config
fs.writeFile(filename, JSON.stringify(config_data, null, 2), (err) => {
if (err) {
logger.error('Could not write JWT key pair to config file: ' + filename);
reject(err);
} else {
logger.info('Wrote JWT key pair to config file: ' + filename);
logger.warn('Restarting interface to apply new configuration');
process.exit(0);
}
});
} else {
// JWT key pair exists
if (debug_mode) {
logger.debug('JWT Keypair already exists');
}
resolve();
}
}
function setupDefaultUser() {
(userModel
.query() .query()
.select(userModel.raw('COUNT(`id`) as `count`')) .select(userModel.raw('COUNT(`id`) as `count`'))
.where('is_deleted', 0) .where('is_deleted', 0)
.first() .first()
).then( (row) => { .then((row) => {
if (!row.count) { if (!row.count) {
// Create a new user and set password // Create a new user and set password
logger.info('Creating a new user: admin@example.com with password: changeme'); logger.info('Creating a new user: admin@example.com with password: changeme');
let data = { let data = {
is_deleted: 0, is_deleted: 0,
email: 'admin@example.com', email: 'admin@example.com',
name: 'Administrator', name: 'Administrator',
nickname: 'Admin', nickname: 'Admin',
avatar: '', avatar: '',
roles: ['admin'] roles: ['admin'],
}; };
return userModel return userModel
.query() .query()
.insertAndFetch(data) .insertAndFetch(data)
.then( (user) => { .then((user) => {
return authModel return authModel
.query() .query()
.insert({ .insert({
user_id: user.id, user_id: user.id,
type: 'password', type: 'password',
secret: 'changeme', secret: 'changeme',
meta: {} meta: {},
}) })
.then(() => { .then(() => {
return userPermissionModel return userPermissionModel.query().insert({
.query()
.insert({
user_id: user.id, user_id: user.id,
visibility: 'all', visibility: 'all',
proxy_hosts: 'manage', proxy_hosts: 'manage',
@ -101,25 +110,31 @@ function setupDefaultUser() {
dead_hosts: 'manage', dead_hosts: 'manage',
streams: 'manage', streams: 'manage',
access_lists: 'manage', access_lists: 'manage',
certificates: 'manage' certificates: 'manage',
}); });
}); });
}) })
.then(() => { .then(() => {
logger.info('Initial admin setup completed'); logger.info('Initial admin setup completed');
}); });
} else if (debug_mode) { } else if (debug_mode) {
logger.debug('Admin user setup not required'); logger.debug('Admin user setup not required');
} }
}); });
} };
function setupDefaultSettings() { /**
* Creates default settings if they don't already exist in the database
*
* @returns {Promise}
*/
const setupDefaultSettings = () => {
return settingModel return settingModel
.query() .query()
.select(userModel.raw('COUNT(`id`) as `count`')) .select(settingModel.raw('COUNT(`id`) as `count`'))
.where({id: 'default-site'})
.first() .first()
.then( (row) => { .then((row) => {
if (!row.count) { if (!row.count) {
settingModel settingModel
.query() .query()
@ -128,22 +143,20 @@ function setupDefaultSettings() {
name: 'Default Site', name: 'Default Site',
description: 'What to show when Nginx is hit with an unknown Host', description: 'What to show when Nginx is hit with an unknown Host',
value: 'congratulations', value: 'congratulations',
meta: {} meta: {},
}).then(() => { })
.then(() => {
logger.info('Default settings added'); logger.info('Default settings added');
}); });
} if (debug_mode) { }
if (debug_mode) {
logger.debug('Default setting setup not required'); logger.debug('Default setting setup not required');
} }
}); });
} };
module.exports = function () { module.exports = function () {
return new Promise((resolve, reject) => { return setupJwt()
return setupJwt(resolve, reject); .then(setupDefaultUser)
}).then(() => { .then(setupDefaultSettings);
return setupDefaultUser();
}).then(() => {
return setupDefaultSettings();
});
}; };

View File

@ -2,14 +2,14 @@
version: "3" version: "3"
services: services:
fullstack: fullstack-mysql:
image: ${IMAGE}:ci-${BUILD_NUMBER} image: ${IMAGE}:ci-${BUILD_NUMBER}
environment: environment:
- NODE_ENV=development - NODE_ENV=development
- FORCE_COLOR=1 - FORCE_COLOR=1
volumes: volumes:
- npm_data:/data - npm_data:/data
- ../.jenkins/config.json:/app/config/production.json - ../.jenkins/config-mysql.json:/app/config/production.json
expose: expose:
- 81 - 81
- 80 - 80
@ -17,6 +17,19 @@ services:
depends_on: depends_on:
- db - db
fullstack-sqlite:
image: ${IMAGE}:ci-${BUILD_NUMBER}
environment:
- NODE_ENV=development
- FORCE_COLOR=1
volumes:
- npm_data:/data
- ../.jenkins/config-sqlite.json:/app/config/production.json
expose:
- 81
- 80
- 443
db: db:
image: jc21/mariadb-aria image: jc21/mariadb-aria
environment: environment: