Changeset 22a0f39 for launchers


Ignore:
Timestamp:
Sep 26, 2018 8:42:58 PM (18 months ago)
Author:
meeh <meeh@…>
Branches:
master
Children:
69f380f
Parents:
d27000e
Message:

Mac OS X Launcher:

  • Enabled Apple's "Hardened Runtime", however unsecure memory had to be allowed to spawn java etc.
  • Updated docs about Event Manager code
  • Make the launcher handle cases where extract is incomplete or invalid
  • Bugfixes as always
Location:
launchers/macosx
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • launchers/macosx/I2PLauncher/SwiftMainDelegate.swift

    rd27000e r22a0f39  
    6060    let results:ExecutionResult = sub.execute(captureOutput: true)!
    6161    if (results.didCaptureOutput) {
    62       let i2pVersion = results.outputLines.first?.replace(target: "I2P Core version: ", withString: "")
    63       NSLog("I2P version detected: %@",i2pVersion ?? "Unknown")
    64       RouterProcessStatus.routerVersion = i2pVersion
    65       RouterManager.shared().eventManager.trigger(eventName: "router_version", information: i2pVersion)
     62      if (results.status == 0) {
     63        let i2pVersion = results.outputLines.first?.replace(target: "I2P Core version: ", withString: "")
     64        NSLog("I2P version detected: %@",i2pVersion ?? "Unknown")
     65        RouterProcessStatus.routerVersion = i2pVersion
     66        RouterManager.shared().eventManager.trigger(eventName: "router_version", information: i2pVersion)
     67        RouterManager.shared().eventManager.trigger(eventName: "router_can_start", information: i2pVersion)
     68      } else {
     69        NSLog("Non zero exit code from subprocess while trying to detect version number!")
     70        for line in results.errorsLines {
     71          NSLog(line)
     72        }
     73      }
    6674    } else {
    6775      print("Warning: Version Detection did NOT captured output")
  • launchers/macosx/I2PLauncher/routermgmt/DetectJava.swift

    rd27000e r22a0f39  
    3333      self.javaHome = self.javaHome.replace(target: "\n", withString: "").replace(target: "Internet Plug-Ins", withString: "Internet\\ Plug-Ins")
    3434      print("DetectJava.javaHome did change to "+self.javaHome)
     35      RouterManager.shared().eventManager.trigger(eventName: "java_found", information: self.javaHome)
    3536    }
    3637  };
  • launchers/macosx/I2PLauncher/routermgmt/RouterManager.swift

    rd27000e r22a0f39  
    88
    99import Foundation
     10
     11
     12enum ErrorsInRouterMgmr: Swift.Error {
     13  case NoJavaFound
     14  case InvalidVersion
     15  case NotFound
     16}
    1017
    1118class RouterManager : NSObject {
     
    1926  var logViewStorage: NSTextStorage?
    2027 
     28  private static func handleRouterException(information:Any?) {
     29    NSLog("event! - handle router exception")
     30    NSLog(information as! String)
     31  }
    2132  private static func handleRouterStart(information:Any?) {
    2233    NSLog("event! - handle router start")
     
    3243  }
    3344  private static func handleRouterPid(information:Any?) {
    34     Swift.print("event! - handle router pid: %s", information ?? "")
     45    Swift.print("event! - handle router pid: ", information ?? "")
    3546  }
    3647  private static func handleRouterVersion(information:Any?) {
    37     Swift.print("event! - handle router version: %s", information ?? "")
    38     let currentVersion : String = information as! String
    39     if (packedVersion.compare(currentVersion, options: .numeric) == .orderedDescending) {
    40       Swift.print("event! - router version: Packed version is newer, gonna re-deploy")
    41       RouterManager.shared().eventManager.trigger(eventName: "router_must_upgrade", information: "got new version")
    42     } else {
    43       Swift.print("event! - router version: No update needed")
    44       RouterManager.shared().eventManager.trigger(eventName: "router_can_start", information: "all ok")
     48    do {
     49      Swift.print("event! - handle router version: ", information ?? "")
     50      guard let currentVersion : String = information as? String else {
     51        throw ErrorsInRouterMgmr.InvalidVersion
     52      }
     53      if (currentVersion == "Unknown") {
     54        throw ErrorsInRouterMgmr.InvalidVersion
     55      }
     56      if (packedVersion.compare(currentVersion, options: .numeric) == .orderedDescending) {
     57        Swift.print("event! - router version: Packed version is newer, gonna re-deploy")
     58        RouterManager.shared().eventManager.trigger(eventName: "router_must_upgrade", information: "got new version")
     59      } else {
     60        Swift.print("event! - router version: No update needed")
     61        RouterManager.shared().eventManager.trigger(eventName: "router_can_start", information: "all ok")
     62      }
     63    } catch ErrorsInRouterMgmr.InvalidVersion {
     64      // This is most likely due to an earlier extract got killed halfway or something
     65      // Trigger an update
     66      RouterManager.shared().eventManager.trigger(eventName: "router_must_upgrade", information: "invalid version found")
     67    } catch {
     68      // WTF
     69      NSLog("Fatal error in RouterManager");
     70      print(error)
    4571    }
    4672  }
     
    5884    routerManager.eventManager.listenTo(eventName: "router_pid", action: handleRouterPid)
    5985    routerManager.eventManager.listenTo(eventName: "router_version", action: handleRouterVersion)
     86    routerManager.eventManager.listenTo(eventName: "router_exception", action: handleRouterException)
    6087    return routerManager
    6188  }()
  • launchers/macosx/README.md

    rd27000e r22a0f39  
    11# The Mac OS X Launcher
     2
     3## The Event Manager
     4
     5This is some Swift code which makes the application use events to signal the different compoents of the application. This seems to be the cleanest way since we're doing java subprocesses and so on. This can also be named a publish-subscribe system as well. If you're familiar with Javascript it would be a handy skill.
     6
     7### Event Overview
     8
     9| Event name | Details sent as arguments | Description |
     10| ------------- | ------------- | ------------- |
     11| router_start | nothing | This event get triggered when the router starts |
     12| router_exception | exception message | This will be triggered in case something within the functions that start the java (router) subprocess throws an exception |
     13| java_found | the location | This will be triggered once the DetectJava swift class has found java |
     14| router_must_upgrade | nothing | This will be triggered if no I2P is found, or if it's failing to get the version from the jar file |
     15| extract_completed | nothing | This is triggered when the deployment process is done extracting I2P to it's directory |
     16| router_can_start | nothing | This event will be triggered when I2P is found and a version number has been found, router won't start before this event |
     17| router_stop | error if any | Triggered when the router subprocess exits |
     18| router_pid | the pid number as string | Triggered when we know the pid of the router subprocess |
     19| router_version | the version string | Triggered when we have successfully extracted current I2P version |
     20| extract_errored | the error message | Triggered if the process didn't exit correctly |
    221
    322## Misc
  • launchers/macosx/RouterTask.mm

    rd27000e r22a0f39  
    8686    auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
    8787    self.isRouterRunning = NO;
    88     [swiftRouterStatus setRouterStatus: false];
    89     [swiftRouterStatus setRouterRanByUs: false];
    90     [swiftRouterStatus triggerEventWithEn:@"router_stop" details:@"error shutdown"];
     88    [swiftRouterStatus triggerEventWithEn:@"router_exception" details:[e reason]];
    9189    [[SBridge sharedInstance] setCurrentRouterInstance:nil];
    9290    sendUserNotification(@"An error occured, can't start the I2P Router", [e reason]);
  • launchers/macosx/SBridge.mm

    rd27000e r22a0f39  
    3737    [[SBridge sharedInstance] setCurrentRouterInstance:instance];
    3838    [instance execute];
     39    sendUserNotification(APP_IDSTR, @"The I2P router is starting up.");
     40    auto pid = [instance getPID];
     41    NSLog(@"Got pid: %d", pid);
    3942    if (routerStatus != nil) {
    4043      [routerStatus setRouterStatus: true];
    4144      [routerStatus setRouterRanByUs: true];
    4245      [routerStatus triggerEventWithEn:@"router_start" details:@"normal start"];
     46      [routerStatus triggerEventWithEn:@"router_pid" details:[NSString stringWithFormat:@"%d", pid]];
    4347    }
    44     sendUserNotification(APP_IDSTR, @"The I2P router is starting up.");
    45     auto pid = [instance getPID];
    46     NSLog(@"Got pid: %d", pid);
    47    
    48     if (routerStatus != nil) [routerStatus triggerEventWithEn:@"router_pid" details:[NSString stringWithFormat:@"%d", pid]];
    4948   
    5049    return std::async(std::launch::async, [&pid]{
     
    6059   
    6160    if (routerStatus != nil) {
    62       [routerStatus setRouterStatus: false];
    63       [routerStatus setRouterRanByUs: false];
    6461      [routerStatus triggerEventWithEn:@"router_exception" details:errStr];
    6562    }
  • launchers/macosx/main.mm

    rd27000e r22a0f39  
    108108
    109109      NSLog(@"Trying cmd: %@", [NSString stringWithUTF8String:execStr.c_str()]);
    110       try {
    111         sendUserNotification(APP_IDSTR, @"Please hold on while we extract I2P. You'll get a new message once done!");
    112         int extractStatus = Popen(execStr.c_str(), environment{{
    113           {"ZIPPATH", zippath.c_str()},
    114           {"I2PBASE", basePath.c_str()}
    115         }}).wait();
    116         NSLog(@"Extraction exit code %@",[NSString stringWithUTF8String:(std::to_string(extractStatus)).c_str()]);
    117         if (extractStatus == 0)
    118         {
    119           NSLog(@"Extraction complete!");
    120         }
    121      
    122       } catch (subprocess::OSError &err) {
    123           auto errMsg = [NSString stringWithUTF8String:err.what()];
    124           //success = NO;
    125           NSLog(@"Exception: %@", errMsg);
    126           sendUserNotification(APP_IDSTR, [NSString stringWithFormat:@"Error: %@", errMsg]);
     110      sendUserNotification(APP_IDSTR, @"Please hold on while we extract I2P. You'll get a new message once done!");
     111      int extractStatus = Popen(execStr.c_str(), environment{{
     112        {"ZIPPATH", zippath.c_str()},
     113        {"I2PBASE", basePath.c_str()}
     114      }}).wait();
     115      NSLog(@"Extraction exit code %@",[NSString stringWithUTF8String:(std::to_string(extractStatus)).c_str()]);
     116      if (extractStatus == 0) {
     117        NSLog(@"Extraction process done");
     118      } else {
     119        NSLog(@"Something went wrong");
    127120      }
    128121
     
    138131      auto errMsg = [NSString stringWithUTF8String:err.what()];
    139132      NSLog(@"Exception: %@", errMsg);
     133      sendUserNotification(APP_IDSTR, [NSString stringWithFormat:@"Error: %@", errMsg]);
    140134    }
    141135  });
     
    225219  // This will trigger the router start after an upgrade.
    226220  [routerStatus listenForEventWithEventName:@"router_must_upgrade" callbackActionFn:^(NSString* information) {
    227     NSLog(@"Got signal, router must be upgraded");
     221    NSLog(@"Got signal, router must be deployed from base.zip");
    228222    [self extractI2PBaseDir:^(BOOL success, NSError *error) {
    229       sendUserNotification(@"I2P is done extracting", @"I2P is now installed and ready to run!");
    230       NSLog(@"Done extracting I2P");
    231       [routerStatus triggerEventWithEn:@"router_can_start" details:@"upgrade complete"];
     223      if (success && error != nil) {
     224        sendUserNotification(@"I2P is done extracting", @"I2P is now installed and ready to run!");
     225        NSLog(@"Done extracting I2P");
     226        [routerStatus triggerEventWithEn:@"extract_completed" details:@"upgrade complete"];
     227      } else {
     228        NSLog(@"Error while extracting I2P");
     229        [routerStatus triggerEventWithEn:@"extract_errored" details:[NSString stringWithFormat:@"%@", error]];
     230      }
    232231    }];
    233232  }];
     
    235234  // Initialize the Swift environment (the UI components)
    236235  [self.swiftRuntime applicationDidFinishLaunching];
    237 
    238   struct stat sb;
    239   if ( !(stat(i2pBaseDir.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) )
     236 
     237  NSString *nsI2PBaseStr = [NSString stringWithUTF8String:i2pBaseDir.c_str()];
     238
     239 
     240  //struct stat sb;
     241  //if ( !(stat(i2pBaseDir.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) )
     242  BOOL shouldBeTrueOnReturnDir = YES;
     243  if (! [NSFileManager.defaultManager fileExistsAtPath: nsI2PBaseStr isDirectory: &shouldBeTrueOnReturnDir])
    240244  {
    241245    // I2P is not extracted.
    242     if (self.enableVerboseLogging) NSLog(@"I2P Directory don't exists!");
    243     [routerStatus triggerEventWithEn:@"router_must_upgrade" details:@"deploy needed"];
     246    if (shouldBeTrueOnReturnDir) {
     247      if (self.enableVerboseLogging) NSLog(@"I2P Directory don't exists!");
     248      [routerStatus triggerEventWithEn:@"router_must_upgrade" details:@"deploy needed"];
     249    } else {
     250      // TODO: handle if i2p path exists but it's not a dir.
     251    }
    244252  } else {
    245253    // I2P was already found extracted
    246     NSLog(@"Time to detect I2P version in install directory");
    247     [self.swiftRuntime findInstalledI2PVersion];
     254    NSString *nsI2pJar = [NSString stringWithFormat:@"%@/lib/i2p.jar", nsI2PBaseStr];
     255   
     256    // But does I2PBASE/lib/i2p.jar exists?
     257    if ([NSFileManager.defaultManager fileExistsAtPath:nsI2pJar]) {
     258      NSLog(@"Time to detect I2P version in install directory");
     259      [self.swiftRuntime findInstalledI2PVersion];
     260    } else {
     261      // The directory exists, but not i2p.jar - most likely we're in mid-extraction state.
     262      [routerStatus listenForEventWithEventName:@"extract_completed" callbackActionFn:^(NSString* information) {
     263        NSLog(@"Time to detect I2P version in install directory");
     264        [self.swiftRuntime findInstalledI2PVersion];
     265      }];
     266    }
    248267  }
    249268 
  • launchers/macosx/osx_create_dmg.sh

    rd27000e r22a0f39  
    11#!/bin/bash
     2
     3. .sign-secrets
    24
    35APP_NAME="I2PLauncher"
     
    99101hdiutil convert "${DMG_TMP}" -format UDZO -imagekey zlib-level=9 -o "${DMG_FINAL}"
    100102
     103codesign --force --sign "${APPLE_CODE_SIGNER_ID}" "${DMG_FINAL}"
     104
    101105# clean up
    102106rm -rf "${DMG_TMP}"
Note: See TracChangeset for help on using the changeset viewer.