create-dev-env.sh 13.9 KB
Newer Older
1
#!/usr/bin/env bash
2 3

#Exit if any commands return a non-zero status
John Jarvis committed
4
set -e
5 6 7 8 9 10 11

# posix compliant sanity check
if [ -z $BASH ] || [  $BASH = "/bin/sh" ]; then
    echo "Please use the bash interpreter to run this script"
    exit 1
fi

12
trap "ouch" ERR
John Jarvis committed
13

14 15 16 17
ouch() {
    printf '\E[31m'

    cat<<EOL
18

19 20
    !! ERROR !!

21
    The last command did not complete successfully,
22
    For more details or trying running the
23 24
    script again with the -v flag.

25
    Output of the script is recorded in $LOG
26 27

EOL
28
    printf '\E[0m'
29 30

}
31

32
#Setting error color to red before reset
John Jarvis committed
33
error() {
34
      printf '\E[31m'; echo "$@"; printf '\E[0m'
John Jarvis committed
35
}
36

37 38 39 40 41 42
#Setting warning color to magenta before reset
warning() {
      printf '\E[35m'; echo "$@"; printf '\E[0m'
}

#Setting output color to cyan before reset
John Jarvis committed
43
output() {
44
      printf '\E[36m'; echo "$@"; printf '\E[0m'
John Jarvis committed
45
}
46

John Jarvis committed
47 48 49 50
usage() {
    cat<<EO

    Usage: $PROG [-c] [-v] [-h]
51

52
            -y        non interactive mode (no prompt, proceed immediately)
John Jarvis committed
53
            -c        compile scipy and numpy
54
            -n        do not attempt to pull edx-platform
55
            -s        give access to global site-packages for virtualenv
56
            -q        be more quiet (removes info at beginning & end)
John Jarvis committed
57 58 59 60 61 62 63 64 65
            -v        set -x + spew
            -h        this

EO
    info
}

info() {
    cat<<EO
66
    edX base dir : $BASE
67
    Python virtualenv dir : $PYTHON_DIR
68
    Ruby rbenv dir : $RBENV_ROOT
John Jarvis committed
69 70 71
    Ruby ver : $RUBY_VER

EO
John Jarvis committed
72
}
John Jarvis committed
73

74 75 76 77 78
change_git_push_defaults() {

    #Set git push defaults to upstream rather than master
    output "Changing git defaults"
    git config --global push.default upstream
79

80 81
}

82
clone_repos() {
83

84
    cd "$BASE"
85

86 87 88 89 90 91 92 93 94 95 96 97 98 99
    if [[ ! $nopull ]]; then
        change_git_push_defaults

        if [[ -d "$BASE/edx-platform/.git" ]]; then
            output "Pulling edx platform"
            cd "$BASE/edx-platform"
            git pull
        else
            output "Cloning edx platform"
            if [[ -d "$BASE/edx-platform" ]]; then
                output "Creating backup for existing edx platform"
                mv "$BASE/edx-platform" "${BASE}/edx-platform.bak.$$"
            fi
            git clone https://github.com/edx/edx-platform.git
100 101
        fi
    fi
Slater-Victoroff committed
102
}
John Jarvis committed
103

104 105
set_base_default() {  # if PROJECT_HOME not set
    # 2 possibilities: this is from cloned repo, or not
106 107 108

    # See if remote's url is named edx-platform (this works for forks too, but
    # not if the name was changed).
109
    cd "$( dirname "${BASH_SOURCE[0]}" )"
110 111 112 113 114 115 116
    this_repo=$(basename $(git ls-remote --get-url 2>/dev/null) 2>/dev/null) ||
        echo -n ""

    if [[ "x$this_repo" = "xedx-platform.git" ]]; then
        # We are in the edx repo and already have git installed. Let git do the
        # work of finding base dir:
        echo "$(dirname $(git rev-parse --show-toplevel))"
117 118 119 120 121 122
    else
        echo "$HOME/edx_all"
    fi
}


123 124
### START

John Jarvis committed
125 126
PROG=${0##*/}

127
# Adjust this to wherever you'd like to place the codebase
128
BASE="${PROJECT_HOME:-$(set_base_default)}"
129

130
# Use a sensible default (~/.virtualenvs) for your Python virtualenvs
131
# unless you've already got one set up with virtualenvwrapper.
132
PYTHON_DIR=${WORKON_HOME:-"$HOME/.virtualenvs"}
133

134 135 136 137 138 139 140 141 142 143
# Find rbenv root (~/.rbenv by default)
if [ -z "${RBENV_ROOT}" ]; then
  RBENV_ROOT="${HOME}/.rbenv"
else
  RBENV_ROOT="${RBENV_ROOT%/}"
fi
# Let the repo override the version of Ruby to install
if [[ -r $BASE/edx-platform/.ruby-version ]]; then
  RUBY_VER=`cat $BASE/edx-platform/.ruby-version`
fi
144

145 146 147
LOG="/var/tmp/install-$(date +%Y%m%d-%H%M%S).log"

# Make sure the user's not about to do anything dumb
John Jarvis committed
148 149 150 151 152
if [[ $EUID -eq 0 ]]; then
    error "This script should not be run using sudo or as the root user"
    usage
    exit 1
fi
153

154 155 156 157 158 159 160 161
# If in an existing virtualenv, bail
if [[ "x$VIRTUAL_ENV" != "x" ]]; then
    envname=`basename $VIRTUAL_ENV`
    error "Looks like you're already in the \"$envname\" virtual env."
    error "Run \`deactivate\` and then re-run this script."
    usage
    exit 1
fi
162 163

# Read arguments
164
ARGS=$(getopt "cvhsynq" "$*")
John Jarvis committed
165 166 167 168 169
if [[ $? != 0 ]]; then
    usage
    exit 1
fi
eval set -- "$ARGS"
170 171
while true; do
    case $1 in
John Jarvis committed
172 173 174 175
        -c)
            compile=true
            shift
            ;;
176 177 178 179
        -s)
            systempkgs=true
            shift
            ;;
John Jarvis committed
180 181 182 183 184
        -v)
            set -x
            verbose=true
            shift
            ;;
185 186 187 188 189 190 191 192 193 194 195 196
        -y)
            noninteractive=true
            shift
            ;;
        -q)
            quiet=true
            shift
            ;;
        -n)
            nopull=true
            shift
            ;;
John Jarvis committed
197 198 199 200 201 202 203 204 205 206 207
        -h)
            usage
            exit 0
            ;;
        --)
            shift
            break
            ;;
    esac
done

208 209
if [[ ! $quiet ]]; then
    cat<<EO
John Jarvis committed
210

211
  This script will setup a local edX environment, this
John Jarvis committed
212 213 214 215 216 217 218 219 220 221 222
  includes

       * Django
       * A local copy of Python and library dependencies
       * A local copy of Ruby and library dependencies

  It will also attempt to install operating system dependencies
  with apt(debian) or brew(OSx).

  To compile scipy and numpy from source use the -c option

John Jarvis committed
223
  !!! Do not run this script from an existing virtualenv !!!
224

John Jarvis committed
225
  If you are in a ruby/python virtualenv please start a new
226
  shell.
John Jarvis committed
227

John Jarvis committed
228
EO
229 230
fi
    info
John Jarvis committed
231

232 233 234 235
if [[ ! $noninteractive ]]; then
    output "Press return to begin or control-C to abort"
    read dummy
fi
236 237 238

# Log all stdout and stderr

239 240 241
exec > >(tee $LOG)
exec 2>&1

242 243

# Install basic system requirements
John Jarvis committed
244

John Jarvis committed
245 246 247 248 249 250 251
mkdir -p $BASE
case `uname -s` in
    [Ll]inux)
        command -v lsb_release &>/dev/null || {
            error "Please install lsb-release."
            exit 1
        }
252

John Jarvis committed
253 254
        distro=`lsb_release -cs`
        case $distro in
255
            wheezy|jessie|maya|olivia|nadia|precise|quantal)
256 257 258
                if [[ ! $noninteractive ]]; then
                    warning "
                            Debian support is not fully debugged. Assuming you have standard
259
                            development packages already working like scipy, the
260
                            installation should go fine, but this is still a work in progress.
261

262 263
                            Please report issues you have and let us know if you are able to figure
                            out any workarounds or solutions
264

265
                            Press return to continue or control-C to abort"
266

267 268
                    read dummy
                fi
269
                sudo apt-get install -yq git ;;
270
            squeeze|lisa|katya|oneiric|natty|raring)
271 272 273 274 275
                if [[ ! $noninteractive ]]; then
                    warning "
                              It seems like you're using $distro which has been deprecated.
                              While we don't technically support this release, the install
                              script will probably still work.
276

277 278 279 280
                              Press return to continue or control-C to abort"
                    read dummy
                fi
                sudo apt-get install -yq git
281
                ;;
282

John Jarvis committed
283 284 285
            *)
                error "Unsupported distribution - $distro"
                exit 1
286
               ;;
John Jarvis committed
287 288
        esac
        ;;
289

290
    Darwin)
291 292
        if [[ ! -w /usr/local ]]; then
            cat<<EO
293 294

        You need to be able to write to /usr/local for
295 296 297 298 299 300 301
        the installation of brew and brew packages.

        Either make sure the group you are in (most likely 'staff')
        can write to that directory or simply execute the following
        and re-run the script:

        $ sudo chown -R $USER /usr/local
John Jarvis committed
302
EO
303 304 305 306 307

            exit 1

        fi

308
        command -v brew &>/dev/null || {
John Jarvis committed
309
            output "Installing brew"
David Baumgold committed
310
            /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
311
        }
312
        command -v git &>/dev/null || {
David Baumgold committed
313 314
            output "Installing git"
            brew install git
315 316
        }

John Jarvis committed
317 318
        ;;
    *)
319
        error "Unsupported platform. Try switching to either Mac or a Debian-based linux distribution (Ubuntu, Debian, or Mint)"
John Jarvis committed
320 321 322
        exit 1
        ;;
esac
323

324

325
# Clone edx repositories
326 327 328

clone_repos

329
# Sanity check to make sure the repo layout hasn't changed
330
if [[ -d $BASE/edx-platform/scripts ]]; then
331 332
    output "Installing system-level dependencies"
    bash $BASE/edx-platform/scripts/install-system-req.sh
333
else
334 335 336 337
    error "It appears that our directory structure has changed and somebody failed to update this script.
            raise an issue on Github and someone should fix it."
    exit 1
fi
338

339
# Install system-level dependencies
340 341 342
if [[ ! -d $RBENV_ROOT ]]; then
    output "Installing rbenv"
    git clone https://github.com/sstephenson/rbenv.git $RBENV_ROOT
343
fi
344 345 346
if [[ ! -d $RBENV_ROOT/plugins/ruby-build ]]; then
    output "Installing ruby-build"
    git clone https://github.com/sstephenson/ruby-build.git $RBENV_ROOT/plugins/ruby-build
347
fi
348 349 350 351 352 353 354
shelltype=$(basename $SHELL)
if ! hash rbenv 2>/dev/null; then
    output "Adding rbenv to \$PATH in ~/.${shelltype}rc"
    echo "export PATH=\"$RBENV_ROOT/bin:\$PATH\"" >> $HOME/.${shelltype}rc
    echo 'eval "$(rbenv init -)"' >> $HOME/.${shelltype}rc
    export PATH="$RBENV_ROOT/bin:$PATH"
    eval "$(rbenv init -)"
355
fi
356

357 358 359 360 361
if [[ ! -d $RBENV_ROOT/versions/$RUBY_VER ]]; then
    output "Installing Ruby $RUBY_VER"
    rbenv install $RUBY_VER
    rbenv global $RUBY_VER
fi
362

363 364 365 366 367
if ! hash bundle 2>/dev/null; then
    output "Installing gem bundler"
    gem install bundler
fi
rbenv rehash
368

369
output "Installing ruby packages"
370
bundle install --gemfile $BASE/edx-platform/Gemfile
371

372 373 374 375 376 377 378 379 380 381
# Install Python virtualenv
output "Installing python virtualenv"

case `uname -s` in
    Darwin)
        # Add brew's path
        PATH=/usr/local/share/python:/usr/local/bin:$PATH
        ;;
esac

382 383 384 385 386 387
# virtualenvwrapper uses the $WORKON_HOME env var to determine where to place
# virtualenv directories. Make sure it matches the selected $PYTHON_DIR.
export WORKON_HOME=$PYTHON_DIR

# Load in the mkvirtualenv function if needed
if [[ `type -t mkvirtualenv` != "function" ]]; then
388 389
    case `uname -s` in
        Darwin)
390
            VEWRAPPER=`which virtualenvwrapper.sh`
391 392
        ;;

393
        [Ll]inux)
394
        if [[ -f "/etc/bash_completion.d/virtualenvwrapper" ]]; then
395
            VEWRAPPER=/etc/bash_completion.d/virtualenvwrapper
396 397 398
        else
            error "Could not find virtualenvwrapper"
            exit 1
399
        fi
400 401
        ;;
    esac
402 403
fi

404
source $VEWRAPPER
405
# Create edX virtualenv and link it to repo
406
# virtualenvwrapper automatically sources the activation script
407
if [[ $systempkgs ]]; then
408
    mkvirtualenv -q -a "$WORKON_HOME" --system-site-packages edx-platform || {
409 410 411
      error "mkvirtualenv exited with a non-zero error"
      return 1
    }
412 413 414
else
    # default behavior for virtualenv>1.7 is
    # --no-site-packages
415
    mkvirtualenv -q -a "$WORKON_HOME" edx-platform || {
416 417 418
      error "mkvirtualenv exited with a non-zero error"
      return 1
    }
419 420
fi

421

422 423
# compile numpy and scipy if requested

424 425 426
NUMPY_VER="1.6.2"
SCIPY_VER="0.10.1"

427
if [[ -n $compile ]]; then
428
    output "Downloading numpy and scipy"
429 430
    curl -sSL -o numpy.tar.gz http://downloads.sourceforge.net/project/numpy/NumPy/${NUMPY_VER}/numpy-${NUMPY_VER}.tar.gz
    curl -sSL -o scipy.tar.gz http://downloads.sourceforge.net/project/scipy/scipy/${SCIPY_VER}/scipy-${SCIPY_VER}.tar.gz
431
    tar xf numpy.tar.gz
432 433
    tar xf scipy.tar.gz
    rm -f numpy.tar.gz scipy.tar.gz
434 435 436
    output "Compiling numpy"
    cd "$BASE/numpy-${NUMPY_VER}"
    python setup.py install
437 438 439
    output "Compiling scipy"
    cd "$BASE/scipy-${SCIPY_VER}"
    python setup.py install
440
    cd "$BASE"
441
    rm -rf numpy-${NUMPY_VER} scipy-${SCIPY_VER}
442
fi
John Jarvis committed
443

444 445 446
# building correct version of distribute from source
DISTRIBUTE_VER="0.6.28"
output "Building Distribute"
447
SITE_PACKAGES="$WORKON_HOME/edx-platform/lib/python2.7/site-packages"
448
cd "$SITE_PACKAGES"
449
curl -sSLO http://pypi.python.org/packages/source/d/distribute/distribute-${DISTRIBUTE_VER}.tar.gz
450 451 452 453 454 455 456 457 458 459 460 461
tar -xzvf distribute-${DISTRIBUTE_VER}.tar.gz
cd distribute-${DISTRIBUTE_VER}
python setup.py install
cd ..
rm distribute-${DISTRIBUTE_VER}.tar.gz

DISTRIBUTE_VERSION=`pip freeze | grep distribute`

if [[ "$DISTRIBUTE_VERSION" == "distribute==0.6.28" ]]; then
  output "Distribute successfully installed"
else
  error "Distribute failed to build correctly. This script requires a working version of Distribute 0.6.28 in your virtualenv's python installation"
462
  exit 1
463 464
fi

465 466 467 468 469 470 471
case `uname -s` in
    Darwin)
        # on mac os x get the latest distribute and pip
        pip install -U pip
        # need latest pytz before compiling numpy and scipy
        pip install -U pytz
        pip install numpy
472 473
        # scipy needs cython
        pip install cython
474 475 476 477 478
        # fixes problem with scipy on 10.8
        pip install -e git+https://github.com/scipy/scipy#egg=scipy-dev
        ;;
esac

479
output "Installing edX pre-requirements"
480
pip install -r $BASE/edx-platform/requirements/edx/pre.txt
481

482 483
output "Installing edX paver-requirements"
pip install -r $BASE/edx-platform/requirements/edx/paver.txt
484

485

486 487 488
output "Installing edX requirements"
# Install prereqs
cd $BASE/edx-platform
Will Daly committed
489
paver install_prereqs
490 491 492 493 494 495 496

# Final dependecy
output "Finishing Touches"
cd $BASE
pip install argcomplete
cd $BASE/edx-platform
bundle install
Will Daly committed
497
paver install_prereqs
498

499 500 501
mkdir -p "$BASE/log"
mkdir -p "$BASE/db"
mkdir -p "$BASE/data"
John Jarvis committed
502

503 504
./manage.py lms syncdb --noinput --migrate
./manage.py cms syncdb --noinput --migrate
505

506 507
# Configure Git

508 509 510
output "Fixing your git default settings"
git config --global push.default current

511 512 513

### DONE

514 515
if [[ ! $quiet ]]; then
    cat<<END
John Jarvis committed
516 517
   Success!!

518
   To start using Django you will need to activate the local Python
519
   environment. Ensure the following lines are added to your
520 521
   login script, and source your login script if needed:

522
        source $VEWRAPPER
523 524

   Then, every time you're ready to work on the project, just run
John Jarvis committed
525

526
        $ workon edx-platform
527

528 529
   To start the Django on port 8000

Will Daly committed
530
        $ paver lms
531

532 533
   Or to start Django on a different <port#>

534
        $ ./manage.py lms runserver <port#>
535

536
  If the  Django development server starts properly you
537 538 539 540 541
  should see:

      Development server is running at http://127.0.0.1:<port#>/
      Quit the server with CONTROL-C.

542
  Connect your browser to http://127.0.0.1:<port#> to
543 544 545
  view the Django site.


John Jarvis committed
546
END
547 548
fi

John Jarvis committed
549
exit 0