improve setup and DB initialization

This commit is contained in:
lesion
2022-01-26 09:51:42 +01:00
parent 5a3ff7564d
commit 55c066b845
13 changed files with 96 additions and 57 deletions

View File

@@ -1,9 +1,14 @@
export default function ({ req, redirect, route }) { export default async function ({ $config, req, redirect, route, error }) {
if (process.server) { if (process.server) {
if (req.firstrun && route.path !== '/setup') { if (req.status === 'SETUP' && route.path !== '/setup/0') {
return redirect('/setup') return redirect('/setup/0')
} }
if (!req.firstrun && route.path === '/setup') {
if (req.status === 'DBCONF' && route.path !== '/setup/1') {
return redirect('/setup/1')
}
if (req.status === 'READY' && route.path.startsWith('/setup')) {
return redirect('/') return redirect('/')
} }
} }

View File

@@ -20,7 +20,7 @@ module.exports = {
vue: { vue: {
config: { config: {
ignoredElements: ['gancio-events'] ignoredElements: ['gancio-events', 'gancio-event']
} }
}, },

View File

@@ -47,6 +47,7 @@
"linkify-html": "^3.0.4", "linkify-html": "^3.0.4",
"linkifyjs": "3.0.4", "linkifyjs": "3.0.4",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mariadb": "^2.5.5",
"microformat-node": "^2.0.1", "microformat-node": "^2.0.1",
"mkdirp": "^1.0.4", "mkdirp": "^1.0.4",
"multer": "^1.4.3", "multer": "^1.4.3",

View File

@@ -24,6 +24,7 @@ export default {
data () { data () {
return { return {
db: { db: {
dialect: 'sqlite',
storage: './gancio.sqlite', storage: './gancio.sqlite',
host: 'localhost', host: 'localhost',
database: 'gancio' database: 'gancio'

View File

@@ -4,14 +4,14 @@
h2.mb-2.text-center Gancio Setup h2.mb-2.text-center Gancio Setup
v-stepper.grey.lighten-5(v-model='step') v-stepper.grey.lighten-5(v-model='step')
v-stepper-header v-stepper-header
v-stepper-step(:complete='step > 1' step='1') Database v-stepper-step(v-show='!dbdone' :complete='step > 1' step='1') Database
v-divider v-divider(v-show='!dbdone')
v-stepper-step(:complete='step > 2' step='2') Configuration v-stepper-step(:complete='step > 2' step='2') Configuration
v-divider v-divider
v-stepper-step(:complete='step > 3' step='3') Finish v-stepper-step(:complete='step > 3' step='3') Finish
v-stepper-items v-stepper-items
v-stepper-content(step='1') v-stepper-content(v-show='!dbdone' step='1')
DbStep(@complete='dbCompleted') DbStep(@complete='dbCompleted')
v-stepper-content(step='2') v-stepper-content(step='2')
Settings(setup, @complete='configCompleted') Settings(setup, @complete='configCompleted')
@@ -36,14 +36,16 @@ export default {
title: 'Setup', title: 'Setup',
}, },
auth: false, auth: false,
data () { asyncData ({ params }) {
return { return {
dbdone: !!Number(params.db),
config: { config: {
db: { db: {
dialect: '' dialect: ''
} }
}, },
step: 1 step: 1 + Number(params.db)
} }
}, },
methods: { methods: {

View File

@@ -54,7 +54,7 @@ const settingsController = {
secretSettings: {}, secretSettings: {},
async load () { async load () {
if (config.firstrun) { if (config.status !== 'READY') {
settingsController.settings = defaultSettings settingsController.settings = defaultSettings
return return
} }

View File

@@ -8,49 +8,59 @@ const path = require('path')
const setupController = { const setupController = {
async setupDb (req, res, next) { async _setupDb (dbConf) {
if (!dbConf) {
throw Error('Empty DB configuration')
}
if (dbConf.dialect === 'sqlite' && dbConf.storage) {
dbConf.storage = path.resolve(process.env.cwd || '', dbConf.storage)
} else {
dbConf.storage = ''
}
// try to connect
dbConf.logging = false
await db.connect(dbConf)
// is empty ?
const isEmpty = await db.isEmpty()
if (!isEmpty) {
log.warn(' ⚠ Non empty db! Please move your current db elsewhere than retry.')
throw Error(' ⚠ Non empty db! Please move your current db elsewhere than retry.')
}
await db.runMigrations()
config.db = dbConf
config.status = 'DBCONF'
config.db.logging = false
const settingsController = require('./settings')
await settingsController.load()
},
async setupDb (req, res) {
log.debug('[SETUP] Check db') log.debug('[SETUP] Check db')
const dbConf = req.body.db const dbConf = req.body.db
if (!dbConf) {
return res.sendStatus(400)
}
if (dbConf.storage) {
dbConf.storage = path.resolve(process.env.cwd || '', dbConf.storage)
}
try { try {
// try to connect await setupController._setupDb(dbConf)
dbConf.logging = false
await db.connect(dbConf)
// is empty ?
const isEmpty = await db.isEmpty()
if (!isEmpty) {
log.warn(' ⚠ Non empty db! Please move your current db elsewhere than retry.')
return res.status(400).send(' ⚠ Non empty db! Please move your current db elsewhere than retry.')
}
await db.runMigrations()
config.db = dbConf
config.firstrun = false
config.db.logging = false
config.baseurl = req.protocol + '://' + req.headers.host
config.hostname = new URL.URL(config.baseurl).hostname
const settingsController = require('./settings')
await settingsController.load()
return res.sendStatus(200)
} catch (e) { } catch (e) {
return res.status(400).send(String(e)) return res.status(400).send(String(e))
} }
return res.sendStatus(200)
}, },
async restart (req, res) { async restart (req, res) {
try { try {
config.baseurl = req.protocol + '://' + req.headers.host
config.hostname = new URL.URL(config.baseurl).hostname
// write configuration // write configuration
config.write() config.write()
@@ -72,8 +82,9 @@ const setupController = {
log.info('Restart needed') log.info('Restart needed')
res.end() res.end()
// exit process so pm2 || docker could restart me || service // exit process so pm2 || docker could restart me || service
process.kill(process.pid) setTimeout(() => process.kill(process.pid), 1000)
} catch (e) { } catch (e) {
log.error(String(e)) log.error(String(e))

View File

@@ -10,7 +10,7 @@ api.use(express.urlencoded({ extended: false }))
api.use(express.json()) api.use(express.json())
if (config.firstrun) { if (config.status !== 'READY') {
const setupController = require('./controller/setup') const setupController = require('./controller/setup')
const settingsController = require('./controller/settings') const settingsController = require('./controller/settings')

View File

@@ -22,7 +22,7 @@ const db = {
return !(users && users.length) return !(users && users.length)
}, },
async runMigrations () { async runMigrations () {
const logging = config.firstrun ? false : log.debug.bind(log) const logging = config.status !== 'READY' ? false : log.debug.bind(log)
const umzug = new Umzug({ const umzug = new Umzug({
storage: 'sequelize', storage: 'sequelize',
storageOptions: { sequelize: db.sequelize }, storageOptions: { sequelize: db.sequelize },
@@ -41,7 +41,7 @@ const db = {
return await umzug.up() return await umzug.up()
}, },
async initialize () { async initialize () {
if (!config.firstrun) { if (config.status === 'READY') {
try { try {
await db.connect() await db.connect()
log.debug('Running migrations') log.debug('Running migrations')

View File

@@ -3,7 +3,7 @@ const path = require('path')
const URL = require('url') const URL = require('url')
let config = { let config = {
firstrun: true, status: 'SETUP',
baseurl: '', baseurl: '',
hostname: '', hostname: '',
server: { server: {
@@ -15,7 +15,7 @@ let config = {
db: {}, db: {},
upload_path: path.resolve(process.env.cwd || '', 'uploads'), upload_path: path.resolve(process.env.cwd || '', 'uploads'),
write (config_path= process.env.config_path || './config.json') { write (config_path= process.env.config_path || './config.json') {
delete config.firstrun delete config.status
return fs.writeFileSync(config_path, JSON.stringify(config, null, 2)) return fs.writeFileSync(config_path, JSON.stringify(config, null, 2))
}, },
@@ -26,12 +26,12 @@ let config = {
if (fs.existsSync(config_path)) { if (fs.existsSync(config_path)) {
const configContent = fs.readFileSync(config_path) const configContent = fs.readFileSync(config_path)
config = Object.assign(config, JSON.parse(configContent)) config = Object.assign(config, JSON.parse(configContent))
config.firstrun = false config.status = 'READY'
if (!config.hostname) { if (!config.hostname) {
config.hostname = new URL.URL(config.baseurl).hostname config.hostname = new URL.URL(config.baseurl).hostname
} }
} else { } else {
config.firstrun = true config.status = 'SETUP'
console.info('> Configuration file does not exists, running setup..') console.info('> Configuration file does not exists, running setup..')
} }
} }

View File

@@ -1,9 +1,6 @@
export default async function () { export default async function () {
const db = require('./api/models/index')
await db.initialize()
async function start (nuxt) { async function start (nuxt) {
const log = require('../server/log') const log = require('../server/log')
const config = require('../server/config') const config = require('../server/config')
const settingsController = require('./api/controller/settings') const settingsController = require('./api/controller/settings')
@@ -14,7 +11,7 @@ export default async function () {
dayjs.tz.setDefault(settingsController.settings.instance_timezone) dayjs.tz.setDefault(settingsController.settings.instance_timezone)
let TaskManager let TaskManager
if (!config.firstrun) { if (config.status === 'READY') {
TaskManager = require('../server/taskManager').TaskManager TaskManager = require('../server/taskManager').TaskManager
TaskManager.start() TaskManager.start()
} }

View File

@@ -6,6 +6,28 @@ const cookieParser = require('cookie-parser')
// const metricsMiddleware = promBundle({ includeMethod: true }) // const metricsMiddleware = promBundle({ includeMethod: true })
const config = require('./config') const config = require('./config')
if (config.status == 'READY') {
const db = require('./api/models/index')
db.initialize()
} else {
if (process.env.GANCIO_DB_DIALECT) {
const setupController = require('./api/controller/setup')
const dbConf = {
dialect: process.env.GANCIO_DB_DIALECT,
storage: process.env.GANCIO_DB_STORAGE,
host: process.env.GANCIO_DB_HOST,
database: process.env.GANCIO_DB_DATABASE,
username: process.env.GANCIO_DB_USERNAME,
password: process.env.GANCIO_DB_PASSWORD,
}
setupController._setupDb(dbConf)
.catch(e => { process.exit(1) })
}
}
const helpers = require('./helpers') const helpers = require('./helpers')
const log = require('./log') const log = require('./log')
const api = require('./api') const api = require('./api')
@@ -23,7 +45,7 @@ app.use(cookieParser())
// do not handle all routes on setup // do not handle all routes on setup
if (!config.firstrun) { if (config.status === 'READY') {
const cors = require('cors') const cors = require('cors')
const { spamFilter } = require('./federation/helpers') const { spamFilter } = require('./federation/helpers')
const oauth = require('./api/oauth') const oauth = require('./api/oauth')
@@ -65,13 +87,13 @@ app.use((error, req, res, next) => {
app.use(async (req, res, next) => { app.use(async (req, res, next) => {
// const start_datetime = getUnixTime(startOfWeek(startOfMonth(new Date()))) // const start_datetime = getUnixTime(startOfWeek(startOfMonth(new Date())))
// req.events = await eventController._select(start_datetime, 100) // req.events = await eventController._select(start_datetime, 100)
if (!config.firstrun) { if (config.status === 'READY') {
const eventController = require('./api/controller/event') const eventController = require('./api/controller/event')
const announceController = require('./api/controller/announce') const announceController = require('./api/controller/announce')
req.meta = await eventController._getMeta() req.meta = await eventController._getMeta()
req.announcements = await announceController._getVisible() req.announcements = await announceController._getVisible()
} }
req.firstrun = config.firstrun req.status = config.status
next() next()
}) })

View File

@@ -54,7 +54,7 @@ export const actions = {
// we use it to get configuration from db, set locale, etc... // we use it to get configuration from db, set locale, etc...
nuxtServerInit ({ commit }, { req }) { nuxtServerInit ({ commit }, { req }) {
commit('setSettings', req.settings) commit('setSettings', req.settings)
if (!req.firstrun) { if (req.status === 'READY') {
commit('setAnnouncements', req.announcements) commit('setAnnouncements', req.announcements)
commit('update', req.meta) commit('update', req.meta)
} }