Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
otros:fabric [2013/08/25 16:36] alfred [Básico] |
otros:fabric [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 31: | Línea 31: | ||
| Disconnecting from 127.0.0.1... done. | Disconnecting from 127.0.0.1... done. | ||
| Disconnecting from 192.168.1.20... done. | Disconnecting from 192.168.1.20... done. | ||
| + | </code> | ||
| + | Para ver las funcionalidades de las que disponemos haremos: | ||
| + | <code> | ||
| + | $ fab --list | ||
| + | </code> | ||
| + | ===== Funciones ===== | ||
| + | En la API de fabric (''fabric.api'') encontramos las siguientes funciones: | ||
| + | * **local**: execute a local command | ||
| + | * **run**: execute a remote command on all specific hosts, user-level permissions | ||
| + | * **sudo**: sudo a command on the remote server | ||
| + | * **put**: copy over a local file to a remote destination | ||
| + | * **get**: download a file from the remote server | ||
| + | * **prompt**: prompt user with text and return the input (like raw_input)) | ||
| + | * **reboot**: reboot the remote system, disconnect, and wait for wait seconds | ||
| + | |||
| + | ===== La fabfile ===== | ||
| + | Cada función es una tarea, ha de estar dentro del directorio donde ejecutas ''fab''. | ||
| + | |||
| + | ===== Comando fab ===== | ||
| + | ==== Usage ==== | ||
| + | <code> | ||
| + | fab [options] <command>[:arg1,arg2=val2,host=foo,hosts='h1;h2',...] ... | ||
| + | </code> | ||
| + | ==== Parámetros ==== | ||
| + | * ''-H'' indica distintos hosts donde se ejecutará. | ||
| + | ==== Parámetros a las tareas ==== | ||
| + | <code python> | ||
| + | def hello(name="world"): | ||
| + | print("Hello %s!" % name) | ||
| + | </code> | ||
| + | <code python> | ||
| + | $ fab hello:name=Jeff | ||
| + | $ fab hello:Jeff | ||
| + | </code> | ||
| + | ===== En código... ===== | ||
| + | ==== Variables de entorno ==== | ||
| + | Si creamos las siguientes variables: | ||
| + | <code python> | ||
| + | env.user = 'username' | ||
| + | env.hosts = ['serverX', 'serverY', 'userX@serverZ'] | ||
| + | </code> | ||
| + | Ejecutará las tareas en los servidores serverX y serverY con nombre de usuario 'username'. En el servidor serverZ utilizará userX. | ||
| + | |||
| + | ==== Tareas complejas ==== | ||
| + | <code python> | ||
| + | from fabric.api import local | ||
| + | |||
| + | def test(): | ||
| + | local("./manage.py test my_app") # ejecuta los tests | ||
| + | |||
| + | def commit(): | ||
| + | local("git add -p && git commit") | ||
| + | |||
| + | def push(): | ||
| + | local("git push") | ||
| + | |||
| + | def prepare_deploy(): | ||
| + | test() | ||
| + | commit() | ||
| + | push() | ||
| + | </code> | ||
| + | ==== Roles ==== | ||
| + | |||
| + | También podemos especificar roles de servidores: | ||
| + | <code python> | ||
| + | env.roledefs = { | ||
| + | 'webservers': ['www1', 'www2', 'www3', 'www4', 'www5'], | ||
| + | 'databases': ['db1', 'db2'], | ||
| + | 'nas': ['nas1', 'nas2'] | ||
| + | } | ||
| + | @roles('webservers', 'nas') | ||
| + | def get_version(): | ||
| + | run('cat /etc/issue') | ||
| + | </code> | ||
| + | Ejecutará ''get_versión'' únicamente en los hosts: www1, www2, www3, www4, www5, nas1 y nas2. | ||
| + | |||
| + | ==== Gestión de errores ==== | ||
| + | <code python> | ||
| + | def test(): | ||
| + | with settings(warn_only=True): | ||
| + | result = local('./manage.py test my_app', capture=True) | ||
| + | if result.failed and not confirm("Tests failed. Continue anyway?"): | ||
| + | abort("Aborting at user request.") | ||
| + | </code> | ||
| + | ===== Ejemplos ===== | ||
| + | ==== Copiar un directorio ==== | ||
| + | <code python> | ||
| + | from fabric.api import * | ||
| + | |||
| + | env.hosts = ['userX@serverX'] | ||
| + | |||
| + | def copy(): | ||
| + | # make sure the directory is there! | ||
| + | run('mkdir -p /home/userX/mynewfolder') | ||
| + | # our local 'localdirectory' (it may contain files or subdirectories) | ||
| + | put('localdirectory', '/home/userX/mynewfolder') | ||
| + | </code> | ||
| + | |||
| + | ==== Llamadas complejas ==== | ||
| + | <code python> | ||
| + | def install(pkg=None): | ||
| + | if pkg is not None: | ||
| + | env["pkg"] = pkg | ||
| + | elif pkg is None and env.get("pkg") is None: | ||
| + | env["pkg"] = prompt("Which package? ") | ||
| + | sudo('yum install -y %s' % env["pkg"]) | ||
| + | </code> | ||
| + | <code> | ||
| + | $ fab --hosts=host1,host2,host3 install | ||
| + | $ fab --hosts=host1,host2,host3 install:pkg=wormux | ||
| + | $ fab --hosts=host1,host2,host3 install:wormux | ||
| + | $ fab --skip-bad-hosts -u user -p 12345 -i ~/.ssh/id_dsa --warn-only --hosts=host1,host2,host3,host4 --parallel --pool-size=20 install:pkg=wormux | ||
| + | </code> | ||
| + | ==== Script que ejecuta tareas según host ==== | ||
| + | * {{:otros:fabric:fabric-executing.zip|script}} | ||
| + | ===== Tips & tricks ===== | ||
| + | |||
| + | ==== Utilizar un fichero con los nombres de hosts ==== | ||
| + | <code python> | ||
| + | def set_hosts(): | ||
| + | env.hosts = open('hosts', 'r').readlines() | ||
| + | </code> | ||
| + | Con esta tarea pondríamos los hostnames en un fichero llamado host y podríamos lanzar nuestro fabfile así: | ||
| + | <code> | ||
| + | $ fab --skip-bad-hosts -u user -p 12345 -i ~/.ssh/id_dsa --warn-only --parallel set_hosts | ||
| + | </code> | ||
| + | |||
| + | ==== Ejecutar comandos en un directorio concreto ==== | ||
| + | Usando ''with'': | ||
| + | <code python> | ||
| + | with cd("~/gitrepo"): | ||
| + | run('git add --all') | ||
| + | run('git commit -m "My super awesome automated commit script for `date`"') | ||
| + | </code> | ||
| + | |||
| + | ==== Usar los nombres en ssh.config ==== | ||
| + | <code python> | ||
| + | from fabric.api import run, env | ||
| + | env.use_ssh_config = True | ||
| </code> | </code> | ||