diff --git a/bin/bin/buildDebian.sh b/bin/bin/buildDebian.sh new file mode 100755 index 000000000..3ca3d512c --- /dev/null +++ b/bin/bin/buildDebian.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# IMPORTANT +# Protect agaisnt mispelling a var and rm -rf / +set -u +set -e + +SRC=/tmp/etherpad-deb-src +DIST=/tmp/etherpad-deb-dist +SYSROOT=${SRC}/sysroot +DEBIAN=${SRC}/DEBIAN + +rm -rf ${DIST} +mkdir -p ${DIST}/ + +rm -rf ${SRC} +rsync -a bin/deb-src/ ${SRC}/ +mkdir -p ${SYSROOT}/opt/ + +rsync --exclude '.git' -a . ${SYSROOT}/opt/etherpad/ --delete + +find ${SRC}/ -type d -exec chmod 0755 {} \; +find ${SRC}/ -type f -exec chmod go-w {} \; +chown -R root:root ${SRC}/ + +let SIZE=`du -s ${SYSROOT} | sed s'/\s\+.*//'`+8 +pushd ${SYSROOT}/ +tar czf ${DIST}/data.tar.gz [a-z]* +popd +sed s"/SIZE/${SIZE}/" -i ${DEBIAN}/control +pushd ${DEBIAN} +tar czf ${DIST}/control.tar.gz * +popd + +pushd ${DIST}/ +echo 2.0 > ./debian-binary + +find ${DIST}/ -type d -exec chmod 0755 {} \; +find ${DIST}/ -type f -exec chmod go-w {} \; +chown -R root:root ${DIST}/ +ar r ${DIST}/etherpad-1.deb debian-binary control.tar.gz data.tar.gz +popd +rsync -a ${DIST}/etherpad-1.deb ./ diff --git a/bin/bin/buildForWindows.sh b/bin/bin/buildForWindows.sh new file mode 100755 index 000000000..a1e2c7570 --- /dev/null +++ b/bin/bin/buildForWindows.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +NODE_VERSION="0.8.4" + +#Move to the folder where ep-lite is installed +cd `dirname $0` + +#Was this script started in the bin folder? if yes move out +if [ -d "../bin" ]; then + cd "../" +fi + +#Is wget installed? +hash wget > /dev/null 2>&1 || { + echo "Please install wget" >&2 + exit 1 +} + +#Is zip installed? +hash zip > /dev/null 2>&1 || { + echo "Please install zip" >&2 + exit 1 +} + +#Is zip installed? +hash unzip > /dev/null 2>&1 || { + echo "Please install unzip" >&2 + exit 1 +} + +START_FOLDER=$(pwd); + +echo "create a clean environment in /tmp/etherpad-lite-win..." +rm -rf /tmp/etherpad-lite-win +cp -ar . /tmp/etherpad-lite-win +cd /tmp/etherpad-lite-win +rm -rf node_modules +rm -f etherpad-lite-win.zip + +echo "do a normal unix install first..." +bin/installDeps.sh || exit 1 + +echo "copy the windows settings template..." +cp settings.json.template settings.json + +echo "resolve symbolic links..." +cp -rL node_modules node_modules_resolved +rm -rf node_modules +mv node_modules_resolved node_modules + +echo "download windows node..." +cd bin +wget "http://nodejs.org/dist/v$NODE_VERSION/node.exe" -O ../node.exe + +echo "remove git history to reduce folder size" +rm -rf .git/objects + +echo "remove windows jsdom-nocontextify/test folder" +rm -rf /tmp/etherpad-lite-win/node_modules/ep_etherpad-lite/node_modules/jsdom-nocontextifiy/test/ +rm -rf /tmp/etherpad-lite-win/src/node_modules/jsdom-nocontextifiy/test/ + +echo "create the zip..." +cd /tmp +zip -9 -r etherpad-lite-win.zip etherpad-lite-win +mv etherpad-lite-win.zip $START_FOLDER + +echo "clean up..." +rm -rf /tmp/etherpad-lite-win + +echo "Finished. You can find the zip in the Etherpad root folder, it's called etherpad-lite-win.zip" diff --git a/bin/bin/checkPad.js b/bin/bin/checkPad.js new file mode 100644 index 000000000..a9b7e8bce --- /dev/null +++ b/bin/bin/checkPad.js @@ -0,0 +1,141 @@ +/* + This is a debug tool. It checks all revisions for data corruption +*/ + +if(process.argv.length != 3) +{ + console.error("Use: node bin/checkPad.js $PADID"); + process.exit(1); +} +//get the padID +var padId = process.argv[2]; + +//initalize the variables +var db, settings, padManager; +var npm = require("../src/node_modules/npm"); +var async = require("../src/node_modules/async"); + +var Changeset = require("ep_etherpad-lite/static/js/Changeset"); + +async.series([ + //load npm + function(callback) { + npm.load({}, function(er) { + callback(er); + }) + }, + //load modules + function(callback) { + settings = require('../src/node/utils/Settings'); + db = require('../src/node/db/DB'); + + //intallize the database + db.init(callback); + }, + //get the pad + function (callback) + { + padManager = require('../src/node/db/PadManager'); + + padManager.doesPadExists(padId, function(err, exists) + { + if(!exists) + { + console.error("Pad does not exist"); + process.exit(1); + } + + padManager.getPad(padId, function(err, _pad) + { + pad = _pad; + callback(err); + }); + }); + }, + function (callback) + { + //create an array with key kevisions + //key revisions always save the full pad atext + var head = pad.getHeadRevisionNumber(); + var keyRevisions = []; + for(var i=0;i +Description: Etherpad is a collaborative editor. diff --git a/bin/bin/deb-src/DEBIAN/postinst b/bin/bin/deb-src/DEBIAN/postinst new file mode 100755 index 000000000..fbc196aed --- /dev/null +++ b/bin/bin/deb-src/DEBIAN/postinst @@ -0,0 +1,6 @@ +#!/bin/bash +# Start the services! + +service etherpad start +echo "Give Etherpad about 3 minutes to install dependencies and start" +rm -f /tmp/etherpad.log /tmp/etherpad.err diff --git a/bin/bin/deb-src/DEBIAN/preinst b/bin/bin/deb-src/DEBIAN/preinst new file mode 100755 index 000000000..e5b5e0b74 --- /dev/null +++ b/bin/bin/deb-src/DEBIAN/preinst @@ -0,0 +1,26 @@ +#!/bin/bash + +# Installs node if it isn't already installed +# +# Don't steamroll over a previously installed node version +# TODO provide a local version of node? + +VER="0.10.4" +ARCH="x86" +if [ `arch | grep 64` ] +then + ARCH="x64" +fi + +# TODO test version +if [ ! -f /usr/local/bin/node ] +then + pushd /tmp + wget -c "http://nodejs.org/dist/v${VER}/node-v${VER}-linux-${ARCH}.tar.gz" + rm -rf /tmp/node-v${VER}-linux-${ARCH} + tar xf node-v${VER}-linux-${ARCH}.tar.gz -C /tmp/ + cp -a /tmp/node-v${VER}-linux-${ARCH}/* /usr/local/ +fi + +# Create Etherpad user +adduser --system etherpad diff --git a/bin/bin/deb-src/DEBIAN/prerm b/bin/bin/deb-src/DEBIAN/prerm new file mode 100755 index 000000000..5e3d0f8a0 --- /dev/null +++ b/bin/bin/deb-src/DEBIAN/prerm @@ -0,0 +1,4 @@ +#!/bin/bash + +# Stop the appserver: +service etherpad stop || true diff --git a/bin/bin/deb-src/sysroot/etc/init/etherpad.conf b/bin/bin/deb-src/sysroot/etc/init/etherpad.conf new file mode 100644 index 000000000..05444ce7b --- /dev/null +++ b/bin/bin/deb-src/sysroot/etc/init/etherpad.conf @@ -0,0 +1,26 @@ +description "etherpad" + +start on started networking +stop on runlevel [!2345] + +env EPHOME=/opt/etherpad +env EPLOGS=/var/log/etherpad +env EPUSER=etherpad + +respawn + +pre-start script + cd $EPHOME + mkdir $EPLOGS ||true + chown $EPUSER:admin $EPLOGS ||true + chmod 0755 $EPLOGS ||true + chown -R $EPUSER:admin $EPHOME/var ||true + $EPHOME/bin/installDeps.sh >> $EPLOGS/error.log || { stop; exit 1; } +end script + +script + cd $EPHOME/ + exec su -s /bin/sh -c 'exec "$0" "$@"' $EPUSER -- node node_modules/ep_etherpad-lite/node/server.js \ + >> $EPLOGS/access.log \ + 2>> $EPLOGS/error.log +end script diff --git a/bin/bin/deb-src/sysroot/usr/share/doc/etherpad/README.md b/bin/bin/deb-src/sysroot/usr/share/doc/etherpad/README.md new file mode 100644 index 000000000..c1acf4618 --- /dev/null +++ b/bin/bin/deb-src/sysroot/usr/share/doc/etherpad/README.md @@ -0,0 +1,115 @@ +# A really-real time collaborative word processor for the web +![alt text](http://i.imgur.com/zYrGkg3.gif "Etherpad in action on PrimaryPad") + +# About +Etherpad is a really-real time collaborative editor maintained by the Etherpad Community. + +Etherpad is written in Javascript(99.9%) on both the server and client so it's easy for developers to maintain and add new features. Because of this Etherpad has tons of customizations that you can leverage. + +Etherpad is designed to be easily embeddable and provides a [HTTP API](https://github.com/ether/etherpad-lite/wiki/HTTP-API) +that allows your web application to manage pads, users and groups. It is recommended to use the [available client implementations](https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries) in order to interact with this API. + +There is also a [jQuery plugin](https://github.com/ether/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website. + +There's also a full-featured plugin framework, allowing you to easily add your own features. By default your Etherpad is rather sparce and because Etherpad takes a lot of it's inspiration from Wordpress plugins are really easy to install and update. Once you have Etherpad installed you should visit the plugin page and take control. + +Finally, Etherpad comes with translations into most languages! Users are automatically delivered the correct language for their local settings. + + +**Visit [beta.etherpad.org](http://beta.etherpad.org) to test it live.** + +Also, check out the **[FAQ](https://github.com/ether/etherpad-lite/wiki/FAQ)**, really! + +# Installation + +Etherpad works with node v0.8 and v0.10, only. (We don't support v0.6) + +## Windows + +### Prebuilt windows package +This package works out of the box on any windows machine, but it's not very useful for developing purposes... + +1. [Download the latest windows package](http://etherpad.org/#download) +2. Extract the folder + +Now, run `start.bat` and open in your browser. You like it? [Next steps](#next-steps). + +### Fancy install +You'll need [node.js](http://nodejs.org) and (optionally, though recommended) git. + +1. Grab the source, either + - download + - or `git clone https://github.com/ether/etherpad-lite.git` (for this you need git, obviously) +2. start `bin\installOnWindows.bat` + +Now, run `start.bat` and open in your browser. + +Update to the latest version with `git pull origin`, then run `bin\installOnWindows.bat`, again. + +[Next steps](#next-steps). + +## GNU/Linux and other UNIX-like systems +You'll need gzip, git, curl, libssl develop libraries, python and gcc. +*For Debian/Ubuntu*: `apt-get install gzip git-core curl python libssl-dev pkg-config build-essential` +*For Fedora/CentOS*: `yum install gzip git-core curl python openssl-devel && yum groupinstall "Development Tools"` +*For FreeBSD*: `portinstall node, npm, git (optional)` + +Additionally, you'll need [node.js](http://nodejs.org) installed, Ideally the latest stable version, be careful of installing nodejs from apt. + +**As any user (we recommend creating a separate user called etherpad):** + +1. Move to a folder where you want to install Etherpad. Clone the git repository `git clone git://github.com/ether/etherpad-lite.git` +2. Change into the new directory containing the cloned source code `cd etherpad-lite` + +Now, run `bin/run.sh` and open in your browser. + +Update to the latest version with `git pull origin`. The next start with bin/run.sh will update the dependencies. + +You like it? [Next steps](#next-steps). + +# Next Steps + +## Tweak the settings +You can initially modify the settings in `settings.json`. (If you need to handle multiple settings files, you can pass the path to a settings file to `bin/run.sh` using the `-s|--settings` option. This allows you to run multiple Etherpad instances from the same installation.) Once you have access to your /admin section settings can be modified through the web browser. + +You should use a dedicated database such as "mysql", if you are planning on using etherpad-in a production environment, since the "dirtyDB" database driver is only for testing and/or development purposes. + +## Helpful resources +The [wiki](https://github.com/ether/etherpad-lite/wiki) is your one-stop resource for Tutorials and How-to's, really check it out! Also, feel free to improve these wiki pages. + +Documentation can be found in `docs/`. + +# Development + +## Things you should know +Read this [git guide](http://learn.github.com/p/index.html) and watch this [video on getting started with Etherpad Development](http://youtu.be/67-Q26YH97E). + +If you're new to node.js, start with Ryan Dahl's [Introduction to Node.js](http://youtu.be/jo_B4LTHi3I). + +You can debug Etherpad using `bin/debugRun.sh`. + +If you want to find out how Etherpad's `Easysync` works (the library that makes it really realtime), start with this [PDF](https://github.com/ether/etherpad-lite/raw/master/doc/easysync/easysync-full-description.pdf) (complex, but worth reading). + +## Getting started +You know all this and just want to know how you can help? + +Look at the [TODO list](https://github.com/ether/etherpad-lite/wiki/TODO) and our [Issue tracker](https://github.com/ether/etherpad-lite/issues). (Please consider using [jshint](http://www.jshint.com/about/), if you plan to contribute code.) + +Also, and most importantly, read our [**Developer Guidelines**](https://github.com/ether/etherpad-lite/blob/master/CONTRIBUTING.md), really! + +# Get in touch +Join the [mailinglist](http://groups.google.com/group/etherpad-lite-dev) and make some noise on our busy freenode irc channel [#etherpad-lite-dev](http://webchat.freenode.net?channels=#etherpad-lite-dev)! + +# Modules created for this project + +* [ueberDB](https://github.com/Pita/ueberDB) "transforms every database into a object key value store" - manages all database access +* [channels](https://github.com/Pita/channels) "Event channels in node.js" - ensures that ueberDB operations are atomic and in series for each key +* [async-stacktrace](https://github.com/Pita/async-stacktrace) "Improves node.js stacktraces and makes it easier to handle errors" + +# Donate! +* [Flattr] (http://flattr.com/thing/71378/Etherpad-Foundation) +* Paypal - Press the donate button on [etherpad.org](http://etherpad.org) +* [Bitcoin] (https://coinbase.com/checkouts/1e572bf8a82e4663499f7f1f66c2d15a) + +# License +[Apache License v2](http://www.apache.org/licenses/LICENSE-2.0.html) diff --git a/bin/bin/debugRun.sh b/bin/bin/debugRun.sh new file mode 100755 index 000000000..f90009d05 --- /dev/null +++ b/bin/bin/debugRun.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +#Move to the folder where ep-lite is installed +cd `dirname $0` + +#Was this script started in the bin folder? if yes move out +if [ -d "../bin" ]; then + cd "../" +fi + +#prepare the enviroment +bin/installDeps.sh || exit 1 + +hash node-inspector > /dev/null 2>&1 || { + echo "You need to install node-inspector to run the tests!" >&2 + echo "You can install it with npm" >&2 + echo "Run: npm install -g node-inspector" >&2 + exit 1 +} + +node-inspector & + +echo "If you are new to node-inspector, take a look at this video: http://youtu.be/AOnK3NVnxL8" + +node --debug node_modules/ep_etherpad-lite/node/server.js $* + +#kill node-inspector before ending +kill $! diff --git a/bin/bin/deletePad.js b/bin/bin/deletePad.js new file mode 100644 index 000000000..f7a6d2038 --- /dev/null +++ b/bin/bin/deletePad.js @@ -0,0 +1,63 @@ +/* + A tool for deleting pads from the CLI, because sometimes a brick is required to fix a window. +*/ + +if(process.argv.length != 3) +{ + console.error("Use: node deletePad.js $PADID"); + process.exit(1); +} +//get the padID +var padId = process.argv[2]; + +var db, padManager, pad, settings; +var neededDBValues = ["pad:"+padId]; + +var npm = require("../src/node_modules/npm"); +var async = require("../src/node_modules/async"); + +async.series([ + // load npm + function(callback) { + npm.load({}, function(er) { + if(er) + { + console.error("Could not load NPM: " + er) + process.exit(1); + } + else + { + callback(); + } + }) + }, + // load modules + function(callback) { + settings = require('../src/node/utils/Settings'); + db = require('../src/node/db/DB'); + callback(); + }, + // intallize the database + function (callback) + { + db.init(callback); + }, + // delete the pad and it's links + function (callback) + { + padManager = require('../src/node/db/PadManager'); + + padManager.removePad(padId, function(err){ + callback(err); + }); + callback(); + } +], function (err) +{ + if(err) throw err; + else + { + console.log("Finished deleting padId: "+padId); + process.exit(); + } +}); diff --git a/bin/bin/extractPadData.js b/bin/bin/extractPadData.js new file mode 100644 index 000000000..e3678c4e0 --- /dev/null +++ b/bin/bin/extractPadData.js @@ -0,0 +1,109 @@ +/* + This is a debug tool. It helps to extract all datas of a pad and move it from an productive enviroment and to a develop enviroment to reproduce bugs there. It outputs a dirtydb file +*/ + +if(process.argv.length != 3) +{ + console.error("Use: node extractPadData.js $PADID"); + process.exit(1); +} +//get the padID +var padId = process.argv[2]; + +var db, dirty, padManager, pad, settings; +var neededDBValues = ["pad:"+padId]; + +var npm = require("../node_modules/ep_etherpad-lite/node_modules/npm"); +var async = require("../node_modules/ep_etherpad-lite/node_modules/async"); + +async.series([ + // load npm + function(callback) { + npm.load({}, function(er) { + if(er) + { + console.error("Could not load NPM: " + er) + process.exit(1); + } + else + { + callback(); + } + }) + }, + // load modules + function(callback) { + settings = require('../node_modules/ep_etherpad-lite/node/utils/Settings'); + db = require('../node_modules/ep_etherpad-lite/node/db/DB'); + dirty = require("../node_modules/ep_etherpad-lite/node_modules/ueberDB/node_modules/dirty")(padId + ".db"); + callback(); + }, + //intallize the database + function (callback) + { + db.init(callback); + }, + //get the pad + function (callback) + { + padManager = require('../node_modules/ep_etherpad-lite/node/db/PadManager'); + + padManager.getPad(padId, function(err, _pad) + { + pad = _pad; + callback(err); + }); + }, + function (callback) + { + //add all authors + var authors = pad.getAllAuthors(); + for(var i=0;i /dev/null 2>&1 || { + echo "Please install ggrep (pkg install gnu-grep)" >&2 + exit 1 + } +fi + +#Is curl installed? +hash curl > /dev/null 2>&1 || { + echo "Please install curl" >&2 + exit 1 +} + +#Is node installed? +hash node > /dev/null 2>&1 || { + echo "Please install node.js ( http://nodejs.org )" >&2 + exit 1 +} + +#Is npm installed? +hash npm > /dev/null 2>&1 || { + echo "Please install npm ( http://npmjs.org )" >&2 + exit 1 +} + +#check npm version +NPM_VERSION=$(npm --version) +if [ ! $(echo $NPM_VERSION | cut -d "." -f 1) = "1" ]; then + echo "You're running a wrong version of npm, you're using $NPM_VERSION, we need 1.x" >&2 + exit 1 +fi + +#check node version +NODE_VERSION=$(node --version) +NODE_V_MINOR=$(echo $NODE_VERSION | cut -d "." -f 1-2) +if [ ! $NODE_V_MINOR = "v0.8" ] && [ ! $NODE_V_MINOR = "v0.10" ] && [ ! $NODE_V_MINOR = "v0.11" ]; then + echo "You're running a wrong version of node, you're using $NODE_VERSION, we need v0.8.x, v0.10.x or v0.11.x" >&2 + exit 1 +fi + +#Get the name of the settings file +settings="settings.json" +a=''; +for arg in $*; do + if [ "$a" = "--settings" ] || [ "$a" = "-s" ]; then settings=$arg; fi + a=$arg +done + +#Does a $settings exist? if no copy the template +if [ ! -f $settings ]; then + echo "Copy the settings template to $settings..." + cp settings.json.template $settings || exit 1 +fi + +echo "Ensure that all dependencies are up to date... If this is the first time you have run Etherpad please be patient." +( + mkdir -p node_modules + cd node_modules + [ -e ep_etherpad-lite ] || ln -s ../src ep_etherpad-lite + cd ep_etherpad-lite + npm install --loglevel warn +) || { + rm -rf node_modules + exit 1 +} + +echo "Ensure jQuery is downloaded and up to date..." +DOWNLOAD_JQUERY="true" +NEEDED_VERSION="1.9.1" +if [ -f "src/static/js/jquery.js" ]; then + if [ $(uname) = "SunOS" ]; then + VERSION=$(cat src/static/js/jquery.js | head -n 3 | ggrep -o "v[0-9]\.[0-9]\(\.[0-9]\)\?"); + else + VERSION=$(cat src/static/js/jquery.js | head -n 3 | grep -o "v[0-9]\.[0-9]\(\.[0-9]\)\?"); + fi + + if [ ${VERSION#v} = $NEEDED_VERSION ]; then + DOWNLOAD_JQUERY="false" + fi +fi + +if [ $DOWNLOAD_JQUERY = "true" ]; then + curl -lo src/static/js/jquery.js http://code.jquery.com/jquery-$NEEDED_VERSION.js || exit 1 +fi + +#Remove all minified data to force node creating it new +echo "Clear minfified cache..." +rm -f var/minified* + +echo "ensure custom css/js files are created..." + +for f in "index" "pad" "timeslider" +do + if [ ! -f "src/static/custom/$f.js" ]; then + cp "src/static/custom/js.template" "src/static/custom/$f.js" || exit 1 + fi + + if [ ! -f "src/static/custom/$f.css" ]; then + cp "src/static/custom/css.template" "src/static/custom/$f.css" || exit 1 + fi +done + +exit 0 diff --git a/bin/bin/installOnWindows.bat b/bin/bin/installOnWindows.bat new file mode 100644 index 000000000..862230641 --- /dev/null +++ b/bin/bin/installOnWindows.bat @@ -0,0 +1,39 @@ +@echo off + +:: change directory to etherpad-lite root +cd /D "%~dp0\.." + +:: Is node installed? +cmd /C node -e "" || ( echo "Please install node.js ( http://nodejs.org )" && exit /B 1 ) + +echo _ +echo Checking node version... +set check_version="if(['8','10'].indexOf(process.version.split('.')[1].toString()) === -1) { console.log('You are running a wrong version of Node. Etherpad requires v0.8.x or v0.10.x'); process.exit(1) }" +cmd /C node -e %check_version% || exit /B 1 + +echo _ +echo Ensure that all dependencies are up to date... If this is the first time you have run Etherpad please be patient. +cmd /C npm install src/ --loglevel warn || exit /B 1 + +echo _ +echo Copying custom templates... +set custom_dir=node_modules\ep_etherpad-lite\static\custom +FOR %%f IN (index pad timeslider) DO ( + if NOT EXIST "%custom_dir%\%%f.js" copy "%custom_dir%\js.template" "%custom_dir%\%%f.js" + if NOT EXIST "%custom_dir%\%%f.css" copy "%custom_dir%\css.template" "%custom_dir%\%%f.css" +) + +echo _ +echo Clearing cache... +del /S var\minified* + +echo _ +echo Setting up settings.json... +IF NOT EXIST settings.json ( + echo Can't find settings.json. + echo Copying settings.json.template... + cmd /C copy settings.json.template settings.json || exit /B 1 +) + +echo _ +echo Installed Etherpad! To run Etherpad type start.bat diff --git a/bin/bin/jshint.sh b/bin/bin/jshint.sh new file mode 100755 index 000000000..4dea73961 --- /dev/null +++ b/bin/bin/jshint.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +if [ -d "../bin" ]; then + cd "../" +fi + +JSHINT=./node_modules/jshint/bin/hint + +$JSHINT ./node/ diff --git a/bin/bin/loadTesting/README b/bin/bin/loadTesting/README new file mode 100644 index 000000000..2252b66c6 --- /dev/null +++ b/bin/bin/loadTesting/README @@ -0,0 +1,79 @@ +This is the new load testing file: https://bitbucket.org/rbraakman/etherpad-stresstest + +BELOW is the original load testing file. + +This load tester is extremely useful for testing how many dormant clients can connect to etherpad. + +TODO: +Emulate characters being typed into a pad + +HOW TO USE (from @mjd75) proper formatting at: https://github.com/ether/etherpad-lite/issues/360 + +Server 1: +Installed Node.js (etc), EtherPad and MySQL + +Server 2: +Installed Xvfb and PhantomJS + +I installed Xvfb following (roughly) this guide: http://blog.martin-lyness.com/archives/installing-xvfb-on-ubuntu-9-10-karmic-koala + + #sudo apt-get install xvfb + #sudo apt-get install xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic + +Launched two instances of Xvfb directly from the terminal: + + #Xvfb :0 -ac + #Xvfb :1 -ac + +I installed PhantomJS following this guide: http://code.google.com/p/phantomjs/wiki/Installation + + #sudo add-apt-repository ppa:jerome-etienne/neoip + #sudo apt-get update + #sudo apt-get install phantomjs + +I created a small JavaScript file for PhatomJS to use to control the browser instances: + +### BEGIN JAVASCRIPT ### + +var page = new WebPage(), + t, address; + +if (phantom.args.length === 0) { + console.log('Usage: loader.js '); + phantom.exit(); +} else { + t = Date.now(); + address = phantom.args[0]; + + var page = new WebPage(); + page.onResourceRequested = function (request) { + console.log('Request ' + JSON.stringify(request, undefined, 4)); + }; + page.onResourceReceived = function (response) { + console.log('Receive ' + JSON.stringify(response, undefined, 4)); + }; + page.open(address); + +} + +### END JAVASCRIPT ### + +And finally a launcher script that uses screen to run 400 instances of PhantomJS with the above script: + +### BEGIN SHELL SCRIPT ### + +#!/bin/bash + +# connect 200 instances to display :0 +for i in {1..200} +do + DISPLAY=:0 screen -d -m phantomjs loader.js http://ec2-50-17-168-xx.compute-1.amazonaws.com:9001/p/pad2 && sleep 2 +done + +# connect 200 instances to display :1 +for i in {1..200} +do + DISPLAY=:1 screen -d -m phantomjs loader.js http://ec2-50-17-168-xx.compute-1.amazonaws.com:9001/p/pad2 && sleep 2 +done + +### END SHELL SCRIPT ### diff --git a/bin/bin/loadTesting/launcher.sh b/bin/bin/loadTesting/launcher.sh new file mode 100755 index 000000000..375b15444 --- /dev/null +++ b/bin/bin/loadTesting/launcher.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# connect 500 instances to display :0 +for i in {1..500} +do + echo $i + echo "Displaying Some shit" + DISPLAY=:0 screen -d -m /home/phantomjs/bin/phantomjs loader.js http://10.0.0.55:9001/p/pad2 && sleep 2 +done + +# connect 500 instances to display :1 +for i in {1..500} +do + echo $i + DISPLAY=:1 screen -d -m /home/phantomjs/bin/phantomjs loader.js http://10.0.0.55:9001/p/pad2 && sleep 2 +done diff --git a/bin/bin/loadTesting/loader.js b/bin/bin/loadTesting/loader.js new file mode 100644 index 000000000..ddcd0572d --- /dev/null +++ b/bin/bin/loadTesting/loader.js @@ -0,0 +1,20 @@ +var page = new WebPage(), + t, address; + +if (phantom.args.length === 0) { + console.log('Usage: loader.js '); + phantom.exit(); +} else { + t = Date.now(); + address = phantom.args[0]; + + var page = new WebPage(); + page.onResourceRequested = function (request) { + console.log('Request ' + JSON.stringify(request, undefined, 4)); + }; + page.onResourceReceived = function (response) { + console.log('Receive ' + JSON.stringify(response, undefined, 4)); + }; + page.open(address); + +} diff --git a/bin/bin/migrateDirtyDBtoMySQL.js b/bin/bin/migrateDirtyDBtoMySQL.js new file mode 100644 index 000000000..b4913e762 --- /dev/null +++ b/bin/bin/migrateDirtyDBtoMySQL.js @@ -0,0 +1,18 @@ +require("ep_etherpad-lite/node_modules/npm").load({}, function(er,npm) { + + process.chdir(npm.root+'/..') + + var settings = require("ep_etherpad-lite/node/utils/Settings"); + var dirty = require("ep_etherpad-lite/node_modules/ueberDB/node_modules/dirty")('var/dirty.db'); + var db = require("ep_etherpad-lite/node/db/DB"); + + db.init(function() { + db = db.db; + dirty.on("load", function() { + dirty.forEach(function(key, value) { + db.set(key, value); + }); + }); + }); + +}); diff --git a/bin/bin/run.sh b/bin/bin/run.sh new file mode 100755 index 000000000..92ae8d482 --- /dev/null +++ b/bin/bin/run.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +#Move to the folder where ep-lite is installed +cd `dirname $0` + +#Was this script started in the bin folder? if yes move out +if [ -d "../bin" ]; then + cd "../" +fi + +ignoreRoot=0 +for ARG in $* +do + if [ "$ARG" = "--root" ]; then + ignoreRoot=1 + fi +done + +#Stop the script if its started as root +if [ "$(id -u)" -eq 0 ] && [ $ignoreRoot -eq 0 ]; then + echo "You shouldn't start Etherpad as root!" + echo "Please type 'Etherpad rocks my socks' or supply the '--root' argument if you still want to start it as root" + read rocks + if [ ! $rocks = "Etherpad rocks my socks" ] + then + echo "Your input was incorrect" + exit 1 + fi +fi + +#prepare the enviroment +bin/installDeps.sh $* || exit 1 + +#Move to the node folder and start +echo "start..." + +SCRIPTPATH=`pwd -P` +node $SCRIPTPATH/node_modules/ep_etherpad-lite/node/server.js $* + diff --git a/bin/bin/safeRun.sh b/bin/bin/safeRun.sh new file mode 100755 index 000000000..4b3485ba4 --- /dev/null +++ b/bin/bin/safeRun.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +#This script ensures that ep-lite is automatically restarting after an error happens + +#Handling Errors +# 0 silent +# 1 email +ERROR_HANDLING=0 +# Your email address which should recieve the error messages +EMAIL_ADDRESS="no-reply@example.com" +# Sets the minimun amount of time betweens the sending of error emails. +# This ensures you not get spamed while a endless reboot loop +# It's the time in seconds +TIME_BETWEEN_EMAILS=600 # 10 minutes + +# DON'T EDIT AFTER THIS LINE + +LAST_EMAIL_SEND=0 +LOG="$1" + +#Move to the folder where ep-lite is installed +cd `dirname $0` + +#Was this script started in the bin folder? if yes move out +if [ -d "../bin" ]; then + cd "../" +fi + +#check if a logfile parameter is set +if [ -z "${LOG}" ]; then + echo "Set a logfile as the first parameter" + exit 1 +fi + +shift +while [ 1 ] +do + #try to touch the file if it doesn't exist + if [ ! -f ${LOG} ]; then + touch ${LOG} || ( echo "Logfile '${LOG}' is not writeable" && exit 1 ) + fi + + #check if the file is writeable + if [ ! -w ${LOG} ]; then + echo "Logfile '${LOG}' is not writeable" + exit 1 + fi + + #start the application + bin/run.sh $@ >>${LOG} 2>>${LOG} + + #Send email + if [ $ERROR_HANDLING = 1 ]; then + TIME_NOW=$(date +%s) + TIME_SINCE_LAST_SEND=$(($TIME_NOW - $LAST_EMAIL_SEND)) + + if [ $TIME_SINCE_LAST_SEND -gt $TIME_BETWEEN_EMAILS ]; then + printf "Server was restared at: $(date)\nThe last 50 lines of the log before the error happens:\n $(tail -n 50 ${LOG})" | mail -s "Pad Server was restarted" $EMAIL_ADDRESS + + LAST_EMAIL_SEND=$TIME_NOW + fi + fi + + echo "RESTART!" >>${LOG} + + #Sleep 10 seconds before restart + sleep 10 +done diff --git a/bin/buildDebian.sh b/bin/buildDebian.sh index 507a60a44..3ca3d512c 100755 --- a/bin/buildDebian.sh +++ b/bin/buildDebian.sh @@ -14,10 +14,10 @@ rm -rf ${DIST} mkdir -p ${DIST}/ rm -rf ${SRC} -rsync -a deb-src/ ${SRC}/ +rsync -a bin/deb-src/ ${SRC}/ mkdir -p ${SYSROOT}/opt/ -rsync --exclude '.git' -a ../ ${SYSROOT}/opt/etherpad/ --delete +rsync --exclude '.git' -a . ${SYSROOT}/opt/etherpad/ --delete find ${SRC}/ -type d -exec chmod 0755 {} \; find ${SRC}/ -type f -exec chmod go-w {} \; diff --git a/bin/deb-src/DEBIAN/postinst b/bin/deb-src/DEBIAN/postinst index fbc196aed..2f483f7e2 100755 --- a/bin/deb-src/DEBIAN/postinst +++ b/bin/deb-src/DEBIAN/postinst @@ -2,5 +2,6 @@ # Start the services! service etherpad start -echo "Give Etherpad about 3 minutes to install dependencies and start" +echo "Give Etherpad about 3 minutes to install dependencies then visit http://localhost:9001 in your web browser" +echo "To stop etherpad type 'service etherpad stop', To restart type 'service etherpad restart'". rm -f /tmp/etherpad.log /tmp/etherpad.err diff --git a/bin/deb-src/sysroot/etc/init/etherpad.conf b/bin/deb-src/sysroot/etc/init/etherpad.conf index 7292bd930..7fb6e37c7 100644 --- a/bin/deb-src/sysroot/etc/init/etherpad.conf +++ b/bin/deb-src/sysroot/etc/init/etherpad.conf @@ -20,7 +20,9 @@ end script script cd $EPHOME/ - exec su -s /bin/sh -c 'exec "$0" "$@"' $EPUSER -- node node_modules/ep_etherpad/node/server.js \ + exec su -s /bin/sh -c 'exec "$0" "$@"' $EPUSER -- node node_modules/ep_etherpad-lite/node/server.js \ >> $EPLOGS/access.log \ 2>> $EPLOGS/error.log + echo "Etherpad is running on http://localhost:9001 - To change settings edit /opt/etherpad/settings.json" + end script