4

Possible Duplicate:
Activate a virtualenv via fabric as deploy user

I've been advised to try and use fabric for deploying Django to a production server, and automating tasks by using python instead of bash.

I wanted to start easily and just automate the activation of my virtualenv, and start the Django development server in it.

I've created a file named fabfile.py:

from fabric.api import local

def activate_env():
    local("source /.../expofit_env/bin/activate")

def run_local_server():
    local("/.../server/manage.py runserver")

def start():
    activate_env()
    run_local_server()

However, when I run

fab start

i get the following message:

[localhost] local: source /.../expofit_env/bin/activate
/bin/sh: 1: source: not found

Fatal error: local() encountered an error (return code 127) while executin
'source /.../expofit_env/bin/activate'

What am I doing wrong?


Update

Based on Burhan Khalid's proposal, i tried the following:

....
def activate_env():
    local("/bin/bash /.../expofit_env/bin/activate")
....

Running just

fab activate_env

results:

[localhost] local: /bin/bash /.../expofit_env/bin/activate

Done.

However after execution, virtualenv isn't activated. For the following code:

def start_env(): 
    with prefix('/bin/bash /.../expofit_env/bin/activate'): 
        local("yolk -l")

I still get an error, as if virtualenv wasn't activated.

alan@linux ~/Desktop/expofit $ fab start_env
[localhost] local: yolk -l
/bin/sh: 1: yolk: not found

When i manually activate virtualenv, yolk workd fine:

alan@linux ~/.../expofit_env $ source bin/activate
(expofit_env)alan@linux ~/.../expofit_env $ yolk -l

DateUtils       - 0.5.2        - active 
Django          - 1.4.1        - active 
Python          - 2.7.3rc2     - active development (/usr/lib/python2.7/lib-dynload)
....

Update

Tried a new approach from this question.

from __future__ import with_statement
from fabric.api import *
from contextlib import contextmanager as _contextmanager

env.activate = 'source /.../expofit_env/bin/activate'

@_contextmanager
def virtualenv():
    with prefix(env.activate):
        yield

def deploy():
    with virtualenv():
        local('yolk -l')

Gives the same error:

[localhost] local: yolk -l
/bin/sh: 1: source: not found

Fatal error: local() encountered an error (return code 127) while executing 'yolk -l'

Aborting.

Even dough the first command passes without errors:

alan@linux ~/.../expofit_env/bin $ fab virtualenv

[servername] Executing task 'virtualenv'

Done.

Update

It is possible to run the local with a custom shell.

from fabric.api import local

def start_env():
        local('source env/bin/activate',shell='/bin/bash')

However, that didn't activate the virtualenv as if it was done manually.

Community
  • 1
  • 1
TheMeaningfulEngineer
  • 15,679
  • 27
  • 85
  • 143

2 Answers2

3

To use enable a virtualenv from the fab file you need to run your commands as follow:

def task():

    # do some things outside the env if needed 

    with prefix('source bin/activate'):
        # do some stuff inside the env
        pip install django-audiofield

All the commands within the with bloc will be executed inside the virtualenv

Jeff
  • 233
  • 2
  • 7
2

By default you are using the sh shell, and the source command is a bashism (that is, something that only works in bash).

To activate your environment, you need to execute it with bash directly. /bin/bash /path/to/bin/activate.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284