示例#1
0
def wait_for_lock():
    if hasattr(env, 'deploy_user'):
        lock_user = env.deploy_user
    else:
        lock_user = env.user

    LOCK_ID = 'u:{user} h:{host} pid:{pid}'.format(user=lock_user,
                                    host=socket.gethostname(),
                                pid=str(os.getpid()))
    sleep_time = 0.1
    timeout = 120
    start_time = time.time()

    with settings(warn_only=True):
        while True:
            wait_time = time.time() - start_time

            # break if the lockfile is removed or if it belongs to this pid
            # if it exists lock_status will have the file's contents

            with hide('running', 'stdout', 'stderr', 'warnings'):
                lock_status = run("test ! -f {lfile} || "
                                  "(cat {lfile} && "
                                  'grep -q "{lid}" {lfile})'.format(
                                      lfile=LOCK_FILE,
                                      lid=LOCK_ID))

                if lock_status.succeeded:
                    noopable(sudo)('echo "{0}" > {1}'.format(
                        LOCK_ID, LOCK_FILE))
                    notify("Took lock")
                    break

                elif wait_time >= timeout:
                    abort("Timeout expired, giving up")

                lock_create_time = run("stat -c %Y {0}".format(LOCK_FILE))

            delta = time.time() - float(lock_create_time)
            (dhour, dsec) = divmod(delta, 3600)

            notify("""

        !! Deploy lockfile already exists ({lockfile}) !!
            Waiting: {wait}s
            Lockfile info: [ {owner} ]
            Lock created: {dhour}h{dmin}m ago
            """.format(
                        lockfile=LOCK_FILE,
                        wait=int(timeout - wait_time),
                        owner=lock_status,
                        dhour=int(dhour),
                        dmin=int(dsec / 60),
                        ))
            time.sleep(sleep_time)
            sleep_time *= 2
            if sleep_time > MAX_SLEEP_TIME:
                sleep_time = MAX_SLEEP_TIME
示例#2
0
def wait_for_lock():
    if hasattr(env, 'deploy_user'):
        lock_user = env.deploy_user
    else:
        lock_user = env.user

    LOCK_ID = 'u:{user} h:{host} pid:{pid}'.format(user=lock_user,
                                                   host=socket.gethostname(),
                                                   pid=str(os.getpid()))
    sleep_time = 0.1
    timeout = 120
    start_time = time.time()

    with settings(warn_only=True):
        while True:
            wait_time = time.time() - start_time

            # break if the lockfile is removed or if it belongs to this pid
            # if it exists lock_status will have the file's contents

            with hide('running', 'stdout', 'stderr', 'warnings'):
                lock_status = run("test ! -f {lfile} || "
                                  "(cat {lfile} && "
                                  'grep -q "{lid}" {lfile})'.format(
                                      lfile=LOCK_FILE, lid=LOCK_ID))

                if lock_status.succeeded:
                    noopable(sudo)('echo "{0}" > {1}'.format(
                        LOCK_ID, LOCK_FILE))
                    notify("Took lock")
                    break

                elif wait_time >= timeout:
                    abort("Timeout expired, giving up")

                lock_create_time = run("stat -c %Y {0}".format(LOCK_FILE))

            delta = time.time() - float(lock_create_time)
            (dhour, dsec) = divmod(delta, 3600)

            notify("""

        !! Deploy lockfile already exists ({lockfile}) !!
            Waiting: {wait}s
            Lockfile info: [ {owner} ]
            Lock created: {dhour}h{dmin}m ago
            """.format(
                lockfile=LOCK_FILE,
                wait=int(timeout - wait_time),
                owner=lock_status,
                dhour=int(dhour),
                dmin=int(dsec / 60),
            ))
            time.sleep(sleep_time)
            sleep_time *= 2
            if sleep_time > MAX_SLEEP_TIME:
                sleep_time = MAX_SLEEP_TIME
示例#3
0
    def wrapper(*args, **kwargs):
        elb = boto.connect_elb()

        elbs = elb.get_all_load_balancers()
        execute('locks.wait_for_all_locks')

        inst_id = instance_id()
        tags = ['task:' + func.__name__] + instance_tags(inst_id)
        active_lbs = sorted(lb for lb in elbs
                            if inst_id in [info.id for info in lb.instances])

        timer = partial(dog_stats_api.timer, tags=tags)

        # Remove this node from the LB
        for lb in active_lbs:
            notify("Removing {id} from {lb}".format(id=inst_id, lb=lb))

            with timer('rolling.deregister_instance'):
                noopable(lb.deregister_instances)([inst_id])
                noopable(await_elb_instance_state)(lb, inst_id, "OutOfService")

        # Execute the operation
        func(*args, **kwargs)

        # Add this node back to the LBs
        for lb in active_lbs:
            notify("Adding {id} to {lb}".format(id=inst_id, lb=lb))
            with timer('rolling.register_instance'):
                noopable(lb.register_instances)([inst_id])

        with timer('rolling.wait_for_start'):
            # Wait for the node to come online in the LBs
            for lb in active_lbs:
                noopable(await_elb_instance_state)(lb, inst_id, "InService")
示例#4
0
def status():
    """
    Drops {0} which is a json formatted file that contains a
    status message that will be displayed to all users on the
    on the courseware for a single course or for all courses
    if 'global' is set.

    Message(s) are entered or removed interactively on the console.

    Example usage:

        $ fab groups:prod_edx status

    """.format(status_file)

    with hide('running', 'stdout', 'stderr', 'warnings'):
        env_json = sudo("cat /opt/wwc/lms-xml.env.json")
    course_listings = json.loads(env_json)['COURSE_LISTINGS']
    course_ids = [course_id for course_list in course_listings.itervalues()
                  for course_id in course_list]
    course_ids = ['global'] + course_ids

    with no_ts():

        course_status = None
        with settings(warn_only=True):
            cur_status = noopable(sudo)('cat {0}'.format(status_file))
        try:
            course_status = json.loads(cur_status)
            # add empty entries for courses not in the list
            empty_entries = set(course_ids) - set(course_status.keys())
            course_status.update({entry: '' for entry in list(empty_entries)})

        except ValueError:
            fastprint(red("Not a valid json file, overwritting\n"))
        if course_status is None:
            course_status = {course: '' for course in course_ids}
        new_status = multi_choose_with_input(
                'Set the status message, blank to disable:',
                course_status)

        if new_status is not None:
            # remove empty entries
            new_status = {entry: new_status[entry]
                    for entry in new_status if len(new_status[entry]) > 1}
            with unsquelched():
                if not console.confirm(
                        'Setting new status message:\n{0}'.format(
                            blue(str(new_status), bold=True)),
                            default=False):
                    abort('Operation cancelled by user')

                with tempfile.NamedTemporaryFile(delete=True) as f:
                    f.write(json.dumps(new_status))
                    f.flush()
                    execute(update_status, f.name)
        else:
            abort('Operation cancelled by user')
示例#5
0
    def wrapper(*args, **kwargs):
        elb = boto.connect_elb()

        elbs = elb.get_all_load_balancers()
        execute('locks.wait_for_all_locks')

        inst_id = instance_id()
        tags = ['task:' + func.__name__] + instance_tags(inst_id)
        active_lbs = sorted(
            lb
            for lb in elbs
            if inst_id in [info.id for info in lb.instances]
        )

        timer = partial(dog_stats_api.timer, tags=tags)

        # Remove this node from the LB
        for lb in active_lbs:
            notify("Removing {id} from {lb}".format(id=inst_id, lb=lb))

            with timer('rolling.deregister_instance'):
                noopable(lb.deregister_instances)([inst_id])
                noopable(await_elb_instance_state)(lb, inst_id, "OutOfService")

        # Execute the operation
        func(*args, **kwargs)

        # Add this node back to the LBs
        for lb in active_lbs:
            notify("Adding {id} to {lb}".format(id=inst_id, lb=lb))
            with timer('rolling.register_instance'):
                noopable(lb.register_instances)([inst_id])

        with timer('rolling.wait_for_start'):
            # Wait for the node to come online in the LBs
            for lb in active_lbs:
                noopable(await_elb_instance_state)(lb, inst_id, "InService")
示例#6
0
def unmaintain_service(service):
    """
    Removes a specified edxapp service from maintenance mode by replacing
    the appropriate link in /etc/nginx/sites-enabled.
    """

    if service not in services:
        raise Exception("Provided service not in the service inventory. "
                        "Acceptable values are {services}".format(
            services=services
        ))

    noopable(sudo)("rm -f /etc/nginx/sites-enabled/{service}-maintenance".format(
        service=service))

    noopable(sudo)("ln -s /etc/nginx/sites-available/{service}"
                   " /etc/nginx/sites-enabled/{service}".format(
        service=service))

    noopable(sudo)("service nginx reload")
示例#7
0
def maintain_service(service):
    """
    Puts a specified edxapp service into maintenance mode by replacing
    its nginx sites-enabled link with a link to the maintenance vhost.
    """

    if service not in services:
        raise Exception("Provided service not in the service inventory. "
                        "Acceptable values are {services}".format(
            services=services
        ))

    noopable(sudo)("rm -f /etc/nginx/sites-enabled/{service}".format(
        service=service))

    noopable(sudo)("ln -s /etc/nginx/sites-available/{service}-maintenance"
                   " /etc/nginx/sites-enabled/{service}-maintenance".format(
        service=service))

    noopable(sudo)("service nginx reload")
示例#8
0
def remove_lock():
    noopable(sudo)("test ! -f {0} || rm {0}".format(LOCK_FILE))
示例#9
0
def remove_status():
    noopable(sudo)('rm -f {0}'.format(status_file))
示例#10
0
def update_status(fjson):
    print status_file
    noopable(put)(fjson, status_file, use_sudo=True)
示例#11
0
def apt_get_clean():
    """ Runs apt-get clean on a remote server """
    noopable(sudo)('apt-get clean')
示例#12
0
def mako_template_cache():
    noopable(sudo)('service gunicorn stop')
    noopable(sudo)('rm -rf /tmp/tmp*mako')
    noopable(sudo)('service gunicorn start')
示例#13
0
def apt_get_clean():
    """ Runs apt-get clean on a remote server """
    noopable(sudo)('apt-get clean')   
示例#14
0
def update_status(fjson):
    print status_file
    noopable(put)(fjson, status_file, use_sudo=True)
示例#15
0
def remove_lock():
    noopable(sudo)("test ! -f {0} || rm {0}".format(LOCK_FILE))
示例#16
0
def status():
    """
    Drops {0} which is a json formatted file that contains a
    status message that will be displayed to all users on the
    on the courseware for a single course or for all courses
    if 'global' is set.

    Message(s) are entered or removed interactively on the console.

    Example usage:

        $ fab groups:prod_edx status

    """.format(status_file)

    with hide('running', 'stdout', 'stderr', 'warnings'):
        env_json = sudo("cat /opt/wwc/lms-xml.env.json")
    course_listings = json.loads(env_json)['COURSE_LISTINGS']
    course_ids = [
        course_id for course_list in course_listings.itervalues()
        for course_id in course_list
    ]
    course_ids = ['global'] + course_ids

    with no_ts():

        course_status = None
        with settings(warn_only=True):
            cur_status = noopable(sudo)('cat {0}'.format(status_file))
        try:
            course_status = json.loads(cur_status)
            # add empty entries for courses not in the list
            empty_entries = set(course_ids) - set(course_status.keys())
            course_status.update({entry: '' for entry in list(empty_entries)})

        except ValueError:
            fastprint(red("Not a valid json file, overwritting\n"))
        if course_status is None:
            course_status = {course: '' for course in course_ids}
        new_status = multi_choose_with_input(
            'Set the status message, blank to disable:', course_status)

        if new_status is not None:
            # remove empty entries
            new_status = {
                entry: new_status[entry]
                for entry in new_status if len(new_status[entry]) > 1
            }
            with unsquelched():
                if not console.confirm(
                        'Setting new status message:\n{0}'.format(
                            blue(str(new_status), bold=True)),
                        default=False):
                    abort('Operation cancelled by user')

                with tempfile.NamedTemporaryFile(delete=True) as f:
                    f.write(json.dumps(new_status))
                    f.flush()
                    execute(update_status, f.name)
        else:
            abort('Operation cancelled by user')
示例#17
0
def remove_status():
    noopable(sudo)('rm -f {0}'.format(status_file))
示例#18
0
def mako_template_cache():
    noopable(sudo)('service gunicorn stop')
    noopable(sudo)('rm -rf /tmp/tmp*mako')
    noopable(sudo)('service gunicorn start')
示例#19
0
def set_maintenance(value):
    noopable(put)(StringIO(json.dumps({'maintenance': value})), '/etc/facter/facts.d/mitx_maintenance.json', use_sudo=True)