signature:
def upload_template ( self , filename , destination , context = None , use_jinja = False , template_dir = None , use_sudo = False , backup = True , mirror_local_mode = False , mode = None , mkdir = False , chown = False , user = None ) :
    """Upload a template file .
 This is a wrapper around : func : ` fabric . contrib . files . upload _ template `
 that adds some extra parameters .
 If ` ` mkdir ` ` is True , then the remote directory will be created , as
 the current user or as ` ` user ` ` if specified .
 If ` ` chown ` ` is True , then it will ensure that the current user ( or
 ` ` user ` ` if specified ) is the owner of the remote file ."""

implementation:
if mkdir :
    remote_dir = os . path . dirname ( destination )
    if use_sudo :
        self . sudo ( 'mkdir -p %s' % quote ( remote_dir ) , user = user )
    else :
        self . run ( 'mkdir -p %s' % quote ( remote_dir ) )
if not self . dryrun :
    _upload_template ( filename = filename , destination = destination , context = context , use_jinja = use_jinja , template_dir = template_dir , use_sudo = use_sudo , backup = backup , mirror_local_mode = mirror_local_mode , mode = mode , )
if chown :
    if user is None :
        user = self . genv . user
    run_as_root ( 'chown %s: %s' % ( user , quote ( destination ) ) )


signature:
def md5sum ( self , filename , use_sudo = False ) :
    """Compute the MD5 sum of a file ."""

implementation:
func = use_sudo and run_as_root or self . run
with self . settings ( hide ( 'running' , 'stdout' , 'stderr' , 'warnings' ) , warn_only = True ) : # Linux ( LSB )
    if exists ( u'/usr/bin/md5sum' ) :
        res = func ( u'/usr/bin/md5sum %(filename)s' % locals ( ) )
    # BSD / OS X
    elif exists ( u'/sbin/md5' ) :
        res = func ( u'/sbin/md5 -r %(filename)s' % locals ( ) )
    # SmartOS Joyent build
    elif exists ( u'/opt/local/gnu/bin/md5sum' ) :
        res = func ( u'/opt/local/gnu/bin/md5sum %(filename)s' % locals ( ) )
    # SmartOS Joyent build
    # ( the former doesn ' t exist , at least on joyent _ 20130222T000747Z )
    elif exists ( u'/opt/local/bin/md5sum' ) :
        res = func ( u'/opt/local/bin/md5sum %(filename)s' % locals ( ) )
    # Try to find ` ` md5sum ` ` or ` ` md5 ` ` on ` ` $ PATH ` ` or abort
    else :
        md5sum = func ( u'which md5sum' )
        md5 = func ( u'which md5' )
        if exists ( md5sum ) :
            res = func ( '%(md5sum)s %(filename)s' % locals ( ) )
        elif exists ( md5 ) :
            res = func ( '%(md5)s %(filename)s' % locals ( ) )
        else :
            abort ( 'No MD5 utility was found on this system.' )
if res . succeeded :
    _md5sum = res
else :
    warn ( res )
    _md5sum = None
if isinstance ( _md5sum , six . string_types ) :
    _md5sum = _md5sum . strip ( ) . split ( '\n' ) [ - 1 ] . split ( ) [ 0 ]
return _md5sum


signature:
def uncommented_lines ( self , filename , use_sudo = False ) :
    """Get the lines of a remote file , ignoring empty or commented ones"""

implementation:
func = run_as_root if use_sudo else self . run
res = func ( 'cat %s' % quote ( filename ) , quiet = True )
if res . succeeded :
    return [ line for line in res . splitlines ( ) if line and not line . startswith ( '#' ) ]
return [ ]


signature:
def getmtime ( self , path , use_sudo = False ) :
    """Return the time of last modification of path .
 The return value is a number giving the number of seconds since the epoch
 Same as : py : func : ` os . path . getmtime ( ) `"""

implementation:
func = use_sudo and run_as_root or self . run
with self . settings ( hide ( 'running' , 'stdout' ) ) :
    return int ( func ( 'stat -c %%Y "%(path)s" ' % locals ( ) ) . strip ( ) )


signature:
def copy ( self , source , destination , recursive = False , use_sudo = False ) :
    """Copy a file or directory"""

implementation:
func = use_sudo and run_as_root or self . run
options = '-r ' if recursive else ''
func ( '/bin/cp {0}{1} {2}' . format ( options , quote ( source ) , quote ( destination ) ) )


signature:
def move ( self , source , destination , use_sudo = False ) :
    """Move a file or directory"""

implementation:
func = use_sudo and run_as_root or self . run
func ( '/bin/mv {0} {1}' . format ( quote ( source ) , quote ( destination ) ) )


signature:
def remove ( self , path , recursive = False , use_sudo = False ) :
    """Remove a file or directory"""

implementation:
func = use_sudo and run_as_root or self . run
options = '-r ' if recursive else ''
func ( '/bin/rm {0}{1}' . format ( options , quote ( path ) ) )


signature:
def require ( self , path = None , contents = None , source = None , url = None , md5 = None , use_sudo = False , owner = None , group = '' , mode = None , verify_remote = True , temp_dir = '/tmp' ) :
    """Require a file to exist and have specific contents and properties .
 You can provide either :
 - * contents * : the required contents of the file : :
 from fabtools import require
 require . file ( ' / tmp / hello . txt ' , contents = ' Hello , world ' )
 - * source * : the local path of a file to upload : :
 from fabtools import require
 require . file ( ' / tmp / hello . txt ' , source = ' files / hello . txt ' )
 - * url * : the URL of a file to download ( * path * is then optional ) : :
 from fabric . api import cd
 from fabtools import require
 with cd ( ' tmp ' ) :
 require . file ( url = ' http : / / example . com / files / hello . txt ' )
 If * verify _ remote * is ` ` True ` ` ( the default ) , then an MD5 comparison
 will be used to check whether the remote file is the same as the
 source . If this is ` ` False ` ` , the file will be assumed to be the
 same if it is present . This is useful for very large files , where
 generating an MD5 sum may take a while .
 When providing either the * contents * or the * source * parameter , Fabric ' s
 ` ` put ` ` function will be used to upload the file to the remote host .
 When ` ` use _ sudo ` ` is ` ` True ` ` , the file will first be uploaded to a temporary
 directory , then moved to its final location . The default temporary
 directory is ` ` / tmp ` ` , but can be overridden with the * temp _ dir * parameter .
 If * temp _ dir * is an empty string , then the user ' s home directory will
 be used .
 If ` use _ sudo ` is ` True ` , then the remote file will be owned by root ,
 and its mode will reflect root ' s default * umask * . The optional * owner * ,
 * group * and * mode * parameters can be used to override these properties .
 . . note : : This function can be accessed directly from the
 ` ` fabtools . require ` ` module for convenience ."""

implementation:
func = use_sudo and run_as_root or self . run
# 1 ) Only a path is given
if path and not ( contents or source or url ) :
    assert path
    if not self . is_file ( path ) :
        func ( 'touch "%(path)s"' % locals ( ) )
# 2 ) A URL is specified ( path is optional )
elif url :
    if not path :
        path = os . path . basename ( urlparse ( url ) . path )
    if not self . is_file ( path ) or md5 and self . md5sum ( path ) != md5 :
        func ( 'wget --progress=dot:mega "%(url)s" -O "%(path)s"' % locals ( ) )
# 3 ) A local filename , or a content string , is specified
else :
    if source :
        assert not contents
        t = None
    else :
        fd , source = mkstemp ( )
        t = os . fdopen ( fd , 'w' )
        t . write ( contents )
        t . close ( )
    if verify_remote : # Avoid reading the whole file into memory at once
        digest = hashlib . md5 ( )
        f = open ( source , 'rb' )
        try :
            while True :
                d = f . read ( BLOCKSIZE )
                if not d :
                    break
                digest . update ( d )
        finally :
            f . close ( )
    else :
        digest = None
    if ( not self . is_file ( path , use_sudo = use_sudo ) or ( verify_remote and self . md5sum ( path , use_sudo = use_sudo ) != digest . hexdigest ( ) ) ) :
        with self . settings ( hide ( 'running' ) ) :
            self . put ( local_path = source , remote_path = path , use_sudo = use_sudo , temp_dir = temp_dir )
    if t is not None :
        os . unlink ( source )
# Ensure correct owner
if use_sudo and owner is None :
    owner = 'root'
if ( owner and self . get_owner ( path , use_sudo ) != owner ) or ( group and self . get_group ( path , use_sudo ) != group ) :
    func ( 'chown %(owner)s:%(group)s "%(path)s"' % locals ( ) )
# Ensure correct mode
if use_sudo and mode is None :
    mode = oct ( 0o666 & ~ int ( self . umask ( use_sudo = True ) , base = 8 ) )
if mode and self . get_mode ( path , use_sudo ) != mode :
    func ( 'chmod %(mode)s "%(path)s"' % locals ( ) )


signature:
def check_for_change ( self ) :
    """Determines if a new release has been made ."""

implementation:
r = self . local_renderer
lm = self . last_manifest
last_fingerprint = lm . fingerprint
current_fingerprint = self . get_target_geckodriver_version_number ( )
self . vprint ( 'last_fingerprint:' , last_fingerprint )
self . vprint ( 'current_fingerprint:' , current_fingerprint )
if last_fingerprint != current_fingerprint :
    print ( 'A new release is available. %s' % self . get_most_recent_version ( ) )
    return True
print ( 'No updates found.' )
return False


signature:
def record_manifest ( self ) :
    """Called after a deployment to record any data necessary to detect changes
 for a future deployment ."""

implementation:
manifest = super ( SeleniumSatchel , self ) . record_manifest ( )
manifest [ 'fingerprint' ] = str ( self . get_target_geckodriver_version_number ( ) )
return manifest


signature:
def update ( kernel = False ) :
    """Upgrade all packages , skip obsoletes if ` ` obsoletes = 0 ` ` in ` ` yum . conf ` ` .
 Exclude * kernel * upgrades by default ."""

implementation:
manager = MANAGER
cmds = { 'yum -y --color=never' : { False : '--exclude=kernel* update' , True : 'update' } }
cmd = cmds [ manager ] [ kernel ]
run_as_root ( "%(manager)s %(cmd)s" % locals ( ) )


signature:
def is_installed ( pkg_name ) :
    """Check if an RPM package is installed ."""

implementation:
manager = MANAGER
with settings ( hide ( 'running' , 'stdout' , 'stderr' , 'warnings' ) , warn_only = True ) :
    res = run ( "rpm --query %(pkg_name)s" % locals ( ) )
    if res . succeeded :
        return True
    return False


signature:
def install ( packages , repos = None , yes = None , options = None ) :
    """Install one or more RPM packages .
 Extra * repos * may be passed to ` ` yum ` ` to enable extra repositories at install time .
 Extra * yes * may be passed to ` ` yum ` ` to validate license if necessary .
 Extra * options * may be passed to ` ` yum ` ` if necessary
 ( e . g . ` ` [ ' - - nogpgcheck ' , ' - - exclude = package ' ] ` ` ) .
 import burlap
 # Install a single package , in an alternative install root
 burlap . rpm . install ( ' emacs ' , options = ' - - installroot = / my / new / location ' )
 # Install multiple packages silently
 burlap . rpm . install ( [
 ' unzip ' ,
 ' nano '
 ] , ' - - quiet ' )"""

implementation:
manager = MANAGER
if options is None :
    options = [ ]
elif isinstance ( options , six . string_types ) :
    options = [ options ]
if not isinstance ( packages , six . string_types ) :
    packages = " " . join ( packages )
if repos :
    for repo in repos :
        options . append ( '--enablerepo=%(repo)s' % locals ( ) )
options = " " . join ( options )
if isinstance ( yes , str ) :
    run_as_root ( 'yes %(yes)s | %(manager)s %(options)s install %(packages)s' % locals ( ) )
else :
    run_as_root ( '%(manager)s %(options)s install %(packages)s' % locals ( ) )


signature:
def groupinstall ( group , options = None ) :
    """Install a group of packages .
 You can use ` ` yum grouplist ` ` to get the list of groups .
 Extra * options * may be passed to ` ` yum ` ` if necessary like
 ( e . g . ` ` [ ' - - nogpgcheck ' , ' - - exclude = package ' ] ` ` ) .
 import burlap
 # Install development packages
 burlap . rpm . groupinstall ( ' Development tools ' )"""

implementation:
manager = MANAGER
if options is None :
    options = [ ]
elif isinstance ( options , str ) :
    options = [ options ]
options = " " . join ( options )
run_as_root ( '%(manager)s %(options)s groupinstall "%(group)s"' % locals ( ) , pty = False )


signature:
def uninstall ( packages , options = None ) :
    """Remove one or more packages .
 Extra * options * may be passed to ` ` yum ` ` if necessary ."""

implementation:
manager = MANAGER
if options is None :
    options = [ ]
elif isinstance ( options , six . string_types ) :
    options = [ options ]
if not isinstance ( packages , six . string_types ) :
    packages = " " . join ( packages )
options = " " . join ( options )
run_as_root ( '%(manager)s %(options)s remove %(packages)s' % locals ( ) )


signature:
def groupuninstall ( group , options = None ) :
    """Remove an existing software group .
 Extra * options * may be passed to ` ` yum ` ` if necessary ."""

implementation:
manager = MANAGER
if options is None :
    options = [ ]
elif isinstance ( options , str ) :
    options = [ options ]
options = " " . join ( options )
run_as_root ( '%(manager)s %(options)s groupremove "%(group)s"' % locals ( ) )


signature:
def repolist ( status = '' , media = None ) :
    """Get the list of ` ` yum ` ` repositories .
 Returns enabled repositories by default . Extra * status * may be passed
 to list disabled repositories if necessary .
 Media and debug repositories are kept disabled , except if you pass * media * .
 import burlap
 # Install a package that may be included in disabled repositories
 burlap . rpm . install ( ' vim ' , burlap . rpm . repolist ( ' disabled ' ) )"""

implementation:
manager = MANAGER
with settings ( hide ( 'running' , 'stdout' ) ) :
    if media :
        repos = run_as_root ( "%(manager)s repolist %(status)s | sed '$d' | sed -n '/repo id/,$p'" % locals ( ) )
    else :
        repos = run_as_root ( "%(manager)s repolist %(status)s | sed '/Media\\|Debug/d' | sed '$d' | sed -n '/repo id/,$p'" % locals ( ) )
    return [ line . split ( ' ' ) [ 0 ] for line in repos . splitlines ( ) [ 1 : ] ]


signature:
def sync ( self , sync_set , force = 0 , site = None , role = None ) :
    """Uploads media to an Amazon S3 bucket using s3sync .
 Requires s3cmd . Install with :
 pip install s3cmd"""

implementation:
from burlap . dj import dj
force = int ( force )
r = self . local_renderer
r . env . sync_force_flag = ' --force ' if force else ''
_settings = dj . get_settings ( site = site , role = role )
assert _settings , 'Unable to import settings.'
for k in _settings . __dict__ . iterkeys ( ) :
    if k . startswith ( 'AWS_' ) :
        r . genv [ k ] = _settings . __dict__ [ k ]
site_data = r . genv . sites [ r . genv . SITE ]
r . env . update ( site_data )
r . env . virtualenv_bin_dir = os . path . split ( sys . executable ) [ 0 ]
rets = [ ]
for paths in r . env . sync_sets [ sync_set ] :
    is_local = paths . get ( 'is_local' , True )
    local_path = paths [ 'local_path' ] % r . genv
    remote_path = paths [ 'remote_path' ]
    remote_path = remote_path . replace ( ':/' , '/' )
    if not remote_path . startswith ( 's3://' ) :
        remote_path = 's3://' + remote_path
    local_path = local_path % r . genv
    if is_local : # local _ or _ dryrun ( ' which s3sync ' ) # , capture = True )
        r . env . local_path = os . path . abspath ( local_path )
    else : # run ( ' which s3sync ' )
        r . env . local_path = local_path
    if local_path . endswith ( '/' ) and not r . env . local_path . endswith ( '/' ) :
        r . env . local_path = r . env . local_path + '/'
    r . env . remote_path = remote_path % r . genv
    print ( 'Syncing %s to %s...' % ( r . env . local_path , r . env . remote_path ) )
    # Superior Python version .
    if force :
        r . env . sync_cmd = 'put'
    else :
        r . env . sync_cmd = 'sync'
    r . local ( 'export AWS_ACCESS_KEY_ID={aws_access_key_id}; ' 'export AWS_SECRET_ACCESS_KEY={aws_secret_access_key}; ' '{s3cmd_path} {sync_cmd} --progress --acl-public --guess-mime-type --no-mime-magic ' '--delete-removed --cf-invalidate --recursive {sync_force_flag} ' '{local_path} {remote_path}' )


signature:
def invalidate ( self , * paths ) :
    """Issues invalidation requests to a Cloudfront distribution
 for the current static media bucket , triggering it to reload the specified
 paths from the origin .
 Note , only 1000 paths can be issued in a request at any one time ."""

implementation:
dj = self . get_satchel ( 'dj' )
if not paths :
    return
# http : / / boto . readthedocs . org / en / latest / cloudfront _ tut . html
_settings = dj . get_settings ( )
if not _settings . AWS_STATIC_BUCKET_NAME :
    print ( 'No static media bucket set.' )
    return
if isinstance ( paths , six . string_types ) :
    paths = paths . split ( ',' )
all_paths = map ( str . strip , paths )
i = 0
while 1 :
    paths = all_paths [ i : i + 1000 ]
    if not paths :
        break
    c = boto . connect_cloudfront ( )
    rs = c . get_all_distributions ( )
    target_dist = None
    for dist in rs :
        print ( dist . domain_name , dir ( dist ) , dist . __dict__ )
        bucket_name = dist . origin . dns_name . replace ( '.s3.amazonaws.com' , '' )
        if bucket_name == _settings . AWS_STATIC_BUCKET_NAME :
            target_dist = dist
            break
    if not target_dist :
        raise Exception ( ( 'Target distribution %s could not be found in the AWS account.' ) % ( settings . AWS_STATIC_BUCKET_NAME , ) )
    print ( 'Using distribution %s associated with origin %s.' % ( target_dist . id , _settings . AWS_STATIC_BUCKET_NAME ) )
    inval_req = c . create_invalidation_request ( target_dist . id , paths )
    print ( 'Issue invalidation request %s.' % ( inval_req , ) )
    i += 1000


signature:
def get_or_create_bucket ( self , name ) :
    """Gets an S3 bucket of the given name , creating one if it doesn ' t already exist .
 Should be called with a role , if AWS credentials are stored in role settings . e . g .
 fab local s3 . get _ or _ create _ bucket : mybucket"""

implementation:
from boto . s3 import connection
if self . dryrun :
    print ( 'boto.connect_s3().create_bucket(%s)' % repr ( name ) )
else :
    conn = connection . S3Connection ( self . genv . aws_access_key_id , self . genv . aws_secret_access_key )
    bucket = conn . create_bucket ( name )
    return bucket


signature:
def static ( self ) :
    """Configures the server to use a static IP ."""

implementation:
fn = self . render_to_file ( 'ip/ip_interfaces_static.template' )
r = self . local_renderer
r . put ( local_path = fn , remote_path = r . env . interfaces_fn , use_sudo = True )


implementation:
manifest = super ( TarballSatchel , self ) . record_manifest ( )
manifest [ 'timestamp' ] = self . timestamp
return manifest


signature:
def get_thumbprint ( self ) :
    """Calculates the current thumbprint of the item being tracked ."""

implementation:
extensions = self . extensions . split ( ' ' )
name_str = ' -or ' . join ( '-name "%s"' % ext for ext in extensions )
cmd = 'find ' + self . base_dir + r' -type f \( ' + name_str + r' \) -exec md5sum {} \; | sort -k 2 | md5sum'
return getoutput ( cmd )


implementation:
d = { }
if self . names :
    names = self . names
else :
    names = list ( self . satchel . lenv )
for name in self . names :
    d [ name ] = deepcopy ( self . satchel . env [ name ] )
return d


implementation:
d = { }
for tracker in self . trackers :
    d [ type ( tracker ) . __name__ ] = tracker . get_thumbprint ( )
return d


signature:
def upgrade ( safe = True ) :
    """Upgrade all packages ."""

implementation:
manager = MANAGER
if safe :
    cmd = 'upgrade'
else :
    cmd = 'dist-upgrade'
run_as_root ( "%(manager)s --assume-yes %(cmd)s" % locals ( ) , pty = False )


signature:
def is_installed ( pkg_name ) :
    """Check if a package is installed ."""

implementation:
with settings ( hide ( 'running' , 'stdout' , 'stderr' , 'warnings' ) , warn_only = True ) :
    res = run ( "dpkg -s %(pkg_name)s" % locals ( ) )
    for line in res . splitlines ( ) :
        if line . startswith ( "Status: " ) :
            status = line [ 8 : ]
            if "installed" in status . split ( ' ' ) :
                return True
    return False


signature:
def install ( packages , update = False , options = None , version = None ) :
    """Install one or more packages .
 If * update * is ` ` True ` ` , the package definitions will be updated
 first , using : py : func : ` ~ burlap . deb . update _ index ` .
 Extra * options * may be passed to ` ` apt - get ` ` if necessary .
 Example : :
 import burlap
 # Update index , then install a single package
 burlap . deb . install ( ' build - essential ' , update = True )
 # Install multiple packages
 burlap . deb . install ( [
 ' python - dev ' ,
 ' libxml2 - dev ' ,
 # Install a specific version
 burlap . deb . install ( ' emacs ' , version = ' 23.3 + 1-1ubuntu9 ' )"""

implementation:
manager = MANAGER
if update :
    update_index ( )
if options is None :
    options = [ ]
if version is None :
    version = ''
if version and not isinstance ( packages , list ) :
    version = '=' + version
if not isinstance ( packages , six . string_types ) :
    packages = " " . join ( packages )
options . append ( "--quiet" )
options . append ( "--assume-yes" )
options = " " . join ( options )
cmd = '%(manager)s install %(options)s %(packages)s%(version)s' % locals ( )
run_as_root ( cmd , pty = False )


signature:
def uninstall ( packages , purge = False , options = None ) :
    """Remove one or more packages .
 If * purge * is ` ` True ` ` , the package configuration files will be
 removed from the system .
 Extra * options * may be passed to ` ` apt - get ` ` if necessary ."""

implementation:
manager = MANAGER
command = "purge" if purge else "remove"
if options is None :
    options = [ ]
if not isinstance ( packages , six . string_types ) :
    packages = " " . join ( packages )
options . append ( "--assume-yes" )
options = " " . join ( options )
cmd = '%(manager)s %(command)s %(options)s %(packages)s' % locals ( )
run_as_root ( cmd , pty = False )


signature:
def preseed_package ( pkg_name , preseed ) :
    """Enable unattended package installation by preseeding ` ` debconf ` `
 parameters .
 Example : :
 import burlap
 # Unattended install of Postfix mail server
 burlap . deb . preseed _ package ( ' postfix ' , {
 ' postfix / main _ mailer _ type ' : ( ' select ' , ' Internet Site ' ) ,
 ' postfix / mailname ' : ( ' string ' , ' example . com ' ) ,
 ' postfix / destinations ' : ( ' string ' , ' example . com , localhost . localdomain , localhost ' ) ,
 burlap . deb . install ( ' postfix ' )"""

implementation:
for q_name , _ in preseed . items ( ) :
    q_type , q_answer = _
    run_as_root ( 'echo "%(pkg_name)s %(q_name)s %(q_type)s %(q_answer)s" | debconf-set-selections' % locals ( ) )


signature:
def get_selections ( ) :
    """Get the state of ` ` dkpg ` ` selections .
 Returns a dict with state = > [ packages ] ."""

implementation:
with settings ( hide ( 'stdout' ) ) :
    res = run_as_root ( 'dpkg --get-selections' )
selections = dict ( )
for line in res . splitlines ( ) :
    package , status = line . split ( )
    selections . setdefault ( status , list ( ) ) . append ( package )
return selections


signature:
def apt_key_exists ( keyid ) :
    """Check if the given key id exists in apt keyring ."""

implementation:
# Command extracted from apt - key source
gpg_cmd = 'gpg --ignore-time-conflict --no-options --no-default-keyring --keyring /etc/apt/trusted.gpg'
with settings ( hide ( 'everything' ) , warn_only = True ) :
    res = run ( '%(gpg_cmd)s --fingerprint %(keyid)s' % locals ( ) )
return res . succeeded


signature:
def add_apt_key ( filename = None , url = None , keyid = None , keyserver = 'subkeys.pgp.net' , update = False ) :
    """Trust packages signed with this public key .
 Example : :
 import burlap
 # Varnish signing key from URL and verify fingerprint )
 burlap . deb . add _ apt _ key ( keyid = ' C4DEFFEB ' , url = ' http : / / repo . varnish - cache . org / debian / GPG - key . txt ' )
 # Nginx signing key from default key server ( subkeys . pgp . net )
 burlap . deb . add _ apt _ key ( keyid = ' 7BD9BF62 ' )
 # From custom key server
 burlap . deb . add _ apt _ key ( keyid = ' 7BD9BF62 ' , keyserver = ' keyserver . ubuntu . com ' )
 # From a file
 burlap . deb . add _ apt _ key ( keyid = ' 7BD9BF62 ' , filename = ' nginx . asc '"""

implementation:
if keyid is None :
    if filename is not None :
        run_as_root ( 'apt-key add %(filename)s' % locals ( ) )
    elif url is not None :
        run_as_root ( 'wget %(url)s -O - | apt-key add -' % locals ( ) )
    else :
        raise ValueError ( 'Either filename, url or keyid must be provided as argument' )
else :
    if filename is not None :
        _check_pgp_key ( filename , keyid )
        run_as_root ( 'apt-key add %(filename)s' % locals ( ) )
    elif url is not None :
        tmp_key = '/tmp/tmp.burlap.key.%(keyid)s.key' % locals ( )
        run_as_root ( 'wget %(url)s -O %(tmp_key)s' % locals ( ) )
        _check_pgp_key ( tmp_key , keyid )
        run_as_root ( 'apt-key add %(tmp_key)s' % locals ( ) )
    else :
        keyserver_opt = '--keyserver %(keyserver)s' % locals ( ) if keyserver is not None else ''
        run_as_root ( 'apt-key adv %(keyserver_opt)s --recv-keys %(keyid)s' % locals ( ) )
if update :
    update_index ( )


signature:
def configure ( self ) :
    """Enables the repository for a most current version on Debian systems .
 https : / / www . rabbitmq . com / install - debian . html"""

implementation:
os_version = self . os_version
if not self . dryrun and os_version . distro != UBUNTU :
    raise NotImplementedError ( "OS %s is not supported." % os_version )
r = self . local_renderer
r . env . codename = ( r . run ( 'lsb_release -c -s' ) or "`lsb_release -c -s`" ) . strip ( )
r . sudo ( 'apt-add-repository "deb http://download.virtualbox.org/virtualbox/debian {codename} contrib"' )
r . sudo ( 'cd /tmp; wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -' )
r . sudo ( 'apt-get update' )


signature:
def exists ( self , name ) :
    """Check if a group exists ."""

implementation:
with self . settings ( hide ( 'running' , 'stdout' , 'warnings' ) , warn_only = True ) :
    return self . run ( 'getent group %(name)s' % locals ( ) ) . succeeded


signature:
def create ( self , name , gid = None ) :
    """Create a new group .
 Example : :
 import burlap
 if not burlap . group . exists ( ' admin ' ) :
 burlap . group . create ( ' admin ' )"""

implementation:
args = [ ]
if gid :
    args . append ( '-g %s' % gid )
args . append ( name )
args = ' ' . join ( args )
self . sudo ( 'groupadd --force %s || true' % args )


signature:
def enter_password_change ( self , username = None , old_password = None ) :
    """Responds to a forced password change via ` passwd ` prompts due to password expiration ."""

implementation:
from fabric . state import connections
from fabric . network import disconnect_all
r = self . local_renderer
# print ( ' self . genv . user : ' , self . genv . user )
# print ( ' self . env . passwords : ' , self . env . passwords )
r . genv . user = r . genv . user or username
r . pc ( 'Changing password for user {user} via interactive prompts.' )
r . env . old_password = r . env . default_passwords [ self . genv . user ]
# print ( ' self . genv . user : ' , self . genv . user )
# print ( ' self . env . passwords : ' , self . env . passwords )
r . env . new_password = self . env . passwords [ self . genv . user ]
if old_password :
    r . env . old_password = old_password
prompts = { '(current) UNIX password: ' : r . env . old_password , 'Enter new UNIX password: ' : r . env . new_password , 'Retype new UNIX password: ' : r . env . new_password , # " Login password for ' % s ' : " % r . genv . user : r . env . new _ password ,
# " Login password for ' % s ' : " % r . genv . user : r . env . old _ password ,
}
print ( 'prompts:' , prompts )
r . env . password = r . env . old_password
with self . settings ( warn_only = True ) :
    ret = r . _local ( "sshpass -p '{password}' ssh -o StrictHostKeyChecking=no {user}@{host_string} echo hello" , capture = True )
    # code 1 = good password , but prompts needed
    # code 5 = bad password
    # code 6 = good password , but host public key is unknown
if ret . return_code in ( 1 , 6 ) or 'hello' in ret : # Login succeeded , so we haven ' t yet changed the password , so use the default password .
    self . genv . password = r . env . old_password
elif self . genv . user in self . genv . user_passwords : # Otherwise , use the password or key set in the config .
    self . genv . password = r . env . new_password
else : # Default password fails and there ' s no current password , so clear .
    self . genv . password = None
print ( 'using password:' , self . genv . password )
# Note , the correct current password should be set in host . initrole ( ) , not here .
# r . genv . password = r . env . new _ password
# r . genv . password = r . env . new _ password
with self . settings ( prompts = prompts ) :
    ret = r . _run ( 'echo checking for expired password' )
    print ( 'ret:[%s]' % ret )
    do_disconnect = 'passwd: password updated successfully' in ret
    print ( 'do_disconnect:' , do_disconnect )
    if do_disconnect : # We need to disconnect to reset the session or else Linux will again prompt
    # us to change our password .
        disconnect_all ( )
        # Further logins should require the new password .
        self . genv . password = r . env . new_password


signature:
def togroups ( self , user , groups ) :
    """Adds the user to the given list of groups ."""

implementation:
r = self . local_renderer
if isinstance ( groups , six . string_types ) :
    groups = [ _ . strip ( ) for _ in groups . split ( ',' ) if _ . strip ( ) ]
for group in groups :
    r . env . username = user
    r . env . group = group
    r . sudo ( 'groupadd --force {group}' )
    r . sudo ( 'adduser {username} {group}' )


signature:
def passwordless ( self , username , pubkey ) :
    """Configures the user to use an SSL key without a password .
 Assumes you ' ve run generate _ keys ( ) first ."""

implementation:
r = self . local_renderer
r . env . username = username
r . env . pubkey = pubkey
if not self . dryrun :
    assert os . path . isfile ( r . env . pubkey ) , 'Public key file "%s" does not exist.' % ( str ( r . env . pubkey ) , )
first = os . path . splitext ( r . env . pubkey ) [ 0 ]
r . env . pubkey = first + '.pub'
r . env . pemkey = first + '.pem'
r . env . home = r . env . home_template . format ( username = username )
# Upload the SSH key .
r . sudo ( 'mkdir -p {home}/.ssh' )
r . sudo ( 'chown -R {user}:{user} {home}/.ssh' )
if r . env . passwordless_method == UPLOAD_KEY :
    put_remote_paths = self . put ( local_path = r . env . pubkey )
    r . env . put_remote_path = put_remote_paths [ 0 ]
    r . sudo ( 'cat {put_remote_path} >> {home}/.ssh/authorized_keys' )
    r . sudo ( 'rm -f {put_remote_path}' )
elif r . env . passwordless_method == CAT_KEY :
    r . env . password = r . env . default_passwords . get ( r . env . username , r . genv . password )
    if r . env . password :
        r . local ( "cat {pubkey} | sshpass -p '{password}' ssh {user}@{host_string} 'cat >> {home}/.ssh/authorized_keys'" )
    else :
        r . local ( "cat {pubkey} | ssh {user}@{host_string} 'cat >> {home}/.ssh/authorized_keys'" )
else :
    raise NotImplementedError
# Disable password .
r . sudo ( 'cp /etc/sudoers {tmp_sudoers_fn}' )
r . sudo ( 'echo "{username} ALL=(ALL) NOPASSWD: ALL" >> {tmp_sudoers_fn}' )
r . sudo ( 'sudo EDITOR="cp {tmp_sudoers_fn}" visudo' )
r . sudo ( 'service ssh reload' )
print ( 'You should now be able to login with:' )
r . env . host_string = self . genv . host_string or ( self . genv . hosts and self . genv . hosts [ 0 ] )
# self . genv . hostname _ hostname
r . comment ( '\tssh -i {pemkey} {username}@{host_string}' )


signature:
def generate_keys ( self , username , hostname ) :
    """Generates * . pem and * . pub key files suitable for setting up passwordless SSH ."""

implementation:
r = self . local_renderer
# r . env . key _ filename = r . env . key _ filename or env . key _ filename
# assert r . env . key _ filename , ' r . env . key _ filename or env . key _ filename must be set . e . g . roles / role / app _ name - role . pem '
r . env . key_filename = self . env . key_filename_template . format ( ROLE = self . genv . ROLE , host = hostname , username = username , )
if os . path . isfile ( r . env . key_filename ) :
    r . pc ( 'Key file {key_filename} already exists. Skipping generation.' . format ( ** r . env ) )
else :
    r . local ( "ssh-keygen -t {key_type} -b {key_bits} -f {key_filename} -N ''" )
    r . local ( 'chmod {key_perms} {key_filename}' )
    if r . env . key_filename . endswith ( '.pem' ) :
        src = r . env . key_filename + '.pub'
        dst = ( r . env . key_filename + '.pub' ) . replace ( '.pem' , '' )
        # print ( ' generate _ keys : ' , src , dst )
        r . env . src = src
        r . env . dst = dst
        r . local ( 'mv {src} {dst}' )
return r . env . key_filename


signature:
def create ( self , username , groups = None , uid = None , create_home = None , system = False , password = None , home_dir = None ) :
    """Creates a user with the given username ."""

implementation:
r = self . local_renderer
r . env . username = username
args = [ ]
if uid :
    args . append ( '-u %s' % uid )
if create_home is None :
    create_home = not system
if create_home is True :
    if home_dir :
        args . append ( '--home %s' % home_dir )
elif create_home is False :
    args . append ( '--no-create-home' )
if password is None :
    pass
elif password :
    crypted_password = _crypt_password ( password )
    args . append ( '-p %s' % quote ( crypted_password ) )
else :
    args . append ( '--disabled-password' )
args . append ( '--gecos ""' )
if system :
    args . append ( '--system' )
r . env . args = ' ' . join ( args )
r . env . groups = ( groups or '' ) . strip ( )
r . sudo ( 'adduser {args} {username} || true' )
if groups :
    for group in groups . split ( ' ' ) :
        group = group . strip ( )
        if not group :
            continue
        r . sudo ( 'adduser %s %s || true' % ( username , group ) )


signature:
def expire_password ( self , username ) :
    """Forces the user to change their password the next time they login ."""

implementation:
r = self . local_renderer
r . env . username = username
r . sudo ( 'chage -d 0 {username}' )


signature:
def run_as_root ( command , * args , ** kwargs ) :
    """Run a remote command as the root user .
 When connecting as root to the remote system , this will use Fabric ' s
 ` ` run ` ` function . In other cases , it will use ` ` sudo ` ` ."""

implementation:
from burlap . common import run_or_dryrun , sudo_or_dryrun
if env . user == 'root' :
    func = run_or_dryrun
else :
    func = sudo_or_dryrun
return func ( command , * args , ** kwargs )


signature:
def oct ( v , ** kwargs ) : # pylint : disable = redefined - builtin
    """A backwards compatible version of oct ( ) that works with Python2.7 and Python3."""

implementation:
v = str ( v )
if six . PY2 :
    if v . startswith ( '0o' ) :
        v = '0' + v [ 2 : ]
else :
    if not v . starswith ( '0o' ) :
        assert v [ 0 ] == '0'
        v = '0o' + v [ 1 : ]
return eval ( '_oct(%s, **kwargs)' % v )


signature:
def get_file_hash ( fin , block_size = 2 ** 20 ) :
    """Iteratively builds a file hash without loading the entire file into memory .
 Designed to process an arbitrary binary file ."""

implementation:
if isinstance ( fin , six . string_types ) :
    fin = open ( fin )
h = hashlib . sha512 ( )
while True :
    data = fin . read ( block_size )
    if not data :
        break
    try :
        h . update ( data )
    except TypeError : # Fixes Python3 error " TypeError : Unicode - objects must be encoded before hashing " .
        h . update ( data . encode ( 'utf-8' ) )
return h . hexdigest ( )


signature:
def check ( self ) :
    """Run inadyn from the commandline to test the configuration .
 To be run like :
 fab role inadyn . check"""

implementation:
self . _validate_settings ( )
r = self . local_renderer
r . env . alias = r . env . aliases [ 0 ]
r . sudo ( r . env . check_command_template )


signature:
def list_env ( self , key = None ) :
    """Displays a list of environment key / value pairs ."""

implementation:
for k , v in sorted ( self . genv . items ( ) , key = lambda o : o [ 0 ] ) :
    if key and k != key :
        continue
    print ( '%s ' % ( k , ) )
    pprint ( v , indent = 4 )


signature:
def list_server_specs ( self , cpu = 1 , memory = 1 , hdd = 1 ) :
    """Displays a list of common servers characteristics , like number
 of CPU cores , amount of memory and hard drive capacity ."""

implementation:
r = self . local_renderer
cpu = int ( cpu )
memory = int ( memory )
hdd = int ( hdd )
# CPU
if cpu :
    cmd = 'cat /proc/cpuinfo | grep -i "model name"'
    ret = r . run ( cmd )
    matches = map ( str . strip , re . findall ( r'model name\s+:\s*([^\n]+)' , ret , re . DOTALL | re . I ) )
    cores = { }
    for match in matches :
        cores . setdefault ( match , 0 )
        cores [ match ] += 1
# Memory
if memory :
    cmd = 'dmidecode --type 17'
    ret = r . sudo ( cmd )
    # print repr ( ret )
    matches = re . findall ( r'Memory\s+Device\r\n(.*?)(?:\r\n\r\n|$)' , ret , flags = re . DOTALL | re . I )
    # print len ( matches )
    # print matches [ 0]
    memory_slot_dicts = [ ]
    for match in matches :
        attrs = dict ( [ ( _a . strip ( ) , _b . strip ( ) ) for _a , _b in re . findall ( r'^([^:]+):\s+(.*)$' , match , flags = re . MULTILINE ) ] )
        # print attrs
        memory_slot_dicts . append ( attrs )
    total_memory_gb = 0
    total_slots_filled = 0
    total_slots = len ( memory_slot_dicts )
    memory_types = set ( )
    memory_forms = set ( )
    memory_speeds = set ( )
    for memory_dict in memory_slot_dicts :
        try :
            size = int ( round ( float ( re . findall ( r'([0-9]+)\s+MB' , memory_dict [ 'Size' ] ) [ 0 ] ) / 1024. ) )
            # print size
            total_memory_gb += size
            total_slots_filled += 1
        except IndexError :
            pass
        _v = memory_dict [ 'Type' ]
        if _v != 'Unknown' :
            memory_types . add ( _v )
        _v = memory_dict [ 'Form Factor' ]
        if _v != 'Unknown' :
            memory_forms . add ( _v )
        # _ v = memory _ dict [ ' Speed ' ]
        # if _ v ! = ' Unknown ' :
        # memory _ speeds . add ( _ v )
# Storage
if hdd : # cmd = ' ls / dev / * d * | grep " / dev / [ a - z ] + d [ a - z ] $ " '
    cmd = 'find /dev -maxdepth 1 | grep -E "/dev/[a-z]+d[a-z]$"'
    devices = map ( str . strip , r . run ( cmd ) . split ( '\n' ) )
    total_drives = len ( devices )
    total_physical_storage_gb = 0
    total_logical_storage_gb = 0
    drive_transports = set ( )
    for device in devices : # cmd = ' udisks - - show - info % s | grep - i " size : " ' % ( device )
        cmd = 'udisksctl info -b %s |grep -i "  size:"' % ( device )
        ret = r . run ( cmd )
        size_bytes = float ( re . findall ( r'size:\s*([0-9]+)' , ret , flags = re . I ) [ 0 ] . strip ( ) )
        size_gb = int ( round ( size_bytes / 1024 / 1024 / 1024 ) )
        # print device , size _ gb
        total_physical_storage_gb += size_gb
        with self . settings ( warn_only = True ) :
            cmd = 'hdparm -I %s|grep -i "Transport:"' % device
            ret = self . sudo ( cmd )
            if ret and not ret . return_code :
                drive_transports . add ( ret . split ( 'Transport:' ) [ - 1 ] . strip ( ) )
    cmd = "df | grep '^/dev/[mhs]d*' | awk '{{s+=$2}} END {{print s/1048576}}'"
    ret = r . run ( cmd )
    total_logical_storage_gb = float ( ret )
if cpu :
    print ( '-' * 80 )
    print ( 'CPU' )
    print ( '-' * 80 )
    type_str = ', ' . join ( [ '%s x %i' % ( _type , _count ) for _type , _count in cores . items ( ) ] )
    print ( 'Cores: %i' % sum ( cores . values ( ) ) )
    print ( 'Types: %s' % type_str )
if memory :
    print ( '-' * 80 )
    print ( 'MEMORY' )
    print ( '-' * 80 )
    print ( 'Total: %s GB' % total_memory_gb )
    print ( 'Type: %s' % list_to_str_or_unknown ( memory_types ) )
    print ( 'Form: %s' % list_to_str_or_unknown ( memory_forms ) )
    print ( 'Speed: %s' % list_to_str_or_unknown ( memory_speeds ) )
    print ( 'Slots: %i (%i filled, %i empty)' % ( total_slots , total_slots_filled , total_slots - total_slots_filled ) )
if hdd :
    print ( '-' * 80 )
    print ( 'STORAGE' )
    print ( '-' * 80 )
    print ( 'Total physical drives: %i' % total_drives )
    print ( 'Total physical storage: %s GB' % total_physical_storage_gb )
    print ( 'Total logical storage: %s GB' % total_logical_storage_gb )
    print ( 'Types: %s' % list_to_str_or_unknown ( drive_transports ) )


signature:
def shell ( self , gui = 0 , command = '' , dryrun = None , shell_interactive_cmd_str = None ) :
    """Opens an SSH connection ."""

implementation:
from burlap . common import get_hosts_for_site
if dryrun is not None :
    self . dryrun = dryrun
r = self . local_renderer
if r . genv . SITE != r . genv . default_site :
    shell_hosts = get_hosts_for_site ( )
    if shell_hosts :
        r . genv . host_string = shell_hosts [ 0 ]
r . env . SITE = r . genv . SITE or r . genv . default_site
if int ( gui ) :
    r . env . shell_default_options . append ( '-X' )
if 'host_string' not in self . genv or not self . genv . host_string :
    if 'available_sites' in self . genv and r . env . SITE not in r . genv . available_sites :
        raise Exception ( 'No host_string set. Unknown site %s.' % r . env . SITE )
    else :
        raise Exception ( 'No host_string set.' )
if '@' in r . genv . host_string :
    r . env . shell_host_string = r . genv . host_string
else :
    r . env . shell_host_string = '{user}@{host_string}'
if command :
    r . env . shell_interactive_cmd_str = command
else :
    r . env . shell_interactive_cmd_str = r . format ( shell_interactive_cmd_str or r . env . shell_interactive_cmd )
r . env . shell_default_options_str = ' ' . join ( r . env . shell_default_options )
if self . is_local :
    self . vprint ( 'Using direct local.' )
    cmd = '{shell_interactive_cmd_str}'
elif r . genv . key_filename :
    self . vprint ( 'Using key filename.' )
    # If host _ string contains the port , then strip it off and pass separately .
    port = r . env . shell_host_string . split ( ':' ) [ - 1 ]
    if port . isdigit ( ) :
        r . env . shell_host_string = r . env . shell_host_string . split ( ':' ) [ 0 ] + ( ' -p %s' % port )
    cmd = 'ssh -t {shell_default_options_str} -i {key_filename} {shell_host_string} "{shell_interactive_cmd_str}"'
elif r . genv . password :
    self . vprint ( 'Using password.' )
    cmd = 'ssh -t {shell_default_options_str} {shell_host_string} "{shell_interactive_cmd_str}"'
else : # No explicit password or key file needed ?
    self . vprint ( 'Using nothing.' )
    cmd = 'ssh -t {shell_default_options_str} {shell_host_string} "{shell_interactive_cmd_str}"'
r . local ( cmd )


signature:
def disk ( self ) :
    """Display percent of disk usage ."""

implementation:
r = self . local_renderer
r . run ( r . env . disk_usage_command )


signature:
def tunnel ( self , local_port , remote_port ) :
    """Creates an SSH tunnel ."""

implementation:
r = self . local_renderer
r . env . tunnel_local_port = local_port
r . env . tunnel_remote_port = remote_port
r . local ( ' ssh -i {key_filename} -L {tunnel_local_port}:localhost:{tunnel_remote_port} {user}@{host_string} -N' )


signature:
def set_satchel_value ( self , satchel , key , value ) :
    """Sets a key / value pair in a satchel ' s local renderer ."""

implementation:
satchel = self . get_satchel ( satchel )
r = satchel . local_renderer
setattr ( r . env , key , value )
print ( 'Set %s=%s in satchel %s.' % ( key , value , satchel . name ) )


signature:
def package_version ( name , python_cmd = 'python' ) :
    """Get the installed version of a package
 Returns ` ` None ` ` if it can ' t be found ."""

implementation:
cmd = '''%(python_cmd)s -c \
        "import pkg_resources;\
        dist = pkg_resources.get_distribution('%(name)s');\
        print dist.version"
        ''' % locals ( )
res = run ( cmd , quiet = True )
if res . succeeded :
    return res
return


signature:
def install_setuptools ( python_cmd = 'python' , use_sudo = True ) :
    """Install the latest version of ` setuptools ` _ .
 import burlap
 burlap . python _ setuptools . install _ setuptools ( )"""

implementation:
setuptools_version = package_version ( 'setuptools' , python_cmd )
distribute_version = package_version ( 'distribute' , python_cmd )
if setuptools_version is None :
    _install_from_scratch ( python_cmd , use_sudo )
else :
    if distribute_version is None :
        _upgrade_from_setuptools ( python_cmd , use_sudo )
    else :
        _upgrade_from_distribute ( python_cmd , use_sudo )


signature:
def _install_from_scratch ( python_cmd , use_sudo ) :
    """Install setuptools from scratch using installer"""

implementation:
with cd ( "/tmp" ) :
    download ( EZ_SETUP_URL )
    command = '%(python_cmd)s ez_setup.py' % locals ( )
    if use_sudo :
        run_as_root ( command )
    else :
        run ( command )
    run ( 'rm -f ez_setup.py' )


signature:
def install ( packages , upgrade = False , use_sudo = False , python_cmd = 'python' ) :
    """Install Python packages with ` ` easy _ install ` ` .
 Examples : :
 import burlap
 # Install a single package
 burlap . python _ setuptools . install ( ' package ' , use _ sudo = True )
 # Install a list of packages
 burlap . python _ setuptools . install ( [ ' pkg1 ' , ' pkg2 ' ] , use _ sudo = True )
 . . note : : most of the time , you ' ll want to use
 : py : func : ` burlap . python . install ( ) ` instead ,
 which uses ` ` pip ` ` to install packages ."""

implementation:
argv = [ ]
if upgrade :
    argv . append ( "-U" )
if isinstance ( packages , six . string_types ) :
    argv . append ( packages )
else :
    argv . extend ( packages )
_easy_install ( argv , python_cmd , use_sudo )


signature:
def _easy_install ( argv , python_cmd , use_sudo ) :
    """Install packages using easy _ install
 We don ' t know if the easy _ install command in the path will be the
 right one , so we use the setuptools entry point to call the script ' s
 main function ourselves ."""

implementation:
command = """python -c "\
        from pkg_resources import load_entry_point;\
        ez = load_entry_point('setuptools', 'console_scripts', 'easy_install');\
        ez(argv=%(argv)r)\
    """ % locals ( )
if use_sudo :
    run_as_root ( command )
else :
    run ( command )


signature:
def bootstrap ( self , force = 0 ) :
    """Installs all the necessary packages necessary for managing virtual
 environments with pip ."""

implementation:
force = int ( force )
if self . has_pip ( ) and not force :
    return
r = self . local_renderer
if r . env . bootstrap_method == GET_PIP :
    r . sudo ( 'curl --silent --show-error --retry 5 https://bootstrap.pypa.io/get-pip.py | python' )
elif r . env . bootstrap_method == EZ_SETUP :
    r . run ( 'wget http://peak.telecommunity.com/dist/ez_setup.py -O /tmp/ez_setup.py' )
    with self . settings ( warn_only = True ) :
        r . sudo ( 'python /tmp/ez_setup.py -U setuptools' )
    r . sudo ( 'easy_install -U pip' )
elif r . env . bootstrap_method == PYTHON_PIP :
    r . sudo ( 'apt-get install -y python-pip' )
else :
    raise NotImplementedError ( 'Unknown pip bootstrap method: %s' % r . env . bootstrap_method )
r . sudo ( 'pip {quiet_flag} install --upgrade pip' )
r . sudo ( 'pip {quiet_flag} install --upgrade virtualenv' )


signature:
def has_virtualenv ( self ) :
    """Returns true if the virtualenv tool is installed ."""

implementation:
with self . settings ( warn_only = True ) :
    ret = self . run_or_local ( 'which virtualenv' ) . strip ( )
    return bool ( ret )


signature:
def virtualenv_exists ( self , virtualenv_dir = None ) :
    """Returns true if the virtual environment has been created ."""

implementation:
r = self . local_renderer
ret = True
with self . settings ( warn_only = True ) :
    ret = r . run_or_local ( 'ls {virtualenv_dir}' ) or ''
    ret = 'cannot access' not in ret . strip ( ) . lower ( )
if self . verbose :
    if ret :
        print ( 'Yes' )
    else :
        print ( 'No' )
return ret


signature:
def what_requires ( self , name ) :
    """Lists the packages that require the given package ."""

implementation:
r = self . local_renderer
r . env . name = name
r . local ( 'pipdeptree -p {name} --reverse' )


signature:
def init ( self ) :
    """Creates the virtual environment ."""

implementation:
r = self . local_renderer
# if self . virtualenv _ exists ( ) :
# print ( ' virtualenv exists ' )
# return
print ( 'Creating new virtual environment...' )
with self . settings ( warn_only = True ) :
    cmd = '[ ! -d {virtualenv_dir} ] && virtualenv --no-site-packages {virtualenv_dir} || true'
    if self . is_local :
        r . run_or_local ( cmd )
    else :
        r . sudo ( cmd )


signature:
def get_combined_requirements ( self , requirements = None ) :
    """Returns all requirements files combined into one string ."""

implementation:
requirements = requirements or self . env . requirements
def iter_lines ( fn ) :
    with open ( fn , 'r' ) as fin :
        for line in fin . readlines ( ) :
            line = line . strip ( )
            if not line or line . startswith ( '#' ) :
                continue
            yield line
content = [ ]
if isinstance ( requirements , ( tuple , list ) ) :
    for f in requirements :
        f = self . find_template ( f )
        content . extend ( list ( iter_lines ( f ) ) )
else :
    assert isinstance ( requirements , six . string_types )
    f = self . find_template ( requirements )
    content . extend ( list ( iter_lines ( f ) ) )
return '\n' . join ( content )


signature:
def record_manifest ( self ) :
    """Called after a deployment to record any data necessary to detect changes
 for a future deployment ."""

implementation:
manifest = super ( PIPSatchel , self ) . record_manifest ( )
manifest [ 'all-requirements' ] = self . get_combined_requirements ( )
if self . verbose :
    pprint ( manifest , indent = 4 )
return manifest


signature:
def list_instances ( show = 1 , name = None , group = None , release = None , except_release = None ) :
    """Retrieves all virtual machines instances in the current environment ."""

implementation:
from burlap . common import shelf , OrderedDict , get_verbose
verbose = get_verbose ( )
require ( 'vm_type' , 'vm_group' )
assert env . vm_type , 'No VM type specified.'
env . vm_type = ( env . vm_type or '' ) . lower ( )
_name = name
_group = group
_release = release
if verbose :
    print ( 'name=%s, group=%s, release=%s' % ( _name , _group , _release ) )
env . vm_elastic_ip_mappings = shelf . get ( 'vm_elastic_ip_mappings' )
data = type ( env ) ( )
if env . vm_type == EC2 :
    if verbose :
        print ( 'Checking EC2...' )
    for instance in get_all_running_ec2_instances ( ) :
        name = instance . tags . get ( env . vm_name_tag )
        group = instance . tags . get ( env . vm_group_tag )
        release = instance . tags . get ( env . vm_release_tag )
        if env . vm_group and env . vm_group != group :
            if verbose :
                print ( ( 'Skipping instance %s because its group "%s" ' 'does not match env.vm_group "%s".' ) % ( instance . public_dns_name , group , env . vm_group ) )
            continue
        if _group and group != _group :
            if verbose :
                print ( ( 'Skipping instance %s because its group "%s" ' 'does not match local group "%s".' ) % ( instance . public_dns_name , group , _group ) )
            continue
        if _name and name != _name :
            if verbose :
                print ( ( 'Skipping instance %s because its name "%s" ' 'does not match name "%s".' ) % ( instance . public_dns_name , name , _name ) )
            continue
        if _release and release != _release :
            if verbose :
                print ( ( 'Skipping instance %s because its release "%s" ' 'does not match release "%s".' ) % ( instance . public_dns_name , release , _release ) )
            continue
        if except_release and release == except_release :
            continue
        if verbose :
            print ( 'Adding instance %s (%s).' % ( name , instance . public_dns_name ) )
        data . setdefault ( name , type ( env ) ( ) )
        data [ name ] [ 'id' ] = instance . id
        data [ name ] [ 'public_dns_name' ] = instance . public_dns_name
        if verbose :
            print ( 'Public DNS: %s' % instance . public_dns_name )
        if env . vm_elastic_ip_mappings and name in env . vm_elastic_ip_mappings :
            data [ name ] [ 'ip' ] = env . vm_elastic_ip_mappings [ name ]
        else :
            data [ name ] [ 'ip' ] = socket . gethostbyname ( instance . public_dns_name )
    if int ( show ) :
        pprint ( data , indent = 4 )
    return data
elif env . vm_type == KVM : # virsh list
    pass
else :
    raise NotImplementedError


signature:
def get_or_create_ec2_security_groups ( names = None , verbose = 1 ) :
    """Creates a security group opening 22 , 80 and 443"""

implementation:
verbose = int ( verbose )
if verbose :
    print ( 'Creating EC2 security groups...' )
conn = get_ec2_connection ( )
if isinstance ( names , six . string_types ) :
    names = names . split ( ',' )
names = names or env . vm_ec2_selected_security_groups
if verbose :
    print ( 'Group names:' , names )
ret = [ ]
for name in names :
    try :
        group_id = get_ec2_security_group_id ( name )
        if verbose :
            print ( 'group_id:' , group_id )
        # group = conn . get _ all _ security _ groups ( groupnames = [ name ] ) [ 0]
        # Note , groups in a VPC can ' t be referred to by name ?
        group = conn . get_all_security_groups ( group_ids = [ group_id ] ) [ 0 ]
    except boto . exception . EC2ResponseError as e :
        if verbose :
            print ( e )
        group = get_ec2_connection ( ) . create_security_group ( name , name , vpc_id = env . vm_ec2_vpc_id , )
        print ( 'group_id:' , group . id )
        set_ec2_security_group_id ( name , group . id )
    ret . append ( group )
    # Find existing rules .
    actual_sets = set ( )
    for rule in list ( group . rules ) :
        ip_protocol = rule . ip_protocol
        from_port = rule . from_port
        to_port = rule . to_port
        for cidr_ip in rule . grants : # print ( ' Revoking : ' , ip _ protocol , from _ port , to _ port , cidr _ ip )
        # group . revoke ( ip _ protocol , from _ port , to _ port , cidr _ ip )
            rule_groups = ( ( rule . groups and rule . groups . split ( ',' ) ) or [ None ] )
            for src_group in rule_groups :
                src_group = ( src_group or '' ) . strip ( )
                if src_group :
                    actual_sets . add ( ( ip_protocol , from_port , to_port , str ( cidr_ip ) , src_group ) )
                else :
                    actual_sets . add ( ( ip_protocol , from_port , to_port , str ( cidr_ip ) ) )
    # Find actual rules .
    expected_sets = set ( )
    for authorization in env . vm_ec2_available_security_groups . get ( name , [ ] ) :
        if verbose :
            print ( 'authorization:' , authorization )
        if len ( authorization ) == 4 or ( len ( authorization ) == 5 and not ( authorization [ - 1 ] or '' ) . strip ( ) ) :
            src_group = None
            ip_protocol , from_port , to_port , cidr_ip = authorization [ : 4 ]
            if cidr_ip :
                expected_sets . add ( ( ip_protocol , str ( from_port ) , str ( to_port ) , cidr_ip ) )
        else :
            ip_protocol , from_port , to_port , cidr_ip , src_group = authorization
            if cidr_ip :
                expected_sets . add ( ( ip_protocol , str ( from_port ) , str ( to_port ) , cidr_ip , src_group ) )
    # Calculate differences and update rules if we own the group .
    if env . vm_ec2_security_group_owner :
        if verbose :
            print ( 'expected_sets:' )
            print ( expected_sets )
            print ( 'actual_sets:' )
            print ( actual_sets )
        del_sets = actual_sets . difference ( expected_sets )
        if verbose :
            print ( 'del_sets:' )
            print ( del_sets )
        add_sets = expected_sets . difference ( actual_sets )
        if verbose :
            print ( 'add_sets:' )
            print ( add_sets )
        # Revoke deleted .
        for auth in del_sets :
            print ( len ( auth ) )
            print ( 'revoking:' , auth )
            group . revoke ( * auth )
        # Create fresh rules .
        for auth in add_sets :
            print ( 'authorizing:' , auth )
            group . authorize ( * auth )
return ret


signature:
def get_or_create_ec2_key_pair ( name = None , verbose = 1 ) :
    """Creates and saves an EC2 key pair to a local PEM file ."""

implementation:
verbose = int ( verbose )
name = name or env . vm_ec2_keypair_name
pem_path = 'roles/%s/%s.pem' % ( env . ROLE , name )
conn = get_ec2_connection ( )
kp = conn . get_key_pair ( name )
if kp :
    print ( 'Key pair %s already exists.' % name )
else : # Note , we only get the private key during creation .
# If we don ' t save it here , it ' s lost forever .
    kp = conn . create_key_pair ( name )
    open ( pem_path , 'wb' ) . write ( kp . material )
    os . system ( 'chmod 600 %s' % pem_path )
    print ( 'Key pair %s created.' % name )
# return kp
return pem_path


signature:
def get_or_create_ec2_instance ( name = None , group = None , release = None , verbose = 0 , backend_opts = None ) :
    """Creates a new EC2 instance .
 You should normally run get _ or _ create ( ) instead of directly calling this ."""

implementation:
from burlap . common import shelf , OrderedDict
from boto . exception import EC2ResponseError
assert name , "A name must be specified."
backend_opts = backend_opts or { }
verbose = int ( verbose )
conn = get_ec2_connection ( )
security_groups = get_or_create_ec2_security_groups ( )
security_group_ids = [ _ . id for _ in security_groups ]
if verbose :
    print ( 'security_groups:' , security_group_ids )
pem_path = get_or_create_ec2_key_pair ( )
assert env . vm_ec2_ami , 'No AMI specified.'
print ( 'Creating EC2 instance from %s...' % ( env . vm_ec2_ami , ) )
print ( env . vm_ec2_zone )
opts = backend_opts . get ( 'run_instances' , { } )
reservation = conn . run_instances ( env . vm_ec2_ami , key_name = env . vm_ec2_keypair_name , # security _ groups = env . vm _ ec2 _ selected _ security _ groups , # conflicts with subnet _ id ? !
security_group_ids = security_group_ids , placement = env . vm_ec2_zone , instance_type = env . vm_ec2_instance_type , subnet_id = env . vm_ec2_subnet_id , ** opts )
instance = reservation . instances [ 0 ]
# Name new instance .
# Note , creation is not instantious , so we may have to wait for a moment
# before we can access it .
while 1 :
    try :
        if name :
            instance . add_tag ( env . vm_name_tag , name )
        if group :
            instance . add_tag ( env . vm_group_tag , group )
        if release :
            instance . add_tag ( env . vm_release_tag , release )
        break
    except EC2ResponseError as e : # print ( ' Unable to set tag : % s ' % e )
        print ( 'Waiting for the instance to be created...' )
        if verbose :
            print ( e )
        time . sleep ( 3 )
# Assign IP .
allocation_id = None
if env . vm_ec2_use_elastic_ip : # Initialize name / ip mapping since we can ' t tag elastic IPs .
    shelf . setdefault ( 'vm_elastic_ip_mappings' , OrderedDict ( ) )
    vm_elastic_ip_mappings = shelf . get ( 'vm_elastic_ip_mappings' )
    elastic_ip = vm_elastic_ip_mappings . get ( name )
    if not elastic_ip :
        print ( 'Allocating new elastic IP address...' )
        addr = conn . allocate_address ( domain = env . vm_ec2_allocate_address_domain )
        # allocation _ id = addr . allocation _ id
        # print ( ' allocation _ id : ' , allocation _ id )
        elastic_ip = addr . public_ip
        print ( 'Allocated address %s.' % elastic_ip )
        vm_elastic_ip_mappings [ name ] = str ( elastic_ip )
        shelf . set ( 'vm_elastic_ip_mappings' , vm_elastic_ip_mappings )
        # conn . get _ all _ addresses ( )
    # Lookup allocation _ id .
    all_eips = conn . get_all_addresses ( )
    for eip in all_eips :
        if elastic_ip == eip . public_ip :
            allocation_id = eip . allocation_id
            break
    print ( 'allocation_id:' , allocation_id )
    while 1 :
        try :
            conn . associate_address ( instance_id = instance . id , # public _ ip = elastic _ ip ,
            allocation_id = allocation_id , # needed for VPC instances
            )
            print ( 'IP address associated!' )
            break
        except EC2ResponseError as e : # print ( ' Unable to assign IP : % s ' % e )
            print ( 'Waiting to associate IP address...' )
            if verbose :
                print ( e )
            time . sleep ( 3 )
# Confirm public DNS name was assigned .
while 1 :
    try :
        instance = get_all_ec2_instances ( instance_ids = [ instance . id ] ) [ 0 ]
        # assert instance . public _ dns _ name , ' No public DNS name found ! '
        if instance . public_dns_name :
            break
    except Exception as e :
        print ( 'error:' , e )
    except SystemExit as e :
        print ( 'systemexit:' , e )
    print ( 'Waiting for public DNS name to be assigned...' )
    time . sleep ( 3 )
# Confirm we can SSH into the server .
# TODO : better handle timeouts ? try / except doesn ' t really work ?
env . connection_attempts = 10
while 1 :
    try :
        with settings ( warn_only = True ) :
            env . host_string = instance . public_dns_name
            ret = run_or_dryrun ( 'who -b' )
            # print ' ret . return _ code : ' , ret . return _ code
            if not ret . return_code :
                break
    except Exception as e :
        print ( 'error:' , e )
    except SystemExit as e :
        print ( 'systemexit:' , e )
    print ( 'Waiting for sshd to accept connections...' )
    time . sleep ( 3 )
print ( "" )
print ( "Login with: ssh -o StrictHostKeyChecking=no -i %s %s@%s" % ( pem_path , env . user , instance . public_dns_name ) )
print ( "OR" )
print ( "fab %(ROLE)s:hostname=%(name)s shell" % dict ( name = name , ROLE = env . ROLE ) )
ip = socket . gethostbyname ( instance . public_dns_name )
print ( "" )
print ( """Example hosts entry:)
%(ip)s    www.mydomain.com # %(name)s""" % dict ( ip = ip , name = name ) )
return instance


signature:
def exists ( name = None , group = None , release = None , except_release = None , verbose = 1 ) :
    """Determines if a virtual machine instance exists ."""

implementation:
verbose = int ( verbose )
instances = list_instances ( name = name , group = group , release = release , except_release = except_release , verbose = verbose , show = verbose )
ret = bool ( instances )
if verbose :
    print ( '\ninstance %s exist' % ( 'DOES' if ret else 'does NOT' ) )
# return ret
return instances


signature:
def get_or_create ( name = None , group = None , config = None , extra = 0 , verbose = 0 , backend_opts = None ) :
    """Creates a virtual machine instance ."""

implementation:
require ( 'vm_type' , 'vm_group' )
backend_opts = backend_opts or { }
verbose = int ( verbose )
extra = int ( extra )
if config :
    config_fn = common . find_template ( config )
    config = yaml . load ( open ( config_fn ) )
    env . update ( config )
env . vm_type = ( env . vm_type or '' ) . lower ( )
assert env . vm_type , 'No VM type specified.'
group = group or env . vm_group
assert group , 'No VM group specified.'
ret = exists ( name = name , group = group )
if not extra and ret :
    if verbose :
        print ( 'VM %s:%s exists.' % ( name , group ) )
    return ret
today = datetime . date . today ( )
release = int ( '%i%02i%02i' % ( today . year , today . month , today . day ) )
if not name :
    existing_instances = list_instances ( group = group , release = release , verbose = verbose )
    name = env . vm_name_template . format ( index = len ( existing_instances ) + 1 )
if env . vm_type == EC2 :
    return get_or_create_ec2_instance ( name = name , group = group , release = release , verbose = verbose , backend_opts = backend_opts )
else :
    raise NotImplementedError


signature:
def delete ( name = None , group = None , release = None , except_release = None , dryrun = 1 , verbose = 1 ) :
    """Permanently erase one or more VM instances from existence ."""

implementation:
verbose = int ( verbose )
if env . vm_type == EC2 :
    conn = get_ec2_connection ( )
    instances = list_instances ( name = name , group = group , release = release , except_release = except_release , )
    for instance_name , instance_data in instances . items ( ) :
        public_dns_name = instance_data [ 'public_dns_name' ]
        print ( '\nDeleting %s (%s)...' % ( instance_name , instance_data [ 'id' ] ) )
        if not get_dryrun ( ) :
            conn . terminate_instances ( instance_ids = [ instance_data [ 'id' ] ] )
        # Clear host key on localhost .
        known_hosts = os . path . expanduser ( '~/.ssh/known_hosts' )
        cmd = 'ssh-keygen -f "%s" -R %s' % ( known_hosts , public_dns_name )
        local_or_dryrun ( cmd )
else :
    raise NotImplementedError


signature:
def get_name ( ) :
    """Retrieves the instance name associated with the current host string ."""

implementation:
if env . vm_type == EC2 :
    for instance in get_all_running_ec2_instances ( ) :
        if env . host_string == instance . public_dns_name :
            name = instance . tags . get ( env . vm_name_tag )
            return name
else :
    raise NotImplementedError


signature:
def respawn ( name = None , group = None ) :
    """Deletes and recreates one or more VM instances ."""

implementation:
if name is None :
    name = get_name ( )
delete ( name = name , group = group )
instance = get_or_create ( name = name , group = group )
env . host_string = instance . public_dns_name


signature:
def deploy_code ( self ) :
    """Generates a rsync of all deployable code ."""

implementation:
assert self . genv . SITE , 'Site unspecified.'
assert self . genv . ROLE , 'Role unspecified.'
r = self . local_renderer
if self . env . exclusions :
    r . env . exclusions_str = ' ' . join ( "--exclude='%s'" % _ for _ in self . env . exclusions )
r . local ( r . env . rsync_command )
r . sudo ( 'chown -R {rsync_chown_user}:{rsync_chown_group} {rsync_dst_dir}' )


signature:
def init_env ( ) :
    """Populates the global env variables with custom default settings ."""

implementation:
env . ROLES_DIR = ROLE_DIR
env . services = [ ]
env . confirm_deployment = False
env . is_local = None
env . base_config_dir = '.'
env . src_dir = 'src'
# The path relative to fab where the code resides .
env . sites = { }
# { site : site _ settings }
env [ SITE ] = None
env [ ROLE ] = None
env . hosts_retriever = None
env . hosts_retrievers = type ( env ) ( )
# ' default ' : lambda hostname : hostname ,
env . hostname_translator = 'default'
env . hostname_translators = type ( env ) ( )
env . hostname_translators . default = lambda hostname : hostname
env . default_site = None
# A list of all site names that should be available on the current host .
env . available_sites = [ ]
# A list of all site names per host .
# { hostname : [ sites ] }
# If no entry found , will use available _ sites .
env . available_sites_by_host = { }
# The command run to determine the percent of disk usage .
env . disk_usage_command = "df -H | grep -vE '^Filesystem|tmpfs|cdrom|none' | awk '{print $5 " " $1}'"
env . burlap_data_dir = '.burlap'
env . setdefault ( 'roledefs' , { } )
env . setdefault ( 'roles' , [ ] )
env . setdefault ( 'hosts' , [ ] )
env . setdefault ( 'exclude_hosts' , [ ] )


signature:
def create_module ( name , code = None ) :
    """Dynamically creates a module with the given name ."""

implementation:
if name not in sys . modules :
    sys . modules [ name ] = imp . new_module ( name )
module = sys . modules [ name ]
if code :
    print ( 'executing code for %s: %s' % ( name , code ) )
    exec ( code in module . __dict__ )
    # pylint : disable = exec - used
    exec ( "from %s import %s" % ( name , '*' ) )
# pylint : disable = exec - used
return module


signature:
def add_class_methods_as_module_level_functions_for_fabric ( instance , module_name , method_name , module_alias = None ) :
    '''Utility to take the methods of the instance of a class , instance ,
 and add them as functions to a module , module _ name , so that Fabric
 can find and call them . Call this at the bottom of a module after
 the class definition .'''

implementation:
import imp
from . decorators import task_or_dryrun
# get the module as an object
module_obj = sys . modules [ module_name ]
module_alias = re . sub ( '[^a-zA-Z0-9]+' , '' , module_alias or '' )
# Iterate over the methods of the class and dynamically create a function
# for each method that calls the method and add it to the current module
# NOTE : inspect . ismethod actually executes the methods ? !
# for method in inspect . getmembers ( instance , predicate = inspect . ismethod ) :
method_obj = getattr ( instance , method_name )
if not method_name . startswith ( '_' ) : # get the bound method
    func = getattr ( instance , method_name )
    # if module _ name = = ' buildbot ' or module _ alias = = ' buildbot ' :
    # print ( ' - ' * 80)
    # print ( ' module _ name : ' , module _ name )
    # print ( ' method _ name : ' , method _ name )
    # print ( ' module _ alias : ' , module _ alias )
    # print ( ' module _ obj : ' , module _ obj )
    # print ( ' func . module : ' , func . _ _ module _ _ )
    # Convert executable to a Fabric task , if not done so already .
    if not hasattr ( func , 'is_task_or_dryrun' ) :
        func = task_or_dryrun ( func )
    if module_name == module_alias or ( module_name . startswith ( 'satchels.' ) and module_name . endswith ( module_alias ) ) : # add the function to the current module
        setattr ( module_obj , method_name , func )
    else : # Dynamically create a module for the virtual satchel .
        _module_obj = module_obj
        module_obj = create_module ( module_alias )
        setattr ( module_obj , method_name , func )
        post_import_modules . add ( module_alias )
    fabric_name = '%s.%s' % ( module_alias or module_name , method_name )
    func . wrapped . __func__ . fabric_name = fabric_name
    return func


signature:
def str_to_list ( s ) :
    """Converts a string of comma delimited values and returns a list ."""

implementation:
if s is None :
    return [ ]
elif isinstance ( s , ( tuple , list ) ) :
    return s
elif not isinstance ( s , six . string_types ) :
    raise NotImplementedError ( 'Unknown type: %s' % type ( s ) )
return [ _ . strip ( ) . lower ( ) for _ in ( s or '' ) . split ( ',' ) if _ . strip ( ) ]


signature:
def get_hosts_retriever ( s = None ) :
    """Given the function name , looks up the method for dynamically retrieving host data ."""

implementation:
s = s or env . hosts_retriever
# # assert s , ' No hosts retriever specified . '
if not s :
    return env_hosts_retriever
# module _ name = ' . ' . join ( s . split ( ' . ' ) [ : - 1 ] )
# func _ name = s . split ( ' . ' ) [ - 1]
# retriever = getattr ( importlib . import _ module ( module _ name ) , func _ name )
# return retriever
return str_to_callable ( s ) or env_hosts_retriever


signature:
def append_or_dryrun ( * args , ** kwargs ) :
    """Wrapper around Fabric ' s contrib . files . append ( ) to give it a dryrun option .
 text filename
 http : / / docs . fabfile . org / en / 0.9.1 / api / contrib / files . html # fabric . contrib . files . append"""

implementation:
from fabric . contrib . files import append
dryrun = get_dryrun ( kwargs . get ( 'dryrun' ) )
if 'dryrun' in kwargs :
    del kwargs [ 'dryrun' ]
use_sudo = kwargs . pop ( 'use_sudo' , False )
text = args [ 0 ] if len ( args ) >= 1 else kwargs . pop ( 'text' )
filename = args [ 1 ] if len ( args ) >= 2 else kwargs . pop ( 'filename' )
if dryrun :
    text = text . replace ( '\n' , '\\n' )
    cmd = 'echo -e "%s" >> %s' % ( text , filename )
    cmd_run = 'sudo' if use_sudo else 'run'
    if BURLAP_COMMAND_PREFIX :
        print ( '%s %s: %s' % ( render_command_prefix ( ) , cmd_run , cmd ) )
    else :
        print ( cmd )
else :
    append ( filename = filename , text = text . replace ( r'\n' , '\n' ) , use_sudo = use_sudo , ** kwargs )


signature:
def disable_attribute_or_dryrun ( * args , ** kwargs ) :
    """Comments - out a line containing an attribute .
 The inverse of enable _ attribute _ or _ dryrun ( ) ."""

implementation:
dryrun = get_dryrun ( kwargs . get ( 'dryrun' ) )
if 'dryrun' in kwargs :
    del kwargs [ 'dryrun' ]
use_sudo = kwargs . pop ( 'use_sudo' , False )
run_cmd = sudo_or_dryrun if use_sudo else run_or_dryrun
run_cmd_str = 'sudo' if use_sudo else 'run'
key = args [ 0 ] if len ( args ) >= 1 else kwargs . pop ( 'key' )
filename = args [ 1 ] if len ( args ) >= 2 else kwargs . pop ( 'filename' )
comment_pattern = args [ 2 ] if len ( args ) >= 3 else kwargs . pop ( 'comment_pattern' , r'#\s*' )
equals_pattern = args [ 3 ] if len ( args ) >= 4 else kwargs . pop ( 'equals_pattern' , r'\s*=\s*' )
equals_literal = args [ 4 ] if len ( args ) >= 5 else kwargs . pop ( 'equals_pattern' , '=' )
context = dict ( key = key , uncommented_literal = '%s%s' % ( key , equals_literal ) , # key = value
uncommented_pattern = '%s%s' % ( key , equals_pattern ) , # key = value
uncommented_pattern_partial = '^%s%s[^\\n]*' % ( key , equals_pattern ) , # key =
commented_pattern = '%s%s%s' % ( comment_pattern , key , equals_pattern ) , # # key = value
commented_pattern_partial = '^%s%s%s[^\\n]*' % ( comment_pattern , key , equals_pattern ) , # # key =
filename = filename , backup = filename + '.bak' , comment_pattern = comment_pattern , equals_pattern = equals_pattern , )
cmds = [ # Replace partial un - commented text with full commented text .
'sed -i -r -e "s/{uncommented_pattern_partial}//g" {filename}' . format ( ** context ) , ]
if dryrun :
    for cmd in cmds :
        if BURLAP_COMMAND_PREFIX :
            print ( '%s %s: %s' % ( render_command_prefix ( ) , run_cmd_str , cmd ) )
        else :
            print ( cmd )
else :
    for cmd in cmds : # print ( ' enable attr : ' , cmd )
        run_cmd ( cmd )


signature:
def write_temp_file_or_dryrun ( content , * args , ** kwargs ) :
    """Writes the given content to a local temporary file ."""

implementation:
dryrun = get_dryrun ( kwargs . get ( 'dryrun' ) )
if dryrun :
    fd , tmp_fn = tempfile . mkstemp ( )
    os . remove ( tmp_fn )
    cmd_run = 'local'
    cmd = 'cat <<EOT >> %s\n%s\nEOT' % ( tmp_fn , content )
    if BURLAP_COMMAND_PREFIX :
        print ( '%s %s: %s' % ( render_command_prefix ( ) , cmd_run , cmd ) )
    else :
        print ( cmd )
else :
    fd , tmp_fn = tempfile . mkstemp ( )
    fout = open ( tmp_fn , 'w' )
    fout . write ( content )
    fout . close ( )
return tmp_fn


signature:
def sed_or_dryrun ( * args , ** kwargs ) :
    """Wrapper around Fabric ' s contrib . files . sed ( ) to give it a dryrun option .
 http : / / docs . fabfile . org / en / 0.9.1 / api / contrib / files . html # fabric . contrib . files . sed"""

implementation:
dryrun = get_dryrun ( kwargs . get ( 'dryrun' ) )
if 'dryrun' in kwargs :
    del kwargs [ 'dryrun' ]
use_sudo = kwargs . get ( 'use_sudo' , False )
if dryrun :
    context = dict ( filename = args [ 0 ] if len ( args ) >= 1 else kwargs [ 'filename' ] , before = args [ 1 ] if len ( args ) >= 2 else kwargs [ 'before' ] , after = args [ 2 ] if len ( args ) >= 3 else kwargs [ 'after' ] , backup = args [ 3 ] if len ( args ) >= 4 else kwargs . get ( 'backup' , '.bak' ) , limit = kwargs . get ( 'limit' , '' ) , )
    cmd = 'sed -i{backup} -r -e "/{limit}/ s/{before}/{after}/g {filename}"' . format ( ** context )
    cmd_run = 'sudo' if use_sudo else 'run'
    if BURLAP_COMMAND_PREFIX :
        print ( '%s %s: %s' % ( render_command_prefix ( ) , cmd_run , cmd ) )
    else :
        print ( cmd )
else :
    from fabric . contrib . files import sed
    sed ( * args , ** kwargs )


signature:
def reboot_or_dryrun ( * args , ** kwargs ) :
    """An improved version of fabric . operations . reboot with better error handling ."""

implementation:
from fabric . state import connections
verbose = get_verbose ( )
dryrun = get_dryrun ( kwargs . get ( 'dryrun' ) )
# Use ' wait ' as max total wait time
kwargs . setdefault ( 'wait' , 120 )
wait = int ( kwargs [ 'wait' ] )
command = kwargs . get ( 'command' , 'reboot' )
now = int ( kwargs . get ( 'now' , 0 ) )
print ( 'now:' , now )
if now :
    command += ' now'
# Shorter timeout for a more granular cycle than the default .
timeout = int ( kwargs . get ( 'timeout' , 30 ) )
reconnect_hostname = kwargs . pop ( 'new_hostname' , env . host_string )
if 'dryrun' in kwargs :
    del kwargs [ 'dryrun' ]
if dryrun :
    print ( '%s sudo: %s' % ( render_command_prefix ( ) , command ) )
else :
    if is_local ( ) :
        if raw_input ( 'reboot localhost now? ' ) . strip ( ) [ 0 ] . lower ( ) != 'y' :
            return
    attempts = int ( round ( float ( wait ) / float ( timeout ) ) )
    # Don ' t bleed settings , since this is supposed to be self - contained .
    # User adaptations will probably want to drop the " with settings ( ) " and
    # just have globally set timeout / attempts values .
    with settings ( warn_only = True ) :
        _sudo ( command )
    env . host_string = reconnect_hostname
    success = False
    for attempt in xrange ( attempts ) : # Try to make sure we don ' t slip in before pre - reboot lockdown
        if verbose :
            print ( 'Waiting for %s seconds, wait %i of %i' % ( timeout , attempt + 1 , attempts ) )
        time . sleep ( timeout )
        # This is actually an internal - ish API call , but users can simply drop
        # it in real fabfile use - - the next run / sudo / put / get / etc call will
        # automatically trigger a reconnect .
        # We use it here to force the reconnect while this function is still in
        # control and has the above timeout settings enabled .
        try :
            if verbose :
                print ( 'Reconnecting to:' , env . host_string )
            # This will fail until the network interface comes back up .
            connections . connect ( env . host_string )
            # This will also fail until SSH is running again .
            with settings ( timeout = timeout ) :
                _run ( 'echo hello' )
            success = True
            break
        except Exception as e :
            print ( 'Exception:' , e )
    if not success :
        raise Exception ( 'Reboot failed or took longer than %s seconds.' % wait )


signature:
def pretty_bytes ( bytes ) : # pylint : disable = redefined - builtin
    """Scales a byte count to the largest scale with a small whole number
 that ' s easier to read .
 Returns a tuple of the format ( scaled _ float , unit _ string ) ."""

implementation:
if not bytes :
    return bytes , 'bytes'
sign = bytes / float ( bytes )
bytes = abs ( bytes )
for x in [ 'bytes' , 'KB' , 'MB' , 'GB' , 'TB' ] :
    if bytes < 1024.0 : # return " % 3.1f % s " % ( bytes , x )
        return sign * bytes , x
    bytes /= 1024.0


signature:
def get_component_settings ( prefixes = None ) :
    """Returns a subset of the env dictionary containing
 only those keys with the name prefix ."""

implementation:
prefixes = prefixes or [ ]
assert isinstance ( prefixes , ( tuple , list ) ) , 'Prefixes must be a sequence type, not %s.' % type ( prefixes )
data = { }
for name in prefixes :
    name = name . lower ( ) . strip ( )
    for k in sorted ( env ) :
        if k . startswith ( '%s_' % name ) :
            new_k = k [ len ( name ) + 1 : ]
            data [ new_k ] = env [ k ]
return data


signature:
def get_last_modified_timestamp ( path , ignore = None ) :
    """Recursively finds the most recent timestamp in the given directory ."""

implementation:
ignore = ignore or [ ]
if not isinstance ( path , six . string_types ) :
    return
ignore_str = ''
if ignore :
    assert isinstance ( ignore , ( tuple , list ) )
    ignore_str = ' ' . join ( "! -name '%s'" % _ for _ in ignore )
cmd = 'find "' + path + '" ' + ignore_str + ' -type f -printf "%T@ %p\n" | sort -n | tail -1 | cut -f 1 -d " "'
# ' find ' + path + ' - type f - printf " % T @ % p \ n " | sort - n | tail - 1 | cut - d " " - f1
ret = subprocess . check_output ( cmd , shell = True )
# Note , we round now to avoid rounding errors later on where some formatters
# use different decimal contexts .
try :
    ret = round ( float ( ret ) , 2 )
except ValueError :
    return
return ret


signature:
def check_settings_for_differences ( old , new , as_bool = False , as_tri = False ) :
    """Returns a subset of the env dictionary keys that differ ,
 either being added , deleted or changed between old and new ."""

implementation:
assert not as_bool or not as_tri
old = old or { }
new = new or { }
changes = set ( k for k in set ( new . iterkeys ( ) ) . intersection ( old . iterkeys ( ) ) if new [ k ] != old [ k ] )
if changes and as_bool :
    return True
added_keys = set ( new . iterkeys ( ) ) . difference ( old . iterkeys ( ) )
if added_keys and as_bool :
    return True
if not as_tri :
    changes . update ( added_keys )
deled_keys = set ( old . iterkeys ( ) ) . difference ( new . iterkeys ( ) )
if deled_keys and as_bool :
    return True
if as_bool :
    return False
if not as_tri :
    changes . update ( deled_keys )
if as_tri :
    return added_keys , changes , deled_keys
return changes


signature:
def get_packager ( ) :
    """Returns the packager detected on the remote system ."""

implementation:
# TODO : remove once fabric stops using contextlib . nested .
# https : / / github . com / fabric / fabric / issues / 1364
import warnings
warnings . filterwarnings ( "ignore" , category = DeprecationWarning )
common_packager = get_rc ( 'common_packager' )
if common_packager :
    return common_packager
# TODO : cache result by current env . host _ string so we can handle multiple hosts with different OSes
with settings ( warn_only = True ) :
    with hide ( 'running' , 'stdout' , 'stderr' , 'warnings' ) :
        ret = _run ( 'cat /etc/fedora-release' )
        if ret . succeeded :
            common_packager = YUM
        else :
            ret = _run ( 'cat /etc/lsb-release' )
            if ret . succeeded :
                common_packager = APT
            else :
                for pn in PACKAGERS :
                    ret = _run ( 'which %s' % pn )
                    if ret . succeeded :
                        common_packager = pn
                        break
if not common_packager :
    raise Exception ( 'Unable to determine packager.' )
set_rc ( 'common_packager' , common_packager )
return common_packager


signature:
def get_os_version ( ) :
    """Returns a named tuple describing the operating system on the remote host ."""

implementation:
# TODO : remove once fabric stops using contextlib . nested .
# https : / / github . com / fabric / fabric / issues / 1364
import warnings
warnings . filterwarnings ( "ignore" , category = DeprecationWarning )
common_os_version = get_rc ( 'common_os_version' )
if common_os_version :
    return common_os_version
with settings ( warn_only = True ) :
    with hide ( 'running' , 'stdout' , 'stderr' , 'warnings' ) :
        ret = _run_or_local ( 'cat /etc/lsb-release' )
        if ret . succeeded :
            return OS ( type = LINUX , distro = UBUNTU , release = re . findall ( r'DISTRIB_RELEASE=([0-9\.]+)' , ret ) [ 0 ] )
        ret = _run_or_local ( 'cat /etc/debian_version' )
        if ret . succeeded :
            return OS ( type = LINUX , distro = DEBIAN , release = re . findall ( r'([0-9\.]+)' , ret ) [ 0 ] )
        ret = _run_or_local ( 'cat /etc/fedora-release' )
        if ret . succeeded :
            return OS ( type = LINUX , distro = FEDORA , release = re . findall ( r'release ([0-9]+)' , ret ) [ 0 ] )
        raise Exception ( 'Unable to determine OS version.' )


signature:
def render_to_string ( template , extra = None ) :
    """Renders the given template to a string ."""

implementation:
from jinja2 import Template
extra = extra or { }
final_fqfn = find_template ( template )
assert final_fqfn , 'Template not found: %s' % template
template_content = open ( final_fqfn , 'r' ) . read ( )
t = Template ( template_content )
if extra :
    context = env . copy ( )
    context . update ( extra )
else :
    context = env
rendered_content = t . render ( ** context )
rendered_content = rendered_content . replace ( '"' , '"' )
return rendered_content


signature:
def render_to_file ( template , fn = None , extra = None , ** kwargs ) :
    """Returns a template to a local file .
 If no filename given , a temporary filename will be generated and returned ."""

implementation:
import tempfile
dryrun = get_dryrun ( kwargs . get ( 'dryrun' ) )
append_newline = kwargs . pop ( 'append_newline' , True )
style = kwargs . pop ( 'style' , 'cat' )
# | echo
formatter = kwargs . pop ( 'formatter' , None )
content = render_to_string ( template , extra = extra )
if append_newline and not content . endswith ( '\n' ) :
    content += '\n'
if formatter and callable ( formatter ) :
    content = formatter ( content )
if dryrun :
    if not fn :
        fd , fn = tempfile . mkstemp ( )
        fout = os . fdopen ( fd , 'wt' )
        fout . close ( )
else :
    if fn :
        fout = open ( fn , 'w' )
    else :
        fd , fn = tempfile . mkstemp ( )
        fout = os . fdopen ( fd , 'wt' )
    fout . write ( content )
    fout . close ( )
assert fn
if style == 'cat' :
    cmd = 'cat <<EOF > %s\n%s\nEOF' % ( fn , content )
elif style == 'echo' :
    cmd = 'echo -e %s > %s' % ( shellquote ( content ) , fn )
else :
    raise NotImplementedError
if BURLAP_COMMAND_PREFIX :
    print ( '%s run: %s' % ( render_command_prefix ( ) , cmd ) )
else :
    print ( cmd )
return fn


signature:
def install_config ( local_path = None , remote_path = None , render = True , extra = None , formatter = None ) :
    """Returns a template to a remote file .
 If no filename given , a temporary filename will be generated and returned ."""

implementation:
local_path = find_template ( local_path )
if render :
    extra = extra or { }
    local_path = render_to_file ( template = local_path , extra = extra , formatter = formatter )
put_or_dryrun ( local_path = local_path , remote_path = remote_path , use_sudo = True )


signature:
def iter_sites ( sites = None , site = None , renderer = None , setter = None , no_secure = False , verbose = None ) :
    """Iterates over sites , safely setting environment variables for each site ."""

implementation:
if verbose is None :
    verbose = get_verbose ( )
hostname = get_current_hostname ( )
target_sites = env . available_sites_by_host . get ( hostname , None )
if sites is None :
    site = site or env . SITE or ALL
    if site == ALL :
        sites = list ( six . iteritems ( env . sites ) )
    else :
        sys . stderr . flush ( )
        sites = [ ( site , env . sites . get ( site ) ) ]
renderer = renderer
# or render _ remote _ paths
env_default = save_env ( )
for _site , site_data in sorted ( sites ) :
    if no_secure and _site . endswith ( '_secure' ) :
        continue
    # Only load site configurations that are allowed for this host .
    if target_sites is None :
        pass
    else :
        assert isinstance ( target_sites , ( tuple , list ) )
        if _site not in target_sites :
            if verbose :
                print ( 'Skipping site %s because not in among target sites.' % _site )
            continue
    env . update ( env_default )
    env . update ( env . sites . get ( _site , { } ) )
    env . SITE = _site
    if callable ( renderer ) :
        renderer ( )
    if setter :
        setter ( _site )
    yield _site , site_data
# Revert modified keys .
env . update ( env_default )
# Remove keys that were added , not simply updated .
added_keys = set ( env ) . difference ( env_default )
for key in added_keys : # Don ' t remove internally maintained variables , because these are used to cache hostnames
# used by iter _ sites ( ) .
    if key . startswith ( '_' ) :
        continue
    del env [ key ]


signature:
def topological_sort ( source ) :
    """perform topo sort on elements .
 : arg source : list of ` ` ( name , [ list of dependancies ] ) ` ` pairs
 : returns : list of names , with dependancies listed first"""

implementation:
if isinstance ( source , dict ) :
    source = source . items ( )
pending = sorted ( [ ( name , set ( deps ) ) for name , deps in source ] )
# copy deps so we can modify set in - place
emitted = [ ]
while pending :
    next_pending = [ ]
    next_emitted = [ ]
    for entry in pending :
        name , deps = entry
        deps . difference_update ( emitted )
        # remove deps we emitted last pass
        if deps : # still has deps ? recheck during next pass
            next_pending . append ( entry )
        else : # no more deps ? time to emit
            yield name
            emitted . append ( name )
            # < - - not required , but helps preserve original ordering
            next_emitted . append ( name )
            # remember what we emitted for difference _ update ( ) in next pass
    if not next_emitted : # all entries have unmet deps , one of two things is wrong . . .
        raise ValueError ( "cyclic or missing dependancy detected: %r" % ( next_pending , ) )
    pending = next_pending
    emitted = next_emitted


signature:
def get_hosts_for_site ( site = None ) :
    """Returns a list of hosts that have been configured to support the given site ."""

implementation:
site = site or env . SITE
hosts = set ( )
for hostname , _sites in six . iteritems ( env . available_sites_by_host ) : # print ( ' checking hostname : ' , hostname , _ sites )
    for _site in _sites :
        if _site == site : # print ( ' _ site : ' , _ site )
            host_ip = get_host_ip ( hostname )
            # print ( ' host _ ip : ' , host _ ip )
            if host_ip :
                hosts . add ( host_ip )
                break
return list ( hosts )


signature:
def collect_genv ( self , include_local = True , include_global = True ) :
    """Returns a copy of the global environment with all the local variables copied back into it ."""

implementation:
e = type ( self . genv ) ( )
if include_global :
    e . update ( self . genv )
if include_local :
    for k , v in self . lenv . items ( ) :
        e [ '%s_%s' % ( self . obj . name . lower ( ) , k ) ] = v
return e


signature:
def _set_defaults ( self ) :
    """Wrapper around the overrideable set _ defaults ( ) ."""

implementation:
# Register an " enabled " flag on all satchels .
# How this flag is interpreted depends on the individual satchel .
_prefix = '%s_enabled' % self . name
if _prefix not in env :
    env [ _prefix ] = True
# Do a one - time init of custom defaults .
_key = '_%s' % self . name
if _key not in env :
    env [ _key ] = True
    self . set_defaults ( )


signature:
def capture_bash ( self ) :
    """Context manager that hides the command prefix and activates dryrun to capture all following task commands to their equivalent Bash outputs ."""

implementation:
class Capture ( object ) :
    def __init__ ( self , satchel ) :
        self . satchel = satchel
        self . _dryrun = self . satchel . dryrun
        self . satchel . dryrun = 1
        begincap ( )
        self . _stdout = sys . stdout
        self . _stderr = sys . stderr
        self . stdout = sys . stdout = StringIO ( )
        self . stderr = sys . stderr = StringIO ( )
    def __enter__ ( self ) :
        return self
    def __exit__ ( self , type , value , traceback ) : # pylint : disable = redefined - builtin
        endcap ( )
        self . satchel . dryrun = self . _dryrun
        sys . stdout = self . _stdout
        sys . stderr = self . _stderr
return Capture ( self )


signature:
def register ( self ) :
    """Adds this satchel to the global registeries for fast lookup from other satchels ."""

implementation:
self . _set_defaults ( )
all_satchels [ self . name . upper ( ) ] = self
manifest_recorder [ self . name ] = self . record_manifest
# Register service commands .
if self . required_system_packages :
    required_system_packages [ self . name . upper ( ) ] = self . required_system_packages


signature:
def unregister ( self ) :
    """Removes this satchel from global registeries ."""

implementation:
for k in list ( env . keys ( ) ) :
    if k . startswith ( self . env_prefix ) :
        del env [ k ]
try :
    del all_satchels [ self . name . upper ( ) ]
except KeyError :
    pass
try :
    del manifest_recorder [ self . name ]
except KeyError :
    pass
try :
    del manifest_deployers [ self . name . upper ( ) ]
except KeyError :
    pass
try :
    del manifest_deployers_befores [ self . name . upper ( ) ]
except KeyError :
    pass
try :
    del required_system_packages [ self . name . upper ( ) ]
except KeyError :
    pass


signature:
def get_tasks ( self ) :
    """Returns an ordered list of all task names ."""

implementation:
tasks = set ( self . tasks )
# DEPRECATED
for _name in dir ( self ) : # Skip properties so we don ' t accidentally execute any methods .
    if isinstance ( getattr ( type ( self ) , _name , None ) , property ) :
        continue
    attr = getattr ( self , _name )
    if hasattr ( attr , '__call__' ) and getattr ( attr , 'is_task' , False ) :
        tasks . add ( _name )
return sorted ( tasks )


signature:
def local_renderer ( self ) :
    """Retrieves the cached local renderer ."""

implementation:
if not self . _local_renderer :
    r = self . create_local_renderer ( )
    self . _local_renderer = r
return self . _local_renderer


signature:
def all_other_enabled_satchels ( self ) :
    """Returns a dictionary of satchels used in the current configuration , excluding ourselves ."""

implementation: return dict ( ( name , satchel ) for name , satchel in self . all_satchels . items ( ) if name != self . name . upper ( ) and name . lower ( ) in map ( str . lower , self . genv . services ) )


signature:
def lenv ( self ) :
    """Returns a version of env filtered to only include the variables in our namespace ."""

implementation:
_env = type ( env ) ( )
for _k , _v in six . iteritems ( env ) :
    if _k . startswith ( self . name + '_' ) :
        _env [ _k [ len ( self . name ) + 1 : ] ] = _v
return _env


signature:
def param_changed_to ( self , key , to_value , from_value = None ) :
    """Returns true if the given parameter , with name key , has transitioned to the given value ."""

implementation:
last_value = getattr ( self . last_manifest , key )
current_value = self . current_manifest . get ( key )
if from_value is not None :
    return last_value == from_value and current_value == to_value
return last_value != to_value and current_value == to_value


signature:
def reboot_or_dryrun ( self , * args , ** kwargs ) :
    """Reboots the server and waits for it to come back ."""

implementation:
warnings . warn ( 'Use self.run() instead.' , DeprecationWarning , stacklevel = 2 )
self . reboot ( * args , ** kwargs )


signature:
def set_site_specifics ( self , site ) :
    """Loads settings for the target site ."""

implementation:
r = self . local_renderer
site_data = self . genv . sites [ site ] . copy ( )
r . env . site = site
if self . verbose :
    print ( 'set_site_specifics.data:' )
    pprint ( site_data , indent = 4 )
# Remove local namespace settings from the global namespace
# by converting < satchel _ name > _ < variable _ name > to < variable _ name > .
local_ns = { }
for k , v in list ( site_data . items ( ) ) :
    if k . startswith ( self . name + '_' ) :
        _k = k [ len ( self . name + '_' ) : ]
        local_ns [ _k ] = v
        del site_data [ k ]
r . env . update ( local_ns )
r . env . update ( site_data )


signature:
def vprint ( self , * args , ** kwargs ) :
    """When verbose is set , acts like the normal print ( ) function .
 Otherwise , does nothing ."""

implementation:
if self . verbose :
    curframe = inspect . currentframe ( )
    calframe = inspect . getouterframes ( curframe , 2 )
    caller_name = calframe [ 1 ] [ 3 ]
    prefix = '%s.%s:' % ( self . name . lower ( ) , caller_name )
    print ( prefix , * args , ** kwargs )


signature:
def get_package_list ( self ) :
    """Returns a list of all required packages ."""

implementation:
os_version = self . os_version
# OS ( type = LINUX , distro = UBUNTU , release = ' 14.04 ' )
self . vprint ( 'os_version:' , os_version )
# Lookup legacy package list .
# OS : [ package1 , package2 , . . . ] ,
req_packages1 = self . required_system_packages
if req_packages1 :
    deprecation ( 'The required_system_packages attribute is deprecated, ' 'use the packager_system_packages property instead.' )
# Lookup new package list .
# OS : [ package1 , package2 , . . . ] ,
req_packages2 = self . packager_system_packages
patterns = [ ( os_version . type , os_version . distro , os_version . release ) , ( os_version . distro , os_version . release ) , ( os_version . type , os_version . distro ) , ( os_version . distro , ) , os_version . distro , ]
self . vprint ( 'req_packages1:' , req_packages1 )
self . vprint ( 'req_packages2:' , req_packages2 )
package_list = None
found = False
for pattern in patterns :
    self . vprint ( 'pattern:' , pattern )
    for req_packages in ( req_packages1 , req_packages2 ) :
        if pattern in req_packages :
            package_list = req_packages [ pattern ]
            found = True
            break
if not found :
    print ( 'Warning: No operating system pattern found for %s' % ( os_version , ) )
self . vprint ( 'package_list:' , package_list )
return package_list


signature:
def install_packages ( self ) :
    """Installs all required packages listed for this satchel .
 Normally called indirectly by running packager . configure ( ) ."""

implementation:
os_version = self . os_version
package_list = self . get_package_list ( )
if package_list :
    package_list_str = ' ' . join ( package_list )
    if os_version . distro == UBUNTU :
        self . sudo ( 'apt-get update --fix-missing; DEBIAN_FRONTEND=noninteractive apt-get install --yes %s' % package_list_str )
    elif os_version . distro == DEBIAN :
        self . sudo ( 'apt-get update --fix-missing; DEBIAN_FRONTEND=noninteractive apt-get install --yes %s' % package_list_str )
    elif os_version . distro == FEDORA :
        self . sudo ( 'yum install --assumeyes %s' % package_list_str )
    else :
        raise NotImplementedError ( 'Unknown distro: %s' % os_version . distro )