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")
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
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)
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()
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()
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)
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()