mirror of https://github.com/requarks/wiki
parent
ba1d83ebcb
commit
82ea0b50fb
After Width: | Height: | Size: 1.6 KiB |
@ -1,136 +1,53 @@
|
||||
'use strict'
|
||||
|
||||
/* global winston, ROOTPATH, appconfig */
|
||||
/* global wiki */
|
||||
|
||||
const Promise = require('bluebird')
|
||||
const crypto = require('crypto')
|
||||
const fs = Promise.promisifyAll(require('fs-extra'))
|
||||
const https = require('follow-redirects').https
|
||||
const klaw = require('klaw')
|
||||
const path = require('path')
|
||||
const pm2 = Promise.promisifyAll(require('pm2'))
|
||||
const tar = require('tar')
|
||||
const through2 = require('through2')
|
||||
const zlib = require('zlib')
|
||||
const _ = require('lodash')
|
||||
// const pm2 = Promise.promisifyAll(require('pm2'))
|
||||
// const _ = require('lodash')
|
||||
const cfgHelper = require('../helpers/config')
|
||||
|
||||
module.exports = {
|
||||
|
||||
_remoteFile: 'https://github.com/Requarks/wiki/releases/download/{0}/wiki-js.tar.gz',
|
||||
_installDir: '',
|
||||
|
||||
/**
|
||||
* Install a version of Wiki.js
|
||||
* Upgrade from Wiki.js 1.x - MongoDB database
|
||||
*
|
||||
* @param {any} targetTag The version to install
|
||||
* @returns {Promise} Promise of the operation
|
||||
* @param {Object} opts Options object
|
||||
*/
|
||||
install (targetTag) {
|
||||
let self = this
|
||||
async upgradeFromMongo (opts) {
|
||||
wiki.telemetry.sendEvent('setup', 'upgradeFromMongo')
|
||||
|
||||
self._installDir = path.resolve(ROOTPATH, appconfig.paths.data, 'install')
|
||||
let mongo = require('mongodb').MongoClient
|
||||
let parsedMongoConStr = cfgHelper.parseConfigValue(opts.mongoCnStr)
|
||||
|
||||
return fs.ensureDirAsync(self._installDir).then(() => {
|
||||
return fs.emptyDirAsync(self._installDir)
|
||||
}).then(() => {
|
||||
let remoteURL = _.replace(self._remoteFile, '{0}', targetTag)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
/**
|
||||
* Fetch tarball and extract to temporary folder
|
||||
*/
|
||||
https.get(remoteURL, resp => {
|
||||
if (resp.statusCode !== 200) {
|
||||
return reject(new Error('Remote file not found'))
|
||||
return new Promise((resolve, reject) => {
|
||||
// Connect to MongoDB
|
||||
|
||||
return mongo.connect(parsedMongoConStr, {
|
||||
autoReconnect: false,
|
||||
reconnectTries: 2,
|
||||
reconnectInterval: 1000,
|
||||
connectTimeoutMS: 5000,
|
||||
socketTimeoutMS: 5000
|
||||
}, async (err, db) => {
|
||||
try {
|
||||
if (err !== null) { throw err }
|
||||
|
||||
let users = db.collection('users')
|
||||
|
||||
// Check if users table is populated
|
||||
let userCount = await users.count()
|
||||
if (userCount < 1) {
|
||||
throw new Error('Users table is empty or invalid!')
|
||||
}
|
||||
winston.info('[SERVER.System] Install tarball found. Downloading...')
|
||||
|
||||
resp.pipe(zlib.createGunzip())
|
||||
.pipe(tar.Extract({ path: self._installDir }))
|
||||
.on('error', err => reject(err))
|
||||
.on('end', () => {
|
||||
winston.info('[SERVER.System] Tarball extracted. Comparing files...')
|
||||
/**
|
||||
* Replace old files
|
||||
*/
|
||||
klaw(self._installDir)
|
||||
.on('error', err => reject(err))
|
||||
.on('end', () => {
|
||||
winston.info('[SERVER.System] All files were updated successfully.')
|
||||
resolve(true)
|
||||
})
|
||||
.pipe(self.replaceFile())
|
||||
})
|
||||
})
|
||||
})
|
||||
}).then(() => {
|
||||
winston.info('[SERVER.System] Cleaning install leftovers...')
|
||||
return fs.removeAsync(self._installDir).then(() => {
|
||||
winston.info('[SERVER.System] Restarting Wiki.js...')
|
||||
return pm2.restartAsync('wiki').catch(err => { // eslint-disable-line handle-callback-err
|
||||
winston.error('Unable to restart Wiki.js via pm2... Do a manual restart!')
|
||||
process.exit()
|
||||
})
|
||||
})
|
||||
}).catch(err => {
|
||||
winston.warn(err)
|
||||
})
|
||||
},
|
||||
// Fetch all users
|
||||
let userData = await users.find({}).toArray()
|
||||
console.info(userData)
|
||||
|
||||
/**
|
||||
* Replace file if different
|
||||
*/
|
||||
replaceFile () {
|
||||
let self = this
|
||||
return through2.obj((item, enc, next) => {
|
||||
if (!item.stats.isDirectory()) {
|
||||
self.digestFile(item.path).then(sourceHash => {
|
||||
let destFilePath = _.replace(item.path, self._installDir, ROOTPATH)
|
||||
return self.digestFile(destFilePath).then(targetHash => {
|
||||
if (sourceHash === targetHash) {
|
||||
winston.log('verbose', '[SERVER.System] Skipping ' + destFilePath)
|
||||
return fs.removeAsync(item.path).then(() => {
|
||||
return next() || true
|
||||
})
|
||||
} else {
|
||||
winston.log('verbose', '[SERVER.System] Updating ' + destFilePath + '...')
|
||||
return fs.moveAsync(item.path, destFilePath, { overwrite: true }).then(() => {
|
||||
return next() || true
|
||||
})
|
||||
}
|
||||
})
|
||||
}).catch(err => {
|
||||
throw err
|
||||
})
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate the hash of a file
|
||||
*
|
||||
* @param {String} filePath The absolute path of the file
|
||||
* @return {Promise<String>} Promise of the hash result
|
||||
*/
|
||||
digestFile: (filePath) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let hash = crypto.createHash('sha1')
|
||||
hash.setEncoding('hex')
|
||||
fs.createReadStream(filePath)
|
||||
.on('error', err => { reject(err) })
|
||||
.on('end', () => {
|
||||
hash.end()
|
||||
resolve(hash.read())
|
||||
})
|
||||
.pipe(hash)
|
||||
}).catch(err => {
|
||||
if (err.code === 'ENOENT') {
|
||||
return '0'
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
resolve(true)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
db.close()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in new issue