|
@@ -1,3 +1,4 @@
|
|
1
|
+# coding: utf-8
|
1
|
2
|
import os
|
2
|
3
|
import json
|
3
|
4
|
import requests
|
|
@@ -21,10 +22,14 @@ logging.basicConfig(format='%(asctime)s %(message)s')
|
21
|
22
|
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
|
22
|
23
|
|
23
|
24
|
|
|
25
|
+def executeSudoCmd(myCmd):
|
|
26
|
+ myCmd = sudoCmd(myCmd)
|
|
27
|
+ executeCmd(myCmd)
|
|
28
|
+
|
24
|
29
|
|
25
|
30
|
def sudoCmd(cmd):
|
26
|
|
- cmd.replace("'","\'")
|
27
|
|
- return 'sudo sh -c \'' + cmd + '\''
|
|
31
|
+ return sudoPath + cmd
|
|
32
|
+ #return sudoPath + ' /bin/sh -c \'' + cmd.replace('\'', "\\'") + '\''
|
28
|
33
|
|
29
|
34
|
"""
|
30
|
35
|
print and save content
|
|
@@ -90,6 +95,65 @@ def getArgValue(name):
|
90
|
95
|
|
91
|
96
|
return value
|
92
|
97
|
|
|
98
|
+def unlockSourceCmd(jupyterName):
|
|
99
|
+ return chattrPath + ' -i \'' + buildPath(['home',jupyterName,'source']) + '\''
|
|
100
|
+
|
|
101
|
+def lockSourceCmd(jupyterName):
|
|
102
|
+ return chattrPath + ' +i \'' + buildPath(['home',jupyterName,'source']) + '\''
|
|
103
|
+
|
|
104
|
+def rmCmd(path):
|
|
105
|
+ return rmPath + '-rf ' + path
|
|
106
|
+
|
|
107
|
+def chownCmd(path,user):
|
|
108
|
+ return chownPath + ' -R ' + user + ':' + user + ' \'' + path + '\''
|
|
109
|
+
|
|
110
|
+def chmodCmd(path,chmod):
|
|
111
|
+ return chmodPath + ' ' + chmod + ' \'' + path + '\''
|
|
112
|
+
|
|
113
|
+def mvCmd(pathFrom,pathTo,userTo):
|
|
114
|
+ return [
|
|
115
|
+ mvPath + ' \'' + pathFrom + '\' \'' + pathTo + '\'',
|
|
116
|
+ chownCmd(pathTo,userTo)
|
|
117
|
+ ]
|
|
118
|
+def mkdirCmd(path,user,chmod=770):
|
|
119
|
+ if type(chmod).__name__ == 'int' :
|
|
120
|
+ chmod = str(chmod)
|
|
121
|
+
|
|
122
|
+ result = [
|
|
123
|
+ mkdirPath + ' -p \'' + path + '\'',
|
|
124
|
+ ]
|
|
125
|
+ if user != None:
|
|
126
|
+ result.append(chownCmd(path,user))
|
|
127
|
+ if chmod != None:
|
|
128
|
+ result.append(chmodCmd(path,chmod))
|
|
129
|
+
|
|
130
|
+ return result
|
|
131
|
+
|
|
132
|
+def executeSudoCmds(cmds):
|
|
133
|
+ end = []
|
|
134
|
+ for cmd in cmds:
|
|
135
|
+ if type(cmd).__name__ == 'list' :
|
|
136
|
+ for subCmd in cmd:
|
|
137
|
+ end.append(subCmd)
|
|
138
|
+
|
|
139
|
+ else:
|
|
140
|
+ end.append(cmd)
|
|
141
|
+ dump(end)
|
|
142
|
+
|
|
143
|
+ cmd = sudoPath + (' ' + cmdsSeparator + ' ' + sudoPath).join(end)
|
|
144
|
+ executeCmd(cmd)
|
|
145
|
+ #executeSudoCmd('; '.join(end))
|
|
146
|
+
|
|
147
|
+def executeCmd(cmd):
|
|
148
|
+ dump(cmd)
|
|
149
|
+ os.system(cmd)
|
|
150
|
+
|
|
151
|
+def copyCmd(pathFrom,pathTo,userTo):
|
|
152
|
+ return [
|
|
153
|
+ cpPath + ' -r \'' + pathFrom + '\' \'' + pathTo + '\'',
|
|
154
|
+ chownCmd(pathTo,userTo)
|
|
155
|
+ ]
|
|
156
|
+
|
93
|
157
|
# configurations par défaut
|
94
|
158
|
|
95
|
159
|
# hote par défaut: 0.0.0.0
|
|
@@ -122,6 +186,9 @@ chmodPath = '/bin/chmod '
|
122
|
186
|
grepPath = '/bin/grep '
|
123
|
187
|
mkdirPath = '/bin/mkdir '
|
124
|
188
|
|
|
189
|
+
|
|
190
|
+cmdsSeparator = '&&'
|
|
191
|
+
|
125
|
192
|
# début configuration --
|
126
|
193
|
"""
|
127
|
194
|
configurations
|
|
@@ -205,10 +272,10 @@ api = Api(app)
|
205
|
272
|
currentUserName = os.popen('echo "$USER"').read().rstrip()
|
206
|
273
|
|
207
|
274
|
def changeFolderRightForGroup(jupyterUsername):
|
208
|
|
- return sudoPath + ' ' + usermodPath + ' -a -G ' + jupyterUsername + ' ' + currentUserName
|
|
275
|
+ return usermodPath + ' -a -G ' + jupyterUsername + ' ' + currentUserName
|
209
|
276
|
|
210
|
277
|
def addCurrentUserToJupyterUserGroup(jupyterUsername):
|
211
|
|
- return sudoPath + ' ' + chmodPath + ' 770 ' + buildPath(['home',jupyterUsername])
|
|
278
|
+ return chmodPath + ' 770 ' + buildPath(['home',jupyterUsername])
|
212
|
279
|
|
213
|
280
|
|
214
|
281
|
|
|
@@ -229,16 +296,13 @@ def onRunCallback():
|
229
|
296
|
# ajoute l'utilisateur courant au groupe de l'utilisateur jupyter
|
230
|
297
|
for jupyterUser in allJupyterUsers:
|
231
|
298
|
cmds.append(changeFolderRightForGroup(jupyterUser))
|
232
|
|
- separator = ' && '
|
233
|
|
- dump(separator.join(cmds))
|
234
|
|
- dump(os.popen(separator.join(cmds)).read())
|
|
299
|
+ executeSudoCmds(cmds)
|
235
|
300
|
|
236
|
301
|
# change les droits des dossiers pour leur attribuer les groupes
|
237
|
302
|
cmds = []
|
238
|
303
|
for jupyterUser in allJupyterUsers:
|
239
|
304
|
cmds.append(addCurrentUserToJupyterUserGroup(jupyterUser))
|
240
|
|
- dump(separator.join(cmds))
|
241
|
|
- os.system(separator.join(cmds))
|
|
305
|
+ executeSudoCmds(cmds)
|
242
|
306
|
|
243
|
307
|
onRunCallback()
|
244
|
308
|
|
|
@@ -270,7 +334,7 @@ va dans le repertoire de l'utilisateur
|
270
|
334
|
@param username
|
271
|
335
|
"""
|
272
|
336
|
def goToUser(username):
|
273
|
|
- return runAsUser(username,'cd /home/' + username)
|
|
337
|
+ return 'cd /home/' + username
|
274
|
338
|
|
275
|
339
|
|
276
|
340
|
"""
|
|
@@ -417,16 +481,16 @@ ecrit un fichier
|
417
|
481
|
|
418
|
482
|
"""
|
419
|
483
|
def write(username,path,content):
|
|
484
|
+ # écrit le fichier temporaire
|
420
|
485
|
tempPath = '/tmp/' + uuid.uuid4().hex
|
421
|
486
|
f = open(tempPath, "w")
|
422
|
487
|
f.write(content)
|
423
|
488
|
f.close()
|
424
|
489
|
|
425
|
|
- myCmd = sudoPath + ' ' + mvPath + ' \'' + tempPath + '\' \'' + path + '\''
|
426
|
|
- myCmd += ' && ' + sudoPath + ' ' + chownPath + ' ' + username + ':' + username + ' \'' + path + '\''
|
427
|
|
-
|
428
|
|
- dump(myCmd)
|
429
|
|
- os.system(myCmd)
|
|
490
|
+ # déplace le fichier temporaire dans le bon dossier
|
|
491
|
+ myCmds = []
|
|
492
|
+ myCmds.append(mvCmd(tempPath,path,username))
|
|
493
|
+ executeSudoCmds(myCmds)
|
430
|
494
|
|
431
|
495
|
"""
|
432
|
496
|
|
|
@@ -577,7 +641,6 @@ def initUserSpace(jupyterUsername,folder,notebookname,fromurl = None,content = '
|
577
|
641
|
path = getNotebookPath(jupyterUsername,folder,notebookname)
|
578
|
642
|
dump('initUserSpace')
|
579
|
643
|
|
580
|
|
-
|
581
|
644
|
if fromurl != None:
|
582
|
645
|
data = fromurl.split('/')
|
583
|
646
|
sizeOfData = len(data)
|
|
@@ -592,44 +655,48 @@ def initUserSpace(jupyterUsername,folder,notebookname,fromurl = None,content = '
|
592
|
655
|
|
593
|
656
|
# dossier ./source
|
594
|
657
|
# débloquage de l'origine
|
595
|
|
- copyCmd = sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',fromJupyterUuid,'source']) + '\''
|
596
|
|
- copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
597
|
|
- # déplace le dossier
|
598
|
|
- copyCmd += ' && ' + sudoPath + ' ' + mvPath + ' \'' + buildPath(['home',fromJupyterUuid,'source',fromFolder]) + '\' \'' + buildPath(['home',jupyterUsername,'source',folder]) + '\''
|
599
|
|
- # corrige les droits
|
600
|
|
- copyCmd += ' && ' + chownPath + ' -R ' + jupyterUsername + ' \'' + buildPath(['home',fromJupyterUuid,'source',folder]) + '\''
|
601
|
|
- copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + buildPath(['home',fromJupyterUuid,'source']) + '\''
|
602
|
|
- copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
603
|
|
- dump(copyCmd)
|
604
|
|
- os.system(copyCmd)
|
605
|
|
-
|
606
|
|
- dump( buildPath(['home',fromJupyterUuid,'source',fromFolder]))
|
607
|
|
- dump( buildPath(['home',jupyterUsername,'source',folder]) )
|
|
658
|
+ mvCmds = []
|
|
659
|
+ mvCmds.append(unlockSourceCmd(fromJupyterUuid))
|
|
660
|
+ mvCmds.append(unlockSourceCmd(jupyterUsername))
|
608
|
661
|
|
|
662
|
+ # déplace le dossier
|
|
663
|
+ mvCmds.append(mvCmd(
|
|
664
|
+ buildPath(['home',fromJupyterUuid,'source',fromFolder]),
|
|
665
|
+ buildPath(['home',jupyterUsername,'source',folder])
|
|
666
|
+ ))
|
|
667
|
+
|
|
668
|
+ mvCmds.append(lockSourceCmd(fromJupyterUuid))
|
|
669
|
+ mvCmds.append(lockSourceCmd(jupyterUsername))
|
|
670
|
+
|
|
671
|
+ executeSudoCmds(mvCmds)
|
|
672
|
+
|
609
|
673
|
# déplace le fichier du notebook s'il existe
|
610
|
|
- moveCmd = sudoPath + ' ' + mvPath + ' \'' + buildPath(['home',jupyterUsername,'source',folder,fromNotebookName]) + '\' \'' + buildPath(['home',jupyterUsername,'source',folder,notebookname]) + '\''
|
611
|
|
- dump(moveCmd)
|
612
|
|
- os.system(moveCmd)
|
|
674
|
+ moveCmd = mvCmd(
|
|
675
|
+ buildPath(['home',jupyterUsername,'source',folder,fromNotebookName]),
|
|
676
|
+ buildPath(['home',jupyterUsername,'source',folder,notebookname]),
|
|
677
|
+ jupyterUsername
|
|
678
|
+ )
|
|
679
|
+ executeSudoCmds(moveCmd)
|
613
|
680
|
|
614
|
681
|
else:
|
615
|
682
|
# -- config notebook jupyter
|
616
|
683
|
# creation des dossiers
|
617
|
684
|
|
618
|
685
|
# dossier ./source
|
619
|
|
- myCmd = sudoPath + ' -u ' + jupyterUsername + ' ' + mkdirPath + ' -p \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
620
|
|
- dump(myCmd)
|
621
|
|
- dump(os.system(myCmd))
|
|
686
|
+ mkdirCmds = mkdirCmd(buildPath(['home',jupyterUsername,'source']),jupyterUsername)
|
|
687
|
+ executeSudoCmds(mkdirCmds)
|
622
|
688
|
|
623
|
689
|
# débloquage de source
|
624
|
|
- myCmd = sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
690
|
+ myCmds = []
|
|
691
|
+ myCmds.append(unlockSourceCmd(jupyterUsername))
|
|
692
|
+
|
625
|
693
|
# dossier ./[folder]
|
626
|
|
- myCmd += ' && ' + sudoPath + ' -u ' + jupyterUsername + ' ' + mkdirPath + ' \'' + buildPath(['home',jupyterUsername,'source',folder]) + '\''
|
|
694
|
+ myCmds.append(mkdirCmd(buildPath(['home',jupyterUsername,'source',folder]),jupyterUsername))
|
|
695
|
+
|
627
|
696
|
# bloquage du source
|
628
|
|
- myCmd += ' && ' + sudoPath + ' ' + ' ' + chattrPath + ' +i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
|
697
|
+ myCmds.append(lockSourceCmd(jupyterUsername))
|
629
|
698
|
|
630
|
|
- dump(myCmd)
|
631
|
|
- dump(os.popen(myCmd).read())
|
632
|
|
- #os.system(myCmd)
|
|
699
|
+ executeSudoCmds(myCmds)
|
633
|
700
|
|
634
|
701
|
if content != '':
|
635
|
702
|
write(jupyterUsername,buildPath(['home',jupyterUsername,'source',folder,notebookname]),content)
|
|
@@ -686,6 +753,38 @@ def index():
|
686
|
753
|
def cleanQuotes(string):
|
687
|
754
|
return urllib.parse.unquote_plus(string)
|
688
|
755
|
|
|
756
|
+def nbGraderInstallCmd(user,options):
|
|
757
|
+ result = [
|
|
758
|
+ goToUser(user),
|
|
759
|
+ jupyterPath + ' ' + nbextensionPath + ' install --user --py nbgrader',
|
|
760
|
+ jupyterPath + ' ' + nbextensionPath + ' disable --user --py nbgrader'
|
|
761
|
+ ]
|
|
762
|
+
|
|
763
|
+ for option in options:
|
|
764
|
+ result.append(jupyterPath + ' ' + nbextensionPath + ' enable --user ' + option)
|
|
765
|
+
|
|
766
|
+ return result
|
|
767
|
+
|
|
768
|
+def writeConfigurations(jupyterUsername,useSource=True):
|
|
769
|
+ # config du notebook jupyter => changement de la racine d'exploration
|
|
770
|
+ mkdirCmds = mkdirCmd(buildPath(['home',jupyterUsername,'.jupyter']),jupyterUsername,770)
|
|
771
|
+ executeSudoCmds(mkdirCmds)
|
|
772
|
+
|
|
773
|
+ configContents = []
|
|
774
|
+ if useSource:
|
|
775
|
+ configContents.append('c.FileContentsManager.root_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'')
|
|
776
|
+ configContents.append('c.NotebookApp.notebook_dir=\'' + buildPath(['home',jupyterUsername,'source']) + '\'')
|
|
777
|
+
|
|
778
|
+ configContents.append('c.MappingKernelManager.cull_idle_timeout = ' + timeout)
|
|
779
|
+ configContents.append('c.MappingKernelManager.shutdown_no_activity_timeout = ' + timeout)
|
|
780
|
+
|
|
781
|
+ write(jupyterUsername,buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py']),"\n".join(configContents) + "\n")
|
|
782
|
+
|
|
783
|
+ # vérouille les configurations
|
|
784
|
+ #myCmd = 'chattr +i ' + buildPath(['home',jupyterUsername,'.jupyter'])
|
|
785
|
+ #myCmd += ' && chattr +i ' + buildPath(['home',jupyterUsername,'.jupyter','jupyter_notebook_config.py'])
|
|
786
|
+ #os.system(myCmd)
|
|
787
|
+
|
689
|
788
|
"""
|
690
|
789
|
url: [host]/trainer/<username>/<folder>/<notebookName>
|
691
|
790
|
"""
|
|
@@ -726,42 +825,18 @@ def createTrainerServer(username,folder,notebookname):
|
726
|
825
|
# + change les droits du groupe sur le dossier de l'utilisateur
|
727
|
826
|
jupyterUsername = getJupyterName(username)
|
728
|
827
|
cmd = changeFolderRightForGroup(jupyterUsername)
|
729
|
|
- dump(cmd)
|
730
|
|
- os.system(cmd)
|
|
828
|
+ executeCmd(cmd)
|
731
|
829
|
|
732
|
830
|
cmd = addCurrentUserToJupyterUserGroup(jupyterUsername)
|
733
|
|
- dump(cmd)
|
734
|
|
- os.system(cmd)
|
|
831
|
+ executeCmd(cmd)
|
735
|
832
|
|
736
|
833
|
# configuration des extensions de l'utilisateur
|
737
|
834
|
# config formateur de nbgrader
|
738
|
|
- myCmd = goToUser(jupyterUsername)
|
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'
|
743
|
|
-
|
744
|
|
- myCmd = sudoCmd(myCmd)
|
745
|
|
- dump(myCmd)
|
746
|
|
- os.system(myCmd)
|
747
|
|
-
|
748
|
|
- # config du notebook jupyter => changement de la racine d'exploration
|
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)
|
|
835
|
+ myCmds = nbGraderInstallCmd(jupyterUsername,['create_assignment/main','validate_assignment/main'])
|
|
836
|
+ executeSudoCmds(myCmds)
|
753
|
837
|
|
754
|
838
|
#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'])
|
764
|
|
- os.system(myCmd)
|
|
839
|
+ writeConfigurations(jupyterUsername)
|
765
|
840
|
|
766
|
841
|
#dump(os.popen(myCmd).read())
|
767
|
842
|
|
|
@@ -814,49 +889,26 @@ def createStudentServer(trainername,username,folder,notebookname):
|
814
|
889
|
jupyterUsername = getJupyterName(username)
|
815
|
890
|
trainerJupyterUsername = getJupyterName(trainername)
|
816
|
891
|
|
817
|
|
-#
|
818
|
|
-# cas d'une creation de compte utilisateur, il faut le configurer en tant que formateur
|
|
892
|
+ #
|
|
893
|
+ # cas d'une creation de compte utilisateur, il faut le configurer en tant que formateur
|
819
|
894
|
if 'token' in result['resultUser'] and ((not 'status' in result['result']) or (result['result']['status'] != '400')):
|
820
|
895
|
# ajout l'utilisateur courant au groupe du nouvel utiliosateur
|
821
|
896
|
# + change les droits du groupe sur le dossier de l'utilisateur
|
822
|
897
|
jupyterUsername = getJupyterName(username)
|
823
|
898
|
cmd = changeFolderRightForGroup(jupyterUsername)
|
824
|
|
- dump(cmd)
|
825
|
|
- os.system(cmd)
|
|
899
|
+ executeCmd(cmd)
|
826
|
900
|
|
827
|
901
|
cmd = addCurrentUserToJupyterUserGroup(jupyterUsername)
|
828
|
|
- dump(cmd)
|
829
|
|
- os.system(cmd)
|
|
902
|
+ executeCmd(cmd)
|
830
|
903
|
|
831
|
|
- # configuration des extensions de l'utilisateur
|
832
|
|
- # config formateur de nbgrader
|
833
|
|
- myCmd = goToUser(jupyterUsername)
|
834
|
|
- myCmd += ' && ' + nbextensionPath + ' install --user --py nbgrader'
|
835
|
|
- myCmd += ' && ' + nbextensionPath + ' disable --user --py nbgrader'
|
836
|
|
- myCmd = runAsUser(jupyterUsername,myCmd)
|
837
|
|
- dump(myCmd)
|
838
|
|
- os.system(myCmd)
|
|
904
|
+ myCmds = nbGraderInstallCmd(jupyterUsername,[])
|
|
905
|
+ executeSudoCmds(myCmds)
|
839
|
906
|
|
840
|
907
|
# 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)
|
|
908
|
+ mkdirCmds = mkdirCmd(buildPath(['home',jupyterUsername,'.jupyter']),jupyterUsername,770)
|
|
909
|
+ executeSudoCmds(mkdirCmds)
|
845
|
910
|
|
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'])
|
856
|
|
- os.system(myCmd)
|
857
|
|
-
|
858
|
|
- #configPath = '/home/' + jupyterUsername + '}/.jupyter/jupyter_notebook_config.py'
|
859
|
|
- #write('root',configPath,configContent)
|
|
911
|
+ writeConfigurations(jupyterUsername)
|
860
|
912
|
|
861
|
913
|
# stop server instance
|
862
|
914
|
# 400 = deja stoppe
|
|
@@ -866,20 +918,19 @@ def createStudentServer(trainername,username,folder,notebookname):
|
866
|
918
|
initUserSpace(jupyterUsername,folder,notebookname,None)
|
867
|
919
|
|
868
|
920
|
# copie du dossier formateur
|
869
|
|
- fromPath = buildPath(['home',trainerJupyterUsername,'source',folder])
|
870
|
|
- toPath = buildPath(['home',jupyterUsername,'source'])
|
871
|
|
-
|
872
|
|
- # dévérouillage des dossiers
|
873
|
|
- copyCmd = ' ' + sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
874
|
|
- copyCmd += '&& ' + sudoPath + ' ' + chattrPath + ' -i \'' + buildPath(['home',trainerJupyterUsername,'source']) + '\''
|
875
|
|
- # copie
|
876
|
|
- copyCmd += '&& ' + sudoPath + ' ' + cpPath + ' -r \'' + fromPath + '\' \'' + toPath + '\''
|
877
|
|
- copyCmd += ' && ' + sudoPath + ' ' + chownPath + ' -R ' + jupyterUsername + ' \'' + toPath + '\''
|
878
|
|
- # vérouillage des dossiers
|
879
|
|
- copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + buildPath(['home',jupyterUsername,'source']) + '\''
|
880
|
|
- copyCmd += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + buildPath(['home',trainerJupyterUsername,'source']) + '\''
|
881
|
|
- dump(copyCmd)
|
882
|
|
- os.system(copyCmd)
|
|
921
|
+ copyCmds = []
|
|
922
|
+ copyCmds.append(unlockSourceCmd(jupyterUsername))
|
|
923
|
+ copyCmds.append(unlockSourceCmd(trainerJupyterUsername))
|
|
924
|
+ copyCmds.append(
|
|
925
|
+ copyCmd(
|
|
926
|
+ buildPath(['home',trainerJupyterUsername,'source',folder]),
|
|
927
|
+ buildPath(['home',jupyterUsername,'source']),
|
|
928
|
+ jupyterUsername
|
|
929
|
+ )
|
|
930
|
+ )
|
|
931
|
+ copyCmds.append(lockSourceCmd(jupyterUsername))
|
|
932
|
+ copyCmds.append(lockSourceCmd(trainerJupyterUsername))
|
|
933
|
+ executeSudoCmds(copyCmds)
|
883
|
934
|
|
884
|
935
|
# retourne l'url menant au notebook + les infos token utilisateur en cas d'ouverture de son serveur
|
885
|
936
|
userToken = None
|
|
@@ -1150,21 +1201,22 @@ def cloneNotebook(fromuuid,touuid,fromfolder,tofolder,reset):
|
1150
|
1201
|
dump(pathTo)
|
1151
|
1202
|
|
1152
|
1203
|
# dévérouille les dossiers
|
1153
|
|
- cloneCommand = sudoPath + ' ' + chattrPath + ' -i \'' + pathSourceFrom + '\''
|
1154
|
|
- cloneCommand += ' && ' + sudoPath + ' ' + chattrPath + ' -i \'' + pathSourceTo + '\''
|
|
1204
|
+ cloneCommands = []
|
|
1205
|
+ cloneCommands.append(unlockSourceCmd(jupyterUuidFrom))
|
|
1206
|
+ cloneCommands.append(unlockSourceCmd(jupyterUuidTo))
|
|
1207
|
+
|
1155
|
1208
|
if os.path.isdir(pathFrom) :
|
1156
|
1209
|
if os.path.isdir(pathTo) and reset == '1' and pathFrom != pathTo:
|
1157
|
1210
|
# suppression
|
1158
|
|
- cloneCommand += ' && ' + sudoPath + ' ' + rmPath + ' -rf \'' + pathTo + '\''
|
|
1211
|
+ cloneCommands.append(rmCmd(pathTo))
|
|
1212
|
+
|
1159
|
1213
|
# copie
|
1160
|
|
- cloneCommand += ' && ' + sudoPath + ' ' + cpPath + ' -r \'' + pathFrom + '/\' \'' + pathTo + '/\''
|
1161
|
|
- cloneCommand += ' && ' + sudoPath + ' ' + chownPath + ' -R ' + jupyterUuidTo + ' \'' + pathSourceTo + '\''
|
|
1214
|
+ cloneCommands.append(copyCmd(pathFrom,buildPath(['home',jupyterUuidTo,'source','']),jupyterUuidTo))
|
1162
|
1215
|
|
1163
|
|
- cloneCommand += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + pathSourceFrom + '\''
|
1164
|
|
- cloneCommand += ' && ' + sudoPath + ' ' + chattrPath + ' +i \'' + pathSourceTo + '\''
|
|
1216
|
+ cloneCommands.append(lockSourceCmd(jupyterUuidFrom))
|
|
1217
|
+ cloneCommands.append(lockSourceCmd(jupyterUuidTo))
|
1165
|
1218
|
|
1166
|
|
- dump(cloneCommand)
|
1167
|
|
- os.system(cloneCommand)
|
|
1219
|
+ executeSudoCmds(cloneCommands)
|
1168
|
1220
|
|
1169
|
1221
|
return json.dumps({ 'result':True,'folder': tofolder }),200
|
1170
|
1222
|
|