Changeset 3988a86 for launchers


Ignore:
Timestamp:
Oct 11, 2018 4:59:59 PM (18 months ago)
Author:
meeh <meeh@…>
Branches:
master
Children:
96d31995
Parents:
b25dec1
Message:

OSX Launcher: major updates to the glue between 'backend' and GUI. Implemented the use of the new LaunchAgent? classes

Location:
launchers/macosx/I2PLauncher/routermgmt
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • launchers/macosx/I2PLauncher/routermgmt/RouterManager.swift

    rb25dec1 r3988a86  
    2020  // MARK: - Properties
    2121 
    22   static let packedVersion : String = "0.9.36"
     22  static let packedVersion : String = "0.9.37"
    2323 
    2424  let eventManager = EventManager()
     25  let routerRunner = RouterRunner()
    2526 
    2627  var logViewStorage: NSTextStorage?
    2728 
    2829  private static func handleRouterException(information:Any?) {
    29     NSLog("event! - handle router exception")
    30     NSLog(information as! String)
     30    Logger.MLog(level:1,"event! - handle router exception")
     31    Logger.MLog(level:1,information as! String)
    3132  }
    3233  private static func handleRouterStart(information:Any?) {
    33     NSLog("event! - handle router start")
     34    Logger.MLog(level:1,"event! - handle router start")
    3435    RouterProcessStatus.routerStartedAt = Date()
    3536    RouterProcessStatus.isRouterChildProcess = true
    3637    RouterProcessStatus.isRouterRunning = true
    3738  }
     39  private static func handleRouterAlreadyStarted(information:Any?) {
     40    Logger.MLog(level:1,"event! - handle router already started");
     41  }
    3842  private static func handleRouterStop(information:Any?) {
    39     NSLog("event! - handle router stop")
     43    Logger.MLog(level:1,"event! - handle router stop")
     44    // TODO: Double check, check if pid stored exists
    4045    RouterProcessStatus.routerStartedAt = nil
    4146    RouterProcessStatus.isRouterChildProcess = false
     
    4348  }
    4449  private static func handleRouterPid(information:Any?) {
    45     Swift.print("event! - handle router pid: ", information ?? "")
     50    Logger.MLog(level:1,"".appendingFormat("event! - handle router pid: ", information as! String!))
     51    if (information != nil) {
     52      let intPid = Int(information as! String)
     53    }
    4654  }
    4755  private static func handleRouterVersion(information:Any?) {
    4856    do {
    49       Swift.print("event! - handle router version: ", information ?? "")
     57      Logger.MLog(level:1, "".appendingFormat("event! - handle router version: ", information as! String!))
    5058      guard let currentVersion : String = information as? String else {
    5159        throw ErrorsInRouterMgmr.InvalidVersion
     
    5563      }
    5664      if (packedVersion.compare(currentVersion, options: .numeric) == .orderedDescending) {
    57         Swift.print("event! - router version: Packed version is newer, gonna re-deploy")
     65        Logger.MLog(level:1,"event! - router version: Packed version is newer, gonna re-deploy")
    5866        RouterManager.shared().eventManager.trigger(eventName: "router_must_upgrade", information: "got new version")
    5967      } else {
    60         Swift.print("event! - router version: No update needed")
    61         RouterManager.shared().eventManager.trigger(eventName: "router_can_start", information: "all ok")
     68        Logger.MLog(level:1,"event! - router version: No update needed")
     69        RouterManager.shared().eventManager.trigger(eventName: "router_can_setup", information: "all ok")
    6270      }
    6371    } catch ErrorsInRouterMgmr.InvalidVersion {
     
    7381 
    7482  private static var sharedRouterManager: RouterManager = {
    75     let inst = DetectJava()
    76     let routerManager = RouterManager(detectJavaInstance: inst)
     83    let routerManager = RouterManager(detectJavaInstance: DetectJava.shared())
    7784   
    7885    // Configuration
     
    8592    routerManager.eventManager.listenTo(eventName: "router_version", action: handleRouterVersion)
    8693    routerManager.eventManager.listenTo(eventName: "router_exception", action: handleRouterException)
     94    routerManager.eventManager.listenTo(eventName: "router_already_running", action: handleRouterAlreadyStarted)
     95    routerManager.eventManager.listenTo(eventName: "router_can_start", action: routerManager.routerRunner.StartAgent)
     96    routerManager.eventManager.listenTo(eventName: "router_can_setup", action: routerManager.routerRunner.SetupAgent)
    8797    return routerManager
    8898  }()
     
    109119  // MARK: - Accessors
    110120 
     121  static func logInfo(format: String, messages: String...) {
     122    //SBridge.sharedInstance().logMessageWithFormat(0, format, messages)func k(_ x: Int32, _ params: String...) {
     123    /*withVaList(messages) {
     124      genericLogger(x, $0)
     125    }*/
     126  }
     127 
    111128  class func shared() -> RouterManager {
    112129    return sharedRouterManager
  • launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus+ObjectiveC.swift

    rb25dec1 r3988a86  
    1111extension RouterProcessStatus {
    1212 
    13   static func createNewRouterProcess(i2pPath: String, javaBinPath: String) {
     13  static func createNewRouterProcess(i2pPath: String) {
    1414    let timeWhenStarted = Date()
    1515    RouterProcessStatus.routerStartedAt = timeWhenStarted
    16     SBridge.sharedInstance().startupI2PRouter(i2pPath, javaBinPath: javaBinPath)
     16    SBridge.sharedInstance().startupI2PRouter(i2pPath)
    1717    RouterManager.shared().updateState()
    1818  }
  • launchers/macosx/I2PLauncher/routermgmt/RouterProcessStatus.swift

    rb25dec1 r3988a86  
    3131 
    3232  @objc func getJavaHome() -> String {
    33     return RouterProcessStatus.knownJavaBinPath!
     33    return DetectJava.shared().javaHome
     34  }
     35 
     36  @objc func getJavaViaLibexec() -> Array<String> {
     37    return DetectJava.shared().getJavaViaLibexecBin()
    3438  }
    3539 
     
    4852  static var routerVersion : String? = Optional.none
    4953  static var routerStartedAt : Date? = Optional.none
    50   static var knownJavaBinPath : String? = Optional.none
    5154  static var i2pDirectoryPath : String = NSHomeDirectory() + "/Library/I2P"
    5255 
    53   static var knownRouterSubTaskRef : I2PSubprocess? = Optional.none
    5456 
    5557}
  • launchers/macosx/I2PLauncher/routermgmt/RouterRunner.swift

    rb25dec1 r3988a86  
    99import Foundation
    1010
    11 class RouterRunner: NSObject, I2PSubprocess {
    12  
    13   var subprocessPath: String?
     11class RouterRunner: NSObject {
     12 
     13 
     14  var daemonPath: String?
    1415  var arguments: String?
    15   var timeWhenStarted: Date?
     16 
     17  static var launchAgent: LaunchAgent?
     18  let routerStatus: RouterProcessStatus = RouterProcessStatus()
    1619 
    1720  var currentRunningProcess: Subprocess?
    1821  var currentProcessResults: ExecutionResult?
    1922 
    20   func findJava() {
    21     self.subprocessPath = RouterProcessStatus.knownJavaBinPath
    22   }
    23  
    24   let defaultStartupFlags:[String] = [
    25     "-Xmx512M",
    26     "-Xms128m",
    27     "-Djava.awt.headless=true",
    28     "-Dwrapper.logfile=/tmp/router.log",
    29     "-Dwrapper.logfile.loglevel=DEBUG",
    30     "-Dwrapper.java.pidfile=/tmp/routerjvm.pid",
    31     "-Dwrapper.console.loglevel=DEBUG"
     23  let domainLabel = "net.i2p.macosx.I2PRouter"
     24 
     25  let plistName = "net.i2p.macosx.I2PRouterAgent.plist"
     26 
     27  let defaultStartupCommand:String = "/usr/libexec/java_home"
     28 
     29  let defaultJavaHomeArgs:[String] = [
     30    "-v",
     31    "1.7+",
     32    "--exec",
     33    "java",
    3234  ]
    3335 
    34   private func subInit(cmdPath: String?, cmdArgs: String?) {
    35     // Use this as common init
    36     self.subprocessPath = cmdPath
    37     self.arguments = cmdArgs
    38     if (self.arguments?.isEmpty)! {
    39       self.arguments = Optional.some(defaultStartupFlags.joined(separator: " "))
    40     };
    41     let newArgs:[String] = ["-c ",
    42                             self.subprocessPath!,
    43       " ",
    44       self.arguments!,
     36  let appSupportPath = FileManager.default.urls(for: FileManager.SearchPathDirectory.applicationSupportDirectory, in: FileManager.SearchPathDomainMask.userDomainMask)
     37 
     38  func SetupAgent() {
     39    let agent = SetupAndReturnAgent()
     40    RouterRunner.launchAgent = agent
     41  }
     42 
     43  typealias Async = (_ success: () -> Void, _ failure: (NSError) -> Void) -> Void
     44 
     45  func retry(numberOfTimes: Int, _ sleepForS: UInt32, task: () -> Async, success: () -> Void, failure: (NSError) -> Void) {
     46    task()(success, { error in
     47      if numberOfTimes > 1 {
     48        sleep(sleepForS)
     49        retry(numberOfTimes: numberOfTimes - 1, sleepForS, task: task, success: success, failure: failure)
     50      } else {
     51        failure(error)
     52      }
     53    })
     54  }
     55 
     56  func SetupAndReturnAgent() -> LaunchAgent {
     57   
     58    let defaultStartupFlags:[String] = [
     59      "-Xmx512M",
     60      "-Xms128m",
     61      "-Djava.awt.headless=true",
     62      "".appendingFormat("-Di2p.base.dir=%@", NSHomeDirectory()+"/Library/I2P"),
     63      "".appendingFormat("-Dwrapper.logfile=%@/Library/I2P/router.log", NSHomeDirectory()),
     64      "-Dwrapper.logfile.loglevel=DEBUG",
     65      "".appendingFormat("-Dwrapper.java.pidfile=%@/i2p/router.pid", appSupportPath.description),
     66      "-Dwrapper.console.loglevel=DEBUG",
     67      "net.i2p.router.Router"
    4568    ]
    46     self.currentRunningProcess = Optional.some(Subprocess.init(executablePath: "/bin/sh", arguments: newArgs))
    47   }
    48  
    49   init(cmdPath: String?, _ cmdArgs: String? = Optional.none) {
    50     super.init()
    51     self.subInit(cmdPath: cmdPath, cmdArgs: cmdArgs)
    52   }
    53  
    54   init(coder: NSCoder) {
    55     super.init()
    56     self.subInit(cmdPath: Optional.none, cmdArgs: Optional.none)
    57   }
    58  
    59   func execute() {
    60     if (self.currentRunningProcess != Optional.none!) {
    61       print("Already executing! Process ", self.toString())
    62     }
    63     self.timeWhenStarted = Date()
    64     RouterProcessStatus.routerStartedAt = self.timeWhenStarted
    65    
    66     self.currentProcessResults = self.currentRunningProcess?.execute(captureOutput: true)
     69   
     70    self.daemonPath = self.defaultStartupCommand
     71    self.arguments = defaultStartupFlags.joined(separator: " ")
     72   
     73    let basePath = NSHomeDirectory()+"/Library/I2P"
     74   
     75    let jars = try! FileManager.default.contentsOfDirectory(atPath: basePath+"/lib")
     76    var classpath:String = "."
     77    for jar in jars {
     78      classpath += ":"+basePath+"/lib/"+jar
     79    }
     80   
     81    var cliArgs:[String] = [
     82      self.daemonPath!,
     83      ]
     84    cliArgs.append(contentsOf: self.defaultJavaHomeArgs)
     85    cliArgs.append(contentsOf: [
     86      "-cp",
     87      classpath,
     88      ])
     89    cliArgs.append(contentsOf: defaultStartupFlags)
     90    let agent = LaunchAgent(label: self.domainLabel,program: cliArgs)
     91    agent.launchOnlyOnce = false
     92    agent.keepAlive = false
     93    agent.workingDirectory = basePath
     94    agent.userName = NSUserName()
     95    agent.standardErrorPath = NSHomeDirectory()+"/Library/Logs/I2P/router.stderr.log"
     96    agent.standardOutPath = NSHomeDirectory()+"/Library/Logs/I2P/router.stdout.log"
     97    agent.environmentVariables = [
     98      "PATH": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin",
     99      "I2PBASE": basePath,
     100    ]
     101    agent.disabled = false
     102    agent.processType = ProcessType.adaptive
     103    RouterRunner.launchAgent = agent
     104   
     105    let userPreferences = UserDefaults.standard
     106    let shouldStartupAtLogin = userPreferences.bool(forKey: "startRouterAtLogin")
     107    agent.runAtLoad = shouldStartupAtLogin
     108    agent.keepAlive = true
     109   
     110    do {
     111     
     112      try LaunchAgentManager.shared.write(agent, called: self.plistName)
     113      sleep(1)
     114      try LaunchAgentManager.shared.load(agent)
     115      sleep(1)
     116     
     117      let agentStatus = LaunchAgentManager.shared.status(agent)
     118      switch agentStatus {
     119      case .running:
     120        break
     121      case .loaded:
     122        break
     123      case .unloaded:
     124        sleep(2)
     125        break
     126      }
     127     
     128     
     129      RouterManager.shared().eventManager.trigger(eventName: "router_can_start", information: agent)
     130    } catch {
     131      RouterManager.shared().eventManager.trigger(eventName: "router_setup_error", information: "\(error)")
     132    }
     133    return agent
     134  }
     135 
     136  func StartAgent(information:Any?) {
     137    let agent = RouterRunner.launchAgent!
     138    LaunchAgentManager.shared.start(agent)
     139    sleep(1)
     140    let agentStatus = agent.status()
     141    switch agentStatus {
     142    case .running(let pid):
     143      RouterManager.shared().eventManager.trigger(eventName: "router_start", information: String(pid))
     144      routerStatus.setRouterStatus(true)
     145      routerStatus.setRouterRanByUs(true)
     146      DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
     147        // Delayed message to ensure UI has been initialized.
     148        RouterManager.shared().eventManager.trigger(eventName: "router_pid", information: String(pid))
     149      }
     150      break
     151     
     152    default: break
     153    }
     154  }
     155 
     156  func StopAgent() {
     157    var agentStatus = LaunchAgentManager.shared.status(RouterRunner.launchAgent!)
     158    switch agentStatus {
     159    case .running:
     160      LaunchAgentManager.shared.stop(RouterRunner.launchAgent!)
     161      break
     162    case .loaded, .unloaded:
     163      try! LaunchAgentManager.shared.load(RouterRunner.launchAgent!)
     164      routerStatus.setRouterStatus(false)
     165      routerStatus.setRouterRanByUs(false)
     166      RouterManager.shared().eventManager.trigger(eventName: "router_stop", information: "ok")
     167      return;
     168      break
     169    default: break
     170    }
     171    sleep(1)
     172    agentStatus = LaunchAgentManager.shared.status(RouterRunner.launchAgent!)
     173    switch agentStatus {
     174    case .loaded, .unloaded:
     175      try! LaunchAgentManager.shared.load(RouterRunner.launchAgent!)
     176      routerStatus.setRouterStatus(false)
     177      routerStatus.setRouterRanByUs(false)
     178      RouterManager.shared().eventManager.trigger(eventName: "router_stop", information: "ok")
     179      break
     180    default: break
     181    }
     182  }
     183 
     184  func SetupLaunchd() {
     185    do {
     186      try LaunchAgentManager.shared.write(RouterRunner.launchAgent!, called: self.plistName)
     187      try LaunchAgentManager.shared.load(RouterRunner.launchAgent!)
     188    } catch {
     189      RouterManager.shared().eventManager.trigger(eventName: "router_exception", information: error)
     190    }
     191  }
     192 
     193  func TeardownLaunchd() {
     194    /*let status = LaunchAgentManager.shared.status(RouterRunner.launchAgent!)
     195    switch status {
     196    case .running:*/
     197      do {
     198        // Unload no matter previous state!
     199        try LaunchAgentManager.shared.unload(RouterRunner.launchAgent!)
     200       
     201        let plistPath = NSHomeDirectory()+"/Library/LaunchAgents/"+self.plistName
     202       
     203        sleep(1)
     204        if FileManager.default.fileExists(atPath: plistPath) {
     205          try FileManager.default.removeItem(atPath: plistPath)
     206        }
     207      } catch LaunchAgentManagerError.urlNotSet(label: self.domainLabel) {
     208        Logger.MLog(level:3, "URL not set in launch agent")
     209      } catch {
     210        Logger.MLog(level:3, "".appendingFormat("Error in launch agent: %s", error as CVarArg))
     211        RouterManager.shared().eventManager.trigger(eventName: "router_exception", information: error)
     212      }
     213   /*   break
     214    default: break
     215    }
     216    */
    67217  }
    68218 
Note: See TracChangeset for help on using the changeset viewer.