Example #1
0
    def write_config(self, name, server_names, proxy_pass, static_locations='', log_root=None, listen=80):
        """
        Writes an Nginx server configuration file.

        This function writes a specific style of configuration, that seems to be somewhat common, where
        Nginx is used as a reverse-proxy for a locally-running (e.g., WSGI) server.

        :param name: identifies the server name; used to name the configuration file.
        :param server_names:
        :param proxy_pass: identifies the local proxy to which Nginx will pass requests.
        """
        start_msg('----- Writing Nginx server configuration for "{0}":'.format(name))

        # be sure the log directory exists.
        if log_root is None:
            log_root = path.join(cfg().deploy_root, name, 'logs')
        result = sudo('mkdir -p {0}'.format(log_root))
        if result.failed:
            raise HaltError('Unable to create log directory: "{0}"'.format(log_root))

        # generate and write the configuration file.
        server_config = _NGINX_SERVER_CONF.format(**locals())
        dest = path.join(cfg().nginx_include_conf, '{name}.conf'.format(**locals()))
        message('Writing to file: "{0}"'.format(dest))
        put_string(server_config, dest, use_sudo=True)

        succeed_msg('Wrote conf file for "{0}".'.format(name))
        return self
Example #2
0
    def install(self, **kwargs):
        """
        Installs and configures supervisor on the remote machine.

        Supervisor is installed via easy_install, a supervisor.conf file is created with an entry
        to include additional conf files in the directory: cfg().supervisord_include_conf. An init.d
        script is written, and if the program "chkconfig" exists, supervisor is added.

        :return: None
        """
        start_msg('----- Install "supervisord" via "easy_install".')
        result = sudo("easy_install supervisor")
        if result.return_code != 0:
            HaltError('Failed to install "supervisord".')

        result = run("which supervisord")
        if result.return_code != 0:
            raise HaltError('Confusion: just installed "supervisord" but its not there?')

        message("Install successful; setting configuration.")

        # create the root supervisord.conf with an [include] entry that allows loading additional
        # from the folder: /etc/supervisor/conf.d/*.conf
        # we use this location for site-specific config (e.g., a site's [program] section).
        # start with the default conf file; the grep strips comment lines.
        result = run('echo_supervisord_conf | grep "^;.*$" -v')
        if result.failed:
            raise HaltError("Unable to retrieve default supervisord configuration.")

        # build the new configuration by just appending the include definition,
        # then write it to: /etc/supervisord.conf
        files = path.join(cfg().supervisord_include_conf, "*.conf")
        new_conf = "{result}\n\n[include]\nfiles = {files}\n".format(**locals())
        put_string(new_conf, "/etc/supervisord.conf", use_sudo=True)

        # make sure the directory exists.
        result = sudo("mkdir -p {0}".format(cfg().supervisord_include_conf))
        if result.failed:
            raise HaltError('Unable to create include dir: "{0}"'.format(cfg().supervisord_include_conf))

        # finally write an init-script to /etc/init.d so supervisord gets run at startup.
        # TODO: write system-dependent script using "uname -s": OSX=Darwin, Amazon Linux AMI=Linux, ??
        put_string(_INIT_SCRIPT_LINUX, "/etc/init.d/supervisor", use_sudo=True, mode=00755)

        # the Amazon Linux AMI uses chkconfig; the init.d script won't do the job by itself.
        # set supervisord so it can be managed by chkconfig; and turn on boot startup.
        # ubuntu (and Debian?) use UpStart or update-rc.d, so check them out.
        result = run("which chkconfig")
        if result.succeeded:
            message("System has chkconfig; configuring.")
            result = sudo("chkconfig --add supervisor")
            if result.failed:
                raise HaltError('"chkconfig --add supervisor" failed.')

            result = sudo("chkconfig supervisor on")
            if result.failed:
                raise HaltError('"chkconfig supervisor on" failed.')

        succeed_msg('"supervisord" is installed ({0}).'.format(result))
        return self
Example #3
0
    def write_config(self, name, cmd, dir=None, log_root=None, env=None):
        """
        Writes a supervisor [program] entry to a "conf" file.

        The conf file is named "<name>.conf", and is located in the directory identified by:
        cfg().supervisord_include_conf

        Calling this function is typically followed soon after by a call to reload_config().

        :param name:
            specifies the program name.

        :param cmd:
            specifies the command to start the program.

        :param dir:
            specifies the directory to chdir to before executing command. default: no chdir.

        :param log_root:
            specifies the location for supervisor log file.
            default is 'logs' in the deployment root directory.

        :param env:
            specifies the child process environment. default: None.
        """
        start_msg('----- Writing supervisor conf file for "{0}":'.format(name))
        if dir is None:
            dir = ""
        if env is None:
            env = ""
        if not log_root:
            log_root = path.join(cfg().deploy_root, "logs")

        # first be sure the log directory exists. if not supervisor will fail to load the config.
        result = sudo("mkdir -p {0}".format(log_root))
        if result.failed:
            raise HaltError('Unable to create log directory: "{0}"'.format(log_root))

        # now write the entry.
        entry = (
            "[program:{name}]\n"
            "command={cmd}\n"
            "directory={dir}\n"
            "user=nobody\n"
            "autostart=true\n"
            "autorestart=true\n"
            "stdout_logfile={log_root}/{name}.log\n"
            "redirect_stderr=True\n"
            "environment={env}\n".format(**locals())
        )

        dest = path.join(cfg().supervisord_include_conf, "{name}.conf".format(**locals()))
        message('Writing to file: "{0}"'.format(dest))
        put_string(entry, dest, use_sudo=True)
        succeed_msg('Wrote conf file for "{0}".'.format(name))
        return self
Example #4
0
    def check(self, **kwargs):
        """Determines if a key-pair has been generated for this host.

        :return: True if a key-pair exists, False otherwise.
        """
        result = run('test -f {0}'.format(cfg().machine_key_file()))
        return result.succeeded
Example #5
0
    def install(self, **kwargs):
        # install Nginx using the package manager.
        self._simple.install()

        start_msg('----- Configuring "Nginx":')
        # verify that there's an init-script.
        result = run('test -f /etc/init.d/nginx')
        if result.failed:
            raise HaltError('Uh oh. Package manager did not install an Nginx init-script.')

        # write nginx.conf file.
        dest = path.join(cfg().nginx_conf, 'nginx.conf')
        message('Writing "nginx.conf"')
        put_string(_NGINX_CONF, dest, use_sudo=True)

        # the Amazon Linux AMI uses chkconfig; the init.d script won't do the job by itself.
        # set Nginx so it can be managed by chkconfig; and turn on boot startup.
        result = run('which chkconfig')
        if result.succeeded:
            message('System has chkconfig; configuring.')
            result = sudo('chkconfig --add nginx')
            if result.failed:
                raise HaltError('"chkconfig --add nginx" failed.')

            result = sudo('chkconfig nginx on')
            if result.failed:
                raise HaltError('"chkconfig nginx on" failed.')

        succeed_msg('Successfully installed and configured "Nginx".')
        return self
Example #6
0
    def build_instance(self, inst):
        # this seems to mitigate random SSH connection issues.
        disconnect_all()

        builder = Builder(self)
        with settings(host_string=inst.public_dns_name, user=self.user):
            build_name = builder.execute()
            inst.add_tag(cfg().fck_last_good_build, build_name)
Example #7
0
    def build_instance(self, inst):
        # this seems to mitigate random SSH connection issues.
        disconnect_all()

        builder = Builder(self)
        with self.and_instance(inst):
            build_name = builder.execute()
            inst.add_tag(cfg().fck_last_good_build, build_name)
Example #8
0
    def activate_instance(self, inst):
        # this seems to mitigate random SSH connection issues.
        disconnect_all()

        activator = Activator(self)
        with settings(host_string=inst.public_dns_name, user=self.user):
            build_name, port = activator.execute()
            if build_name is not None:
                inst.add_tag(cfg().fck_active_build, '{build_name} ({port})'.format(**locals()))
Example #9
0
def generate_key_pair():
    """
    Generates a private/public key-pair for the host, stored in the ~/.ssh/ directory.

    :return: None
    """
    if not has_key_pair():
        result = run('ssh-keygen -b 1024 -t rsa -N "" -f {0}'.format(cfg().machine_key_file()))
        if result.failed:
            raise HaltError('Unable to generate key pair.')
Example #10
0
    def install(self, **kwargs):
        """Generates a private/public key-pair for the host, stored in the ~/.ssh/ directory.

        :return: self
        """
        result = run('ssh-keygen -b 1024 -t rsa -N "" -f {0}'.format(cfg().machine_key_file()))
        if result.failed:
            raise HaltError('Unable to generate and install key pair.')
        succeed_msg('Key pair generated.')
        return self
Example #11
0
def delete_server_config(name):
    start_msg('----- Deleting server configuration for "{0}":'.format(name))

    # delete the file, but ignore any errors.
    config_name = '{name}.conf'.format(**locals())
    result = sudo('rm -f {0}'.format(path.join(cfg().nginx_include_conf, config_name)))
    if result.failed:
        failed_msg('Ignoring failed attempt to delete configuration "{0}"'.format(config_name))
    else:
        succeed_msg('Successfully deleted configuration "{0}".'.format(config_name))
Example #12
0
def install_internal(name):
    start_msg('----- Running installation for: "{0}":'.format(name))

    info = cfg().tool_info(name)
    if not info:
        raise HaltError('No tool information available for: "{0}"'.format(name))

    cmd = info["yum"] if has_yum() else info["apt"]
    result = sudo(cmd, warn_only=True)
    if result.failed:
        raise HaltError('Failed to install: "{0}".'.format(name))
    succeed_msg('Installed "{0}" successfully.'.format(name))
Example #13
0
def delete_program_config(name):
    """
    Deletes a program entry previously written by write_program_config().

    :param name: specifies the program name used with write_program_config().
    :return: None
    """
    start_msg('----- Removing supervisor program entry for "{0}":'.format(name))
    dest = path.join(cfg().supervisord_include_conf, '{name}.conf'.format(**locals()))
    result = sudo('rm -f {dest}'.format(**locals()))
    if result.failed:
        raise HaltError('Unable to remove entry.')
    succeed_msg('Removed successfully.')
Example #14
0
    def get_public_key(self):
        """Returns a string containing the public key portion of the host's key-pair.

        The key_pair() should have already been installed.

        :return: string containing the host's public key (empty if no key-pair has been generated).
        """
        stream = StringIO()
        if self.check():
            result = get('{0}.pub'.format(cfg().machine_key_file()), stream)
            if result.failed:
                raise HaltError('Unable to retrieve public key file.')
        return stream.getvalue()
Example #15
0
def check_internal(name):
    start_msg('----- Checking for tool "{0}":'.format(name))

    # if info for this tool isn't available, act as though the tool isn't present.
    info = cfg().tool_info(name)
    if not info:
        message('No information available for tool "{0}"'.format(name))
        return False

    # if there's no "check" command, act as though the tool isn't present.
    cmd = info.get("check", None)
    if not cmd:
        message('No check command for tool "{0}"; assuming not installed'.format(name))
        return False

    # otherwise run the check command.
    result = run(cmd, warn_only=True)
    if result.failed:
        failed_msg('Tool "{0}" is not installed.'.format(name))
        return False

    succeed_msg('Tool "{0}" is installed.'.format(name))
    return result.succeeded
Example #16
0
 def create(cls, name):
     info = cfg().tool_info(name)
     if not info:
         raise HaltError('There is no tool-definition for "{0}"'.format(name))
     return SimpleTool(name, info)
Example #17
0
 def repos_root(self):
     return posixpath.join(cfg().deploy_root, self.name, cfg().repos_dir)
Example #18
0
 def builds_root(self):
     return posixpath.join(cfg().deploy_root, self.name, cfg().builds_dir)
Example #19
0
 def all_hosts_in_role(self, role_name):
     hosts = []
     for inst in self._instances.itervalues():
         if role_name == inst.tags.get(cfg().fck_role, None):
             hosts.append(inst)
     return hosts, self.get_role(role_name)
Example #20
0
 def get_host_in_role(self, role_name):
     for inst in self._instances.itervalues():
         instance_role_name = inst.tags.get(cfg().fck_role, None)
         if instance_role_name == role_name:
             return inst, self.get_role(role_name)
     raise RuntimeError('No instance in role "{0}" is available.'.format(role_name))
Example #21
0
def copy_file_from(from_user, from_host, from_path, to_path):
    result = run(
        'scp -o StrictHostKeyChecking=no -i {key} {from_user}@{from_host}:{from_path} {to_path}'
        .format(key=cfg().machine_key_file(), **locals()))
    if result.failed:
        raise HaltError('Unable to copy from {0}:{1}'.format(from_host, from_path))
Example #22
0
 def deactivate_instance(self, inst):
     activator = Activator(self)
     with settings(host_string=inst.public_dns_name, user=self.user):
         activator.deactivate()
         inst.remove_tag(cfg().fck_active_build)
Example #23
0
 def init_instance(self, inst):
     inst.add_tag(cfg().fck_role, self.name)
     ctx().add_instance(inst)
     return inst