feat: npm install execute OS specific install script

pull/203/head
NGPixel 7 years ago
parent 23e0d473e9
commit 61fe3d3d8b

@ -1,154 +0,0 @@
#######################################################################
# Wiki.js - CONFIGURATION #
#######################################################################
# Full explanation + examples in the documentation:
# https://docs.requarks.io/wiki/install
# ---------------------------------------------------------------------
# Title of this site
# ---------------------------------------------------------------------
title: $(WIKI_TITLE)
# ---------------------------------------------------------------------
# Full public path to the site, without the trailing slash
# ---------------------------------------------------------------------
host: $(WIKI_HOST)
# ---------------------------------------------------------------------
# Port the main server should listen to (80 by default)
# ---------------------------------------------------------------------
port: $(PORT)
# ---------------------------------------------------------------------
# Data Directories
# ---------------------------------------------------------------------
paths:
repo: ./repo
data: ./data
# ---------------------------------------------------------------------
# Upload Limits
# ---------------------------------------------------------------------
# In megabytes (MB)
uploads:
maxImageFileSize: 3
maxOtherFileSize: 100
# ---------------------------------------------------------------------
# Site Language
# ---------------------------------------------------------------------
# Possible values: en, es, fr, ko, ru or zh
lang: $(WIKI_LANG)
# ---------------------------------------------------------------------
# Site Authentication
# ---------------------------------------------------------------------
public: $(WIKI_PUBLIC)
auth:
defaultReadAccess: false
local:
enabled: true
google:
enabled: false
clientId: GOOGLE_CLIENT_ID
clientSecret: GOOGLE_CLIENT_SECRET
microsoft:
enabled: false
clientId: MS_APP_ID
clientSecret: MS_APP_SECRET
facebook:
enabled: false
clientId: FACEBOOK_APP_ID
clientSecret: FACEBOOK_APP_SECRET
github:
enabled: false
clientId: GITHUB_CLIENT_ID
clientSecret: GITHUB_CLIENT_SECRET
slack:
enabled: false
clientId: SLACK_CLIENT_ID
clientSecret: SLACK_CLIENT_SECRET
ldap:
enabled: false
url: ldap://serverhost:389
bindDn: cn='root'
bindCredentials: BIND_PASSWORD
searchBase: o=users,o=example.com
searchFilter: (uid={{username}})
tlsEnabled: false
tlsCertPath: C:\example\root_ca_cert.crt
azure:
enabled: false
clientID: APP_ID
clientSecret: APP_SECRET_KEY
resource: '00000002-0000-0000-c000-000000000000'
tenant: 'YOUR_TENANT.onmicrosoft.com'
# ---------------------------------------------------------------------
# Secret key to use when encrypting sessions
# ---------------------------------------------------------------------
# Use a long and unique random string (256-bit keys are perfect!)
sessionSecret: $(WIKI_SESSION_KEY)
# ---------------------------------------------------------------------
# Database Connection String
# ---------------------------------------------------------------------
db: $(MONGODB_URI)
# ---------------------------------------------------------------------
# Git Connection Info
# ---------------------------------------------------------------------
git:
url: $(WIKI_GIT_URL)
branch: $(WIKI_GIT_BRANCH)
auth:
# Type: basic or ssh
type: basic
# Only for Basic authentication:
username: $(WIKI_GIT_USERNAME)
password: $(WIKI_GIT_PASSWORD)
# Only for SSH authentication:
privateKey: /etc/wiki/keys/git.pem
sslVerify: true
# Default email to use as commit author
serverEmail: $(WIKI_SERVER_EMAIL)
# Whether to use user email as author in commits
showUserEmail: $(WIKI_SHOW_USER_EMAIL)
# ---------------------------------------------------------------------
# Features
# ---------------------------------------------------------------------
# You can enable / disable specific features below
features:
linebreaks: true
mathjax: true
# ---------------------------------------------------------------------
# External Logging
# ---------------------------------------------------------------------
externalLogging:
bugsnag: false
loggly: false
papertrail: false
rollbar: false
sentry: false

@ -5,274 +5,21 @@
// Installation Script // Installation Script
// ===================================================== // =====================================================
const Promise = require('bluebird')
const _ = require('lodash')
const colors = require('colors/safe')
const exec = require('execa')
const fs = Promise.promisifyAll(require('fs-extra'))
const https = require('follow-redirects').https
const inquirer = require('inquirer')
const os = require('os')
const path = require('path') const path = require('path')
const pm2 = Promise.promisifyAll(require('pm2')) const spawn = require('child_process').spawn
const tar = require('tar')
const zlib = require('zlib')
const installDir = path.resolve(__dirname, '../..') const installDir = path.resolve(__dirname, '../..')
const isContainerBased = (process.env.WIKI_JS_HEROKU || process.env.WIKI_JS_DOCKER) const cmd = (process.platform !== 'win32')
let installMode = 'new' ? 'curl -s -S -o- https://wiki.js.org/install.sh | bash'
: `PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://wiki.js.org/install.ps1'))"`
// =====================================================
// INSTALLATION TASKS
// =====================================================
const tasks = {
/**
* Stop and delete existing instances
*/
stopAndDeleteInstances() {
ora.text = 'Looking for running instances...'
return pm2.connectAsync().then(() => {
return pm2.describeAsync('wiki').then(() => {
ora.text = 'Stopping and deleting process from pm2...'
return pm2.deleteAsync('wiki')
}).catch(err => { // eslint-disable-line handle-callback-err
return true
}).finally(() => {
pm2.disconnect()
})
}).catch(err => { // eslint-disable-line handle-callback-err
return true
})
},
/**
* Check for sufficient memory
*/
checkRequirements() {
ora.text = 'Checking system requirements...'
if (os.totalmem() < 1000 * 1000 * 768) {
return Promise.reject(new Error('Not enough memory to install dependencies. Minimum is 768 MB.'))
} else {
return Promise.resolve(true)
}
},
/**
* Install via local tarball if present
*/
installFromLocal() {
let hasTarball = true
let tbPath = path.join(installDir, 'wiki-js.tar.gz')
return fs.accessAsync(tbPath)
.catch(err => { // eslint-disable-line handle-callback-err
hasTarball = false
}).then(() => {
if (hasTarball) {
ora.text = 'Local tarball found. Extracting...'
return new Promise((resolve, reject) => {
fs.createReadStream(tbPath).pipe(zlib.createGunzip())
.pipe(tar.extract({ cwd: installDir }))
.on('error', err => reject(err))
.on('end', () => {
ora.text = 'Tarball extracted successfully.'
resolve(tasks.installDependencies())
isContainerBased && console.info('>> Installing dependencies...')
})
})
} else {
return false
}
})
},
/**
* Install from GitHub release download
*/
installFromRemote() {
// Fetch version from npm package
return fs.readJsonAsync('package.json').then((packageObj) => {
let versionGet = _.chain(packageObj.version).split('.').take(4).join('.')
let remoteURLApp = _.replace('https://github.com/Requarks/wiki/releases/download/v{0}/wiki-js.tar.gz', '{0}', versionGet)
let remoteURLDeps = _.replace('https://github.com/Requarks/wiki/releases/download/v{0}/node_modules.tar.gz', '{0}', versionGet)
return new Promise((resolve, reject) => {
// Fetch app tarball
ora.text = 'Looking for app package...'
https.get(remoteURLApp, resp => {
if (resp.statusCode !== 200) {
return reject(new Error('Remote file not found'))
}
ora.text = 'Remote app tarball found. Downloading...'
isContainerBased && console.info('>> Extracting app to ' + installDir)
// Extract app tarball console.info(`Executing installation script for ${process.platform} platform...`)
resp.pipe(zlib.createGunzip())
.pipe(tar.extract({ cwd: installDir }))
.on('error', err => reject(err))
.on('end', () => {
ora.text = 'App tarball extracted successfully.'
resolve(true)
})
})
}).then(() => {
return new Promise((resolve, reject) => {
// Fetch deps tarball
ora.text = 'Looking for dependencies package...'
https.get(remoteURLDeps, resp => {
if (resp.statusCode !== 200) {
return reject(new Error('Remote file not found'))
}
ora.text = 'Remote dependencies tarball found. Downloading...'
isContainerBased && console.info('>> Extracting dependencies to ' + installDir)
// Extract deps tarball let inst = spawn(cmd, [], {
resp.pipe(zlib.createGunzip()) cwd: installDir,
.pipe(tar.extract({ cwd: path.join(installDir, 'node_modules') })) env: process.env,
.on('error', err => reject(err)) shell: true,
.on('end', () => { stdio: 'inherit',
ora.text = 'Dependencies tarball extracted successfully.' detached: true
resolve(true)
})
})
}) })
})
})
},
/**
* Create default config.yml file if new installation
*/
ensureConfigFile() {
return fs.accessAsync(path.join(installDir, 'config.yml')).then(() => {
// Is Upgrade
ora.text = 'Existing config.yml found. Upgrade mode.'
installMode = 'upgrade'
return true
}).catch(err => {
// Is New Install
if (err.code === 'ENOENT') {
ora.text = 'First-time install, creating a new config.yml...'
installMode = 'new'
let sourceConfigFile = path.join(installDir, 'config.sample.yml')
if (process.env.WIKI_JS_HEROKU || process.env.WIKI_JS_DOCKER) {
sourceConfigFile = path.join(__dirname, 'configs/config.passive.yml')
}
return fs.copyAsync(sourceConfigFile, path.join(installDir, 'config.yml'))
} else {
return err
}
})
},
/**
* Install npm dependencies
*/
installDependencies() {
ora.text = 'Installing Wiki.js npm dependencies...'
return exec.stdout('npm', ['install', '--only=production', '--no-optional'], {
cwd: installDir
}).then(results => {
ora.text = 'Wiki.js npm dependencies installed successfully.'
return true
})
},
startConfigurationWizard() {
ora.succeed('Installation succeeded.')
if (process.env.WIKI_JS_HEROKU) {
console.info('> Wiki.js has been installed and is configured to use Heroku configuration.')
return true
} else if (process.env.WIKI_JS_DOCKER) {
console.info('Docker environment detected. Skipping setup wizard auto-start.')
return true
} else if (process.stdout.isTTY) {
if (installMode === 'upgrade') {
console.info(colors.yellow('\n!!! IMPORTANT !!!'))
console.info(colors.yellow('Running the configuration wizard is optional but recommended after an upgrade to ensure your config file is using the latest available settings.'))
console.info(colors.yellow('Note that the contents of your config file will be displayed during the configuration wizard. It is therefor highly recommended to run the wizard on a non-publicly accessible port or skip this step completely.\n'))
}
inquirer.prompt([{
type: 'list',
name: 'action',
message: 'Continue with configuration wizard?',
default: 'default',
choices: [
{ name: 'Yes, run configuration wizard on port 3000 (recommended)', value: 'default', short: 'Yes' },
{ name: 'Yes, run configuration wizard on a custom port...', value: 'custom', short: 'Yes' },
{ name: 'No, I\'ll configure the config file manually', value: 'exit', short: 'No' }
]
}, {
type: 'input',
name: 'customport',
message: 'Custom port to use:',
default: 3000,
validate: (val) => {
val = _.toNumber(val)
return (_.isNumber(val) && val > 0) ? true : 'Invalid Port!'
},
when: (ans) => {
return ans.action === 'custom'
}
}]).then((ans) => {
switch (ans.action) {
case 'default':
console.info(colors.bold.cyan('> Browse to http://your-server:3000/ to configure your wiki! (Replaced your-server with the hostname or IP of your server!)'))
ora = require('ora')({ text: 'I\'ll wait until you\'re done ;)', color: 'yellow', spinner: 'pong' }).start()
return exec.stdout('node', ['wiki', 'configure'], {
cwd: installDir
})
case 'custom':
console.info(colors.bold.cyan('> Browse to http://your-server:' + ans.customport + '/ to configure your wiki! (Replaced your-server with the hostname or IP of your server!)'))
ora = require('ora')({ text: 'I\'ll wait until you\'re done ;)', color: 'yellow', spinner: 'pong' }).start()
return exec.stdout('node', ['wiki', 'configure', ans.customport], {
cwd: installDir
})
default:
console.info(colors.bold.cyan('\n> You can run the configuration wizard using command:') + colors.bold.white(' node wiki configure') + colors.bold.cyan('.\n> Then start Wiki.js using command: ') + colors.bold.white('node wiki start'))
return Promise.delay(7000).then(() => {
process.exit(0)
})
}
}).then(() => {
ora.succeed(colors.bold.green('Wiki.js has been configured successfully. It is now starting up and should be accessible very soon!'))
return Promise.delay(3000).then(() => {
console.info('npm is finishing... please wait...')
})
})
} else {
console.info(colors.cyan('[WARNING] Non-interactive terminal detected. You must manually start the configuration wizard using the command: node wiki configure'))
}
}
}
// =====================================================
// INSTALL SEQUENCE
// =====================================================
if (!isContainerBased) { inst.unref()
console.info(colors.yellow(
' __ __ _ _ _ _ \n' +
'/ / /\\ \\ (_) | _(_) (_)___ \n' +
'\\ \\/ \\/ / | |/ / | | / __| \n' +
' \\ /\\ /| | <| |_ | \\__ \\ \n' +
' \\/ \\/ |_|_|\\_\\_(_)/ |___/ \n' +
' |__/\n'))
} else {
console.info('> WIKI.JS [Installing...]')
}
let ora = require('ora')({ text: 'Initializing...', spinner: 'dots12' }).start()
Promise.join(
tasks.stopAndDeleteInstances(),
tasks.checkRequirements()
).then(() => {
isContainerBased && console.info('>> Fetching tarball...')
return tasks.installFromLocal().then(succeeded => {
return (!succeeded) ? tasks.installFromRemote() : true
})
}).then(() => {
isContainerBased && console.info('>> Creating config file...')
return tasks.ensureConfigFile()
}).then(() => {
return tasks.startConfigurationWizard()
}).catch(err => {
isContainerBased && console.error(err)
ora.fail(err)
})

1328
npm/package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
{ {
"name": "wiki.js", "name": "wiki.js",
"version": "1.0.5", "version": "1.0.5-rev.1",
"description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown", "description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown",
"main": "install.js", "main": "install.js",
"scripts": { "scripts": {
@ -28,16 +28,5 @@
"url": "https://github.com/Requarks/wiki/issues" "url": "https://github.com/Requarks/wiki/issues"
}, },
"homepage": "https://github.com/Requarks/wiki#readme", "homepage": "https://github.com/Requarks/wiki#readme",
"dependencies": { "dependencies": {}
"bluebird": "~3.5.0",
"colors": "~1.1.2",
"execa": "~0.7.0",
"follow-redirects": "~1.2.4",
"fs-extra": "~3.0.1",
"inquirer": "~3.1.1",
"lodash": "~4.17.4",
"ora": "~1.3.0",
"pm2": "~2.5.0",
"tar": "~3.1.5"
}
} }

Loading…
Cancel
Save