traduccion software examples python fabric

software - ¿El tejido python es compatible con el conjunto dinámico env.hosts?



pip install fabric (3)

Más o menos tarde en la fiesta, pero logré esto con ec2 así (nota en EC2, no sabes cuál puede ser el ip / nombre de host, en general, por lo que casi tienes que ir dinámico para tener en cuenta cómo funciona el entorno / los sistemas. podría surgir - otra opción sería usar dyndns, pero esto aún sería útil):

from fabric.api import * import datetime import time import urllib2 import ConfigParser from platform_util import * config = ConfigParser.RawConfigParser() @task def load_config(configfile=None): '''''' ***REQUIRED*** Pass in the configuration to use - usage load_config:</path/to/config.cfg> '''''' if configfile != None: # Load up our config file config.read(configfile) # Key/secret needed for aws interaction with boto # (anyone help figure out a better way to do this with sub modules, please don''t say classes :-) ) global aws_key global aws_sec aws_key = config.get("main","aws_key") aws_sec = config.get("main","aws_sec") # Stuff for fabric env.user = config.get("main","fabric_ssh_user") env.key_filename = config.get("main","fabric_ssh_key_filename") env.parallel = config.get("main","fabric_default_parallel") # Load our role definitions for fabric for i in config.sections(): if i != "main": hostlist = [] if config.get(i,"use-regex") == ''yes'': for x in get_running_instances_by_regex(aws_key,aws_sec,config.get(i,"security-group"),config.get(i,"pattern")): hostlist.append(x.private_ip_address) env.roledefs[i] = hostlist else: for x in get_running_instances(aws_key,aws_sec,config.get(i,"security-group")): hostlist.append(x.private_ip_address) env.roledefs[i] = hostlist if config.has_option(i,"base-group"): if config.get(i,"base-group") == ''yes'': print "%s is a base group" % i print env.roledefs[i] # env["basegroups"][i] = True

donde get_running_instances y get_running_instances_by_regex son funciones de utilidad que hacen uso de boto ( http://code.google.com/p/boto/ )

ex:

import logging import re from boto.ec2.connection import EC2Connection from boto.ec2.securitygroup import SecurityGroup from boto.ec2.instance import Instance from boto.s3.key import Key ######################################## # B-O-F get_instances ######################################## def get_instances(access_key=None, secret_key=None, security_group=None): '''''' Get all instances. Only within a security group if specified., doesnt'' matter their state (running/stopped/etc) '''''' logging.debug(''get_instances()'') conn = EC2Connection(aws_access_key_id=access_key, aws_secret_access_key=secret_key) if security_group: sg = SecurityGroup(connection=conn, name=security_group) instances = sg.instances() return instances else: instances = conn.get_all_instances() return instances

Aquí hay una muestra de cómo se veía mi configuración:

# Config file for fabric toolset # # This specific configuration is for <whatever> related hosts # # [main] aws_key = <key> aws_sec = <secret> fabric_ssh_user = <your_user> fabric_ssh_key_filename = /path/to/your/.ssh/<whatever>.pem fabric_default_parallel = 1 # # Groupings - Fabric knows them as roledefs (check env dict) # # Production groupings [app-prod] security-group = app-prod use-regex = no pattern = [db-prod] security-group = db-prod use-regex = no pattern = [db-prod-masters] security-group = db-prod use-regex = yes pattern = mysql-[d-s]01

Quiero cambiar el env.hosts dinámicamente porque a veces quiero implementar primero en una máquina, verifique si está bien y luego implementar en muchas máquinas. Actualmente necesito configurar env.hosts primero, ¿cómo podría configurar env.hosts en un método y no en global al inicio del script?


Otra nueva respuesta a una vieja pregunta. :) Pero recientemente me encontré intentando configurar hosts de forma dinámica, y realmente tengo que estar en desacuerdo con la respuesta principal. Mi idea de dinámica , o al menos lo que intentaba hacer, era tomar un nombre de DNS de instancia que acaba de crearse por boto y acceder a esa instancia con un comando fab. No pude realizar el fab staging deploy , porque la instancia no existe en el momento de la edición de archivos fab.

Afortunadamente, fabric admite una asignación de host verdaderamente dinámica con execute . (Es posible que esto no existiera cuando se hizo la pregunta por primera vez, por supuesto, pero ahora sí). execute permite definir una función a la que llamar, y el env.hosts que debe usar para ese comando. Por ejemplo:

def create_EC2_box(data=fab_base_data): conn = boto.ec2.connect_to_region(region) reservations = conn.run_instances(image_id=image_id, ...) ... return instance.public_dns_name def _ping_box(): run(''uname -a'') run(''tail /var/log/cloud-init-output.log'') def build_box(): box_name = create_EC2_box(fab_base_data) new_hosts = [box_name] # new_hosts = [''ec2-54-152-152-123.compute-1.amazonaws.com''] # testing execute(_ping_box, hosts=new_hosts)

Ahora puedo hacer fab build_box , y se activará una llamada de boto que crea una instancia y otra llamada de fabric que se ejecuta en la nueva instancia, sin tener que definir el nombre de la instancia en el momento de la edición.


Sí, puedes configurar env.hosts dinámicamente. Un patrón común que utilizamos es:

from fabric.api import env def staging(): env.hosts = [''XXX.XXX.XXX.XXX'', ] def production(): env.hosts = [''YYY.YYY.YYY.YYY'', ''ZZZ.ZZZ.ZZZ.ZZZ'', ] def deploy(): # Do something...

Usaría esto para encadenar las tareas como la fab staging deploy fab production deploy o la fab production deploy .