Exemplo n.º 1
0
def deploy(project=None, commit=None):
    """ Deploy a specific version in the specified environment. """
    version(project)

    # Prompt for the commit ID if not given as a parameter.
    if not commit:
        commit = prompt('Enter commit to deploy (40 character SHA1)',
            validate=r'^[0-9a-fA-F]{6,40}$')

    require('user', 'hosts', 'webroot', 'role',
        used_for='These variables are used for finding the target deployment environment.',
    )

    make_path = time.strftime('ding-%Y%m%d%H%M')[:-1]
    cwd = os.path.join(env.build_path, env.project, 'build')
    abs_make_path = os.path.join(cwd, make_path)

    with cd(cwd):
        # Update git checkout.
        run('git fetch')
        run('git checkout %s' % commit)

        # Run the build process via drush make.
        logging.info('Starting build in %s' % abs_make_path)
        run('./ding_build.py -lL %s -m profile %s' % (env.role, make_path))

    run('curl -s http://localhost/apc_clear_cache.php')

    logging.warning('%(site)s | %(user)s | %(commit)s' % {
        'site': env.webroot.split('/')[-1],
        'user': _get_system_username(),
        'commit': commit[0:7],
    })
Exemplo n.º 2
0
def deploy(project=None, commit=None):
    """ Deploy a specific version in the specified environment. """
    version(project)

    # Prompt for the commit ID if not given as a parameter.
    if not commit:
        commit = prompt('Enter commit to deploy (40 character SHA1)',
            validate=r'^[0-9a-fA-F]{6,40}$')

    require('user', 'hosts', 'webroot', 'role',
        used_for='These variables are used for finding the target deployment environment.',
    )

    make_path = time.strftime('ding-%Y%m%d%H%M')[:-1]
    profile_path = os.path.join(env.build_path, env.project)
    abs_make_path = os.path.join(profile_path, 'build', make_path)

    with cd(profile_path):
        # Update git checkout.
        run('git fetch')
        run('git checkout %s' % commit)

        # Run the build process via drush make.
        logging.info('Starting build in %s' % abs_make_path)
        run('./ding_build.py -lL %s -m profile %s' % (env.role, make_path))

    run('curl -s http://localhost/apc_clear_cache.php')

    logging.warning('%(site)s | %(user)s | %(commit)s' % {
        'site': env.webroot.split('/')[-1],
        'user': _get_system_username(),
        'commit': commit[0:7],
    })
Exemplo n.º 3
0
 def test_host_string_normalization(self):
     username = _get_system_username()
     for description, input, output_ in (
         ("Sanity check: equal strings remain equal", "localhost", "localhost"),
         ("Empty username is same as get_system_username", "localhost", username + "@localhost"),
         ("Empty port is same as port 22", "localhost", "localhost:22"),
         ("Both username and port tested at once, for kicks", "localhost", username + "@localhost:22"),
     ):
         eq_.description = "Host-string normalization: %s" % description
         yield eq_, normalize(input), normalize(output_)
         del eq_.description
Exemplo n.º 4
0
 def test_host_string_denormalization(self):
     username = _get_system_username()
     for description, string1, string2 in (
         ("Sanity check: equal strings remain equal", "localhost", "localhost"),
         ("Empty username is same as get_system_username", "localhost:22", username + "@localhost:22"),
         ("Empty port is same as port 22", "user@localhost", "user@localhost:22"),
         ("Both username and port", "localhost", username + "@localhost:22"),
         ("IPv6 address", "2001:DB8::1", username + "@[2001:DB8::1]:22"),
     ):
         eq_.description = "Host-string denormalization: %s" % description
         yield eq_, denormalize(string1), denormalize(string2)
         del eq_.description
Exemplo n.º 5
0
def test_host_string_denormalization():
    username = _get_system_username()
    for description, string1, string2 in (
        ("Sanity check: equal strings remain equal", 'localhost', 'localhost'),
        ("Empty username is same as get_system_username", 'localhost:22',
         username + '@localhost:22'),
        ("Empty port is same as port 22", 'user@localhost',
         'user@localhost:22'),
        ("Both username and port", 'localhost', username + '@localhost:22'),
    ):
        eq_.description = "Host-string denormalization: %s" % description
        yield eq_, denormalize(string1), denormalize(string2)
        del eq_.description
Exemplo n.º 6
0
def test_host_string_normalization():
    username = _get_system_username()
    for description, input, output in (
        ("Sanity check: equal strings remain equal", 'localhost', 'localhost'),
        ("Empty username is same as get_system_username", 'localhost',
         username + '@localhost'),
        ("Empty port is same as port 22", 'localhost', 'localhost:22'),
        ("Both username and port tested at once, for kicks", 'localhost',
         username + '@localhost:22'),
    ):
        eq_.description = "Host-string normalization: %s" % description
        yield eq_, normalize(input), normalize(output)
        del eq_.description
Exemplo n.º 7
0
def test_host_string_normalization():
    username = _get_system_username()
    for description, string1, string2 in (
        ("Sanity check: equal strings remain equal",
            'localhost', 'localhost'),
        ("Empty username is same as get_system_username",
            'localhost', username + '@localhost'),
        ("Empty port is same as port 22",
            'localhost', 'localhost:22'),
        ("Both username and port tested at once, for kicks",
            'localhost', username + '@localhost:22'),
    ):
        eq_.description = description
        yield eq_, normalize(string1), normalize(string2) 
        del eq_.description
Exemplo n.º 8
0
 def test_host_string_denormalization(self):
     username = _get_system_username()
     for description, string1, string2 in (
         ("Sanity check: equal strings remain equal",
             'localhost', 'localhost'),
         ("Empty username is same as get_system_username",
             'localhost:22', username + '@localhost:22'),
         ("Empty port is same as port 22",
             'user@localhost', 'user@localhost:22'),
         ("Both username and port",
             'localhost', username + '@localhost:22'),
     ):
         eq_.description = "Host-string denormalization: %s" % description
         yield eq_, denormalize(string1), denormalize(string2)
         del eq_.description
Exemplo n.º 9
0
 def test_normalization_for_ipv6(self):
     """
     normalize() will accept IPv6 notation and can separate host and port
     """
     username = _get_system_username()
     for description, input, output_ in (
         ("Full IPv6 address", '2001:DB8:0:0:0:0:0:1',
          (username, '2001:DB8:0:0:0:0:0:1', '22')),
         ("IPv6 address in short form", '2001:DB8::1',
          (username, '2001:DB8::1', '22')),
         ("IPv6 localhost", '::1', (username, '::1', '22')),
         ("Square brackets are required to separate non-standard port from IPv6 address",
          '[2001:DB8::1]:1222', (username, '2001:DB8::1', '1222')),
         ("Username and IPv6 address", 'user@2001:DB8::1',
          ('user', '2001:DB8::1', '22')),
         ("Username and IPv6 address with non-standard port",
          'user@[2001:DB8::1]:1222', ('user', '2001:DB8::1', '1222')),
     ):
         eq_.description = "Host-string IPv6 normalization: %s" % description
         yield eq_, normalize(input), output_
         del eq_.description
Exemplo n.º 10
0
 def test_normalization_for_ipv6(self):
     """
     normalize() will accept IPv6 notation and can separate host and port
     """
     username = _get_system_username()
     for description, input, output_ in (
         ("Full IPv6 address",
             '2001:DB8:0:0:0:0:0:1', (username, '2001:DB8:0:0:0:0:0:1', '22')),
         ("IPv6 address in short form",
             '2001:DB8::1', (username, '2001:DB8::1', '22')),
         ("IPv6 localhost",
             '::1', (username, '::1', '22')),
         ("Square brackets are required to separate non-standard port from IPv6 address",
             '[2001:DB8::1]:1222', (username, '2001:DB8::1', '1222')),
         ("Username and IPv6 address",
             'user@2001:DB8::1', ('user', '2001:DB8::1', '22')),
         ("Username and IPv6 address with non-standard port",
             'user@[2001:DB8::1]:1222', ('user', '2001:DB8::1', '1222')),
     ):
         eq_.description = "Host-string IPv6 normalization: %s" % description
         yield eq_, normalize(input), output_
         del eq_.description
Exemplo n.º 11
0
class WovenCommand(BaseCommand):
    option_list = BaseCommand.option_list + (
        make_option(
            '--noinput',
            action='store_false',
            dest='interactive',
            default=True,
            help='Do NOT prompt for input (except password entry if required)'
        ),
        make_option('-r',
                    '--reject-unknown-hosts',
                    action='store_true',
                    default=False,
                    help="reject unknown hosts"),
        make_option('-D',
                    '--disable-known-hosts',
                    action='store_true',
                    default=False,
                    help="do not load user known_hosts file"),
        make_option('-i',
                    action='append',
                    dest='key_filename',
                    default=None,
                    help="path to SSH private key file."),
        make_option('-u',
                    '--user',
                    default=state._get_system_username(),
                    help="username to use when connecting to remote hosts"),
        make_option('-p',
                    '--password',
                    default=None,
                    help="password for use with authentication and/or sudo"),
        make_option(
            '--setup',
            help=
            'The /path/to/dir containing the setup.py module. The command will execute from this directory. Only required if you are not executing the command from below the setup.py directory',
        ),
    )
    help = ""
    args = "host1 [host2 ...] or user@host1 ..."
    requires_model_validation = False

    def handle_host(self, *args, **options):
        """
        This will be executed per host - override in subclass
        """

    def parse_host_args(self, *args):
        """
        Returns a comma separated string of hosts
        """
        return ','.join(args)

    def handle(self, *args, **options):
        """
        Initializes the fabric environment
        """
        self.style = no_style()
        #manage.py execution specific variables
        #verbosity 0 = No output at all, 1 = woven output only, 2 = Fabric outputlevel = everything except debug
        state.env.verbosity = int(options.get('verbosity', 1))

        #show_traceback = options.get('traceback', False)
        state.env.INTERACTIVE = options.get('interactive')

        #Fabric options
        #Django passes in a dictionary instead of the optparse options objects
        for option in options:
            state.env[option] = options[option]

        #args will be tuple. We convert it to a comma separated string for fabric
        all_role_hosts = []

        if args:
            #subclasses can implement parse_host_args to strip out subcommands
            comma_hosts = self.parse_host_args(*args)
            normalized_host_list = comma_hosts.split(',')
            for r in normalized_host_list:
                #define a list of hosts for given roles
                if hasattr(settings, 'ROLEDEFS') and settings.ROLEDEFS.get(r):
                    all_role_hosts += settings.ROLEDEFS[r]
                    state.env['roles'] = state.env['roles'] + [r]
                #simple single host
                else:
                    all_role_hosts.append(r)

        #if no args are given we'll use either a 'default' roledef/role_node
        #or as last resort we'll use a simple HOSTS list
        elif hasattr(settings,
                     'ROLEDEFS') and settings.ROLEDEFS.get('default'):
            all_role_hosts = settings.ROLEDEFS['default']
            state.env['roles'] = ['default']
        elif hasattr(settings, 'HOSTS') and settings.HOSTS:
            all_role_hosts = settings.HOSTS
        else:
            print "Error: You must include a host or role in the command line or set HOSTS or ROLEDEFS in your settings file"
            sys.exit(1)
        state.env['hosts'] = all_role_hosts

        #This next section is taken pretty much verbatim from fabric.main
        #so we follow an almost identical but more limited execution strategy

        #We now need to load django project woven settings into env
        #This is the equivalent to module level execution of the fabfile.py.
        #If we were using a fabfile.py then we would include set_env()

        if int(state.env.verbosity) < 2:
            with hide('warnings', 'running', 'stdout', 'stderr'):
                set_env(settings, state.env.setup)
        else:
            set_env(settings, state.env.setup)

        #Back to the standard execution strategy
        # Set host list (also copy to env)
        state.env.all_hosts = hosts = state.env.hosts
        # If hosts found, execute the function on each host in turn
        for host in hosts:
            # Preserve user
            prev_user = state.env.user
            # Split host string and apply to env dict
            #TODO - This section is replaced by network.interpret_host_string in Fabric 1.0
            username, hostname, port = normalize(host)
            state.env.host_string = host
            state.env.host = hostname
            state.env.user = username
            state.env.port = port

            # Actually run command
            if int(state.env.verbosity) < 2:
                with hide('warnings', 'running', 'stdout', 'stderr'):
                    self.handle_host(*args, **options)
            else:
                self.handle_host(*args, **options)
            # Put old user back
            state.env.user = prev_user