Esempio n. 1
0
 def build_student_docker(self, image_name, docker, private_key, public_key, user_name, user_psw, user_email, user_token, git_host, git_port, teacher_token, docker_namespace, mem_limit='256m'):
     result, message = GitLabUtil.get_user(git_host, git_port, teacher_token)
     if not result:
         self.logger.info(message)
         return 2
     try:
         teacher_id = json.loads(message)["id"]
         teacher_name = json.loads(message)["username"]
     except Exception:
         return 3
     project_name = docker.name
     dockerfile_text = self._format_ucore_dockerfile_text(docker, private_key, public_key, user_name, user_psw, user_email, git_host, docker_namespace)
     dockerfile_path = self._create_tmp_dockerfile(dockerfile_text)
     result, message = GitLabUtil.create_private_project(git_host, git_port, user_token, project_name)
     if not result:
         self.logger.info(message)
         return 4
     result, message = GitLabUtil.add_project_developer(git_host, git_port, user_token, user_name, project_name, teacher_id)
     if not result:
         self.logger.info(message)
         return 5
     cmd = "docker --tlsverify --tlscacert={0} --tlscert={1} --tlskey={2} -H={3}:{4} build --rm -t {5} {6}"
     cmd = cmd.format(self._ca, self._cert, self._key, self._host, self._port, image_name, dockerfile_path)
     process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     (std_output, err_output) = process.communicate(timeout=60*5)
     if err_output != '':
         return 6
     cmd = "docker --tlsverify --tlscacert={0} --tlscert={1} --tlskey={2} -H={3}:{4} create -p :8080 -p :6080 -m {5} {6}"
     cmd = cmd.format(self._ca, self._cert, self._key, self._host, self._port, mem_limit, image_name)
     process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     (std_output, err_output) = process.communicate(timeout=15)
     if err_output != '':
         return 7
     docker.container_id = std_output
     return 0
    def build_student_docker(self, image_name, docker_obj, private_key, public_key, user_name, user_psw, user_email, user_token, git_host, git_port, teacher_token, docker_namespace):
        self.logger.info("DockerHelper.build_student_docker")
        result, message = GitLabUtil.get_user(git_host, git_port, teacher_token)
        if not result:
            self.logger.info(message)
            return
        teacher_id = json.loads(message)["id"]
        teacher_name = json.loads(message)["username"]

        project_name = docker_obj.name
        docker_file_text = self._create_ucore_docker_file(docker_obj, private_key, public_key, user_name, user_psw, user_email, git_host, git_port, docker_namespace, teacher_name)
        docker_file = BytesIO(docker_file_text.encode('utf-8'))

        result, message = GitLabUtil.create_private_project(git_host, git_port, user_token, project_name)
        if not result:
            self.logger.info(message)
            return

        result, message = GitLabUtil.add_project_developer(git_host, git_port, user_token, user_name, project_name, teacher_id)
        if not result:
            self.logger.info(message)
            return

        response = [line for line in self._client.build(tag=image_name, rm=True, fileobj=docker_file)]
        self.logger.info("build docker result:")
        for line in response:
            self.logger.info(line)

        container = self._client.create_container(image=image_name, ports=[8080])
        self.logger.info("docker.create_container:")
        self.logger.info(container)
        docker_obj.container_id = container["Id"]
        self.logger.info("DockerHelper.build_student_docker.complete")
Esempio n. 3
0
    def build_student_docker(self, image_name, docker_obj, private_key,
                             public_key, user_name, user_psw, user_email,
                             user_token, git_host, git_port, teacher_token,
                             docker_namespace):
        self.logger.info("DockerHelper.build_student_docker")
        result, message = GitLabUtil.get_user(git_host, git_port,
                                              teacher_token)
        if not result:
            self.logger.info(message)
            return
        teacher_id = json.loads(message)["id"]
        teacher_name = json.loads(message)["username"]

        project_name = docker_obj.name
        docker_file_text = self._create_ucore_docker_file(
            docker_obj, private_key, public_key, user_name, user_psw,
            user_email, git_host, git_port, docker_namespace, teacher_name)
        docker_file = BytesIO(docker_file_text.encode('utf-8'))

        result, message = GitLabUtil.create_private_project(
            git_host, git_port, user_token, project_name)
        if not result:
            self.logger.info(message)
            return

        result, message = GitLabUtil.add_project_developer(
            git_host, git_port, user_token, user_name, project_name,
            teacher_id)
        if not result:
            self.logger.info(message)
            return

        response = [
            line for line in self._client.build(
                tag=image_name, rm=True, fileobj=docker_file)
        ]
        self.logger.info("build docker result:")
        for line in response:
            self.logger.info(line)

        container = self._client.create_container(image=image_name,
                                                  ports=[8080])
        self.logger.info("docker.create_container:")
        self.logger.info(container)
        docker_obj.container_id = container["Id"]
        self.logger.info("DockerHelper.build_student_docker.complete")
    def build_student_docker(self, image_name, docker, private_key, public_key, user_name, user_psw, user_email, user_token, git_host, git_port, teacher_token, docker_namespace, mem_limit='256m'):
        result, message = GitLabUtil.get_user(git_host, git_port, teacher_token)
        if not result:
            self.logger.info(message)
            return 2
        try:
            teacher_id = json.loads(message)["id"]
            teacher_name = json.loads(message)["username"]
        except Exception:
            return 3
        project_name = docker.name
        dockerfile_text = self._format_ucore_dockerfile_text(docker, private_key, public_key, user_name, user_psw, user_email, git_host, docker_namespace)
        dockerfile_path = self._create_tmp_dockerfile(dockerfile_text)
        result, message = GitLabUtil.create_private_project(git_host, git_port, user_token, project_name)
        if not result:
	    self.logger.info(user_token + project_name)
            self.logger.info(message)
            self.logger.info("hhhhhhhhhhhhh1")
            return 4
        #result, message = GitLabUtil.add_project_developer(git_host, git_port, user_token, user_name, project_name, teacher_id)
        #if not result:
	#    self.logger.info(user_token + " "+project_name)
        #    self.logger.info(message)
        #    self.logger.info("hhhhhhhhhhhhhh2")
        #    return 5
        cmd = "docker --tlsverify --tlscacert={0} --tlscert={1} --tlskey={2} -H={3}:{4} build --rm -t {5} {6}"
        cmd = cmd.format(self._ca, self._cert, self._key, self._host, self._port, image_name, dockerfile_path)
	self.logger.info(cmd)
        process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        (std_output, err_output) = process.communicate()#timeout=60*5)
        if err_output != '':
            return 6
        cmd = "docker --tlsverify --tlscacert={0} --tlscert={1} --tlskey={2} -H={3}:{4} create -p :8080 -p :6080 -m {5} {6}"
        cmd = cmd.format(self._ca, self._cert, self._key, self._host, self._port, mem_limit, image_name)
        process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        (std_output, err_output) = process.communicate()#timeout=15)
        docker.container_id = std_output
        if err_output != '':
            return 7
        docker.container_id = std_output
        return 0
Esempio n. 5
0
    def student_view(self, context=None):

        # runtime error
        if not hasattr(self.runtime, "anonymous_student_id"):
            return self.message_view("Error in uc_docker (get anonymous student id)", "Cannot get anonymous_student_id in runtime", context)

        # preview in studio
        if self.runtime.anonymous_student_id == "student":

            result, message = GitLabUtil.get_user_projects(self.git_host, self.git_port, self.git_teacher_token)
            if not result:
                return self.message_view("Error in uc_docker (get git projects)", "Cannot get user's projects in git", context)

            context_dict = {
                "labs": self.labs,
                "message": ""
            }
            fragment = Fragment()
            fragment.add_content(Util.render_template('static/html/uc_lab.html', context_dict))
            fragment.add_css(Util.load_resource("static/css/uc_docker.css"))
            fragment.add_javascript(Util.load_resource("static/js/src/uc_lab.js"))
            fragment.initialize_js("UcDockerXBlock")
            return fragment

        # student view in open-edx
        if self.is_new:
            # create git account when first visiting
            student = self.runtime.get_real_user(self.runtime.anonymous_student_id)
            email = student.email
            name = student.first_name + " " + student.last_name
            username = student.username
            self.git_password = Util.create_random_password()
            # first_name, last_name are empty
            if name == " ":
                name = username
            self.logger.info("password is " + self.git_password)

            self.logger.info(self.git_host + "," + str(self.git_port) + "," + self.git_admin_token + "," + name + "," + username + "," + email + "," + self.git_password)
            result, message = GitLabUtil.create_account(self.git_host, self.git_port, self.git_admin_token, name, username, email, self.git_password)
            self.logger.info("create_account result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view("Error in uc_docker (create git account)", message, context)

            result, message = GitLabUtil.login(self.git_host, self.git_port, username, self.git_password)
            self.logger.info("login result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view("Error in uc_docker (login git account)", message, context)

            try:
                message = json.loads(message)
                self.git_id = message["id"]
                self.git_user_token = message["private_token"]
            except Exception, ex:
                return self.message_view("Error in uc_docker (load json string)", message, context)

            try:
                self.private_key, self.public_key = Util.gen_ssh_keys(email)
            except Exception, ex:
                return self.message_view("Error in uc_docker (gen ssh key)", ex, context)
Esempio n. 6
0
    def student_view(self, context=None):

        # runtime error
        if not hasattr(self.runtime, "anonymous_student_id"):
            return self.message_view(
                "Error in ibm_docker (get anonymous student id)" +
                "Cannot get anonymous_student_id in runtime", None)

        # preview in studio
        if self.runtime.anonymous_student_id == "student":
            cluster_list = []

            conn = pymongo.Connection('localhost', 27017)
            db = conn.test
            db.authenticate(self.mongo_admin, self.mongo_pwd)
            cluster = db.cluster
            for i in cluster.find():
                new_cluster = Cluster()
                new_cluster.set_name(i["cluster_name"])
                new_cluster.set_user(i["username"])
                new_cluster.set_id(i["cluster_id"])
                new_cluster.set_creation_time(i["creation_time"])
                new_cluster.set_status(i["status"])
                new_cluster.set_ip(i["ip"])
                cluster_list.append(new_cluster.object_to_dict())

            context_dict = {"clusters": cluster_list, "message": ""}
            fragment = Fragment()
            fragment.add_content(
                Util.render_template('static/html/ibm_clusters.html',
                                     context_dict))
            fragment.add_css(Util.load_resource("static/css/ibm_docker.css"))
            #fragment.add_javascript(Util.load_resource("static/js/src/uc_lab.js"))
            fragment.initialize_js("IBMDockerTestXBlock")
            return fragment

        student = self.runtime.get_real_user(self.runtime.anonymous_student_id)
        email = student.email
        name = student.first_name + " " + student.last_name
        username = student.username

        # temporary code ,not used in next course
        conn = pymongo.Connection('localhost', 27017)
        db = conn.test
        db.authenticate(self.mongo_admin, self.mongo_pwd)
        token = db.token
        result = token.find_one({"username": username})
        conn.disconnect()

        #I dont now why the cluster cannot be shown in page directly
        temp_clusters = self.clusters

        if self.is_new and not result:
            # create git account when first visiting

            # get teacher id
            #result, message = GitLabUtil.get_user(self.git_host, self.git_port, self.git_teacher_token)
            #self.logger.info("get teacher id")
            #self.logger.info(result)
            #self.logger.info(message)
            #if not result:
            #    return self.message_view("Error in get teacher info")
            #try:
            #    message = json.loads(message)
            #    teacher_id = message["id"]
            #except Exception:
            #    return self.message_view("Error in uc_docker (load json string)", message, context)

            #add teacher to developer
            #result, message = GitLabUtil.add_project_developer(self.git_host, self.git_port, self.git_user_token, username, self.git_project_name, teacher_id)
            #self.logger.info("add developer result:")
            #self.logger.info(result)
            #self.logger.info(message)
            #if not result:
            #    return self.message_view("Error in uc_docker (add teacher to developer)", message, context)
            conn = pymongo.Connection('localhost', 27017)
            db = conn.test
            db.authenticate(self.mongo_admin, self.mongo_pwd)
            ibm = db.ibm
            result = ibm.find_one({"email": email})
            if not result:
                return self.message_view(
                    "Error in ibm_docker (get shibboleth account info). detail"
                    + message, temp_clusters)

            self.ldap_name = result["name"]
            self.ldap_pwd = result["password"]

            #get user id by email
            result, message = GitLabUtil.get_userid(self.git_host,
                                                    self.git_port,
                                                    self.git_admin_token,
                                                    self.ldap_name)
            self.logger.info("get user id result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in ibm_docker (get user id). detail" + message,
                    temp_clusters)
            self.git_id = message["id"]
            self.save()

            result, message = GitLabUtil.create_project(
                self.git_host, self.git_port, self.git_admin_token,
                self.git_import_url, self.git_project_name, self.git_id)
            self.logger.info("add project result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in ibm_docker (add project). detail:" + message,
                    temp_clusters)

            try:
                conn = pymongo.Connection('localhost', 27017)
                db = conn.test
                db.authenticate(self.mongo_admin, self.mongo_pwd)
                token = db.token
                result = token.find_one({"username": username})
                if not result:
                    self.private_key, self.public_key = Util.gen_ssh_keys(
                        email)
                    #self.logger.info("private_key:" + self.private_key)
                    self.save()
                    token.insert({
                        "username": username,
                        "private_key": self.private_key,
                        "public_key": self.public_key
                    })
                else:
                    self.private_key = result["private_key"]
                    self.public_key = result["public_key"]
                    self.save()
                conn.disconnect()

            except Exception, ex:
                return self.message_view(
                    "Error in ibm_docker (gen ssh key). detail:" + ex, context)

            result, message = GitLabUtil.add_ssh_key(
                self.git_host, self.git_port, self.git_admin_token,
                "ucore default", self.public_key, self.git_id)
            self.logger.info("add_ssh_key result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in ibm_docker (add git ssh key). detail:" + message,
                    temp_clusters)

            self.is_new = False
            self.save()
Esempio n. 7
0
    def create_docker(self, data, suffix=""):

        if self.is_empty == True:
            ret = self.cluster_helper.cluster_create()
            if ret["success"] == False:
                return {"result": False, "message": ret["messages"]}

            self.cluster_id = ret["clusters"][0]["id"]
            self.is_empty = False
            cluster_name = ret["clusters"][0]["name"]
            cluster_status = "creating"
            cluster_creation_time = datetime.datetime.strftime(
                datetime.datetime.today(), "%Y-%m-%d %H:%M:%S")

            cluster = Cluster()
            cluster.set_id(self.cluster_id)
            cluster.set_name(cluster_name)
            cluster.set_status(cluster_status)
            cluster.set_creation_time(cluster_creation_time)
            self.clusters.append(cluster.object_to_dict())
            self.save()
            time.sleep(40)

        #create cluster is a asynchronous api,so we should read status constantly to get ip
        #if user already have docker,the code below will update docker info
        for i in range(60):
            try:
                ret = self.cluster_helper.cluster_show(self.cluster_id)
            except Exception:
                #self.logger.info("fail to get ip,cluster id: " + self.cluster_id + " should try again")
                if i == 59:
                    return {"result": False, "message": "time out to get ip"}
                time.sleep(10)
                continue

            if ret["success"] == False:
                self.clear_docker_info()
                return {"result": False, "message": ret["messages"]}
            if ret["status"] == "CREATE_FAILED":
                self.clear_docker_info()
                return {"result": False, "message": "docker create failed"}
            if ret["status"] == "CREATE_COMPLETE":
                break
            time.sleep(10)

        cluster_ip = ret["ext_ip"]
        self.clusters[0]["ip"] = cluster_ip
        self.clusters[0]["status"] = "CREATE_COMPLETE"

        #get webshell url
        #get webshell url,may be failed with service or name unknown
        for i in range(10):
            try:
                ret = self.cluster_helper.get_webshell(self.user_Authorization,
                                                       cluster_ip)
                if ret["success"] == False:
                    return {"result": False, "message": ret["messages"]}
                break
            except Exception:
                #self.logger.info("fail to get webshell ,should try again")
                if i == 9:
                    return {
                        "result": False,
                        "message": "time out to get webshell"
                    }
                time.sleep(1)
                continue

        self.clusters[0]["webshell"] = ret["url"]
        self.save()

        student = self.runtime.get_real_user(self.runtime.anonymous_student_id)
        username = student.username
        email = student.email

        conn = pymongo.Connection('localhost', 27017)
        db = conn.test
        db.authenticate(self.mongo_admin, self.mongo_pwd)
        cluster = db.cluster
        result = cluster.find_one({"cluster_id": self.clusters[0]["id"]})
        if not result:
            cluster_name = self.clusters[0]["name"]
            cluster_id = self.clusters[0]["id"]
            creation_time = self.clusters[0]["creation_time"]
            ip = self.clusters[0]["ip"]
            status = self.clusters[0]["status"]
            cluster.insert({
                "username": username,
                "cluster_name": cluster_name,
                "cluster_id": cluster_id,
                "creation_time": creation_time,
                "ip": ip,
                "status": status
            })
            self.logger.info("username:"******" create cluster,cluster_name:" + cluster_name +
                             " cluster_id:" + cluster_id + " creation_time:" +
                             creation_time + " ip" + ip + " status: " + status)

            #start timer to delete docker after 4 hours
            t = Timer(self.delete_time * 3600, auto_delete_docker, (self, ))
            t.start()

            # initialize docker
            # get user's name and pwd in ldap
            ibm = db.ibm
            result_ibm = ibm.find_one({"email": email})
            if not result_ibm:
                return {
                    "result": False,
                    "message": "fail to get shibboleth account info"
                }

            self.ldap_name = result_ibm["name"]
            self.ldap_pwd = result_ibm["password"]

            #wait for docker to start
            time.sleep(10)
            for i in range(20):
                try:
                    self.docker_helper.init_user(ip, self.ldap_name,
                                                 self.ldap_pwd)
                    break
                except Exception:
                    self.logger.info(
                        "fail to get ssh to docker,should try again")
                    if i == 19:
                        return {
                            "result": False,
                            "message": "time out to initialize docker"
                        }
                    time.sleep(5)
                    continue
            #get private and public key to initialize git config
            token = db.token
            result_token = token.find_one({"username": username})
            if not result_token:
                return {
                    "result":
                    False,
                    "message":
                    "initialize git config in docker failed,could not find private key"
                }

            try:
                #get user repo url,should place the code below on line 154,but for some reason place here temporarily
                result_git, message = GitLabUtil.get_userid(
                    self.git_host, self.git_port, self.git_admin_token,
                    self.ldap_name)
                if not result_git:
                    return {
                        "result": False,
                        "message": "fail to get user repo url"
                    }
                self.git_name = message["username"]
                self.save()
                self.docker_helper.init_git(ip, self.ldap_name, self.ldap_pwd,
                                            email, self.git_name,
                                            result_token["private_key"],
                                            result_token["public_key"])
            except Exception:
                return {
                    "result": False,
                    "message": "fail to initialize docker"
                }

        conn.disconnect()
        return {"result": True}
    def student_view(self, context=None):

        # runtime error
        if not hasattr(self.runtime, "anonymous_student_id"):
            return self.message_view("Error in uc_docker (get anonymous student id)", "Cannot get anonymous_student_id in runtime", context)

        # preview in studio
        if self.runtime.anonymous_student_id == "student":

            result, message = GitLabUtil.get_user_projects(self.git_host, self.git_port, self.git_teacher_token)
            if not result:
                return self.message_view("Error in uc_docker (get git projects)", "Cannot get user's projects in git", context)

            context_dict = {
                "labs": self.labs,
                "message": ""
            }
            fragment = Fragment()
            fragment.add_content(Util.render_template('static/html/uc_lab.html', context_dict))
            fragment.add_css(Util.load_resource("static/css/uc_docker.css"))
            fragment.add_javascript(Util.load_resource("static/js/src/uc_lab.js"))
            fragment.initialize_js("UcDockerXBlock")
            return fragment

        # student view in open-edx
        if self.is_new:
            # create git account when first visiting
            student = self.runtime.get_real_user(self.runtime.anonymous_student_id)
            email = student.email
            name = student.first_name + " " + student.last_name
            username = student.username
            self.git_password = Util.create_random_password()
            self.save()
            # first_name, last_name are empty
            if name == " ":
                name = username
            self.logger.info("password is " + self.git_password)

	    # create ldap account
	    l = ldap.initialize(self.ldap_url) 
	    l.bind(self.principal_name, self.ldap_password) 
	    dn= "uid=" + username + "," + self.base_dn

	    attrs = {}
	    attrs['objectclass'] = ['top','inetOrgPerson','eduPerson']
	    attrs['cn'] = str(username)
	    attrs['sn'] = str(username)
	    attrs['givenName'] = str(username)
	    attrs['uid'] = str(username)
	    attrs['userPassword'] = str(self.git_password)
	    attrs['description'] = 'ldap user for shibboleth'
	    attrs['eduPersonPrincipalName'] = str(email)

	    # Convert our dict to nice syntax for the add-function using modlist-module
	    ldif = modlist.addModlist(attrs)
	    l.add_s(dn,ldif)
	    l.unbind_s()
	    self.logger.info("create ldap account " + username + "," + dn)

            self.logger.info(self.git_host + "," + str(self.git_port) + "," + self.git_admin_token + "," + name + "," + username + "," + email + "," + self.git_password)
            result, message = GitLabUtil.create_account(self.git_host, self.git_port, self.git_admin_token, name, username, email, self.git_password)
            self.logger.info("create_account result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view("Error in uc_docker (create git account)", message, context)

            result, message = GitLabUtil.login(self.git_host, self.git_port, username, self.git_password)
            self.logger.info("login result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view("Error in uc_docker (login git account)", message, context)

            try:
                message = json.loads(message)
                self.git_id = message["id"]
                self.git_user_token = message["private_token"]
                self.save()
               
            except Exception, ex:
                return self.message_view("Error in uc_docker (load json string)", message, context)

            try:
                self.private_key, self.public_key = Util.gen_ssh_keys(email)
                self.logger.info("private_key:" + self.private_key)
                self.save()
                conn=pymongo.Connection('localhost', 27017)
                db = conn.test
                token=db.token
                token.insert({"username":username,"token":message["private_token"],"password":self.git_password,"private_key":self.private_key,"public_key":self.public_key})
                conn.disconnect()

            except Exception, ex:
                return self.message_view("Error in uc_docker (gen ssh key)", ex, context)
    def student_view(self, context=None):

        # runtime error
        if not hasattr(self.runtime, "anonymous_student_id"):
            return self.message_view(
                "Error in uc_docker (get anonymous student id)",
                "Cannot get anonymous_student_id in runtime", context)

        # preview in studio
        if self.runtime.anonymous_student_id == "student":

            result, message = GitLabUtil.get_user_projects(
                self.git_host, self.git_port, self.git_teacher_token)
            if not result:
                return self.message_view(
                    "Error in uc_docker (get git projects)",
                    "Cannot get user's projects in git", context)

            context_dict = {"labs": self.labs, "message": ""}
            fragment = Fragment()
            fragment.add_content(
                Util.render_template('static/html/uc_lab.html', context_dict))
            fragment.add_css(Util.load_resource("static/css/uc_docker.css"))
            fragment.add_javascript(
                Util.load_resource("static/js/src/uc_lab.js"))
            fragment.initialize_js("UcDockerXBlock")
            return fragment

        # student view in open-edx
        if self.is_new:
            # create git account when first visiting
            student = self.runtime.get_real_user(
                self.runtime.anonymous_student_id)
            email = student.email
            name = student.first_name + " " + student.last_name
            username = student.username
            self.git_password = Util.create_random_password()
            self.save()
            # first_name, last_name are empty
            if name == " ":
                name = username
            self.logger.info("password is " + self.git_password)

            # create ldap account
            l = ldap.initialize(self.ldap_url)
            l.bind(self.principal_name, self.ldap_password)
            dn = "uid=" + username + "," + self.base_dn

            attrs = {}
            attrs['objectclass'] = ['top', 'inetOrgPerson', 'eduPerson']
            attrs['cn'] = str(username)
            attrs['sn'] = str(username)
            attrs['givenName'] = str(username)
            attrs['uid'] = str(username)
            attrs['userPassword'] = str(self.git_password)
            attrs['description'] = 'ldap user for shibboleth'
            attrs['eduPersonPrincipalName'] = str(email)

            # Convert our dict to nice syntax for the add-function using modlist-module
            ldif = modlist.addModlist(attrs)
            l.add_s(dn, ldif)
            l.unbind_s()
            self.logger.info("create ldap account " + username + "," + dn)

            self.logger.info(self.git_host + "," + str(self.git_port) + "," +
                             self.git_admin_token + "," + name + "," +
                             username + "," + email + "," + self.git_password)
            result, message = GitLabUtil.create_account(
                self.git_host, self.git_port, self.git_admin_token, name,
                username, email, self.git_password)
            self.logger.info("create_account result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (create git account)", message,
                    context)

            result, message = GitLabUtil.login(self.git_host, self.git_port,
                                               username, self.git_password)
            self.logger.info("login result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (login git account)", message, context)

            try:
                message = json.loads(message)
                self.git_id = message["id"]
                self.git_user_token = message["private_token"]
                self.save()

            except Exception, ex:
                return self.message_view(
                    "Error in uc_docker (load json string)", message, context)

            try:
                self.private_key, self.public_key = Util.gen_ssh_keys(email)
                self.logger.info("private_key:" + self.private_key)
                self.save()
                conn = pymongo.Connection('localhost', 27017)
                db = conn.test
                token = db.token
                token.insert({
                    "username": username,
                    "token": message["private_token"],
                    "password": self.git_password,
                    "private_key": self.private_key,
                    "public_key": self.public_key
                })
                conn.disconnect()

            except Exception, ex:
                return self.message_view("Error in uc_docker (gen ssh key)",
                                         ex, context)
class UcDockerXBlock(XBlock):

    logger = Util.uc_logger()

    is_new = Boolean(default=True, scope=Scope.user_state, help="is new")
    private_key = String(default="",
                         scope=Scope.user_state,
                         help="SHH Private Key")
    public_key = String(default="",
                        scope=Scope.user_state,
                        help="SHH Public Key")
    git_password = String(default="",
                          scope=Scope.user_state,
                          help="Git password")
    git_id = Integer(default="", scope=Scope.user_state, help="Git id")
    git_user_token = String(default="",
                            scope=Scope.user_state,
                            help="Git private token")
    dockers = List(default=[], scope=Scope.user_state, help="dockers")

    labs = List(default=[], scope=Scope.content, help="labs")

    # config
    CONFIG = Config.CONFIG
    git_host = CONFIG["GIT"]["HOST"]
    git_port = CONFIG["GIT"]["PORT"]
    git_admin_token = CONFIG["GIT"]["ADMIN_TOKEN"]
    docker_host = CONFIG["DOCKER"]["HOST"]
    docker_url = CONFIG["DOCKER"]["REMOTE_API"]["URL"]
    docker_namespace = CONFIG["DOCKER"]["NAMESPACE"]
    docker_mem = CONFIG["DOCKER"]["MEM_LIMIT"]
    ca = CONFIG["DOCKER"]["REMOTE_API"]["CA"]
    cert = CONFIG["DOCKER"]["REMOTE_API"]["CERT"]
    key = CONFIG["DOCKER"]["REMOTE_API"]["KEY"]
    version = CONFIG["DOCKER"]["REMOTE_API"]["VERSION"]
    git_teacher_token = CONFIG["GIT"]["TEACHER"]["TOKEN"]

    principal_name = CONFIG["LDAP"]["PRINCIPAL_NAME"]
    ldap_password = CONFIG["LDAP"]["PASSWORD"]
    ldap_url = CONFIG["LDAP"]["LDAP_URL"]
    base_dn = CONFIG["LDAP"]["BASE_DN"]

    docker_helper = DockerRawHelper(docker_host, docker_url, ca, cert, key)

    def student_view(self, context=None):

        # runtime error
        if not hasattr(self.runtime, "anonymous_student_id"):
            return self.message_view(
                "Error in uc_docker (get anonymous student id)",
                "Cannot get anonymous_student_id in runtime", context)

        # preview in studio
        if self.runtime.anonymous_student_id == "student":

            result, message = GitLabUtil.get_user_projects(
                self.git_host, self.git_port, self.git_teacher_token)
            if not result:
                return self.message_view(
                    "Error in uc_docker (get git projects)",
                    "Cannot get user's projects in git", context)

            context_dict = {"labs": self.labs, "message": ""}
            fragment = Fragment()
            fragment.add_content(
                Util.render_template('static/html/uc_lab.html', context_dict))
            fragment.add_css(Util.load_resource("static/css/uc_docker.css"))
            fragment.add_javascript(
                Util.load_resource("static/js/src/uc_lab.js"))
            fragment.initialize_js("UcDockerXBlock")
            return fragment

        # student view in open-edx
        if self.is_new:
            # create git account when first visiting
            student = self.runtime.get_real_user(
                self.runtime.anonymous_student_id)
            email = student.email
            name = student.first_name + " " + student.last_name
            username = student.username
            self.git_password = Util.create_random_password()
            self.save()
            # first_name, last_name are empty
            if name == " ":
                name = username
            self.logger.info("password is " + self.git_password)

            # create ldap account
            l = ldap.initialize(self.ldap_url)
            l.bind(self.principal_name, self.ldap_password)
            dn = "uid=" + username + "," + self.base_dn

            attrs = {}
            attrs['objectclass'] = ['top', 'inetOrgPerson', 'eduPerson']
            attrs['cn'] = str(username)
            attrs['sn'] = str(username)
            attrs['givenName'] = str(username)
            attrs['uid'] = str(username)
            attrs['userPassword'] = str(self.git_password)
            attrs['description'] = 'ldap user for shibboleth'
            attrs['eduPersonPrincipalName'] = str(email)

            # Convert our dict to nice syntax for the add-function using modlist-module
            ldif = modlist.addModlist(attrs)
            l.add_s(dn, ldif)
            l.unbind_s()
            self.logger.info("create ldap account " + username + "," + dn)

            self.logger.info(self.git_host + "," + str(self.git_port) + "," +
                             self.git_admin_token + "," + name + "," +
                             username + "," + email + "," + self.git_password)
            result, message = GitLabUtil.create_account(
                self.git_host, self.git_port, self.git_admin_token, name,
                username, email, self.git_password)
            self.logger.info("create_account result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (create git account)", message,
                    context)

            result, message = GitLabUtil.login(self.git_host, self.git_port,
                                               username, self.git_password)
            self.logger.info("login result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (login git account)", message, context)

            try:
                message = json.loads(message)
                self.git_id = message["id"]
                self.git_user_token = message["private_token"]
                self.save()

            except Exception, ex:
                return self.message_view(
                    "Error in uc_docker (load json string)", message, context)

            try:
                self.private_key, self.public_key = Util.gen_ssh_keys(email)
                self.logger.info("private_key:" + self.private_key)
                self.save()
                conn = pymongo.Connection('localhost', 27017)
                db = conn.test
                token = db.token
                token.insert({
                    "username": username,
                    "token": message["private_token"],
                    "password": self.git_password,
                    "private_key": self.private_key,
                    "public_key": self.public_key
                })
                conn.disconnect()

            except Exception, ex:
                return self.message_view("Error in uc_docker (gen ssh key)",
                                         ex, context)

            result, message = GitLabUtil.add_ssh_key(self.git_host,
                                                     self.git_port,
                                                     self.git_user_token,
                                                     "uClassroom default",
                                                     self.public_key)
            self.logger.info("add_ssh_key result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (add git ssh key)", message, context)

            self.is_new = False
            self.save()
Esempio n. 11
0
    def student_view(self, context=None):

        # runtime error
        if not hasattr(self.runtime, "anonymous_student_id"):
            return self.message_view(
                "Error in uc_docker (get anonymous student id)",
                "Cannot get anonymous_student_id in runtime", context)

        # preview in studio
        if self.runtime.anonymous_student_id == "student":

            result, message = GitLabUtil.get_user_projects(
                self.git_host, self.git_port, self.git_teacher_token)
            if not result:
                return self.message_view(
                    "Error in uc_docker (get git projects)",
                    "Cannot get user's projects in git", context)

            context_dict = {"labs": self.labs, "message": ""}
            fragment = Fragment()
            fragment.add_content(
                Util.render_template('static/html/uc_lab.html', context_dict))
            fragment.add_css(Util.load_resource("static/css/uc_docker.css"))
            fragment.add_javascript(
                Util.load_resource("static/js/src/uc_lab.js"))
            fragment.initialize_js("UcDockerXBlock")
            return fragment

        # student view in open-edx
        if self.is_new:
            # create git account when first visiting
            student = self.runtime.get_real_user(
                self.runtime.anonymous_student_id)
            email = student.email
            name = student.first_name + " " + student.last_name
            username = student.username
            self.git_password = Util.create_random_password()
            self.save()
            # first_name, last_name are empty
            if name == " ":
                name = username
            self.logger.info("password is " + self.git_password)

            self.logger.info(self.git_host + "," + str(self.git_port) + "," +
                             self.git_admin_token + "," + name + "," +
                             username + "," + email + "," + self.git_password)
            result, message = GitLabUtil.create_account(
                self.git_host, self.git_port, self.git_admin_token, name,
                username, email, self.git_password)
            self.logger.info("create_account result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (create git account)", message,
                    context)

            result, message = GitLabUtil.login(self.git_host, self.git_port,
                                               username, self.git_password)
            self.logger.info("login result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (login git account)", message, context)

            try:
                message = json.loads(message)
                self.git_id = message["id"]
                self.git_user_token = message["private_token"]
                self.save()

            except Exception, ex:
                return self.message_view(
                    "Error in uc_docker (load json string)", message, context)

            try:
                self.private_key, self.public_key = Util.gen_ssh_keys(email)
                self.logger.info("private_key:" + self.private_key)
                self.save()
                conn = pymongo.Connection('192.168.122.183', 27017)
                db = conn.test
                token = db.token
                token.insert({
                    "username": username,
                    "token": message["private_token"],
                    "password": self.git_password,
                    "private_key": self.private_key,
                    "public_key": self.public_key
                })
                conn.disconnect()

            except Exception, ex:
                return self.message_view("Error in uc_docker (gen ssh key)",
                                         ex, context)
Esempio n. 12
0
class UcDockerXBlock(XBlock):

    logger = Util.uc_logger()

    is_new = Boolean(default=True, scope=Scope.user_state, help="is new")
    private_key = String(default="",
                         scope=Scope.user_state,
                         help="SHH Private Key")
    public_key = String(default="",
                        scope=Scope.user_state,
                        help="SHH Public Key")
    git_password = String(default="",
                          scope=Scope.user_state,
                          help="Git password")
    git_id = Integer(default="", scope=Scope.user_state, help="Git id")
    git_user_token = String(default="",
                            scope=Scope.user_state,
                            help="Git private token")
    dockers = List(default=[], scope=Scope.user_state, help="dockers")

    labs = List(default=[], scope=Scope.content, help="labs")

    # config
    CONFIG = Config.CONFIG
    git_host = CONFIG["GIT"]["HOST"]
    git_port = CONFIG["GIT"]["PORT"]
    git_admin_token = CONFIG["GIT"]["ADMIN_TOKEN"]
    docker_host = CONFIG["DOCKER"]["HOST"]
    docker_url = CONFIG["DOCKER"]["REMOTE_API"]["URL"]
    docker_namespace = CONFIG["DOCKER"]["NAMESPACE"]
    docker_mem = CONFIG["DOCKER"]["MEM_LIMIT"]
    ca = CONFIG["DOCKER"]["REMOTE_API"]["CA"]
    cert = CONFIG["DOCKER"]["REMOTE_API"]["CERT"]
    key = CONFIG["DOCKER"]["REMOTE_API"]["KEY"]
    version = CONFIG["DOCKER"]["REMOTE_API"]["VERSION"]
    git_teacher_token = CONFIG["GIT"]["TEACHER"]["TOKEN"]

    docker_helper = DockerRawHelper(docker_host, docker_url, ca, cert, key)

    def student_view(self, context=None):

        # runtime error
        if not hasattr(self.runtime, "anonymous_student_id"):
            return self.message_view(
                "Error in uc_docker (get anonymous student id)",
                "Cannot get anonymous_student_id in runtime", context)

        # preview in studio
        if self.runtime.anonymous_student_id == "student":

            result, message = GitLabUtil.get_user_projects(
                self.git_host, self.git_port, self.git_teacher_token)
            if not result:
                return self.message_view(
                    "Error in uc_docker (get git projects)",
                    "Cannot get user's projects in git", context)

            context_dict = {"labs": self.labs, "message": ""}
            fragment = Fragment()
            fragment.add_content(
                Util.render_template('static/html/uc_lab.html', context_dict))
            fragment.add_css(Util.load_resource("static/css/uc_docker.css"))
            fragment.add_javascript(
                Util.load_resource("static/js/src/uc_lab.js"))
            fragment.initialize_js("UcDockerXBlock")
            return fragment

        # student view in open-edx
        if self.is_new:
            # create git account when first visiting
            student = self.runtime.get_real_user(
                self.runtime.anonymous_student_id)
            email = student.email
            name = student.first_name + " " + student.last_name
            username = student.username
            self.git_password = Util.create_random_password()
            self.save()
            # first_name, last_name are empty
            if name == " ":
                name = username
            self.logger.info("password is " + self.git_password)

            self.logger.info(self.git_host + "," + str(self.git_port) + "," +
                             self.git_admin_token + "," + name + "," +
                             username + "," + email + "," + self.git_password)
            result, message = GitLabUtil.create_account(
                self.git_host, self.git_port, self.git_admin_token, name,
                username, email, self.git_password)
            self.logger.info("create_account result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (create git account)", message,
                    context)

            result, message = GitLabUtil.login(self.git_host, self.git_port,
                                               username, self.git_password)
            self.logger.info("login result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (login git account)", message, context)

            try:
                message = json.loads(message)
                self.git_id = message["id"]
                self.git_user_token = message["private_token"]
                self.save()

            except Exception, ex:
                return self.message_view(
                    "Error in uc_docker (load json string)", message, context)

            try:
                self.private_key, self.public_key = Util.gen_ssh_keys(email)
                self.logger.info("private_key:" + self.private_key)
                self.save()
                conn = pymongo.Connection('192.168.122.183', 27017)
                db = conn.test
                token = db.token
                token.insert({
                    "username": username,
                    "token": message["private_token"],
                    "password": self.git_password,
                    "private_key": self.private_key,
                    "public_key": self.public_key
                })
                conn.disconnect()

            except Exception, ex:
                return self.message_view("Error in uc_docker (gen ssh key)",
                                         ex, context)

            result, message = GitLabUtil.add_ssh_key(self.git_host,
                                                     self.git_port,
                                                     self.git_user_token,
                                                     "uClassroom default",
                                                     self.public_key)
            self.logger.info("add_ssh_key result:")
            self.logger.info(result)
            self.logger.info(message)
            if not result:
                return self.message_view(
                    "Error in uc_docker (add git ssh key)", message, context)

            self.is_new = False
            self.save()