示例#1
0
def call_slave_start(app_logger, uuidcode, app_database, app_urls, userfolder,
                     jlab_path, quota_config, set_user_quota, user_id,
                     servername, email, environments, image, port,
                     jupyterhub_api_url):
    next_slave_id, next_slave_hostname = utils_db.get_next_slave(
        app_logger, uuidcode, app_database)
    if next_slave_id == 0:
        app_logger.error(
            "uuidcode={} - Could not find any slaves in database".format(
                uuidcode))
        raise Exception("No Slaves available")
    header = {
        "Intern-Authorization": utils_file_loads.get_j4j_dockerspawner_token(),
        "uuidcode": uuidcode
    }
    body = {
        "email": email,
        "environments": environments,
        "image": image,
        "port": port,
        "servername": servername,
        "jupyterhub_api_url": jupyterhub_api_url
    }
    url = app_urls.get('dockerspawner',
                       {}).get('url_jlab_hostname', '<no_url_found>').replace(
                           '<hostname>', next_slave_hostname)
    try:
        with closing(
                requests.post(url, headers=header, json=body,
                              verify=False)) as r:
            if r.status_code != 202:
                app_logger.error(
                    "uuidcode={} - DockerSpawner answered .post with {} {}".
                    format(uuidcode, r.text, r.status_code))
                return False
    except:
        app_logger.exception(
            "uuidcode={} - DockerSpawner post failed".format(uuidcode))
        return False
    utils_db.insert_container(app_logger, uuidcode, app_database, user_id,
                              next_slave_id, servername)
    user_running = utils_db.get_user_running(app_logger, uuidcode,
                                             app_database, user_id)
    utils_db.increase_slave_running(app_logger, uuidcode, app_database,
                                    next_slave_id)
    jlab_output = "{};{};{};{};{};{};{};{};{}".format(
        userfolder, email.replace("@", "_at_"), uuidcode,
        quota_config.get('ALL', "25g"), quota_config.get('WORK', "10g"),
        quota_config.get('PROJECTS', "10g"), quota_config.get('HOME', "512m"),
        set_user_quota, user_running == 1)

    app_logger.debug("uuidcode={} - Write {} to {}".format(
        uuidcode, jlab_output, os.path.join(jlab_path, uuidcode)))
    with open(os.path.join(jlab_path, uuidcode), 'w') as f:
        f.write(jlab_output)
    return True
def validate_auth(app_logger, uuidcode, intern_authorization):
    if not intern_authorization == None:
        token = get_j4j_dockerspawner_token()
        if intern_authorization == token:
            app_logger.debug(
                "uuidcode={} - intern-authorization validated".format(
                    uuidcode))
            return
    app_logger.warning(
        "uuidcode={} - Could not validate Intern-Authorization".format(
            uuidcode))
    abort(401)
 def delete(self):
     """
     Headers
         Intern-Authorization
         uuidcode
         email
     """
     try:
         # Track actions through different webservices.
         uuidcode = request.headers.get('uuidcode', '<no uuidcode>')
         app.log.info("uuidcode={} - Delete Account".format(uuidcode))
         app.log.trace("uuidcode={} - Headers: {}".format(uuidcode, request.headers))
 
         # Check for the J4J intern token
         utils_common.validate_auth(app.log,
                                    uuidcode,
                                    request.headers.get('intern-authorization', None))
         request_headers = {}
         for key, value in request.headers.items():
             if 'Token' in key: # refresh, jhub, access
                 key = key.replace('-', '_')
             request_headers[key.lower()] = value           
         
         config = utils_file_loads.get_general_config()
         email = request_headers.get('email', '<no_email_submitted>')
         email = email.replace("@", "_at_")
         basefolder = config.get('basefolder', '<no basefolder defined>')
         userfolder = os.path.join(basefolder, email)
         
         user_id = utils_db.get_user_id(app.log,
                                        uuidcode,
                                        app.database,
                                        email)
         
         servernames = utils_db.get_all_user_container_names(app.log,
                                                             uuidcode,
                                                             app.database,
                                                             user_id)
         for servername in servernames:            
             results = jlab_utils.get_slave_infos(app.log,
                                                  uuidcode,
                                                  app.database,
                                                  servername,
                                                  email)
             if len(results) > 0:
                 user_id, slave_id, slave_hostname, containername, running_no = results
             else:
                 app.log.warning("uuidcode={} - {} not in database".format(uuidcode, servername))
                 continue;
         
             url = app.urls.get('dockerspawner', {}).get('url_jlab_hostname', '<no_url_found>').replace('<hostname>', slave_hostname)
             headers = {"Intern-Authorization": utils_file_loads.get_j4j_dockerspawner_token(),
                        "uuidcode": uuidcode,
                        "containername": containername}
             try:
                 with closing(requests.delete(url,
                                              headers=headers,
                                              verify=False)) as r:
                     if r.status_code != 202:
                         app.log.error("uuidcode={} - DockerSpawner delete failed: {} {}".format(uuidcode, r.text, r.status_code))
             except:
                 app.log.exception("uuidcode={} - Could not call DockerSpawner {}".format(uuidcode, slave_hostname))
             serverfolder = Path(os.path.join(userfolder, '.{}'.format(containername)))
             utils_db.decrease_slave_running(app.log, uuidcode, app.database, slave_id)
             utils_db.remove_container(app.log, uuidcode, app.database, user_id, servername)
             log_dir = Path(os.path.join(config.get('jobs_path', '<no_jobs_path>'), "{}-{}".format(email, containername)))
             try:
                 os.makedirs(log_dir, exist_ok=True)
                 shutil.copy2(os.path.join(serverfolder, ".jupyterlabhub.log"), os.path.join(log_dir, "jupyterlabhub.log"))
             except:
                 app.log.exception("uuidcode={} - Could not copy log".format(uuidcode))
             jlab_output = "{};{};{}".format(userfolder,
                                             containername,
                                             running_no == 1)
             jlab_delete_path = config.get('jlab_delete', '<no_jlab_delete_defined>')
             app.log.debug("uuidcode={} - Write {} to {}".format(uuidcode, jlab_output, os.path.join(jlab_delete_path, uuidcode)))
             with open(os.path.join(jlab_delete_path, uuidcode), 'w') as f:
                 f.write(jlab_output)
         # end for loop all containers are stopped
         utils_db.delete_account(app.log,
                                 uuidcode,
                                 app.database,
                                 user_id)
         try:
             #shutil.rmtree(userfolder)
             app.log.error("uuidcode={} - Account deletion. Please remove {} from the disk.".format(uuidcode, userfolder))
             # remove user quota from xfs_quota
             jlab_output = "{}".format(uuidcode)
             jlab_delete_path = config.get('jlab_delete', '<no_jlab_delete_defined>')
             app.log.debug("uuidcode={} - Write {} to {}.deletion".format(uuidcode, jlab_output, os.path.join(jlab_delete_path, email)))
             with open('{}.deletion'.format(os.path.join(jlab_delete_path, email)), 'w') as f:
                 f.write(jlab_output)
         except:
             app.log.exception("uuidcode={} - Could not delete the users directories".format(uuidcode))
         
     except:
         app.log.exception("Deletion.delete failed. Bugfix required")
         return "", 500
     return '', 204
示例#4
0
    def get(self):
        """
        Headers:
            intern-authorization
            uuidcode
            email
            servername
            
        """
        try:
            # Track actions through different webservices.
            uuidcode = request.headers.get('uuidcode', '<no uuidcode>')
            app.log.info(
                "uuidcode={} - Get JupyterLab Status".format(uuidcode))
            app.log.trace("uuidcode={} - Headers: {}".format(
                uuidcode, request.headers))

            # Check for the J4J intern token
            utils_common.validate_auth(
                app.log, uuidcode,
                request.headers.get('intern-authorization', None))

            request_headers = {}
            for key, value in request.headers.items():
                if 'Token' in key:  # refresh, jhub, access
                    key = key.replace('-', '_')
                request_headers[key.lower()] = value
            email = request_headers.get('email', '<no_email_submitted>')
            email = email.replace("@", "_at_")
            app.log.trace("uuidcode={} - Get User ID for email: {}".format(
                uuidcode, email))
            servername = request_headers.get('servername',
                                             '<no_servername_submitted>6')
            user_id = utils_db.get_user_id(app.log, uuidcode, app.database,
                                           email)

            app.log.trace("uuidcode={} - User_id: {}".format(
                uuidcode, user_id))
            results = utils_db.get_container_info(app.log, uuidcode,
                                                  app.database, user_id,
                                                  servername)
            if len(results) > 0:
                slave_id, containername = results
            else:
                app.log.error(
                    "uuidcode={} - Containerinfo is empty for: user_id: {} , servername={}"
                    .format(uuidcode, user_id, servername))
                return "unknown", 200

            if slave_id == 0:
                app.log.error(
                    "uuidcode={} - Could not check if container {} is running".
                    format(uuidcode, containername))
                return "unknown", 200
            slave_hostname = utils_db.get_slave_hostname(
                app.log, uuidcode, app.database, slave_id)
            url = app.urls.get('dockerspawner', {}).get(
                'url_jlab_hostname',
                '<no_url_found>').replace('<hostname>', slave_hostname)
            header = {
                "Intern-Authorization":
                utils_file_loads.get_j4j_dockerspawner_token(),
                "uuidcode":
                uuidcode,
                "containername":
                containername
            }
            with closing(requests.get(url, headers=header, verify=False)) as r:
                if r.status_code == 200:
                    app.log.trace(
                        "uuidcode={} - Answer from DockerSpawner {}: {}".
                        format(uuidcode, slave_hostname, r.text.strip()))
                    return r.text.strip(), 200
                else:
                    app.log.error(
                        "uuidcode={} - Could not check if container {} is running. DockerSpawner answered with: {} {}"
                        .format(uuidcode, containername, r.text,
                                r.status_code))
                    return "unknown", 200
        except:
            app.log.exception("JLab.get failed. Bugfix required")
        return '', 202
示例#5
0
def create_server_dirs(app_logger, uuidcode, app_urls, app_database, service,
                       dashboard, user_id, email, servername, serverfolder,
                       basefolder):
    results = utils_db.get_container_info(app_logger, uuidcode, app_database,
                                          user_id, servername)
    app_logger.debug("uuidcode={} - Container Info: {}".format(
        uuidcode, results))
    if len(results) > 0:
        app_logger.debug(
            "uuidcode={} - Server with name {} already exists. Delete it.".
            format(uuidcode, serverfolder))
        config = utils_file_loads.get_general_config()
        user_id, slave_id, slave_hostname, containername, running_no = jlab_utils.get_slave_infos(
            app_logger, uuidcode, app_database, servername, email)

        url = app_urls.get('dockerspawner', {}).get('url_jlab_hostname',
                                                    '<no_url_found>').replace(
                                                        '<hostname>',
                                                        slave_hostname)
        headers = {
            "Intern-Authorization":
            utils_file_loads.get_j4j_dockerspawner_token(),
            "uuidcode": uuidcode,
            "containername": containername
        }
        try:
            with closing(requests.delete(url, headers=headers,
                                         verify=False)) as r:
                if r.status_code != 202:
                    app_logger.error(
                        "uuidcode={} - DockerSpawner delete failed: {} {}".
                        format(uuidcode, r.text, r.status_code))
        except:
            app_logger.exception(
                "uuidcode={} - Could not call DockerSpawner {}".format(
                    uuidcode, slave_hostname))
        basefolder = config.get('basefolder', '<no basefolder defined>')
        userfolder = os.path.join(basefolder, email)
        serverfolder = Path(
            os.path.join(userfolder, '.{}'.format(containername)))
        utils_db.decrease_slave_running(app_logger, uuidcode, app_database,
                                        slave_id)
        utils_db.remove_container(app_logger, uuidcode, app_database, user_id,
                                  servername)
        log_dir = Path(
            os.path.join(config.get('jobs_path', '<no_jobs_path>'),
                         "{}-{}".format(email, containername)))
        try:
            os.makedirs(log_dir, exist_ok=True)
            shutil.copy2(os.path.join(serverfolder, ".jupyterlabhub.log"),
                         os.path.join(log_dir, "jupyterlabhub.log"))
        except:
            app_logger.exception(
                "uuidcode={} - Could not copy log".format(uuidcode))

        jlab_output = "{};{};{}".format(userfolder, servername,
                                        running_no == 1)
        jlab_delete_path = config.get('jlab_delete',
                                      '<no_jlab_delete_defined>')
        app_logger.debug("uuidcode={} - Write {} to {}".format(
            uuidcode, jlab_output, os.path.join(jlab_delete_path, uuidcode)))
        with open(os.path.join(jlab_delete_path, uuidcode), 'w') as f:
            f.write(jlab_output)

    # Create folder for this JupyterLab
    if not serverfolder.exists():
        b2drop = Path(os.path.join(serverfolder, "B2DROP"))
        hpcmount = Path(os.path.join(serverfolder, "HPCMOUNT"))
        projects = Path(os.path.join(serverfolder, "Projects"))
        myprojects = Path(os.path.join(projects, "MyProjects"))
        sharedprojects = Path(os.path.join(projects, "SharedProjects"))
        serverfolder.mkdir()
        os.chmod(serverfolder, 0o777)
        b2drop.mkdir()
        os.chown(b2drop, 1000, 100)
        hpcmount.mkdir()
        os.chown(hpcmount, 1000, 100)
        projects.mkdir()
        os.chown(projects, 1000, 100)
        myprojects.mkdir()
        os.chown(myprojects, 1000, 100)
        sharedprojects.mkdir()
        os.chown(sharedprojects, 1000, 100)

    # Copy files to user home
    if service == "Dashboard":
        app_logger.debug(
            "{} - Try to copy base_home/.config_{}.py and base_home/.start_{}.sh"
            .format(uuidcode, dashboard.replace(" ", "_"),
                    dashboard.replace(" ", "_")))
        base_start_sh = Path(
            os.path.join(basefolder, "base_home",
                         ".start_{}.sh".format(dashboard.replace(" ", "_"))))
        base_config_py = Path(
            os.path.join(basefolder, "base_home",
                         ".config_{}.py".format(dashboard.replace(" ", "_"))))
    else:
        base_config_py = Path(
            os.path.join(basefolder, "base_home", ".config.py"))
        base_start_sh = Path(os.path.join(basefolder, "base_home",
                                          ".start.sh"))
    user_start_sh = Path(os.path.join(serverfolder, ".start.sh"))
    shutil.copy2(base_start_sh, user_start_sh)
    os.chown(user_start_sh, 1000, 100)
    user_config_py = Path(os.path.join(serverfolder, ".config.py"))
    shutil.copy2(base_config_py, user_config_py)
    os.chown(user_config_py, 1000, 100)
    base_jovyan = Path(
        os.path.join(basefolder, "base_home", ".who_is_jovyan.txt"))
    user_jovyan = Path(os.path.join(serverfolder, ".who_is_jovyan.txt"))
    shutil.copy2(base_jovyan, user_jovyan)
    os.chown(user_jovyan, 1000, 100)
    base_mounthpc_sh = Path(
        os.path.join(basefolder, "base_home", "mount_hpc.sh"))
    user_mounthpc_sh = Path(os.path.join(serverfolder, "mount_hpc.sh"))
    shutil.copy2(base_mounthpc_sh, user_mounthpc_sh)
    os.chown(user_mounthpc_sh, 1000, 100)
    base_manageprojects_sh = Path(
        os.path.join(basefolder, "base_home", "manage_projects.sh"))
    user_manageprojects_sh = Path(
        os.path.join(serverfolder, "manage_projects.sh"))
    shutil.copy2(base_manageprojects_sh, user_manageprojects_sh)
    os.chown(user_manageprojects_sh, 1000, 100)
    base_faq_ipynb = Path(os.path.join(basefolder, "base_home", "FAQ.ipynb"))
    user_faq_ipynb = Path(os.path.join(serverfolder, "FAQ.ipynb"))
    shutil.copy2(base_faq_ipynb, user_faq_ipynb)
    os.chown(user_faq_ipynb, 1000, 100)
示例#6
0
def call_slave_start(app_logger, uuidcode, app_database, app_urls, accesstoken, expire, userfolder, config, quota_config, set_user_quota, user_id, servername, email, environments, image, port, jupyterhub_api_url):
    user_running = utils_db.get_user_running(app_logger, uuidcode, app_database, user_id)
    if user_running >= config.get('user_running_limit', 10):
        app_logger.error("uuidcode={} - User has already {} JupyterLabs running (Limit: {}). Cancel start.".format(uuidcode, user_running, config.get('user_running_limit', 5)))
        try:
            # we have to sleep for 2 seconds, otherwise JupyterHub is not ready for this call
            sleep(2)
            cancel(app_logger,
                   uuidcode,
                   config.get('jupyterhub_cancel_url', '<no_jupyterhub_cancel_url_defined>'),
                   environments.get('JUPYTERHUB_API_TOKEN'),
                   "Due to heavy load on the HDF-Cloud, the access is currently limited to {} JupyterLabs per user.".format(config.get('user_running_limit', 10)),
                   email.replace("_at_", "@"),
                   servername)
        except:
            app_logger.exception("uuidcode={} - Could not cancel start.".format(uuidcode))
        return False
    next_slave_id, next_slave_hostname = utils_db.get_next_slave(app_logger, uuidcode, app_database)
    if next_slave_id == 0:
        app_logger.error("uuidcode={} - Could not find any slaves in database".format(uuidcode))
        raise Exception("No Slaves available")
    header = {
             "Intern-Authorization": utils_file_loads.get_j4j_dockerspawner_token(),
             "uuidcode": uuidcode,
             "accesstoken": accesstoken,
             "expire": expire
             }
    body = {
           "email": email,
           "environments": environments,
           "image": image,
           "port": port,
           "servername": servername,
           "jupyterhub_api_url": jupyterhub_api_url
           }
    url = app_urls.get('dockerspawner', {}).get('url_jlab_hostname', '<no_url_found>').replace('<hostname>', next_slave_hostname)
    try:
        with closing(requests.post(url,
                                   headers=header,
                                   json=body,
                                   verify=False)) as r:
            if r.status_code != 202:
                app_logger.error("uuidcode={} - DockerSpawner answered .post with {} {}".format(uuidcode, r.text, r.status_code))
                return False
    except:
        app_logger.exception("uuidcode={} - DockerSpawner post failed".format(uuidcode))
        return False
    utils_db.insert_container(app_logger, uuidcode, app_database, user_id, next_slave_id, servername)
    user_running = utils_db.get_user_running(app_logger, uuidcode, app_database, user_id)
    utils_db.increase_slave_running(app_logger, uuidcode, app_database, next_slave_id)
    jlab_output = "{};{};{};{};{};{};{};{};{}".format(userfolder,
                                                      email.replace("@", "_at_"),
                                                      uuidcode,
                                                      quota_config.get('ALL', "25g"),
                                                      quota_config.get('WORK', "10g"),
                                                      quota_config.get('PROJECTS', "10g"),
                                                      quota_config.get('HOME', "512m"),
                                                      set_user_quota,
                                                      user_running == 1)
    
    app_logger.debug("uuidcode={} - Write {} to {}".format(uuidcode, jlab_output, os.path.join(config.get('jlab', '<no_jlab_path_defined>'), uuidcode)))
    with open(os.path.join(config.get('jlab', '<no_jlab_path_defined>'), uuidcode), 'w') as f:
        f.write(jlab_output)
    return True