def backuptarfile(filepath, arcname=None, compress=None): """ Almost same - returns file descriptor for process that makes tar archive. But tar archive is created from single file, not folder. """ if not os.path.isfile(filepath): lg.out(1, 'backup_tar.backuptarfile ERROR %s not found' % filepath) return None if compress is None: compress = 'none' if arcname is None: arcname = strng.to_text(os.path.basename(filepath)) # lg.out(14, "backup_tar.backuptarfile %s compress=%s" % (filepath, compress)) if bpio.Windows(): if bpio.isFrozen(): commandpath = "bppipe.exe" cmdargs = [commandpath, 'nosubdirs', compress, filepath, arcname] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, 'nosubdirs', compress, filepath, arcname] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, 'nosubdirs', compress, filepath, arcname] if not os.path.isfile(commandpath): lg.out(1, 'backup_tar.backuptarfile ERROR %s not found' % commandpath) return None # lg.out(12, "backup_tar.backuptarfile going to execute %s" % str(cmdargs)) # p = run(cmdargs) p = child_process.pipe(cmdargs) return p
def backuptar(directorypath, recursive_subfolders=True, compress=None): """ Returns file descriptor for process that makes tar archive. In other words executes a child process and create a Pipe to communicate with it. """ if not bpio.pathIsDir(directorypath): lg.out(1, 'backup_tar.backuptar ERROR %s not found' % directorypath) return None subdirs = 'subdirs' if not recursive_subfolders: subdirs = 'nosubdirs' if compress is None: compress = 'none' # lg.out(14, "backup_tar.backuptar %s %s compress=%s" % (directorypath, subdirs, compress)) if bpio.Windows(): if bpio.isFrozen(): commandpath = "bppipe.exe" cmdargs = [commandpath, subdirs, compress, directorypath] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, subdirs, compress, directorypath] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, subdirs, compress, directorypath] if not os.path.isfile(commandpath): lg.out(1, 'backup_tar.backuptar ERROR %s not found' % commandpath) return None # lg.out(14, "backup_tar.backuptar going to execute %s" % str(cmdargs)) # p = child_process.run('bppipe', cmdargs[2:]) p = child_process.pipe(cmdargs) return p
def extracttar(tarfile, outdir): """ Opposite method, run bppipe to extract files and folders from ".tar" file. """ if not os.path.isfile(tarfile): lg.out(1, 'backup_tar.extracttar ERROR %s not found' % tarfile) return None lg.out(6, "backup_tar.extracttar %s %s" % (tarfile, outdir)) if bpio.Windows(): if bpio.isFrozen(): commandpath = 'bppipe.exe' cmdargs = [commandpath, 'extract', tarfile, outdir] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, 'extract', tarfile, outdir] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, 'extract', tarfile, outdir] if not os.path.isfile(commandpath): lg.out(1, 'backup_tar.extracttar ERROR %s is not found' % commandpath) return None # p = run(cmdargs) cmdargs = [strng.to_text(a) for a in cmdargs] p = child_process.pipe(cmdargs) return p
def backuptardir(directorypath, arcname=None, recursive_subfolders=True, compress=None): """ Returns file descriptor for process that makes tar archive. In other words executes a child process and create a Pipe to communicate with it. """ if not bpio.pathIsDir(directorypath): lg.out(1, 'backup_tar.backuptar ERROR %s not found' % directorypath) return None subdirs = 'subdirs' if not recursive_subfolders: subdirs = 'nosubdirs' if compress is None: compress = 'none' if arcname is None: arcname = strng.to_text(os.path.basename(directorypath)) # lg.out(14, "backup_tar.backuptar %s %s compress=%s" % (directorypath, subdirs, compress)) if bpio.Windows(): if bpio.isFrozen(): commandpath = "bppipe.exe" cmdargs = [commandpath, subdirs, compress, directorypath, arcname] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, subdirs, compress, directorypath, arcname] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, subdirs, compress, directorypath, arcname] if not os.path.isfile(commandpath): lg.out(1, 'backup_tar.backuptar ERROR %s not found' % commandpath) return None # lg.out(14, "backup_tar.backuptar going to execute %s" % str(cmdargs)) # p = child_process.run('bppipe', cmdargs[2:]) p = child_process.pipe(cmdargs) return p
def shutdown(): from logs import lg from main import config from system import bpio lg.out(2, 'bpmain.shutdown') import shutdowner shutdowner.A('reactor-stopped') from automats import automat automat.objects().clear() if len(automat.index()) > 0: lg.warn('%d automats was not cleaned' % len(automat.index())) for a in automat.index().keys(): lg.out(2, ' %r' % a) else: lg.out(2, 'bpmain.shutdown automat.objects().clear() SUCCESS, no state machines left in memory') config.conf().removeCallback('logs/debug-level') lg.out(2, 'bpmain.shutdown currently %d threads running:' % len(threading.enumerate())) for t in threading.enumerate(): lg.out(2, ' ' + str(t)) lg.out(2, 'bpmain.shutdown finishing and closing log file, EXIT') automat.CloseLogFile() lg.close_log_file() if bpio.Windows() and bpio.isFrozen(): lg.stdout_stop_redirecting() return 0
def backuptarfile(filepath, compress=None): """ Almost same - returns file descriptor for process that makes tar archive. But tar archive is created from single file, not folder. """ if not os.path.isfile(filepath): lg.out(1, 'backup_tar.backuptarfile ERROR %s not found' % filepath) return None if compress is None: compress = 'none' # lg.out(14, "backup_tar.backuptarfile %s compress=%s" % (filepath, compress)) if bpio.Windows(): if bpio.isFrozen(): commandpath = "bppipe.exe" cmdargs = [commandpath, 'nosubdirs', compress, filepath] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, 'nosubdirs', compress, filepath] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, 'nosubdirs', compress, filepath] if not os.path.isfile(commandpath): lg.out(1, 'backup_tar.backuptarfile ERROR %s not found' % commandpath) return None # lg.out(12, "backup_tar.backuptarfile going to execute %s" % str(cmdargs)) # p = run(cmdargs) p = child_process.pipe(cmdargs) return p
def run(child_name, params=[], base_dir='.', process_protocol=None): """ This is another portable solution to execute a process. """ if bpio.isFrozen() and bpio.Windows(): progpath = os.path.abspath(os.path.join(base_dir, child_name + '.exe')) executable = progpath cmdargs = [progpath] cmdargs.extend(params) else: progpath = os.path.abspath(os.path.join(base_dir, child_name + '.py')) executable = sys.executable cmdargs = [executable, progpath] cmdargs.extend(params) if not os.path.isfile(executable): lg.out(1, 'child_process.run ERROR %s not found' % executable) return None if not os.path.isfile(progpath): lg.out(1, 'child_process.run ERROR %s not found' % progpath) return None lg.out(6, 'child_process.run: "%s"' % (' '.join(cmdargs))) if bpio.Windows(): from twisted.internet import _dumbwin32proc real_CreateProcess = _dumbwin32proc.win32process.CreateProcess # @UndefinedVariable def fake_createprocess(_appName, _commandLine, _processAttributes, _threadAttributes, _bInheritHandles, creationFlags, _newEnvironment, _currentDirectory, startupinfo): import win32con # @UnresolvedImport flags = win32con.CREATE_NO_WINDOW return real_CreateProcess(_appName, _commandLine, _processAttributes, _threadAttributes, _bInheritHandles, flags, _newEnvironment, _currentDirectory, startupinfo) setattr(_dumbwin32proc.win32process, 'CreateProcess', fake_createprocess) if process_protocol is None: process_protocol = ChildProcessProtocol(child_name) try: Process = reactor.spawnProcess(process_protocol, executable, cmdargs, path=base_dir) # @UndefinedVariable except: lg.out(1, 'child_process.run ERROR executing: %s' % str(cmdargs)) lg.exc() return None if bpio.Windows(): setattr(_dumbwin32proc.win32process, 'CreateProcess', real_CreateProcess) lg.out(6, 'child_process.run [%s] pid=%d' % (child_name, Process.pid)) return Process
def shutdown(): from logs import lg from main import config from system import bpio if _Debug: lg.out(_DebugLevel, 'bpmain.shutdown') if config.conf(): config.conf().removeConfigNotifier('logs/debug-level') from . import shutdowner shutdowner.A('reactor-stopped') from main import events events.shutdown() from automats import automat automat.objects().clear() if len(automat.index()) > 0: lg.warn('%d automats was not cleaned' % len(automat.index())) for a in automat.index().keys(): if _Debug: lg.out(_DebugLevel, ' %r' % a) else: if _Debug: lg.out( _DebugLevel, 'bpmain.shutdown automat.objects().clear() SUCCESS, no state machines left in memory' ) if _Debug: lg.out( _DebugLevel, 'bpmain.shutdown currently %d threads running:' % len(threading.enumerate())) for t in threading.enumerate(): if _Debug: lg.out(_DebugLevel, ' ' + str(t)) if _Debug: lg.out(_DebugLevel, 'bpmain.shutdown finishing and closing log file, EXIT') automat.CloseLogFile() lg.close_log_file() lg.close_intercepted_log_file() if bpio.Windows() and bpio.isFrozen(): lg.stdout_stop_redirecting() from main import settings settings.shutdown() return 0
def init(): lg.out(4, 'os_windows_update.init') # update_shedule_file(settings.getUpdatesSheduleData()) if not bpio.isFrozen() or not bpio.Windows(): lg.out(6, 'os_windows_update.init finishing') return # if not os.path.isfile(settings.VersionFile()): # bpio.WriteFile(settings.VersionFile(), '') SetLocalDir(bpio.getExecutableDir()) if settings.getUpdatesMode() != settings.getUpdatesModeValues()[2]: lg.out(6, 'os_windows_update.init starting the loop') reactor.callLater(0, loop, True) else: lg.out(6, 'os_windows_update.init skip, update mode is: %s' % settings.getUpdatesMode())
def run(Tester): global _CurrentProcess # lg.out(8, 'localtester.run ' + str(Tester)) if bpio.isFrozen() and bpio.Windows(): commandpath = 'bptester.exe' cmdargs = [commandpath, Tester] else: commandpath = 'bptester.py' cmdargs = [sys.executable, commandpath, Tester] if not os.path.isfile(commandpath): lg.out(1, 'localtester.run ERROR %s not found' % commandpath) return None lg.out(14, 'localtester.run execute: %s' % cmdargs) try: if bpio.Windows(): import win32process _CurrentProcess = nonblocking.Popen( cmdargs, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, creationflags=win32process.CREATE_NO_WINDOW, ) else: _CurrentProcess = nonblocking.Popen( cmdargs, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, ) except: lg.out(1, 'localtester.run ERROR executing: %s' % str(cmdargs)) lg.exc() return None return _CurrentProcess
def run(Tester): global _CurrentProcess # lg.out(8, 'localtester.run ' + str(Tester)) if bpio.isFrozen() and bpio.Windows(): commandpath = 'bptester.exe' cmdargs = [commandpath, Tester] else: commandpath = 'bptester.py' cmdargs = [sys.executable, commandpath, Tester] if not os.path.isfile(commandpath): lg.out(1, 'localtester.run ERROR %s not found' % commandpath) return None lg.out(14, 'localtester.run execute: %s' % cmdargs) try: if bpio.Windows(): import win32process _CurrentProcess = nonblocking.Popen( cmdargs, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, creationflags=win32process.CREATE_NO_WINDOW,) else: _CurrentProcess = nonblocking.Popen( cmdargs, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False,) except: lg.out(1, 'localtester.run ERROR executing: %s' % str(cmdargs)) lg.exc() return None return _CurrentProcess
def extracttar(tarfile, outdir): """ Opposite method, run bppipe to extract files and folders from ".tar" file. """ if not os.path.isfile(tarfile): lg.out(1, 'backup_tar.extracttar ERROR %s not found' % tarfile) return None lg.out(6, "backup_tar.extracttar %s %s" % (tarfile, outdir)) if bpio.Windows(): if bpio.isFrozen(): commandpath = 'bppipe.exe' cmdargs = [commandpath, 'extract', tarfile, outdir] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, 'extract', tarfile, outdir] else: commandpath = "bppipe.py" cmdargs = [sys.executable, commandpath, 'extract', tarfile, outdir] if not os.path.isfile(commandpath): lg.out(1, 'backup_tar.extracttar ERROR %s is not found' % commandpath) return None # p = run(cmdargs) p = child_process.pipe(cmdargs) return p
def init(UI='', options=None, args=None, overDict=None, executablePath=None): """ In the method ``main()`` program firstly checks the command line arguments and then calls this method to start the whole process. This initialize some low level modules and finally create an instance of ``initializer()`` state machine and send it an event "run". """ global AppDataDir from logs import lg lg.out(4, 'bpmain.run UI="%s"' % UI) from system import bpio #---settings--- from main import settings if overDict: settings.override_dict(overDict) settings.init(AppDataDir) if not options or options.debug is None: lg.set_debug_level(settings.getDebugLevel()) from main import config config.conf().addCallback('logs/debug-level', lambda p, value, o, r: lg.set_debug_level(value)) #---USE_TRAY_ICON--- if os.path.isfile(settings.LocalIdentityFilename()) and os.path.isfile(settings.KeyFileName()): try: from system.tray_icon import USE_TRAY_ICON if bpio.Mac() or not bpio.isGUIpossible(): lg.out(4, ' GUI is not possible') USE_TRAY_ICON = False if USE_TRAY_ICON: from twisted.internet import wxreactor wxreactor.install() lg.out(4, ' wxreactor installed') except: USE_TRAY_ICON = False lg.exc() else: lg.out(4, ' local identity or key file is not ready') USE_TRAY_ICON = False lg.out(4, ' USE_TRAY_ICON=' + str(USE_TRAY_ICON)) if USE_TRAY_ICON: from system import tray_icon icons_path = bpio.portablePath(os.path.join(bpio.getExecutableDir(), 'icons')) lg.out(4, 'bpmain.run call tray_icon.init(%s)' % icons_path) tray_icon.init(icons_path) def _tray_control_func(cmd): if cmd == 'exit': from . import shutdowner shutdowner.A('stop', 'exit') tray_icon.SetControlFunc(_tray_control_func) #---OS Windows init--- if bpio.Windows(): try: from win32event import CreateMutex # @UnresolvedImport mutex = CreateMutex(None, False, "BitDust") lg.out(4, 'bpmain.run created a Mutex: %s' % str(mutex)) except: lg.exc() #---twisted reactor--- lg.out(4, 'bpmain.run want to import twisted.internet.reactor') try: from twisted.internet import reactor # @UnresolvedImport except: lg.exc() sys.exit('Error initializing reactor in bpmain.py\n') #---logfile---- if lg.logs_enabled() and lg.log_file(): lg.out(2, 'bpmain.run want to switch log files') if bpio.Windows() and bpio.isFrozen(): lg.stdout_stop_redirecting() lg.close_log_file() lg.open_log_file(settings.MainLogFilename()) # lg.open_log_file(settings.MainLogFilename() + '-' + time.strftime('%y%m%d%H%M%S') + '.log') if bpio.Windows() and bpio.isFrozen(): lg.stdout_start_redirecting() #---memdebug--- # if settings.uconfig('logs.memdebug-enable') == 'True': # try: # from logs import memdebug # memdebug_port = int(settings.uconfig('logs.memdebug-port')) # memdebug.start(memdebug_port) # reactor.addSystemEventTrigger('before', 'shutdown', memdebug.stop) # lg.out(2, 'bpmain.run memdebug web server started on port %d' % memdebug_port) # except: # lg.exc() #---process ID--- try: pid = os.getpid() pid_file_path = os.path.join(settings.MetaDataDir(), 'processid') bpio.WriteTextFile(pid_file_path, str(pid)) lg.out(2, 'bpmain.run wrote process id [%s] in the file %s' % (str(pid), pid_file_path)) except: lg.exc() # #---reactor.callLater patch--- # if lg.is_debug(12): # patchReactorCallLater(reactor) # monitorDelayedCalls(reactor) # #---plugins--- # from plugins import plug # plug.init() # reactor.addSystemEventTrigger('before', 'shutdown', plug.shutdown) lg.out(2, " python executable is: %s" % sys.executable) lg.out(2, " python version is:\n%s" % sys.version) lg.out(2, " python sys.path is:\n %s" % ('\n '.join(sys.path))) lg.out(2, "bpmain.run UI=[%s]" % UI) if lg.is_debug(20): lg.out(0, '\n' + bpio.osinfofull()) lg.out(4, 'import automats') #---START!--- from automats import automat automat.LifeBegins(lg.when_life_begins()) automat.OpenLogFile(settings.AutomatsLog()) from main import events events.init() from main import initializer IA = initializer.A() lg.out(4, 'sending event "run" to initializer()') reactor.callWhenRunning(IA.automat, 'run', UI) # @UndefinedVariable return IA
def main(executable_path=None): """ THIS IS THE ENTRY POINT OF THE PROGRAM! """ global AppDataDir pars = parser() (opts, args) = pars.parse_args() overDict = override_options(opts, args) cmd = '' if len(args) > 0: cmd = args[0].lower() #---install--- if cmd in ['deploy', 'install', 'venv', 'virtualenv', ]: from system import deploy return deploy.run(args) try: from logs import lg except: dirpath = os.path.dirname(os.path.abspath(sys.argv[0])) sys.path.insert(0, os.path.abspath(os.path.join(dirpath, '..'))) # sys.path.insert(0, os.path.abspath(os.path.join(dirpath, '..', '..'))) from distutils.sysconfig import get_python_lib sys.path.append(os.path.join(get_python_lib(), 'bitdust')) try: from logs import lg except: print('ERROR! can not import working code. Python Path:') print('\n'.join(sys.path)) return 1 # init IO module, update locale from system import bpio bpio.init() # sys.excepthook = lg.exception_hook if not bpio.isFrozen(): try: from twisted.internet.defer import setDebugging setDebugging(True) # from twisted.python import log as twisted_log # twisted_log.startLogging(sys.stdout) except: lg.warn('python-twisted is not installed') if opts.appdir: appdata = opts.appdir AppDataDir = appdata else: curdir = os.getcwd() # os.path.dirname(os.path.abspath(sys.executable)) appdatafile = os.path.join(curdir, 'appdata') defaultappdata = os.path.join(os.path.expanduser('~'), '.bitdust') appdata = defaultappdata if os.path.isfile(appdatafile): try: appdata = os.path.abspath(open(appdatafile, 'rb').read().strip()) except: appdata = defaultappdata if not os.path.isdir(appdata): appdata = defaultappdata AppDataDir = appdata # ask to count time for each log line from that moment, not absolute time lg.life_begins() # try to read debug level value at the early stage - no problem if fail here try: if cmd == '' or cmd == 'start' or cmd == 'go' or cmd == 'show' or cmd == 'open': lg.set_debug_level(int( bpio.ReadTextFile( os.path.abspath( os.path.join(appdata, 'config', 'logs', 'debug-level'))))) except: pass if opts.no_logs: lg.disable_logs() #---logpath--- logpath = os.path.join(appdata, 'logs', 'start.log') if opts.output: logpath = opts.output need_redirecting = False if bpio.Windows() and not bpio.isConsoled(): need_redirecting = True if logpath != '': lg.open_log_file(logpath) lg.out(2, 'bpmain.main log file opened ' + logpath) if bpio.Windows() and bpio.isFrozen(): need_redirecting = True if need_redirecting: lg.stdout_start_redirecting() lg.out(2, 'bpmain.main redirecting started') # very basic solution to record run-time errors try: if os.path.isfile(os.path.join(appdata, 'logs', 'exception.log')): os.remove(os.path.join(appdata, 'logs', 'exception.log')) except: pass if opts.debug or str(opts.debug) == '0': lg.set_debug_level(opts.debug) # if opts.quite and not opts.verbose: # lg.disable_output() if opts.verbose: copyright_text() lg.out(2, 'bpmain.main started ' + time.asctime()) lg.out(2, 'bpmain.main args=%s' % str(args)) #---start--- if cmd == '' or cmd == 'start' or cmd == 'go': appList = bpio.find_main_process(pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if appList: lg.out(0, 'BitDust already started, found another process: %s\n' % str(appList)) bpio.shutdown() return 0 UI = '' # if cmd == 'show' or cmd == 'open': # UI = 'show' try: ret = run(UI, opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret #---daemon--- elif cmd == 'detach' or cmd == 'daemon': appList = bpio.find_main_process(pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if len(appList) > 0: lg.out(0, 'main BitDust process already started: %s\n' % str(appList)) bpio.shutdown() return 0 from lib import misc lg.out(0, 'new BitDust process will be started in daemon mode, finishing current process\n') bpio.shutdown() result = misc.DoRestart( detach=True, std_out=os.path.join(appdata, 'logs', 'stdout.log'), std_err=os.path.join(appdata, 'logs', 'stderr.log'), ) if result is not None: try: result = int(result) except: try: result = result.pid except: pass return 0 #---restart--- elif cmd == 'restart' or cmd == 'reboot': appList = bpio.find_main_process(pid_file_path=os.path.join(appdata, 'metadata', 'processid')) ui = False if len(appList) > 0: lg.out(0, 'found main BitDust process: %s, sending "restart" command ... ' % str(appList), '') def done(x): lg.out(0, 'DONE\n', '') from twisted.internet import reactor # @UnresolvedImport if reactor.running and not reactor._stopped: # @UndefinedVariable reactor.stop() # @UndefinedVariable def failed(x): ok = str(x).count('Connection was closed cleanly') > 0 from twisted.internet import reactor # @UnresolvedImport if ok and reactor.running and not reactor._stopped: # @UndefinedVariable lg.out(0, 'DONE\n', '') reactor.stop() # @UndefinedVariable return lg.out(0, 'FAILED while killing previous process - do HARD restart\n', '') try: kill() except: lg.exc() from lib import misc reactor.addSystemEventTrigger( # @UndefinedVariable 'after', 'shutdown', misc.DoRestart, param='show' if ui else '', detach=True, std_out=os.path.join(appdata, 'logs', 'stdout.log'), std_err=os.path.join(appdata, 'logs', 'stderr.log'), ) reactor.stop() # @UndefinedVariable try: from twisted.internet import reactor # @UnresolvedImport # from interface.command_line import run_url_command # d = run_url_command('?action=restart', False) # from interface import cmd_line # d = cmd_line.call_xmlrpc_method('restart', ui) from interface import cmd_line_json d = cmd_line_json.call_jsonrpc_method('restart', ui) d.addCallback(done) d.addErrback(failed) reactor.run() # @UndefinedVariable bpio.shutdown() return 0 except: lg.exc() bpio.shutdown() return 1 else: ui = '' if cmd == 'restart': ui = 'show' try: ret = run(ui, opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret #---show--- elif cmd == 'show' or cmd == 'open': if not bpio.isGUIpossible(): lg.out(0, 'BitDust GUI is turned OFF\n') bpio.shutdown() return 0 if bpio.Linux() and not bpio.X11_is_running(): lg.out(0, 'this operating system not supported X11 interface\n') bpio.shutdown() return 0 appList = bpio.find_main_process(pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if len(appList) == 0: try: ret = run('show', opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret lg.out(0, 'found main BitDust process: %s, start the GUI\n' % str(appList)) ret = show() bpio.shutdown() return ret #---stop--- elif cmd == 'stop' or cmd == 'kill' or cmd == 'shutdown': appList = bpio.find_main_process( pid_file_path=os.path.join(appdata, 'metadata', 'processid'), ) if len(appList) > 0: lg.out(0, 'found main BitDust process: %r, sending command "exit" ... ' % appList, '') try: from twisted.internet import reactor # @UnresolvedImport # from interface.command_line import run_url_command # url = '?action=exit' # run_url_command(url, False).addBoth(wait_then_kill) # reactor.run() # bpio.shutdown() def _stopped(x): lg.out(0, 'BitDust process finished correctly\n') reactor.stop() # @UndefinedVariable bpio.shutdown() # from interface import cmd_line # cmd_line.call_xmlrpc_method('stop').addBoth(_stopped) from interface import cmd_line_json cmd_line_json.call_jsonrpc_method('stop').addBoth(_stopped) reactor.run() # @UndefinedVariable return 0 except: lg.exc() ret = kill() bpio.shutdown() return ret else: appListAllChilds = bpio.find_main_process( check_processid_file=False, extra_lookups=['regexp:^.*python.*bitdust.py.*?$', ], ) if len(appListAllChilds) > 0: lg.out(0, 'BitDust child processes found: %r, performing "kill process" actions ...\n' % appListAllChilds, '') ret = kill() return ret lg.out(0, 'BitDust is not running at the moment\n') bpio.shutdown() return 0 #---command_line--- from interface import cmd_line_json as cmdln ret = cmdln.run(opts, args, pars, overDict, executable_path) if ret == 2: print(usage_text()) bpio.shutdown() return ret
def main(executable_path=None): """ THIS IS THE ENTRY POINT OF THE PROGRAM! """ global AppDataDir import warnings warnings.filterwarnings("ignore", message="You do not have a working installation of the service_identity module") try: from logs import lg except: dirpath = os.path.dirname(os.path.abspath(sys.argv[0])) sys.path.insert(0, os.path.abspath(os.path.join(dirpath, '..'))) # sys.path.insert(0, os.path.abspath(os.path.join(dirpath, '..', '..'))) from distutils.sysconfig import get_python_lib sys.path.append(os.path.join(get_python_lib(), 'bitdust')) try: from logs import lg except: print 'ERROR! can not import working code. Python Path:' print '\n'.join(sys.path) return 1 # init IO module, update locale from system import bpio bpio.init() # sys.excepthook = lg.exception_hook if not bpio.isFrozen(): try: from twisted.internet.defer import setDebugging setDebugging(True) # from twisted.python import log as twisted_log # twisted_log.startLogging(sys.stdout) except: lg.warn('python-twisted is not installed') pars = parser() (opts, args) = pars.parse_args() if opts.appdir: appdata = opts.appdir AppDataDir = appdata else: curdir = os.getcwd() # os.path.dirname(os.path.abspath(sys.executable)) appdatafile = os.path.join(curdir, 'appdata') defaultappdata = os.path.join(os.path.expanduser('~'), '.bitdust') appdata = defaultappdata if os.path.isfile(appdatafile): try: appdata = os.path.abspath(open(appdatafile, 'rb').read().strip()) except: appdata = defaultappdata if not os.path.isdir(appdata): appdata = defaultappdata AppDataDir = appdata cmd = '' if len(args) > 0: cmd = args[0].lower() # ask to count time for each log line from that moment, not absolute time lg.life_begins() # try to read debug level value at the early stage - no problem if fail here try: if cmd == '' or cmd == 'start' or cmd == 'go' or cmd == 'show' or cmd == 'open': lg.set_debug_level(int( bpio._read_data( os.path.abspath( os.path.join(appdata, 'config', 'logs', 'debug-level'))))) except: pass if opts.no_logs: lg.disable_logs() #---logpath--- logpath = os.path.join(appdata, 'logs', 'start.log') if opts.output: logpath = opts.output need_redirecting = False if bpio.Windows() and not bpio.isConsoled(): need_redirecting = True if logpath != '': lg.open_log_file(logpath) lg.out(2, 'bpmain.main log file opened ' + logpath) if bpio.Windows() and bpio.isFrozen(): need_redirecting = True if need_redirecting: lg.stdout_start_redirecting() lg.out(2, 'bpmain.main redirecting started') # TODO: temporary solution to record run-time errors try: if os.path.isfile(os.path.join(appdata, 'logs', 'exception.log')): os.remove(os.path.join(appdata, 'logs', 'exception.log')) except: pass if opts.debug or str(opts.debug) == '0': lg.set_debug_level(opts.debug) # if opts.quite and not opts.verbose: # lg.disable_output() if opts.verbose: copyright_text() lg.out(2, 'bpmain.main started ' + time.asctime()) overDict = override_options(opts, args) lg.out(2, 'bpmain.main args=%s' % str(args)) #---start--- if cmd == '' or cmd == 'start' or cmd == 'go': appList = bpio.find_main_process(pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if appList: lg.out(0, 'BitDust already started, found another process: %s\n' % str(appList)) bpio.shutdown() return 0 UI = '' # if cmd == 'show' or cmd == 'open': # UI = 'show' try: ret = run(UI, opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret #---daemon--- elif cmd == 'detach' or cmd == 'daemon' or cmd == 'background': appList = bpio.find_main_process(pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if len(appList) > 0: lg.out(0, 'main BitDust process already started: %s\n' % str(appList)) bpio.shutdown() return 0 from lib import misc lg.out(0, 'new BitDust process will be started in daemon mode, finishing current process\n') bpio.shutdown() result = misc.DoRestart(detach=True) if result is not None: try: result = int(result) except: try: result = result.pid except: pass return 0 #---restart--- elif cmd == 'restart' or cmd == 'reboot': appList = bpio.find_main_process(pid_file_path=os.path.join(appdata, 'metadata', 'processid')) ui = False if len(appList) > 0: lg.out(0, 'found main BitDust process: %s, sending "restart" command ... ' % str(appList), '') def done(x): lg.out(0, 'DONE\n', '') from twisted.internet import reactor if reactor.running and not reactor._stopped: reactor.stop() def failed(x): ok = str(x).count('Connection was closed cleanly') > 0 from twisted.internet import reactor if ok and reactor.running and not reactor._stopped: lg.out(0, 'DONE\n', '') reactor.stop() return lg.out(0, 'FAILED while killing previous process - do HARD restart\n', '') try: kill() except: lg.exc() from lib import misc reactor.addSystemEventTrigger('after', 'shutdown', misc.DoRestart, param='show' if ui else '', detach=True) reactor.stop() try: from twisted.internet import reactor # from interface.command_line import run_url_command # d = run_url_command('?action=restart', False) # from interface import cmd_line # d = cmd_line.call_xmlrpc_method('restart', ui) from interface import cmd_line_json d = cmd_line_json.call_jsonrpc_method('restart', ui) d.addCallback(done) d.addErrback(failed) reactor.run() bpio.shutdown() return 0 except: lg.exc() bpio.shutdown() return 1 else: ui = '' if cmd == 'restart': ui = 'show' try: ret = run(ui, opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret #---show--- elif cmd == 'show' or cmd == 'open': from main import settings if not bpio.isGUIpossible() and not settings.NewWebGUI(): lg.out(0, 'BitDust GUI is turned OFF\n') bpio.shutdown() return 0 if bpio.Linux() and not bpio.X11_is_running(): lg.out(0, 'this operating system not supported X11 interface\n') bpio.shutdown() return 0 appList = bpio.find_main_process(pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if len(appList) == 0: try: ret = run('show', opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret lg.out(0, 'found main BitDust process: %s, start the GUI\n' % str(appList)) ret = show() bpio.shutdown() return ret #---stop--- elif cmd == 'stop' or cmd == 'kill' or cmd == 'shutdown': appList = bpio.find_main_process(pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if len(appList) > 0: lg.out(0, 'found main BitDust process: %s, sending command "exit" ... ' % str(appList), '') try: from twisted.internet import reactor # from interface.command_line import run_url_command # url = '?action=exit' # run_url_command(url, False).addBoth(wait_then_kill) # reactor.run() # bpio.shutdown() def _stopped(x): lg.out(0, 'BitDust process finished correctly\n') reactor.stop() bpio.shutdown() # from interface import cmd_line # cmd_line.call_xmlrpc_method('stop').addBoth(_stopped) from interface import cmd_line_json cmd_line_json.call_jsonrpc_method('stop').addBoth(_stopped) reactor.run() return 0 except: lg.exc() ret = kill() bpio.shutdown() return ret else: lg.out(0, 'BitDust is not running at the moment\n') bpio.shutdown() return 0 #---uninstall--- elif cmd == 'uninstall': def do_spawn(x=None): from main.settings import WindowsStarterFileName starter_filepath = os.path.join(bpio.getExecutableDir(), WindowsStarterFileName()) lg.out(0, "bpmain.main bitstarter.exe path: %s " % starter_filepath) if not os.path.isfile(starter_filepath): lg.out(0, "ERROR: %s not found\n" % starter_filepath) bpio.shutdown() return 1 cmdargs = [os.path.basename(starter_filepath), 'uninstall'] lg.out(0, "bpmain.main os.spawnve cmdargs=" + str(cmdargs)) ret = os.spawnve(os.P_DETACH, starter_filepath, cmdargs, os.environ) bpio.shutdown() return ret def do_reactor_stop_and_spawn(x=None): lg.out(0, 'BitDust process finished correctly\n') reactor.stop() ret = do_spawn() bpio.shutdown() return ret lg.out(0, 'bpmain.main UNINSTALL!') if not bpio.Windows(): lg.out(0, 'This command can be used only under OS Windows.\n') bpio.shutdown() return 0 if not bpio.isFrozen(): lg.out(0, 'You are running BitDust from sources, uninstall command is available only for installable version.\n') bpio.shutdown() return 0 appList = bpio.find_process(['bitdust.exe', ]) if len(appList) > 0: lg.out(0, 'found main BitDust process... ', '') try: # from twisted.internet import reactor # from interface.command_line import run_url_command # url = '?action=exit' # run_url_command(url).addBoth(do_reactor_stop_and_spawn) # reactor.run() # bpio.shutdown() # from interface import cmd_line # cmd_line.call_xmlrpc_method('stop').addBoth(do_reactor_stop_and_spawn) from interface import cmd_line_json cmd_line_json.call_jsonrpc_method('stop').addBoth(do_reactor_stop_and_spawn) reactor.run() return 0 except: lg.exc() ret = do_spawn() bpio.shutdown() return ret #---command_line--- # from interface import command_line as cmdln # from interface import cmd_line as cmdln from interface import cmd_line_json as cmdln ret = cmdln.run(opts, args, pars, overDict, executable_path) if ret == 2: print usage_text() bpio.shutdown() return ret
def main(executable_path=None): """ THIS IS THE ENTRY POINT OF THE PROGRAM! """ global AppDataDir import warnings warnings.filterwarnings("ignore", message="You do not have a working installation of the service_identity module") try: from logs import lg except: dirpath = os.path.dirname(os.path.abspath(sys.argv[0])) sys.path.insert(0, os.path.abspath(os.path.join(dirpath, '..'))) # sys.path.insert(0, os.path.abspath(os.path.join(dirpath, '..', '..'))) from distutils.sysconfig import get_python_lib sys.path.append(os.path.join(get_python_lib(), 'bitdust')) try: from logs import lg except: print 'ERROR! can not import working code. Python Path:' print '\n'.join(sys.path) return 1 # init IO module, update locale from system import bpio bpio.init() # sys.excepthook = lg.exception_hook if not bpio.isFrozen(): from twisted.internet.defer import setDebugging setDebugging(True) pars = parser() (opts, args) = pars.parse_args() if opts.appdir: appdata = opts.appdir AppDataDir = appdata else: curdir = os.getcwd() # os.path.dirname(os.path.abspath(sys.executable)) appdatafile = os.path.join(curdir, 'appdata') defaultappdata = os.path.join(os.path.expanduser('~'), '.bitdust') appdata = defaultappdata if os.path.isfile(appdatafile): try: appdata = os.path.abspath(open(appdatafile, 'rb').read().strip()) except: appdata = defaultappdata if not os.path.isdir(appdata): appdata = defaultappdata AppDataDir = appdata cmd = '' if len(args) > 0: cmd = args[0].lower() # ask to count time for each log line from that moment, not absolute time lg.life_begins() # try to read debug level value at the early stage - no problem if fail here try: if cmd == '' or cmd == 'start' or cmd == 'go' or cmd == 'show' or cmd == 'open': lg.set_debug_level(int( bpio._read_data( os.path.abspath( os.path.join(appdata, 'config', 'logs', 'debug-level'))))) except: pass if opts.no_logs: lg.disable_logs() #---logpath--- logpath = os.path.join(appdata, 'logs', 'start.log') if opts.output: logpath = opts.output need_redirecting = False if bpio.Windows() and not bpio.isConsoled(): need_redirecting = True if logpath != '': lg.open_log_file(logpath) lg.out(2, 'bpmain.main log file opened ' + logpath) if bpio.Windows() and bpio.isFrozen(): need_redirecting = True if need_redirecting: lg.stdout_start_redirecting() lg.out(2, 'bpmain.main redirecting started') try: if os.path.isfile(os.path.join(appdata, 'logs', 'exception.log')): os.remove(os.path.join(appdata, 'logs', 'exception.log')) except: pass if opts.debug or str(opts.debug) == '0': lg.set_debug_level(opts.debug) # if opts.quite and not opts.verbose: # lg.disable_output() if opts.verbose: copyright() lg.out(2, 'bpmain.main started ' + time.asctime()) overDict = override_options(opts, args) lg.out(2, 'bpmain.main args=%s' % str(args)) #---start--- if cmd == '' or cmd == 'start' or cmd == 'go': appList = bpio.find_process([ 'bitdust.exe', 'bpmain.py', 'bitdust.py', 'regexp:^/usr/bin/python\ +/usr/bin/bitdust.*$', ]) # this is extra protection for Debian release # I am not sure how process name can looks on different systems # check the process ID from previous start # it file exists and we found this PID in the currently running apps - BitDust is working # if file not exists we don't want to start if found some other jobs with same name # pid = -1 # try: # if bpio.Windows(): # _data_path = os.path.join(os.environ.get('APPDATA', os.path.join(os.path.expanduser('~'), 'Application Data')), 'BitDust') # pid_path = os.path.join(_data_path, 'metadata', 'processid') # else: # pid_path = os.path.join(appdata, 'metadata', 'processid') # if os.path.isfile(pid_path): # pid = int(bpio.ReadBinaryFile(pid_path).strip()) # except: # lg.exc() if len(appList) > 0: lg.out(0, 'BitDust already started, found another process: %s\n' % str(appList)) bpio.shutdown() return 0 UI = '' # if cmd == 'show' or cmd == 'open': # UI = 'show' try: ret = run(UI, opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret #---detach--- elif cmd == 'detach' or cmd == 'daemon' or cmd == 'background': # lg.set_debug_level(20) appList = bpio.find_process([ 'bitdust.exe', 'bpmain.py', 'bitdust.py', 'regexp:^/usr/bin/python\ +/usr/bin/bitdust.*$', ]) if len(appList) > 0: lg.out(0, 'main BitDust process already started: %s\n' % str(appList)) bpio.shutdown() return 0 from lib import misc # from twisted.internet import reactor # def _detach(): # result = misc.DoRestart(detach=True) # lg.out(0, 'run and detach main BitDust process: %s' % str(result)) # reactor.callLater(2, reactor.stop) # reactor.addSystemEventTrigger('after','shutdown', misc.DoRestart, detach=True) # reactor.callLater(0.01, _detach) # reactor.run() lg.out(0, 'main BitDust process started in daemon mode\n') bpio.shutdown() result = misc.DoRestart(detach=True) try: result = result.pid except: pass return 0 #---restart--- elif cmd == 'restart' or cmd == 'reboot': appList = bpio.find_process([ 'bitdust.exe', 'bpmain.py', 'bitdust.py', 'regexp:^/usr/bin/python\ +/usr/bin/bitdust.*$', ]) ui = False # if cmd == 'restart': # ui = True if len(appList) > 0: lg.out(0, 'found main BitDust process: %s, sending "restart" command ... ' % str(appList), '') def done(x): lg.out(0, 'DONE\n', '') from twisted.internet import reactor if reactor.running and not reactor._stopped: reactor.stop() def failed(x): ok = str(x).count('Connection was closed cleanly') > 0 from twisted.internet import reactor if ok and reactor.running and not reactor._stopped: lg.out(0, 'DONE\n', '') reactor.stop() return lg.out(0, 'FAILED while killing previous process - do HARD restart\n', '') try: kill() except: lg.exc() from lib import misc reactor.addSystemEventTrigger('after', 'shutdown', misc.DoRestart, param='show' if ui else '', detach=True) reactor.stop() try: from twisted.internet import reactor # from interface.command_line import run_url_command # d = run_url_command('?action=restart', False) # from interface import cmd_line # d = cmd_line.call_xmlrpc_method('restart', ui) from interface import cmd_line_json d = cmd_line_json.call_jsonrpc_method('restart', ui) d.addCallback(done) d.addErrback(failed) reactor.run() bpio.shutdown() return 0 except: lg.exc() bpio.shutdown() return 1 else: ui = '' if cmd == 'restart': ui = 'show' try: ret = run(ui, opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret #---show--- elif cmd == 'show' or cmd == 'open': from main import settings if not bpio.isGUIpossible() and not settings.NewWebGUI(): lg.out(0, 'BitDust GUI is turned OFF\n') bpio.shutdown() return 0 if bpio.Linux() and not bpio.X11_is_running(): lg.out(0, 'this operating system not supported X11 interface\n') bpio.shutdown() return 0 appList = bpio.find_process([ 'bitdust.exe', 'bpmain.py', 'bitdust.py', 'regexp:^/usr/bin/python\ +/usr/bin/bitdust.*$', ]) if not settings.NewWebGUI(): appList_bpgui = bpio.find_process([ 'bpgui.exe', 'bpgui.py', ]) if len(appList_bpgui) > 0: if len(appList) == 0: for pid in appList_bpgui: bpio.kill_process(pid) else: lg.out(0, 'BitDust GUI already opened, found another process: %s\n' % str(appList)) bpio.shutdown() return 0 if len(appList) == 0: try: ret = run('show', opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret lg.out(0, 'found main BitDust process: %s, start the GUI\n' % str(appList)) ret = show() bpio.shutdown() return ret #---stop--- elif cmd == 'stop' or cmd == 'kill' or cmd == 'shutdown': appList = bpio.find_process([ 'bitdust.exe', 'bpmain.py', 'bitdust.py', 'regexp:^/usr/bin/python\ +/usr/bin/bitdust.*$', ]) if len(appList) > 0: lg.out(0, 'found main BitDust process: %s, sending command "exit" ... ' % str(appList), '') try: from twisted.internet import reactor # from interface.command_line import run_url_command # url = '?action=exit' # run_url_command(url, False).addBoth(wait_then_kill) # reactor.run() # bpio.shutdown() def _stopped(x): lg.out(0, 'BitDust process finished correctly\n') reactor.stop() bpio.shutdown() # from interface import cmd_line # cmd_line.call_xmlrpc_method('stop').addBoth(_stopped) from interface import cmd_line_json cmd_line_json.call_jsonrpc_method('stop').addBoth(_stopped) reactor.run() return 0 except: lg.exc() ret = kill() bpio.shutdown() return ret else: lg.out(0, 'BitDust is not running at the moment\n') bpio.shutdown() return 0 #---uninstall--- elif cmd == 'uninstall': def do_spawn(x=None): from main.settings import WindowsStarterFileName starter_filepath = os.path.join(bpio.getExecutableDir(), WindowsStarterFileName()) lg.out(0, "bpmain.main bitstarter.exe path: %s " % starter_filepath) if not os.path.isfile(starter_filepath): lg.out(0, "ERROR: %s not found\n" % starter_filepath) bpio.shutdown() return 1 cmdargs = [os.path.basename(starter_filepath), 'uninstall'] lg.out(0, "bpmain.main os.spawnve cmdargs=" + str(cmdargs)) ret = os.spawnve(os.P_DETACH, starter_filepath, cmdargs, os.environ) bpio.shutdown() return ret def do_reactor_stop_and_spawn(x=None): lg.out(0, 'BitDust process finished correctly\n') reactor.stop() ret = do_spawn() bpio.shutdown() return ret lg.out(0, 'bpmain.main UNINSTALL!') if not bpio.Windows(): lg.out(0, 'This command can be used only under OS Windows.\n') bpio.shutdown() return 0 if not bpio.isFrozen(): lg.out(0, 'You are running BitDust from sources, uninstall command is available only for installable version.\n') bpio.shutdown() return 0 appList = bpio.find_process(['bitdust.exe', ]) if len(appList) > 0: lg.out(0, 'found main BitDust process... ', '') try: # from twisted.internet import reactor # from interface.command_line import run_url_command # url = '?action=exit' # run_url_command(url).addBoth(do_reactor_stop_and_spawn) # reactor.run() # bpio.shutdown() # from interface import cmd_line # cmd_line.call_xmlrpc_method('stop').addBoth(do_reactor_stop_and_spawn) from interface import cmd_line_json cmd_line_json.call_jsonrpc_method('stop').addBoth(do_reactor_stop_and_spawn) reactor.run() return 0 except: lg.exc() ret = do_spawn() bpio.shutdown() return ret #---command_line--- # from interface import command_line as cmdln # from interface import cmd_line as cmdln from interface import cmd_line_json as cmdln ret = cmdln.run(opts, args, pars, overDict, executable_path) if ret == 2: print usage() bpio.shutdown() return ret
def init(UI='', options=None, args=None, overDict=None, executablePath=None): """ In the method ``main()`` program firstly checks the command line arguments and then calls this method to start the whole process. This initialize some low level modules and finally create an instance of ``initializer()`` state machine and send it an event "run". """ global AppDataDir from logs import lg lg.out(4, 'bpmain.run UI="%s"' % UI) from system import bpio #---settings--- from main import settings if overDict: settings.override_dict(overDict) settings.init(AppDataDir) if not options or options.debug is None: lg.set_debug_level(settings.getDebugLevel()) from main import config config.conf().addCallback('logs/debug-level', lambda p, value, o, r: lg.set_debug_level(value)) #---USE_TRAY_ICON--- if os.path.isfile(settings.LocalIdentityFilename()) and os.path.isfile(settings.KeyFileName()): try: from system.tray_icon import USE_TRAY_ICON if bpio.Mac() or not bpio.isGUIpossible(): lg.out(4, ' GUI is not possible') USE_TRAY_ICON = False if USE_TRAY_ICON: from twisted.internet import wxreactor wxreactor.install() lg.out(4, ' wxreactor installed') except: USE_TRAY_ICON = False lg.exc() else: lg.out(4, ' local identity or key file is not ready') USE_TRAY_ICON = False lg.out(4, ' USE_TRAY_ICON=' + str(USE_TRAY_ICON)) if USE_TRAY_ICON: from system import tray_icon icons_path = bpio.portablePath(os.path.join(bpio.getExecutableDir(), 'icons')) lg.out(4, 'bpmain.run call tray_icon.init(%s)' % icons_path) tray_icon.init(icons_path) def _tray_control_func(cmd): if cmd == 'exit': import shutdowner shutdowner.A('stop', 'exit') tray_icon.SetControlFunc(_tray_control_func) #---OS Windows init--- if bpio.Windows(): try: from win32event import CreateMutex mutex = CreateMutex(None, False, "BitDust") lg.out(4, 'bpmain.run created a Mutex: %s' % str(mutex)) except: lg.exc() #---twisted reactor--- lg.out(4, 'bpmain.run want to import twisted.internet.reactor') try: from twisted.internet import reactor except: lg.exc() sys.exit('Error initializing reactor in bpmain.py\n') #---logfile---- if lg.logs_enabled() and lg.log_file(): lg.out(2, 'bpmain.run want to switch log files') if bpio.Windows() and bpio.isFrozen(): lg.stdout_stop_redirecting() lg.close_log_file() lg.open_log_file(settings.MainLogFilename() + '-' + time.strftime('%y%m%d%H%M%S') + '.log') if bpio.Windows() and bpio.isFrozen(): lg.stdout_start_redirecting() #---memdebug--- # if settings.uconfig('logs.memdebug-enable') == 'True': # try: # from logs import memdebug # memdebug_port = int(settings.uconfig('logs.memdebug-port')) # memdebug.start(memdebug_port) # reactor.addSystemEventTrigger('before', 'shutdown', memdebug.stop) # lg.out(2, 'bpmain.run memdebug web server started on port %d' % memdebug_port) # except: # lg.exc() #---process ID--- try: pid = os.getpid() pid_file_path = os.path.join(settings.MetaDataDir(), 'processid') bpio.WriteFile(pid_file_path, str(pid)) lg.out(2, 'bpmain.run wrote process id [%s] in the file %s' % (str(pid), pid_file_path)) except: lg.exc() # #---reactor.callLater patch--- # if lg.is_debug(12): # patchReactorCallLater(reactor) # monitorDelayedCalls(reactor) # #---plugins--- # from plugins import plug # plug.init() # reactor.addSystemEventTrigger('before', 'shutdown', plug.shutdown) lg.out(2, "bpmain.run UI=[%s]" % UI) if lg.is_debug(20): lg.out(0, '\n' + bpio.osinfofull()) lg.out(4, 'bpmain.run import automats') #---START!--- from automats import automat automat.LifeBegins(lg.when_life_begins()) automat.OpenLogFile(settings.AutomatsLog()) import initializer I = initializer.A() lg.out(4, 'bpmain.run send event "run" to initializer()') reactor.callWhenRunning(I.automat, 'run', UI) return I
def DoRestart(param='', detach=False, std_out='/dev/null', std_err='/dev/null'): """ A smart and portable way to restart a whole program. """ if bpio.Windows(): if bpio.isFrozen(): # lg.out(2, "misc.DoRestart under Windows (Frozen), param=%s" % param) # lg.out(2, "misc.DoRestart sys.executable=" + sys.executable) # lg.out(2, "misc.DoRestart sys.argv=" + str(sys.argv)) starter_filepath = os.path.join(bpio.getExecutableDir(), settings.WindowsStarterFileName()) if not os.path.isfile(starter_filepath): # lg.out(2, "misc.DoRestart ERROR %s not found" % starter_filepath) main_filepath = os.path.join( bpio.getExecutableDir(), settings.WindowsMainScriptFileName()) cmdargs = [ os.path.basename(main_filepath), ] if param != '': cmdargs.append(param) # lg.out(2, "misc.DoRestart cmdargs="+str(cmdargs)) return os.spawnve(os.P_DETACH, main_filepath, cmdargs, os.environ) # @UndefinedVariable cmdargs = [ os.path.basename(starter_filepath), ] if param != '': cmdargs.append(param) # lg.out(2, "misc.DoRestart cmdargs="+str(cmdargs)) return os.spawnve(os.P_DETACH, starter_filepath, cmdargs, os.environ) # @UndefinedVariable pypath = sys.executable cmdargs = [ sys.executable, ] cmdargs.append(sys.argv[0]) cmdargs += sys.argv[1:] if param != '' and not sys.argv.count(param): cmdargs.append(param) if cmdargs.count('restart'): cmdargs.remove('restart') if cmdargs.count('detach'): cmdargs.remove('detach') if cmdargs.count('daemon'): cmdargs.remove('daemon') if detach: from system import child_process cmdargs = [strng.to_text(a) for a in cmdargs] return child_process.detach(cmdargs) return os.execvpe(pypath, cmdargs, os.environ) pypyth = sys.executable cmdargs = [ sys.executable, ] if sys.argv[0] == '/usr/share/bitdust/bitdust.py': cmdargs.append('/usr/bin/bitdust') else: cmdargs.append(sys.argv[0]) if param: cmdargs.append(param) if cmdargs.count('restart'): cmdargs.remove('restart') if cmdargs.count('detach'): cmdargs.remove('detach') if cmdargs.count('daemon'): cmdargs.remove('daemon') pid = os.fork() if pid != 0: return None if detach: cmdargs[1] = os.path.abspath(cmdargs[1]) cmdargs.append('1>%s' % std_out) cmdargs.append('2>%s' % std_err) cmd = '/usr/bin/nohup ' + (' '.join(cmdargs)) + ' &' BITDUST_COVERAGE_PROCESS_START = os.environ.get( 'COVERAGE_PROCESS_START') if BITDUST_COVERAGE_PROCESS_START: cmd = 'COVERAGE_PROCESS_START="%s" %s' % ( BITDUST_COVERAGE_PROCESS_START, cmd, ) BITDUST_LOG_USE_COLORS = os.environ.get('BITDUST_LOG_USE_COLORS') if BITDUST_LOG_USE_COLORS: cmd = 'BITDUST_LOG_USE_COLORS="%s" %s' % ( BITDUST_LOG_USE_COLORS, cmd, ) return os.system(cmd) return os.execvpe(pypyth, cmdargs, os.environ)
def cmd_uninstall(opts, args, overDict): if not bpio.Windows(): print 'This command can be used only under OS Windows.' return 0 if not bpio.isFrozen(): print 'You are running BitDust from sources, uninstall command is available only for binary version.' return 0 def do_uninstall(): lg.out(0, 'command_line.do_uninstall') # batfilename = misc.MakeBatFileToUninstall() # misc.UpdateRegistryUninstall(True) # misc.RunBatFile(batfilename, 'c:/out2.txt') def kill(): lg.out(0, 'kill') total_count = 0 found = False while True: appList = bpio.find_process([ 'bitdust.exe', 'bpmain.py', 'bitdust.py', 'regexp:^/usr/bin/python.*bitdust.*$', 'bpgui.exe', 'bpgui.py', 'bppipe.exe', 'bppipe.py', 'bptester.exe', 'bptester.py', 'bitstarter.exe', ]) if len(appList) > 0: found = True for pid in appList: lg.out(0, 'trying to stop pid %d' % pid) bpio.kill_process(pid) if len(appList) == 0: if found: lg.out(0, 'BitDust stopped\n') else: lg.out(0, 'BitDust was not started\n') return 0 total_count += 1 if total_count > 10: lg.out(0, 'some BitDust process found, but can not stop it\n') return 1 time.sleep(1) def wait_then_kill(x): lg.out(0, 'wait_then_kill') total_count = 0 #while True: def _try(): lg.out(0, '_try') appList = bpio.find_process([ 'bitdust.exe', 'bpgui.exe', 'bppipe.exe', 'bptester.exe', 'bitstarter.exe', ]) lg.out(0, 'appList:' + str(appList)) if len(appList) == 0: lg.out(0, 'finished') reactor.stop() do_uninstall() return 0 total_count += 1 lg.out(0, '%d' % total_count) if total_count > 10: lg.out(0, 'not responding') ret = kill() reactor.stop() if ret == 0: do_uninstall() return ret reactor.callLater(1, _try) _try() # time.sleep(1) appList = bpio.find_process([ 'bitdust.exe', 'bpgui.exe', 'bppipe.exe', 'bptester.exe', 'bitstarter.exe', ]) if len(appList) == 0: lg.out(0, 'uninstalling BitDust ... ') do_uninstall() return 0 lg.out(0, 'found BitDust processes ... ') try: url = webcontrol._PAGE_ROOT+'?action=exit' run_url_command(url).addCallback(wait_then_kill) #reactor.addSystemEventTrigger('before', 'shutdown', do_uninstall) reactor.run() return 0 except: lg.exc() ret = kill() if ret == 0: do_uninstall() return ret
def main(executable_path=None, start_reactor=True): """ THE ENTRY POINT """ global AppDataDir pars = parser() (opts, args) = pars.parse_args() if opts.coverage: import coverage # @UnresolvedImport cov = coverage.Coverage(config_file=opts.coverage_config) cov.start() overDict = override_options(opts, args) cmd = '' if len(args) > 0: cmd = args[0].lower() try: from system import deploy except: dirpath = os.path.dirname(os.path.abspath(sys.argv[0])) sys.path.insert(0, os.path.abspath(os.path.join(dirpath, '..'))) from distutils.sysconfig import get_python_lib sys.path.append(os.path.join(get_python_lib(), 'bitdust')) try: from system import deploy except: print_text('ERROR! can not import working code. Python Path:') print_text('\n'.join(sys.path)) return 1 #---install--- if cmd in [ 'deploy', 'install', 'venv', 'virtualenv', ]: from system import deploy return deploy.run(args) if opts.appdir: appdata = opts.appdir AppDataDir = appdata else: curdir = os.getcwd() appdatafile = os.path.join(curdir, 'appdata') defaultappdata = deploy.default_base_dir_portable() appdata = defaultappdata if os.path.isfile(appdatafile): try: appdata = os.path.abspath( open(appdatafile, 'rb').read().strip()) except: appdata = defaultappdata if not os.path.isdir(appdata): appdata = defaultappdata AppDataDir = appdata #---BitDust Home deploy.init_base_dir(base_dir=AppDataDir) from logs import lg #---init IO module from system import bpio bpio.init() appList = bpio.find_main_process( pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if bpio.Android(): lg.close_intercepted_log_file() lg.open_intercepted_log_file( '/storage/emulated/0/Android/data/org.bitdust_io.bitdust1/files/Documents/.bitdust/logs/android.log' ) # sys.excepthook = lg.exception_hook #---init logging from twisted.internet.defer import setDebugging if _Debug: if bpio.isFrozen(): setDebugging(False) else: setDebugging(True) else: setDebugging(False) from twisted.logger import globalLogPublisher, LogLevel tw_log_observer = TwistedUnhandledErrorsObserver(level=LogLevel.critical) globalLogPublisher.addObserver(tw_log_observer) #---life begins! # ask logger to count time for each log line from that moment, not absolute time lg.life_begins() # try to read debug level value at the early stage - no problem if fail here try: if cmd == '' or cmd == 'start' or cmd == 'go' or cmd == 'show' or cmd == 'open': lg.set_debug_level( int( bpio.ReadTextFile( os.path.abspath( os.path.join(appdata, 'config', 'logs', 'debug-level'))))) except: pass if opts.no_logs: lg.disable_logs() if opts.debug or str(opts.debug) == '0': lg.set_debug_level(int(opts.debug)) #---logpath--- logpath = None if opts.output: logpath = opts.output else: try: os.makedirs(os.path.join(appdata, 'logs'), exist_ok=True) except: pass logpath = os.path.join(appdata, 'logs', 'stdout.log') need_redirecting = False if bpio.Windows() and not bpio.isConsoled(): need_redirecting = True if logpath: if not appList: if cmd not in [ 'detach', 'daemon', 'stop', 'kill', 'shutdown', 'restart', 'reboot', 'reconnect', 'show', 'open', ]: lg.open_log_file(logpath) if bpio.Windows() and bpio.isFrozen(): need_redirecting = True if bpio.Android(): need_redirecting = True if opts.quite and not opts.verbose: lg.disable_output() else: if need_redirecting: lg.stdout_start_redirecting() lg.stderr_start_redirecting() #---start--- if cmd == '' or cmd == 'start' or cmd == 'go': if appList: print_text('BitDust already started, found another process: %s\n' % str(appList), nl='') bpio.shutdown() return 0 UI = '' try: ret = run(UI, opts, args, overDict, executable_path, start_reactor) except: lg.exc() ret = 1 bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return ret #---daemon--- elif cmd == 'detach' or cmd == 'daemon': appList = bpio.find_main_process( pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if len(appList) > 0: print_text('main BitDust process already started: %s\n' % str(appList), nl='') bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return 0 from lib import misc print_text('new BitDust process will be started in daemon mode\n', nl='') result = misc.DoRestart( detach=True, # std_out=os.path.join(appdata, 'logs', 'stdout.log'), # std_err=os.path.join(appdata, 'logs', 'stderr.log'), ) if result is not None: try: result = int(result) except: try: result = result.pid except: pass bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return 0 #---restart--- elif cmd == 'restart' or cmd == 'reboot': appList = bpio.find_main_process( pid_file_path=os.path.join(appdata, 'metadata', 'processid')) ui = False if len(appList) > 0: print_text('found main BitDust process: %r ... ' % appList, nl='') def done(x): print_text('finished successfully\n', nl='') from twisted.internet import reactor # @UnresolvedImport if reactor.running and not reactor._stopped: # @UndefinedVariable reactor.stop() # @UndefinedVariable def failed(x): if isinstance(x, Failure): print_text('finished with: %s\n' % x.getErrorMessage(), nl='') else: print_text('finished successfully\n', nl='') ok = str(x).count('Connection was closed cleanly') > 0 from twisted.internet import reactor # @UnresolvedImport if ok and reactor.running and not reactor._stopped: # @UndefinedVariable # print_text('DONE\n', '') reactor.stop() # @UndefinedVariable return print_text('forcing previous process shutdown\n', nl='') try: kill() except: lg.exc() from lib import misc reactor.addSystemEventTrigger( # @UndefinedVariable 'after', 'shutdown', misc.DoRestart, param='show' if ui else '', detach=True, # std_out=os.path.join(appdata, 'logs', 'stdout.log'), # std_err=os.path.join(appdata, 'logs', 'stderr.log'), ) reactor.stop() # @UndefinedVariable try: from twisted.internet import reactor # @UnresolvedImport # from interface.command_line import run_url_command # d = run_url_command('?action=restart', False) # from interface import cmd_line # d = cmd_line.call_xmlrpc_method('restart', ui) from interface import cmd_line_json d = cmd_line_json.call_websocket_method('process_restart', websocket_timeout=5) d.addCallback(done) d.addErrback(failed) reactor.run() # @UndefinedVariable bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return 0 except: lg.exc() bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return 1 else: ui = '' if cmd == 'restart': ui = 'show' try: ret = run(ui, opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return ret #---show--- elif cmd == 'show' or cmd == 'open': if not bpio.isGUIpossible(): print_text('BitDust GUI is turned OFF\n', nl='') bpio.shutdown() return 0 if bpio.Linux() and not bpio.X11_is_running(): print_text('this operating system not supporting X11 interface\n', nl='') bpio.shutdown() return 0 appList = bpio.find_main_process( pid_file_path=os.path.join(appdata, 'metadata', 'processid')) if len(appList) == 0: try: ret = run('show', opts, args, overDict, executable_path) except: lg.exc() ret = 1 bpio.shutdown() return ret # print_text('found main BitDust process: %s, start the GUI\n' % str(appList)) # ret = show() bpio.shutdown() return ret #---stop--- elif cmd == 'stop' or cmd == 'kill' or cmd == 'shutdown': if cmd == 'kill': ret = kill() bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return ret appList = bpio.find_main_process(pid_file_path=os.path.join( appdata, 'metadata', 'processid'), ) if len(appList) > 0: if cmd == 'kill': print_text( 'found main BitDust process: %s, about to kill running process ... ' % appList, nl='') ret = kill() bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return ret try: from twisted.internet import reactor # @UnresolvedImport from twisted.python.failure import Failure def _stopped(x): if _Debug: if isinstance(x, Failure): print_text('finished with: %s\n' % x.getErrorMessage(), nl='') else: print_text('finished with: %s\n' % x, nl='') else: print_text('finished successfully\n', nl='') reactor.stop() # @UndefinedVariable bpio.shutdown() print_text('found main BitDust process: %s ... ' % appList, nl='') from interface import cmd_line_json cmd_line_json.call_websocket_method( 'process_stop', websocket_timeout=2).addBoth(_stopped) reactor.run() # @UndefinedVariable if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return 0 except: lg.exc() ret = kill() bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return ret else: appListAllChilds = bpio.find_main_process( check_processid_file=False, extra_lookups=[], ) if len(appListAllChilds) > 0: print_text( 'BitDust child processes found: %s, performing "kill process" action ...\n' % appListAllChilds, nl='') ret = kill() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return ret print_text('BitDust is not running at the moment\n', nl='') bpio.shutdown() if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return 0 #---command_line--- from interface import cmd_line_json as cmdln ret = cmdln.run(opts, args, pars, overDict, executable_path) if ret == 2: print_text(usage_text()) bpio.shutdown() #---coverage report--- if opts.coverage: cov.stop() cov.save() if opts.coverage_report: cov.report(file=open(opts.coverage_report, 'w')) return ret