15from IPython.terminal.embed
import InteractiveShellEmbed
17from traitlets.config
import get_config
19from getpass
import getpass
25Home=os.environ[
'HOME']
26user=os.environ[
"USER"]
27TiledVizPath=
'/TiledViz'
29TilesScriptsPath=
'/opt'
31sys.path.append(
"/usr/local/lib/python3.10/site-packages")
32sys.path.append(
"/usr/local/lib64/python3.10/site-packages")
34sys.path.append(os.path.abspath(TiledVizPath+
'/TVDatabase'))
36from TVDb
import models
39sys.path.append(os.path.realpath(TiledVizPath+
'/TVConnections/'))
40from connect
import sock
44TVrunDir=Home+
'/.tiledviz'
45TVconf=TVrunDir+
"/tiledviz.conf"
47config = configparser.ConfigParser()
48config.optionxform = str
50ActionPort=int(config[
'TVSecure'][
'ActionPort'])
56MSGsize=int(config[
'sock'][
'MSGsize'])
58MaxSessionDuration=21600
65def cat_between(b,e,f):
66 os.system(
'/cat_between %d %d %s' % ( b, e, f))
69 return '{:03d}'.format(num)
72 parser = argparse.ArgumentParser(
73 'From a connection Id in PostgreSQL DB get connection parameters from TiledViz database.')
74 parser.add_argument(
'--host', default=
'localhost',
75 help=
'Database host (default: localhost)')
76 parser.add_argument(
'--port', default=
'6431',
77 help=
'Port (default: 6431)')
78 parser.add_argument(
'-l',
'--login', default=
'tiledviz',
79 help=
'Database login (default: tiledviz)')
80 parser.add_argument(
'-n',
'--databasename', default=
'TiledViz',
81 help=
'Database name (default: TiledViz)')
82 parser.add_argument(
'-u',
'--usertest', default=
'ddurandi',
83 help=
'User name for test (default: ddurandi)')
84 parser.add_argument(
'-c',
'--connectionId',
85 help=
'Connection Id in DB.')
86 parser.add_argument(
'--debug', action=
'store_true',
87 help=
'Debug switch for new job.',default=
False)
89 args = parser.parse_args(argv[1:])
96 def __init__(self,connectionId,globals,locals):
97 threading.Thread.__init__(self)
98 self.
thread = threading.Thread(target=self.
run, name=
"ServerAction",
99 args=(connectionId,globals,locals,)).start()
101 def run(self,connectionId,globals,locals):
103 tiles_actions[
"action0"]=[
"get_new_nodes",
"system_update_alt"]
107 logging.warning(f
"Launch server for action on {ActionPort}.")
111 logging.warning(f
"New connection detected on action server.")
116 logging.warning(f
"Action server hello message : {HelloMsg}")
118 logging.warning(
"Action server send back hello message")
122 logging.error(
"ServerAction : can't connect to client TVSecure")
123 traceback.print_exc(file=sys.stderr)
128 detectActionConnection=self.
detect()
129 if (detectActionConnection):
131 elif (detectActionConnection == -1):
134 if (self.
iter > NbActionDetect):
135 logging.warning(f
"No ActionServer detected after {NbActionDetect} tries.")
143 if (
"actionserver" in dir(self)):
149 logging.error(
"ServerAction : No more Action connection to server connectiondock")
155 actiontiles=list(map(int,data.replace(
',,',
'').split(
",")))
156 logging.warning(
"ServerAction : get actionTile message "+str(actiontiles))
157 actionId=actiontiles.pop(0)
159 logging.warning(
"ServerAction : not an action "+data)
165 if (len(actiontiles) > 0):
169 logging.debug(
"ServerAction : detect a valid selection "+str(self.
thisSelection))
173 logging.warning(
"ServerAction : detect a global action ")
176 logging.error(
"ServerAction : error reading "+self.
thisAction)
180 def execute(self,globals,locals):
182 logging.debug(
"ServerAction : run")
187 functionAction=eval(funaction)
188 search_tileNum=inspect.signature(functionAction).parameters
189 logging.debug(
"ServerAction : "+funaction+
" parameters :"+str(search_tileNum))
190 if (
"tileNum" in search_tileNum):
193 action=funaction+
"(tileNum="+str(num)+
")"
194 logging.warning(
"ServerAction : send action "+action)
195 eval(action,globals,locals)
197 logging.warning(
"ServerAction : Apply this action "+funaction+
" on all tiles.")
198 for num
in range(NUM_DOCKERS):
199 action=funaction+
"(tileNum="+str(num)+
")"
200 logging.warning(
"ServerAction : send action "+action)
201 eval(action,globals,locals)
203 action=funaction+
"()"
204 logging.warning(
"ServerAction : No tile for this action "+action)
205 eval(action,globals,locals)
206 logging.warning(
"ServerAction : action "+action+
" launched.")
208 traceback.print_exc(file=sys.stderr)
209 logging.warning(
"ServerAction : problem with action "+funaction+
" launch.")
218 COMMAND=
"bash -c \""+os.path.join(TILEDOCKERS_path,
"launch_dockers")+
" "+REF_CAS+
" "+GPU_FILE+
" "+SSH_FRONTEND+
":"+SSH_IP+\
219 " "+network+
" "+nethost+
" "+domain+
" "+init_IP+
" TileSetPort "+UserFront+
"@"+Frontend+
" "+OPTIONS+\
220 " > "+os.path.join(JOBPath,
"output_launch")+
" 2>&1 \""
221 logging.warning(
"\nCommand dockers : "+COMMAND)
222 client.send_server(LaunchTS+
' '+COMMAND)
223 state=client.get_OK()
224 logging.warning(
"Out of launch docker : "+ str(state))
230def Run_singularitys():
231 COMMAND=
"bash -c \""+os.path.join(TILESINGULARITYS_DIR,
"launch_singularitys")+
" "+REF_CAS+
" "+GPU_FILE+
" "+SSH_FRONTEND+
":"+SSH_IP+
" "+TILEDVIZ_DIR+
" "+TILESINGULARITYS_DIR+\
232 " TileSetPort "+UserFront+
"@"+Frontend+
" "+OPTIONS+\
233 " > "+os.path.join(JOBPath,
"output_launch")+
" 2>&1 \""
244 client.send_server(LaunchTS+
' '+COMMAND)
245 state=client.get_OK()
246 logging.warning(
"Out of launch singularity : "+ str(state))
252def build_nodes_file():
253 logging.warning(
"Build nodes.json file from new dockers list.")
254 COMMAND=LaunchTS+
' ./build_nodes_file '+os.path.join(JOBPath,CASE_config)+
' '+os.path.join(JOBPath,SITE_config)+
' '+TileSet
255 logging.warning(
"\nCommand dockers : "+COMMAND)
256 client.send_server(COMMAND)
257 state=client.get_OK()
258 logging.warning(
"Out of build_nodes_file : "+ str(state))
261 state=launch_nodes_json()
262 stateVM=stateVM
and (state == 0)
263 os.system(
"mv nodes.json nodes.json_init")
267 if (re.search(
'}',x)):
268 varname=x.replace(
"{",
"").replace(
"}",
"")
269 return config[
'CASE'][varname]
273def kill_all_containers():
283def Get_client_IP(tileNum=-1,tileId='001'):
285 TilesStr=
' Tiles=('+containerId(tileNum+1)+
') '
286 Id=containerId(tileNum+1)
288 TilesStr=
' Tiles=('+tileId+
') '
291 client.send_server(ExecuteTS+TilesStr+
292 'bash -c "/usr/local/bin/get_ip.sh;' +
293 'scp .vnc/myip '+HTTP_LOGIN+
'@'+HTTP_FRONTEND+
':'+JOBPath+
'/'+fileIP+
'"')
294 logging.debug(
"Out of get %s ip : %s " % ( Id,str(client.get_OK()) ))
295 get_file_client(client,TileSet,JOBPath,fileIP,
".")
300 with open(fileIP,
'r')
as fip:
301 IP=fip.read().replace(domain+
'.',
"").replace(
"\n",
"")
302 logging.warning(
"%s ip : "+domain+
'.'+IP)
306 logging.error(
"Cannot retreive ip from %s." % (Id) )
309def read_nodes_init():
311 JsonFile=
"nodes.json_init"
312 logging.warning(
"Before read : "+ str(JsonFile))
314 with open(JsonFile)
as json_tiles_file:
315 nodes_json=json.loads(json_tiles_file.read())
318 traceback.print_exc(file=sys.stdout)
319 os.system(
'ls -la '+JsonFile)
320 kill_all_containers()
323def nodes_json_init():
324 with open(
"listPortsTiles.pickle",
'rb')
as file_pi:
325 listPortsTilesIE=pickle.load(file_pi)
327 nodes_json=read_nodes_init()
329 for tilei
in range(NUM_DOCKERS):
330 nodeurl=nodes_json[
"nodes"][tilei][
"url"]
331 nodeurl=re.sub(
r'https://[^/]*',
r'https://'+listPortsTilesIE[
"TiledVizHost"],nodeurl)
332 nodeurl=re.sub(
r'host=[^&]*',
r'host='+listPortsTilesIE[
"TiledVizHost"],nodeurl)
333 oldport=int(re.sub(
r'.*port=([^&]*)&.*',
r'\1',nodeurl))
334 tileip=oldport % 1000 - 1
336 if ( str(tileip)
in listPortsTilesIE):
337 extern=listPortsTilesIE[str(tileip)][1]
338 nodes_json[
"nodes"][tilei][
"url"]=re.sub(
r'port=[^&]*',
r'port='+str(extern),nodeurl)
339 logging.warning(
"tile %d : new url %s" % (tilei,nodes_json[
"nodes"][tilei][
"url"]))
341 logging.warning(
"Before write nodes.json")
342 with open(
"nodes.json",
'w')
as nodesf:
343 nodesf.write(json.dumps(nodes_json))
347def share_ssh_key_docker():
352 filesize=os.path.getsize(sshKeyPath)
353 connectionkey=os.path.join(Home,
".ssh/"+sshKeyName)
354 os.system(
"cp "+sshKeyPath+
".pub "+os.path.join(Home,
".ssh/authorized_keys"))
355 packet_id_length=MSGsize-200
356 with open(sshKeyPath,
'rb')
as privatek:
357 l =
'\\\"'+str(privatek.read(packet_id_length).replace(b
"\n",b
""),
"utf-8")+
'\\\"'
358 COMMANDid=ExecuteTS+
' bash -c "echo '+l+
' > '+connectionkey+
'; chmod 600 '+connectionkey+
'"'
359 logging.warning(
"Send id_ed with %s." % (COMMANDid) )
360 client.send_server(COMMANDid)
361 state=client.get_OK()
362 stateVM=stateVM
and (state == 0)
364 totbyte=totbyte+packet_id_length
365 rest=filesize-totbyte;
366 if (rest > packet_id_length ):
367 l =
'\\\"'+str(privatek.read(packet_id_length).replace(b
"\n",b
""),
"utf-8")+
'\\\"'
368 COMMANDid=ExecuteTS+
' bash -c "echo '+l+
' >> '+connectionkey+
'"'
369 logging.warning(
"Send id_ed with %s." % (COMMANDid) )
370 client.send_server(COMMANDid)
371 state=client.get_OK()
372 stateVM=stateVM
and (state == 0)
375 l =
'\\\"'+str(privatek.read(rest).replace(b
"\n",b
""),
"utf-8")+
'\\\"'
376 COMMANDid=ExecuteTS+
' bash -c "echo '+l+
' >> '+connectionkey+
'"'
377 logging.warning(
"Send id_ed with %s." % (COMMANDid) )
378 client.send_server(COMMANDid)
379 state=client.get_OK()
380 stateVM=stateVM
and (state == 0)
382 logging.warning(
"Out of id_ed : "+ str(stateVM))
383 COMMANDid=ExecuteTS+
' bash -c "sed -e \\\"s&KEY-----&KEY-----\\\\n&\\\" -e \\\"s&-----END&\\\\n-----END&\\\" -i '+connectionkey+
'"'
384 logging.warning(
"Send id_ed with %s." % (COMMANDid) )
385 client.send_server(COMMANDid)
386 state=client.get_OK()
387 stateVM=stateVM
and (state == 0)
388 with open(sshKeyPath+
'.pub',
'rb')
as publick:
389 l =
'\\\"'+str(publick.read().replace(b
"\n",b
""),
"utf-8")+
'\\\"'
390 COMMANDid=ExecuteTS+
' bash -c "echo '+l+
' > '+connectionkey+
'.pub"'
391 logging.warning(
"Send id_ed.pub with %s." % (COMMANDid) )
392 client.send_server(COMMANDid)
393 state=client.get_OK()
394 stateVM=stateVM
and (state == 0)
395 logging.warning(
"Out of id_ed.pub : "+ str(stateVM))
397 logging.error(
"!! Error send id_ed.!!")
401def share_ssh_key_singularity():
405 connectionkey=os.path.join(HomeFront,
".ssh/"+sshKeyName)
406 os.system(
"cp "+sshKeyPath+
".pub "+os.path.join(Home,
".ssh/authorized_keys"))
407 send_file_server(client,TileSet,os.path.join(Home,
".ssh"), sshKeyName, JOBPath)
408 COMMANDid=LaunchTS+
' bash -c "mv '+os.path.join(JOBPath,sshKeyName)+
' '+connectionkey+
'; chmod 600 '+connectionkey+
'"'
409 logging.warning(
"Send id_ed with \"%s\"." % (COMMANDid) )
410 client.send_server(COMMANDid)
411 state=client.get_OK()
412 stateVM=stateVM
and (state == 0)
414 send_file_server(client,TileSet,os.path.join(Home,
".ssh"), sshKeyName+
".pub", JOBPath)
415 COMMANDid=LaunchTS+
' bash -c "mv '+os.path.join(JOBPath,sshKeyName+
".pub")+
' '+connectionkey+
".pub"+
'; chmod 666 '+connectionkey+
".pub"+
'"'
416 logging.warning(
"Send id_ed with \"%s\"." % (COMMANDid) )
417 client.send_server(COMMANDid)
418 state=client.get_OK()
419 stateVM=stateVM
and (state == 0)
420 logging.warning(
"Out of id_ed.pub : "+ str(stateVM))
422 logging.error(
"!! Error send id_ed.!!")
425share_ssh_key=share_ssh_key_docker
428def launch_tunnel_docker():
429 global TilesScriptsPath
430 logging.warning(
"TilesScriptsPath : %s" % (TilesScriptsPath))
433 connectionkey=
"/home/myuser/.ssh/"+sshKeyName
435 with open(
"listPortsTiles.pickle",
'rb')
as file_pi:
436 listPortsTilesIE=pickle.load(file_pi)
438 for i
in range(NUM_DOCKERS):
440 TILEi=ExecuteTS+
' Tiles=('+containerId(i+1)+
') '
441 internPort=listPortsTilesIE[str(i)][0]
442 WebServerHost=listPortsTilesIE[
"TiledVizHost"]
443 ServerTSPortSSH=listPortsTilesIE[
"TiledVizConnectionPort"]
444 COMMANDi=
' ssh-agent '+TilesScriptsPath+
'/tunnel_ssh '+SSH_FRONTEND+
' '+SSH_LOGIN+
' '+str(internPort)+
' '+WebServerHost+
' '+str(ServerTSPortSSH)+
' -i '+connectionkey
445 client.send_server(TILEi+COMMANDi)
446 state=client.get_OK()
447 logging.warning(
"%s | %s : %s" % (TILEi, COMMANDi,state))
448 stateVM=stateVM
and (state == 0)
450 print(
"!! Error launch_tunnel.!!")
454 logging.warning(
"Out of tunnel_ssh : "+ str(stateVM))
458def launch_tunnel_singularity():
459 global TilesScriptsPath
460 logging.warning(
"Singularity TilesScriptsPath : %s" % (TilesScriptsPath))
461 logging.warning(
"Frontend Home in anatomist_job: "+HomeFront)
464 connectionkey=os.path.join(HomeFront,
".ssh/"+sshKeyName)
466 with open(
"listPortsTiles.pickle",
'rb')
as file_pi:
467 listPortsTilesIE=pickle.load(file_pi)
469 for i
in range(NUM_DOCKERS):
471 TILEi=ExecuteTS+
' Tiles=('+containerId(i+1)+
') '
472 internPort=listPortsTilesIE[str(i)][0]
473 WebServerHost=listPortsTilesIE[
"TiledVizHost"]
474 ServerTSPortSSH=listPortsTilesIE[
"TiledVizConnectionPort"]
477 COMMANDi=
" nohup bash -c ' ssh-agent "+TilesScriptsPath+
'/tunnel_ssh '+SSH_FRONTEND+
' '+SSH_LOGIN+
' '+str(internPort)+
' '+WebServerHost+
' '+str(ServerTSPortSSH)+
' -i '+connectionkey+
" '&"
478 client.send_server(TILEi+COMMANDi)
479 state=client.get_OK()
480 logging.warning(
"%s | %s : %s" % (TILEi, COMMANDi,state))
481 stateVM=stateVM
and (state == 0)
483 print(
"!! Error launch_tunnel.!!")
488 logging.warning(
"Out of tunnel_ssh : "+ str(stateVM))
491launch_tunnel=launch_tunnel_docker
494 client.send_server(ExecuteTS+
' '+TilesScriptsPath+
'/vnccommand')
495 state=client.get_OK()
496 logging.warning(
"Out of vnccommand : "+ str(state))
502 client.send_server(ExecuteTS+
' wmctrl -l -G')
503 state=client.get_OK()
504 logging.warning(
"Out of wmctrl : "+ str(state))
509def clear_vnc(tileNum=-1,tileId='001'):
511 TilesStr=
' Tiles=('+containerId(tileNum+1)+
') '
513 TilesStr=
' Tiles=('+tileId+
') '
514 client.send_server(ExecuteTS+TilesStr+
' x11vnc -R clear-all')
515 state=client.get_OK()
516 logging.warning(
"Out of clear-vnc : "+ str(state))
522 os.system(
'x11vnc -R clear-all')
524 for i
in range(NUM_DOCKERS):
525 stateVM=stateVM
and clear_vnc(i)
529def changeSize(RESOL="1920x1080",tileNum=-1,tileId='001'):
531 TilesStr=
' Tiles=('+containerId(tileNum+1)+
') '
533 TilesStr=
' Tiles=('+tileId+
') '
534 COMMAND=ExecuteTS+TilesStr+
' xrandr --fb '+RESOL
535 logging.warning(
"call server with : "+COMMAND)
536 client.send_server(COMMAND)
537 state=client.get_OK()
538 logging.warning(
"server answer is "+str(state))
542def all_resize(RESOL="1280x800"):
543 client.send_server(ExecuteTS+
' bash -c "export DISPLAY=:1; xrandr --fb '+RESOL+
'"')
544 state=client.get_OK()
545 logging.warning(
"Out of xrandr : "+ str(state))
559def fullscreenApp(windowname=App,tileNum=-1,tileId='001'):
561 stateVM=movewindows(windowname=windowname,wmctrl_option=
'toggle,fullscreen',tileNum=tileNum)
563 stateVM=movewindows(windowname=windowname,wmctrl_option=
'toggle,fullscreen',tileId=tileId)
566def movewindows(windowname=App,wmctrl_option='toggle,fullscreen',tileNum=-1,tileId='001'):
567 COMMAND=TilesScriptsPath+
'/movewindows '+windowname+
' -b '+wmctrl_option
571 TilesStr=
' Tiles=('+containerId(tileNum+1)+
') '
573 TilesStr=
' Tiles=('+tileId+
') '
574 client.send_server(ExecuteTS+TilesStr+COMMAND)
575 state=client.get_OK()
579def showThisGUI(App="xterm",tileNum=-1,tileId='001'):
580 COMMAND=TilesScriptsPath+
'/movewindows '+App+
' -b toggle,above'
582 TilesStr=
' Tiles=('+containerId(tileNum+1)+
') '
584 TilesStr=
' Tiles=('+tileId+
') '
585 client.send_server(ExecuteTS+TilesStr+COMMAND)
586 state=client.get_OK()
590def click_point(tileNum=-1,tileId='001',X=0,Y=0):
592 TilesStr=
' Tiles=('+containerId(tileNum+1)+
') '
594 TilesStr=
' Tiles=('+tileId+
') '
595 COMMAND=
" xdotool mousemove "+str(X)+
" "+str(Y)+
" click 1 mousemove restore"
597 client.send_server(ExecuteTS+TilesStr+COMMAND)
598 state=client.get_OK()
599 logging.warning(
"Out of click_point : "+ str(state))
604if __name__ ==
'__main__':
605 args = parse_args(sys.argv)
607 logFormatter = logging.Formatter(
"TVConnection %(asctime)s - %(threadName)s - %(levelname)s: %(message)s ")
608 rootLogger = logging.getLogger()
609 rootLogger.setLevel(logging.WARNING)
610 fileHandler = logging.FileHandler(Home+
"/.vnc/TVConnection.log")
611 fileHandler.setLevel(logging.DEBUG)
612 fileHandler.setFormatter(logFormatter)
613 rootLogger.addHandler(fileHandler)
614 outHandler = logging.StreamHandler(sys.stdout)
615 outLevel=logging.DEBUG
617 outHandler.setLevel(outLevel)
618 outHandler.setFormatter(logFormatter)
619 rootLogger.addHandler(outHandler)
626 def set_thread_name(name):
627 logging.debug(
"For thread "+threading.current_thread().name+
" give name %s " % (name))
630 def _thread_name_hack(self):
631 set_thread_name(self.name)
632 logging.debug(
"For thread "+threading.current_thread().name+
" hack name %s " % (self.name))
634 self._bootstrap_inner()
636 if self._daemonic
and _sys
is None:
640 logging.debug(
"For thread "+threading.current_thread().name+
" end of hack name %s " % (self.name))
643 threading.Thread._bootstrap = _thread_name_hack
646 logging.debug(
'No python-prctl module. No thread names')
647 def set_thread_name(name):
pass
650 metadata, conn, engine, pool, session = tvdb.SQLconnector(args)
651 os.environ[
"POSTGRES_PASSWORD"]=
""
652 os.environ[
"passwordDB"]=
""
653 connectionId=int(args.connectionId)
654 logging.warning(
"Build connection number "+args.connectionId)
656 TVconnection=session.query(models.Connections).filter(models.Connections.id == connectionId).one()
657 auth_type=TVconnection.auth_type
659 logging.warning(
"From DB connection informations : "+str((auth_type,TVconnection.host_address,TVconnection.scheduler)))
660 TileSetDB=session.query(models.TileSets).filter_by(id_connections=args.connectionId).order_by(models.TileSets.id.desc()).first()
661 TileSet=TileSetDB.name
663 DATE=re.sub(
r'\..*',
'',datetime.datetime.isoformat(datetime.datetime.now(),sep=
'_').replace(
":",
"-"))
665 myhostname=os.getenv(
'HOSTNAME', os.getenv(
'COMPUTERNAME', platform.node())).split(
'.')[0]
668 CreateTS=
'create TS='+TileSet+
' Nb='+str(1)
671 ExecuteTS=
'execute TS='+TileSet+
" "
673 LaunchTS=
'launch TS='+TileSet+
" ."
675 def Remove_TileSet():
677 RemoveTS=
'remove TS='+TileSet
678 client.send_server(RemoveTS)
681 if (auth_type ==
"ssh" or auth_frontend):
682 CleanKeyFrontend =
"ssh -o ForwardX11=no -i "+sshKeyPath+
" -p "+sshPORT+
" "+UserFront+
'@localhost bash -cvx \'\"sed -i.'+DATE+
' /'+myhostname+
'/d ~/.ssh/authorized_keys; rm .ssh/'+sshKeyName+
'* \"\''
683 logging.warning(CleanKeyFrontend)
685 os.system(CleanKeyFrontend)
687 if (auth_type ==
"rebound"):
688 for iFront
in reversed(range(NbFrontendTo)):
689 CleanKeyFrontend =
"ssh -o ForwardX11=no -i "+sshKeyPath+
" "+lUserFront[iFront]+
"@"+lFrontend[iFront]+
' bash -cvx \'\"sed -i.'+DATE+
' /'+myhostname+
'/d ~/.ssh/authorized_keys; rm .ssh/'+sshKeyName+
'* \"\''
690 logging.warning(CleanKeyFrontend)
692 os.system(CleanKeyFrontend)
694 logging.warning(
"TileSet "+TileSet+
" removed on server")
697 TVuser=session.query(models.Users).filter(models.Users.id==TVconnection.id_users).first().name
709 if (auth_type ==
"rebound"):
712 NbFrontendTo = int(input(
"Give the number of gateways to go to the HPC frontend (0 if direct connection - ssh auth_type option) : "))
716 except ValueError
as err:
717 logging.error(
"Error : number of gateways - Only one integer.")
718 print(f
"Error : {err}\n Number of gateways - Only one integer is acceptable here please. Try again.")
721 Frontend = TVconnection.host_address
722 sshKeyName=
"id_ed_"+Frontend+
'_'+myhostname
723 sshKeyPath=os.path.join(Home,
".ssh",sshKeyName)
727 ansi_escape = re.compile(
r'''
729 (?: # 7-bit C1 Fe (except CSI)
731 | # or [ for CSI, followed by a control sequence
733 [0-?]* # Parameter bytes
734 [ -/]* # Intermediate bytes
743 if (auth_type ==
"rebound"):
745 if (NbFrontendTo == 0):
748 if (auth_type ==
"rebound"):
755 sshconfig=
"\nStrictHostKeyChecking no\n"
756 config_init=
"Config for connection for TileSet %s at date %s " % (TileSet, DATE)
757 sshconfig+=
"\n#---- "+config_init+
"\n"
759 for iFront
in range(NbFrontendTo):
762 nFront = input(f
"Enter the remote machine name number {iFront+1} : \n")
763 nFront = nFront.encode(
'ascii').decode()
765 except Exception
as err:
766 logging.error(f
"Error : remote machine {iFront+1} name - only ascii chars are available.")
767 print(f
"Error : {err}\n Remote machine {iFront+1} name - only ascii chars are available. Try again.")
769 lFrontend.append(nFront)
773 UserFront = input(
"Enter your remote machine number %d user name \n" % (iFront+1))
774 UserFront = UserFront.encode(
'ascii').decode()
776 except Exception
as err:
777 logging.error(f
"Error : remote machine {iFront+1} Username - only ascii chars are available.")
778 print(f
"Error : {err}\n Remote machine {iFront+1} Username - only ascii chars are available. Try again.")
781 lUserFront.append(UserFront)
787 sshconfig +=
"Host "+lFrontend[iFront]+
"\n"
788 sshconfig +=
" User "+lUserFront[iFront]+
"\n"
789 sshconfig +=
" IdentityFile ~/.ssh/"+sshKeyName+
"\n"
790 sshconfig +=
" IdentitiesOnly yes"+
"\n"
791 sshconfig +=
" ProxyJump "+lUserFront[iFront-1]+
'@'+lFrontend[iFront-1]+
"\n"
794 sshconfig +=
"Host "+lFrontend[iFront]+
"\n"
795 sshconfig +=
" User "+lUserFront[iFront]+
"\n"
796 sshconfig +=
" IdentityFile ~/.ssh/"+sshKeyName+
"\n"
797 sshconfig +=
" IdentitiesOnly yes"+
"\n"
801 if (sys.version_info[0:3] > (3,14,0)):
802 Password = getpass(f
"Enter your password for this machine {iFront+1} for user {UserFront} :\n", echo_char=
'_')
804 Password = getpass(f
"Enter your password for this machine {iFront+1} for user {UserFront} :\n")
805 Password=ansi_escape.sub(
'', Password)
807 except Exception
as err:
808 logging.error(f
"Error : remote machine {iFront+1} {UserFront} password - error with password.")
809 print(f
"Error : {err}\n remote machine {iFront+1} {UserFront} password - error with password. Try again.")
811 lPassword.append(Password)
813 if (auth_type ==
"ssh" or auth_type ==
"rebound"):
814 logging.warning(
"Remote machine frontend : "+Frontend)
817 UserFront = input(f
"Enter your frontend machine {Frontend} user name \n")
818 UserFront = UserFront.encode(
'ascii').decode()
820 except Exception
as err:
821 logging.error(f
"Error : frontend machine {Frontend} Username. only ascii chars are available.")
822 print(f
"Error : {err}\n Frontend machine {Frontend} Username - Only ascii chars are available. Try again.")
826 if (sys.version_info[0:3] > (3,14,0)):
827 Password = getpass(f
"Enter your frontend {Frontend} password for this user {UserFront} :\n", echo_char=
'_')
829 Password = getpass(f
"Enter your frontend {Frontend} password for this user {UserFront} :\n")
830 Password=ansi_escape.sub(
'', Password)
832 except Exception
as err:
833 logging.error(f
"Error : frontend {Frontend} {UserFront} password error.")
834 print(f
"Error : {err}\n Frontend {Frontend} {UserFront} password error. Try again.")
836 if (auth_type ==
"rebound"):
838 lFrontend.append(Frontend)
839 lUserFront.append(UserFront)
840 lPassword.append(Password)
844 sshconfig +=
"Host "+Frontend+
"\n"
845 sshconfig +=
" User "+UserFront+
"\n"
846 sshconfig +=
" IdentityFile ~/.ssh/"+sshKeyName+
"\n"
847 sshconfig +=
" IdentitiesOnly yes"+
"\n"
848 sshconfig +=
" ProxyJump "+lUserFront[NbFrontendTo-1]+
'@'+lFrontend[NbFrontendTo-1]+
"\n"
849 config_end=
"End config for connection for TileSet %s at date %s" % (TileSet, DATE)
850 sshconfig +=
"\n#---- "+config_end+
"\n"
853 sshconfigname=
".ssh/config"
854 with open(sshconfigname,
"w+")
as sshconfigf:
855 sshconfigf.write(str(sshconfig))
856 os.system(
'chmod 600 '+sshconfigname)
859 resp=input(
"Hit enter or save connection data now of 'n' to change remote login/password.\n")
864 cmdgen=
"ssh-keygen -t ed25519 -N '' -f "+sshKeyPath
865 childgen=pexpect.spawn(cmdgen)
866 childgen.expect(
'Generating public/private ed25519 key pair.')
867 childgen.expect(pexpect.EOF)
868 childgen.close(force=
True)
869 logging.warning(
"ssh key for this connection OK.")
870 os.system(
"cp -f "+sshKeyPath+
".pub .ssh/authorized_keys")
874 if (os.path.exists(
"config.tar")):
875 os.system(
"tar xf config.tar")
877 if (os.path.exists(
"rebound.sh")):
878 os.system(
"bash -c 'chmod u+x rebound.sh; ./rebound.sh 2>&1 > .vnc/out_rebound'")
881 if (auth_type ==
"rebound"):
883 for iFront
in range(NbFrontendTo):
884 cmdcopy=
"ssh-copy-id -f -o ForwardX11=no -o StrictHostKeyChecking=no -i "+sshKeyPath+
" "+lUserFront[iFront]+
"@"+lFrontend[iFront]
886 logging.warning(
"ssh-copy-id command :"+cmdcopy)
887 childcopy=pexpect.spawn(cmdcopy)
889 expindex=childcopy.expect([lUserFront[iFront]+
"@"+lFrontend[iFront]+
"\'s password: ",
".*Password: ",pexpect.EOF, pexpect.TIMEOUT])
890 if (expindex == 0
or expindex == 1 ):
891 outpass = childcopy.sendline(lPassword[iFront])
892 if outpass < len(lPassword[iFront]):
893 Password = getpass(
"Wrong password for "+lUserFront[iFront]+
"@"+lFrontend[iFront]+
". Try again enter your password for this user :\n")
894 Password=ansi_escape.sub(
'', Password)
895 childcopy.close(force=
True)
897 expindex=childcopy.expect([pexpect.EOF, pexpect.TIMEOUT])
900 logging.error(
"Error respond from server : "+str(childcopy.before,
"utf-8"))
902 logging.error(
"Error respond from server. "+str(expindex))
904 logging.warning(
"ssh authorized key copied on the server.")
905 childcopy.close(force=
True)
906 if (childcopy.exitstatus == 0):
907 lCONNECTED.append(
True)
909 lCONNECTED.append(
False)
912 logging.error(
"Error with copy id "+str(expindex))
913 logging.error(
"Spawn output : |"+str(childcopy.before,
"utf-8")+
"|")
915 logging.warning(
"after TIMEOUT ")
917 logging.warning(
"after "+str(childcopy.after,
"utf-8"))
918 logging.warning(
"existstatus : ",childcopy.exitstatus,
" signalestatus : ",childcopy.signalstatus)
920 logging.warning(
"ssh authorized key copied on the server after password.")
923 logging.error(
"load interact prompt to test by hand :")
924 code.interact(banner=
"Try connection :",local=dict(globals(), **locals()))
927 childcopy.close(force=
True)
928 if (childcopy.exitstatus == 0):
930 cmdcopy=
"scp -p -o ForwardX11=no -o StrictHostKeyChecking=no -i "+sshKeyPath+
" "+sshKeyPath+
" "+lUserFront[iFront]+
"@"+lFrontend[iFront]+
":.ssh/"
932 childcopy=pexpect.spawn(cmdcopy)
933 expindex=childcopy.expect([lUserFront[iFront]+
"@"+lFrontend[iFront]+
"\'s password: ",
".*Password: ",pexpect.EOF, pexpect.TIMEOUT])
935 logging.warning(
"ssh private key copied on the server %s." % (lFrontend[iFront]))
936 elif( expindex == 0
or expindex == 1 ):
937 logging.warning(
"Problem : ssh authorized key NOT copied on the server %s." % (lFrontend[iFront]))
938 outpass = childcopy.sendline(lPassword[iFront])
939 expindex=childcopy.expect([pexpect.EOF, pexpect.TIMEOUT])
942 logging.error(
"Error respond from server : "+str(childcopy.before,
"utf-8"))
944 logging.error(
"Error respond from server. "+str(expindex))
946 logging.warning(
"ssh private key copied on the server after password.")
947 childcopy.close(force=
True)
949 cmdcopy=
"scp -p -o ForwardX11=no -o StrictHostKeyChecking=no -i "+sshKeyPath+
" "+sshKeyPath+
".pub "+lUserFront[iFront]+
"@"+lFrontend[iFront]+
":.ssh/"
951 childcopy=pexpect.spawn(cmdcopy)
952 expindex=childcopy.expect([lUserFront[iFront]+
"@"+lFrontend[iFront]+
"\'s password: ",
".*Password: ",pexpect.EOF, pexpect.TIMEOUT])
954 logging.warning(
"ssh public key copied on the server %s." % (lFrontend[iFront]))
955 elif( expindex == 0
or expindex == 1 ):
956 logging.warning(
"Problem : ssh authorized key NOT copied on the server %s." % (lFrontend[iFront]))
957 outpass = childcopy.sendline(lPassword[iFront])
958 expindex=childcopy.expect([pexpect.EOF, pexpect.TIMEOUT])
961 logging.error(
"Error respond from server : "+str(childcopy.before,
"utf-8"))
963 logging.error(
"Error respond from server. "+str(expindex))
965 logging.warning(
"ssh public key copied on the server after password.")
966 childcopy.close(force=
True)
970 if (auth_type ==
"ssh" or auth_frontend):
971 cmdcopy=
"ssh-copy-id -f -o ForwardX11=no -o StrictHostKeyChecking=no -i "+sshKeyPath+
" "+UserFront+
"@"+Frontend
974 logging.warning(
"ssh-copy-id command :"+cmdcopy)
975 childcopy=pexpect.spawn(cmdcopy)
977 expindex=childcopy.expect([UserFront+
"@"+Frontend+
"\'s password: ",
".*Password: ",pexpect.EOF, pexpect.TIMEOUT]+[lUserFront[iFront]+
"@"+lFrontend[iFront]+
"\'s password: " for iFront
in range(NbFrontendTo)])
978 if (expindex == 0
or expindex == 1 ):
979 outpass = childcopy.sendline(Password)
980 if outpass < len(Password):
981 Password = getpass(
"Wrong password for "+UserFront+
"@"+Frontend+
". Try again enter your password for this user :\n")
982 Password=ansi_escape.sub(
'', Password)
983 childcopy.close(force=
True)
985 expindex=childcopy.expect([pexpect.EOF, pexpect.TIMEOUT])
988 logging.error(
"Error respond from server : "+str(childcopy.before,
"utf-8"))
990 logging.error(
"Error respond from server. "+str(expindex))
992 logging.warning(
"ssh key copied on the server.")
993 childcopy.close(force=
True)
994 if (childcopy.exitstatus == 0):
998 logging.error(
"Error with copy id %d" % (expindex))
999 logging.error(
"Spawn output : |"+str(childcopy.before,
"utf-8")+
"|")
1001 logging.warning(
"after TIMEOUT ")
1003 logging.warning(
"after "+str(childcopy.after,
"utf-8"))
1004 logging.warning(
"existstatus : ",childcopy.exitstatus,
" signalestatus : ",childcopy.signalstatus)
1006 logging.warning(
"ssh key copied on the server.")
1009 logging.error(
"load interact prompt to test by hand :")
1010 code.interact(banner=
"Try connection :",local=dict(globals(), **locals()))
1013 childcopy.close(force=
True)
1014 if (childcopy.exitstatus == 0):
1017 if (auth_type ==
"rebound"):
1024 sshPORT=str(int(s.getsockname()[1]));
1027 TunnelFrontend =
"ssh -o ForwardX11=no -4 -i "+sshKeyPath+
" -T -N -nf"+\
1028 " -L "+str(sock.PORTServer)+
":"+Frontend+
":"+str(sock.PORTServer)+\
1029 " -L "+sshPORT+
":localhost:22 "+UserFront+
"@"+Frontend
1031 logging.debug(TunnelFrontend)
1032 os.system(TunnelFrontend)
1033 logging.info(
"ssh tunneling OK.")
1035 lshome=
"ssh -o ForwardX11=no -i "+sshKeyPath+
" -p "+sshPORT+
" "+UserFront+
"@localhost 'ls $HOME/.tiledviz'"
1036 logging.debug(lshome)
1039 mkdirhome=
"ssh -o ForwardX11=no -i "+sshKeyPath+
" -p "+sshPORT+
" "+UserFront+
"@localhost 'mkdir $HOME/.tiledviz'"
1040 logging.debug(mkdirhome)
1041 os.system(mkdirhome)
1043 chmodhome=
"ssh -o ForwardX11=no -i "+sshKeyPath+
" -p "+sshPORT+
" "+UserFront+
"@localhost 'chmod og-rx $HOME/.tiledviz'"
1044 logging.debug(chmodhome)
1045 os.system(chmodhome)
1047 cmdhome=
"ssh -o ForwardX11=no -i "+sshKeyPath+
" -p "+sshPORT+
" "+UserFront+
"@localhost 'echo $HOME'"
1048 logging.debug(cmdhome)
1049 childhome=pexpect.spawn(cmdhome)
1050 expindex=childhome.expect([pexpect.EOF, pexpect.TIMEOUT])
1051 if ( expindex == 0 ):
1052 HomeFront = childhome.before.decode(
"utf-8").replace(
"\n",
"").replace(
"\r",
"")
1053 logging.warning(HomeFront)
1055 logging.warning(
"Error with requiring remote 'home' dir.")
1056 HomeFront = os.path.join(
"/home",UserFront)
1057 childhome.close(force=
True)
1059 TiledVizConfPath=os.path.join(HomeFront,
'.tiledviz')
1067 JOBPath=os.path.join(TiledVizConfPath,TileSet+
'_'+DATE)
1069 if (auth_type ==
"ssh"):
1070 WorkdirFrontend =
"ssh -o ForwardX11=no -i "+sshKeyPath+
" -p "+sshPORT+
" "+UserFront+
"@localhost mkdir "+JOBPath
1071 logging.debug(WorkdirFrontend)
1072 os.system(WorkdirFrontend)
1075 CONNECTdir=TiledVizPath+
"/TVConnections/connect"
1076 CONNECTpath=os.path.join(JOBPath,
"connect")
1078 ConnectdirFrontend =
'rsync -va -e "ssh -o ForwardX11=no -T -i '+sshKeyPath+
' -p '+sshPORT+
' " '+CONNECTdir+
' '+UserFront+
"@localhost"+
":"+JOBPath
1079 logging.debug(ConnectdirFrontend)
1080 os.system(ConnectdirFrontend)
1083 def launch_server(ServerFront):
1084 if ( ServerFront ==
"" ):
1085 TileServerFrontend =
'scp -o ForwardX11=no -i '+sshKeyPath+
' -P '+sshPORT+
' '+TiledVizPath+
'/TVConnections/TileServer.py '+UserFront+
"@localhost"+
":"+TiledVizConfPath
1086 logging.debug(TileServerFrontend)
1087 os.system(TileServerFrontend)
1088 cmdTileServer=
"ssh -o ForwardX11=no -i "+sshKeyPath+
" -p "+sshPORT+
" "+UserFront+
"@localhost 'sh -c \"cd "+TiledVizConfPath+
"; cp -rp "+os.path.join(JOBPath,
"connect")+
" .; HOSTNAME=\""+Frontend+
"\" python3 TileServer.py > TileServer_"+DATE+
".log 2>&1 & \"'"
1089 logging.debug(cmdTileServer)
1090 childTileServer=pexpect.spawn(cmdTileServer)
1091 expindex=childTileServer.expect([pexpect.EOF, pexpect.TIMEOUT])
1092 if ( expindex == 0 ):
1093 logging.warning(
"TileServer launched on frontend "+Frontend+
" !")
1096 logging.warning(
"Error on TileServer launched on frontend "+Frontend+
".")
1097 childTileServer.close(force=
True)
1099 def test_TileServer():
1100 cmdServer=
"ssh -o ForwardX11=no -i "+sshKeyPath+
" -p "+sshPORT+
" "+UserFront+
"@localhost 'sh -c \"ps -Aef |grep TileServer |grep -v grep |grep "+UserFront+
"\"'"
1101 logging.debug(cmdServer)
1102 childServer=pexpect.spawn(cmdServer)
1103 expindex=childServer.expect([pexpect.EOF, pexpect.TIMEOUT])
1104 if ( expindex == 0 ):
1105 ServerFront = childServer.before.decode(
"utf-8").replace(
"\n",
"").replace(
"\r",
"")
1106 logging.debug(ServerFront)
1107 launch_server(ServerFront)
1108 childServer.close(force=
True)
1113 filename=TileSetDB.launch_file
1126 def get_new_nodes():
1130 def launch_nodes_json():
1131 if (os.path.exists(
"nodes.json")):
1132 os.system(
'bash -c "mv nodes.json nodes.json_$(date +%F_%H-%M-%S)"')
1133 out_get=get_file_client(client,TileSet,JOBPath,
"nodes.json",
".")
1134 logging.warning(
"out of get_file nodes.json size : "+str(out_get))
1136 while( out_get <= 0):
1138 out_get=get_file_client(client,TileSet,JOBPath,
"nodes.json",
".")
1139 logging.warning(
"out of get_file "+str(iter)+
" nodes.json : "+str(out_get))
1142 logging.error(
"Something go wrong with nodes.json. We quit.")
1143 kill_all_containers()
1159 client=sock.client()
1161 logging.warning(
"Connection is not working with TileServer on Frontend, but the process exists. We ")
1162 cmdServer=
"ssh -o ForwardX11=no -i "+sshKeyPath+
" -p "+sshPORT+
" "+UserFront+
"@localhost 'sh -c \"pgrep TileServer |xargs kill \"'"
1163 os.system(cmdServer)
1164 logging.debug(cmdServer)
1168 client=sock.client()
1170 logging.warning(
"Second test. Can not connect with TileServer on Frontend. We may stop.")
1173 code.interact(banner=
"Wrong socket connection client (use raise Exception to close prompt without exiting).",local=dict(globals(), **locals()))
1178 traceback.print_exc(file=sys.stderr)
1182 def launch_actions():
1186 logging.warning(
"Launch actions thread.")
1189 GetActions=ServerAction(connectionId,globals=dict(globals()),locals=dict(**locals()))
1192 traceback.print_exc(file=sys.stdout)
1193 code.interact(banner=
"Error ServerAction :",local=dict(globals(), **locals()))
1195 logging.warning(f
"Actions \n {tiles_actions}")
1200 def launch_actions_and_interact():
1218 c.InteractiveShellEmbed.banner1 =
"Please type exit() to terminate launch script ."
1219 c.InteractiveShellEmbed.confirm_exit =
False
1221 IPython.embed(config=c)
1223 time.sleep(MaxSessionDuration)
1227 COMMANDStop=
"echo 'error script "+filename+
"'"
1228 exec(compile(open(filename,
"rb").read(), filename,
'exec'), globals(), locals())
1230 time.sleep(MaxSessionDuration)
1232 traceback.print_exc(file=sys.stderr)
1239 kill_all_containers()
1246 os.system(
'killall -9 ssh')
1250 code.interact(banner=
"Stop Connections :",local=dict(globals(), **locals()))
1254 traceback.print_exc(file=sys.stderr)
run(self, connectionId, globals, locals)
execute(self, globals, locals)