UNPKG

masq

Version:

A simple local dns server extracted from Pow

430 lines (296 loc) 17 kB
<!DOCTYPE html> <html> <head> <title>installer.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <ul id="jump_to"> <li> <a class="large" href="javascript:void(0);">Jump To &hellip;</a> <a class="small" href="javascript:void(0);">+</a> <div id="jump_wrapper"> <div id="jump_page_wrapper"> <div id="jump_page"> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="configuration.html"> configuration.coffee </a> <a class="source" href="daemon.html"> daemon.coffee </a> <a class="source" href="dns_server.html"> dns_server.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="installer.html"> installer.coffee </a> <a class="source" href="logger.html"> logger.coffee </a> <a class="source" href="utils.html"> utils.coffee </a> </div> </div> </li> </ul> <ul class="sections"> <li id="title"> <div class="annotation"> <h1>installer.coffee</h1> </div> </li> <li id="section-1"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>The <code>Installer</code> class, in conjunction with the private <code>InstallerFile</code> class, creates and installs local and system configuration files if they’re missing or out of date. It’s used by the Pow install script to set up the system for local development.</p> </div> <div class="content"><div class='highlight'><pre> async = <span class="hljs-built_in">require</span> <span class="hljs-string">"async"</span> fs = <span class="hljs-built_in">require</span> <span class="hljs-string">"fs"</span> path = <span class="hljs-built_in">require</span> <span class="hljs-string">"path"</span> {mkdirp} = <span class="hljs-built_in">require</span> <span class="hljs-string">"./utils"</span> {chown} = <span class="hljs-built_in">require</span> <span class="hljs-string">"./utils"</span> util = <span class="hljs-built_in">require</span> <span class="hljs-string">"util"</span></pre></div></div> </li> <li id="section-2"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>Import the Eco templates for the <code>/etc/resolver</code> and <code>launchd</code> configuration files.</p> </div> <div class="content"><div class='highlight'><pre>resolverSource = <span class="hljs-built_in">require</span> <span class="hljs-string">"./templates/resolver"</span></pre></div></div> </li> <li id="section-3"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>firewallSource = require “./templates/cx.masq.firewall.plist”</p> </div> <div class="content"><div class='highlight'><pre>daemonSource = <span class="hljs-built_in">require</span> <span class="hljs-string">"./templates/cx.masq.masqd.plist"</span></pre></div></div> </li> <li id="section-4"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p><code>InstallerFile</code> represents a single file candidate for installation: a pathname, a string of the file’s source, and optional flags indicating whether the file needs to be installed as root and what permission bits it should have.</p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InstallerFile</span></span> constructor: <span class="hljs-function"><span class="hljs-params">(@path, source, @root = <span class="hljs-literal">false</span>, @mode = <span class="hljs-number">0</span>o644)</span> -&gt;</span> @source = source.trim()</pre></div></div> </li> <li id="section-5"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Check to see whether the file actually needs to be installed. If the file exists on the filesystem with the specified path and contents, <code>callback</code> is invoked with false. Otherwise, <code>callback</code> is invoked with true.</p> </div> <div class="content"><div class='highlight'><pre> isStale: <span class="hljs-function"><span class="hljs-params">(callback)</span> -&gt;</span> fs.exists @path, <span class="hljs-function"><span class="hljs-params">(exists)</span> =&gt;</span> <span class="hljs-keyword">if</span> exists fs.readFile @path, <span class="hljs-string">"utf8"</span>, <span class="hljs-function"><span class="hljs-params">(err, contents)</span> =&gt;</span> <span class="hljs-keyword">if</span> err callback <span class="hljs-literal">true</span> <span class="hljs-keyword">else</span> callback @source <span class="hljs-keyword">isnt</span> contents.trim() <span class="hljs-keyword">else</span> callback <span class="hljs-literal">true</span></pre></div></div> </li> <li id="section-6"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>Create all the parent directories of the file’s path, if necessary, and then invoke <code>callback</code>.</p> </div> <div class="content"><div class='highlight'><pre> vivifyPath: <span class="hljs-function"><span class="hljs-params">(callback)</span> -&gt;</span> mkdirp path.dirname(@path), callback</pre></div></div> </li> <li id="section-7"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Write the file’s source to disk and invoke <code>callback</code>.</p> </div> <div class="content"><div class='highlight'><pre> writeFile: <span class="hljs-function"><span class="hljs-params">(callback)</span> -&gt;</span> fs.writeFile @path, @source, <span class="hljs-string">"utf8"</span>, callback</pre></div></div> </li> <li id="section-8"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>If the root flag is set for this file, change its ownership to the <code>root</code> user and <code>wheel</code> group. Then invoke <code>callback</code>.</p> </div> <div class="content"><div class='highlight'><pre> setOwnership: <span class="hljs-function"><span class="hljs-params">(callback)</span> -&gt;</span> <span class="hljs-keyword">if</span> @root chown @path, <span class="hljs-string">"root:wheel"</span>, callback <span class="hljs-keyword">else</span> callback <span class="hljs-literal">false</span></pre></div></div> </li> <li id="section-9"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>Set permissions on the installed file with <code>chmod</code>.</p> </div> <div class="content"><div class='highlight'><pre> setPermissions: <span class="hljs-function"><span class="hljs-params">(callback)</span> -&gt;</span> fs.chmod @path, @mode, callback</pre></div></div> </li> <li id="section-10"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Install a file asynchronously, first by making its parent directory, then writing it to disk, and finally setting its ownership and permission bits.</p> </div> <div class="content"><div class='highlight'><pre> install: <span class="hljs-function"><span class="hljs-params">(callback)</span> -&gt;</span> async.series [ @vivifyPath.bind(@), @writeFile.bind(@), @setOwnership.bind(@), @setPermissions.bind(@) ], callback</pre></div></div> </li> <li id="section-11"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>The <code>Installer</code> class operates on a set of <code>InstallerFile</code> instances. It can check to see if any files are stale and whether or not root access is necessary for installation. It can also install any stale files asynchronously.</p> </div> <div class="content"><div class='highlight'><pre><span class="hljs-built_in">module</span>.exports = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Installer</span></span></pre></div></div> </li> <li id="section-12"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Factory method that takes a <code>Configuration</code> instance and returns an <code>Installer</code> for system firewall and DNS configuration files.</p> </div> <div class="content"><div class='highlight'><pre> @getSystemInstaller: <span class="hljs-function"><span class="hljs-params">(configuration)</span> -&gt;</span> files = [</pre></div></div> </li> <li id="section-13"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>new InstallerFile “/Library/LaunchDaemons/cx.masq.firewall.plist”, firewallSource(configuration), true</p> </div> <div class="content"><div class='highlight'><pre> ] <span class="hljs-keyword">for</span> domain <span class="hljs-keyword">in</span> configuration.domains files.push <span class="hljs-keyword">new</span> InstallerFile <span class="hljs-string">"/etc/resolver/<span class="hljs-subst">#{domain}</span>"</span>, resolverSource(configuration), <span class="hljs-literal">true</span> <span class="hljs-keyword">new</span> Installer files</pre></div></div> </li> <li id="section-14"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Factory method that takes a <code>Configuration</code> instance and returns an <code>Installer</code> for the Pow <code>launchctl</code> daemon configuration file.</p> </div> <div class="content"><div class='highlight'><pre> @getLocalInstaller: <span class="hljs-function"><span class="hljs-params">(configuration)</span> -&gt;</span> <span class="hljs-keyword">new</span> Installer [ <span class="hljs-keyword">new</span> InstallerFile <span class="hljs-string">"<span class="hljs-subst">#{process.env.HOME}</span>/Library/LaunchAgents/cx.masq.masqd.plist"</span>, daemonSource(configuration) ]</pre></div></div> </li> <li id="section-15"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Create an installer for a set of files.</p> </div> <div class="content"><div class='highlight'><pre> constructor: <span class="hljs-function"><span class="hljs-params">(@files = [])</span> -&gt;</span></pre></div></div> </li> <li id="section-16"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>Invoke <code>callback</code> with an array of any files that need to be installed.</p> </div> <div class="content"><div class='highlight'><pre> getStaleFiles: <span class="hljs-function"><span class="hljs-params">(callback)</span> -&gt;</span> async.select @files, <span class="hljs-function"><span class="hljs-params">(file, proceed)</span> -&gt;</span> file.isStale proceed , callback @files</pre></div></div> </li> <li id="section-17"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Invoke <code>callback</code> with a boolean argument indicating whether or not any files need to be installed as root.</p> </div> <div class="content"><div class='highlight'><pre> needsRootPrivileges: <span class="hljs-function"><span class="hljs-params">(callback)</span> -&gt;</span> @getStaleFiles (files) -&gt; async.detect files, <span class="hljs-function"><span class="hljs-params">(file, proceed)</span> -&gt;</span> proceed file.root , <span class="hljs-function"><span class="hljs-params">(result)</span> -&gt;</span> callback result?</pre></div></div> </li> <li id="section-18"> <div class="annotation"> <div class="pilwrap "> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>Installs any stale files asynchronously and then invokes <code>callback</code>.</p> </div> <div class="content"><div class='highlight'><pre> install: <span class="hljs-function"><span class="hljs-params">(callback)</span> -&gt;</span> @getStaleFiles (files) -&gt; async.forEach files, <span class="hljs-function"><span class="hljs-params">(file, proceed)</span> -&gt;</span> file.install (err) -&gt; util.puts file.path <span class="hljs-keyword">unless</span> err proceed err , callback</pre></div></div> </li> </ul> </div> </body> </html>