|
@@ -20,6 +20,12 @@ logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
|
20
|
20
|
logging.basicConfig(format='%(asctime)s %(message)s')
|
21
|
21
|
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
|
22
|
22
|
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+def sudoCmd(cmd):
|
|
26
|
+ cmd.replace("'","\'")
|
|
27
|
+ return 'sudo sh -c \'' + cmd + '\''
|
|
28
|
+
|
23
|
29
|
"""
|
24
|
30
|
print and save content
|
25
|
31
|
@param string
|
|
@@ -110,10 +116,11 @@ mvPath = '/bin/mv '
|
110
|
116
|
cpPath = '/bin/cp '
|
111
|
117
|
rmPath = '/bin/rm '
|
112
|
118
|
nbgraderPath = '/usr/local/bin/nbgrader '
|
113
|
|
-nbextensionPath = '/usr/local/bin/nbextension '
|
|
119
|
+nbextensionPath = 'nbextension'
|
114
|
120
|
usermodPath = '/usr/sbin/usermod '
|
115
|
121
|
chmodPath = '/bin/chmod '
|
116
|
122
|
grepPath = '/bin/grep '
|
|
123
|
+mkdirPath = '/bin/mkdir '
|
117
|
124
|
|
118
|
125
|
# début configuration --
|
119
|
126
|
"""
|
|
@@ -194,13 +201,20 @@ api = Api(app)
|
194
|
201
|
app.run(debug=debugMode,host=host,port=port)
|
195
|
202
|
'''
|
196
|
203
|
|
197
|
|
-currentUserName = ''
|
|
204
|
+ # initialise l'utilisateur qui execute le script
|
|
205
|
+currentUserName = os.popen('echo "$USER"').read().rstrip()
|
|
206
|
+
|
|
207
|
+def changeFolderRightForGroup(jupyterUsername):
|
|
208
|
+ return sudoPath + ' ' + usermodPath + ' -a -G ' + jupyterUsername + ' ' + currentUserName
|
|
209
|
+
|
|
210
|
+def addCurrentUserToJupyterUserGroup(jupyterUsername):
|
|
211
|
+ return sudoPath + ' ' + chmodPath + ' 770 ' + buildPath(['home',jupyterUsername])
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
198
|
215
|
def onRunCallback():
|
199
|
216
|
dump('onRunCallback')
|
200
|
217
|
|
201
|
|
- # initialise l'utilisateur qui execute le script
|
202
|
|
- currentUserName = os.popen('echo "$USER"').read().rstrip()
|
203
|
|
-
|
204
|
218
|
# patchs
|
205
|
219
|
# controler les groupes utilisateurs
|
206
|
220
|
jupyterUsers = os.popen(grepPath + '"^jupyter\-" /etc/group').read().split('\n')
|
|
@@ -228,11 +242,6 @@ def onRunCallback():
|
228
|
242
|
|
229
|
243
|
onRunCallback()
|
230
|
244
|
|
231
|
|
-def changeFolderRightForGroup(jupyterUsername):
|
232
|
|
- return sudoPath + ' ' + usermodPath + ' -a -G ' + jupyterUsername + ' ' + currentUserName
|
233
|
|
-
|
234
|
|
-def addCurrentUserToJupyterUserGroup(jupyterUsername):
|
235
|
|
- return sudoPath + ' ' + chmodPath + ' 770 ' + buildPath(['home',jupyterUsername])
|
236
|
245
|
|
237
|
246
|
"""
|
238
|
247
|
execute une commande sous l'identite de l'utilisateur donne
|
|
@@ -413,10 +422,9 @@ def write(username,path,content):
|
413
|
422
|
f.write(content)
|
414
|
423
|
f.close()
|
415
|
424
|
|
416
|
|
- myCmd = sudoPath + mvPath + ' \'' + tempPath + '\' \'' + path + '\''
|
417
|
|
- myCmd += ' && ' + chownPath + ' ' + username + ':' + username + ' \'' + path + '\''
|
|
425
|
+ myCmd = sudoPath + ' ' + mvPath + ' \'' + tempPath + '\' \'' + path + '\''
|
|
426
|
+ myCmd += ' && ' + sudoPath + ' ' + chownPath + ' ' + username + ':' + username + ' \'' + path + '\''
|
418
|
427
|
|
419
|
|
- myCmd = sudo(myCmd)
|
420
|
428
|
dump(myCmd)
|
421
|
429
|
os.system(myCmd)
|
422
|
430
|
|
|
@@ -584,14 +592,14 @@ def initUserSpace(jupyterUsername,folder,notebookname,fromurl = None,content = '
|
584
|
592
|
|
585
|
593
|
# dossier ./source
|
586
|
594
|
# débloquage de l'origine
|
587
|
|
- copyCmd = ' ' + chattrPath + ' -i \'' + buildPath(['home',fromJupyterUuid,'source']) + '\''
|
588
|
|
- copyCmd += ' && ' + chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
595
|
+ copyCmd = sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',fromJupyterUuid,'source']) + '\''
|
|
596
|
+ copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
589
|
597
|
# déplace le dossier
|
590
|
|
- copyCmd += ' && ' + mvPath + ' \'' + buildPath(['home',fromJupyterUuid,'source',fromFolder]) + '\' \'' + buildPath(['home',jupyterUsername,'source',folder]) + '\''
|
|
598
|
+ copyCmd += ' && ' + sudoPath + ' ' + mvPath + ' \'' + buildPath(['home',fromJupyterUuid,'source',fromFolder]) + '\' \'' + buildPath(['home',jupyterUsername,'source',folder]) + '\''
|
591
|
599
|
# corrige les droits
|
592
|
600
|
copyCmd += ' && ' + chownPath + ' -R ' + jupyterUsername + ' \'' + buildPath(['home',fromJupyterUuid,'source',folder]) + '\''
|
593
|
|
- copyCmd += ' && ' + chattrPath + ' +i \'' + buildPath(['home',fromJupyterUuid,'source']) + '\''
|
594
|
|
- copyCmd += ' && ' + chattrPath + ' +i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
601
|
+ copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + buildPath(['home',fromJupyterUuid,'source']) + '\''
|
|
602
|
+ copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
595
|
603
|
dump(copyCmd)
|
596
|
604
|
os.system(copyCmd)
|
597
|
605
|
|
|
@@ -599,7 +607,7 @@ def initUserSpace(jupyterUsername,folder,notebookname,fromurl = None,content = '
|
599
|
607
|
dump( buildPath(['home',jupyterUsername,'source',folder]) )
|
600
|
608
|
|
601
|
609
|
# déplace le fichier du notebook s'il existe
|
602
|
|
- moveCmd = mvPath + ' \'' + buildPath(['home',jupyterUsername,'source',folder,fromNotebookName]) + '\' \'' + buildPath(['home',jupyterUsername,'source',folder,notebookname]) + '\''
|
|
610
|
+ moveCmd = sudoPath + ' ' + mvPath + ' \'' + buildPath(['home',jupyterUsername,'source',folder,fromNotebookName]) + '\' \'' + buildPath(['home',jupyterUsername,'source',folder,notebookname]) + '\''
|
603
|
611
|
dump(moveCmd)
|
604
|
612
|
os.system(moveCmd)
|
605
|
613
|
|
|
@@ -608,17 +616,20 @@ def initUserSpace(jupyterUsername,folder,notebookname,fromurl = None,content = '
|
608
|
616
|
# creation des dossiers
|
609
|
617
|
|
610
|
618
|
# dossier ./source
|
611
|
|
- myCmd += sudoPath + ' -u ' + jupyterUsername + ' mkdir -p \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
619
|
+ myCmd = sudoPath + ' -u ' + jupyterUsername + ' ' + mkdirPath + ' -p \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
620
|
+ dump(myCmd)
|
|
621
|
+ dump(os.system(myCmd))
|
|
622
|
+
|
612
|
623
|
# débloquage de source
|
613
|
|
- myCmd += ' && ' + chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
624
|
+ myCmd = sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
614
|
625
|
# dossier ./[folder]
|
615
|
|
- myCmd += ' && ' + sudoPath + ' -u ' + jupyterUsername + ' mkdir \'' + buildPath(['home',jupyterUsername,'source',folder]) + '\''
|
|
626
|
+ myCmd += ' && ' + sudoPath + ' -u ' + jupyterUsername + ' ' + mkdirPath + ' \'' + buildPath(['home',jupyterUsername,'source',folder]) + '\''
|
616
|
627
|
# bloquage du source
|
617
|
|
- myCmd += ' && ' + chattrPath + ' +i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
628
|
+ myCmd += ' && ' + sudoPath + ' ' + ' ' + chattrPath + ' +i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
618
|
629
|
|
619
|
|
- myCmd = sudo(myCmd)
|
620
|
630
|
dump(myCmd)
|
621
|
|
- os.system(myCmd)
|
|
631
|
+ dump(os.popen(myCmd).read())
|
|
632
|
+ #os.system(myCmd)
|
622
|
633
|
|
623
|
634
|
if content != '':
|
624
|
635
|
write(jupyterUsername,buildPath(['home',jupyterUsername,'source',folder,notebookname]),content)
|
|
@@ -654,12 +665,6 @@ def createUserIfNotExists(token,username):
|
654
|
665
|
URL = serverUrl + buildPath(['users',username,'tokens'])
|
655
|
666
|
result = doPost(token,URL,200)
|
656
|
667
|
|
657
|
|
- # ajout l'utilisateur courant au groupe du nouvel utiliosateur
|
658
|
|
- # + change les droits du groupe sur le dossier de l'utilisateur
|
659
|
|
- jupyterUsername = getJupyterName(username)
|
660
|
|
- os.system(changeFolderRightForGroup(jupyterUsername))
|
661
|
|
- os.system(addCurrentUserToJupyterUserGroup(jupyterUsername))
|
662
|
|
-
|
663
|
668
|
return { 'result' : True,'token' : result['token'],'tokenId':result['id']}
|
664
|
669
|
else:
|
665
|
670
|
return { 'result' : False }
|
|
@@ -717,30 +722,49 @@ def createTrainerServer(username,folder,notebookname):
|
717
|
722
|
|
718
|
723
|
# cas d'une creation de compte utilisateur, il faut le configurer
|
719
|
724
|
if 'token' in result['resultUser'] and ((not 'status' in result['result']) or (result['result']['status'] != '400')):
|
|
725
|
+ # ajout l'utilisateur courant au groupe du nouvel utiliosateur
|
|
726
|
+ # + change les droits du groupe sur le dossier de l'utilisateur
|
|
727
|
+ jupyterUsername = getJupyterName(username)
|
|
728
|
+ cmd = changeFolderRightForGroup(jupyterUsername)
|
|
729
|
+ dump(cmd)
|
|
730
|
+ os.system(cmd)
|
|
731
|
+
|
|
732
|
+ cmd = addCurrentUserToJupyterUserGroup(jupyterUsername)
|
|
733
|
+ dump(cmd)
|
|
734
|
+ os.system(cmd)
|
|
735
|
+
|
720
|
736
|
# configuration des extensions de l'utilisateur
|
721
|
737
|
# config formateur de nbgrader
|
722
|
738
|
myCmd = goToUser(jupyterUsername)
|
723
|
|
- myCmd += ' && ' + nbextensionPath + ' install --user --py nbgrader'
|
724
|
|
- myCmd += ' && ' + nbextensionPath + ' disable --user --py nbgrader'
|
725
|
|
- myCmd += ' && ' + nbextensionPath + ' enable --user create_assignment/main'
|
726
|
|
- myCmd += ' && ' + nbextensionPath + ' enable --user validate_assignment/main'
|
|
739
|
+ myCmd += ' && ' + jupyterPath + ' ' + nbextensionPath + ' install --user --py nbgrader'
|
|
740
|
+ myCmd += ' && ' + jupyterPath + ' ' + nbextensionPath + ' disable --user --py nbgrader'
|
|
741
|
+ myCmd += ' && ' + jupyterPath + ' ' + nbextensionPath + ' enable --user create_assignment/main'
|
|
742
|
+ myCmd += ' && ' + jupyterPath + ' ' + nbextensionPath + ' enable --user validate_assignment/main'
|
727
|
743
|
|
728
|
|
- myCmd = runAsUser(jupyterUsername,myCmd)
|
|
744
|
+ myCmd = sudoCmd(myCmd)
|
729
|
745
|
dump(myCmd)
|
730
|
746
|
os.system(myCmd)
|
731
|
747
|
|
732
|
748
|
# config du notebook jupyter => changement de la racine d'exploration
|
733
|
|
- myCmd += 'echo "c.FileContentsManager.root_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'" >> ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
734
|
|
- myCmd += ' && echo "c.NotebookApp.notebook_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'" >> ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
735
|
|
-
|
736
|
|
- # ajoute la configuration de jupyter => timeout de deconnexion
|
737
|
|
- myCmd += ' && echo "c.MappingKernelManager.cull_idle_timeout = ' + timeout + '" >> ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
738
|
|
- myCmd += ' && echo "c.MappingKernelManager.shutdown_no_activity_timeout = ' + timeout + '" >> ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
739
|
|
-
|
740
|
|
- myCmd = sudo(myCmd)
|
741
|
|
- dump(myCmd)
|
|
749
|
+ myCmd = sudoPath + ' ' + mkdirPath + ' -p ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
750
|
+ myCmd += ' && ' + sudoPath + ' ' + chownPath + ' ' + jupyterUsername + ' ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
751
|
+ myCmd += ' && ' + sudoPath + ' ' + chmodPath + ' 770 ' + ' ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
752
|
+ os.system(myCmd)
|
|
753
|
+
|
|
754
|
+ #myCmd += ' && ' + sudoPath + ' -u ' + currentUserName + ' ' + chmodPath + ' 770 ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
755
|
+ configContent = 'c.FileContentsManager.root_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'' + "\n"
|
|
756
|
+ configContent += 'c.NotebookApp.notebook_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'' + "\n"
|
|
757
|
+ configContent += 'c.MappingKernelManager.cull_idle_timeout = ' + timeout + "\n"
|
|
758
|
+ configContent += 'c.MappingKernelManager.shutdown_no_activity_timeout = ' + timeout + "\n"
|
|
759
|
+ write(jupyterUsername,buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py']),configContent)
|
|
760
|
+
|
|
761
|
+ # vérouille les configurations
|
|
762
|
+ myCmd = 'chattr +i ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
763
|
+ myCmd += ' && chattr +i ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
742
|
764
|
os.system(myCmd)
|
743
|
765
|
|
|
766
|
+ #dump(os.popen(myCmd).read())
|
|
767
|
+
|
744
|
768
|
# ajoute la configuration de jupyter
|
745
|
769
|
#configContent = "c.FileContentsManager.root_dir='" + buildPath(['home',jupyterUsername,'source']) + "'\n"
|
746
|
770
|
#configContent += "c.NotebookApp.notebook_dir ='c.FileContentsManager.root_dir='" + buildPath(['home',jupyterUsername,'source']) + "'"
|
|
@@ -766,7 +790,7 @@ def createTrainerServer(username,folder,notebookname):
|
766
|
790
|
return json.dumps(reponse),200
|
767
|
791
|
|
768
|
792
|
"""
|
769
|
|
-url: [host]/student/<username>/<fodler>/<notebookName>
|
|
793
|
+url: [host]/student/<username>/<folder>/<notebookName>
|
770
|
794
|
"""
|
771
|
795
|
@app.route(buildRoutePath(['student','<trainername>','<username>','<folder>','<notebookname>']),methods=['POST'])
|
772
|
796
|
def createStudentServer(trainername,username,folder,notebookname):
|
|
@@ -793,28 +817,42 @@ def createStudentServer(trainername,username,folder,notebookname):
|
793
|
817
|
#
|
794
|
818
|
# cas d'une creation de compte utilisateur, il faut le configurer en tant que formateur
|
795
|
819
|
if 'token' in result['resultUser'] and ((not 'status' in result['result']) or (result['result']['status'] != '400')):
|
|
820
|
+ # ajout l'utilisateur courant au groupe du nouvel utiliosateur
|
|
821
|
+ # + change les droits du groupe sur le dossier de l'utilisateur
|
|
822
|
+ jupyterUsername = getJupyterName(username)
|
|
823
|
+ cmd = changeFolderRightForGroup(jupyterUsername)
|
|
824
|
+ dump(cmd)
|
|
825
|
+ os.system(cmd)
|
|
826
|
+
|
|
827
|
+ cmd = addCurrentUserToJupyterUserGroup(jupyterUsername)
|
|
828
|
+ dump(cmd)
|
|
829
|
+ os.system(cmd)
|
|
830
|
+
|
796
|
831
|
# configuration des extensions de l'utilisateur
|
797
|
832
|
# config formateur de nbgrader
|
798
|
833
|
myCmd = goToUser(jupyterUsername)
|
799
|
|
-
|
800
|
|
- # personalise les extensions
|
801
|
834
|
myCmd += ' && ' + nbextensionPath + ' install --user --py nbgrader'
|
802
|
835
|
myCmd += ' && ' + nbextensionPath + ' disable --user --py nbgrader'
|
803
|
|
- #myCmd += ' && ' + runAsUser(jupyterUsername) + '\'jupyter nbextension disable --user validate_assignment/main\''
|
804
|
836
|
myCmd = runAsUser(jupyterUsername,myCmd)
|
805
|
837
|
dump(myCmd)
|
806
|
838
|
os.system(myCmd)
|
807
|
839
|
|
808
|
|
- # config du notebook jupyter => changement de la racine d'exploration + configuration nbgrader
|
809
|
|
- myCmd = 'echo "c.FileContentsManager.root_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'" >> ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
810
|
|
- myCmd += ' && echo "c.NotebookApp.notebook_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'" >> ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
|
840
|
+ # config du notebook jupyter => changement de la racine d'exploration
|
|
841
|
+ myCmd = sudoPath + ' ' + mkdirPath + ' -p ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
842
|
+ myCmd += ' && ' + sudoPath + ' ' + chownPath + ' ' + jupyterUsername + ' ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
843
|
+ myCmd += ' && ' + sudoPath + ' ' + chmodPath + ' 770 ' + ' ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
844
|
+ os.system(myCmd)
|
811
|
845
|
|
812
|
|
- # ajoute la configuration de jupyter => timeout de deconnexion
|
813
|
|
- myCmd += ' && echo "c.MappingKernelManager.cull_idle_timeout = ' + timeout + '" >> ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
814
|
|
- myCmd += ' && echo "c.MappingKernelManager.shutdown_no_activity_timeout = ' + timeout + '" >> ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
815
|
|
-
|
816
|
|
- myCmd = sudo(myCmd)
|
817
|
|
- dump(myCmd)
|
|
846
|
+ #myCmd += ' && ' + sudoPath + ' -u ' + currentUserName + ' ' + chmodPath + ' 770 ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
847
|
+ configContent = 'c.FileContentsManager.root_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'' + "\n"
|
|
848
|
+ configContent += 'c.NotebookApp.notebook_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'' + "\n"
|
|
849
|
+ configContent += 'c.MappingKernelManager.cull_idle_timeout = ' + timeout + "\n"
|
|
850
|
+ configContent += 'c.MappingKernelManager.shutdown_no_activity_timeout = ' + timeout + "\n"
|
|
851
|
+ write(jupyterUsername,buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py']),configContent)
|
|
852
|
+
|
|
853
|
+ # vérouille les configurations
|
|
854
|
+ myCmd = 'chattr +i ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
855
|
+ myCmd += ' && chattr +i ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
818
|
856
|
os.system(myCmd)
|
819
|
857
|
|
820
|
858
|
#configPath = '/home/' + jupyterUsername + '}/.jupyter/jupyter_notebook_config.py'
|
|
@@ -832,14 +870,14 @@ def createStudentServer(trainername,username,folder,notebookname):
|
832
|
870
|
toPath = buildPath(['home',jupyterUsername,'source'])
|
833
|
871
|
|
834
|
872
|
# dévérouillage des dossiers
|
835
|
|
- copyCmd = ' ' + chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
836
|
|
- copyCmd += '&& ' + chattrPath + ' -i \'' + buildPath(['home',trainerJupyterUsername,'source']) + '\''
|
|
873
|
+ copyCmd = ' ' + sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
874
|
+ copyCmd += '&& ' + sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',trainerJupyterUsername,'source']) + '\''
|
837
|
875
|
# copie
|
838
|
|
- copyCmd += '&& ' + cpPath + ' -r \'' + fromPath + '\' \'' + toPath + '\''
|
839
|
|
- copyCmd += ' && ' + chownPath + ' -R ' + jupyterUsername + ' \'' + toPath + '\''
|
|
876
|
+ copyCmd += '&& ' + sudoPath + ' ' + cpPath + ' -r \'' + fromPath + '\' \'' + toPath + '\''
|
|
877
|
+ copyCmd += ' && ' + sudoPath + ' ' + chownPath + ' -R ' + jupyterUsername + ' \'' + toPath + '\''
|
840
|
878
|
# vérouillage des dossiers
|
841
|
|
- copyCmd += ' && ' + chattrPath + ' +i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
842
|
|
- copyCmd += ' && ' + chattrPath + ' +i \'' + buildPath(['home',trainerJupyterUsername,'source']) + '\''
|
|
879
|
+ copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
880
|
+ copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + buildPath(['home',trainerJupyterUsername,'source']) + '\''
|
843
|
881
|
dump(copyCmd)
|
844
|
882
|
os.system(copyCmd)
|
845
|
883
|
|
|
@@ -940,9 +978,9 @@ def createAssesmentStudentServer(trainername,username,folder,notebookname):
|
940
|
978
|
# débloquage du source
|
941
|
979
|
myCmd = chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
942
|
980
|
# dossier ./source
|
943
|
|
- myCmd += ' && ' + sudoPath + ' -u ' + jupyterUsername + ' mkdir -p \''+ buildPath(['home',jupyterUsername,'source']) +'\''
|
|
981
|
+ myCmd += ' && ' + sudoPath + ' -u ' + jupyterUsername + ' ' + mkdirPath + ' -p \''+ buildPath(['home',jupyterUsername,'source']) +'\''
|
944
|
982
|
# dossier ./cours
|
945
|
|
- myCmd += ' && ' + sudoPath + ' -u ' + jupyterUsername + ' mkdir \''+ buildPath(['home',jupyterUsername,'source',folder]) + '\''
|
|
983
|
+ myCmd += ' && ' + sudoPath + ' -u ' + jupyterUsername + ' ' + mkdirPath + ' \''+ buildPath(['home',jupyterUsername,'source',folder]) + '\''
|
946
|
984
|
# bloquage du source
|
947
|
985
|
myCmd += ' && ' + chattrPath + ' +i \''+ buildPath(['home',jupyterUsername,'source']) +'\''
|
948
|
986
|
|
|
@@ -1016,6 +1054,7 @@ def sendStudentNotebook(trainername,username,folder):
|
1016
|
1054
|
dump(getScoresCommand)
|
1017
|
1055
|
os.system(getScoresCommand)
|
1018
|
1056
|
|
|
1057
|
+
|
1019
|
1058
|
score = None
|
1020
|
1059
|
maxScore = None
|
1021
|
1060
|
|
|
@@ -1074,9 +1113,9 @@ def deleteNotebook(uuid,folder):
|
1074
|
1113
|
path = buildPath(['home',getJupyterName(uuid),'source',folder])
|
1075
|
1114
|
dump('|' + path + '|')
|
1076
|
1115
|
#if os.path.isdir(path) :
|
1077
|
|
- removeCmd = '' + chattrPath + ' -i \'' + pathSource + '\''
|
1078
|
|
- removeCmd += ' && ' + rmPath + ' -rf \'' + path + '\''
|
1079
|
|
- removeCmd += ' && ' + chattrPath + ' +i \'' + pathSource + '\''
|
|
1116
|
+ removeCmd = sudoPath + ' ' + chattrPath + ' -i \'' + pathSource + '\''
|
|
1117
|
+ removeCmd += ' && ' + sudoPath + ' ' + rmPath + ' -rf \'' + path + '\''
|
|
1118
|
+ removeCmd += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + pathSource + '\''
|
1080
|
1119
|
dump(removeCmd)
|
1081
|
1120
|
os.system(removeCmd)
|
1082
|
1121
|
|
|
@@ -1111,18 +1150,18 @@ def cloneNotebook(fromuuid,touuid,fromfolder,tofolder,reset):
|
1111
|
1150
|
dump(pathTo)
|
1112
|
1151
|
|
1113
|
1152
|
# dévérouille les dossiers
|
1114
|
|
- cloneCommand = chattrPath + ' -i \'' + pathSourceFrom + '\''
|
1115
|
|
- cloneCommand += ' && ' + chattrPath + ' -i \'' + pathSourceTo + '\''
|
|
1153
|
+ cloneCommand = sudoPath + ' ' + chattrPath + ' -i \'' + pathSourceFrom + '\''
|
|
1154
|
+ cloneCommand += ' && ' + sudoPath + ' ' + chattrPath + ' -i \'' + pathSourceTo + '\''
|
1116
|
1155
|
if os.path.isdir(pathFrom) :
|
1117
|
1156
|
if os.path.isdir(pathTo) and reset == '1' and pathFrom != pathTo:
|
1118
|
1157
|
# suppression
|
1119
|
|
- cloneCommand += ' && ' + rmPath + ' -rf \'' + pathTo + '\''
|
|
1158
|
+ cloneCommand += ' && ' + sudoPath + ' ' + rmPath + ' -rf \'' + pathTo + '\''
|
1120
|
1159
|
# copie
|
1121
|
|
- cloneCommand += ' && ' + cpPath + ' -r \'' + pathFrom + '/\' \'' + pathTo + '/\''
|
1122
|
|
- cloneCommand += ' && ' + chownPath + ' -R ' + jupyterUuidTo + ' \'' + pathSourceTo + '\''
|
|
1160
|
+ cloneCommand += ' && ' + sudoPath + ' ' + cpPath + ' -r \'' + pathFrom + '/\' \'' + pathTo + '/\''
|
|
1161
|
+ cloneCommand += ' && ' + sudoPath + ' ' + chownPath + ' -R ' + jupyterUuidTo + ' \'' + pathSourceTo + '\''
|
1123
|
1162
|
|
1124
|
|
- cloneCommand += ' && ' + chattrPath + ' +i \'' + pathSourceFrom + '\''
|
1125
|
|
- cloneCommand += ' && ' + chattrPath + ' +i \'' + pathSourceTo + '\''
|
|
1163
|
+ cloneCommand += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + pathSourceFrom + '\''
|
|
1164
|
+ cloneCommand += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + pathSourceTo + '\''
|
1126
|
1165
|
|
1127
|
1166
|
dump(cloneCommand)
|
1128
|
1167
|
os.system(cloneCommand)
|