コード例 #1
0
ファイル: views.py プロジェクト: huanpc/mesos-admin
def send_to_marathon(request):
    try:
        if request.method == 'POST':
            action = request.POST.get('action', None)
            id = request.POST.get('id', None)
            mc = MarathonClient('http://{}:{}'.format(settings.MARATHON['host'], settings.MARATHON['port']))
            if action == 'stop':
                mc.scale_app(id, 0, force=True)
            elif action == 'start':
                mc.scale_app(id, 1)
            elif action == 'destroy':
                if request.user.has_perm("auth.can_init_app"):
                    mc.delete_app(id)
                else:
                    raise PermissionDenied
            elif action == 'restart':
                mc.restart_app(id)
            elif action == 'scale':
                mc.scale_app(id, int(request.POST.get('number_instance')))
            elif action == 'update':
                app = mc.get_app(id)
                app.cpus = float(request.POST.get('cpus'))
                app.mem = float(request.POST.get('mem'))
                app.container.docker.image = request.POST.get('version')
                mc.update_app(id, app)
            elif action  == "stop-deployment":
                mc.delete_deployment(id)
            result = '{"status":"success", "msg": "%(action)s success"}'%{"action":action}
    except Exception as e:
        result = '{"status":"error", "msg": "%(action)s fail: %(error)s" }'%{"action":action, "error": html.escape(str(e))}
    return HttpResponse(result)
コード例 #2
0
ファイル: views.py プロジェクト: cuongtransc/mesos-admin
def send_to_marathon(request):
    try:
        if request.method == 'POST':
            action = request.POST.get('action', None)
            id = request.POST.get('id', None)
            mc = MarathonClient('http://{}:{}'.format(
                settings.MARATHON['host'], settings.MARATHON['port']))
            if action == 'stop':
                mc.scale_app(id, 0, force=True)
            elif action == 'start':
                mc.scale_app(id, 1)
            elif action == 'destroy':
                if request.user.has_perm("auth.can_init_app"):
                    mc.delete_app(id)
                else:
                    raise PermissionDenied
            elif action == 'restart':
                mc.restart_app(id)
            elif action == 'scale':
                mc.scale_app(id, int(request.POST.get('number_instance')))
            elif action == 'update':
                app = mc.get_app(id)
                app.cpus = float(request.POST.get('cpus'))
                app.mem = float(request.POST.get('mem'))
                app.container.docker.image = request.POST.get('version')
                mc.update_app(id, app)
            elif action == "stop-deployment":
                mc.delete_deployment(id)
            result = '{"status":"success", "msg": "%(action)s success"}' % {
                "action": action
            }
    except Exception as e:
        result = '{"status":"error", "msg": "%(action)s fail: %(error)s" }' % {
            "action": action,
            "error": html.escape(str(e))
        }
    return HttpResponse(result)
コード例 #3
0
def wait_for_deployment(client: MarathonClient,
                        deployment: Union[MarathonDeployment, dict]) -> bool:
    def show_affected_apps(target_deploy):
        for aff in target_deploy.affected_apps:
            print('- {}: {}ui/#/apps/{}/debug'.format(aff, srv,
                                                      aff.replace('/', '%2F')))

    target = None
    if isinstance(deployment, dict):
        if not client.list_deployments():
            print('No deployments in progress. Grace time of 3 seconds.')
            time.sleep(3)
        for current_deployment in client.list_deployments():
            if deployment.get('deploymentId') == current_deployment.id:
                target = current_deployment
    else:
        target = deployment
    if target is None:
        print('Deployment {} not found. Assuming complete.'.format(deployment))
        return False
    if target not in client.list_deployments():
        print('Not found yet. Grace time of 3 seconds.')
        time.sleep(3)
    srv = client.servers if isinstance(client.servers,
                                       str) else client.servers[0]
    print('Watching deployment {}'.format(target.id))
    print('Affected apps:')
    show_affected_apps(target)
    try:
        i = 0
        print('Waiting', end='')
        sys.stdout.flush()
        while target in client.list_deployments():
            time.sleep(0.5)
            i += 0.5
            if i % 5 == 0:
                print('.', end='')
                sys.stdout.flush()
        print()
    except KeyboardInterrupt:
        rollback = input('\nRoll back deployment? Type \'YES\' to confirm: ')
        if rollback == 'YES':
            prompt = 'Force it?\n' \
                     'Doing so does not create a new rollback deployment, but forcefully deletes the current one.\n' \
                     'WARNING: APPLICATION MAY BE STUCK IN AN INCONSISTENT STATE.\n' \
                     'NO FURTHER ROLLBACKS WILL BE PERFORMED (even if launched with `--fullrollback`)\n' \
                     'Type \'YES\' to confirm: '
            if input(prompt) == 'YES':
                client.delete_deployment(target.id, force=True)
                print('Deployment deleted. Check status of applications:')
                show_affected_apps(target)
                sys.exit(2)
            deployment = client.delete_deployment(target.id, force=False)
            print('Rollback deployment launched: {}'.format(
                deployment.get('deploymentId')))
            # Do not wait for this one. It must not be cancelled.
            # TODO: Review options?
            return False

        print('\nDeployment monitoring aborted. Check status in:')
        print('- All deployments: {}/ui/#/deployments'.format(srv))
        show_affected_apps(target)
        sys.exit(1)
    print('Deployment {} complete.'.format(target.id))
    return True
コード例 #4
0
ファイル: mmapi.py プロジェクト: annym/hydra
class MarathonIF(object):
    def __init__(self, marathon_addr, my_addr, mesos):
        self.mcli = MarathonClient(marathon_addr)
        self.myAddr = my_addr
        self.mesos = mesos

    def get_apps(self):
        listapps = self.mcli.list_apps()
        return listapps

    def get_app(self, app_id):
        try:
            a = self.mcli.get_app(app_id)
        except marathon.exceptions.NotFoundError as e:  # NOQA
            return None
        return a

    def delete_app(self, app_id, force=False):
        return self.mcli.delete_app(app_id, force)

    def delete_deployment(self, dep_id):
        return self.mcli.delete_deployment(dep_id)

    def get_deployments(self):
        return self.mcli.list_deployments()

    def delete_app_ifexisting(self, app_id, trys=4):
        for idx in range(0, trys):
            try:
                a = self.get_app(app_id)
                if a:
                    return self.delete_app(app_id)
                return None
            except:
                e = sys.exc_info()[0]
                pprint("<p>Error: %s</p>" % e)
                time.sleep(10)
        raise

    @staticmethod
    def is_valid_app_id(app_id):
        # allowed: lowercase letters, digits, hyphens, slash, dot
        if re.match("^[A-Za-z0-9-/.]*$", app_id):
            return True
        return False

    def create_app(self, app_id, attr):
        """
            Create and start an app.
            :param app_id: (str) - Application ID
            :param attr: marathon.models.app.MarathonApp application to create.
            :return: the created app
        """
        # Validate that app_id conforms to allowed naming scheme.
        if not self.is_valid_app_id(app_id):
            l.error("Error: Only lowercase letters, digits, hyphens are allowed in app_id. %s" % app_id)
            raise Exception("Invalid app_id")

        for idx in range(0, 10):
            try:
                a = self.mcli.create_app(app_id, attr)
                return a
            except marathon.exceptions.MarathonHttpError as e:
                if str(e).find('App is locked by one or more deployments. Override with the option') >= 0:
                    time.sleep(1)
                else:
                    raise
        raise

    def wait_app_removal(self, app):
        cnt = 0
        while True:
            if not self.get_app(app):
                break
            time.sleep(0.2)
            cnt += 1
            if cnt > 0:
                l.info("Stuck waiting for %s to be deleted CNT=%d" % (app, cnt))
        return True

    def wait_app_ready(self, app, running_count):
        cnt = 0
        while True:
            a1 = self.get_app(app)
            if a1.tasks_running == running_count:
                return a1
            cnt += 1
            time.sleep(1)
            if (cnt % 30) == 29:
                l.info("[%d]Waiting for task to move to running stage, " % cnt +
                       "current stat staged=%d running=%d expected Running=%d" %
                       (a1.tasks_staged, a1.tasks_running, running_count))

    def scale_app(self, app, scale):
        return self.mcli.scale_app(app, scale)

    def ping(self):
        return self.mcli.ping()
コード例 #5
0
ファイル: mmapi.py プロジェクト: lorenzodavid/hydra
class MarathonIF(object):
    def __init__(self, marathon_addr, my_addr, mesos):
        self.mcli = MarathonClient(marathon_addr)
        self.myAddr = my_addr
        self.mesos = mesos

    def get_apps(self):
        listapps = self.mcli.list_apps()
        return listapps

    def get_app(self, app_id):
        try:
            a = self.mcli.get_app(app_id)
        except marathon.exceptions.NotFoundError as e:  # NOQA
            return None
        return a

    def delete_app(self, app_id, force=False):
        return self.mcli.delete_app(app_id, force)

    def delete_deployment(self, dep_id):
        return self.mcli.delete_deployment(dep_id)

    def get_deployments(self):
        return self.mcli.list_deployments()

    def delete_app_ifexisting(self, app_id, trys=4):
        for idx in range(0, trys):
            try:
                a = self.get_app(app_id)
                if a:
                    return self.delete_app(app_id)
                return None
            except:
                e = sys.exc_info()[0]
                pprint("<p>Error: %s</p>" % e)
                time.sleep(10)
        raise

    def create_app(self, app_id, attr):
        for idx in range(0, 10):
            try:
                a = self.mcli.create_app(app_id, attr)
                return a
            except marathon.exceptions.MarathonHttpError as e:
                if str(e).find('App is locked by one or more deployments. Override with the option') >= 0:
                    time.sleep(1)
                else:
                    raise
        raise

    def wait_app_removal(self, app):
        cnt = 0
        while True:
            if not self.get_app(app):
                break
            time.sleep(0.2)
            cnt += 1
            if cnt > 0:
                l.info("Stuck waiting for %s to be deleted CNT=%d" % (app, cnt))
        return True

    def wait_app_ready(self, app, running_count):
        cnt = 0
        while True:
            a1 = self.get_app(app)
            if a1.tasks_running == running_count:
                return a1
            cnt += 1
            time.sleep(1)
            if (cnt % 30) == 29:
                l.info("[%d]Waiting for task to move to running stage, " % cnt +
                       "current stat staged=%d running=%d expected Running=%d" %
                       (a1.tasks_staged, a1.tasks_running, running_count))

    def scale_app(self, app, scale):
        return self.mcli.scale_app(app, scale)

    def ping(self):
        return self.mcli.ping()
コード例 #6
0
ファイル: mmapi.py プロジェクト: kratos7/hydra
class MarathonIF(object):
    def __init__(self, marathon_addr, my_addr, mesos):
        self.mcli = MarathonClient(marathon_addr)
        self.myAddr = my_addr
        self.mesos = mesos

    def get_apps(self):
        listapps = self.mcli.list_apps()
        return listapps

    def get_app(self, app_id, timeout=300):
        st_time = time.time()
        while(time.time() - st_time < timeout):
            try:
                try:
                    a = self.mcli.get_app(app_id)
                except marathon.exceptions.NotFoundError as e:  # NOQA
                    return None
                return a
            except:
                l.info("mcli: get_app returned error")
                l.info(traceback.format_exc())
                l.info("Retrying after 10 secs timeout=%d", timeout)
                time.sleep(10)
        raise Exception("mcli get_app timed out, possible zookeper/marathon/mesos malfunction")

    def delete_app(self, app_id, force=False, timeout=200):
        st_time = time.time()
        while(time.time() - st_time < timeout):
            try:
                self.mcli.delete_app(app_id, force)
                return
            except:
                l.info("mcli: delete_app returned error")
                l.info(traceback.format_exc())
                l.info("Retrying after 10 secs timeout=%d", timeout)
                time.sleep(10)
        raise Exception("mcli delete_app timed out, possible zookeper/marathon/mesos malfunction")

    def delete_deployment(self, dep_id):
        return self.mcli.delete_deployment(dep_id)

    def get_deployments(self):
        return self.mcli.list_deployments()

    def delete_app_ifexisting(self, app_id, trys=4):
        for idx in range(0, trys):
            try:
                a = self.get_app(app_id)
                if a:
                    return self.delete_app(app_id)
                return None
            except:
                e = sys.exc_info()[0]
                pprint("<p>Error: %s</p>" % e)
                time.sleep(10)
        raise

    @staticmethod
    def is_valid_app_id(app_id):
        # allowed: lowercase letters, digits, hyphens, slash, dot
        if re.match("^[A-Za-z0-9-/.]*$", app_id):
            return True
        return False

    def create_app(self, app_id, attr):
        """
            Create and start an app.
            :param app_id: (str) - Application ID
            :param attr: marathon.models.app.MarathonApp application to create.
            :return: the created app
        """
        # Validate that app_id conforms to allowed naming scheme.
        if not self.is_valid_app_id(app_id):
            l.error("Error: Only lowercase letters, digits, hyphens are allowed in app_id. %s" % app_id)
            raise Exception("Invalid app_id")

        for idx in range(0, 10):
            try:
                a = self.mcli.create_app(app_id, attr)
                return a
            except marathon.exceptions.MarathonHttpError as e:
                if str(e).find('App is locked by one or more deployments. Override with the option') >= 0:
                    time.sleep(1)
                else:
                    raise
        raise

    def wait_app_removal(self, app):
        cnt = 0
        while True:
            if not self.get_app(app):
                break
            time.sleep(0.2)
            cnt += 1
            if cnt > 0:
                l.info("Stuck waiting for %s to be deleted CNT=%d" % (app, cnt))
        return True

    def wait_app_ready(self, app, running_count, sleep_before_next_try=1):
        cnt = 0
        while True:
            a1 = self.get_app(app)
            # if tasks_running are greater (due to whatever reason, scale down accordingly)
            if a1.tasks_running > running_count:
                delta = a1.tasks_running - running_count
                l.info("Found [%d] more apps, scaling down to [%d]", delta, running_count)
                self.scale_app(app, running_count)
                # Allow for some time before next poll
                time.sleep(1)
                continue
            if a1.tasks_running == running_count:
                return a1
            cnt += 1
            time.sleep(sleep_before_next_try)
            if (cnt % 30) == 29:
                l.info("[%d]Waiting for task to move to running stage, " % cnt +
                       "current stat staged=%d running=%d expected Running=%d" %
                       (a1.tasks_staged, a1.tasks_running, running_count))

    def scale_app(self, app, scale, timeout=300):
        st_time = time.time()
        while(time.time() - st_time < timeout):
            try:
                self.mcli.scale_app(app, scale)
                return
            except:
                l.info("mcli: scale_app returned error")
                l.info(traceback.format_exc())
                l.info("Retrying after 10 secs timeout=%d", timeout)
                time.sleep(10)
        raise Exception("mcli scale_app timed out, possible zookeper/marathon/mesos malfunction")

    def ping(self):
        return self.mcli.ping()

    def kill_task(self, app_id, task_id):
        return self.mcli.kill_task(app_id, task_id)
コード例 #7
0
ファイル: mmapi.py プロジェクト: tahir24434/hydra
class MarathonIF(object):
    def __init__(self, marathon_addr, my_addr, mesos):
        self.mcli = MarathonClient(marathon_addr)
        self.myAddr = my_addr
        self.mesos = mesos

    def get_apps(self):
        listapps = self.mcli.list_apps()
        return listapps

    def get_app(self, app_id, timeout=300):
        st_time = time.time()
        while (time.time() - st_time < timeout):
            try:
                try:
                    a = self.mcli.get_app(app_id)
                except marathon.exceptions.NotFoundError as e:  # NOQA
                    return None
                return a
            except:
                l.info("mcli: get_app returned error")
                l.info(traceback.format_exc())
                l.info("Retrying after 10 secs timeout=%d", timeout)
                time.sleep(10)
        raise Exception(
            "mcli get_app timed out, possible zookeper/marathon/mesos malfunction"
        )

    def delete_app(self, app_id, force=False, timeout=200):
        st_time = time.time()
        while (time.time() - st_time < timeout):
            try:
                self.mcli.delete_app(app_id, force)
                return
            except:
                l.info("mcli: delete_app returned error")
                l.info(traceback.format_exc())
                l.info("Retrying after 10 secs timeout=%d", timeout)
                time.sleep(10)
        raise Exception(
            "mcli delete_app timed out, possible zookeper/marathon/mesos malfunction"
        )

    def delete_deployment(self, dep_id):
        return self.mcli.delete_deployment(dep_id)

    def get_deployments(self):
        return self.mcli.list_deployments()

    def delete_app_ifexisting(self, app_id, trys=4):
        for idx in range(0, trys):
            try:
                a = self.get_app(app_id)
                if a:
                    return self.delete_app(app_id)
                return None
            except:
                e = sys.exc_info()[0]
                pprint("<p>Error: %s</p>" % e)
                time.sleep(10)
        raise

    @staticmethod
    def is_valid_app_id(app_id):
        # allowed: lowercase letters, digits, hyphens, slash, dot
        if re.match("^[A-Za-z0-9-/.]*$", app_id):
            return True
        return False

    def create_app(self, app_id, attr):
        """
            Create and start an app.
            :param app_id: (str) - Application ID
            :param attr: marathon.models.app.MarathonApp application to create.
            :return: the created app
        """
        # Validate that app_id conforms to allowed naming scheme.
        if not self.is_valid_app_id(app_id):
            l.error(
                "Error: Only lowercase letters, digits, hyphens are allowed in app_id. %s"
                % app_id)
            raise Exception("Invalid app_id")

        for idx in range(0, 10):
            try:
                a = self.mcli.create_app(app_id, attr)
                return a
            except marathon.exceptions.MarathonHttpError as e:
                if str(
                        e
                ).find('App is locked by one or more deployments. Override with the option'
                       ) >= 0:
                    time.sleep(1)
                else:
                    raise
        raise

    def wait_app_removal(self, app):
        cnt = 0
        while True:
            if not self.get_app(app):
                break
            time.sleep(0.2)
            cnt += 1
            if cnt > 0:
                l.info("Stuck waiting for %s to be deleted CNT=%d" %
                       (app, cnt))
        return True

    def wait_app_ready(self, app, running_count, sleep_before_next_try=1):
        cnt = 0
        while True:
            a1 = self.get_app(app)
            # if tasks_running are greater (due to whatever reason, scale down accordingly)
            if a1.tasks_running > running_count:
                delta = a1.tasks_running - running_count
                l.info("Found [%d] more apps, scaling down to [%d]", delta,
                       running_count)
                self.scale_app(app, running_count)
                # Allow for some time before next poll
                time.sleep(1)
                continue
            if a1.tasks_running == running_count:
                return a1
            cnt += 1
            time.sleep(sleep_before_next_try)
            if (cnt % 30) == 29:
                l.info(
                    "[%d]Waiting for task to move to running stage, " % cnt +
                    "current stat staged=%d running=%d expected Running=%d" %
                    (a1.tasks_staged, a1.tasks_running, running_count))

    def scale_app(self, app, scale, timeout=300):
        st_time = time.time()
        while (time.time() - st_time < timeout):
            try:
                self.mcli.scale_app(app, scale)
                return
            except:
                l.info("mcli: scale_app returned error")
                l.info(traceback.format_exc())
                l.info("Retrying after 10 secs timeout=%d", timeout)
                time.sleep(10)
        raise Exception(
            "mcli scale_app timed out, possible zookeper/marathon/mesos malfunction"
        )

    def ping(self):
        return self.mcli.ping()

    def kill_task(self, app_id, task_id):
        return self.mcli.kill_task(app_id, task_id)