Last active
August 18, 2017 12:41
-
-
Save rjmoggach/1d038a31e5d998bbcf37 to your computer and use it in GitHub Desktop.
Webfaction MongoDB/Meteor Install
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python2.7 | |
import xmlrpclib | |
import os | |
import socket | |
import wget | |
import getpass | |
from subprocess import call | |
# Set some defaults | |
MONGO_VERSION="mongodb-linux-x86_64-2.4.12" | |
NODE_VERSION="0.10.33" # "wget http://nodejs.org/dist/v0.10.33/node-v0.10.33-linux-x64.tar.gz" | |
NODE_DIR="node-v%s"%NODE_VERSION | |
SERVER_IP_ADDRESS=socket.gethostbyname(socket.gethostname()) | |
SERVER_HOSTNAME=socket.gethostname().split('.')[0].capitalize() | |
USERNAME=getpass.getuser() | |
# This is the install specific docs for node and meteor that get returned to the user | |
# during the install process - easier than trying to automate for now | |
BUILD_NODE_INFO=''' | |
Open another ssh session and build/install node.js in the {app_dir} app as follows: | |
# this is slow so better to do it in a separate shell | |
cd $HOME/webapps/{app_dir}/{node_dir} | |
./configure --prefix=$HOME | |
make | |
make install | |
npm install -g forever demeteorizer | |
Then you have to get the latest meteor installed because the npm bundled one is old. | |
You also need to tweak the script a bit to change the PREFIX to $HOME. | |
cd $HOME/webapps/{app_dir} | |
wget https://install.meteor.com -O install_meteor.sh | |
sed -i 's/^PREFIX=.*$/PREFIX=$HOME/g' install_meteor.sh | |
./install_meteor.sh | |
meteor create {app_name} | |
cd {app_name} | |
demeteorizer -o $HOME/webapps/{app_dir}/deploy | |
cd ../deploy | |
npm install | |
\n\nHave you finished buiding/installing Node.js and Meteor?" | |
''' | |
# Template for the mongo startup script - pretty basic and could be better | |
MONGO_SCRIPT=''' | |
#!/bin/bash | |
PIDFILE="$HOME/webapps/{mongo_app}/mongod.pid" | |
if [ -e "${{PIDFILE}}" ] && (ps -u $(whoami) -opid= | grep -P "^\s*$(cat ${{PIDFILE}})$" &> /dev/null); then | |
echo "Already running." | |
exit 99 | |
fi | |
$HOME/webapps/{mongo_app}/{mongo_version}/bin/mongod --auth --dbpath $HOME/webapps/{mongo_app}/data/ --port {mongo_port} > $HOME/webapps/{mongo_app}/mongod.log & | |
echo $! > "${{PIDFILE}}" | |
chmod 644 "${{PIDFILE}}" | |
echo "Mongo Started." | |
''' | |
# command to create the database admin user/password | |
MONGO_CREATE_USER = "$HOME/webapps/{mongo_app}/{mongo_version}/bin/mongo localhost:{mongo_port}/admin --eval \"db.createUser({{user: '{mongo_user}', pwd: '{mongo_pass}', roles: ['userAdminAnyDatabase']}})\"" | |
# Template for the meteor startup script - pretty basic and could be better | |
METEOR_SCRIPT=''' | |
#!/bin/sh | |
APPPATH="$HOME/webapps/{webfaction_app}" | |
PIDFILE="$APPPATH/meteor.pid" | |
LOGDIR="$APPPATH/logs" | |
MONGO_URL="mongodb://{mongo_user}:{mongo_pass}@localhost:{mongo_port}/{app_name}?autoReconnect=true" | |
PORT={meteor_port} | |
ROOT_URL={meteor_url} | |
forever start --pidfile $APPPATH/meteor.pid -l $APPPATH/meteor.log $APPPATH/deploy/main.js | |
''' | |
# This is the question and answer part of the script... | |
username = raw_input("\nEnter your webfaction username\n username [{username}]: ".format(username=USERNAME) ) or USERNAME | |
password = getpass.getpass("\nEnter your webfaction password\n password: ") | |
app_name = raw_input("\nEnter the app name you want to use\n (This will create 2 apps Eg. 'app_name_mongodb' & 'app_name_meteor'\n app_name: ") | |
app_domain = raw_input("\nEnter the domain name you want to use (or press Enter for none)\n app_domain: ") | |
app_user = raw_input("\nEnter the app admin username or press Enter to use your username\n app_user [{username}]: ".format(username=USERNAME) ) or USERNAME | |
app_pass = getpass.getpass("\nEnter the app admin password or press Enter to use your password\n app_pass: ") or password | |
app_machine = raw_input("\nWhich machine are we putting this one? Case-sensitive!\n app_machine [{hostname}]: ".format(hostname=SERVER_HOSTNAME)) or SERVER_HOSTNAME | |
meteor_apps={} | |
# Setup the API | |
server = xmlrpclib.ServerProxy('https://api.webfaction.com/') | |
try: | |
session_id, account = server.login(username, password, app_machine) | |
except: | |
print 'Your username or password was incorrect.' | |
raise "Authentication Error!" | |
def confirm(prompt_text, default="Y"): | |
# this method is for convenience to make the script interactive | |
question = "\n{prompt}\n Enter Y or N [{default}] : ".format(prompt=prompt_text, default=default) | |
CONFIRM = raw_input(question) or default | |
if CONFIRM in ["Y", "y"]: | |
return True | |
else: | |
return False | |
def get_apps(app_prefix): | |
# the API returns a tuple but I prefer a dict | |
for webapp in server.list_apps(session_id): | |
if webapp['name'].startswith(app_prefix): | |
if webapp['name'].endswith('mongodb'): | |
meteor_apps['mongodb'] = webapp | |
if webapp['name'].endswith('meteor'): | |
meteor_apps['meteor'] = webapp | |
def server_cmd(cmd): | |
# shortcut for running a system command | |
server.system(session_id, cmd) | |
def create_domain(app_domain): | |
# delete the domain if it exists and re-add it | |
domain=app_domain.split('.') | |
if len(domain) < 2: | |
raise "Your domain is invalid!" | |
if len(domain) == 2: | |
server.create_domain(session_id, app_domain) | |
else: | |
tld='.'.join(domain[-2:]) | |
if len(domain) == 3: | |
subdomain = domain[0] | |
if len(domain) > 3: | |
subdomain = '.'.join(domain[:-2]) | |
if confirm("Create %s subdomain for %s tld?" % (subdomain, tld)): | |
server.delete_domain(session_id, tld, subdomain) | |
server.create_domain(session_id, tld, subdomain) | |
create_domain(app_domain) | |
for app_suffix in ['mongodb', 'meteor']: | |
app_fullname = '_'.join([app_name, app_suffix]) | |
print "\nStarting setup of %s app\n----------------------------------------" % app_fullname | |
app_path = os.path.expanduser("~/webapps/{app_name}".format(app_name=app_fullname)) | |
if confirm("Delete and create the %s App?" % app_suffix): | |
try: | |
server.delete_app(session_id, app_fullname) | |
except: | |
pass | |
server.create_app(session_id, app_fullname, 'custom_app_with_port') | |
get_apps(app_name) | |
app_port = meteor_apps[app_suffix]['port'] | |
if app_suffix == 'mongodb': | |
mongo_port = app_port | |
MONGO_SCRIPT = MONGO_SCRIPT.format( | |
mongo_app=app_fullname, | |
mongo_version=MONGO_VERSION, | |
mongo_port=app_port) | |
mongo_script_path = os.path.expanduser('~/webapps/{app_name}/start.sh'.format(app_name=app_fullname)) | |
mongo_script_file=open(mongo_script_path, 'a') | |
mongo_script_file.write(MONGO_SCRIPT) | |
mongo_script_file.close() | |
mongo_create_user = MONGO_CREATE_USER.format( | |
mongo_app=app_fullname, | |
mongo_version=MONGO_VERSION, | |
mongo_port=app_port, | |
mongo_user=app_user, | |
mongo_pass=app_pass) | |
os.chdir(app_path) | |
server_cmd("cd $HOME/webapps/%s" % app_fullname) | |
server_cmd("rm -f index.html") | |
server_cmd("chmod 750 %s" % mongo_script_path) | |
url="http://downloads.mongodb.org/linux/%s.tgz" % MONGO_VERSION | |
print "Downloading %s" % MONGO_VERSION | |
wget.download(url) | |
server_cmd("tar xzvf %s.tgz" % MONGO_VERSION) | |
server_cmd("mkdir data") | |
if confirm("\n\nOpen another ssh session and run the {app_name} start script\n\nHave you started {app_name}?".format(app_name=app_suffix)): | |
if confirm('Create admin user?'): | |
server_cmd(mongo_create_user) | |
if confirm('Create cron jobs for %s?' % app_suffix, 'N'): | |
mongo_cron='8,28,48 * * * * ~/webapps/{app_name}/start.sh > /dev/null 2>&1'.format(app_name=app_fullname) | |
server.delete_cronjob(session_id, mongo_cron) | |
server.create_cronjob(session_id, mongo_cron) | |
print "Created cron job" | |
if app_suffix == 'meteor': | |
meteor_app = app_fullname | |
METEOR_SCRIPT = METEOR_SCRIPT.format( | |
webfaction_app=app_fullname, | |
meteor_app=app_name, | |
mongo_user=app_user, | |
mongo_pass=app_pass, | |
mongo_port=mongo_port, | |
meteor_port=app_port, | |
app_name=app_name, | |
meteor_url="http://{domain}".format(domain=app_domain)) | |
meteor_script_path = os.path.expanduser('~/webapps/{app_name}/start.sh'.format(app_name=app_fullname)) | |
meteor_script_file=open(meteor_script_path, 'a') | |
meteor_script_file.write(METEOR_SCRIPT) | |
meteor_script_file.close() | |
os.chdir(app_path) | |
server_cmd("cd $HOME/webapps/%s" % app_fullname) | |
server_cmd("rm -f index.html") | |
server_cmd("chmod 750 %s" % meteor_script_path) | |
server_cmd("mkdir logs deploy") | |
url="http://nodejs.org/dist/v{node_version}/node-v{node_version}.tar.gz".format(node_version=NODE_VERSION) | |
print "Downloading Node.js" | |
wget.download(url) | |
server_cmd("tar xvzf node-v{node_version}.tar.gz".format(node_version=NODE_VERSION)) | |
if confirm(BUILD_NODE_INFO.format(app_dir=app_fullname, node_dir=NODE_DIR, app_name=app_name)): | |
if confirm("\n\nOpen another ssh session and run the {app_name} start script\n\nHave you started {app_name}?".format(app_name=app_suffix)): | |
if confirm('Create cron jobs for %s?' % app_suffix, 'N'): | |
meteor_cron='8,28,48 * * * * ~/webapps/{app_name}/start.sh start > /dev/null 2>&1'.format(app_name=app_fullname) | |
server.delete_cronjob(session_id, meteor_cron) | |
server.create_cronjob(session_id, meteor_cron) | |
print "Created cron job" | |
if confirm("Connect app to domain?"): | |
if not app_domain is None: | |
server.create_website(session_id, | |
'%s_site' % app_name, | |
SERVER_IP_ADDRESS, | |
False, | |
[app_domain], | |
[meteor_app, '/'] | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment