- Notifications
You must be signed in to change notification settings - Fork5
chore: use slim binary over dylib#210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -10,3 +10,5 @@ type_name: | ||
| identifier_name: | ||
| allowed_symbols:"_" | ||
| min_length:1 | ||
| line_length: | ||
| ignores_urls:true | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -7,26 +7,56 @@ actor Manager { | ||
| letcfg:ManagerConfig | ||
| lettelemetryEnricher:TelemetryEnricher | ||
| lettunnelDaemon:TunnelDaemon | ||
| letspeaker:Speaker<Vpn_ManagerMessage,Vpn_TunnelMessage> | ||
| varreadLoop:Task<Void,anyError>! | ||
| #if arch(arm64) | ||
| privatestaticletbinaryName="coder-darwin-arm64" | ||
| #else | ||
| privatestaticletbinaryName="coder-darwin-amd64" | ||
| #endif | ||
| // /var/root/Library/Application Support/com.coder.Coder-Desktop/coder-darwin-{arm64,amd64} | ||
| privateletdest=try?FileManager.default | ||
| .url(for:.applicationSupportDirectory, in:.userDomainMask, appropriateFor:nil, create:true) | ||
| .appendingPathComponent(Bundle.main.bundleIdentifier??"com.coder.Coder-Desktop", isDirectory:true) | ||
| .appendingPathComponent(binaryName) | ||
| privateletlogger=Logger(subsystem:Bundle.main.bundleIdentifier!, category:"manager") | ||
| // swiftlint:disable:next function_body_length | ||
| init(cfg:ManagerConfig)asyncthrows(ManagerError){ | ||
| self.cfg= cfg | ||
| telemetryEnricher=TelemetryEnricher() | ||
| guardlet destelse{ | ||
| // This should never happen | ||
| throw.fileError("Failed to create path for binary destination"+ | ||
| "(/var/root/Library/Application Support/com.coder.Coder-Desktop)") | ||
| } | ||
| do{ | ||
| tryFileManager.default.ensureDirectories(for: dest) | ||
| }catch{ | ||
| throw.fileError( | ||
| "Failed to create directories for binary destination (\(dest)):\(error.localizedDescription)" | ||
| ) | ||
| } | ||
| letclient=Client(url: cfg.serverUrl) | ||
| letbuildInfo:BuildInfoResponse | ||
| do{ | ||
| buildInfo=tryawait client.buildInfo() | ||
| }catch{ | ||
| throw.serverInfo(error.description) | ||
| } | ||
| guardlet serverSemver= buildInfo.semverelse{ | ||
| throw.serverInfo("invalid version:\(buildInfo.version)") | ||
| } | ||
| guardValidator.minimumCoderVersion | ||
| .compare(serverSemver, options:.numeric)!=.orderedDescending | ||
| else{ | ||
| throw.belowMinimumCoderVersion(actualVersion: serverSemver) | ||
| } | ||
| letbinaryPath= cfg.serverUrl.appending(path:"bin").appending(path:Manager.binaryName) | ||
| do{ | ||
| letsessionConfig=URLSessionConfiguration.default | ||
| // The tunnel might be asked to start before the network interfaces have woken up from sleep | ||
| @@ -35,7 +65,7 @@ actor Manager { | ||
| sessionConfig.timeoutIntervalForRequest=60 | ||
| sessionConfig.timeoutIntervalForResource=300 | ||
| tryawaitdownload( | ||
| src:binaryPath, | ||
| dest: dest, | ||
| urlSession:URLSession(configuration: sessionConfig) | ||
| ){ progressin | ||
| @@ -45,48 +75,46 @@ actor Manager { | ||
| throw.download(error) | ||
| } | ||
| pushProgress(stage:.validating) | ||
| do{ | ||
| tryValidator.validate(path: dest) | ||
| }catch{ | ||
| // Cleanup unvalid binary | ||
| try?FileManager.default.removeItem(at: dest) | ||
| throw.validation(error) | ||
| } | ||
| // Without this, the TUN fd isn't recognised as a socket in the | ||
| // spawned process, and the tunnel fails to start. | ||
| do{ | ||
| tryunsetCloseOnExec(fd: cfg.tunFd) | ||
| }catch{ | ||
| throw.cloexec(error) | ||
| } | ||
| do{ | ||
| try tunnelDaemon=awaitTunnelDaemon(binaryPath: dest){ errin | ||
| Task{try?awaitNEXPCServerDelegate.cancelProvider(error: | ||
| makeNSError(suffix:"TunnelDaemon", desc:"Tunnel daemon:\(err.description)") | ||
| )} | ||
| } | ||
| }catch{ | ||
| throw.tunnelSetup(error) | ||
| } | ||
| speaker=awaitSpeaker<Vpn_ManagerMessage,Vpn_TunnelMessage>( | ||
| writeFD:tunnelDaemon.writeHandle, | ||
| readFD:tunnelDaemon.readHandle | ||
| ) | ||
| do{ | ||
| tryawait speaker.handshake() | ||
| }catch{ | ||
| throw.handshake(error) | ||
| } | ||
| readLoop=Task{tryawaitrun()} | ||
| } | ||
| deinit{ logger.debug("manager deinit")} | ||
| func run()asyncthrows{ | ||
| do{ | ||
| fortryawaitmin speaker{ | ||
| @@ -99,14 +127,14 @@ actor Manager { | ||
| } | ||
| }catch{ | ||
| logger.error("tunnel read loop failed:\(error.localizedDescription, privacy:.public)") | ||
| tryawaittunnelDaemon.close() | ||
| tryawaitNEXPCServerDelegate.cancelProvider(error: | ||
| makeNSError(suffix:"Manager", desc:"Tunnel read loop failed:\(error.localizedDescription)") | ||
| ) | ||
| return | ||
| } | ||
| logger.info("tunnel read loop exited") | ||
| tryawaittunnelDaemon.close() | ||
| tryawaitNEXPCServerDelegate.cancelProvider(error:nil) | ||
| } | ||
| @@ -204,6 +232,12 @@ actor Manager { | ||
| if !stopResp.success{ | ||
| throw.errorResponse(msg: stopResp.errorMessage) | ||
| } | ||
| do{ | ||
| tryawait tunnelDaemon.close() | ||
| }catch{ | ||
| throw.tunnelFail(error) | ||
| } | ||
| readLoop.cancel() | ||
| } | ||
| // Retrieves the current state of all peers, | ||
| @@ -239,28 +273,32 @@ struct ManagerConfig { | ||
| enumManagerError:Error{ | ||
| case download(DownloadError) | ||
| case fileError(String) | ||
| case tunnelSetup(TunnelDaemonError) | ||
| case handshake(HandshakeError) | ||
| case validation(ValidationError) | ||
| case incorrectResponse(Vpn_TunnelMessage) | ||
| case cloexec(POSIXError) | ||
| case failedRPC(anyError) | ||
| case serverInfo(String) | ||
| case errorResponse(msg:String) | ||
| case tunnelFail(anyError) | ||
| case belowMinimumCoderVersion(actualVersion:String) | ||
| vardescription:String{ | ||
| switchself{ | ||
| caselet.download(err): | ||
| "Download error:\(err.localizedDescription)" | ||
| caselet.fileError(msg): | ||
| msg | ||
| caselet.tunnelSetup(err): | ||
| "Tunnel setup error:\(err.localizedDescription)" | ||
| caselet.handshake(err): | ||
| "Handshake error:\(err.localizedDescription)" | ||
| caselet.validation(err): | ||
| "Validation error:\(err.localizedDescription)" | ||
| caselet.cloexec(err): | ||
| "Failed to mark TUN fd as non-cloexec:\(err.localizedDescription)" | ||
| case.incorrectResponse: | ||
| "Received unexpected response over tunnel" | ||
| caselet.failedRPC(err): | ||
| @@ -269,14 +307,13 @@ enum ManagerError: Error { | ||
| msg | ||
| caselet.errorResponse(msg): | ||
| msg | ||
| caselet.tunnelFail(err): | ||
| "Failed to communicate with daemon over tunnel:\(err.localizedDescription)" | ||
| caselet.belowMinimumCoderVersion(actualVersion): | ||
| """ | ||
| The Coder deployment must be version\(Validator.minimumCoderVersion) | ||
| or higher to use Coder Desktop. Current version:\(actualVersion) | ||
ethanndickson marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| """ | ||
| } | ||
| } | ||
| @@ -297,9 +334,16 @@ func writeVpnLog(_ log: Vpn_Log) { | ||
| case.UNRECOGNIZED:.info | ||
| } | ||
| letlogger=Logger( | ||
| subsystem:"\(Bundle.main.bundleIdentifier!).daemon", | ||
| category: log.loggerNames.joined(separator:".") | ||
| ) | ||
| letfields= log.fields.map{"\($0.name):\($0.value)"}.joined(separator:",") | ||
| logger.log(level: level,"\(log.message, privacy:.public)\(fields.isEmpty?"":":\(fields)", privacy:.public)") | ||
| } | ||
| extensionFileManager{ | ||
| func ensureDirectories(for url:URL)throws{ | ||
| letdir= url.hasDirectoryPath? url: url.deletingLastPathComponent() | ||
| trycreateDirectory(at: dir, withIntermediateDirectories:true, attributes:nil) | ||
| } | ||
| } | ||
This file was deleted.
Uh oh!
There was an error while loading.Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.