From d63fe83a91e02cf0651d2cb93ffa47d2a6b58a2f Mon Sep 17 00:00:00 2001 From: itwrx Date: Tue, 27 Jun 2023 11:23:34 -0500 Subject: [PATCH 1/2] threads attempt --- views/routine_list.nim | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/views/routine_list.nim b/views/routine_list.nim index 7771f3d..af18d4b 100644 --- a/views/routine_list.nim +++ b/views/routine_list.nim @@ -4,7 +4,9 @@ EZ-Bkup is released under the General Public License 3.0. See COPYING or for details.]# import owlkettle -import std/osproc +import std/osproc, std/os +#import asynctools +#import threadpool import edit_routine_dialog import "../models/routine", "../shared" @@ -12,9 +14,19 @@ viewable RoutineList: ## Displays a list of routines routineModel: RoutineModel ## Model of all routines runStatus: string + rsyncRun: tuple[output: string, exitCode: int] proc changed(state: bool) +var thread: Thread[RoutineListState] +#var rsyncRun: tuple[output: string, exitCode: int] + +proc rsyncThread(list: RoutineListState, rsyncCommand: string) {.thread.} = + while true: + list.rsyncRun = execCmdEx(rsyncCommand) + list.redrawFromThread() + sleep(1000) + method view(list: RoutineListState): Widget {.locks: "unknown".} = result = gui: ScrolledWindow: @@ -138,7 +150,7 @@ method view(list: RoutineListState): Widget {.locks: "unknown".} = useMarkup = true proc clicked() = list.runStatus = "Running Bkup..." - var rsyncRun: tuple[output: string, exitCode: int] + #var rsyncRun: tuple[output: string, exitCode: int] var rsyncErrors: seq[string] var routineRunCount = 0 for routine in list.routineModel.routineSeq(): @@ -151,18 +163,29 @@ method view(list: RoutineListState): Widget {.locks: "unknown".} = for destination in routine.destinations: list.runStatus = "Bkup " & source & " to " & destination & "..." #try without requiring superuser privs by default. - rsyncRun = execCmdEx("rsync -aq " & source & " " & destination) - if rsyncRun.exitCode != 0: + #rsyncRun = execCmdEx("rsync -aq " & source & " " & destination) + let rsyncRunCmd = "rsync -aq " & source & " " & destination + #let rsyncThreadProcCall = rsyncThread(rsyncRunCmd) + createThread(thread, rsyncThread(list, rsyncRunCmd), list) + #createThread(thread, rsyncThreadProcCall, list) + #rsyncRun = spawn execCmdEx("rsync -aq " & source & " " & destination) + #sync() + #rsyncRun = await asynctools.execProcess("rsync -aq " & source & " " & destination) + if list.rsyncRun.exitCode != 0: #handle permission denied error. - if rsyncRun.exitCode == 23: + if list.rsyncRun.exitCode == 23: let rsyncRunCmd = "SUDO_ASKPASS=" & getAskPassPath() & " sudo -A rsync -aq " & source & " " & destination - rsyncRun = execCmdEx(rsyncRunCmd) - if rsyncRun.exitCode != 0: + #rsyncRun = execCmdEx(rsyncRunCmd) + #rsyncRun = spawn execCmdEx(rsyncRunCmd) + #sync() + createThread(thread, rsyncThread(rsyncRunCmd), list) + #rsyncRun = await asynctools.execProcess(rsyncRunCmd) + if list.rsyncRun.exitCode != 0: rsyncErrors.add("EZ-Bkup's rsync process(es) returned error (" & $rsyncRun.output & ") while attempting to back up " & source & " to " & destination) else: rsyncErrors.add("EZ-Bkup's rsync process(es) returned error (" & $rsyncRun.output & ") while attempting to back up " & source & " to " & destination) #makes the "Bkup Complete" msg below wait on the rsyncRun to finish. - if rsyncRun.exitCode == 1 or rsyncRun.exitCode == 0: + if list.rsyncRun.exitCode == 1 or list.rsyncRun.exitCode == 0: if rsyncErrors.len > 0: list.runStatus = "Error! Please see the log at ~/.ez-bkup/errors.log" for err in rsyncErrors: From 3f075a9a90ae16cf9ae822c8538bc006e055d590 Mon Sep 17 00:00:00 2001 From: itwrx Date: Wed, 28 Jun 2023 15:00:51 -0500 Subject: [PATCH 2/2] move rsync stuff to thread & make logging & askpasspath stuff compat w thread --- shared.nim | 47 ++++------------- views/routine_list.nim | 115 ++++++++++++++++++++--------------------- 2 files changed, 66 insertions(+), 96 deletions(-) diff --git a/shared.nim b/shared.nim index 7276958..e218131 100644 --- a/shared.nim +++ b/shared.nim @@ -37,45 +37,16 @@ proc hasCommas*(filename: string):bool = proc getAskPassPath*(): string = var askPassPath: string - if detectOs(Fedora): - if fileExists("/usr/libexec/openssh/ssh-askpass"): - askPassPath = "/usr/libexec/openssh/ssh-askpass" - else: - writeErrorToLog("No ssh-askpass binary found. Please run 'dnf install openssh-askpass'") - askPassPath = "" - elif detectOs(Ubuntu): - if fileExists("/usr/lib/openssh/gnome-ssh-askpass"): - askPassPath = "/usr/lib/openssh/gnome-ssh-askpass" - else: - writeErrorToLog("No ssh-askpass binary found. Please run 'sudo apt install ssh-askpass-gnome'.") - askPassPath = "" - #save this for a musl build. - #[elif detectOs(Alpine): - if fileExists("/usr/lib/ssh/gtk-ssh-askpass"): - askPassPath = "/usr/lib/ssh/gtk-ssh-askpass" - else: - writeErrorToLog("No ssh-askpass binary found. Please run 'apk add gtk-ssh-askpass'.") - askPassPath = ""]# - elif detectOs(ArchLinux): - if fileExists("/usr/lib/ssh/ssh-askpass"): - askPassPath = "/usr/lib/ssh/ssh-askpass" - else: - writeErrorToLog("No ssh-askpass binary found. Please run 'pacman -S x11-ssh-askpass', or similar.") - askPassPath = "" - elif detectOs(Linux): - if fileExists("/usr/libexec/openssh/ssh-askpass"): - askPassPath = "/usr/libexec/openssh/ssh-askpass" - elif fileExists("/usr/lib/openssh/gnome-ssh-askpass"): - askPassPath = "/usr/lib/openssh/gnome-ssh-askpass" - elif fileExists("/usr/lib/ssh/gtk-ssh-askpass"): - askPassPath = "/usr/lib/ssh/gtk-ssh-askpass" - elif fileExists("/usr/lib/ssh/ssh-askpass"): - askPassPath = "/usr/lib/ssh/ssh-askpass" - else: - writeErrorToLog("No ssh-askpass binary found. Please install an ssh-askpass package for your distro, and let us know if EZ-Bkup still can't detect it's location.") - askPassPath = "" + + if fileExists("/usr/libexec/openssh/ssh-askpass"): + askPassPath = "/usr/libexec/openssh/ssh-askpass" + elif fileExists("/usr/lib/openssh/gnome-ssh-askpass"): + askPassPath = "/usr/lib/openssh/gnome-ssh-askpass" + elif fileExists("/usr/lib/ssh/gtk-ssh-askpass"): + askPassPath = "/usr/lib/ssh/gtk-ssh-askpass" + elif fileExists("/usr/lib/ssh/ssh-askpass"): + askPassPath = "/usr/lib/ssh/ssh-askpass" else: - writeErrorToLog("Your OS does not appear to be supported at this time. If you are getting this error and you are using a x86_64 gnu libc-based linux distribution please report this issue. Please include the path to your ssh-askpass binary, as well.") askPassPath = "" return askPassPath diff --git a/views/routine_list.nim b/views/routine_list.nim index af18d4b..360666a 100644 --- a/views/routine_list.nim +++ b/views/routine_list.nim @@ -4,28 +4,71 @@ EZ-Bkup is released under the General Public License 3.0. See COPYING or for details.]# import owlkettle -import std/osproc, std/os -#import asynctools -#import threadpool +import std/osproc, std/os, std/logging import edit_routine_dialog import "../models/routine", "../shared" viewable RoutineList: - ## Displays a list of routines - routineModel: RoutineModel ## Model of all routines + routineModel: RoutineModel runStatus: string - rsyncRun: tuple[output: string, exitCode: int] proc changed(state: bool) var thread: Thread[RoutineListState] -#var rsyncRun: tuple[output: string, exitCode: int] -proc rsyncThread(list: RoutineListState, rsyncCommand: string) {.thread.} = - while true: - list.rsyncRun = execCmdEx(rsyncCommand) - list.redrawFromThread() - sleep(1000) +proc rsyncThread(list: RoutineListState) {.thread.} = + + let appPath = getHomeDir() & ".ez-bkup" + + if not dirExists(appPath): + createDir(appPath) + + var logger = newFileLogger(appPath & "/errors.log") + + #i'm not sure if using threadvar here is needed, but doing it just in case. :) + var rsyncRunCmd {.threadvar.}: string + var rsyncRun {.threadvar.}: tuple[output: string, exitCode: int] + + var rsyncErrors: seq[string] + var routineRunCount: int + routineRunCount = 0 + for routine in list.routineModel.routineSeq(): + #using this as "selected" for now. + if routine.selByDef == true: + #skip routines that don't have at least one source and one destination. + if routine.sources.len != 0 and routine.destinations.len != 0: + list.runStatus = "Horses, please to be holding..." + routineRuncount += 1 + for source in routine.sources: + for destination in routine.destinations: + #per source/dest compbo msgs still don't seem to be working right. + #maybe it requires a separate thread per combo? deprioritized. + #list.runStatus = "Bkup " & source & " to " & destination & "..." + #try without requiring superuser privs by default. + rsyncRunCmd = "rsync -aq " & source & " " & destination + rsyncRun = execCmdEx(rsyncRunCmd) + if rsyncRun.exitCode != 0: + #handle permission denied error. + if rsyncRun.exitCode == 23: + rsyncRun.exitCode = 0 + if getAskPassPath() == "": + let err = "No ssh-askpass binary found. Please install an ssh-askpass package for your distro, and let us know if EZ-Bkup still can't detect it's location." + rsyncErrors.add(err) + else: + rsyncRunCmd = "SUDO_ASKPASS=" & getAskPassPath() & " sudo -A rsync -aq " & source & " " & destination + rsyncRun = execCmdEx(rsyncRunCmd) + if rsyncRun.exitCode != 0: + rsyncErrors.add("EZ-Bkup's rsync process(es) returned error (" & $rsyncRun.output & ") while attempting to back up " & source & " to " & destination) + if rsyncErrors.len > 0: + list.runStatus = "Error! Please see the log at ~/.ez-bkup/errors.log" + for err in rsyncErrors: + logger.log(lvlError, err) + elif routineRunCount == 0: + list.runStatus = "Meh. No Bkup Routines were run." + else: + list.runStatus = "Bkup Complete!" + + list.redrawFromThread() method view(list: RoutineListState): Widget {.locks: "unknown".} = result = gui: @@ -149,52 +192,8 @@ method view(list: RoutineListState): Widget {.locks: "unknown".} = xAlign = 0 useMarkup = true proc clicked() = - list.runStatus = "Running Bkup..." - #var rsyncRun: tuple[output: string, exitCode: int] - var rsyncErrors: seq[string] - var routineRunCount = 0 - for routine in list.routineModel.routineSeq(): - #using this as "selected" for now. - if routine.selByDef == true: - #skip routines that don't have at least one source and one destination. - if routine.sources.len != 0 and routine.destinations.len != 0: - routineRuncount += 1 - for source in routine.sources: - for destination in routine.destinations: - list.runStatus = "Bkup " & source & " to " & destination & "..." - #try without requiring superuser privs by default. - #rsyncRun = execCmdEx("rsync -aq " & source & " " & destination) - let rsyncRunCmd = "rsync -aq " & source & " " & destination - #let rsyncThreadProcCall = rsyncThread(rsyncRunCmd) - createThread(thread, rsyncThread(list, rsyncRunCmd), list) - #createThread(thread, rsyncThreadProcCall, list) - #rsyncRun = spawn execCmdEx("rsync -aq " & source & " " & destination) - #sync() - #rsyncRun = await asynctools.execProcess("rsync -aq " & source & " " & destination) - if list.rsyncRun.exitCode != 0: - #handle permission denied error. - if list.rsyncRun.exitCode == 23: - let rsyncRunCmd = "SUDO_ASKPASS=" & getAskPassPath() & " sudo -A rsync -aq " & source & " " & destination - #rsyncRun = execCmdEx(rsyncRunCmd) - #rsyncRun = spawn execCmdEx(rsyncRunCmd) - #sync() - createThread(thread, rsyncThread(rsyncRunCmd), list) - #rsyncRun = await asynctools.execProcess(rsyncRunCmd) - if list.rsyncRun.exitCode != 0: - rsyncErrors.add("EZ-Bkup's rsync process(es) returned error (" & $rsyncRun.output & ") while attempting to back up " & source & " to " & destination) - else: - rsyncErrors.add("EZ-Bkup's rsync process(es) returned error (" & $rsyncRun.output & ") while attempting to back up " & source & " to " & destination) - #makes the "Bkup Complete" msg below wait on the rsyncRun to finish. - if list.rsyncRun.exitCode == 1 or list.rsyncRun.exitCode == 0: - if rsyncErrors.len > 0: - list.runStatus = "Error! Please see the log at ~/.ez-bkup/errors.log" - for err in rsyncErrors: - writeErrorToLog(err) - echo err - elif routineRunCount == 0: - list.runStatus = "Meh. No Bkup Routines were run." - else: - list.runStatus = "Bkup Complete!" + #list.runStatus = "Running Bkup..." + createThread(thread, rsyncThread, list) else: Box {.expand: false.}: orient = OrientY