improve setup and DB initialization

This commit is contained in:
lesion 2022-01-26 09:51:42 +01:00
parent 5a3ff7564d
commit 55c066b845
No known key found for this signature in database
GPG key ID: 352918250B012177
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 (req.firstrun && route.path !== '/setup') {
return redirect('/setup')
if (req.status === 'SETUP' && route.path !== '/setup/0') {
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('/')
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,49 +8,59 @@ const path = require('path')
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')
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 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.')
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)
await setupController._setupDb(dbConf)
} catch (e) {
return res.status(400).send(String(e))
}
return res.sendStatus(200)
},
async restart (req, res) {
try {
config.baseurl = req.protocol + '://' + req.headers.host
config.hostname = new URL.URL(config.baseurl).hostname
// write configuration
config.write()
@ -72,8 +82,9 @@ const setupController = {
log.info('Restart needed')
res.end()
// exit process so pm2 || docker could restart me || service
process.kill(process.pid)
setTimeout(() => process.kill(process.pid), 1000)
} catch (e) {
log.error(String(e))

View file

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

View file

@ -22,7 +22,7 @@ const db = {
return !(users && users.length)
},
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({
storage: 'sequelize',
storageOptions: { sequelize: db.sequelize },
@ -41,7 +41,7 @@ const db = {
return await umzug.up()
},
async initialize () {
if (!config.firstrun) {
if (config.status === 'READY') {
try {
await db.connect()
log.debug('Running migrations')

View file

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

View file

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

View file

@ -6,6 +6,28 @@ const cookieParser = require('cookie-parser')
// const metricsMiddleware = promBundle({ includeMethod: true })
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 log = require('./log')
const api = require('./api')
@ -23,7 +45,7 @@ app.use(cookieParser())
// do not handle all routes on setup
if (!config.firstrun) {
if (config.status === 'READY') {
const cors = require('cors')
const { spamFilter } = require('./federation/helpers')
const oauth = require('./api/oauth')
@ -65,13 +87,13 @@ app.use((error, req, res, next) => {
app.use(async (req, res, next) => {
// const start_datetime = getUnixTime(startOfWeek(startOfMonth(new Date())))
// req.events = await eventController._select(start_datetime, 100)
if (!config.firstrun) {
if (config.status === 'READY') {
const eventController = require('./api/controller/event')
const announceController = require('./api/controller/announce')
req.meta = await eventController._getMeta()
req.announcements = await announceController._getVisible()
}
req.firstrun = config.firstrun
req.status = config.status
next()
})

View file

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