From 4a4b6b46f84c28640c711655f4f3c339ccf8fbba Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 19 Feb 2021 12:20:55 +0100 Subject: [pkg] improve osx installer - install into global /Applications - document how to troubleshoot helper - uninstall app is visible on top-level folder - improve detection of running processes for old and new binaries - Closes: #441 - Closes: #445 - Closes: #435 --- branding/templates/qtinstaller/installer.pro | 18 +--------- .../templates/qtinstaller/osx-data/post-install.py | 26 +++++++-------- .../templates/qtinstaller/osx-data/uninstall.py | 39 ++++++++++------------ .../packages/bitmaskvpn/meta/install.js | 37 ++++++++++---------- 4 files changed, 51 insertions(+), 69 deletions(-) (limited to 'branding/templates/qtinstaller') diff --git a/branding/templates/qtinstaller/installer.pro b/branding/templates/qtinstaller/installer.pro index 6aab843..0c05442 100644 --- a/branding/templates/qtinstaller/installer.pro +++ b/branding/templates/qtinstaller/installer.pro @@ -13,27 +13,11 @@ QMAKE_TARGET_BUNDLE_PREFIX = se.leap QMAKE_BUNDLE = $$TARGET QMAKE_EXTRA_COMPILERS += inst -OTHER_FILES += \ -# watch out... it chokes with dashes in the path - packages/riseupvpn/meta/package.xml \ - packages/riseupvpn/meta/install.js \ - packages/riseupvpn/data/README.txt \ +# OTHER_FILES += \ macx { - OTHER_FILES += "packages/riseupvpn/data/riseup-vpn.app" - OTHER_FILES += "packages/riseupvpn/data/bitmask-helper" - OTHER_FILES += "packages/riseupvpn/data/installer.py" - OTHER_FILES += "packages/riseupvpn/data/se.leap.bitmask-helper.plist" - OTHER_FILES += "packages/riseupvpn/data/openvpn.leap" - OTHER_FILES += "packages/riseupvpn/data/helper/bitmask.pf.conf" - OTHER_FILES += "packages/riseupvpn/data/client.up.sh" - OTHER_FILES += "packages/riseupvpn/data/client.down.sh" } linux { - OTHER_FILES += "packages/riseupvpn/data/riseup-vpn" - OTHER_FILES += "packages/riseupvpn/data/bitmask-helper" } win32{ - OTHER_FILES += "packages/riseupvpn/data/riseup-vpn.exe" - OTHER_FILES += "packages/riseupvpn/data/helper.exe" } diff --git a/branding/templates/qtinstaller/osx-data/post-install.py b/branding/templates/qtinstaller/osx-data/post-install.py index 2c15845..83c8370 100755 --- a/branding/templates/qtinstaller/osx-data/post-install.py +++ b/branding/templates/qtinstaller/osx-data/post-install.py @@ -5,15 +5,18 @@ # This means that, for the time being, you can only install ONE of the BitmaskVPN derivatives at the same time. # This might change in the future. +import glob import os import shutil import sys import subprocess +import time HELPER = "bitmask-helper" HELPER_PLIST = "/Library/LaunchDaemons/se.leap.bitmask-helper.plist" _dir = os.path.dirname(os.path.realpath(__file__)) +_appdir = glob.glob('{}/*VPN.app'.format(_dir))[0] def main(): log = open(os.path.join(_dir, 'post-install.log'), 'w') @@ -21,10 +24,9 @@ def main(): _id = os.getuid() if _id != 0: - err = "error: need to run as root. UID: %s\n" % str(_id) - logErr(log, err) - - # failure: sys.exit(1) + err = "ERROR: need to run as root. UID: %s\n" % str(_id) + log.write(err) + sys.exit(1) if isHelperRunning(): log.write("Trying to stop bitmask-helper...\n") @@ -48,22 +50,19 @@ def main(): log.write('post-install script: done\n') sys.exit(0) - -def logErr(log, msg): - log.write(msg) - sys.exit(1) - def isHelperRunning(): ps = _getProcessList() return HELPER in ps def unloadHelper(): out = subprocess.call(["launchctl", "unload", HELPER_PLIST]) + time.sleep(0.5) out2 = subprocess.call(["pkill", "-9", "bitmask-helper"]) # just in case + time.sleep(0.5) return out == 0 def fixHelperOwner(log): - path = os.path.join(_dir, HELPER) + path = os.path.join(_appdir, HELPER) try: os.chown(path, 0, 0) except OSError as exc: @@ -74,8 +73,9 @@ def fixHelperOwner(log): def copyLaunchDaemon(): plist = "se.leap.bitmask-helper.plist" path = os.path.join(_dir, plist) - _p = _dir.replace("/", "\/") - subprocess.call(["sed", "-i.back", "s/PATH/%s/" % _p, path]) + _p = os.path.join(_dir, _appdir) + _p2= _p.replace("/", "\/") + subprocess.call(["sed", "-i.back", "s/PATH/%s/" % _p2, path]) shutil.copy(path, HELPER_PLIST) def launchHelper(): @@ -83,7 +83,7 @@ def launchHelper(): return out == 0 def grantPermissionsOnLogFolder(): - helperDir = os.path.join(_dir, 'helper') + helperDir = os.path.join(_appdir, 'helper') try: os.makedirs(helperDir) except Exception: diff --git a/branding/templates/qtinstaller/osx-data/uninstall.py b/branding/templates/qtinstaller/osx-data/uninstall.py index d47acc5..ef012e4 100755 --- a/branding/templates/qtinstaller/osx-data/uninstall.py +++ b/branding/templates/qtinstaller/osx-data/uninstall.py @@ -6,6 +6,7 @@ import os import shutil import sys import subprocess +import time HELPER = "bitmask-helper" HELPER_PLIST = "/Library/LaunchDaemons/se.leap.bitmask-helper.plist" @@ -21,16 +22,19 @@ def main(stage="uninstall"): log.write("UID: %s\n" % str(_id)) if int(_id) != 0: err = "error: need to run as root. UID: %s\n" % str(_id) - logErr(log, err) - - # failure: sys.exit(1) + log.write(err) + sys.exit(1) log.write('Checking if helper is running\n') if isHelperRunning(): log.write("Trying to stop bitmask-helper...\n") # if this fail, we can check if the HELPER_PLIST is there - ok = unloadHelper() + try: + ok = unloadHelper() + except Exception as exc: + log.write('error: %v' % exc) + time.sleep(0.5) log.write("success: %s \n" % str(ok)) log.write("Removing LaunchDaemon\n") @@ -41,14 +45,14 @@ def main(stage="uninstall"): log.write(stage + ' script: done\n') sys.exit(0) - -def logErr(log, msg): - log.write(msg) - sys.exit(1) - def isHelperRunning(): - ps = _getProcessList() - return HELPER in ps + try: + pid = subprocess.check_output(['pgrep', HELPER]) + if pid.strip() != '': + return True + except subprocess.CalledProcessError: + return False + return False def unloadHelper(): out = subprocess.call(["launchctl", "unload", HELPER_PLIST]) @@ -58,17 +62,8 @@ def unloadHelper(): def removeLaunchDaemon(): return subprocess.call(["rm", "-f", HELPER_PLIST]) -def _getProcessList(): - _out = [] - output = subprocess.Popen(["ps", "-ceA"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - stdout, stderr = output.communicate() - for line in stdout.split('\n'): - cmd = line.split(' ')[-1] - _out.append(cmd.strip()) - return _out - if __name__ == "__main__": stage="uninstall" - if len(sys.argv) > 2 and sys.argv[2] == "pre": - stage="pre-install" + if len(sys.argv) == 2 and sys.argv[1] == "pre": + stage="preinstall" main(stage) diff --git a/branding/templates/qtinstaller/packages/bitmaskvpn/meta/install.js b/branding/templates/qtinstaller/packages/bitmaskvpn/meta/install.js index 407ea39..dada918 100644 --- a/branding/templates/qtinstaller/packages/bitmaskvpn/meta/install.js +++ b/branding/templates/qtinstaller/packages/bitmaskvpn/meta/install.js @@ -58,6 +58,9 @@ function Component() { Component.prototype.createOperations = function () { + if (systemInfo.productType === "osx") { + preInstallOSX(); + } // This will actually install the files component.createOperations(); @@ -70,27 +73,13 @@ Component.prototype.createOperations = function () if (systemInfo.productType === "windows") { postInstallWindows(); } else if (systemInfo.productType === "osx") { - preInstallOSX(); + uninstallOSX(); postInstallOSX(); } else { postInstallLinux(); } } -Component.prototype.installationFinished = function() -{ - console.log("DEBUG: running installationFinished"); - if (installer.isInstaller() && installer.status == QInstaller.Success) { - var argList = ["-a", "@TargetDir@/$APPNAME.app"]; - try { - installer.execute("touch", ["/tmp/install-finished"]); - installer.execute("open", argList); - } catch(e) { - console.log(e); - } - } -} - function postInstallWindows() { // TODO - check if we're on Windows10 or older, and use the needed tap-windows installer accordingly. console.log("Installing OpenVPN tap driver"); @@ -111,12 +100,26 @@ function postInstallWindows() { } function preInstallOSX() { - console.log("Pre-installation for OSX"); + console.log("Pre-installation for OSX: check for running bitmask"); + component.addOperation( + "Execute", "{1}", "pgrep", "bitmask-vpn$$", /* $$$$ is escaped by python template: the old app binary was called bitmask-vpn */ + "errormessage=It seems that an old RiseupVPN client is running. Please exit the app and run this installer again.", + ); + component.addOperation( + "Execute", "{1}", "pgrep", "bitmask$$", /* $$$$ is escaped by python template: we don't want to catch bitmask app */ + "errormessage=It seems RiseupVPN, CalyxVPN or LibraryVPN are running. Please exit the app and run this installer again.", + "UNDOEXECUTE", "{1}", "pgrep", "bitmask$$", /* $$$$ is escaped: we dont want bitmask app */ + "errormessage=It seems RiseupVPN, CalyxVPN or LibraryVPN are running. Please exit the app before trying to run the uninstaller again." + ); +} + +function uninstallOSX() { + console.log("Pre-installation for OSX: uninstall previous helpers"); // TODO use installer filepath?? component.addElevatedOperation( "Execute", "{0}", "@TargetDir@/uninstall.py", "pre", - "errormessage=There was an error during the pre-installation script, things might be broken. Please report this error and attach the pre-install.log file." + "errormessage=There was an error during the pre-installation script, things might be broken. Please report this error and attach /tmp/bitmask-uninstall.log" ); } -- cgit v1.2.3