2012-10-26 12 views
18

Ho un problema quando utilizzo Fabric per simulare il flusso di lavoro SSH per distribuire la mia applicazione web.Cambiare utente in Fabric

Ecco il mio solito flusso di comandi quando ho SSH ad un server:

  1. SSH utilizzando utente root. ssh [email protected]
  2. Passa a utente web: su - web
  3. Cambio directory: cd/srv/web/prod/abc_project
  4. Inizio virtualenv: workon abc_env
  5. Eseguire git pull: origine tirare git padroneggiare
  6. Esegui uno script: build_stuff -m costruire
  7. eseguire un altro script: ./Run

ho cercato di scrivere questo come uno script deploy in tessuto e ho un uscita shell quando s u - il web è inserito. Devo premere Ctrl-D per continuare lo script. Sono anche in grado di attivare il mio virtualenv .... perché: su - web passa con successo l'utente a web ma a causa del Ctrl-d (in modo che possa continuare lo script Fabric), si disconnette da tale utente e torna a radice.

Ecco il mio script:

env.user = 'root' 

@roles('web') 
def deploy(): 
    dev_path = '/srv/web/prod' 
    app_path = '/srv/web/prod/rhino' 
    workon = 'workon rhino_env' 
    with prefix('su - web'): 
     puts('Switched to `web` user') 
     with settings(warn_only=True): 
      run('kill -9 `cat /srv/web/run/rhino/rhino.pid`') 
      puts('Stopped rhino...') 
     with cd(app_path): 
      run('git reset --hard HEAD') 
      puts('Discarded all untracked and modified files') 
      run('git checkout master') 
      run('git pull origin master') 
      users = run('users') 
      puts('Output from `users` command: %s' % users) 
      run(workon) 
      run('build_assets -m build') 
     run('cd %(dev_path)s; chown -R web:ebalu rhino' % {'dev_path': dev_path}) 
     run('cd %(app_path)s; ./run' % {'app_path': app_path}) 
     pid = run('cat /srv/web/run/rhino/rhino.pid') 
     puts('Rhino started again with pid: %s.' % pid) 

... c'è una cosa più: No, non posso effettuare il login come web inizialmente, devo effettuare il login come root. È l'utente Web che ha virtualenv e non l'utente root.

risposta

12

Prima di tutto, è necessario utilizzare sudo quando l'esecuzione di comandi sotto un altro utente. In secondo luogo, workon imposta le variabili di ambiente per la shell corrente. Poiché fabric invoca una nuova shell per ogni comando, è necessario eseguire workon rhino_env in ogni comando, dove è necessario virtualenv (cioè come prefisso). Con questa modifica yor codice dovrebbe essere simile a questo:

env.user = 'root' 

@roles('web') 
def deploy(): 
    dev_path = '/srv/web/prod' 
    app_path = '/srv/web/prod/rhino' 
    workon = 'workon rhino_env; ' 
    with settings(warn_only=True): 
     run('kill -9 `cat /srv/web/run/rhino/rhino.pid`') 
     puts('Stopped rhino...') 
    with cd(app_path): 
     sudo('git reset --hard HEAD', user='web') 
     puts('Discarded all untracked and modified files') 
     sudo('git checkout master', user='web') 
     sudo('git pull origin master', user='web') 
     users = run('users') 
     puts('Output from `users` command: %s' % users) 

     with prefix(workon): 
      sudo('build_assets -m build', user='web') 
    with cd(dev_path): 
     run('chown -R web:ebalu rhino') 

    with cd(app_path): 
     sudo('./run', user='web') 

    pid = run('cat /srv/web/run/rhino/rhino.pid') 
    puts('Rhino started again with pid: %s.' % pid) 
+0

Grazie mille! Non ho mai pensato di eseguire comandi git usando l'utente web. Ho continuato a provare a usare 'su - web' di fronte ai comandi git. Grazie mille milioni di menti! – Mark

3

Una possibile soluzione consiste nell'utilizzare l'operazione sudo invece di modificare l'utente remoto con su.

3

Il mio modo di raggiungere questo obiettivo è con

from fabric.api import settings 

with settings(user='otheruser'): 
    ... 

Verrà richiesto di inserire la password di otheruser, anche se solo una volta. Quindi non è equivalente quindi sudo su otheruser, dove root accede all'account utente senza password, ma è un modo semplice per passare da uno script all'altro, digitando ogni password solo una volta

+1

Giuro che questo ha funzionato una volta! Il mio compito di provisioning è ora interrotto. –